@kunolu/dsh-sbtd 0.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +51 -0
  3. package/cordis.patch.yml +3 -0
  4. package/dist/hooks.d.ts +47 -0
  5. package/dist/hooks.d.ts.map +1 -0
  6. package/dist/hooks.js +275 -0
  7. package/dist/hooks.js.map +1 -0
  8. package/dist/index.d.ts +13 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +19 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/section.d.ts +14 -0
  13. package/dist/section.d.ts.map +1 -0
  14. package/dist/section.js +16 -0
  15. package/dist/section.js.map +1 -0
  16. package/dist/state.d.ts +38 -0
  17. package/dist/state.d.ts.map +1 -0
  18. package/dist/state.js +41 -0
  19. package/dist/state.js.map +1 -0
  20. package/dist/tools/plan.d.ts +53 -0
  21. package/dist/tools/plan.d.ts.map +1 -0
  22. package/dist/tools/plan.js +290 -0
  23. package/dist/tools/plan.js.map +1 -0
  24. package/dist/tools/review.d.ts +41 -0
  25. package/dist/tools/review.d.ts.map +1 -0
  26. package/dist/tools/review.js +161 -0
  27. package/dist/tools/review.js.map +1 -0
  28. package/manuals/MANIFEST.json +67 -0
  29. package/manuals/book-ddd-distilled-modeling/SKILL.md +66 -0
  30. package/manuals/book-ddia-data-design/SKILL.md +74 -0
  31. package/manuals/book-legacy-change-safety/SKILL.md +74 -0
  32. package/manuals/book-refactoring-pass/SKILL.md +70 -0
  33. package/manuals/book-release-readiness/SKILL.md +73 -0
  34. package/manuals/domain-modeling/SKILL.md +74 -0
  35. package/manuals/grill-me/SKILL.md +7 -0
  36. package/manuals/grill-with-docs/SKILL.md +7 -0
  37. package/manuals/grilling/SKILL.md +28 -0
  38. package/manuals/to-spec/SKILL.md +75 -0
  39. package/manuals/to-tickets/SKILL.md +105 -0
  40. package/manuals/trellis-workflow/SKILL.md +475 -0
  41. package/package.json +40 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section.d.ts","sourceRoot":"","sources":["../src/section.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,SAAS,CAAC;AACxC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,eAAO,MAAM,iBAAiB,mzBAKiC,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG;IACxB,YAAY,EAAE;QACZ,OAAO,EAAE,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,KAAK,IAAI,CAAC;KACxE,CAAC;CACH,CAAC;AAEF,wBAAgB,eAAe,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAMtD"}
