@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.
- package/dist/analysis/conflict.d.ts +20 -0
- package/dist/analysis/conflict.d.ts.map +1 -0
- package/dist/analysis/conflict.js +116 -0
- package/dist/analysis/conflict.js.map +1 -0
- package/dist/analysis/consistency.d.ts +28 -0
- package/dist/analysis/consistency.d.ts.map +1 -0
- package/dist/analysis/consistency.js +108 -0
- package/dist/analysis/consistency.js.map +1 -0
- package/dist/analysis/hook.d.ts +157 -0
- package/dist/analysis/hook.d.ts.map +1 -0
- package/dist/analysis/hook.js +381 -0
- package/dist/analysis/hook.js.map +1 -0
- package/dist/analysis/orphan.d.ts +60 -0
- package/dist/analysis/orphan.d.ts.map +1 -0
- package/dist/analysis/orphan.js +153 -0
- package/dist/analysis/orphan.js.map +1 -0
- package/dist/analysis/path.d.ts +23 -0
- package/dist/analysis/path.d.ts.map +1 -0
- package/dist/analysis/path.js +114 -0
- package/dist/analysis/path.js.map +1 -0
- package/dist/analysis/suggest.d.ts +19 -0
- package/dist/analysis/suggest.d.ts.map +1 -0
- package/dist/analysis/suggest.js +92 -0
- package/dist/analysis/suggest.js.map +1 -0
- package/dist/analysis/utils.d.ts +54 -0
- package/dist/analysis/utils.d.ts.map +1 -0
- package/dist/analysis/utils.js +123 -0
- package/dist/analysis/utils.js.map +1 -0
- package/dist/context.d.ts +10 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +11 -0
- package/dist/context.js.map +1 -0
- package/dist/executor/delta.d.ts +4 -0
- package/dist/executor/delta.d.ts.map +1 -0
- package/dist/executor/delta.js +22 -0
- package/dist/executor/delta.js.map +1 -0
- package/dist/executor/entity.d.ts +8 -0
- package/dist/executor/entity.d.ts.map +1 -0
- package/dist/executor/entity.js +47 -0
- package/dist/executor/entity.js.map +1 -0
- package/dist/executor/hook.d.ts +8 -0
- package/dist/executor/hook.d.ts.map +1 -0
- package/dist/executor/hook.js +183 -0
- package/dist/executor/hook.js.map +1 -0
- package/dist/executor/index.d.ts +22 -0
- package/dist/executor/index.d.ts.map +1 -0
- package/dist/executor/index.js +89 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/executor/outline.d.ts +8 -0
- package/dist/executor/outline.d.ts.map +1 -0
- package/dist/executor/outline.js +39 -0
- package/dist/executor/outline.js.map +1 -0
- package/dist/executor/relation.d.ts +6 -0
- package/dist/executor/relation.d.ts.map +1 -0
- package/dist/executor/relation.js +33 -0
- package/dist/executor/relation.js.map +1 -0
- package/dist/executor/types.d.ts +25 -0
- package/dist/executor/types.d.ts.map +1 -0
- package/dist/executor/types.js +54 -0
- package/dist/executor/types.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +359 -0
- package/dist/index.js.map +1 -0
- package/dist/proposal/delta.d.ts +8 -0
- package/dist/proposal/delta.d.ts.map +1 -0
- package/dist/proposal/delta.js +29 -0
- package/dist/proposal/delta.js.map +1 -0
- package/dist/proposal/entity.d.ts +16 -0
- package/dist/proposal/entity.d.ts.map +1 -0
- package/dist/proposal/entity.js +54 -0
- package/dist/proposal/entity.js.map +1 -0
- package/dist/proposal/hook.d.ts +24 -0
- package/dist/proposal/hook.d.ts.map +1 -0
- package/dist/proposal/hook.js +81 -0
- package/dist/proposal/hook.js.map +1 -0
- package/dist/proposal/outline.d.ts +24 -0
- package/dist/proposal/outline.d.ts.map +1 -0
- package/dist/proposal/outline.js +78 -0
- package/dist/proposal/outline.js.map +1 -0
- package/dist/proposal/relation.d.ts +12 -0
- package/dist/proposal/relation.d.ts.map +1 -0
- package/dist/proposal/relation.js +50 -0
- package/dist/proposal/relation.js.map +1 -0
- package/dist/proposal/types.d.ts +72 -0
- package/dist/proposal/types.d.ts.map +1 -0
- package/dist/proposal/types.js +105 -0
- package/dist/proposal/types.js.map +1 -0
- package/dist/query/delta.d.ts +20 -0
- package/dist/query/delta.d.ts.map +1 -0
- package/dist/query/delta.js +41 -0
- package/dist/query/delta.js.map +1 -0
- package/dist/query/entity.d.ts +29 -0
- package/dist/query/entity.d.ts.map +1 -0
- package/dist/query/entity.js +53 -0
- package/dist/query/entity.js.map +1 -0
- package/dist/query/outline.d.ts +20 -0
- package/dist/query/outline.d.ts.map +1 -0
- package/dist/query/outline.js +68 -0
- package/dist/query/outline.js.map +1 -0
- package/dist/query/relation.d.ts +12 -0
- package/dist/query/relation.d.ts.map +1 -0
- package/dist/query/relation.js +30 -0
- package/dist/query/relation.js.map +1 -0
- package/dist/registry.d.ts +41 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +46 -0
- package/dist/registry.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// 执行类工具:伏笔生命周期复合写(S6.7,tools.md「执行类」3 个)
|
|
2
|
+
// advance_hook / resolve_hook / abandon_hook
|
|
3
|
+
//
|
|
4
|
+
// **复合写(2026-08 修订,tools.md「复合写说明」)**:确认后封装「delta 插入 + relation 插入」
|
|
5
|
+
// 两步写为**一次提交**(withTransaction),失败整体回滚、不产生半状态。
|
|
6
|
+
// - advance_hook:delta_records 记 status → progressing + relation_records 插 advances
|
|
7
|
+
// - resolve_hook:delta_records 记 status → resolved + relation_records 插 resolves
|
|
8
|
+
// - abandon_hook:仅 delta_records 记 status → abandoned(tools.md:无 relation;args 无 node_id)
|
|
9
|
+
//
|
|
10
|
+
// **幂等**:先查 (node_id, hook_id, relation_type) 是否已有未软删记录,存在即返回已有 id
|
|
11
|
+
// (不重复写)——重复确认/重复提案均不重复推进;abandon 无关系可查,改查「已记
|
|
12
|
+
// status=abandoned 的 delta」(同语义:不重复写废弃记录;**JSON 解析精确判定**,见
|
|
13
|
+
// findExistingStatusDeltaId——避免 LIKE 误命中其他字段的 to=abandoned)。
|
|
14
|
+
// **边界**:advance/resolve 幂等只查关系记录,不查 delta——关系被**手动物理删**(决策 12:
|
|
15
|
+
// 手动删关系不走回收站、物理删)后重复确认会再写一条 delta + relation(幂等失效但语义
|
|
16
|
+
// 自洽:关系已不存在,重写即恢复;delta 的 from 取当前 data.status,链条不破)。
|
|
17
|
+
//
|
|
18
|
+
// 变更形态(hooks.md「伏笔状态变化」):changes = [{ field: "status", op: "update",
|
|
19
|
+
// from: 当前状态, to: 目标状态 }]——from 取 hook.data.status(缺省 planted,决策 21 口径:
|
|
20
|
+
// 状态缺失视为 planted),保证 computeState 的 update 校验(决策 9)正常累积;
|
|
21
|
+
// description 取 proposal.args.description(delta_records.description NOT NULL)。
|
|
22
|
+
// 终态守卫:resolved/abandoned 为生命周期终态(hooks.md),终态伏笔不可再推进/回收/废弃。
|
|
23
|
+
//
|
|
24
|
+
// **状态同步(S6.7 修复轮必须改)**:复合写事务内插入 delta 后**同步更新
|
|
25
|
+
// entities.data.status**(浅合并 + 刷新 updated_at,与决策 14 快照比对语义兼容)——
|
|
26
|
+
// 终态守卫(assertNotTerminal)、delta 的 from(currentHookStatus)与 S6.5 hookStatuses
|
|
27
|
+
// (analysis/hook.ts collectHooks 读 entity.data.status)均以 data.status 为唯一事实来源
|
|
28
|
+
// (决策 21 口径);不同步则 resolved/abandoned 后仍可推进、同 hook 二次推进 from 断裂
|
|
29
|
+
// (computeState conflicts)、已回收伏笔仍计 active。**幂等命中路径不更新**(首次执行已同步)。
|
|
30
|
+
//
|
|
31
|
+
// 执行类是短同步事务,不做 signal 检查(决策 16 ③:长工具才要求执行中检查;入口检查由
|
|
32
|
+
// S7.5 确认路由承担)。
|
|
33
|
+
import { createRelation, findOutlineNode, insertDelta, readOutlineFile, readProjectFile, updateEntity, withTransaction } from "@whispering233/ai-editor-db";
|
|
34
|
+
import { requireHook, requireOutlineNode } from "../proposal/types.js";
|
|
35
|
+
import { requireString } from "./types.js";
|
|
36
|
+
/** 伏笔生命周期终态(hooks.md:planted → progressing → resolved 或 abandoned) */
|
|
37
|
+
const TERMINAL_STATUSES = ["resolved", "abandoned"];
|
|
38
|
+
/** 取伏笔当前状态(data.status 缺失/空串 → planted——创建即埋设,决策 21 口径) */
|
|
39
|
+
function currentHookStatus(hook) {
|
|
40
|
+
const status = hook.data.status;
|
|
41
|
+
return typeof status === "string" && status !== "" ? status : "planted";
|
|
42
|
+
}
|
|
43
|
+
/** 终态守卫:终态伏笔不可再推进/回收/废弃(生命周期语义,hooks.md) */
|
|
44
|
+
function assertNotTerminal(hook, actionLabel) {
|
|
45
|
+
const status = currentHookStatus(hook);
|
|
46
|
+
if (TERMINAL_STATUSES.includes(status)) {
|
|
47
|
+
throw new Error(`伏笔已处于终态 ${status},无法${actionLabel}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 幂等查询(advance/resolve):同 (node_id, hook_id, relation_type) 已有**未软删**记录
|
|
52
|
+
* → 返回其 id(tools.md 复合写说明:重复确认/重复提案均不重复推进;含端点软删后还原的
|
|
53
|
+
* 记录——deleted_at 置 NULL 后仍命中)。
|
|
54
|
+
*/
|
|
55
|
+
function findExistingLifecycleRelation(db, nodeId, hookId, relationType) {
|
|
56
|
+
const row = db
|
|
57
|
+
.prepare("SELECT id FROM relation_records WHERE source_id = ? AND target_id = ? AND relation_type = ? AND deleted_at IS NULL")
|
|
58
|
+
.get(nodeId, hookId, relationType);
|
|
59
|
+
return row?.id ?? null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 幂等查询(abandon):已存在记 status=abandoned 的未软删 delta → 返回其 id
|
|
63
|
+
* (abandon 无 node_id/关系可查,改按 delta 内容判重——同「不重复写」语义)。
|
|
64
|
+
* changes 列为 JSON 字符串,**逐行 JSON 解析精确判定**(S6.7 修复轮:不用 LIKE 文本
|
|
65
|
+
* 形态——`%"to":"abandoned"%` 会误命中任意字段的该值,如 {field:"category", to:"abandoned"}):
|
|
66
|
+
* 任一 change 为 { field: "status", to: toStatus } 即命中(新写 delta 必带该形态);
|
|
67
|
+
* 坏 JSON 行跳过(脏数据防御)。取最新一条(order DESC,与原 LIMIT 1 语义一致)。
|
|
68
|
+
*/
|
|
69
|
+
function findExistingStatusDeltaId(db, hookId, toStatus) {
|
|
70
|
+
const rows = db
|
|
71
|
+
.prepare('SELECT id, changes FROM delta_records WHERE target_id = ? AND deleted_at IS NULL ORDER BY "order" DESC')
|
|
72
|
+
.all(hookId);
|
|
73
|
+
for (const row of rows) {
|
|
74
|
+
let changes;
|
|
75
|
+
try {
|
|
76
|
+
changes = JSON.parse(row.changes);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
continue; // 坏 JSON:跳过该行继续查(不误判)
|
|
80
|
+
}
|
|
81
|
+
const hit = Array.isArray(changes) && changes.some((c) => {
|
|
82
|
+
if (c === null || typeof c !== "object")
|
|
83
|
+
return false;
|
|
84
|
+
const change = c;
|
|
85
|
+
return change.field === "status" && change.to === toStatus;
|
|
86
|
+
});
|
|
87
|
+
if (hit)
|
|
88
|
+
return row.id;
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* abandon 的 delta 锚定节点:废弃是主动放弃(无指定节点,propose_abandon_hook 仅 hook_id +
|
|
94
|
+
* description)——取 project.json current_position(决策 21「当前章节」锚点,存在且未软删);
|
|
95
|
+
* 未设置/失效则退化取树末节点(当前写作进度末端);大纲空树 → 抛错(无锚点不可记录)。
|
|
96
|
+
*/
|
|
97
|
+
function anchorNodeForAbandon(ctx) {
|
|
98
|
+
const config = readProjectFile(ctx.outlineDir);
|
|
99
|
+
if (config !== null && config.current_position !== null && config.current_position !== "") {
|
|
100
|
+
const node = findOutlineNode(readOutlineFile(ctx.outlineDir), config.current_position);
|
|
101
|
+
if (node !== undefined && node.deleted !== true)
|
|
102
|
+
return config.current_position;
|
|
103
|
+
}
|
|
104
|
+
const tree = readOutlineFile(ctx.outlineDir);
|
|
105
|
+
// 树末节点:先序遍历最后一个叶子(卷→章→场景的最深最后节点)
|
|
106
|
+
let last = null;
|
|
107
|
+
const visit = (node) => {
|
|
108
|
+
if (node.deleted === true)
|
|
109
|
+
return;
|
|
110
|
+
last = node.id;
|
|
111
|
+
const kids = node.children;
|
|
112
|
+
if (kids !== undefined) {
|
|
113
|
+
for (const kid of kids)
|
|
114
|
+
visit(kid);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
for (const child of tree.children)
|
|
118
|
+
visit(child);
|
|
119
|
+
if (last === null) {
|
|
120
|
+
throw new Error("大纲无可用节点,无法记录伏笔废弃位置");
|
|
121
|
+
}
|
|
122
|
+
return last;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 复合写公共骨架(advance/resolve/abandon 共用):
|
|
126
|
+
* 幂等判重 → 校验(伏笔/节点存在且未软删 + 终态守卫)→ delta 插入 → relation 插入,
|
|
127
|
+
* **withTransaction 一次提交**——任一步抛错整体回滚(失败不产生半状态)。
|
|
128
|
+
* @param relationType advance/resolve 插入的关系类型;abandon 传 null(无关系)
|
|
129
|
+
* @param toStatus delta 记入的目标状态(progressing/resolved/abandoned)
|
|
130
|
+
*/
|
|
131
|
+
function executeHookTransition(ctx, proposal, relationType, toStatus, actionLabel) {
|
|
132
|
+
const args = proposal.args;
|
|
133
|
+
const hookId = requireString(args, "hook_id");
|
|
134
|
+
const nodeId = relationType === null ? null : requireString(args, "node_id");
|
|
135
|
+
const description = requireString(args, "description"); // delta_records.description NOT NULL(tools.md)
|
|
136
|
+
return withTransaction(ctx.db, () => {
|
|
137
|
+
// 幂等(含未软删记录):命中即返回已有 id,不重复写
|
|
138
|
+
if (relationType !== null) {
|
|
139
|
+
const existing = findExistingLifecycleRelation(ctx.db, nodeId, hookId, relationType);
|
|
140
|
+
if (existing !== null)
|
|
141
|
+
return { id: existing, duplicated: true };
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
const existing = findExistingStatusDeltaId(ctx.db, hookId, toStatus);
|
|
145
|
+
if (existing !== null)
|
|
146
|
+
return { id: existing, duplicated: true };
|
|
147
|
+
}
|
|
148
|
+
// 校验:伏笔存在且 type=hook;推进/回收节点存在且未软删(决策 12)
|
|
149
|
+
const hook = requireHook(ctx, hookId);
|
|
150
|
+
if (nodeId !== null)
|
|
151
|
+
requireOutlineNode(ctx, nodeId);
|
|
152
|
+
// 终态守卫(resolved/abandoned 不可再推进/回收;废弃时不可再废弃)
|
|
153
|
+
assertNotTerminal(hook, actionLabel);
|
|
154
|
+
// delta:记 status 变化(from=当前状态,决策 9 update 语义,computeState 正常累积)
|
|
155
|
+
const changes = [{ field: "status", op: "update", from: currentHookStatus(hook), to: toStatus }];
|
|
156
|
+
const delta = insertDelta(ctx.db, {
|
|
157
|
+
nodeId: nodeId ?? anchorNodeForAbandon(ctx),
|
|
158
|
+
targetType: "hook",
|
|
159
|
+
targetId: hookId,
|
|
160
|
+
changes,
|
|
161
|
+
description,
|
|
162
|
+
});
|
|
163
|
+
// **状态同步(S6.7 修复轮必须改)**:同一事务内浅合并更新 entities.data.status
|
|
164
|
+
// (updateEntity 内部 withTransaction → 嵌套自动升级 SAVEPOINT,整体仍一次提交):
|
|
165
|
+
// 终态守卫 / delta 的 from / S6.5 hookStatuses 均读 data.status——不落地则 resolved 后
|
|
166
|
+
// 仍可推进(守卫失效)、同 hook 二次推进 from 断裂(computeState conflicts)、
|
|
167
|
+
// 已回收伏笔仍计 active。幂等命中路径(上方 early return)不更新——首次执行已同步。
|
|
168
|
+
updateEntity(ctx.db, hookId, { data: { status: toStatus } });
|
|
169
|
+
// relation:advances / resolves(大纲节点 → hook;hooks.md 方向约定)
|
|
170
|
+
if (relationType !== null) {
|
|
171
|
+
const relation = createRelation(ctx.db, { sourceType: "outline_node", sourceId: nodeId, targetType: "hook", targetId: hookId, relationType }, ctx.outlineDir);
|
|
172
|
+
return { id: relation.id };
|
|
173
|
+
}
|
|
174
|
+
return { id: delta.id };
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/** advance_hook(tools.md:advance_hook(hook_id, node_id, description) → id) */
|
|
178
|
+
export const executeAdvanceHook = (ctx, proposal) => executeHookTransition(ctx, proposal, "advances", "progressing", "推进");
|
|
179
|
+
/** resolve_hook(tools.md:resolve_hook(hook_id, node_id, description) → id) */
|
|
180
|
+
export const executeResolveHook = (ctx, proposal) => executeHookTransition(ctx, proposal, "resolves", "resolved", "回收");
|
|
181
|
+
/** abandon_hook(tools.md:abandon_hook(hook_id, description) → id;仅 delta 记 status=abandoned) */
|
|
182
|
+
export const executeAbandonHook = (ctx, proposal) => executeHookTransition(ctx, proposal, null, "abandoned", "废弃");
|
|
183
|
+
//# sourceMappingURL=hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/executor/hook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { EXECUTOR_TOOLS, PROPOSAL_TOOLS } from "@whispering233/ai-editor-shared";
|
|
2
|
+
import type { ToolContext } from "../context.js";
|
|
3
|
+
import type { Proposal } from "../proposal/types.js";
|
|
4
|
+
import { type ExecutorResult } from "./types.js";
|
|
5
|
+
/** 提案类型字面量联合(14 个,PROPOSAL_TOOLS 常量派生——注册表/门面共用契约) */
|
|
6
|
+
export type ProposalType = (typeof PROPOSAL_TOOLS)[number];
|
|
7
|
+
/** 执行工具名字面量联合(12 个,EXECUTOR_TOOLS 常量派生) */
|
|
8
|
+
export type ExecutorToolName = (typeof EXECUTOR_TOOLS)[number];
|
|
9
|
+
/**
|
|
10
|
+
* 执行提案(S7.5 确认后调用):按 proposal.type 映射执行函数,args 透传(S6.6 已规范化
|
|
11
|
+
* 为执行形态),返回执行结果(如新 id)。未知/缺失映射抛错(防静默——不该出现的
|
|
12
|
+
* 提案类型说明上层调度 bug)。
|
|
13
|
+
*/
|
|
14
|
+
export declare function executeProposal(ctx: ToolContext, proposal: Proposal): ExecutorResult;
|
|
15
|
+
export type { ExecutorFn, ExecutorResult } from "./types.js";
|
|
16
|
+
export { executeCreateEntity, executeUpdateEntity, executeDeleteEntity } from "./entity.js";
|
|
17
|
+
export { executeAddRelation, executeRemoveRelation } from "./relation.js";
|
|
18
|
+
export { executeAddDelta } from "./delta.js";
|
|
19
|
+
export { executeCreateOutlineNode, executeMoveNode, executeDeleteNode } from "./outline.js";
|
|
20
|
+
export { executeAdvanceHook, executeResolveHook, executeAbandonHook } from "./hook.js";
|
|
21
|
+
export { EXECUTOR_TOOLS };
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/executor/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMrD,OAAO,EAAkD,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjG,sDAAsD;AACtD,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,2CAA2C;AAC3C,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAsD/D;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAMpF;AAGD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// executor 门面(S6.7):executeProposal(ctx, proposal)——提案确认后的执行入口
|
|
2
|
+
//
|
|
3
|
+
// 按 proposal.type 映射执行函数(PROPOSAL_TOOLS 名 ↔ EXECUTOR_TOOLS 名):
|
|
4
|
+
// propose_create_entity → create_entity、propose_add_relation → add_relation、
|
|
5
|
+
// propose_advance_hook → advance_hook 等(14 提案 → 12 执行);
|
|
6
|
+
// propose_create_hook / propose_update_hook 为适配器(hook 即 type=hook 的实体):
|
|
7
|
+
// - propose_create_hook → create_entity 注入 type="hook" + plant_at_node_id 时
|
|
8
|
+
// 同事务补插 plants 关系(提案承诺「确认后建立 plants 关系」,hooks.md 生命周期「埋下」)
|
|
9
|
+
// - propose_update_hook → update_entity(hook_id 即 entity_id,patches 浅合并进 data)
|
|
10
|
+
//
|
|
11
|
+
// **不注册 registry**:执行类是用户确认后由本门面调用的底层写路径,**不暴露给 LLM**
|
|
12
|
+
// (tools.md「核心设计原则」——AI 不可以调用执行类工具)。
|
|
13
|
+
// 映射表类型安全:key 为 14 个提案类型字面量联合(Record 缺键编译期报错);
|
|
14
|
+
// 运行时未知 type → 查表 undefined → 抛错(防静默,S7.5 转错误响应)。
|
|
15
|
+
// signal:执行类是短同步事务,不做中止检查(决策 16 ③ 只要求长工具执行中检查;
|
|
16
|
+
// S7.5 确认路由在调用前做取消判定)。
|
|
17
|
+
import { createEntity, createRelation, withTransaction } from "@whispering233/ai-editor-db";
|
|
18
|
+
import { EXECUTOR_TOOLS } from "@whispering233/ai-editor-shared";
|
|
19
|
+
import { requireHook, requireOutlineNode } from "../proposal/types.js";
|
|
20
|
+
import { executeAddDelta } from "./delta.js";
|
|
21
|
+
import { executeCreateEntity, executeDeleteEntity, executeUpdateEntity } from "./entity.js";
|
|
22
|
+
import { executeAddRelation, executeRemoveRelation } from "./relation.js";
|
|
23
|
+
import { executeCreateOutlineNode, executeDeleteNode, executeMoveNode } from "./outline.js";
|
|
24
|
+
import { executeAbandonHook, executeAdvanceHook, executeResolveHook } from "./hook.js";
|
|
25
|
+
import { optionalRecord, requireString } from "./types.js";
|
|
26
|
+
/** 适配 propose_create_hook → 复合建 hook:create_entity(type=hook) + plants 关系一次提交 */
|
|
27
|
+
const executeCreateHook = (ctx, proposal) => {
|
|
28
|
+
const args = proposal.args;
|
|
29
|
+
const name = requireString(args, "name");
|
|
30
|
+
const data = optionalRecord(args, "data");
|
|
31
|
+
const plantAtNodeId = args.plant_at_node_id === undefined ? undefined : requireString(args, "plant_at_node_id");
|
|
32
|
+
return withTransaction(ctx.db, () => {
|
|
33
|
+
const row = createEntity(ctx.db, { type: "hook", name, data });
|
|
34
|
+
if (plantAtNodeId !== undefined) {
|
|
35
|
+
requireOutlineNode(ctx, plantAtNodeId); // 埋设节点存在且未软删(决策 12;createRelation 亦校验)
|
|
36
|
+
createRelation(ctx.db, { sourceType: "outline_node", sourceId: plantAtNodeId, targetType: "hook", targetId: row.id, relationType: "plants" }, ctx.outlineDir);
|
|
37
|
+
}
|
|
38
|
+
return { id: row.id };
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
/** 适配 propose_update_hook → update_entity:hook_id 即 entity_id(hook 是实体的一种) */
|
|
42
|
+
const executeUpdateHook = (ctx, proposal) => {
|
|
43
|
+
const args = proposal.args;
|
|
44
|
+
const hookId = requireString(args, "hook_id");
|
|
45
|
+
// 复核实体类型(S6.7 修复轮建议 4):委托 update_entity 前再 requireHook 一次——
|
|
46
|
+
// 防御纵深,与 create_hook 适配器同风格(提案层 zod 已校验,此处防类型漂移/绕过)
|
|
47
|
+
requireHook(ctx, hookId);
|
|
48
|
+
return executeUpdateEntity(ctx, { ...proposal, args: { entity_id: hookId, patches: args.patches } });
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* 提案类型 → 执行函数映射表(S6.7 门面核心)。
|
|
52
|
+
* 类型安全:key 为 ProposalType 字面量联合,缺映射编译期报错;values 均为
|
|
53
|
+
* (ctx, proposal) → ExecutorResult 的执行函数/适配器。
|
|
54
|
+
*/
|
|
55
|
+
const EXECUTE_BY_PROPOSAL_TYPE = {
|
|
56
|
+
propose_create_entity: executeCreateEntity,
|
|
57
|
+
propose_update_entity: executeUpdateEntity,
|
|
58
|
+
propose_delete_entity: executeDeleteEntity,
|
|
59
|
+
propose_add_relation: executeAddRelation,
|
|
60
|
+
propose_remove_relation: executeRemoveRelation,
|
|
61
|
+
propose_add_delta: executeAddDelta,
|
|
62
|
+
propose_outline_node: executeCreateOutlineNode,
|
|
63
|
+
propose_move_node: executeMoveNode,
|
|
64
|
+
propose_delete_node: executeDeleteNode,
|
|
65
|
+
propose_create_hook: executeCreateHook,
|
|
66
|
+
propose_update_hook: executeUpdateHook,
|
|
67
|
+
propose_advance_hook: executeAdvanceHook,
|
|
68
|
+
propose_resolve_hook: executeResolveHook,
|
|
69
|
+
propose_abandon_hook: executeAbandonHook,
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* 执行提案(S7.5 确认后调用):按 proposal.type 映射执行函数,args 透传(S6.6 已规范化
|
|
73
|
+
* 为执行形态),返回执行结果(如新 id)。未知/缺失映射抛错(防静默——不该出现的
|
|
74
|
+
* 提案类型说明上层调度 bug)。
|
|
75
|
+
*/
|
|
76
|
+
export function executeProposal(ctx, proposal) {
|
|
77
|
+
const fn = EXECUTE_BY_PROPOSAL_TYPE[proposal.type];
|
|
78
|
+
if (fn === undefined) {
|
|
79
|
+
throw new Error(`executeProposal: 未知提案类型 ${proposal.type}`);
|
|
80
|
+
}
|
|
81
|
+
return fn(ctx, proposal);
|
|
82
|
+
}
|
|
83
|
+
export { executeCreateEntity, executeUpdateEntity, executeDeleteEntity } from "./entity.js";
|
|
84
|
+
export { executeAddRelation, executeRemoveRelation } from "./relation.js";
|
|
85
|
+
export { executeAddDelta } from "./delta.js";
|
|
86
|
+
export { executeCreateOutlineNode, executeMoveNode, executeDeleteNode } from "./outline.js";
|
|
87
|
+
export { executeAdvanceHook, executeResolveHook, executeAbandonHook } from "./hook.js";
|
|
88
|
+
export { EXECUTOR_TOOLS };
|
|
89
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/executor/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ExecutorFn } from "./types.js";
|
|
2
|
+
/** create_outline_node(tools.md:create_outline_node(type, title, parent) → id) */
|
|
3
|
+
export declare const executeCreateOutlineNode: ExecutorFn;
|
|
4
|
+
/** move_node(tools.md:move_node(node_id, parent, order) → void;parent 可为 root,决策 19) */
|
|
5
|
+
export declare const executeMoveNode: ExecutorFn;
|
|
6
|
+
/** delete_node(tools.md:delete_node(node_id) → void;软删 + 递归子树,决策 12) */
|
|
7
|
+
export declare const executeDeleteNode: ExecutorFn;
|
|
8
|
+
//# sourceMappingURL=outline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../src/executor/outline.ts"],"names":[],"mappings":"AAWA,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE3E,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,EAAE,UAUtC,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,eAAe,EAAE,UAa7B,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,EAAE,UAI/B,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// 执行类工具:大纲(S6.7,tools.md「执行类」3 个)
|
|
2
|
+
// create_outline_node / move_node / delete_node
|
|
3
|
+
//
|
|
4
|
+
// 写路径:直接调 db outline-ops(唯一写路径;outline.json 原子写由 db 层保证,决策 11);
|
|
5
|
+
// updatedAt 由应用层 nowIso() 传入(时间约定:ISO 8601 应用层写入,模块不生成时间)。
|
|
6
|
+
// 层级约束(决策 19 严格三层)由 db assertCanHold 兜底:scene 挂 chapter、chapter 挂卷/根、
|
|
7
|
+
// volume 挂根;parent_id 缺省挂 root(volume/chapter 可挂根,scene 缺省即拒绝——与提案层同语义)。
|
|
8
|
+
// 软删语义(决策 12):delete_node 软删 + 递归子树(本体保留可回收站还原)。
|
|
9
|
+
import { createOutlineNode, deleteOutlineNode, moveOutlineNode, nowIso } from "@whispering233/ai-editor-db";
|
|
10
|
+
import { requireNumber, requireString } from "./types.js";
|
|
11
|
+
/** create_outline_node(tools.md:create_outline_node(type, title, parent) → id) */
|
|
12
|
+
export const executeCreateOutlineNode = (ctx, proposal) => {
|
|
13
|
+
const args = proposal.args;
|
|
14
|
+
const parentId = args.parent_id === undefined ? "root" : requireString(args, "parent_id"); // 缺省挂根(决策 19)
|
|
15
|
+
const node = createOutlineNode(ctx.outlineDir, {
|
|
16
|
+
type: requireString(args, "type"),
|
|
17
|
+
title: requireString(args, "title"),
|
|
18
|
+
parentId,
|
|
19
|
+
updatedAt: nowIso(),
|
|
20
|
+
});
|
|
21
|
+
return { id: node.id };
|
|
22
|
+
};
|
|
23
|
+
/** move_node(tools.md:move_node(node_id, parent, order) → void;parent 可为 root,决策 19) */
|
|
24
|
+
export const executeMoveNode = (ctx, proposal) => {
|
|
25
|
+
const args = proposal.args;
|
|
26
|
+
const nodeId = requireString(args, "node_id");
|
|
27
|
+
const result = moveOutlineNode(ctx.outlineDir, nodeId, {
|
|
28
|
+
parentId: requireString(args, "parent_id"),
|
|
29
|
+
order: requireNumber(args, "order"), // 越界由 db clamp(0..children.length)
|
|
30
|
+
}, nowIso());
|
|
31
|
+
return { id: nodeId, ...result };
|
|
32
|
+
};
|
|
33
|
+
/** delete_node(tools.md:delete_node(node_id) → void;软删 + 递归子树,决策 12) */
|
|
34
|
+
export const executeDeleteNode = (ctx, proposal) => {
|
|
35
|
+
const nodeId = requireString(proposal.args, "node_id");
|
|
36
|
+
const { children } = deleteOutlineNode(ctx.outlineDir, nodeId, nowIso());
|
|
37
|
+
return { id: nodeId, deleted: true, cascadedChildren: children };
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=outline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outline.js","sourceRoot":"","sources":["../../src/executor/outline.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,gDAAgD;AAChD,EAAE;AACF,gEAAgE;AAChE,2DAA2D;AAC3D,sEAAsE;AACtE,yEAAyE;AACzE,iDAAiD;AAEjD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE5G,OAAO,EAAE,aAAa,EAAE,aAAa,EAAmB,MAAM,YAAY,CAAC;AAE3E,kFAAkF;AAClF,MAAM,CAAC,MAAM,wBAAwB,GAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;IACpE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,cAAc;IACzG,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,CAAC,UAAU,EAAE;QAC7C,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,MAAM,CAAqC;QACrE,KAAK,EAAE,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC;QACnC,QAAQ;QACR,SAAS,EAAE,MAAM,EAAE;KACpB,CAAC,CAAC;IACH,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AACzB,CAAC,CAAC;AAEF,wFAAwF;AACxF,MAAM,CAAC,MAAM,eAAe,GAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;IAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,eAAe,CAC5B,GAAG,CAAC,UAAU,EACd,MAAM,EACN;QACE,QAAQ,EAAE,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC;QAC1C,KAAK,EAAE,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,mCAAmC;KACzE,EACD,MAAM,EAAE,CACT,CAAC;IACF,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;AACnC,CAAC,CAAC;AAEF,wEAAwE;AACxE,MAAM,CAAC,MAAM,iBAAiB,GAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;IAC7D,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACvD,MAAM,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC;AACnE,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ExecutorFn } from "./types.js";
|
|
2
|
+
/** add_relation(tools.md:add_relation(source, target, type) → id) */
|
|
3
|
+
export declare const executeAddRelation: ExecutorFn;
|
|
4
|
+
/** remove_relation(tools.md:remove_relation(id) → void;物理删,决策 12 修订) */
|
|
5
|
+
export declare const executeRemoveRelation: ExecutorFn;
|
|
6
|
+
//# sourceMappingURL=relation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation.d.ts","sourceRoot":"","sources":["../../src/executor/relation.ts"],"names":[],"mappings":"AAUA,OAAO,EAAiC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5E,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,EAAE,UAehC,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAE,UAOnC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// 执行类工具:关系(S6.7,tools.md「执行类」2 个)
|
|
2
|
+
// add_relation / remove_relation
|
|
3
|
+
//
|
|
4
|
+
// - add_relation:端点类型(source_type/target_type)已由 S6.6 提案层派生规范化到 args,
|
|
5
|
+
// 此处直接透传 db createRelation(判重 RELATION_EXISTS / 端点存在性校验 db 层负责);
|
|
6
|
+
// 重复确认同一 add_relation 提案 → RELATION_EXISTS 抛错(幂等只保证 hook 复合写,tools.md)
|
|
7
|
+
// - remove_relation:手动删关系 = **物理删**(决策 12 修订:不置 deleted_at、不进回收站);
|
|
8
|
+
// 0 行影响(关系不存在)→ 抛错(fail-fast,S7.5 转错误响应)
|
|
9
|
+
import { createRelation, deleteRelation } from "@whispering233/ai-editor-db";
|
|
10
|
+
import { optionalRecord, requireString } from "./types.js";
|
|
11
|
+
/** add_relation(tools.md:add_relation(source, target, type) → id) */
|
|
12
|
+
export const executeAddRelation = (ctx, proposal) => {
|
|
13
|
+
const args = proposal.args;
|
|
14
|
+
const row = createRelation(ctx.db, {
|
|
15
|
+
sourceType: requireString(args, "source_type"),
|
|
16
|
+
sourceId: requireString(args, "source_id"),
|
|
17
|
+
targetType: requireString(args, "target_type"),
|
|
18
|
+
targetId: requireString(args, "target_id"),
|
|
19
|
+
relationType: requireString(args, "relation_type"),
|
|
20
|
+
metadata: optionalRecord(args, "metadata"),
|
|
21
|
+
}, ctx.outlineDir);
|
|
22
|
+
return { id: row.id };
|
|
23
|
+
};
|
|
24
|
+
/** remove_relation(tools.md:remove_relation(id) → void;物理删,决策 12 修订) */
|
|
25
|
+
export const executeRemoveRelation = (ctx, proposal) => {
|
|
26
|
+
const relationId = requireString(proposal.args, "relation_id");
|
|
27
|
+
const changes = deleteRelation(ctx.db, relationId);
|
|
28
|
+
if (changes === 0) {
|
|
29
|
+
throw new Error(`关系不存在: ${relationId}`);
|
|
30
|
+
}
|
|
31
|
+
return { id: relationId, deleted: true };
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=relation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation.js","sourceRoot":"","sources":["../../src/executor/relation.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,iCAAiC;AACjC,EAAE;AACF,sEAAsE;AACtE,mEAAmE;AACnE,yEAAyE;AACzE,mEAAmE;AACnE,2CAA2C;AAE3C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAmB,MAAM,YAAY,CAAC;AAE5E,qEAAqE;AACrE,MAAM,CAAC,MAAM,kBAAkB,GAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;IAC9D,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,MAAM,GAAG,GAAG,cAAc,CACxB,GAAG,CAAC,EAAE,EACN;QACE,UAAU,EAAE,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC;QAC9C,QAAQ,EAAE,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC;QAC1C,UAAU,EAAE,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC;QAC9C,QAAQ,EAAE,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC;QAC1C,YAAY,EAAE,aAAa,CAAC,IAAI,EAAE,eAAe,CAAC;QAClD,QAAQ,EAAE,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC;KAC3C,EACD,GAAG,CAAC,UAAU,CACf,CAAC;IACF,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;AACxB,CAAC,CAAC;AAEF,wEAAwE;AACxE,MAAM,CAAC,MAAM,qBAAqB,GAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;IACjE,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IACnD,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,UAAU,UAAU,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3C,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ToolContext } from "../context.js";
|
|
2
|
+
import type { Proposal } from "../proposal/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* 执行结果(统一携带 id:新对象 id 或操作对象 id;扩展字段 camelCase)。
|
|
5
|
+
* duplicated=true:幂等命中——(node_id, hook_id, relation_type) 已有记录,未重复写(tools.md 复合写说明)。
|
|
6
|
+
*/
|
|
7
|
+
export type ExecutorResult = {
|
|
8
|
+
id: string;
|
|
9
|
+
duplicated?: boolean;
|
|
10
|
+
} & Record<string, unknown>;
|
|
11
|
+
/** 执行函数统一签名:直接消费 Proposal(args 规范化形态 + summary),返回可序列化结果或抛错 */
|
|
12
|
+
export type ExecutorFn = (ctx: ToolContext, proposal: Proposal) => ExecutorResult;
|
|
13
|
+
/** 必填字符串参数(缺失/空串/非字符串 → 抛错,防脏调用写脏数据) */
|
|
14
|
+
export declare function requireString(args: Record<string, unknown>, key: string): string;
|
|
15
|
+
/** 可选字符串参数(缺失返回 undefined;存在但非字符串 → 抛错) */
|
|
16
|
+
export declare function optionalString(args: Record<string, unknown>, key: string): string | undefined;
|
|
17
|
+
/** 必填对象参数(patches/metadata 等) */
|
|
18
|
+
export declare function requireRecord(args: Record<string, unknown>, key: string): Record<string, unknown>;
|
|
19
|
+
/** 可选对象参数(缺失返回 undefined) */
|
|
20
|
+
export declare function optionalRecord(args: Record<string, unknown>, key: string): Record<string, unknown> | undefined;
|
|
21
|
+
/** 必填数组参数(changes 等) */
|
|
22
|
+
export declare function requireArray(args: Record<string, unknown>, key: string): unknown[];
|
|
23
|
+
/** 必填数字参数(order 等;NaN 拒绝) */
|
|
24
|
+
export declare function requireNumber(args: Record<string, unknown>, key: string): number;
|
|
25
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/executor/types.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5F,+DAA+D;AAC/D,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,KAAK,cAAc,CAAC;AAElF,wCAAwC;AACxC,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMhF;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI7F;AAED,iCAAiC;AACjC,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMjG;AAED,6BAA6B;AAC7B,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAI9G;AAED,wBAAwB;AACxB,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,CAMlF;AAED,6BAA6B;AAC7B,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMhF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// 执行层公共类型与参数提取辅助(S6.7)
|
|
2
|
+
//
|
|
3
|
+
// 执行函数统一签名 (ctx, proposal):proposal.args 是 S6.6 已规范化的执行形态(add_relation
|
|
4
|
+
// 已派生 source_type/target_type、hook 变更 args.description 承载描述),可直接消费;
|
|
5
|
+
// proposal.summary 供 add_delta 取人类可读描述(S6.6 delta.ts 注释:description 由执行器取
|
|
6
|
+
// summary)。参数提取做运行时防御(防脏调用),提取失败抛错即失败(S7.5 转错误响应)。
|
|
7
|
+
// **执行类不注册 registry**(registry 是 LLM 可见工具表;执行函数仅由 executor 门面调用)。
|
|
8
|
+
/** 必填字符串参数(缺失/空串/非字符串 → 抛错,防脏调用写脏数据) */
|
|
9
|
+
export function requireString(args, key) {
|
|
10
|
+
const v = args[key];
|
|
11
|
+
if (typeof v !== "string" || v === "") {
|
|
12
|
+
throw new Error(`执行参数缺失或非法: ${key}`);
|
|
13
|
+
}
|
|
14
|
+
return v;
|
|
15
|
+
}
|
|
16
|
+
/** 可选字符串参数(缺失返回 undefined;存在但非字符串 → 抛错) */
|
|
17
|
+
export function optionalString(args, key) {
|
|
18
|
+
const v = args[key];
|
|
19
|
+
if (v === undefined)
|
|
20
|
+
return undefined;
|
|
21
|
+
return requireString(args, key);
|
|
22
|
+
}
|
|
23
|
+
/** 必填对象参数(patches/metadata 等) */
|
|
24
|
+
export function requireRecord(args, key) {
|
|
25
|
+
const v = args[key];
|
|
26
|
+
if (typeof v !== "object" || v === null || Array.isArray(v)) {
|
|
27
|
+
throw new Error(`执行参数缺失或非法: ${key}`);
|
|
28
|
+
}
|
|
29
|
+
return v;
|
|
30
|
+
}
|
|
31
|
+
/** 可选对象参数(缺失返回 undefined) */
|
|
32
|
+
export function optionalRecord(args, key) {
|
|
33
|
+
const v = args[key];
|
|
34
|
+
if (v === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
return requireRecord(args, key);
|
|
37
|
+
}
|
|
38
|
+
/** 必填数组参数(changes 等) */
|
|
39
|
+
export function requireArray(args, key) {
|
|
40
|
+
const v = args[key];
|
|
41
|
+
if (!Array.isArray(v)) {
|
|
42
|
+
throw new Error(`执行参数缺失或非法: ${key}`);
|
|
43
|
+
}
|
|
44
|
+
return v;
|
|
45
|
+
}
|
|
46
|
+
/** 必填数字参数(order 等;NaN 拒绝) */
|
|
47
|
+
export function requireNumber(args, key) {
|
|
48
|
+
const v = args[key];
|
|
49
|
+
if (typeof v !== "number" || Number.isNaN(v)) {
|
|
50
|
+
throw new Error(`执行参数缺失或非法: ${key}`);
|
|
51
|
+
}
|
|
52
|
+
return v;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/executor/types.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,EAAE;AACF,uEAAuE;AACvE,oEAAoE;AACpE,0EAA0E;AAC1E,mDAAmD;AACnD,kEAAkE;AAclE,wCAAwC;AACxC,MAAM,UAAU,aAAa,CAAC,IAA6B,EAAE,GAAW;IACtE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,cAAc,CAAC,IAA6B,EAAE,GAAW;IACvE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACtC,OAAO,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED,iCAAiC;AACjC,MAAM,UAAU,aAAa,CAAC,IAA6B,EAAE,GAAW;IACtE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAA4B,CAAC;AACtC,CAAC;AAED,6BAA6B;AAC7B,MAAM,UAAU,cAAc,CAAC,IAA6B,EAAE,GAAW;IACvE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACtC,OAAO,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED,wBAAwB;AACxB,MAAM,UAAU,YAAY,CAAC,IAA6B,EAAE,GAAW;IACrE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,6BAA6B;AAC7B,MAAM,UAAU,aAAa,CAAC,IAA6B,EAAE,GAAW;IACtE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const TOOLS_PKG_NAME = "@whispering233/ai-editor-tools";
|
|
2
|
+
export declare const TOOLS_PKG_VERSION = "0.1.0";
|
|
3
|
+
export * from "./context.js";
|
|
4
|
+
export * from "./registry.js";
|
|
5
|
+
export * from "./query/entity.js";
|
|
6
|
+
export * from "./query/relation.js";
|
|
7
|
+
export * from "./query/outline.js";
|
|
8
|
+
export * from "./query/delta.js";
|
|
9
|
+
export * from "./analysis/utils.js";
|
|
10
|
+
export * from "./analysis/consistency.js";
|
|
11
|
+
export * from "./analysis/conflict.js";
|
|
12
|
+
export * from "./analysis/path.js";
|
|
13
|
+
export * from "./analysis/orphan.js";
|
|
14
|
+
export * from "./analysis/suggest.js";
|
|
15
|
+
export * from "./analysis/hook.js";
|
|
16
|
+
export * from "./proposal/types.js";
|
|
17
|
+
export * from "./proposal/entity.js";
|
|
18
|
+
export * from "./proposal/relation.js";
|
|
19
|
+
export * from "./proposal/delta.js";
|
|
20
|
+
export * from "./proposal/outline.js";
|
|
21
|
+
export * from "./proposal/hook.js";
|
|
22
|
+
export * from "./executor/index.js";
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,cAAc,mCAAmC,CAAC;AAC/D,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,qBAAqB,CAAC"}
|