@whispering233/ai-editor-tools 0.0.1

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.
Files changed (109) hide show
  1. package/dist/analysis/conflict.d.ts +20 -0
  2. package/dist/analysis/conflict.d.ts.map +1 -0
  3. package/dist/analysis/conflict.js +116 -0
  4. package/dist/analysis/conflict.js.map +1 -0
  5. package/dist/analysis/consistency.d.ts +28 -0
  6. package/dist/analysis/consistency.d.ts.map +1 -0
  7. package/dist/analysis/consistency.js +108 -0
  8. package/dist/analysis/consistency.js.map +1 -0
  9. package/dist/analysis/hook.d.ts +157 -0
  10. package/dist/analysis/hook.d.ts.map +1 -0
  11. package/dist/analysis/hook.js +381 -0
  12. package/dist/analysis/hook.js.map +1 -0
  13. package/dist/analysis/orphan.d.ts +60 -0
  14. package/dist/analysis/orphan.d.ts.map +1 -0
  15. package/dist/analysis/orphan.js +153 -0
  16. package/dist/analysis/orphan.js.map +1 -0
  17. package/dist/analysis/path.d.ts +23 -0
  18. package/dist/analysis/path.d.ts.map +1 -0
  19. package/dist/analysis/path.js +114 -0
  20. package/dist/analysis/path.js.map +1 -0
  21. package/dist/analysis/suggest.d.ts +19 -0
  22. package/dist/analysis/suggest.d.ts.map +1 -0
  23. package/dist/analysis/suggest.js +92 -0
  24. package/dist/analysis/suggest.js.map +1 -0
  25. package/dist/analysis/utils.d.ts +54 -0
  26. package/dist/analysis/utils.d.ts.map +1 -0
  27. package/dist/analysis/utils.js +123 -0
  28. package/dist/analysis/utils.js.map +1 -0
  29. package/dist/context.d.ts +10 -0
  30. package/dist/context.d.ts.map +1 -0
  31. package/dist/context.js +11 -0
  32. package/dist/context.js.map +1 -0
  33. package/dist/executor/delta.d.ts +4 -0
  34. package/dist/executor/delta.d.ts.map +1 -0
  35. package/dist/executor/delta.js +22 -0
  36. package/dist/executor/delta.js.map +1 -0
  37. package/dist/executor/entity.d.ts +8 -0
  38. package/dist/executor/entity.d.ts.map +1 -0
  39. package/dist/executor/entity.js +47 -0
  40. package/dist/executor/entity.js.map +1 -0
  41. package/dist/executor/hook.d.ts +8 -0
  42. package/dist/executor/hook.d.ts.map +1 -0
  43. package/dist/executor/hook.js +183 -0
  44. package/dist/executor/hook.js.map +1 -0
  45. package/dist/executor/index.d.ts +22 -0
  46. package/dist/executor/index.d.ts.map +1 -0
  47. package/dist/executor/index.js +89 -0
  48. package/dist/executor/index.js.map +1 -0
  49. package/dist/executor/outline.d.ts +8 -0
  50. package/dist/executor/outline.d.ts.map +1 -0
  51. package/dist/executor/outline.js +39 -0
  52. package/dist/executor/outline.js.map +1 -0
  53. package/dist/executor/relation.d.ts +6 -0
  54. package/dist/executor/relation.d.ts.map +1 -0
  55. package/dist/executor/relation.js +33 -0
  56. package/dist/executor/relation.js.map +1 -0
  57. package/dist/executor/types.d.ts +25 -0
  58. package/dist/executor/types.d.ts.map +1 -0
  59. package/dist/executor/types.js +54 -0
  60. package/dist/executor/types.js.map +1 -0
  61. package/dist/index.d.ts +23 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +359 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/proposal/delta.d.ts +8 -0
  66. package/dist/proposal/delta.d.ts.map +1 -0
  67. package/dist/proposal/delta.js +29 -0
  68. package/dist/proposal/delta.js.map +1 -0
  69. package/dist/proposal/entity.d.ts +16 -0
  70. package/dist/proposal/entity.d.ts.map +1 -0
  71. package/dist/proposal/entity.js +54 -0
  72. package/dist/proposal/entity.js.map +1 -0
  73. package/dist/proposal/hook.d.ts +24 -0
  74. package/dist/proposal/hook.d.ts.map +1 -0
  75. package/dist/proposal/hook.js +81 -0
  76. package/dist/proposal/hook.js.map +1 -0
  77. package/dist/proposal/outline.d.ts +24 -0
  78. package/dist/proposal/outline.d.ts.map +1 -0
  79. package/dist/proposal/outline.js +78 -0
  80. package/dist/proposal/outline.js.map +1 -0
  81. package/dist/proposal/relation.d.ts +12 -0
  82. package/dist/proposal/relation.d.ts.map +1 -0
  83. package/dist/proposal/relation.js +50 -0
  84. package/dist/proposal/relation.js.map +1 -0
  85. package/dist/proposal/types.d.ts +72 -0
  86. package/dist/proposal/types.d.ts.map +1 -0
  87. package/dist/proposal/types.js +105 -0
  88. package/dist/proposal/types.js.map +1 -0
  89. package/dist/query/delta.d.ts +20 -0
  90. package/dist/query/delta.d.ts.map +1 -0
  91. package/dist/query/delta.js +41 -0
  92. package/dist/query/delta.js.map +1 -0
  93. package/dist/query/entity.d.ts +29 -0
  94. package/dist/query/entity.d.ts.map +1 -0
  95. package/dist/query/entity.js +53 -0
  96. package/dist/query/entity.js.map +1 -0
  97. package/dist/query/outline.d.ts +20 -0
  98. package/dist/query/outline.d.ts.map +1 -0
  99. package/dist/query/outline.js +68 -0
  100. package/dist/query/outline.js.map +1 -0
  101. package/dist/query/relation.d.ts +12 -0
  102. package/dist/query/relation.d.ts.map +1 -0
  103. package/dist/query/relation.js +30 -0
  104. package/dist/query/relation.js.map +1 -0
  105. package/dist/registry.d.ts +41 -0
  106. package/dist/registry.d.ts.map +1 -0
  107. package/dist/registry.js +46 -0
  108. package/dist/registry.js.map +1 -0
  109. package/package.json +35 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/proposal/hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { ProposeDeleteNodeArgs, ProposeMoveNodeArgs, ProposeOutlineNodeArgs } from "@whispering233/ai-editor-shared";