@@ -0,0 +1,16 @@
1
+ export const SBTD_SECTION_NAME = "sbtd";
2
+ export const SBTD_SECTION_ORDER = 50;
3
+ export const SBTD_SECTION_TEXT = `开发任务先调用 sbtd_plan,未出计划不准改生产代码。
4
+ 澄清走 sbtd_clarify,完整澄清后必须有 DDD 复审通过态。
5
+ 改代码前/后的分析、验证走 sbtd_validate / sbtd_e2e,不要直接裸调 MCP 名称。
6
+ 命中 book gate 必须 sbtd_review 到通过态。
7
+ 最终输出必须包含结论、文件、验证、跳过原因、风险。
8
+ Maestro:缺 Java / CLI / 设备 / 已装 app / app 内测试环境时 blocked,先引导用户。`;
9
+ export function registerSection(ctx) {
10
+ ctx.systemPrompt.section({
11
+ name: SBTD_SECTION_NAME,
12
+ order: SBTD_SECTION_ORDER,
13
+ text: SBTD_SECTION_TEXT,
14
+ });
15
+ }
16
+ //# sourceMappingURL=section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section.js","sourceRoot":"","sources":["../src/section.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACxC,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;+DAK8B,CAAC;AAQhE,MAAM,UAAU,eAAe,CAAC,GAAgB;IAC9C,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC;QACvB,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,kBAAkB;QACzB,IAAI,EAAE,iBAAiB;KACxB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,38 @@
1
+ export type GateState = "planned" | "running" | "passed" | "blocked" | "not-required";
2
+ export interface BookGatePlan {
3
+ taskId: string;
4
+ summary: string;
5
+ gates: Record<"ddd" | "ddia" | "legacy" | "refactor" | "release", {
6
+ requirement: "required" | "on-demand";
7
+ state: GateState;
8
+ fact?: string;
9
+ reviewStatus?: string;
10
+ }>;
11
+ taskAutoExit?: boolean;
12
+ }
13
+ export interface SbtdSessionState {
14
+ plan?: BookGatePlan;
15
+ validate: {
16
+ pre?: "done" | "skipped";
17
+ post?: "done" | "blocked";
18
+ };
19
+ maestro?: {
20
+ java?: string;
21
+ cli?: string;
22
+ device?: string;
23
+ appInstalled?: boolean;
24
+ appEnv?: string;
25
+ lastPreflight?: "ok" | "blocked";
26
+ missing: string[];
27
+ };
28
+ }
29
+ export interface SbtdHandoffSnapshot {
30
+ plan?: BookGatePlan;
31
+ maestro?: {
32
+ missing: string[];
33
+ };
34
+ }
35
+ export declare function getSession(sessionId: string): SbtdSessionState;
36
+ export declare function serialize(sessionId: string): SbtdHandoffSnapshot;
37
+ export declare function restore(sessionId: string, snapshot: SbtdHandoffSnapshot): void;
38
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,SAAS,GACT,QAAQ,GACR,SAAS,GACT,cAAc,CAAC;AAEnB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CACX,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,EAClD;QACE,WAAW,EAAE,UAAU,GAAG,WAAW,CAAC;QACtC,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CACF,CAAC;IACF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAClE,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;QACjC,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACjC;AAID,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAQ9D;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAahE;AAED,wBAAgB,OAAO,CACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,mBAAmB,GAC5B,IAAI,CAaN"}
package/dist/state.js ADDED
@@ -0,0 +1,41 @@
1
+ const sessions = new Map();
2
+ export function getSession(sessionId) {
3
+ const existing = sessions.get(sessionId);
4
+ if (existing !== undefined) {
5
+ return existing;
6
+ }
7
+ const created = { validate: {} };
8
+ sessions.set(sessionId, created);
9
+ return created;
10
+ }
11
+ export function serialize(sessionId) {
12
+ const state = sessions.get(sessionId);
13
+ if (state === undefined) {
14
+ return {};
15
+ }
16
+ const snapshot = {};
17
+ if (state.plan !== undefined) {
18
+ snapshot.plan = structuredClone(state.plan);
19
+ }
20
+ if (state.maestro !== undefined) {
21
+ snapshot.maestro = { missing: [...state.maestro.missing] };
22
+ }
23
+ return snapshot;
24
+ }
25
+ export function restore(sessionId, snapshot) {
26
+ const cloned = structuredClone(snapshot);
27
+ const state = getSession(sessionId);
28
+ if (cloned.plan !== undefined) {
29
+ state.plan = cloned.plan;
30
+ }
31
+ else {
32
+ delete state.plan;
33
+ }
34
+ if (cloned.maestro !== undefined) {
35
+ state.maestro = { missing: [...cloned.maestro.missing] };
36
+ }
37
+ else {
38
+ delete state.maestro;
39
+ }
40
+ }
41
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAyCA,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;AAErD,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,OAAO,GAAqB,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACnD,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,SAAiB;IACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,QAAQ,GAAwB,EAAE,CAAC;IACzC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,QAAQ,CAAC,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,QAAQ,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,SAAiB,EACjB,QAA6B;IAE7B,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACpC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,KAAK,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { type BookGatePlan, type GateState } from "../state.js";
2
+ export declare const SBTD_PLAN_TOOL_NAME = "sbtd_plan";
3
+ export declare const GATE_KINDS: readonly ["ddd", "ddia", "legacy", "refactor", "release"];
4
+ export type GateKind = (typeof GATE_KINDS)[number];
5
+ export type PlanInput = {
6
+ task_summary: string;
7
+ facts?: string[];
8
+ };
9
+ export type PlanToolResult = {
10
+ plan: BookGatePlan;
11
+ markdown: string;
12
+ };
13
+ export type PlanToolExec = {
14
+ agent?: {
15
+ id?: string;
16
+ };
17
+ };
18
+ export type PlanToolDefinition = {
19
+ name: string;
20
+ description: string;
21
+ parameters: Record<string, unknown>;
22
+ output: {
23
+ schema: Record<string, unknown>;
24
+ render: (args: unknown, value: PlanToolResult) => Array<{
25
+ type: "text";
26
+ text: string;
27
+ }>;
28
+ };
29
+ isConcurrencySafe: (args: unknown) => false;
30
+ execute: (args: PlanInput, exec: PlanToolExec) => Promise<PlanToolResult>;
31
+ };
32
+ export type ToolsHost = {
33
+ tools: {
34
+ register: (definition: {
35
+ name: string;
36
+ }) => unknown;
37
+ };
38
+ };
39
+ type InferredGate = {
40
+ requirement: "required" | "on-demand";
41
+ state: GateState;
42
+ fact?: string;
43
+ };
44
+ export declare function sessionIdFromExec(exec: PlanToolExec | undefined): string;
45
+ export declare function taskIdFromSummary(summary: string): string;
46
+ export declare function inferRequirements(summary: string, facts?: string[]): Record<GateKind, InferredGate>;
47
+ export declare function formatPlanMarkdown(plan: BookGatePlan, notes?: string[]): string;
48
+ export declare function sbtdPlan(sessionId: string, input: PlanInput): PlanToolResult;
49
+ export declare const SBTD_PLAN_DESCRIPTION = "Register or update the session Book Gate Plan. Pass task_summary; optional facts are objective trigger strings. Required gates are inferred from PRD 3.4 predicates, never from subjective risk. Repeat calls for the same goal keep passed gates only while their requirement remains required and the trigger fact is unchanged; reset a pass when a trigger disappears, the trigger fact changes, or the gate is promoted from on-demand.";
50
+ export declare function createPlanTool(): PlanToolDefinition;
51
+ export declare function registerPlanTool(ctx: ToolsHost): void;
52
+ export {};
53
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAc,MAAM,aAAa,CAAC;AAE5E,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAE/C,eAAO,MAAM,UAAU,2DAMb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,MAAM,MAAM,SAAS,GAAG;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,EAAE,CACN,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,cAAc,KAClB,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC5C,CAAC;IACF,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,KAAK,CAAC;IAC5C,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CAC3E,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE;QACL,QAAQ,EAAE,CAAC,UAAU,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC;KACrD,CAAC;CACH,CAAC;AAIF,KAAK,YAAY,GAAG;IAClB,WAAW,EAAE,UAAU,GAAG,WAAW,CAAC;IACtC,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAkDF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,CAMxE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAYzD;AAOD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,EAAE,GACf,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAmBhC;AA8GD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,YAAY,EAClB,KAAK,GAAE,MAAM,EAAO,GACnB,MAAM,CAwBR;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,cAAc,CA8B5E;AAED,eAAO,MAAM,qBAAqB,ibAC8Y,CAAC;AAEjb,wBAAgB,cAAc,IAAI,kBAAkB,CAwCnD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAErD"}
@@ -0,0 +1,290 @@
1
+ import { createHash } from "node:crypto";
2
+ import { getSession } from "../state.js";
3
+ export const SBTD_PLAN_TOOL_NAME = "sbtd_plan";
4
+ export const GATE_KINDS = [
5
+ "ddd",
6
+ "ddia",
7
+ "legacy",
8
+ "refactor",
9
+ "release",
10
+ ];
11
+ const DEFAULT_SESSION_ID = "default";
12
+ const PREDICATES = {
13
+ ddd: [
14
+ { re: /完整执行\s*grill-with-docs/i, fact: "完整执行 grill-with-docs" },
15
+ { re: /completed\s+grill-with-docs/i, fact: "completed grill-with-docs" },
16
+ {
17
+ re: /fully?\s+executed\s+grill-with-docs/i,
18
+ fact: "fully executed grill-with-docs",
19
+ },
20
+ ],
21
+ ddia: [
22
+ { re: /持久化/, fact: "持久化" },
23
+ { re: /persist/i, fact: "persistence" },
24
+ { re: /数据库/, fact: "数据库" },
25
+ { re: /database|\bsql\b|\bschema\b/i, fact: "database/schema" },
26
+ { re: /缓存|cache|\bredis\b/i, fact: "cache" },
27
+ { re: /共享数据|shared data/i, fact: "共享数据" },
28
+ { re: /异步/, fact: "异步数据流" },
29
+ { re: /\basync\b/i, fact: "async data flow" },
30
+ { re: /跨服务|cross[- ]service/i, fact: "跨服务数据流" },
31
+ {
32
+ re: /\bqueue\b|\bkafka\b|\bpubsub\b|event bus/i,
33
+ fact: "queue/event bus",
34
+ },
35
+ ],
36
+ legacy: [
37
+ { re: /既有行为/, fact: "修既有行为" },
38
+ { re: /existing behavio[u]?r/i, fact: "existing behavior" },
39
+ { re: /bugfix|\bbug[- ]fix\b/i, fact: "bugfix" },
40
+ { re: /弱测试|weak tests/i, fact: "弱测试" },
41
+ { re: /行为不清|unclear behavio[u]?r/i, fact: "行为不清" },
42
+ { re: /隐藏依赖|hidden dependenc/i, fact: "隐藏依赖" },
43
+ { re: /高回归|high regression/i, fact: "高回归" },
44
+ ],
45
+ refactor: [
46
+ { re: /既有生产/, fact: "既有生产代码" },
47
+ { re: /existing production/i, fact: "existing production" },
48
+ ],
49
+ release: [
50
+ { re: /生产路径|production path/i, fact: "生产路径" },
51
+ { re: /部署|\bdeploy/i, fact: "deploy" },
52
+ { re: /发布/, fact: "发布" },
53
+ {
54
+ re: /production (?:service|api|job)/i,
55
+ fact: "production service/API/job",
56
+ },
57
+ ],
58
+ };
59
+ export function sessionIdFromExec(exec) {
60
+ const id = exec?.agent?.id;
61
+ if (typeof id === "string" && id.length > 0) {
62
+ return id;
63
+ }
64
+ return DEFAULT_SESSION_ID;
65
+ }
66
+ export function taskIdFromSummary(summary) {
67
+ const trimmed = summary.trim();
68
+ const digest = createHash("sha256")
69
+ .update(trimmed)
70
+ .digest("hex")
71
+ .slice(0, 12);
72
+ const slug = trimmed
73
+ .toLowerCase()
74
+ .replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-")
75
+ .replace(/^-+|-+$/g, "")
76
+ .slice(0, 48);
77
+ return slug.length > 0 ? `${slug}-${digest}` : `task-${digest}`;
78
+ }
79
+ function haystack(summary, facts) {
80
+ const extra = facts === undefined ? "" : facts.join("\n");
81
+ return `${summary}\n${extra}`;
82
+ }
83
+ export function inferRequirements(summary, facts) {
84
+ const text = haystack(summary, facts);
85
+ const out = {};
86
+ for (const kind of GATE_KINDS) {
87
+ const hit = PREDICATES[kind].find((p) => p.re.test(text));
88
+ if (hit !== undefined) {
89
+ out[kind] = {
90
+ requirement: "required",
91
+ state: "planned",
92
+ fact: hit.fact,
93
+ };
94
+ }
95
+ else {
96
+ out[kind] = {
97
+ requirement: "on-demand",
98
+ state: "not-required",
99
+ };
100
+ }
101
+ }
102
+ return out;
103
+ }
104
+ function mergeGate(previous, inferred) {
105
+ if (inferred.requirement === "required") {
106
+ if (previous !== undefined &&
107
+ previous.requirement === "required" &&
108
+ previous.state === "passed") {
109
+ if (previous.fact !== undefined &&
110
+ inferred.fact !== undefined &&
111
+ previous.fact !== inferred.fact) {
112
+ return {
113
+ gate: {
114
+ requirement: "required",
115
+ state: "planned",
116
+ fact: inferred.fact,
117
+ },
118
+ note: `trigger fact changed; reset inherited pass (${previous.fact} → ${inferred.fact})`,
119
+ };
120
+ }
121
+ const kept = {
122
+ requirement: "required",
123
+ state: "passed",
124
+ };
125
+ const fact = inferred.fact ?? previous.fact;
126
+ if (fact !== undefined) {
127
+ kept.fact = fact;
128
+ }
129
+ if (previous.reviewStatus !== undefined) {
130
+ kept.reviewStatus = previous.reviewStatus;
131
+ }
132
+ return { gate: kept };
133
+ }
134
+ if (previous !== undefined &&
135
+ previous.requirement === "on-demand" &&
136
+ previous.state === "passed") {
137
+ const gate = {
138
+ requirement: "required",
139
+ state: "planned",
140
+ };
141
+ if (inferred.fact !== undefined) {
142
+ gate.fact = inferred.fact;
143
+ }
144
+ return {
145
+ gate,
146
+ note: "promoted from on-demand; reset inherited pass",
147
+ };
148
+ }
149
+ if (previous !== undefined &&
150
+ (previous.state === "running" ||
151
+ previous.state === "blocked" ||
152
+ previous.state === "planned")) {
153
+ const kept = {
154
+ requirement: "required",
155
+ state: previous.state,
156
+ };
157
+ const fact = inferred.fact ?? previous.fact;
158
+ if (fact !== undefined) {
159
+ kept.fact = fact;
160
+ }
161
+ if (previous.reviewStatus !== undefined) {
162
+ kept.reviewStatus = previous.reviewStatus;
163
+ }
164
+ return { gate: kept };
165
+ }
166
+ const next = {
167
+ requirement: "required",
168
+ state: "planned",
169
+ };
170
+ if (inferred.fact !== undefined) {
171
+ next.fact = inferred.fact;
172
+ }
173
+ return { gate: next };
174
+ }
175
+ if (previous !== undefined && previous.state === "passed") {
176
+ return {
177
+ gate: {
178
+ requirement: "on-demand",
179
+ state: "not-required",
180
+ },
181
+ note: "trigger fact disappeared; reset passed",
182
+ };
183
+ }
184
+ const optional = {
185
+ requirement: "on-demand",
186
+ state: "not-required",
187
+ };
188
+ if (inferred.fact !== undefined) {
189
+ optional.fact = inferred.fact;
190
+ }
191
+ return { gate: optional };
192
+ }
193
+ export function formatPlanMarkdown(plan, notes = []) {
194
+ const rows = GATE_KINDS.map((kind) => {
195
+ const gate = plan.gates[kind];
196
+ const fact = gate.fact ?? "";
197
+ return `| ${kind} | ${gate.requirement} | ${gate.state} | ${fact} |`;
198
+ });
199
+ const parts = [
200
+ "# Book Gate Plan",
201
+ "",
202
+ `taskId: ${plan.taskId}`,
203
+ "",
204
+ plan.summary,
205
+ "",
206
+ "| Gate | Requirement | State | Fact |",
207
+ "|---|---|---|---|",
208
+ ...rows,
209
+ ];
210
+ if (notes.length > 0) {
211
+ parts.push("", "## Reset notes", "");
212
+ for (const note of notes) {
213
+ parts.push(`- ${note}`);
214
+ }
215
+ }
216
+ return parts.join("\n");
217
+ }
218
+ export function sbtdPlan(sessionId, input) {
219
+ const summary = input.task_summary.trim();
220
+ if (summary.length === 0) {
221
+ throw new Error("sbtd_plan: task_summary must be a non-empty string");
222
+ }
223
+ const session = getSession(sessionId);
224
+ const taskId = taskIdFromSummary(summary);
225
+ const inferred = inferRequirements(summary, input.facts);
226
+ const existing = session.plan;
227
+ const sameGoal = existing !== undefined && existing.taskId === taskId;
228
+ const gates = {};
229
+ const notes = [];
230
+ for (const kind of GATE_KINDS) {
231
+ const previous = sameGoal ? existing.gates[kind] : undefined;
232
+ const merged = mergeGate(previous, inferred[kind]);
233
+ gates[kind] = merged.gate;
234
+ if (merged.note !== undefined) {
235
+ notes.push(`${kind}: ${merged.note}`);
236
+ }
237
+ }
238
+ const plan = {
239
+ taskId,
240
+ summary,
241
+ gates,
242
+ };
243
+ session.plan = plan;
244
+ return { plan, markdown: formatPlanMarkdown(plan, notes) };
245
+ }
246
+ export const SBTD_PLAN_DESCRIPTION = "Register or update the session Book Gate Plan. Pass task_summary; optional facts are objective trigger strings. Required gates are inferred from PRD 3.4 predicates, never from subjective risk. Repeat calls for the same goal keep passed gates only while their requirement remains required and the trigger fact is unchanged; reset a pass when a trigger disappears, the trigger fact changes, or the gate is promoted from on-demand.";
247
+ export function createPlanTool() {
248
+ return {
249
+ name: SBTD_PLAN_TOOL_NAME,
250
+ description: SBTD_PLAN_DESCRIPTION,
251
+ parameters: {
252
+ type: "object",
253
+ properties: {
254
+ task_summary: {
255
+ type: "string",
256
+ description: "Short description of the development task.",
257
+ },
258
+ facts: {
259
+ type: "array",
260
+ description: "Optional objective trigger facts (PRD 3.4). Also inferred from task_summary.",
261
+ items: { type: "string" },
262
+ },
263
+ },
264
+ required: ["task_summary"],
265
+ },
266
+ output: {
267
+ schema: {
268
+ type: "object",
269
+ additionalProperties: false,
270
+ properties: {
271
+ plan: { type: "object" },
272
+ markdown: { type: "string" },
273
+ },
274
+ },
275
+ render(_args, value) {
276
+ return [{ type: "text", text: value.markdown }];
277
+ },
278
+ },
279
+ isConcurrencySafe() {
280
+ return false;
281
+ },
282
+ async execute(args, exec) {
283
+ return sbtdPlan(sessionIdFromExec(exec), args);
284
+ },
285
+ };
286
+ }
287
+ export function registerPlanTool(ctx) {
288
+ ctx.tools.register(createPlanTool());
289
+ }
290
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { type GateState } from "../state.js";
2
+ import { type PlanToolExec, type ToolsHost } from "./plan.js";
3
+ export declare const SBTD_REVIEW_TOOL_NAME = "sbtd_review";
4
+ export declare const REVIEW_KINDS: readonly ["legacy", "refactor", "ddd", "ddia", "release"];
5
+ export type ReviewKind = (typeof REVIEW_KINDS)[number];
6
+ export declare const REVIEW_TITLES: Record<ReviewKind, string>;
7
+ export type ReviewInput = {
8
+ kind: string;
9
+ status: string;
10
+ conclusions?: string;
11
+ };
12
+ export type ReviewToolResult = {
13
+ title: string;
14
+ kind: ReviewKind;
15
+ reviewStatus: string;
16
+ requirement: "required" | "on-demand";
17
+ state: GateState;
18
+ conclusions: string;
19
+ markdown: string;
20
+ manual: string;
21
+ };
22
+ export type ReviewToolDefinition = {
23
+ name: string;
24
+ description: string;
25
+ parameters: Record<string, unknown>;
26
+ output: {
27
+ schema: Record<string, unknown>;
28
+ render: (args: unknown, value: ReviewToolResult) => Array<{
29
+ type: "text";
30
+ text: string;
31
+ }>;
32
+ };
33
+ isConcurrencySafe: (args: unknown) => false;
34
+ execute: (args: ReviewInput, exec: PlanToolExec) => Promise<ReviewToolResult>;
35
+ };
36
+ export declare function loadReviewManual(kind: ReviewKind): string;
37
+ export declare function sbtdReview(sessionId: string, input: ReviewInput): ReviewToolResult;
38
+ export declare const SBTD_REVIEW_DESCRIPTION = "Record a book-gate review. kind is legacy|refactor|ddd|ddia|release only (no skill ids or aliases). status is the source-skill reviewer enum. Without a plan, call sbtd_plan first. Does not change requirement.";
39
+ export declare function createReviewTool(): ReviewToolDefinition;
40
+ export declare function registerReviewTool(ctx: ToolsHost): void;
41
+ //# sourceMappingURL=review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/tools/review.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,aAAa,CAAC;AACzD,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,SAAS,EACf,MAAM,WAAW,CAAC;AAEnB,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AAEnD,eAAO,MAAM,YAAY,2DAMf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAMpD,CAAC;AAkCF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,UAAU,GAAG,WAAW,CAAC;IACtC,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,EAAE,CACN,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,gBAAgB,KACpB,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC5C,CAAC;IACF,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,KAAK,CAAC;IAC5C,OAAO,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC/E,CAAC;AAmBF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAQzD;AAED,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,WAAW,GACjB,gBAAgB,CA8ClB;AAED,eAAO,MAAM,uBAAuB,qNACgL,CAAC;AAErN,wBAAgB,gBAAgB,IAAI,oBAAoB,CAoDvD;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAEvD"}