@godv61/dsh-task-engine 0.7.0 → 0.8.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dsh-task-engine
2
2
 
3
- 一个**可安装、项目无关、硬约束**的工程化交付引擎,把「需求评审 → 设计 → 开发 → 交付 → 代码审核」这套流程做成 DeepSeek Harness 的一个 bundle。同事 `dsh plugin add` 装一下就能在自己项目里用——**不需要**每个项目手写 `.agents` / `.claude` / `.harness`,也**不需要**建预设(`eng-delivery` 技能带 `whenToUse`,模型遇到开发类请求会自己加载并走 `dev_task`)。
3
+ 一个**可安装、项目无关、硬约束**的工程化交付引擎,把「需求评审 → 设计 → 开发 → 交付 → 代码审核」这套流程做成 DeepSeek Harness 的一个 bundle。**按预设激活**:装 bundle 后在目标预设的 `agent.cordis.yml` 加一行,该预设的会话才挂上 `dev_task` 工具、内置技能和人设;换到别的预设(不加那行)就完全不激活——不需要每个项目手写 `.agents` / `.claude` / `.harness`。
4
4
 
5
5
  核心是一个 `dev_task` 工具 + 内置技能。工具的硬约束在代码里执行,不是"提醒模型":
6
6
 
@@ -14,17 +14,21 @@
14
14
  ## 目录
15
15
 
16
16
  ```
17
- cordis.patch.yml bundle 声明 + host 组合 patch(一行,注册本插件,双端)
17
+ cordis.patch.yml bundle 声明 + host 组合 patch(一行,只挂 host 半:Remote 控制器 + 工作台 UI)
18
18
  defaults/eng.json 内置默认工作流(可被项目 .dsh/eng.json 覆盖)
19
19
  hooks/commit-msg git 提交门禁钩子(install_hook 装进 .git/hooks/)
20
20
  src/engine.ts 纯函数状态机 + 配置校验(无 harness 依赖,双端复用)
21
- src/index.ts 插件(host):注册 dev_task 工具 + 技能 + 挂 task-engine Remote 控制器
22
- src/controller.ts Host 端 Remote 控制器:网页读写 .dsh/eng.json
23
- src/client/ 浏览器半:设置页「工程流程配置」(表单 + 实时校验 + 保存 + 挂载/新建)
21
+ src/index.ts host 入口:只挂 task-engine Remote 控制器(配置面板用,非模型可见)
22
+ src/agent.ts agent 入口(./agent 出品):在调用它的预设 scope 里注册 dev_task + 内置技能
23
+ src/dev-task.ts dev_task 工具定义 + 全部文件系统辅助(模型门禁,随 agent 入口激活)
24
+ src/shipped-skills.ts 内置技能扫描 + 注册(随 agent 入口激活)
25
+ src/controller.ts Host 端 Remote 控制器:网页读写 .dsh/eng.json + skill/rule
26
+ src/client/ 浏览器半:全屏工作台(流程配置 / 技能 skill / 规则 rule 三个标签页)
24
27
  skills/ 内置技能库(需求分析/方案设计/实现/验证/审核/提交/交付编排)
25
28
  rules/ 内置规则库(编码规范/提交规范/安全红线)
29
+ preset/agent.cordis.yml 预设接入片段(persona 行 + agent 行,复制进你的预设)
26
30
  preset/preset.yml 预设元数据
27
- preset/persona.md 预设 persona 文案(复制粘贴用)
31
+ preset/persona.md 预设 persona 文案
28
32
  ```
29
33
 
30
34
  ## 构建
@@ -48,17 +52,23 @@ dsh plugin --profile <name> add github:<你的org>/dsh-task-engine
48
52
  dsh plugin --profile <name> add .