2
+ import type { ToolContext } from "../context.js";
3
+ import { type Proposal, type ToolProposalResult } from "./types.js";
4
+ /** 产出新增大纲节点提案(parent_id 缺省挂根;scene 无 parent 直接拒绝,决策 19) */
5
+ export declare function buildProposeOutlineNode(ctx: ToolContext, args: ProposeOutlineNodeArgs): Proposal;
6
+ /** propose_outline_node run */
7
+ export declare function runProposeOutlineNode(ctx: ToolContext, args: ProposeOutlineNodeArgs, signal?: AbortSignal): ToolProposalResult;
8
+ /**
9
+ * 产出移动大纲节点提案(目标父须可容纳该层级,决策 19)。
10
+ * parent_id 可为 "root"(决策 19:volume/chapter 可挂 root——db moveOutlineNode 支持
11
+ * parentId === "root",AI 可提案「把卷移到树首」等合法操作):root 恒存在、非节点,
12
+ * 跳过 requireOutlineNode 且**不采集 root 引用快照**(与 propose_outline_node 缺省挂根语义对齐);
13
+ * 此时层级约束只取决于 node 自身类型(volume/chapter 可挂 root,scene 不可)。
14
+ * order 语义:目标父 children 数组中的目标位置(0 起);超出长度的行为(clamp 或抛错)
15
+ * 由 S6.7/db 执行时定义,生成时校验不做上限(见 schema 注释)。
16
+ */
17
+ export declare function buildProposeMoveNode(ctx: ToolContext, args: ProposeMoveNodeArgs): Proposal;
18
+ /** propose_move_node run */
19
+ export declare function runProposeMoveNode(ctx: ToolContext, args: ProposeMoveNodeArgs, signal?: AbortSignal): ToolProposalResult;
20
+ /** 产出删除大纲节点提案(软删 + 递归子树,可回收站还原,决策 12) */
21
+ export declare function buildProposeDeleteNode(ctx: ToolContext, args: ProposeDeleteNodeArgs): Proposal;
22
+ /** propose_delete_node run */
23
+ export declare function runProposeDeleteNode(ctx: ToolContext, args: ProposeDeleteNodeArgs, signal?: AbortSignal): ToolProposalResult;
24
+ //# sourceMappingURL=outline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../src/proposal/outline.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC1H,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAA2E,KAAK,QAAQ,EAA0B,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErK,2DAA2D;AAC3D,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,sBAAsB,GAAG,QAAQ,CAiBhG;AAED,+BAA+B;AAC/B,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,sBAAsB,EAC5B,MAAM,CAAC,EAAE,WAAW,GACnB,kBAAkB,CAIpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,mBAAmB,GAAG,QAAQ,CAqB1F;AAED,4BAA4B;AAC5B,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,mBAAmB,EACzB,MAAM,CAAC,EAAE,WAAW,GACnB,kBAAkB,CAIpB;AAED,yCAAyC;AACzC,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,qBAAqB,GAAG,QAAQ,CAS9F;AAED,8BAA8B;AAC9B,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,qBAAqB,EAC3B,MAAM,CAAC,EAAE,WAAW,GACnB,kBAAkB,CAIpB"}
@@ -0,0 +1,78 @@
1
+ // 提案类工具:大纲(S6.6,tools.md「提案类」3 个)
2
+ // propose_outline_node / propose_move_node / propose_delete_node
3
+ //
4
+ // 语义:只产出提案对象并返回 { proposal_id, summary }(2026-08 修订:tool_result 不含预览);
5
+ // **不落盘、不写任何数据**(与 S6.7 create_outline_node/move_node/delete_node 对比的核心差异)。
6
+ //
7
+ // 生成时校验(决策 14/19/12):
8
+ // - propose_outline_node:parent_id 缺省挂根(volume/chapter 可挂 root,scene 必须挂 chapter——
9
+ // assertCanHold 抛 INVALID_HIERARCHY);父节点存在且未软删时采集节点级 updated_at 快照
10
+ // - propose_move_node:节点与目标父均存在且未软删,且目标父可容纳该层级(严格三层);
11
+ // 采集两节点 updated_at 快照
12
+ // - propose_delete_node:节点存在且未软删(软删 + 递归子树,可回收站还原,决策 12)
13
+ import { assertCanHold } from "@whispering233/ai-editor-db";
14
+ import { buildProposal, checkProposalAborted, refOutlineNode, requireOutlineNode } from "./types.js";
15
+ /** 产出新增大纲节点提案(parent_id 缺省挂根;scene 无 parent 直接拒绝,决策 19) */
16
+ export function buildProposeOutlineNode(ctx, args) {
17
+ // 层级约束(决策 19 严格三层):root 可挂 volume/chapter;scene 必须挂 chapter(缺省 root 即拒绝)
18
+ const references = [];
19
+ if (args.parent_id === undefined) {
20
+ assertCanHold("root", args.type);
21
+ }
22
+ else {
23
+ const parent = requireOutlineNode(ctx, args.parent_id);
24
+ assertCanHold(parent.type, args.type);
25
+ references.push(refOutlineNode(parent));
26
+ }
27
+ return buildProposal(ctx, "propose_outline_node", { type: args.type, title: args.title, ...(args.parent_id === undefined ? {} : { parent_id: args.parent_id }) }, references, `新增大纲节点「${args.title}」(${args.type}${args.parent_id === undefined ? ",挂根" : `,挂 ${args.parent_id}`})`);
28
+ }
29
+ /** propose_outline_node run */
30
+ export function runProposeOutlineNode(ctx, args, signal) {
31
+ checkProposalAborted(signal);
32
+ const proposal = buildProposeOutlineNode(ctx, args);
33
+ return { proposal_id: proposal.proposal_id, summary: proposal.summary };
34
+ }
35
+ /**
36
+ * 产出移动大纲节点提案(目标父须可容纳该层级,决策 19)。
37
+ * parent_id 可为 "root"(决策 19:volume/chapter 可挂 root——db moveOutlineNode 支持
38
+ * parentId === "root",AI 可提案「把卷移到树首」等合法操作):root 恒存在、非节点,
39
+ * 跳过 requireOutlineNode 且**不采集 root 引用快照**(与 propose_outline_node 缺省挂根语义对齐);
40
+ * 此时层级约束只取决于 node 自身类型(volume/chapter 可挂 root,scene 不可)。
41
+ * order 语义:目标父 children 数组中的目标位置(0 起);超出长度的行为(clamp 或抛错)
42
+ * 由 S6.7/db 执行时定义,生成时校验不做上限(见 schema 注释)。
43
+ */
44
+ export function buildProposeMoveNode(ctx, args) {
45
+ const node = requireOutlineNode(ctx, args.node_id);
46
+ const references = [refOutlineNode(node)];
47
+ // 目标父展示名(root 恒存在、非节点,无 title)
48
+ let parentLabel = "树根";
49
+ if (args.parent_id === "root") {
50
+ // root 恒存在、非引用对象:仅校验层级(scene 不能挂 root,决策 19 严格三层)
51
+ assertCanHold("root", node.type);
52
+ }
53
+ else {
54
+ const parent = requireOutlineNode(ctx, args.parent_id);
55
+ assertCanHold(parent.type, node.type);
56
+ references.push(refOutlineNode(parent));
57
+ parentLabel = `「${parent.title}」`;
58
+ }
59
+ return buildProposal(ctx, "propose_move_node", { node_id: args.node_id, parent_id: args.parent_id, order: args.order }, references, `移动节点「${node.title}」到${parentLabel}下第 ${args.order} 位`);
60
+ }
61
+ /** propose_move_node run */
62
+ export function runProposeMoveNode(ctx, args, signal) {
63
+ checkProposalAborted(signal);
64
+ const proposal = buildProposeMoveNode(ctx, args);
65
+ return { proposal_id: proposal.proposal_id, summary: proposal.summary };
66
+ }
67
+ /** 产出删除大纲节点提案(软删 + 递归子树,可回收站还原,决策 12) */
68
+ export function buildProposeDeleteNode(ctx, args) {
69
+ const node = requireOutlineNode(ctx, args.node_id);
70
+ return buildProposal(ctx, "propose_delete_node", { node_id: args.node_id }, [refOutlineNode(node)], `删除大纲节点「${node.title}」(${node.type},含子树,软删可还原)`);
71
+ }
72
+ /** propose_delete_node run */
73
+ export function runProposeDeleteNode(ctx, args, signal) {
74
+ checkProposalAborted(signal);
75
+ const proposal = buildProposeDeleteNode(ctx, args);
76
+ return { proposal_id: proposal.proposal_id, summary: proposal.summary };
77
+ }
78
+ //# sourceMappingURL=outline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outline.js","sourceRoot":"","sources":["../../src/proposal/outline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ProposeAddRelationArgs, ProposeRemoveRelationArgs } from "@whispering233/ai-editor-shared";
2
+ import type { ToolContext } from "../context.js";
3
+ import { type Proposal, type ToolProposalResult } from "./types.js";
4
+ /** 产出新增关系提案(端点类型生成时自动识别,执行形态规范化到 args) */
5
+ export declare function buildProposeAddRelation(ctx: ToolContext, args: ProposeAddRelationArgs): Proposal;
6
+ /** propose_add_relation run */
7
+ export declare function runProposeAddRelation(ctx: ToolContext, args: ProposeAddRelationArgs, signal?: AbortSignal): ToolProposalResult;
8
+ /** 产出移除关系提案(确认后物理删,不进回收站,决策 12) */
9
+ export declare function buildProposeRemoveRelation(ctx: ToolContext, args: ProposeRemoveRelationArgs): Proposal;
10
+ /** propose_remove_relation run */
11
+ export declare function runProposeRemoveRelation(ctx: ToolContext, args: ProposeRemoveRelationArgs, signal?: AbortSignal): ToolProposalResult;
12
+ //# sourceMappingURL=relation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation.d.ts","sourceRoot":"","sources":["../../src/proposal/relation.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AACzG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAqE,KAAK,QAAQ,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEvI,0CAA0C;AAC1C,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,sBAAsB,GAAG,QAAQ,CAmBhG;AAED,+BAA+B;AAC/B,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,sBAAsB,EAC5B,MAAM,CAAC,EAAE,WAAW,GACnB,kBAAkB,CAIpB;AAED,mCAAmC;AACnC,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,yBAAyB,GAAG,QAAQ,CAYtG;AAED,kCAAkC;AAClC,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,yBAAyB,EAC/B,MAAM,CAAC,EAAE,WAAW,GACnB,kBAAkB,CAIpB"}
@@ -0,0 +1,50 @@
1
+ // 提案类工具:关系(S6.6,tools.md「提案类」2 个)
2
+ // propose_add_relation / propose_remove_relation
3
+ //
4
+ // 语义:只产出提案对象并返回 { proposal_id, summary }(2026-08 修订:tool_result 不含预览);
5
+ // **不落盘、不写任何数据**(本模块零写操作——与 S6.7 add_relation/remove_relation 对比的核心差异)。
6
+ //
7
+ // 生成时校验(决策 14/19):
8
+ // - propose_add_relation:source/target 端点存在且未软删(resolveEndpoint:实体表优先、
9
+ // 其次大纲树),采集各端点 updated_at 快照;args 规范化为执行形态
10
+ // (source_type/source_id/target_type/target_id/relation_type/metadata——S6.7 执行时可直接透传)
11
+ // - propose_remove_relation:关系存在且可见(getRelation 已含端点软删联动过滤,决策 12 修订),
12
+ // 采集关系自身 updated_at 快照(决策 14)
13
+ import { getRelation } from "@whispering233/ai-editor-db";
14
+ import { buildProposal, checkProposalAborted, refRelation, resolveEndpoint } from "./types.js";
15
+ /** 产出新增关系提案(端点类型生成时自动识别,执行形态规范化到 args) */
16
+ export function buildProposeAddRelation(ctx, args) {
17
+ const source = resolveEndpoint(ctx, args.source);
18
+ const target = resolveEndpoint(ctx, args.target);
19
+ // 执行信息:派生端点类型 + 原样透传 relation_type/metadata(S6.7 add_relation 直接消费)
20
+ const executeArgs = {
21
+ source_type: source.type,
22
+ source_id: args.source,
23
+ target_type: target.type,
24
+ target_id: args.target,
25
+ relation_type: args.type,
26
+ ...(args.metadata === undefined ? {} : { metadata: args.metadata }),
27
+ };
28
+ return buildProposal(ctx, "propose_add_relation", executeArgs, [source.ref, target.ref], `新增关系: ${args.source} —${args.type}→ ${args.target}`);
29
+ }
30
+ /** propose_add_relation run */
31
+ export function runProposeAddRelation(ctx, args, signal) {
32
+ checkProposalAborted(signal);
33
+ const proposal = buildProposeAddRelation(ctx, args);
34
+ return { proposal_id: proposal.proposal_id, summary: proposal.summary };
35
+ }
36
+ /** 产出移除关系提案(确认后物理删,不进回收站,决策 12) */
37
+ export function buildProposeRemoveRelation(ctx, args) {
38
+ const relation = getRelation(ctx.db, args.relation_id, ctx.outlineDir);
39
+ if (relation === null) {
40
+ throw new Error(`关系不存在或不可见: ${args.relation_id}`);
41
+ }
42
+ return buildProposal(ctx, "propose_remove_relation", { relation_id: args.relation_id }, [refRelation(relation)], `移除关系 ${relation.source_type}/${relation.source_id} —${relation.relation_type}→ ${relation.target_type}/${relation.target_id}`);
43
+ }
44
+ /** propose_remove_relation run */
45
+ export function runProposeRemoveRelation(ctx, args, signal) {
46
+ checkProposalAborted(signal);
47
+ const proposal = buildProposeRemoveRelation(ctx, args);
48
+ return { proposal_id: proposal.proposal_id, summary: proposal.summary };
49
+ }
50
+ //# sourceMappingURL=relation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation.js","sourceRoot":"","sources":["../../src/proposal/relation.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,iDAAiD;AACjD,EAAE;AACF,uEAAuE;AACvE,wEAAwE;AACxE,EAAE;AACF,mBAAmB;AACnB,uEAAuE;AACvE,6CAA6C;AAC7C,wFAAwF;AACxF,sEAAsE;AACtE,gCAAgC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG1D,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,WAAW,EAAE,eAAe,EAA0C,MAAM,YAAY,CAAC;AAEvI,0CAA0C;AAC1C,MAAM,UAAU,uBAAuB,CAAC,GAAgB,EAAE,IAA4B;IACpF,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACjD,oEAAoE;IACpE,MAAM,WAAW,GAA4B;QAC3C,WAAW,EAAE,MAAM,CAAC,IAAI;QACxB,SAAS,EAAE,IAAI,CAAC,MAAM;QACtB,WAAW,EAAE,MAAM,CAAC,IAAI;QACxB,SAAS,EAAE,IAAI,CAAC,MAAM;QACtB,aAAa,EAAE,IAAI,CAAC,IAAI;QACxB,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;KACpE,CAAC;IACF,OAAO,aAAa,CAClB,GAAG,EACH,sBAAsB,EACtB,WAAW,EACX,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,EACxB,SAAS,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,CACrD,CAAC;AACJ,CAAC;AAED,+BAA+B;AAC/B,MAAM,UAAU,qBAAqB,CACnC,GAAgB,EAChB,IAA4B,EAC5B,MAAoB;IAEpB,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;AAC1E,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,0BAA0B,CAAC,GAAgB,EAAE,IAA+B;IAC1F,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IACvE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,aAAa,CAClB,GAAG,EACH,yBAAyB,EACzB,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,EACjC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EACvB,QAAQ,QAAQ,CAAC,WAAW,IAAI,QAAQ,CAAC,SAAS,KAAK,QAAQ,CAAC,aAAa,KAAK,QAAQ,CAAC,WAAW,IAAI,QAAQ,CAAC,SAAS,EAAE,CAC/H,CAAC;AACJ,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,wBAAwB,CACtC,GAAgB,EAChB,IAA+B,EAC/B,MAAoB;IAEpB,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,0BAA0B,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACvD,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,72 @@
1
+ import type { EntityRow, OutlineFileNode, RelationRow } from "@whispering233/ai-editor-shared";
2
+ import type { ToolContext } from "../context.js";
3
+ /** 被引用对象种类(决策 14/19:确认时按 kind 走对应存在性 + updated_at 重校验路径) */
4
+ export type ProposalReferenceKind = "entity" | "relation" | "delta" | "outline_node";
5
+ /** 单个引用快照:被引用对象 id + updated_at(决策 14 快照比对) */
6
+ export interface ProposalReference {
7
+ kind: ProposalReferenceKind;
8
+ id: string;
9
+ /** 快照:实体/关系用自身 updated_at;大纲节点用节点级 updated_at(决策 14/19) */
10
+ updated_at: string;
11
+ }
12
+ /** 提案对象(决策 14:仅内存;S7.4 提案仓存储,S7.5 confirm/reject 消费) */
13
+ export interface Proposal {
14
+ /** 运行时 id(prop_ 前缀,endpoints.md id 约定) */
15
+ proposal_id: string;
16
+ /** 工具名(propose_*,PROPOSAL_TOOLS 一员) */
17
+ type: string;
18
+ /** 执行信息:确认后 S6.7 执行工具可直接使用的参数(含派生端点类型等规范化形态) */
19
+ args: Record<string, unknown>;
20
+ /** 项目绑定(决策 14 修订;confirm/reject 校验与当前项目一致) */
21
+ project_id: string;
22
+ /** 引用对象快照(决策 14/19:存在性 + updated_at) */
23
+ references: ProposalReference[];
24
+ /** 一句话摘要(tool_result + GUI 展示) */
25
+ summary: string;
26
+ /** ISO 8601 创建时间(应用层写入约定;TTL 计算基准,S7.4) */
27
+ createdAt: string;
28
+ }
29
+ /** propose_* tool_result(tools.md 2026-08 修订:仅「提案已发出」提示,不含预览细节) */
30
+ export interface ToolProposalResult {
31
+ proposal_id: string;
32
+ summary: string;
33
+ }
34
+ /**
35
+ * 构造提案对象(S6.6 产出):生成 prop_ id + 绑定 project_id + 应用层写入 createdAt。
36
+ * 返回**完整 Proposal**(供 S7.4 提案仓存储);run 函数只把 { proposal_id, summary }
37
+ * 作为 tool_result 返回(S7.4 同时需要完整对象,故此处返回完整结构)。
38
+ *
39
+ * **入口约定**:build 为纯产出层(无 signal 参数,不做中止检查)——S7.4 提案仓统一走
40
+ * 各工具 run 入口(含 checkProposalAborted);build 仅供构建期复用(测试断言结构、
41
+ * S7.4 需要完整对象时经 run 内部产出路径间接获取),直接调用方自行保证无并发取消语义。
42
+ */
43
+ export declare function buildProposal(ctx: ToolContext, type: string, args: Record<string, unknown>, references: ProposalReference[], summary: string): Proposal;
44
+ /** 实体引用快照(决策 14:用实体自身 updated_at) */
45
+ export declare function refEntity(row: EntityRow): ProposalReference;
46
+ /** 关系引用快照(决策 14:用关系自身 updated_at) */
47
+ export declare function refRelation(row: RelationRow): ProposalReference;
48
+ /** 大纲节点引用快照(决策 19:用节点级 updated_at) */
49
+ export declare function refOutlineNode(node: OutlineFileNode): ProposalReference;
50
+ /**
51
+ * 解析端点(关系 source/target、Delta target 共用):id → { 类型, 引用快照 }。
52
+ * 判定顺序:实体表优先(getEntity 已过滤软删,决策 12),其次大纲树(存在且未软删);
53
+ * 两者皆不命中抛错(工具执行契约「抛错即失败」,executor 转结构化结果喂回 LLM 自纠)。
54
+ * root 是树根而非端点,直接拒绝。
55
+ */
56
+ export declare function resolveEndpoint(ctx: ToolContext, id: string): {
57
+ type: string;
58
+ ref: ProposalReference;
59
+ };
60
+ /**
61
+ * 按 id 取大纲节点(存在且未软删,决策 12);否则抛错。
62
+ * 供 propose_add_delta 触发节点 / propose_outline_node 父节点 / move / delete / hook 埋设节点复用。
63
+ */
64
+ export declare function requireOutlineNode(ctx: ToolContext, nodeId: string): OutlineFileNode;
65
+ /**
66
+ * 按 id 取伏笔实体(type === "hook" 且未软删,类型一致性校验);否则抛错。
67
+ * 伏笔即 type=hook 的实体(hooks.md:用户手动创建或 AI 提案创建),快照用实体自身 updated_at(决策 14)。
68
+ */
69
+ export declare function requireHook(ctx: ToolContext, hookId: string): EntityRow;
70
+ /** 提案工具入口统一中止检查(决策 16 ③:长工具执行中检查 signal;提案生成是同步短操作,入口检查一次即可) */
71
+ export declare function checkProposalAborted(signal?: AbortSignal): void;
72
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/proposal/types.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE/F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGjD,4DAA4D;AAC5D,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,cAAc,CAAC;AAErF,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wDAAwD;AACxD,MAAM,WAAW,QAAQ;IACvB,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,EAAE,iBAAiB,EAAE,EAC/B,OAAO,EAAE,MAAM,GACd,QAAQ,CAUV;AAED,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,iBAAiB,CAE3D;AAED,qCAAqC;AACrC,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,iBAAiB,CAE/D;AAED,sCAAsC;AACtC,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,iBAAiB,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,EAAE,EAAE,MAAM,GACT;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,iBAAiB,CAAA;CAAE,CAa1C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAMpF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAMvE;AAED,gEAAgE;AAChE,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAE/D"}
@@ -0,0 +1,105 @@
1
+ // 提案对象类型 + 构造辅助(S6.6,proposal/ 模块公共层)
2
+ //
3
+ // **提案是服务端运行时对象**(决策 14:仅内存、不落盘、随 SSE 推送 GUI;prop_ 前缀运行时 id,
4
+ // 不跨 client——故定义在 tools 包而非 shared)。提案仓(TTL 10 分钟 + 条数上限 + 项目绑定)
5
+ // 属 S7.4 范围,本模块只负责**产出提案对象结构**。
6
+ //
7
+ // 提案对象结构(决策 14/19):
8
+ // - proposal_id:prop_ 前缀(generateRuntimeId,endpoints.md id 约定)
9
+ // - type:工具名(PROPOSAL_TOOLS 一员,S7.4 executor 按名调度)
10
+ // - args:**执行信息**——确认后调用 S6.7 执行工具所需的全部参数(端点类工具已把
11
+ // id 解析为 {source_type, source_id} 等规范化形态,执行时可直接透传)
12
+ // - project_id:项目绑定(决策 14 修订,confirm/reject 校验归属)
13
+ // - references:被引用对象 id + updated_at 快照——实体/关系用自身 updated_at、
14
+ // 大纲节点用节点级 updated_at(决策 14/19);确认(S7.5)时按 kind 重校验
15
+ // (存在性 + updated_at 比对,失败 409 PROPOSAL_STALE)
16
+ // - summary:一句话摘要(tool_result + GUI 展示)
17
+ // - createdAt:ISO 8601(应用层写入约定;TTL 计算基准)
18
+ //
19
+ // tool_result 语义(tools.md「返回语义」2026-08 修订):propose_* 的 run 只返回
20
+ // { proposal_id, summary },**不含预览细节**——避免 LLM 误以为提案已生效而重复提案;
21
+ // 完整预览经 SSE proposal 事件推送 GUI(S7 实现)。
22
+ import { getEntity } from "@whispering233/ai-editor-db";
23
+ import { nowIso } from "@whispering233/ai-editor-db";
24
+ import { generateRuntimeId } from "@whispering233/ai-editor-shared";
25
+ import { findOutlineNode, readOutlineFile } from "@whispering233/ai-editor-db";
26
+ import { throwIfAborted } from "../analysis/utils.js";
27
+ /**
28
+ * 构造提案对象(S6.6 产出):生成 prop_ id + 绑定 project_id + 应用层写入 createdAt。
29
+ * 返回**完整 Proposal**(供 S7.4 提案仓存储);run 函数只把 { proposal_id, summary }
30
+ * 作为 tool_result 返回(S7.4 同时需要完整对象,故此处返回完整结构)。
31
+ *
32
+ * **入口约定**:build 为纯产出层(无 signal 参数,不做中止检查)——S7.4 提案仓统一走
33
+ * 各工具 run 入口(含 checkProposalAborted);build 仅供构建期复用(测试断言结构、
34
+ * S7.4 需要完整对象时经 run 内部产出路径间接获取),直接调用方自行保证无并发取消语义。
35
+ */
36
+ export function buildProposal(ctx, type, args, references, summary) {
37
+ return {
38
+ proposal_id: generateRuntimeId("proposal"),
39
+ type,
40
+ args,
41
+ project_id: ctx.projectId,
42
+ references,
43
+ summary,
44
+ createdAt: nowIso(),
45
+ };
46
+ }
47
+ /** 实体引用快照(决策 14:用实体自身 updated_at) */
48
+ export function refEntity(row) {
49
+ return { kind: "entity", id: row.id, updated_at: row.updated_at };
50
+ }
51
+ /** 关系引用快照(决策 14:用关系自身 updated_at) */
52
+ export function refRelation(row) {
53
+ return { kind: "relation", id: row.id, updated_at: row.updated_at };
54
+ }
55
+ /** 大纲节点引用快照(决策 19:用节点级 updated_at) */
56
+ export function refOutlineNode(node) {
57
+ return { kind: "outline_node", id: node.id, updated_at: node.updated_at };
58
+ }
59
+ /**
60
+ * 解析端点(关系 source/target、Delta target 共用):id → { 类型, 引用快照 }。
61
+ * 判定顺序:实体表优先(getEntity 已过滤软删,决策 12),其次大纲树(存在且未软删);
62
+ * 两者皆不命中抛错(工具执行契约「抛错即失败」,executor 转结构化结果喂回 LLM 自纠)。
63
+ * root 是树根而非端点,直接拒绝。
64
+ */
65
+ export function resolveEndpoint(ctx, id) {
66
+ if (id === "root") {
67
+ throw new Error(`端点不存在或已软删: ${id}`);
68
+ }
69
+ const entity = getEntity(ctx.db, id);
70
+ if (entity !== null) {
71
+ return { type: entity.type, ref: refEntity(entity) };
72
+ }
73
+ const node = findOutlineNode(readOutlineFile(ctx.outlineDir), id);
74
+ if (node !== undefined && node.deleted !== true) {
75
+ return { type: "outline_node", ref: refOutlineNode(node) };
76
+ }
77
+ throw new Error(`端点不存在或已软删: ${id}`);
78
+ }
79
+ /**
80
+ * 按 id 取大纲节点(存在且未软删,决策 12);否则抛错。
81
+ * 供 propose_add_delta 触发节点 / propose_outline_node 父节点 / move / delete / hook 埋设节点复用。
82
+ */
83
+ export function requireOutlineNode(ctx, nodeId) {
84
+ const node = findOutlineNode(readOutlineFile(ctx.outlineDir), nodeId);
85
+ if (node === undefined || node.deleted === true) {
86
+ throw new Error(`大纲节点不存在或已软删: ${nodeId}`);
87
+ }
88
+ return node;
89
+ }
90
+ /**
91
+ * 按 id 取伏笔实体(type === "hook" 且未软删,类型一致性校验);否则抛错。
92
+ * 伏笔即 type=hook 的实体(hooks.md:用户手动创建或 AI 提案创建),快照用实体自身 updated_at(决策 14)。
93
+ */
94
+ export function requireHook(ctx, hookId) {
95
+ const entity = getEntity(ctx.db, hookId);
96
+ if (entity === null || entity.type !== "hook") {
97
+ throw new Error(`伏笔不存在或已软删: ${hookId}`);
98
+ }
99
+ return entity;
100
+ }
101
+ /** 提案工具入口统一中止检查(决策 16 ③:长工具执行中检查 signal;提案生成是同步短操作,入口检查一次即可) */
102
+ export function checkProposalAborted(signal) {
103
+ throwIfAborted(signal);
104
+ }
105
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/proposal/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { ComputeStateResult, DeltaRecord } from "@whispering233/ai-editor-shared";
2
+ import type { ToolContext } from "../context.js";
3
+ import type { ComputeStateArgs, GetDeltaHistoryArgs } from "@whispering233/ai-editor-shared";
4
+ /**
5
+ * 实体到达指定节点时的累积状态(tools.md compute_state(target_type, target_id, at_node_id))。
6
+ * 透传 db computeState:只沿大纲树父链(根 → at_node_id)累积已确认 Delta(决策 9),
7
+ * 节点间按树路径序、节点内按 order 双层排序;plot_edge 不参与;op=update from 校验失败
8
+ * **跳过该 change 并继续累积**,结果在 conflicts 中标注 { field, expected, actual }
9
+ * (不返回 409——手动编辑 data 属正常用户行为,决策 9 修订)。
10
+ * 目标实体不存在/已软删 → null;at_node_id 不存在 → db 抛错(上层按工具失败处理)。
11
+ */
12
+ export declare function runComputeState(ctx: ToolContext, args: ComputeStateArgs): ComputeStateResult | null;
13
+ /**
14
+ * 目标实体的全部属性变更记录(tools.md get_delta_history(target_type, target_id))。
15
+ * 透传 db listDeltasByTarget:按 target_id 查询 + 全局 order ASC(时间序)排序 +
16
+ * 可见性三态过滤(决策 12 修订:delta 自身 / 触发节点 / 目标端点任一软删即不可见)+
17
+ * targetName 联表填充。target_type 仅由 db 侧用于判定目标端点类型(实体/大纲节点)。
18
+ */
19
+ export declare function runGetDeltaHistory(ctx: ToolContext, args: GetDeltaHistoryArgs): DeltaRecord[];
20
+ //# sourceMappingURL=delta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delta.d.ts","sourceRoot":"","sources":["../../src/query/delta.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAI7F;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,GAAG,kBAAkB,GAAG,IAAI,CAMnG;AAID;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,mBAAmB,GAAG,WAAW,EAAE,CAE7F"}
@@ -0,0 +1,41 @@
1
+ // 查询类工具:Delta 侧实现(S6.3)
2
+ // compute_state / get_delta_history(tools.md「状态查询(Delta 相关)」)
3
+ // 契约来源:doc/api/tools.md;doc/api/endpoints.md Delta 端点;决策 9(父链累积、
4
+ // conflicts 跳过语义)、决策 12 修订(可见性三态过滤)、决策 19(严格三层路径唯一)。
5
+ //
6
+ // db 层能力确认与分工(S6.3 修复轮:数据访问一律走 db 查询层,工具层无原生 SQL):
7
+ // - compute_state:db computeState 已封装全部语义(父链双层排序累积、op=update from
8
+ // 校验失败跳过 + conflicts 标注不返回 409、软删过滤、目标实体缺失返回 null)——
9
+ // 工具层参数映射透传;at_node_id 不存在时 db 抛错(视为调用方 bug,路由层前置校验
10
+ // 的约定),工具层不捕获——executor 统一转结构化错误喂回 LLM 自纠
11
+ // - get_delta_history:db listDeltasByTarget(S6.3 下沉)已实现按目标端点查询 +
12
+ // 可见性三态过滤(delta 自身/触发节点/目标端点软删,决策 12 修订,与 listDeltasByNode
13
+ // 共享 filterVisibleDeltas 实现)——工具层一行透传
14
+ import { computeState as dbComputeState, listDeltasByTarget } from "@whispering233/ai-editor-db";
15
+ // ============ compute_state ============
16
+ /**
17
+ * 实体到达指定节点时的累积状态(tools.md compute_state(target_type, target_id, at_node_id))。
18
+ * 透传 db computeState:只沿大纲树父链(根 → at_node_id)累积已确认 Delta(决策 9),
19
+ * 节点间按树路径序、节点内按 order 双层排序;plot_edge 不参与;op=update from 校验失败
20
+ * **跳过该 change 并继续累积**,结果在 conflicts 中标注 { field, expected, actual }
21
+ * (不返回 409——手动编辑 data 属正常用户行为,决策 9 修订)。
22
+ * 目标实体不存在/已软删 → null;at_node_id 不存在 → db 抛错(上层按工具失败处理)。
23
+ */
24
+ export function runComputeState(ctx, args) {
25
+ return dbComputeState(ctx.db, ctx.outlineDir, {
26
+ targetType: args.target_type,
27
+ targetId: args.target_id,
28
+ atNodeId: args.at_node_id,
29
+ });
30
+ }
31
+ // ============ get_delta_history ============
32
+ /**
33
+ * 目标实体的全部属性变更记录(tools.md get_delta_history(target_type, target_id))。
34
+ * 透传 db listDeltasByTarget:按 target_id 查询 + 全局 order ASC(时间序)排序 +
35
+ * 可见性三态过滤(决策 12 修订:delta 自身 / 触发节点 / 目标端点任一软删即不可见)+
36
+ * targetName 联表填充。target_type 仅由 db 侧用于判定目标端点类型(实体/大纲节点)。
37
+ */
38
+ export function runGetDeltaHistory(ctx, args) {
39
+ return listDeltasByTarget(ctx.db, args.target_id, ctx.outlineDir);
40
+ }
41
+ //# sourceMappingURL=delta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delta.js","sourceRoot":"","sources":["../../src/query/delta.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,8DAA8D;AAC9D,iEAAiE;AACjE,uDAAuD;AACvD,EAAE;AACF,mDAAmD;AACnD,kEAAkE;AAClE,uDAAuD;AACvD,sDAAsD;AACtD,4CAA4C;AAC5C,iEAAiE;AACjE,6DAA6D;AAC7D,wCAAwC;AAExC,OAAO,EAAE,YAAY,IAAI,cAAc,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAKjG,0CAA0C;AAE1C;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,GAAgB,EAAE,IAAsB;IACtE,OAAO,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,UAAU,EAAE;QAC5C,UAAU,EAAE,IAAI,CAAC,WAAW;QAC5B,QAAQ,EAAE,IAAI,CAAC,SAAS;QACxB,QAAQ,EAAE,IAAI,CAAC,UAAU;KAC1B,CAAC,CAAC;AACL,CAAC;AAED,8CAA8C;AAE9C;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAgB,EAAE,IAAyB;IAC5E,OAAO,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { Entity } from "@whispering233/ai-editor-shared";
2
+ import type { EntityListResult, EntitySummaryStats } from "@whispering233/ai-editor-db";
3
+ import type { ToolContext } from "../context.js";
4
+ import type { GetEntityArgs, GetEntitySummaryArgs, SearchEntitiesArgs } from "@whispering233/ai-editor-shared";
5
+ /**
6
+ * 实体详情(tools.md get_entity(type, id) → 实体详情,含 data JSON 解析后的字段)。
7
+ * - db 层 getEntity 默认过滤软删(决策 12 修订:回收站对象不可见)
8
+ * - type 与行内实际类型不一致 → null(参数错误,id 前缀体系下正常调用不会出现;
9
+ * LLM 传错类型时得到「不存在」而非脏数据)
10
+ * - 不存在/已软删 → null(查询无结果 ≠ 失败,LLM 据 null 自纠或向用户确认)
11
+ */
12
+ export declare function runGetEntity(ctx: ToolContext, args: GetEntityArgs): Entity | null;
13
+ /** search_entities 结果:匹配实体摘要列表 + 过滤后总数(db listEntities 同构) */
14
+ export type SearchEntitiesResult = EntityListResult;
15
+ /**
16
+ * 实体搜索(tools.md search_entities(type, query, filters?) → 匹配实体列表)。
17
+ * 透传 db listEntities:type + name LIKE 模糊匹配 + **软删过滤**(决策 12 修订)
18
+ * + filters(tags AND / status 精确匹配,data 字段 JS 过滤)+ 摘要提取(db 单一实现)。
19
+ * limit 传 200(db clamp 上限):搜索结果尽量全(token 截断由上层按决策 15 处理)。
20
+ */
21
+ export declare function runSearchEntities(ctx: ToolContext, args: SearchEntitiesArgs): SearchEntitiesResult;
22
+ /**
23
+ * 实体聚合统计(tools.md get_entity_summary(type) → 总数、角色分布、能力分布等)。
24
+ * 透传 db getEntitySummaryStats:仅统计非软删实体(决策 12 修订);分布字段按类型
25
+ * 稀疏出现(character→byRole/byStatus/topAbilities、setting→byCategory、
26
+ * location→byType、hook→byStatus/byPayoffTiming),缺字段不报错。
27
+ */
28
+ export declare function runGetEntitySummary(ctx: ToolContext, args: GetEntitySummaryArgs): EntitySummaryStats;
29
+ //# sourceMappingURL=entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../src/query/entity.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACxF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAI/G;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAIjF;AAID,8DAA8D;AAC9D,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,kBAAkB,GAAG,oBAAoB,CAOlG;AAID;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,oBAAoB,GAAG,kBAAkB,CAEpG"}
@@ -0,0 +1,53 @@
1
+ // 查询类工具:实体侧实现(S6.3)
2
+ // get_entity / search_entities / get_entity_summary
3
+ // 契约来源:doc/api/tools.md「实体查询」「聚合分析」;doc/api/endpoints.md 实体端点;
4
+ // 决策 12 修订(查询类工具默认过滤软删对象)。
5
+ //
6
+ // db 层能力确认与分工(S6.3 修复轮:数据访问一律走 db 查询层,工具层无原生 SQL):
7
+ // - get_entity:db getEntity 已过滤软删(决策 12)——工具层直接复用;
8
+ // type 一致性校验(id 前缀体系全局唯一,type 传错 = 参数错误,返回 null 让 LLM 自纠)
9
+ // - search_entities:db listEntities 已扩展 filters(tags/status data 字段 JS 过滤,
10
+ // S6.3 下沉)+ 软删过滤 + 摘要提取单一化(db toSummary)——工具层参数映射透传
11
+ // - get_entity_summary:db getEntitySummaryStats(S6.3 下沉:总数 + 类型专属分布,
12
+ // 稀疏字段知识归拢 db 单一位置)——工具层透传
13
+ import { getEntity as dbGetEntity, getEntitySummaryStats, listEntities } from "@whispering233/ai-editor-db";
14
+ import { mapRowToEntity } from "@whispering233/ai-editor-shared";
15
+ // ============ get_entity ============
16
+ /**
17
+ * 实体详情(tools.md get_entity(type, id) → 实体详情,含 data JSON 解析后的字段)。
18
+ * - db 层 getEntity 默认过滤软删(决策 12 修订:回收站对象不可见)
19
+ * - type 与行内实际类型不一致 → null(参数错误,id 前缀体系下正常调用不会出现;
20
+ * LLM 传错类型时得到「不存在」而非脏数据)
21
+ * - 不存在/已软删 → null(查询无结果 ≠ 失败,LLM 据 null 自纠或向用户确认)
22
+ */
23
+ export function runGetEntity(ctx, args) {
24
+ const row = dbGetEntity(ctx.db, args.id);
25
+ if (row === null || row.type !== args.type)
26
+ return null;
27
+ return mapRowToEntity(row);
28
+ }
29
+ /**
30
+ * 实体搜索(tools.md search_entities(type, query, filters?) → 匹配实体列表)。
31
+ * 透传 db listEntities:type + name LIKE 模糊匹配 + **软删过滤**(决策 12 修订)
32
+ * + filters(tags AND / status 精确匹配,data 字段 JS 过滤)+ 摘要提取(db 单一实现)。
33
+ * limit 传 200(db clamp 上限):搜索结果尽量全(token 截断由上层按决策 15 处理)。
34
+ */
35
+ export function runSearchEntities(ctx, args) {
36
+ return listEntities(ctx.db, {
37
+ type: args.type,
38
+ q: args.query,
39
+ filters: args.filters,
40
+ limit: 200,
41
+ });
42
+ }
43
+ // ============ get_entity_summary ============
44
+ /**
45
+ * 实体聚合统计(tools.md get_entity_summary(type) → 总数、角色分布、能力分布等)。
46
+ * 透传 db getEntitySummaryStats:仅统计非软删实体(决策 12 修订);分布字段按类型
47
+ * 稀疏出现(character→byRole/byStatus/topAbilities、setting→byCategory、
48
+ * location→byType、hook→byStatus/byPayoffTiming),缺字段不报错。
49
+ */
50
+ export function runGetEntitySummary(ctx, args) {
51
+ return getEntitySummaryStats(ctx.db, args.type);
52
+ }
53
+ //# sourceMappingURL=entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/query/entity.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,oDAAoD;AACpD,+DAA+D;AAC/D,6BAA6B;AAC7B,EAAE;AACF,mDAAmD;AACnD,mDAAmD;AACnD,4DAA4D;AAC5D,2EAA2E;AAC3E,sDAAsD;AACtD,qEAAqE;AACrE,6BAA6B;AAE7B,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC5G,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAMjE,uCAAuC;AAEvC;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAgB,EAAE,IAAmB;IAChE,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACzC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACxD,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAOD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAgB,EAAE,IAAwB;IAC1E,OAAO,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE;QAC1B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,CAAC,EAAE,IAAI,CAAC,KAAK;QACb,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,GAAG;KACX,CAAC,CAAC;AACL,CAAC;AAED,+CAA+C;AAE/C;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAgB,EAAE,IAA0B;IAC9E,OAAO,qBAAqB,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { OutlineTree } from "@whispering233/ai-editor-shared";
2
+ import type { ToolContext } from "../context.js";
3
+ import type { GetOutlinePathArgs } from "@whispering233/ai-editor-shared";
4
+ /**
5
+ * 完整大纲树(tools.md get_outline() → 严格三层树,决策 19)。
6
+ * - 默认不含 metadata 统计(省 token;需统计走 API GET /outline?with_metadata=)
7
+ * - 软删节点过滤(决策 12 修订)
8
+ * - 返回 API 形态 OutlineTree(camelCase;data 嵌套字段原样透传)
9
+ * 无参工具:签名省略 args(少参数赋值兼容 ToolDefinition.run,避免未使用参数 lint)
10
+ */
11
+ export declare function runGetOutline(ctx: ToolContext): OutlineTree;
12
+ /**
13
+ * 根 → 目标节点的路径 ID 列表(tools.md get_outline_path(node_id),含 root,
14
+ * 如 ["root", "vol-1", "ch-3", "sc-15"];严格三层下路径唯一,决策 19)。
15
+ * - 节点不存在 → null(db getOutlinePathIds 抛错,工具层转查询无结果)
16
+ * - 路径上任一节点软删 → null(决策 12 修订:软删对象不可见——目标节点软删时
17
+ * 其路径对 AI 无意义;防御手改 outline.json 产生的祖先软删不一致)
18
+ */
19
+ export declare function runGetOutlinePath(ctx: ToolContext, args: GetOutlinePathArgs): string[] | null;
20
+ //# sourceMappingURL=outline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../src/query/outline.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAmB,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAkB1E;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,WAAW,CAI3D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,kBAAkB,GAAG,MAAM,EAAE,GAAG,IAAI,CAc7F"}