dsh-thesis 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +390 -0
- package/LICENSE +21 -0
- package/NOTICE.md +10 -0
- package/README.md +253 -0
- package/cordis.patch.yml +17 -0
- package/docs/host-api.md +640 -0
- package/lib/codewalk/commands.d.ts +23 -0
- package/lib/codewalk/commands.js +168 -0
- package/lib/codewalk/engine.d.ts +108 -0
- package/lib/codewalk/engine.js +449 -0
- package/lib/codewalk/errors.d.ts +31 -0
- package/lib/codewalk/errors.js +20 -0
- package/lib/codewalk/fs-types.d.ts +34 -0
- package/lib/codewalk/fs-types.js +10 -0
- package/lib/codewalk/gate.d.ts +30 -0
- package/lib/codewalk/gate.js +60 -0
- package/lib/codewalk/host-types.d.ts +198 -0
- package/lib/codewalk/host-types.js +11 -0
- package/lib/codewalk/prestep.d.ts +17 -0
- package/lib/codewalk/prestep.js +62 -0
- package/lib/codewalk/register.d.ts +23 -0
- package/lib/codewalk/register.js +31 -0
- package/lib/codewalk/skill.d.ts +15 -0
- package/lib/codewalk/skill.js +57 -0
- package/lib/codewalk/tools.d.ts +18 -0
- package/lib/codewalk/tools.js +314 -0
- package/lib/codewalk/types.d.ts +151 -0
- package/lib/codewalk/types.js +9 -0
- package/lib/commands.d.ts +33 -0
- package/lib/commands.js +60 -0
- package/lib/config.d.ts +125 -0
- package/lib/config.js +139 -0
- package/lib/dedup/commands.d.ts +21 -0
- package/lib/dedup/commands.js +93 -0
- package/lib/dedup/index.d.ts +75 -0
- package/lib/dedup/index.js +331 -0
- package/lib/dedup/normalize.d.ts +125 -0
- package/lib/dedup/normalize.js +329 -0
- package/lib/dedup/report.d.ts +114 -0
- package/lib/dedup/report.js +309 -0
- package/lib/dedup/rewrite.d.ts +71 -0
- package/lib/dedup/rewrite.js +228 -0
- package/lib/dedup/similarity.d.ts +169 -0
- package/lib/dedup/similarity.js +323 -0
- package/lib/gates/dangerous.d.ts +22 -0
- package/lib/gates/dangerous.js +47 -0
- package/lib/gates/detect.d.ts +54 -0
- package/lib/gates/detect.js +106 -0
- package/lib/gates/messages.d.ts +39 -0
- package/lib/gates/messages.js +74 -0
- package/lib/gates/prompt.d.ts +21 -0
- package/lib/gates/prompt.js +56 -0
- package/lib/gates/writing-intent.d.ts +49 -0
- package/lib/gates/writing-intent.js +68 -0
- package/lib/index.d.ts +36 -0
- package/lib/index.js +76 -0
- package/lib/ingest/code.d.ts +71 -0
- package/lib/ingest/code.js +356 -0
- package/lib/ingest/commands.d.ts +23 -0
- package/lib/ingest/commands.js +74 -0
- package/lib/ingest/docx.d.ts +29 -0
- package/lib/ingest/docx.js +92 -0
- package/lib/ingest/index.d.ts +179 -0
- package/lib/ingest/index.js +640 -0
- package/lib/ingest/ooxml.d.ts +58 -0
- package/lib/ingest/ooxml.js +393 -0
- package/lib/ingest/pdf.d.ts +86 -0
- package/lib/ingest/pdf.js +1016 -0
- package/lib/ingest/pptx.d.ts +32 -0
- package/lib/ingest/pptx.js +116 -0
- package/lib/ingest/text.d.ts +25 -0
- package/lib/ingest/text.js +180 -0
- package/lib/ingest/types.d.ts +48 -0
- package/lib/ingest/types.js +47 -0
- package/lib/ingest/xlsx.d.ts +72 -0
- package/lib/ingest/xlsx.js +411 -0
- package/lib/ingest/zip.d.ts +76 -0
- package/lib/ingest/zip.js +393 -0
- package/lib/intake/definitions.d.ts +65 -0
- package/lib/intake/definitions.js +42 -0
- package/lib/intake/gate-rules.d.ts +57 -0
- package/lib/intake/gate-rules.js +118 -0
- package/lib/intake/gate.d.ts +24 -0
- package/lib/intake/gate.js +86 -0
- package/lib/intake/index.d.ts +76 -0
- package/lib/intake/index.js +468 -0
- package/lib/intake/questions.d.ts +169 -0
- package/lib/intake/questions.js +720 -0
- package/lib/intake/spec.d.ts +66 -0
- package/lib/intake/spec.js +221 -0
- package/lib/intake/state.d.ts +192 -0
- package/lib/intake/state.js +420 -0
- package/lib/memory/recall.d.ts +69 -0
- package/lib/memory/recall.js +177 -0
- package/lib/memory/register.d.ts +37 -0
- package/lib/memory/register.js +52 -0
- package/lib/memory/service.d.ts +39 -0
- package/lib/memory/service.js +39 -0
- package/lib/memory/store.d.ts +45 -0
- package/lib/memory/store.js +123 -0
- package/lib/memory/tools.d.ts +19 -0
- package/lib/memory/tools.js +195 -0
- package/lib/memory/types.d.ts +55 -0
- package/lib/memory/types.js +6 -0
- package/lib/paper/commands.d.ts +13 -0
- package/lib/paper/commands.js +84 -0
- package/lib/paper/lib/aicheck.d.ts +38 -0
- package/lib/paper/lib/aicheck.js +241 -0
- package/lib/paper/lib/bibtex.d.ts +21 -0
- package/lib/paper/lib/bibtex.js +114 -0
- package/lib/paper/lib/check.d.ts +32 -0
- package/lib/paper/lib/check.js +215 -0
- package/lib/paper/lib/defense.d.ts +48 -0
- package/lib/paper/lib/defense.js +220 -0
- package/lib/paper/lib/docx.d.ts +35 -0
- package/lib/paper/lib/docx.js +213 -0
- package/lib/paper/lib/layout.d.ts +41 -0
- package/lib/paper/lib/layout.js +572 -0
- package/lib/paper/lib/ledger.d.ts +112 -0
- package/lib/paper/lib/ledger.js +349 -0
- package/lib/paper/lib/lit-api.d.ts +59 -0
- package/lib/paper/lib/lit-api.js +296 -0
- package/lib/paper/lib/lit-cache.d.ts +32 -0
- package/lib/paper/lib/lit-cache.js +91 -0
- package/lib/paper/lib/project.d.ts +29 -0
- package/lib/paper/lib/project.js +93 -0
- package/lib/paper/lib/review.d.ts +37 -0
- package/lib/paper/lib/review.js +194 -0
- package/lib/paper/lib/zip.d.ts +14 -0
- package/lib/paper/lib/zip.js +124 -0
- package/lib/paper/register.d.ts +20 -0
- package/lib/paper/register.js +183 -0
- package/lib/paper/tools/aicheck.d.ts +6 -0
- package/lib/paper/tools/aicheck.js +38 -0
- package/lib/paper/tools/build.d.ts +27 -0
- package/lib/paper/tools/build.js +166 -0
- package/lib/paper/tools/check.d.ts +7 -0
- package/lib/paper/tools/check.js +79 -0
- package/lib/paper/tools/decision.d.ts +13 -0
- package/lib/paper/tools/decision.js +53 -0
- package/lib/paper/tools/defense.d.ts +11 -0
- package/lib/paper/tools/defense.js +74 -0
- package/lib/paper/tools/init.d.ts +23 -0
- package/lib/paper/tools/init.js +99 -0
- package/lib/paper/tools/lit.d.ts +27 -0
- package/lib/paper/tools/lit.js +236 -0
- package/lib/paper/tools/progress.d.ts +18 -0
- package/lib/paper/tools/progress.js +77 -0
- package/lib/paper/tools/review.d.ts +11 -0
- package/lib/paper/tools/review.js +41 -0
- package/lib/ppt/actions.d.ts +97 -0
- package/lib/ppt/actions.js +263 -0
- package/lib/ppt/check.d.ts +64 -0
- package/lib/ppt/check.js +185 -0
- package/lib/ppt/commands.d.ts +28 -0
- package/lib/ppt/commands.js +71 -0
- package/lib/ppt/convert.d.ts +146 -0
- package/lib/ppt/convert.js +423 -0
- package/lib/ppt/index.d.ts +45 -0
- package/lib/ppt/index.js +57 -0
- package/lib/ppt/marp.d.ts +74 -0
- package/lib/ppt/marp.js +165 -0
- package/lib/ppt/outline.d.ts +206 -0
- package/lib/ppt/outline.js +695 -0
- package/lib/shared/define-tool.d.ts +77 -0
- package/lib/shared/define-tool.js +235 -0
- package/lib/shared/fs-errors.d.ts +50 -0
- package/lib/shared/fs-errors.js +90 -0
- package/lib/shared/index.d.ts +31 -0
- package/lib/shared/index.js +32 -0
- package/lib/shared/spawn.d.ts +38 -0
- package/lib/shared/spawn.js +50 -0
- package/lib/shared/text.d.ts +14 -0
- package/lib/shared/text.js +26 -0
- package/package.json +82 -0
- package/skills/code-walkthrough/SKILL.md +94 -0
- package/skills/code-walkthrough/references/examples.md +129 -0
- package/skills/paper-dedup/SKILL.md +58 -0
- package/skills/paper-intake/SKILL.md +64 -0
- package/skills/thesis-citation/SKILL.md +67 -0
- package/skills/thesis-defense/SKILL.md +87 -0
- package/skills/thesis-eng-design/SKILL.md +97 -0
- package/skills/thesis-inquiry/SKILL.md +55 -0
- package/skills/thesis-inquiry/references/intent-spec-template.md +39 -0
- package/skills/thesis-literature/SKILL.md +56 -0
- package/skills/thesis-opener/SKILL.md +77 -0
- package/skills/thesis-pipeline/SKILL.md +121 -0
- package/skills/thesis-writing/SKILL.md +86 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 人类可用的 `/thesis-defense` 命令:`new`、`status`、`check`。
|
|
3
|
+
*
|
|
4
|
+
* 只有在组合了命令适配器时才通过 `ctx.commands` 注册(交互式部署);纯 headless
|
|
5
|
+
* 与仅 ACP 的组合没有命令注册表,直接跳过这一层表面。命令面的结果直接渲染,
|
|
6
|
+
* 不进入模型历史。
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-thesis/codewalk
|
|
9
|
+
*/
|
|
10
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
11
|
+
import { AiLearningEngine } from './engine.ts';
|
|
12
|
+
import type { CommandInvocationShape, CommandResultShape } from './host-types.ts';
|
|
13
|
+
/** 代码演练侧的子命令(与幻灯侧区分)。 */
|
|
14
|
+
export declare const CODEWALK_SUBCOMMANDS: readonly string[];
|
|
15
|
+
/** 命令的展示元信息(装配层注册 `/thesis-defense` 时使用)。 */
|
|
16
|
+
export declare const CODEWALK_COMMAND_HINT = "new <\u539F\u59CB\u9879\u76EE\u8DEF\u5F84> [--lang go] [--level beginner] [--module pkg] | status | check [\u91CC\u7A0B\u7891]";
|
|
17
|
+
/**
|
|
18
|
+
* 代码演练侧的命令处理器(由装配层在 `/thesis-defense` 下调度)。
|
|
19
|
+
*
|
|
20
|
+
* `rawInput` 是命令名之后的全部输入;本函数只认代码演练侧的子命令
|
|
21
|
+
* (`new` / `status` / `check`),其余一律交回装配层。
|
|
22
|
+
*/
|
|
23
|
+
export declare function handleCodewalkCommand(ctx: Context, engine: AiLearningEngine, invocation: CommandInvocationShape): Promise<CommandResultShape>;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 人类可用的 `/thesis-defense` 命令:`new`、`status`、`check`。
|
|
3
|
+
*
|
|
4
|
+
* 只有在组合了命令适配器时才通过 `ctx.commands` 注册(交互式部署);纯 headless
|
|
5
|
+
* 与仅 ACP 的组合没有命令注册表,直接跳过这一层表面。命令面的结果直接渲染,
|
|
6
|
+
* 不进入模型历史。
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-thesis/codewalk
|
|
9
|
+
*/
|
|
10
|
+
import { AiLearningEngine } from "./engine.js";
|
|
11
|
+
import { isLearningError } from "./errors.js";
|
|
12
|
+
import { runMilestoneGate } from "./gate.js";
|
|
13
|
+
const DEFAULT_LANGUAGE = 'go';
|
|
14
|
+
const LEVELS = ['beginner', 'intermediate', 'advanced'];
|
|
15
|
+
/** 会话没有工作目录时的统一答复。 */
|
|
16
|
+
const NO_WORKSPACE = {
|
|
17
|
+
kind: 'error',
|
|
18
|
+
text: '本次会话没有工作目录,无法定位代码演练状态。请在论文工作区目录里打开会话。',
|
|
19
|
+
};
|
|
20
|
+
/** 代码演练侧的子命令(与幻灯侧区分)。 */
|
|
21
|
+
export const CODEWALK_SUBCOMMANDS = ['new', 'status', 'check'];
|
|
22
|
+
/** 命令的展示元信息(装配层注册 `/thesis-defense` 时使用)。 */
|
|
23
|
+
export const CODEWALK_COMMAND_HINT = 'new <原始项目路径> [--lang go] [--level beginner] [--module pkg] | status | check [里程碑]';
|
|
24
|
+
/**
|
|
25
|
+
* 代码演练侧的命令处理器(由装配层在 `/thesis-defense` 下调度)。
|
|
26
|
+
*
|
|
27
|
+
* `rawInput` 是命令名之后的全部输入;本函数只认代码演练侧的子命令
|
|
28
|
+
* (`new` / `status` / `check`),其余一律交回装配层。
|
|
29
|
+
*/
|
|
30
|
+
export async function handleCodewalkCommand(ctx, engine, invocation) {
|
|
31
|
+
try {
|
|
32
|
+
const tokens = invocation.rawInput.trim().split(/\s+/);
|
|
33
|
+
const sub = tokens[0] ?? '';
|
|
34
|
+
const args = tokens.slice(1);
|
|
35
|
+
if (sub === 'new')
|
|
36
|
+
return await handleNew(engine, invocation, args);
|
|
37
|
+
if (sub === 'status')
|
|
38
|
+
return await handleStatus(engine, invocation);
|
|
39
|
+
if (sub === 'check')
|
|
40
|
+
return await handleCheck(ctx, engine, invocation, args);
|
|
41
|
+
return { kind: 'error', text: `未知子命令 "${sub}";代码演练侧应为 new | status | check` };
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (isLearningError(error))
|
|
45
|
+
return { kind: 'error', text: error.message };
|
|
46
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
47
|
+
return { kind: 'error', text: `内部错误:${message}` };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function parseNewArgs(args) {
|
|
51
|
+
const options = { language: DEFAULT_LANGUAGE, level: 'beginner' };
|
|
52
|
+
const positional = [];
|
|
53
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
54
|
+
const arg = args[index];
|
|
55
|
+
if (arg === '--lang' || arg === '--level' || arg === '--module') {
|
|
56
|
+
const value = args[index + 1];
|
|
57
|
+
if (value === undefined)
|
|
58
|
+
continue;
|
|
59
|
+
if (arg === '--lang')
|
|
60
|
+
options.language = value;
|
|
61
|
+
else if (arg === '--level')
|
|
62
|
+
options.level = value;
|
|
63
|
+
else
|
|
64
|
+
options.module = value;
|
|
65
|
+
index += 1;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (arg.startsWith('--lang='))
|
|
69
|
+
options.language = arg.slice('--lang='.length);
|
|
70
|
+
else if (arg.startsWith('--level='))
|
|
71
|
+
options.level = arg.slice('--level='.length);
|
|
72
|
+
else if (arg.startsWith('--module='))
|
|
73
|
+
options.module = arg.slice('--module='.length);
|
|
74
|
+
else
|
|
75
|
+
positional.push(arg);
|
|
76
|
+
}
|
|
77
|
+
const first = positional[0];
|
|
78
|
+
if (first !== undefined)
|
|
79
|
+
options.path = first;
|
|
80
|
+
return options;
|
|
81
|
+
}
|
|
82
|
+
async function handleNew(engine, invocation, args) {
|
|
83
|
+
const options = parseNewArgs(args);
|
|
84
|
+
if (options.path === undefined) {
|
|
85
|
+
return {
|
|
86
|
+
kind: 'error',
|
|
87
|
+
text: '用法:/thesis-defense new <原始项目路径> [--lang go] [--level beginner] [--module pkg]',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (!LEVELS.includes(options.level)) {
|
|
91
|
+
return { kind: 'error', text: `非法的 level "${options.level}";应为 ${LEVELS.join(' | ')}` };
|
|
92
|
+
}
|
|
93
|
+
const cwd = invocation.agent.session.header.cwd;
|
|
94
|
+
if (cwd === undefined || cwd === '')
|
|
95
|
+
return NO_WORKSPACE;
|
|
96
|
+
const state = await engine.create(cwd, {
|
|
97
|
+
origin: { path: options.path, language: options.language },
|
|
98
|
+
scope: { level: options.level, ...(options.module !== undefined ? { module: options.module } : {}) },
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
kind: 'success',
|
|
102
|
+
text: `已为 ${options.path} 创建代码演练(${options.language},${options.level})。\n` +
|
|
103
|
+
`${engine.describe(state)}\n` +
|
|
104
|
+
`下一步:让 AI 分析该项目,用 defense_code_update 工具登记 todo 与里程碑。`,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
async function handleStatus(engine, invocation) {
|
|
108
|
+
const cwd = invocation.agent.session.header.cwd;
|
|
109
|
+
if (cwd === undefined || cwd === '')
|
|
110
|
+
return NO_WORKSPACE;
|
|
111
|
+
const state = await engine.load(cwd);
|
|
112
|
+
if (state === undefined) {
|
|
113
|
+
return { kind: 'error', text: `${cwd} 下没有代码演练状态;请先执行 "/thesis-defense new <原始项目路径>"` };
|
|
114
|
+
}
|
|
115
|
+
return { kind: 'success', text: engine.describe(state) };
|
|
116
|
+
}
|
|
117
|
+
async function handleCheck(ctx, engine, invocation, args) {
|
|
118
|
+
const cwd = invocation.agent.session.header.cwd;
|
|
119
|
+
if (cwd === undefined || cwd === '')
|
|
120
|
+
return NO_WORKSPACE;
|
|
121
|
+
const state = await engine.load(cwd);
|
|
122
|
+
if (state === undefined) {
|
|
123
|
+
return { kind: 'error', text: `${cwd} 下没有代码演练状态;请先执行 "/thesis-defense new <原始项目路径>"` };
|
|
124
|
+
}
|
|
125
|
+
const milestone = pickMilestone(state.milestones, args[0]);
|
|
126
|
+
if (milestone === undefined) {
|
|
127
|
+
return {
|
|
128
|
+
kind: 'error',
|
|
129
|
+
text: args[0] === undefined
|
|
130
|
+
? '当前没有 in_progress 或 failed 的里程碑,没有可检查的对象'
|
|
131
|
+
: `未知里程碑 "${args[0]}"`,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
if (milestone.status === 'failed')
|
|
135
|
+
engine.retryMilestone(state, milestone.id);
|
|
136
|
+
const settled = await runMilestoneGate(ctx, engine, cwd, state, milestone, invocation.signal, invocation.agent.session);
|
|
137
|
+
if (settled.interrupted) {
|
|
138
|
+
return { kind: 'error', text: `验证门 "${settled.command.join(' ')}" 被中断;该里程碑已标记为 failed` };
|
|
139
|
+
}
|
|
140
|
+
if (settled.outcome.kind === 'failed') {
|
|
141
|
+
return {
|
|
142
|
+
kind: 'error',
|
|
143
|
+
text: `验证门 "${settled.command.join(' ')}" 失败,退出码 ${settled.exitCode};该里程碑已标记为 failed。\n` +
|
|
144
|
+
(settled.stderr.trim() === '' ? `stdout 末尾:\n${settled.stdout}` : `stderr 末尾:\n${settled.stderr}`),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (settled.outcome.kind === 'pending-questions') {
|
|
148
|
+
return {
|
|
149
|
+
kind: 'success',
|
|
150
|
+
text: `验证门 "${settled.command.join(' ')}" 通过,但仍有 ${milestone.questions.filter((question) => question.status !== 'passed').length} 个问题未通过。\n` +
|
|
151
|
+
'让 AI 把追问做完;当验证门为绿且全部问题通过时,该里程碑才算 verified。',
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const next = state.milestones.find((entry) => entry.status === 'in_progress');
|
|
155
|
+
const complete = state.phase === 'complete';
|
|
156
|
+
return {
|
|
157
|
+
kind: 'success',
|
|
158
|
+
text: `验证门 "${settled.command.join(' ')}" 通过 —— 里程碑 "${milestone.id}" 已验证。\n` +
|
|
159
|
+
(complete ? '全部里程碑已验证:本次代码演练完成。' : `下一个里程碑:${next?.title ?? '无'}。`),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function pickMilestone(milestones, requestedId) {
|
|
163
|
+
if (requestedId !== undefined) {
|
|
164
|
+
return milestones.find((milestone) => milestone.id === requestedId);
|
|
165
|
+
}
|
|
166
|
+
return (milestones.find((milestone) => milestone.status === 'in_progress') ??
|
|
167
|
+
milestones.find((milestone) => milestone.status === 'failed'));
|
|
168
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 代码演练引擎:一个普通类,由 `register.ts` 里的 `registerCodewalk`
|
|
3
|
+
* 注册为 `paperLearn` 服务。
|
|
4
|
+
*
|
|
5
|
+
* 引擎负责守住流程,模型负责执行流程。所有非法迁移都在这里被拒绝:没有
|
|
6
|
+
* 真实跑过一次验证门,模型就不能把某个里程碑标成 verified;不能修改已冻结
|
|
7
|
+
* (verified)的里程碑;不能跳阶段。状态落在 `<cwd>/.paper/state.json`,
|
|
8
|
+
* 因此跨会话存活,并随演练骨架仓库一起走。
|
|
9
|
+
*
|
|
10
|
+
* 这个类刻意**不**继承 Cordis 的 `Service`:装进 profile 的 bundle 会从自己的
|
|
11
|
+
* 依赖树里解析 `@deepseek-ai/cordis`,两份模块副本会破坏框架以 Symbol 为键的
|
|
12
|
+
* 生命周期钩子。注册一律走 `ctx.provide` —— 与生产 boot 插件用的是同一个接缝。
|
|
13
|
+
*
|
|
14
|
+
* @module dsh-thesis/codewalk
|
|
15
|
+
*/
|
|
16
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
17
|
+
import type { StateFileSystem } from './fs-types.ts';
|
|
18
|
+
import type { CreateStateInput, EngineStateSnapshot, GateOutcome, GateRecord, GateSpec, LearningState, LearnOptions, Milestone, Phase, Todo, TodoStatus } from './types.ts';
|
|
19
|
+
declare module '@deepseek-ai/cordis' {
|
|
20
|
+
interface Context {
|
|
21
|
+
paperLearn: AiLearningEngine;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** 已物化全部默认值的解析后配置。 */
|
|
25
|
+
export interface ResolvedConfig {
|
|
26
|
+
readonly stateDir: string;
|
|
27
|
+
readonly gates: Readonly<Record<string, GateSpec>>;
|
|
28
|
+
readonly maxCapturedOutput: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 代码演练引擎。
|
|
32
|
+
*
|
|
33
|
+
* 所有状态机方法都直接修改传入的 `state` 对象,并用 `LearningError` 拒绝非法
|
|
34
|
+
* 迁移。持久化方法一律走注入的文件系统,因此本地与远端后端行为一致。
|
|
35
|
+
*/
|
|
36
|
+
export declare class AiLearningEngine {
|
|
37
|
+
private readonly ctx;
|
|
38
|
+
private readonly resolved;
|
|
39
|
+
constructor(ctx: Context, config?: LearnOptions);
|
|
40
|
+
/** 解析后的配置(默认值已物化)。 */
|
|
41
|
+
get config(): ResolvedConfig;
|
|
42
|
+
/** 宿主文件系统接缝;`inject: ['fs']` 保证其存在。 */
|
|
43
|
+
private get fs();
|
|
44
|
+
private stateFilePath;
|
|
45
|
+
/** 相对会话 cwd 解析状态文件目标。 */
|
|
46
|
+
stateTarget(cwd: string): Promise<ReturnType<StateFileSystem['resolve']>>;
|
|
47
|
+
/** `cwd` 下是否已存在演练状态。 */
|
|
48
|
+
hasState(cwd: string): Promise<boolean>;
|
|
49
|
+
/**
|
|
50
|
+
* 读取并校验 `cwd` 下的状态;不存在时返回 `undefined`。
|
|
51
|
+
* 内容损坏时以 `STATE_INVALID` 拒绝。
|
|
52
|
+
*/
|
|
53
|
+
load(cwd: string): Promise<LearningState | undefined>;
|
|
54
|
+
/**
|
|
55
|
+
* 为一次新的代码演练创建初始状态。
|
|
56
|
+
*
|
|
57
|
+
* 已存在状态时以 `STATE_EXISTS` 拒绝(经 `createIfAbsent` 保证竞态安全);
|
|
58
|
+
* 源语言没有配置验证门时以 `GATE_UNKNOWN` 拒绝。
|
|
59
|
+
*/
|
|
60
|
+
create(cwd: string, input: CreateStateInput): Promise<LearningState>;
|
|
61
|
+
/** 持久化当前状态,并刷新 `updatedAt`。 */
|
|
62
|
+
save(cwd: string, state: LearningState): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* 推进工作流阶段。只允许沿
|
|
65
|
+
* analyzing → skeletonizing → learning → complete 向前走。
|
|
66
|
+
* 进入 `learning` 至少需要一个带 todo 的里程碑;
|
|
67
|
+
* 进入 `complete` 需要每个里程碑都已 verified。
|
|
68
|
+
*/
|
|
69
|
+
advancePhase(state: LearningState, next: Phase): void;
|
|
70
|
+
/** 新增或替换一个 todo。被 verified 里程碑引用的 todo 已冻结。 */
|
|
71
|
+
upsertTodo(state: LearningState, todo: Todo): void;
|
|
72
|
+
/** 沿 pending → in_progress → done 迁移一个 todo(允许返工)。 */
|
|
73
|
+
setTodoStatus(state: LearningState, todoId: string, status: TodoStatus): void;
|
|
74
|
+
private assertTodoEditable;
|
|
75
|
+
/**
|
|
76
|
+
* 新增或替换一个里程碑。verified 里程碑已冻结。每个 todo 引用都必须能解析。
|
|
77
|
+
* 新里程碑从 `pending` 开始;对未关闭里程碑做内容编辑会保留其当前状态。
|
|
78
|
+
*/
|
|
79
|
+
upsertMilestone(state: LearningState, milestone: Milestone): void;
|
|
80
|
+
/** 启动第一个 pending 里程碑。要求处于 learning 阶段。 */
|
|
81
|
+
startNextMilestone(state: LearningState): void;
|
|
82
|
+
/** 重新打开一个 failed 里程碑,允许再试一次。 */
|
|
83
|
+
retryMilestone(state: LearningState, milestoneId: string): void;
|
|
84
|
+
private milestone;
|
|
85
|
+
/** 提出(或在失分后重提)某个里程碑问题。 */
|
|
86
|
+
askQuestion(state: LearningState, milestoneId: string, questionIndex: number): void;
|
|
87
|
+
/**
|
|
88
|
+
* 为一个已提出的问题给出下一级升级提示。返回提示文本;提示阶梯用尽时返回
|
|
89
|
+
* `null` —— 此时必须公布答案,并要求学生用自己的话复述,再走 `assessAnswer`。
|
|
90
|
+
*/
|
|
91
|
+
giveHint(state: LearningState, milestoneId: string, questionIndex: number): string | null;
|
|
92
|
+
/** 用评分结论(可选评分备注)给一个已提出的问题定分。 */
|
|
93
|
+
assessAnswer(state: LearningState, milestoneId: string, questionIndex: number, passed: boolean, note?: string): void;
|
|
94
|
+
private question;
|
|
95
|
+
/**
|
|
96
|
+
* 记录一次实际执行的验证门,并把结论折进里程碑。
|
|
97
|
+
*
|
|
98
|
+
* - 退出码 0 且所有问题已 passed → `verified`,随后启动下一个 pending
|
|
99
|
+
* 里程碑(或整个流程完成);
|
|
100
|
+
* - 退出码 0 但仍有未通过的问题 → 保持 in_progress(`pending-questions`);
|
|
101
|
+
* - 退出码非 0 → `failed`;用 `retryMilestone` 重新打开。
|
|
102
|
+
*/
|
|
103
|
+
recordGate(state: LearningState, milestoneId: string, input: Omit<GateRecord, 'milestone' | 'at'>): GateOutcome;
|
|
104
|
+
/** 只读快照,供状态视图、模型工具与注入使用。 */
|
|
105
|
+
snapshot(state: LearningState): EngineStateSnapshot;
|
|
106
|
+
/** `/thesis-defense status` 用的人类可读状态文本。 */
|
|
107
|
+
describe(state: LearningState): string;
|
|
108
|
+
}
|