49
53
  ```
50
54
 
51
- ## 启用
55
+ ## 启用(按预设激活)
52
56
 
53
- 装完即用:`eng-delivery` 技能带 `whenToUse`,模型遇到开发、改 bug、加功能、评审、提交类请求会先加载它,再按技能铁律走 `dev_task`——不需要预设。
57
+ 装 bundle 只挂 host 半(配置工作台),**不**给任何会话挂 `dev_task` 或技能——流程惰性待命。要在哪个预设激活,就在那个预设的 `agent.cordis.yml` 加一行:
54
58
 
55
- ### 可选:专用「工程化开发引擎」预设
59
+ 1. 复制一个预设(GUI 预设管理里复制 `standard` → `eng`,落在 `~/.dsh/.agent-presets/eng/`)。
60
+ 2. 打开 `eng` 的 `agent.cordis.yml`,做两处改动(可直接照抄 `preset/agent.cordis.yml` 片段):
61
+ - `persona` 行换成工程化人设(`preset/persona.md` 的内容);
62
+ - 追加一行 agent 入口:
63
+ ```yaml
64
+ - id: task-engine-agent
65
+ name: '@godv61/dsh-task-engine/agent'
66
+ ```
67
+ 3. 新会话选 `eng`:挂上 `dev_task` 工具 + 内置技能 + 工程化人设,模型走完整流程。
68
+ - 换回 `standard` / `minimal` / 其它**没加那行**的预设:没有 `dev_task`、没有内置技能、没有工程化人设——流程完全不介入。
69
+ - 侧边栏「工程流程」全屏工作台仍在(host 半),随时供人查看/配置 `.dsh/eng.json` 和 skill/rule,与激活与否无关。
56
70
 
57
- 想要团队有个固定人设(新会话选它即进入工程化流程),才需要建预设:
58
-
59
- 1. 复制 `standard` 预设为 `eng`(GUI 预设管理里的「复制」,或手动建 `~/.dsh/.agent-presets/eng/` 目录)。
60
- 2. 把该预设的 persona 换成 `preset/persona.md` 内容。
61
- 3. 新会话选「工程化开发引擎」。`dev_task` 工具与 `eng-delivery` 技能由 bundle 提供。
71
+ 这一层对称由 DSH 的工具/技能 scope 机制保证:host 半从不把 `dev_task` 注册进全局工具层,agent 半只在命名它的预设 scope 里注册——不是一个“开关”,而是两个不同层的注册位置。
62
72
 
63
73
  ## 项目配置(让流程贴合你的项目)
64
74
 
@@ -122,4 +132,5 @@ dsh plugin --profile <name> add .
122
132
  - **网页图形化配置界面(0.5.0)**:新增 `src/client/` 设置页「工程流程配置」+ Host 端 `task-engine` Remote 控制器;`@godv61/dsh-task-engine` 升级为双端包(`dsh.client` manifest + `./client` 出品,`exports` 暴露)。已实机验证:`dsh web` 起服务后 boot 数据里 `@godv61/dsh-task-engine` 以 `inject:["@deepseek-ai/dsh-api-gateway"]` 进入 application batch、`/plugins/…/client.js` 正常服务;headless 冒烟确认 boot + `dev_task` 未被新控制器破坏。浏览器点击级 e2e 留到发布后用真浏览器收尾。
123
133
  - **skill/rule 挂载与渐进披露(0.6.0)**:`WorkflowConfig` 新增 `stage_bindings`(每阶段挂 skills/rules,可选字段),`dev_task` 的 `status`/`advance` 按当前阶段披露挂载的 skill 名 + rule 正文;内置 6 技能 + 3 规则库;Host 控制器新增 `listSkills`/`listRules`/`writeSkill`/`writeRule`;设置页新增「节点挂载」和「新建 skill / rule」两块,同时补上 `dev_task` 缺失的 `items` 操作(更新实施项状态)。引擎层 `stage_bindings` 校验(未知阶段/空名)与合并已单测通过。
124
134
  - **配置页精简 + 自建 skill 可观测(0.6.1)**:设置页的流转/产物/提交规则/新建默认折叠,「节点挂载」从六阶段全平铺改成「选一个阶段再看它挂了什么」;新建成功提示带回显路径(`.dsh/skills/<name>/SKILL.md` 或 `$DSH_HOME/…`),挂载清单给非内置的 skill/rule 标「(项目)/(用户)」来源。修复 `listSkills` 依赖 host skill registry 导致项目 `.dsh/skills` 自建技能不显示的问题——改为与 `listRules` 一致,直接扫「内置 + 项目 + 用户」三层目录。浏览器 e2e 全绿。
125
- - **全屏工作台 + 在线编辑(0.7.0)**:配置页从设置弹窗迁出,改为侧边栏 `sidebar.footer.action`「工程流程」按钮,点开 `shell.overlay` 全屏工作台(触发按钮与覆盖层共享一个 store 控制开关)。工作台分「流程配置 / 技能 skill / 规则 rule」三个标签页;技能和规则列表支持在线编辑——`readSkill`/`readRule` 读回正文、改 description/whenToUse/正文、`writeSkill`/`writeRule` 写回;内置项只读,项目/用户项可原地编辑,新建同时支持项目级/用户级。旧的 `settings.section` 入口移除,统一走侧边栏按钮。浏览器 e2e 全绿。
135
+ - **全屏工作台 + 在线编辑(0.7.0)**:配置页从设置弹窗迁出,改为侧边栏 `sidebar.footer.action`「工程流程」按钮,点开 `shell.overlay` 全屏工作台(触发按钮与覆盖层共享一个 store 控制开关)。工作台分「流程配置 / 技能 skill / 规则 rule」三个标签页;技能和规则列表支持在线编辑——`readSkill`/`readRule` 读回正文、改 description/whenToUse/正文、`writeSkill`/`writeRule` 写回;内置项只读,项目/用户项可原地编辑,新建同时支持项目级/用户级。旧的 `settings.section` 入口移除,统一走侧边栏按钮。浏览器 e2e 全绿。
136
+ - **按预设激活(0.8.0)**:`dev_task` 工具与内置技能从 host 全局层拆到 agent 层。host 入口只挂 `task-engine` Remote 控制器 + 工作台 UI(`src/index.ts`);新增 `src/agent.ts`(`./agent` 出品)、`src/dev-task.ts`、`src/shipped-skills.ts`,由预设的 `agent.cordis.yml` 命名后,在**该预设的 scope** 里注册工具与技能。实机 boot 验证:`standard` 会话工具目录不含 `dev_task`(26 个工具),加了 `@godv61/dsh-task-engine/agent` 行的 `eng` 会话含 `dev_task`(27 个工具)且描述正确,换回 `standard` 再次不含——切换预设即切换流程激活状态。
package/cordis.patch.yml CHANGED
@@ -1,10 +1,11 @@
1
- # dsh-task-engine bundle: one host-plane row that registers the `dev_task` tool
2
- # and the shipped engineering skills. The agent-plane opt-in (persona + routing)
3
- # lives in `preset/` and is copied into a preset by whoever enables the engine.
4
- #
5
- # Host row + global tools/skills registries means: install the bundle once and the
6
- # capability is dormant-available to every agent; the preset decides whether an
7
- # agent actually routes its work through it.
1
+ # dsh-task-engine bundle: one host-plane row that mounts the `task-engine`
2
+ # Remote namespace (what the browser workbench reads/writes) plus, via
3
+ # `dsh.client`, the workbench UI. This host row registers NO model-facing tool
4
+ # and NO skill — `dev_task` and the shipped skills live on the AGENT plane,
5
+ # behind the `@godv61/dsh-task-engine/agent` entry. A preset's
6
+ # `agent.cordis.yml` names that agent row to activate the flow for its
7
+ # sessions; presets that never name it get neither the tool nor the skills
8
+ # (the workbench stays available so a human can still configure the flow).
8
9
  - insert:
9
10
  - id: task-engine
10
11
  name: '@godv61/dsh-task-engine'
package/lib/agent.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Agent half of dsh-task-engine: registers the model-facing `dev_task` tool and
3
+ * the shipped engineering skills onto the calling (preset) scope. Name this row
4
+ * from a preset's `agent.cordis.yml` to activate the delivery flow for that
5
+ * preset's sessions; presets that never name it see neither the tool nor the
6
+ * skills.
7
+ *
8
+ * @module dsh-task-engine/agent
9
+ */
10
+ import type { Context } from '@deepseek-ai/cordis';
11
+ export declare const name = "task-engine-agent";
12
+ export declare const inject: string[];
13
+ export declare function apply(ctx: Context): void;
package/lib/agent.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Agent half of dsh-task-engine: registers the model-facing `dev_task` tool and
3
+ * the shipped engineering skills onto the calling (preset) scope. Name this row
4
+ * from a preset's `agent.cordis.yml` to activate the delivery flow for that
5
+ * preset's sessions; presets that never name it see neither the tool nor the
6
+ * skills.
7
+ *
8
+ * @module dsh-task-engine/agent
9
+ */
10
+ import { registerDevTask } from "./dev-task.js";
11
+ import { registerShippedSkills } from "./shipped-skills.js";
12
+ export const name = 'task-engine-agent';
13
+ export const inject = ['tools', 'fs'];
14
+ export function apply(ctx) {
15
+ registerDevTask(ctx);
16
+ registerShippedSkills(ctx);
17
+ }
18
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAE3D,MAAM,CAAC,MAAM,IAAI,GAAG,mBAAmB,CAAA;AACvC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AAErC,MAAM,UAAU,KAAK,CAAC,GAAY;IAChC,eAAe,CAAC,GAAG,CAAC,CAAA;IACpB,qBAAqB,CAAC,GAAG,CAAC,CAAA;AAC5B,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The model-facing `dev_task` tool: the hard engineering-delivery gate.
3
+ *
4
+ * This module owns the tool definition and every filesystem-adjacent helper it
5
+ * needs, so the registration can run on the AGENT plane (inside a preset's
6
+ * scope) rather than the host plane. Registering through a scoped context files
7
+ * the tool in that scope's layer — a session on another preset never sees it —
8
+ * while the pure state machine in {@link ../engine} and the config-facing
9
+ * `task-engine` Remote stay shared.
10
+ *
11
+ * @module dsh-task-engine/dev-task
12
+ */
13
+ import type { Context } from '@deepseek-ai/cordis';
14
+ /**
15
+ * Register the `dev_task` tool on the calling scope. Call from an agent-plane
16
+ * plugin (a row in `agent.cordis.yml`) so the tool is filed in that preset's
17
+ * scope layer and only sessions on that preset see it.
18
+ * @param ctx - a scoped context whose `tools` and `fs` resolve to the host registries.
19
+ */
20
+ export declare function registerDevTask(ctx: Context): void;
@@ -0,0 +1,370 @@
1
+ /**
2
+ * The model-facing `dev_task` tool: the hard engineering-delivery gate.
3
+ *
4
+ * This module owns the tool definition and every filesystem-adjacent helper it
5
+ * needs, so the registration can run on the AGENT plane (inside a preset's
6
+ * scope) rather than the host plane. Registering through a scoped context files
7
+ * the tool in that scope's layer — a session on another preset never sees it —
8
+ * while the pure state machine in {@link ../engine} and the config-facing
9
+ * `task-engine` Remote stay shared.
10
+ *
11
+ * @module dsh-task-engine/dev-task
12
+ */
13
+ import { readFileSync } from 'node:fs';
14
+ import { homedir } from 'node:os';
15
+ import { join } from 'node:path';
16
+ import { fileURLToPath } from 'node:url';
17
+ import { defineTool } from '@deepseek-ai/dsh-tools';
18
+ import { assertAdvance, bindingsForStage, checkFileScope, commitCheckpoint, legalTargets, loadWorkflow, newTask, validateCommitMessage, validateWorkflow, } from "./engine.js";
19
+ const DEFAULTS = JSON.parse(readFileSync(fileURLToPath(new URL('../defaults/eng.json', import.meta.url)), 'utf8'));
20
+ /** Bundled commit-msg hook, copied into `.git/hooks/` by the `install_hook` operation. */
21
+ const HOOK_TEMPLATE = readFileSync(fileURLToPath(new URL('../hooks/commit-msg', import.meta.url)), 'utf8');
22
+ /** Pins the hook directory to CommonJS so the extensionless hook runs under any repo `type`. */
23
+ const HOOK_PACKAGE_JSON = '{\n "type": "commonjs"\n}\n';
24
+ async function readText(fs, relPath) {
25
+ try {
26
+ const target = await fs.resolve(relPath);
27
+ return await fs.readText(target);
28
+ }
29
+ catch {
30
+ return undefined;
31
+ }
32
+ }
33
+ async function writeText(fs, relPath, content) {
34
+ const target = await fs.resolve(relPath);
35
+ await fs.writeText(target, content);
36
+ }
37
+ function sanitize(id) {
38
+ return id.replace(/[^0-9a-zA-Z_-]/g, '-');
39
+ }
40
+ const taskPath = (id) => `.dsh/task-${sanitize(id)}.json`;
41
+ /**
42
+ * Resolve the effective workflow, distinguishing a missing config from a bad one.
43
+ *
44
+ * `default` means no `.dsh/eng.json` (bundled defaults). `project` means the
45
+ * project config is present and structurally sound. `invalid` means the project
46
+ * config exists but is unparsable or fails {@link validateWorkflow}; its
47
+ * problems are surfaced so a misconfigured gate fails loudly instead of
48
+ * silently degrading to the default.
49
+ */
50
+ async function resolveWorkflow(fs) {
51
+ const raw = await readText(fs, '.dsh/eng.json');
52
+ if (raw === undefined)
53
+ return { config: DEFAULTS, problems: [], source: 'default' };
54
+ let parsed;
55
+ try {
56
+ parsed = JSON.parse(raw);
57
+ }
58
+ catch (error) {
59
+ return {
60
+ config: DEFAULTS,
61
+ problems: [`invalid JSON: ${error instanceof Error ? error.message : String(error)}`],
62
+ source: 'invalid',
63
+ };
64
+ }
65
+ const config = loadWorkflow(DEFAULTS, parsed);
66
+ const problems = validateWorkflow(config);
67
+ return { config, problems, source: problems.length === 0 ? 'project' : 'invalid' };
68
+ }
69
+ /** Write the bundled notch gate into `.git/hooks/` so `git commit` is mechanically gated. */
70
+ async function installCommitHook(fs) {
71
+ await writeText(fs, '.git/hooks/commit-msg', HOOK_TEMPLATE);
72
+ await writeText(fs, '.git/hooks/package.json', HOOK_PACKAGE_JSON);
73
+ }
74
+ async function loadTask(fs, id) {
75
+ const raw = await readText(fs, taskPath(id));
76
+ if (raw === undefined)
77
+ throw new Error(`no task "${id}" under ${taskPath(id)}`);
78
+ const state = JSON.parse(raw);
79
+ // Tasks recorded before these features lack the fields; treat them as empty.
80
+ state.artifacts = state.artifacts ?? {};
81
+ state.files = state.files ?? [];
82
+ return state;
83
+ }
84
+ async function writeTask(fs, state) {
85
+ await writeText(fs, taskPath(state.id), JSON.stringify(state, null, 2));
86
+ }
87
+ function dshHome() {
88
+ return process.env.DSH_HOME ?? join(homedir(), '.dsh');
89
+ }
90
+ /** Read a rule file with a hard path, or undefined. */
91
+ function readAbsRule(file) {
92
+ try {
93
+ return readFileSync(file, 'utf8');
94
+ }
95
+ catch {
96
+ return undefined;
97
+ }
98
+ }
99
+ /**
100
+ * Resolve rule contents by name, project first, then user home, then bundled.
101
+ * @param names - rule names from the current stage binding.
102
+ * @param fs - sandboxed filesystem for the project-level lookup.
103
+ * @returns the rules that resolved, in name order, with their bodies.
104
+ */
105
+ async function resolveRules(names, fs) {
106
+ const result = [];
107
+ for (const rawName of names) {
108
+ const name = sanitize(rawName);
109
+ if (name === '')
110
+ continue;
111
+ const project = await readText(fs, `.dsh/rules/${name}.md`);
112
+ if (project !== undefined) {
113
+ result.push({ name: rawName, content: project });
114
+ continue;
115
+ }
116
+ const user = readAbsRule(join(dshHome(), 'rules', `${name}.md`));
117
+ if (user !== undefined) {
118
+ result.push({ name: rawName, content: user });
119
+ continue;
120
+ }
121
+ const bundled = readAbsRule(fileURLToPath(new URL(`../rules/${name}.md`, import.meta.url)));
122
+ if (bundled !== undefined)
123
+ result.push({ name: rawName, content: bundled });
124
+ }
125
+ return result;
126
+ }
127
+ /**
128
+ * Render a stage's progressive-disclosure payload: skill names to load via the
129
+ * `skill` tool, plus the resolved rule bodies to follow. Empty text means the
130
+ * stage declares no bindings.
131
+ * @param stage - current stage.
132
+ * @param workflow - effective workflow.
133
+ * @param fs - host filesystem for project-rule resolution.
134
+ * @returns the disclosure text, or an empty string.
135
+ */
136
+ async function renderBindings(stage, workflow, fs) {
137
+ const binding = bindingsForStage(stage, workflow);
138
+ const skills = binding?.skills ?? [];
139
+ const ruleNames = binding?.rules ?? [];
140
+ if (binding === undefined || (skills.length === 0 && ruleNames.length === 0))
141
+ return '';
142
+ const rules = await resolveRules(ruleNames, fs);
143
+ const skillPart = skills.length > 0
144
+ ? `skills to load: ${skills.join(', ')} (use the skill tool by name)`
145
+ : 'skills to load: none';
146
+ const rulePart = rules.length > 0
147
+ ? `rules for this stage:\n${rules.map(r => `### ${r.name}\n${r.content}`).join('\n\n')}`
148
+ : '';
149
+ return [skillPart, rulePart].filter(Boolean).join('\n');
150
+ }
151
+ /** Normalize the tool's `items` argument into complete TaskItem records. */
152
+ function normalizeItems(items) {
153
+ return (items ?? []).map(item => ({
154
+ id: String(item.id ?? ''),
155
+ title: String(item.title ?? ''),
156
+ status: item.status ?? 'todo',
157
+ }));
158
+ }
159
+ const OPERATIONS = ['status', 'create', 'confirm', 'record', 'items', 'scope', 'advance', 'verify', 'review', 'commit', 'config', 'install_hook'];
160
+ const TOOL_DESCRIPTION = 'Own the engineering delivery workflow as hard state. Read or create the task record, record a ' +
161
+ 'confirmation or a stage artifact, advance one stage (rejected unless every configured guard already ' +
162
+ 'holds, including the stage artifacts), record verification or review, and gate a commit on ' +
163
+ 'stage/scope/message. The tool refuses illegal moves instead of degrading — treat a rejection as a ' +
164
+ 'fact to fix, not a prompt to retry another way.';
165
+ /**
166
+ * Register the `dev_task` tool on the calling scope. Call from an agent-plane
167
+ * plugin (a row in `agent.cordis.yml`) so the tool is filed in that preset's
168
+ * scope layer and only sessions on that preset see it.
169
+ * @param ctx - a scoped context whose `tools` and `fs` resolve to the host registries.
170
+ */
171
+ export function registerDevTask(ctx) {
172
+ ctx.tools.register(defineTool({
173
+ name: 'dev_task',
174
+ description: TOOL_DESCRIPTION,
175
+ parameters: {
176
+ operation: { type: 'string', enum: [...OPERATIONS], required: true, description: 'Which task-record action to perform.' },
177
+ task_id: { type: 'string', description: 'Task id (short stable id like GREET-001); required on create and every other operation.' },
178
+ branch: { type: 'string', description: 'Current git branch (recorded on create).' },
179
+ title: { type: 'string', description: 'Task title (create).' },
180
+ work_size: { type: 'string', enum: ['tiny', 'standard', 'complex'], description: 'Workload tier (create).' },
181
+ risk_level: { type: 'string', enum: ['standard', 'high_risk'], description: 'Risk tier (create).' },
182
+ items: {
183
+ type: 'array',
184
+ description: 'Implementation items (create/update).',
185
+ items: {
186
+ type: 'object',
187
+ additionalProperties: false,
188
+ properties: {
189
+ id: { type: 'string' },
190
+ title: { type: 'string' },
191
+ status: { type: 'string', enum: ['todo', 'doing', 'done'] },
192
+ },
193
+ },
194
+ },
195
+ field: { type: 'string', enum: ['requirement', 'solution'], description: 'Which confirmation (confirm).' },
196
+ target_stage: { type: 'string', description: 'Stage to advance to (advance).' },
197
+ passed: { type: 'boolean', description: 'Verification passed (verify).' },
198
+ evidence: { type: 'array', items: { type: 'string' }, description: 'Verification evidence (verify).' },
199
+ outcome: { type: 'string', enum: ['pass', 'blocked'], description: 'Review outcome (review).' },
200
+ artifact: { type: 'string', description: 'Artifact id to record fields for (record).' },
201
+ fields: {
202
+ type: 'object',
203
+ description: 'Field values for the artifact (record).',
204
+ additionalProperties: true,
205
+ },
206
+ files: {
207
+ type: 'array',
208
+ items: { type: 'string' },
209
+ description: 'Repo-relative paths in scope (create/scope) or being committed (commit).',
210
+ },
211
+ message: { type: 'string', description: 'Commit summary to validate (commit).' },
212
+ hash: { type: 'string', description: 'Commit hash to record after the git commit (commit).' },
213
+ },
214
+ output: {
215
+ schema: { type: 'string' },
216
+ render(_args, value) {
217
+ return [{ type: 'text', text: value }];
218
+ },
219
+ },
220
+ async execute(args) {
221
+ const a = args;
222
+ const fs = ctx.fs;
223
+ if (a.operation === 'config') {
224
+ const resolved = await resolveWorkflow(fs);
225
+ return JSON.stringify({
226
+ source: resolved.source,
227
+ valid: resolved.problems.length === 0,
228
+ problems: resolved.problems,
229
+ workflow: resolved.config,
230
+ }, null, 2);
231
+ }
232
+ if (a.operation === 'install_hook') {
233
+ await installCommitHook(fs);
234
+ return 'installed commit-msg hook at .git/hooks/commit-msg — git commit is now gated by the task state';
235
+ }
236
+ const resolved = await resolveWorkflow(fs);
237
+ if (resolved.problems.length > 0) {
238
+ throw new Error(`invalid .dsh/eng.json — fix the project config first:\n- ${resolved.problems.join('\n- ')}`);
239
+ }
240
+ const workflow = resolved.config;
241
+ if (a.operation === 'create') {
242
+ if (!a.task_id || !a.title || !a.branch) {
243
+ throw new Error('create requires task_id, title, and branch');
244
+ }
245
+ const state = newTask({
246
+ id: a.task_id,
247
+ title: a.title,
248
+ branch: a.branch,
249
+ work_size: a.work_size ?? 'standard',
250
+ risk_level: a.risk_level ?? 'standard',
251
+ }, workflow);
252
+ state.items = normalizeItems(a.items);
253
+ state.files = a.files ?? [];
254
+ await writeTask(fs, state);
255
+ return `created ${state.id} at stage ${state.stage}; legal next: ${legalTargets(state.stage, workflow).join(', ') || 'none'}`;
256
+ }
257
+ if (!a.task_id)
258
+ throw new Error('task_id is required for this operation');
259
+ const state = await loadTask(fs, a.task_id);
260
+ if (a.operation === 'status') {
261
+ const binding = bindingsForStage(state.stage, workflow);
262
+ const rules = await resolveRules(binding?.rules ?? [], fs);
263
+ return JSON.stringify({
264
+ id: state.id,
265
+ stage: state.stage,
266
+ risk_level: state.risk_level,
267
+ work_size: state.work_size,
268
+ requirement_confirmed: state.requirement_confirmed,
269
+ solution_confirmed: state.solution_confirmed,
270
+ items_done: `${state.items.filter(i => i.status === 'done').length}/${state.items.length}`,
271
+ verification: state.verification,
272
+ review: state.review,
273
+ artifacts: state.artifacts,
274
+ files: state.files,
275
+ legal_next: legalTargets(state.stage, workflow),
276
+ commit: commitCheckpoint(state, workflow),
277
+ bindings: {
278
+ skills: binding?.skills ?? [],
279
+ rules: rules.map(r => ({ name: r.name, content: r.content })),
280
+ },
281
+ }, null, 2);
282
+ }
283
+ if (a.operation === 'commit') {
284
+ const checkpoint = commitCheckpoint(state, workflow);
285
+ if (!checkpoint.allowed)
286
+ throw new Error(checkpoint.reason ?? 'no commit is due');
287
+ if (workflow.commit.file_scope) {
288
+ if (!a.files || a.files.length === 0) {
289
+ throw new Error('commit requires files (the repo-relative paths being committed) when file_scope is on');
290
+ }
291
+ const scope = checkFileScope(state, a.files, workflow);
292
+ if (!scope.ok) {
293
+ throw new Error(scope.noScope
294
+ ? 'task declares no file scope; record files first (create files=... or scope files=...)'
295
+ : `commit touches files outside the task scope: ${scope.outside.join(', ')}`);
296
+ }
297
+ }
298
+ const message = validateCommitMessage(a.message ?? '', workflow);
299
+ if (!message.ok)
300
+ throw new Error(message.errors.join('; '));
301
+ if (a.hash)
302
+ state.commits.push({ label: checkpoint.label, hash: a.hash });
303
+ await writeTask(fs, state);
304
+ return `commit approved (${checkpoint.label ?? ''}) — git add ${(a.files ?? []).join(' ')}; git commit -m "${a.message ?? ''}"`;
305
+ }
306
+ let note;
307
+ switch (a.operation) {
308
+ case 'confirm':
309
+ if (a.field === 'requirement')
310
+ state.requirement_confirmed = true;
311
+ else if (a.field === 'solution')
312
+ state.solution_confirmed = true;
313
+ else
314
+ throw new Error('confirm requires field: requirement|solution');
315
+ break;
316
+ case 'record': {
317
+ if (!a.artifact)
318
+ throw new Error('record requires artifact (the artifact id)');
319
+ const def = workflow.artifacts.find(artifact => artifact.id === a.artifact);
320
+ if (!def) {
321
+ throw new Error(`unknown artifact "${a.artifact}"; declared: ${workflow.artifacts.map(x => x.id).join(', ') || 'none'}`);
322
+ }
323
+ const merged = { ...(state.artifacts[def.id] ?? {}) };
324
+ for (const [field, value] of Object.entries(a.fields ?? {})) {
325
+ if (!def.fields.includes(field)) {
326
+ throw new Error(`artifact "${def.id}" has no field "${field}"; fields: ${def.fields.join(', ')}`);
327
+ }
328
+ merged[field] = value === undefined || value === null ? '' : String(value);
329
+ }
330
+ state.artifacts[def.id] = merged;
331
+ const missing = def.fields.filter(field => !merged[field] || merged[field].trim() === '');
332
+ note = missing.length === 0
333
+ ? `recorded ${def.name} ("${def.id}") — all required fields present`
334
+ : `recorded ${def.name} ("${def.id}"); still missing: ${missing.join(', ')}`;
335
+ break;
336
+ }
337
+ case 'scope':
338
+ state.files = a.files ?? [];
339
+ note = `file scope set to ${state.files.length} files${state.files.length > 0 ? ': ' + state.files.join(', ') : ' (empty — commits are blocked until files are declared)'}`;
340
+ break;
341
+ case 'items':
342
+ state.items = normalizeItems(a.items);
343
+ note = `items set: ${state.items.map(i => `${i.id}:${i.status}`).join(', ') || 'none'}`;
344
+ break;
345
+ case 'advance': {
346
+ const result = assertAdvance(state, a.target_stage ?? '', workflow);
347
+ if (!result.ok)
348
+ throw new Error(result.errors.join('; '));
349
+ state.stage = a.target_stage;
350
+ const disclosure = await renderBindings(state.stage, workflow, fs);
351
+ note = disclosure === '' ? `advanced to ${state.stage}` : `advanced to ${state.stage}\n${disclosure}`;
352
+ break;
353
+ }
354
+ case 'verify':
355
+ state.verification = { passed: a.passed === true, evidence: a.evidence ?? [] };
356
+ break;
357
+ case 'review':
358
+ if (a.outcome !== 'pass' && a.outcome !== 'blocked')
359
+ throw new Error('review requires outcome: pass|blocked');
360
+ state.review.outcome = a.outcome;
361
+ break;
362
+ default:
363
+ throw new Error(`unknown operation ${a.operation}`);
364
+ }
365
+ await writeTask(fs, state);
366
+ return note ?? `ok (stage ${state.stage})`;
367
+ },
368
+ }));
369
+ }
370
+ //# sourceMappingURL=dev-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-task.js","sourceRoot":"","sources":["../src/dev-task.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  /**
2
- * dsh-task-engine plugin: registers the model-facing `dev_task` tool (the hard
3
- * gate) and ships the bundled engineering skills.
2
+ * Host half of dsh-task-engine: mounts the `task-engine` Remote namespace that
3
+ * the browser workbench reads/writes, plus the browser half (declared via
4
+ * `dsh.client`). The model-facing `dev_task` tool and the shipped engineering
5
+ * skills live on the AGENT plane (`./agent`), so a session activates them only
6
+ * when its preset names the `@godv61/dsh-task-engine/agent` row.
4
7
  *
5
8
  * @module dsh-task-engine
6
9
  */
7
10
  import type { Context } from '@deepseek-ai/cordis';
8
11
  export declare const name = "task-engine";
9
- export declare const inject: string[];
10
12
  export declare function apply(ctx: Context): void;
package/lib/index.js CHANGED
@@ -1,392 +1,15 @@
1
1
  /**
2
- * dsh-task-engine plugin: registers the model-facing `dev_task` tool (the hard
3
- * gate) and ships the bundled engineering skills.
2
+ * Host half of dsh-task-engine: mounts the `task-engine` Remote namespace that
3
+ * the browser workbench reads/writes, plus the browser half (declared via
4
+ * `dsh.client`). The model-facing `dev_task` tool and the shipped engineering
5
+ * skills live on the AGENT plane (`./agent`), so a session activates them only
6
+ * when its preset names the `@godv61/dsh-task-engine/agent` row.
4
7
  *
5
8
  * @module dsh-task-engine
6
9
  */
7
- import { readFileSync, readdirSync } from 'node:fs';
8
- import { homedir } from 'node:os';
9
- import { join } from 'node:path';
10
- import { fileURLToPath } from 'node:url';
11
- import { defineTool } from '@deepseek-ai/dsh-tools';
12
10
  import TaskEngineController from "./controller.js";
13
- import { assertAdvance, bindingsForStage, checkFileScope, commitCheckpoint, legalTargets, loadWorkflow, newTask, validateCommitMessage, validateWorkflow, } from "./engine.js";
14
11
  export const name = 'task-engine';
15
- export const inject = ['tools', 'fs'];
16
- const DEFAULTS = JSON.parse(readFileSync(fileURLToPath(new URL('../defaults/eng.json', import.meta.url)), 'utf8'));
17
- /** Bundled commit-msg hook, copied into `.git/hooks/` by the `install_hook` operation. */
18
- const HOOK_TEMPLATE = readFileSync(fileURLToPath(new URL('../hooks/commit-msg', import.meta.url)), 'utf8');
19
- /** Pins the hook directory to CommonJS so the extensionless hook runs under any repo `type`. */
20
- const HOOK_PACKAGE_JSON = '{\n "type": "commonjs"\n}\n';
21
- async function readText(fs, relPath) {
22
- try {
23
- const target = await fs.resolve(relPath);
24
- return await fs.readText(target);
25
- }
26
- catch {
27
- return undefined;
28
- }
29
- }
30
- async function writeText(fs, relPath, content) {
31
- const target = await fs.resolve(relPath);
32
- await fs.writeText(target, content);
33
- }
34
- function sanitize(id) {
35
- return id.replace(/[^0-9a-zA-Z_-]/g, '-');
36
- }
37
- const taskPath = (id) => `.dsh/task-${sanitize(id)}.json`;
38
- /**
39
- * Resolve the effective workflow, distinguishing a missing config from a bad one.
40
- *
41
- * `default` means no `.dsh/eng.json` (bundled defaults). `project` means the
42
- * project config is present and structurally sound. `invalid` means the project
43
- * config exists but is unparsable or fails {@link validateWorkflow}; its
44
- * problems are surfaced so a misconfigured gate fails loudly instead of
45
- * silently degrading to the default.
46
- */
47
- async function resolveWorkflow(fs) {
48
- const raw = await readText(fs, '.dsh/eng.json');
49
- if (raw === undefined)
50
- return { config: DEFAULTS, problems: [], source: 'default' };
51
- let parsed;
52
- try {
53
- parsed = JSON.parse(raw);
54
- }
55
- catch (error) {
56
- return {
57
- config: DEFAULTS,
58
- problems: [`invalid JSON: ${error instanceof Error ? error.message : String(error)}`],
59
- source: 'invalid',
60
- };
61
- }
62
- const config = loadWorkflow(DEFAULTS, parsed);
63
- const problems = validateWorkflow(config);
64
- return { config, problems, source: problems.length === 0 ? 'project' : 'invalid' };
65
- }
66
- /** Write the bundled notch gate into `.git/hooks/` so `git commit` is mechanically gated. */
67
- async function installCommitHook(fs) {
68
- await writeText(fs, '.git/hooks/commit-msg', HOOK_TEMPLATE);
69
- await writeText(fs, '.git/hooks/package.json', HOOK_PACKAGE_JSON);
70
- }
71
- async function loadTask(fs, id) {
72
- const raw = await readText(fs, taskPath(id));
73
- if (raw === undefined)
74
- throw new Error(`no task "${id}" under ${taskPath(id)}`);
75
- const state = JSON.parse(raw);
76
- // Tasks recorded before these features lack the fields; treat them as empty.
77
- state.artifacts = state.artifacts ?? {};
78
- state.files = state.files ?? [];
79
- return state;
80
- }
81
- async function writeTask(fs, state) {
82
- await writeText(fs, taskPath(state.id), JSON.stringify(state, null, 2));
83
- }
84
- function dshHome() {
85
- return process.env.DSH_HOME ?? join(homedir(), '.dsh');
86
- }
87
- /** Read a rule file with a hard path, or undefined. */
88
- function readAbsRule(file) {
89
- try {
90
- return readFileSync(file, 'utf8');
91
- }
92
- catch {
93
- return undefined;
94
- }
95
- }
96
- /**
97
- * Resolve rule contents by name, project first, then user home, then bundled.
98
- * @param names - rule names from the current stage binding.
99
- * @param fs - sandboxed filesystem for the project-level lookup.
100
- * @returns the rules that resolved, in name order, with their bodies.
101
- */
102
- async function resolveRules(names, fs) {
103
- const result = [];
104
- for (const rawName of names) {
105
- const name = sanitize(rawName);
106
- if (name === '')
107
- continue;
108
- const project = await readText(fs, `.dsh/rules/${name}.md`);
109
- if (project !== undefined) {
110
- result.push({ name: rawName, content: project });
111
- continue;
112
- }
113
- const user = readAbsRule(join(dshHome(), 'rules', `${name}.md`));
114
- if (user !== undefined) {
115
- result.push({ name: rawName, content: user });
116
- continue;
117
- }
118
- const bundled = readAbsRule(fileURLToPath(new URL(`../rules/${name}.md`, import.meta.url)));
119
- if (bundled !== undefined)
120
- result.push({ name: rawName, content: bundled });
121
- }
122
- return result;
123
- }
124
- /**
125
- * Render a stage's progressive-disclosure payload: skill names to load via the
126
- * `skill` tool, plus the resolved rule bodies to follow. Empty text means the
127
- * stage declares no bindings.
128
- * @param stage - current stage.
129
- * @param workflow - effective workflow.
130
- * @param fs - host filesystem for project-rule resolution.
131
- * @returns the disclosure text, or an empty string.
132
- */
133
- async function renderBindings(stage, workflow, fs) {
134
- const binding = bindingsForStage(stage, workflow);
135
- const skills = binding?.skills ?? [];
136
- const ruleNames = binding?.rules ?? [];
137
- if (binding === undefined || (skills.length === 0 && ruleNames.length === 0))
138
- return '';
139
- const rules = await resolveRules(ruleNames, fs);
140
- const skillPart = skills.length > 0
141
- ? `skills to load: ${skills.join(', ')} (use the skill tool by name)`
142
- : 'skills to load: none';
143
- const rulePart = rules.length > 0
144
- ? `rules for this stage:\n${rules.map(r => `### ${r.name}\n${r.content}`).join('\n\n')}`
145
- : '';
146
- return [skillPart, rulePart].filter(Boolean).join('\n');
147
- }
148
- /** Normalize the tool's `items` argument into complete TaskItem records. */
149
- function normalizeItems(items) {
150
- return (items ?? []).map(item => ({
151
- id: String(item.id ?? ''),
152
- title: String(item.title ?? ''),
153
- status: item.status ?? 'todo',
154
- }));
155
- }
156
- const OPERATIONS = ['status', 'create', 'confirm', 'record', 'items', 'scope', 'advance', 'verify', 'review', 'commit', 'config', 'install_hook'];
157
- const TOOL_DESCRIPTION = 'Own the engineering delivery workflow as hard state. Read or create the task record, record a ' +
158
- 'confirmation or a stage artifact, advance one stage (rejected unless every configured guard already ' +
159
- 'holds, including the stage artifacts), record verification or review, and gate a commit on ' +
160
- 'stage/scope/message. The tool refuses illegal moves instead of degrading — treat a rejection as a ' +
161
- 'fact to fix, not a prompt to retry another way.';
162
12
  export function apply(ctx) {
163
13
  ctx.plugin(TaskEngineController);
164
- ctx.tools.register(defineTool({
165
- name: 'dev_task',
166
- description: TOOL_DESCRIPTION,
167
- parameters: {
168
- operation: { type: 'string', enum: [...OPERATIONS], required: true, description: 'Which task-record action to perform.' },
169
- task_id: { type: 'string', description: 'Task id (short stable id like GREET-001); required on create and every other operation.' },
170
- branch: { type: 'string', description: 'Current git branch (recorded on create).' },
171
- title: { type: 'string', description: 'Task title (create).' },
172
- work_size: { type: 'string', enum: ['tiny', 'standard', 'complex'], description: 'Workload tier (create).' },
173
- risk_level: { type: 'string', enum: ['standard', 'high_risk'], description: 'Risk tier (create).' },
174
- items: {
175
- type: 'array',
176
- description: 'Implementation items (create/update).',
177
- items: {
178
- type: 'object',
179
- additionalProperties: false,
180
- properties: {
181
- id: { type: 'string' },
182
- title: { type: 'string' },
183
- status: { type: 'string', enum: ['todo', 'doing', 'done'] },
184
- },
185
- },
186
- },
187
- field: { type: 'string', enum: ['requirement', 'solution'], description: 'Which confirmation (confirm).' },
188
- target_stage: { type: 'string', description: 'Stage to advance to (advance).' },
189
- passed: { type: 'boolean', description: 'Verification passed (verify).' },
190
- evidence: { type: 'array', items: { type: 'string' }, description: 'Verification evidence (verify).' },
191
- outcome: { type: 'string', enum: ['pass', 'blocked'], description: 'Review outcome (review).' },
192
- artifact: { type: 'string', description: 'Artifact id to record fields for (record).' },
193
- fields: {
194
- type: 'object',
195
- description: 'Field values for the artifact (record).',
196
- additionalProperties: true,
197
- },
198
- files: {
199
- type: 'array',
200
- items: { type: 'string' },
201
- description: 'Repo-relative paths in scope (create/scope) or being committed (commit).',
202
- },
203
- message: { type: 'string', description: 'Commit summary to validate (commit).' },
204
- hash: { type: 'string', description: 'Commit hash to record after the git commit (commit).' },
205
- },
206
- output: {
207
- schema: { type: 'string' },
208
- render(_args, value) {
209
- return [{ type: 'text', text: value }];
210
- },
211
- },
212
- async execute(args) {
213
- const a = args;
214
- if (a.operation === 'config') {
215
- const resolved = await resolveWorkflow(ctx.fs);
216
- return JSON.stringify({
217
- source: resolved.source,
218
- valid: resolved.problems.length === 0,
219
- problems: resolved.problems,
220
- workflow: resolved.config,
221
- }, null, 2);
222
- }
223
- if (a.operation === 'install_hook') {
224
- await installCommitHook(ctx.fs);
225
- return 'installed commit-msg hook at .git/hooks/commit-msg — git commit is now gated by the task state';
226
- }
227
- const resolved = await resolveWorkflow(ctx.fs);
228
- if (resolved.problems.length > 0) {
229
- throw new Error(`invalid .dsh/eng.json — fix the project config first:\n- ${resolved.problems.join('\n- ')}`);
230
- }
231
- const workflow = resolved.config;
232
- if (a.operation === 'create') {
233
- if (!a.task_id || !a.title || !a.branch) {
234
- throw new Error('create requires task_id, title, and branch');
235
- }
236
- const state = newTask({
237
- id: a.task_id,
238
- title: a.title,
239
- branch: a.branch,
240
- work_size: a.work_size ?? 'standard',
241
- risk_level: a.risk_level ?? 'standard',
242
- }, workflow);
243
- state.items = normalizeItems(a.items);
244
- state.files = a.files ?? [];
245
- await writeTask(ctx.fs, state);
246
- return `created ${state.id} at stage ${state.stage}; legal next: ${legalTargets(state.stage, workflow).join(', ') || 'none'}`;
247
- }
248
- if (!a.task_id)
249
- throw new Error('task_id is required for this operation');
250
- const state = await loadTask(ctx.fs, a.task_id);
251
- if (a.operation === 'status') {
252
- const binding = bindingsForStage(state.stage, workflow);
253
- const rules = await resolveRules(binding?.rules ?? [], ctx.fs);
254
- return JSON.stringify({
255
- id: state.id,
256
- stage: state.stage,
257
- risk_level: state.risk_level,
258
- work_size: state.work_size,
259
- requirement_confirmed: state.requirement_confirmed,
260
- solution_confirmed: state.solution_confirmed,
261
- items_done: `${state.items.filter(i => i.status === 'done').length}/${state.items.length}`,
262
- verification: state.verification,
263
- review: state.review,
264
- artifacts: state.artifacts,
265
- files: state.files,
266
- legal_next: legalTargets(state.stage, workflow),
267
- commit: commitCheckpoint(state, workflow),
268
- bindings: {
269
- skills: binding?.skills ?? [],
270
- rules: rules.map(r => ({ name: r.name, content: r.content })),
271
- },
272
- }, null, 2);
273
- }
274
- if (a.operation === 'commit') {
275
- const checkpoint = commitCheckpoint(state, workflow);
276
- if (!checkpoint.allowed)
277
- throw new Error(checkpoint.reason ?? 'no commit is due');
278
- if (workflow.commit.file_scope) {
279
- if (!a.files || a.files.length === 0) {
280
- throw new Error('commit requires files (the repo-relative paths being committed) when file_scope is on');
281
- }
282
- const scope = checkFileScope(state, a.files, workflow);
283
- if (!scope.ok) {
284
- throw new Error(scope.noScope
285
- ? 'task declares no file scope; record files first (create files=... or scope files=...)'
286
- : `commit touches files outside the task scope: ${scope.outside.join(', ')}`);
287
- }
288
- }
289
- const message = validateCommitMessage(a.message ?? '', workflow);
290
- if (!message.ok)
291
- throw new Error(message.errors.join('; '));
292
- if (a.hash)
293
- state.commits.push({ label: checkpoint.label, hash: a.hash });
294
- await writeTask(ctx.fs, state);
295
- return `commit approved (${checkpoint.label ?? ''}) — git add ${(a.files ?? []).join(' ')}; git commit -m "${a.message ?? ''}"`;
296
- }
297
- let note;
298
- switch (a.operation) {
299
- case 'confirm':
300
- if (a.field === 'requirement')
301
- state.requirement_confirmed = true;
302
- else if (a.field === 'solution')
303
- state.solution_confirmed = true;
304
- else
305
- throw new Error('confirm requires field: requirement|solution');
306
- break;
307
- case 'record': {
308
- if (!a.artifact)
309
- throw new Error('record requires artifact (the artifact id)');
310
- const def = workflow.artifacts.find(artifact => artifact.id === a.artifact);
311
- if (!def) {
312
- throw new Error(`unknown artifact "${a.artifact}"; declared: ${workflow.artifacts.map(x => x.id).join(', ') || 'none'}`);
313
- }
314
- const merged = { ...(state.artifacts[def.id] ?? {}) };
315
- for (const [field, value] of Object.entries(a.fields ?? {})) {
316
- if (!def.fields.includes(field)) {
317
- throw new Error(`artifact "${def.id}" has no field "${field}"; fields: ${def.fields.join(', ')}`);
318
- }
319
- merged[field] = value === undefined || value === null ? '' : String(value);
320
- }
321
- state.artifacts[def.id] = merged;
322
- const missing = def.fields.filter(field => !merged[field] || merged[field].trim() === '');
323
- note = missing.length === 0
324
- ? `recorded ${def.name} ("${def.id}") — all required fields present`
325
- : `recorded ${def.name} ("${def.id}"); still missing: ${missing.join(', ')}`;
326
- break;
327
- }
328
- case 'scope':
329
- state.files = a.files ?? [];
330
- note = `file scope set to ${state.files.length} files${state.files.length > 0 ? ': ' + state.files.join(', ') : ' (empty — commits are blocked until files are declared)'}`;
331
- break;
332
- case 'items':
333
- state.items = normalizeItems(a.items);
334
- note = `items set: ${state.items.map(i => `${i.id}:${i.status}`).join(', ') || 'none'}`;
335
- break;
336
- case 'advance': {
337
- const result = assertAdvance(state, a.target_stage ?? '', workflow);
338
- if (!result.ok)
339
- throw new Error(result.errors.join('; '));
340
- state.stage = a.target_stage;
341
- const disclosure = await renderBindings(state.stage, workflow, ctx.fs);
342
- note = disclosure === '' ? `advanced to ${state.stage}` : `advanced to ${state.stage}\n${disclosure}`;
343
- break;
344
- }
345
- case 'verify':
346
- state.verification = { passed: a.passed === true, evidence: a.evidence ?? [] };
347
- break;
348
- case 'review':
349
- if (a.outcome !== 'pass' && a.outcome !== 'blocked')
350
- throw new Error('review requires outcome: pass|blocked');
351
- state.review.outcome = a.outcome;
352
- break;
353
- default:
354
- throw new Error(`unknown operation ${a.operation}`);
355
- }
356
- await writeTask(ctx.fs, state);
357
- return note ?? `ok (stage ${state.stage})`;
358
- },
359
- }));
360
- // Ship the bundled engineering skills into this bundle's layer of the host
361
- // skill registry (optional surface: skip when the registry is absent).
362
- const skills = ctx.get('skills');
363
- if (skills !== undefined) {
364
- const skillsRoot = fileURLToPath(new URL('../skills/', import.meta.url));
365
- for (const entry of readdirSync(skillsRoot, { withFileTypes: true })) {
366
- if (!entry.isDirectory())
367
- continue;
368
- const raw = readFileSync(fileURLToPath(new URL(`../skills/${entry.name}/SKILL.md`, import.meta.url)), 'utf8');
369
- const m = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
370
- if (!m)
371
- continue;
372
- const head = m[1];
373
- const body = m[2];
374
- const meta = {};
375
- for (const line of head.split('\n')) {
376
- const i = line.indexOf(':');
377
- if (i > 0)
378
- meta[line.slice(0, i).trim()] = line.slice(i + 1).trim();
379
- }
380
- if (!meta.name || !meta.description)
381
- continue;
382
- skills.register({
383
- name: meta.name,
384
- description: meta.description,
385
- ...(meta.whenToUse !== undefined ? { whenToUse: meta.whenToUse } : {}),
386
- content: body,
387
- source: 'custom',
388
- });
389
- }
390
- }
391
14
  }
392
15
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGnD,OAAO,oBAAoB,MAAM,iBAAiB,CAAA;AAClD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,qBAAqB,EACrB,gBAAgB,GAIjB,MAAM,aAAa,CAAA;AAEpB,MAAM,CAAC,MAAM,IAAI,GAAG,aAAa,CAAA;AACjC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AAErC,MAAM,QAAQ,GAAmB,IAAI,CAAC,KAAK,CACzC,YAAY,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,sBAAsB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CACpE,CAAA;AAEnB,0FAA0F;AAC1F,MAAM,aAAa,GAAG,YAAY,CAChC,aAAa,CAAC,IAAI,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CACvE,CAAA;AAED,gGAAgG;AAChG,MAAM,iBAAiB,GAAG,8BAA8B,CAAA;AAIxD,KAAK,UAAU,QAAQ,CAAC,EAAM,EAAE,OAAe;IAC7C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACxC,OAAO,MAAO,EAAgE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACjG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,EAAM,EAAE,OAAe,EAAE,OAAe;IAC/D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IACxC,MAAO,EAAmF,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AACvH,CAAC;AAED,SAAS,QAAQ,CAAC,EAAU;IAC1B,OAAO,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAA;AAC3C,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,aAAa,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAA;AAQzE;;;;;;;;GAQG;AACH,KAAK,UAAU,eAAe,CAAC,EAAM;IACnC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,eAAe,CAAC,CAAA;IAC/C,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IACnF,IAAI,MAA+B,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAA;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAE,CAAC,iBAAiB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACrF,MAAM,EAAE,SAAS;SAClB,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IACzC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAA;AACpF,CAAC;AAED,6FAA6F;AAC7F,KAAK,UAAU,iBAAiB,CAAC,EAAM;IACrC,MAAM,SAAS,CAAC,EAAE,EAAE,uBAAuB,EAAE,aAAa,CAAC,CAAA;IAC3D,MAAM,SAAS,CAAC,EAAE,EAAE,yBAAyB,EAAE,iBAAiB,CAAC,CAAA;AACnE,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,EAAM,EAAE,EAAU;IACxC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;IAC5C,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,YAAY,EAAE,WAAW,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAC/E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAA;IAC1C,6EAA6E;IAC7E,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,EAAE,CAAA;IACvC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAA;IAC/B,OAAO,KAAK,CAAA;AACd,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,EAAM,EAAE,KAAgB;IAC/C,MAAM,SAAS,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AACzE,CAAC;AAED,SAAS,OAAO;IACd,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAA;AACxD,CAAC;AAED,uDAAuD;AACvD,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,YAAY,CAAC,KAAe,EAAE,EAAM;IACjD,MAAM,MAAM,GAAwC,EAAE,CAAA;IACtD,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC9B,IAAI,IAAI,KAAK,EAAE;YAAE,SAAQ;QACzB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,cAAc,IAAI,KAAK,CAAC,CAAA;QAC3D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;YAChD,SAAQ;QACV,CAAC;QACD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC,CAAA;QAChE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;YAC7C,SAAQ;QACV,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAC3F,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IAC7E,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,QAAwB,EAAE,EAAM;IAC3E,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACjD,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,CAAA;IACpC,MAAM,SAAS,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAA;IACtC,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,CAAA;IACvF,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;IAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC;QACjC,CAAC,CAAC,mBAAmB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,gCAAgC;QACtE,CAAC,CAAC,sBAAsB,CAAA;IAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC;QAC/B,CAAC,CAAC,0BAA0B,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACxF,CAAC,CAAC,EAAE,CAAA;IACN,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzD,CAAC;AAuBD,4EAA4E;AAC5E,SAAS,cAAc,CAAC,KAAwF;IAC9G,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC/B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,MAAM;KAC9B,CAAC,CAAC,CAAA;AACL,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,CAAU,CAAA;AAE1J,MAAM,gBAAgB,GACpB,gGAAgG;IAChG,sGAAsG;IACtG,6FAA6F;IAC7F,oGAAoG;IACpG,iDAAiD,CAAA;AAEnD,MAAM,UAAU,KAAK,CAAC,GAAY;IAChC,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAChC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5B,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,gBAAgB;QAC7B,UAAU,EAAE;YACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sCAAsC,EAAE;YACzH,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yFAAyF,EAAE;YACnI,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0CAA0C,EAAE;YACnF,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;YAC9D,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,yBAAyB,EAAE;YAC5G,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,qBAAqB,EAAE;YACnG,KAAK,EAAE;gBACL,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,uCAAuC;gBACpD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,KAAK;oBAC3B,UAAU,EAAE;wBACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACtB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACzB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE;qBAC5D;iBACF;aACF;YACD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,UAAU,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE;YAC1G,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE;YAC/E,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,+BAA+B,EAAE;YACzE,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,iCAAiC,EAAE;YACtG,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,0BAA0B,EAAE;YAC/F,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,4CAA4C,EAAE;YACvF,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yCAAyC;gBACtD,oBAAoB,EAAE,IAAI;aAC3B;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,WAAW,EAAE,0EAA0E;aACxF;YACD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE;YAChF,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sDAAsD,EAAE;SAC9F;QACD,MAAM,EAAE;YACN,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,MAAM,CAAC,KAAc,EAAE,KAAa;gBAClC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;YACxC,CAAC;SACF;QACD,KAAK,CAAC,OAAO,CAAC,IAA6B;YACzC,MAAM,CAAC,GAAG,IAAyB,CAAA;YAEnC,IAAI,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;gBAC9C,OAAO,IAAI,CAAC,SAAS,CAAC;oBACpB,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;oBACrC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;oBAC3B,QAAQ,EAAE,QAAQ,CAAC,MAAM;iBAC1B,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;YACb,CAAC;YAED,IAAI,CAAC,CAAC,SAAS,KAAK,cAAc,EAAE,CAAC;gBACnC,MAAM,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;gBAC/B,OAAO,gGAAgG,CAAA;YACzG,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC9C,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjC,MAAM,IAAI,KAAK,CAAC,4DAA4D,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YAC/G,CAAC;YACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAA;YAEhC,IAAI,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC7B,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;oBACxC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;gBAC/D,CAAC;gBACD,MAAM,KAAK,GAAG,OAAO,CACnB;oBACE,EAAE,EAAE,CAAC,CAAC,OAAO;oBACb,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,UAAU;oBACpC,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,UAAU;iBACvC,EACD,QAAQ,CACT,CAAA;gBACD,KAAK,CAAC,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;gBACrC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;gBAC3B,MAAM,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;gBAC9B,OAAO,WAAW,KAAK,CAAC,EAAE,aAAa,KAAK,CAAC,KAAK,iBAAiB,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE,CAAA;YAC/H,CAAC;YAED,IAAI,CAAC,CAAC,CAAC,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;YACzE,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;YAE/C,IAAI,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;gBACvD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;gBAC9D,OAAO,IAAI,CAAC,SAAS,CAAC;oBACpB,EAAE,EAAE,KAAK,CAAC,EAAE;oBACZ,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;oBAClD,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;oBAC5C,UAAU,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE;oBAC1F,YAAY,EAAE,KAAK,CAAC,YAAY;oBAChC,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;oBAC/C,MAAM,EAAE,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC;oBACzC,QAAQ,EAAE;wBACR,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;wBAC7B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;qBAC9D;iBACF,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;YACb,CAAC;YAED,IAAI,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;gBACpD,IAAI,CAAC,UAAU,CAAC,OAAO;oBAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,kBAAkB,CAAC,CAAA;gBACjF,IAAI,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;oBAC/B,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACrC,MAAM,IAAI,KAAK,CAAC,uFAAuF,CAAC,CAAA;oBAC1G,CAAC;oBACD,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;oBACtD,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;wBACd,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO;4BAC3B,CAAC,CAAC,uFAAuF;4BACzF,CAAC,CAAC,gDAAgD,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;oBACjF,CAAC;gBACH,CAAC;gBACD,MAAM,OAAO,GAAG,qBAAqB,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAA;gBAChE,IAAI,CAAC,OAAO,CAAC,EAAE;oBAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;gBAC5D,IAAI,CAAC,CAAC,IAAI;oBAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;gBAC1E,MAAM,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;gBAC9B,OAAO,oBAAoB,UAAU,CAAC,KAAK,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,OAAO,IAAI,EAAE,GAAG,CAAA;YACjI,CAAC;YAED,IAAI,IAAwB,CAAA;YAC5B,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC;gBACpB,KAAK,SAAS;oBACZ,IAAI,CAAC,CAAC,KAAK,KAAK,aAAa;wBAAE,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAA;yBAC5D,IAAI,CAAC,CAAC,KAAK,KAAK,UAAU;wBAAE,KAAK,CAAC,kBAAkB,GAAG,IAAI,CAAA;;wBAC3D,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;oBACpE,MAAK;gBACP,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACd,IAAI,CAAC,CAAC,CAAC,QAAQ;wBAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAA;oBAC9E,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAA;oBAC3E,IAAI,CAAC,GAAG,EAAE,CAAC;wBACT,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,QAAQ,gBAAgB,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC,CAAA;oBAC1H,CAAC;oBACD,MAAM,MAAM,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAA;oBACrD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;wBAC5D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;4BAChC,MAAM,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,EAAE,mBAAmB,KAAK,cAAc,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;wBACnG,CAAC;wBACD,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;oBAC5E,CAAC;oBACD,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAA;oBAChC,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;oBACzF,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC;wBACzB,CAAC,CAAC,YAAY,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,kCAAkC;wBACpE,CAAC,CAAC,YAAY,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,sBAAsB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;oBAC9E,MAAK;gBACP,CAAC;gBACD,KAAK,OAAO;oBACV,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAA;oBAC3B,IAAI,GAAG,qBAAqB,KAAK,CAAC,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,yDAAyD,EAAE,CAAA;oBAC3K,MAAK;gBACP,KAAK,OAAO;oBACV,KAAK,CAAC,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;oBACrC,IAAI,GAAG,cAAc,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE,CAAA;oBACvF,MAAK;gBACP,KAAK,SAAS,CAAC,CAAC,CAAC;oBACf,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAA;oBACnE,IAAI,CAAC,MAAM,CAAC,EAAE;wBAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;oBAC1D,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,YAAa,CAAA;oBAC7B,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;oBACtE,IAAI,GAAG,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE,CAAA;oBACrG,MAAK;gBACP,CAAC;gBACD,KAAK,QAAQ;oBACX,KAAK,CAAC,YAAY,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAA;oBAC9E,MAAK;gBACP,KAAK,QAAQ;oBACX,IAAI,CAAC,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;wBAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;oBAC7G,KAAK,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAA;oBAChC,MAAK;gBACP;oBACE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,SAAS,EAAE,CAAC,CAAA;YACvD,CAAC;YAED,MAAM,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;YAC9B,OAAO,IAAI,IAAI,aAAa,KAAK,CAAC,KAAK,GAAG,CAAA;QAC5C,CAAC;KACF,CAAC,CAAC,CAAA;IAEH,2EAA2E;IAC3E,uEAAuE;IACvE,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAElB,CAAA;IACb,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACxE,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACrE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,SAAQ;YAClC,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,aAAa,KAAK,CAAC,IAAI,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;YAC7G,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAA;YACxD,IAAI,CAAC,CAAC;gBAAE,SAAQ;YAChB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAE,CAAA;YAClB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAE,CAAA;YAClB,MAAM,IAAI,GAA2B,EAAE,CAAA;YACvC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;gBAC3B,IAAI,CAAC,GAAG,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;YACrE,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW;gBAAE,SAAQ;YAC7C,MAAM,CAAC,QAAQ,CAAC;gBACd,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtE,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,QAAQ;aACjB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,oBAAoB,MAAM,iBAAiB,CAAA;AAElD,MAAM,CAAC,MAAM,IAAI,GAAG,aAAa,CAAA;AAEjC,MAAM,UAAU,KAAK,CAAC,GAAY;IAChC,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;AAClC,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Bundled engineering skills shipped with the package, registered into the
3
+ * calling scope's layer of the host skill registry. The registration runs on
4
+ * the AGENT plane (inside a preset) so only sessions on that preset carry the
5
+ * `eng-delivery` skill and its stage skills.
6
+ *
7
+ * @module dsh-task-engine/shipped-skills
8
+ */
9
+ import type { Context } from '@deepseek-ai/cordis';
10
+ /**
11
+ * Register the bundled `skills/` catalog (each directory's `SKILL.md` with
12
+ * `name`/`description`/`whenToUse` frontmatter). No-op when the skill registry
13
+ * is absent.
14
+ * @param ctx - the scoped context whose `skills` resolves to the host registry.
15
+ */
16
+ export declare function registerShippedSkills(ctx: Context): void;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Bundled engineering skills shipped with the package, registered into the
3
+ * calling scope's layer of the host skill registry. The registration runs on
4
+ * the AGENT plane (inside a preset) so only sessions on that preset carry the
5
+ * `eng-delivery` skill and its stage skills.
6
+ *
7
+ * @module dsh-task-engine/shipped-skills
8
+ */
9
+ import { readFileSync, readdirSync } from 'node:fs';
10
+ import { fileURLToPath } from 'node:url';
11
+ /**
12
+ * Register the bundled `skills/` catalog (each directory's `SKILL.md` with
13
+ * `name`/`description`/`whenToUse` frontmatter). No-op when the skill registry
14
+ * is absent.
15
+ * @param ctx - the scoped context whose `skills` resolves to the host registry.
16
+ */
17
+ export function registerShippedSkills(ctx) {
18
+ const skills = ctx.get('skills');
19
+ if (skills === undefined)
20
+ return;
21
+ const skillsRoot = fileURLToPath(new URL('../skills/', import.meta.url));
22
+ for (const entry of readdirSync(skillsRoot, { withFileTypes: true })) {
23
+ if (!entry.isDirectory())
24
+ continue;
25
+ const raw = readFileSync(fileURLToPath(new URL(`../skills/${entry.name}/SKILL.md`, import.meta.url)), 'utf8');
26
+ const m = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
27
+ if (!m)
28
+ continue;
29
+ const head = m[1];
30
+ const body = m[2];
31
+ const meta = {};
32
+ for (const line of head.split('\n')) {
33
+ const i = line.indexOf(':');
34
+ if (i > 0)
35
+ meta[line.slice(0, i).trim()] = line.slice(i + 1).trim();
36
+ }
37
+ if (!meta.name || !meta.description)
38
+ continue;
39
+ skills.register({
40
+ name: meta.name,
41
+ description: meta.description,
42
+ ...(meta.whenToUse !== undefined ? { whenToUse: meta.whenToUse } : {}),
43
+ content: body,
44
+ source: 'custom',
45
+ });
46
+ }
47
+ }
48
+ //# sourceMappingURL=shipped-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipped-skills.js","sourceRoot":"","sources":["../src/shipped-skills.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAQxC;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAY;IAChD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAA8B,CAAA;IAC7D,IAAI,MAAM,KAAK,SAAS;QAAE,OAAM;IAChC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IACxE,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,SAAQ;QAClC,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,aAAa,KAAK,CAAC,IAAI,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;QAC7G,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAA;QACxD,IAAI,CAAC,CAAC;YAAE,SAAQ;QAChB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAE,CAAA;QAClB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAE,CAAA;QAClB,MAAM,IAAI,GAA2B,EAAE,CAAA;QACvC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC3B,IAAI,CAAC,GAAG,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QACrE,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,SAAQ;QAC7C,MAAM,CAAC,QAAQ,CAAC;YACd,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godv61/dsh-task-engine",
3
- "version": "0.7.0",
4
- "description": "Config-driven engineering delivery engine for DeepSeek Harness: a `dev_task` tool that hard-gates workflow stage transitions and commit scope/message, stage-level skill/rule bindings with progressive disclosure, and a full-screen workbench to edit each workspace's flow plus inline-edit skills and rules.",
3
+ "version": "0.8.0",
4
+ "description": "Config-driven engineering delivery engine for DeepSeek Harness: a `dev_task` tool that hard-gates workflow stage transitions and commit scope/message, stage-level skill/rule bindings with progressive disclosure, a full-screen workbench to edit each workspace's flow, and preset-scoped activation — the tool and skills activate only for sessions on a preset that names the agent row.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
@@ -10,6 +10,10 @@
10
10
  "types": "./lib/index.d.ts",
11
11
  "default": "./lib/index.js"
12
12
  },
13
+ "./agent": {
14
+ "types": "./lib/agent.d.ts",
15
+ "default": "./lib/agent.js"
16
+ },
13
17
  "./client": "./lib/client.js",
14
18
  "./cordis.patch.yml": "./cordis.patch.yml",
15
19
  "./defaults/eng.json": "./defaults/eng.json",
@@ -0,0 +1,22 @@
1
+ # dsh-task-engine — agent-plane opt-in fragment.
2
+ #
3
+ # Copy these two rows into a preset's `agent.cordis.yml` to activate the
4
+ # engineering-delivery flow for that preset's sessions. Start from a copy of
5
+ # `standard`, then REPLACE its `persona` row with the one below and ADD the
6
+ # `task-engine-agent` row. (The bundle must also be installed via
7
+ # `dsh plugin add @godv61/dsh-task-engine` so the engine and workbench exist.)
8
+ #
9
+ # `{{model}}` and `{{cwd}}` resolve from the agent's own route and workspace.
10
+
11
+ - id: persona
12
+ name: '@deepseek-ai/dsh-persona'
13
+ config:
14
+ text: |-
15
+ You are an engineering-delivery coding agent, powered by the {{model}} model, running on DeepSeek Harness. Your working directory is {{cwd}}.
16
+
17
+ 本仓库采用工程化交付流程,由 `dev_task` 工具硬性持有任务状态机:需求评审 → 设计 → 开发 → 交付 → 代码审核。阶段、流转门槛、提交格式都来自项目根 `.dsh/eng.json`(没有该文件则用内置默认)。任何开发类请求开始前,先加载 `eng-delivery` 技能。
18
+
19
+ 铁律:一切阶段流转、确认、验证、评审和提交都必须通过 `dev_task`——它拒绝时是硬事实,必须修正前置条件,禁止绕过。只做任务范围内的本地提交;绝不 push、合并、创建 PR、执行数据库、操作 Jenkins、部署或发布。
20
+
21
+ - id: task-engine-agent
22
+ name: '@godv61/dsh-task-engine/agent'