agent-step-gate 0.3.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.
Files changed (68) hide show
  1. package/ARCHITECTURE.md +393 -0
  2. package/README.md +662 -0
  3. package/SKILL.md +190 -0
  4. package/Weaver.md +140 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +573 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/core/errors.d.ts +16 -0
  9. package/dist/core/errors.js +32 -0
  10. package/dist/core/errors.js.map +1 -0
  11. package/dist/core/gate.d.ts +20 -0
  12. package/dist/core/gate.js +82 -0
  13. package/dist/core/gate.js.map +1 -0
  14. package/dist/core/keys.d.ts +18 -0
  15. package/dist/core/keys.js +37 -0
  16. package/dist/core/keys.js.map +1 -0
  17. package/dist/core/plan.d.ts +2 -0
  18. package/dist/core/plan.js +135 -0
  19. package/dist/core/plan.js.map +1 -0
  20. package/dist/core/program.d.ts +69 -0
  21. package/dist/core/program.js +191 -0
  22. package/dist/core/program.js.map +1 -0
  23. package/dist/core/reconcile.d.ts +37 -0
  24. package/dist/core/reconcile.js +198 -0
  25. package/dist/core/reconcile.js.map +1 -0
  26. package/dist/core/session.d.ts +25 -0
  27. package/dist/core/session.js +88 -0
  28. package/dist/core/session.js.map +1 -0
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.js +29 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/storage/db.d.ts +3 -0
  33. package/dist/storage/db.js +117 -0
  34. package/dist/storage/db.js.map +1 -0
  35. package/dist/storage/repository.d.ts +24 -0
  36. package/dist/storage/repository.js +449 -0
  37. package/dist/storage/repository.js.map +1 -0
  38. package/dist/tools/activeTask.d.ts +2 -0
  39. package/dist/tools/activeTask.js +41 -0
  40. package/dist/tools/activeTask.js.map +1 -0
  41. package/dist/tools/cancelTask.d.ts +2 -0
  42. package/dist/tools/cancelTask.js +39 -0
  43. package/dist/tools/cancelTask.js.map +1 -0
  44. package/dist/tools/checkpoint.d.ts +2 -0
  45. package/dist/tools/checkpoint.js +71 -0
  46. package/dist/tools/checkpoint.js.map +1 -0
  47. package/dist/tools/current.d.ts +2 -0
  48. package/dist/tools/current.js +64 -0
  49. package/dist/tools/current.js.map +1 -0
  50. package/dist/tools/finalize.d.ts +2 -0
  51. package/dist/tools/finalize.js +95 -0
  52. package/dist/tools/finalize.js.map +1 -0
  53. package/dist/tools/index.d.ts +6 -0
  54. package/dist/tools/index.js +7 -0
  55. package/dist/tools/index.js.map +1 -0
  56. package/dist/tools/startPlan.d.ts +2 -0
  57. package/dist/tools/startPlan.js +124 -0
  58. package/dist/tools/startPlan.js.map +1 -0
  59. package/dist/types/index.d.ts +142 -0
  60. package/dist/types/index.js +6 -0
  61. package/dist/types/index.js.map +1 -0
  62. package/package.json +48 -0
  63. package/scripts/interactive-demo.ts +394 -0
  64. package/scripts/mcp-call.mjs +56 -0
  65. package/scripts/prompt-check-hook.sh +27 -0
  66. package/scripts/session-start-hook.sh +47 -0
  67. package/scripts/stop-hook.mjs +83 -0
  68. package/scripts/stop-hook.sh +75 -0
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerCurrent(server: McpServer, getSessionId: () => string | null): void;
@@ -0,0 +1,64 @@
1
+ // ============================================================================
2
+ // Agent Step Gate — gate_current MCP Tool
3
+ // Phase 2: Returns ALL current steps (DAG supports multiple active steps).
4
+ // ============================================================================
5
+ import { z } from 'zod';
6
+ import { getTask, getCurrentSteps } from '../storage/repository.js';
7
+ // ---------------------------------------------------------------------------
8
+ // Zod schema for input validation
9
+ // ---------------------------------------------------------------------------
10
+ const GateCurrentSchema = {
11
+ taskId: z.string().describe('The task ID to query'),
12
+ };
13
+ // ---------------------------------------------------------------------------
14
+ // Tool handler
15
+ // ---------------------------------------------------------------------------
16
+ async function handleCurrent(params, sessionId) {
17
+ // 1. Get task — enforce session_id isolation
18
+ const task = getTask(params.taskId);
19
+ if (!task) {
20
+ return {
21
+ taskId: params.taskId,
22
+ status: 'not_found',
23
+ currentSteps: [],
24
+ };
25
+ }
26
+ if (task.sessionId && task.sessionId !== sessionId) {
27
+ return {
28
+ taskId: params.taskId,
29
+ status: 'not_found',
30
+ currentSteps: [],
31
+ };
32
+ }
33
+ // 2. Get all current steps
34
+ const currentSteps = getCurrentSteps(params.taskId);
35
+ // 3. Return current step info (do NOT return step_key — security design)
36
+ return {
37
+ taskId: params.taskId,
38
+ status: task.status,
39
+ currentSteps: currentSteps.map(cs => ({
40
+ stepId: cs.id,
41
+ path: cs.path,
42
+ index: cs.orderIndex,
43
+ total: task.totalSteps,
44
+ })),
45
+ };
46
+ }
47
+ // ---------------------------------------------------------------------------
48
+ // MCP Tool registration
49
+ // ---------------------------------------------------------------------------
50
+ export function registerCurrent(server, getSessionId) {
51
+ server.tool('gate_current', "Query all current steps for a task. Does NOT return step_keys for security. Keys are only revealed on creation (gate_start_plan) or rotation (gate_checkpoint).", GateCurrentSchema, async (args) => {
52
+ const sessionId = getSessionId();
53
+ if (!sessionId) {
54
+ return {
55
+ content: [{ type: 'text', text: JSON.stringify({ taskId: args.taskId, status: 'not_found', currentSteps: [] }) }],
56
+ };
57
+ }
58
+ const result = await handleCurrent(args, sessionId);
59
+ return {
60
+ content: [{ type: 'text', text: JSON.stringify(result) }],
61
+ };
62
+ });
63
+ }
64
+ //# sourceMappingURL=current.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"current.js","sourceRoot":"","sources":["../../src/tools/current.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,0CAA0C;AAC1C,2EAA2E;AAC3E,+EAA+E;AAG/E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEpE,8EAA8E;AAC9E,kCAAkC;AAClC,8EAA8E;AAE9E,MAAM,iBAAiB,GAAG;IACxB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;CACpD,CAAC;AAEF,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,KAAK,UAAU,aAAa,CAAC,MAAwB,EAAE,SAAiB;IACtE,6CAA6C;IAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,WAAW;YACnB,YAAY,EAAE,EAAE;SACjB,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACnD,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,WAAW;YACnB,YAAY,EAAE,EAAE;SACjB,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEpD,yEAAyE;IACzE,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,EAAE,EAAE,CAAC,EAAE;YACb,IAAI,EAAE,EAAE,CAAC,IAAI;YACb,KAAK,EAAE,EAAE,CAAC,UAAU;YACpB,KAAK,EAAE,IAAI,CAAC,UAAU;SACvB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,YAAiC;IAClF,MAAM,CAAC,IAAI,CACT,cAAc,EACd,iKAAiK,EACjK,iBAAiB,EACjB,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QACjC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;aAC3H,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACpD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerFinalize(server: McpServer): void;
@@ -0,0 +1,95 @@
1
+ // ============================================================================
2
+ // Agent Step Gate — gate_finalize MCP Tool
3
+ // Phase 2: Returns pendingSteps on failure so Agent sees what's missing.
4
+ // ============================================================================
5
+ import { z } from 'zod';
6
+ import { getTask, getTaskSteps, verifyTaskKey, updateTaskStatus, addEvent } from '../storage/repository.js';
7
+ import { commitProgramNode } from '../core/program.js';
8
+ // ---------------------------------------------------------------------------
9
+ // Zod input schema
10
+ // ---------------------------------------------------------------------------
11
+ const FinalizeInputSchema = {
12
+ taskId: z.string().describe('The task ID to finalize'),
13
+ taskKey: z.string().describe('The task key obtained from the last checkpoint'),
14
+ };
15
+ // ---------------------------------------------------------------------------
16
+ // Handler
17
+ // ---------------------------------------------------------------------------
18
+ async function handleFinalize(params) {
19
+ // 1. Get task
20
+ const task = getTask(params.taskId);
21
+ if (!task) {
22
+ return {
23
+ accepted: false,
24
+ status: 'not_found',
25
+ message: 'Task not found.',
26
+ };
27
+ }
28
+ // 2. Check if task is already completed (idempotent)
29
+ if (task.status === 'completed') {
30
+ return {
31
+ accepted: true,
32
+ status: 'completed',
33
+ message: 'Task was already finalized.',
34
+ };
35
+ }
36
+ // 3. Verify task key
37
+ const isValid = verifyTaskKey(params.taskId, params.taskKey);
38
+ if (!isValid) {
39
+ const allSteps = getTaskSteps(params.taskId);
40
+ const pendingSteps = allSteps
41
+ .filter(s => s.status !== 'completed' && s.status !== 'skipped')
42
+ .map(s => ({
43
+ stepId: s.id,
44
+ path: s.path,
45
+ index: s.orderIndex,
46
+ total: task.totalSteps,
47
+ }));
48
+ const response = {
49
+ accepted: false,
50
+ status: 'active',
51
+ message: 'Task cannot be finalized. Some steps are not checkpointed.',
52
+ pendingSteps,
53
+ };
54
+ return response;
55
+ }
56
+ // 4. Validation passed — mark task completed
57
+ updateTaskStatus(params.taskId, 'completed');
58
+ addEvent(params.taskId, null, 'task_finalized', JSON.stringify({ taskKeyHash: task.finalKeyHash }));
59
+ const output = {
60
+ accepted: true,
61
+ status: 'completed',
62
+ message: 'All planned steps have been checkpointed.',
63
+ };
64
+ // 5. Auto-propagate: check if node is complete
65
+ if (task.sessionId) {
66
+ const cr = commitProgramNode(task.sessionId);
67
+ if (cr) {
68
+ output.nodeCompleted = { nodeId: cr.nodeId, programId: cr.programId, nodeKey: cr.nodeKey };
69
+ output.message = 'Task finalized. Node auto-completed (all tasks done).';
70
+ if (cr.allDone) {
71
+ output.programCompleted = { programId: cr.programId };
72
+ output.message = 'Task finalized → Node completed → Program completed.';
73
+ }
74
+ }
75
+ }
76
+ return output;
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // MCP Tool registration
80
+ // ---------------------------------------------------------------------------
81
+ export function registerFinalize(server) {
82
+ server.tool('gate_finalize', 'Finalize a task by verifying the final_key. Returns pendingSteps when steps are missing. Stop Hooks can call this to prevent premature task completion.', FinalizeInputSchema, async (params) => {
83
+ const output = await handleFinalize(params);
84
+ return {
85
+ content: [
86
+ {
87
+ type: 'text',
88
+ text: JSON.stringify(output),
89
+ },
90
+ ],
91
+ isError: !output.accepted,
92
+ };
93
+ });
94
+ }
95
+ //# sourceMappingURL=finalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalize.js","sourceRoot":"","sources":["../../src/tools/finalize.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,2CAA2C;AAC3C,yEAAyE;AACzE,+EAA+E;AAE/E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,OAAO,EAAmB,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC7H,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,mBAAmB,GAAG;IAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IACtD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;CAC/E,CAAC;AAEF,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,KAAK,UAAU,cAAc,CAAC,MAAyB;IACrD,cAAc;IACd,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,iBAAiB;SAC3B,CAAC;IACJ,CAAC;IAED,qDAAqD;IACrD,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QAChC,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,6BAA6B;SACvC,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,QAAQ;aAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;aAC/D,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACT,MAAM,EAAE,CAAC,CAAC,EAAE;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,KAAK,EAAE,CAAC,CAAC,UAAU;YACnB,KAAK,EAAE,IAAI,CAAC,UAAU;SACvB,CAAC,CAAC,CAAC;QAEN,MAAM,QAAQ,GAAuB;YACnC,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,4DAA4D;YACrE,YAAY;SACb,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,6CAA6C;IAC7C,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC7C,QAAQ,CACN,MAAM,CAAC,MAAM,EACb,IAAI,EACJ,gBAAgB,EAChB,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CACnD,CAAC;IAEF,MAAM,MAAM,GAAuB;QACjC,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,WAAW;QACnB,OAAO,EAAE,2CAA2C;KACrD,CAAC;IAEF,+CAA+C;IAC/C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,MAAM,EAAE,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,EAAE,EAAE,CAAC;YACN,MAAc,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC;YACpG,MAAM,CAAC,OAAO,GAAG,uDAAuD,CAAC;YACzE,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;gBACd,MAAc,CAAC,gBAAgB,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC;gBAC/D,MAAM,CAAC,OAAO,GAAG,sDAAsD,CAAC;YAC1E,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,MAAM,CAAC,IAAI,CACT,eAAe,EACf,yJAAyJ,EACzJ,mBAAmB,EACnB,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,MAA2B,CAAC,CAAC;QAEjE,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;iBAC7B;aACF;YACD,OAAO,EAAE,CAAC,MAAM,CAAC,QAAQ;SAC1B,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { registerStartPlan } from './startPlan.js';
2
+ export { registerCurrent } from './current.js';
3
+ export { registerCheckpoint } from './checkpoint.js';
4
+ export { registerFinalize } from './finalize.js';
5
+ export { registerActiveTask } from './activeTask.js';
6
+ export { registerCancelTask } from './cancelTask.js';
@@ -0,0 +1,7 @@
1
+ export { registerStartPlan } from './startPlan.js';
2
+ export { registerCurrent } from './current.js';
3
+ export { registerCheckpoint } from './checkpoint.js';
4
+ export { registerFinalize } from './finalize.js';
5
+ export { registerActiveTask } from './activeTask.js';
6
+ export { registerCancelTask } from './cancelTask.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerStartPlan(server: McpServer): void;
@@ -0,0 +1,124 @@
1
+ import { z } from 'zod';
2
+ import { flattenPlan } from '../core/plan.js';
3
+ import { generateStepKey, randomCode } from '../core/keys.js';
4
+ import { createSession } from '../core/session.js';
5
+ import { createTask } from '../storage/repository.js';
6
+ import { GateErrorCode } from '../core/errors.js';
7
+ // One session per MCP process. Created lazily on first gate_start_plan call.
8
+ let processSession = null;
9
+ const stepNodeSchema = z.lazy(() => z.object({
10
+ id: z.string().optional(),
11
+ title: z.string(),
12
+ children: z.array(stepNodeSchema).optional(),
13
+ dependsOn: z.array(z.string()).optional(),
14
+ }));
15
+ export function registerStartPlan(server) {
16
+ server.tool('gate_start_plan', 'Create a task plan with nested steps and DAG dependencies. Creates a session on first call. Returns session credentials for CLI resume.', {
17
+ title: z.string(),
18
+ steps: z.array(stepNodeSchema),
19
+ }, async (params) => {
20
+ // 1. Validate input
21
+ if (!params.title || !params.steps || params.steps.length === 0) {
22
+ return {
23
+ content: [
24
+ {
25
+ type: 'text',
26
+ text: JSON.stringify({
27
+ accepted: false,
28
+ error: GateErrorCode.PLAN_SCHEMA_INVALID,
29
+ message: 'Title and at least one step are required',
30
+ }),
31
+ },
32
+ ],
33
+ isError: true,
34
+ };
35
+ }
36
+ // 2. Ensure session exists (created lazily on first call)
37
+ if (!processSession) {
38
+ processSession = createSession(process.cwd());
39
+ }
40
+ const sessionId = processSession.sessionId;
41
+ // 3. Generate task_id (6-char alphanumeric)
42
+ const taskId = `tsk_${randomCode(6)}`;
43
+ // 4. Flatten nested plan into leaf steps (with DAG dependsOn)
44
+ const leafSteps = flattenPlan(params.steps, taskId);
45
+ // 5. Determine initial current steps: those with empty dependsOn
46
+ const initialCurrent = leafSteps.filter(s => s.dependsOn.length === 0);
47
+ const stepKeys = {};
48
+ // 6. Build TaskRow
49
+ const now = new Date().toISOString();
50
+ const task = {
51
+ id: taskId,
52
+ title: params.title,
53
+ status: 'active',
54
+ currentIndex: 1,
55
+ totalSteps: leafSteps.length,
56
+ finalKeyHash: null,
57
+ sessionId,
58
+ createdAt: now,
59
+ updatedAt: now,
60
+ };
61
+ // 7. Build StepRow[] — initial current steps get 'current', others 'pending'
62
+ const steps = leafSteps.map((ls) => {
63
+ const isInitialCurrent = initialCurrent.some(cs => cs.id === ls.id);
64
+ if (isInitialCurrent) {
65
+ const { plaintext, hash } = generateStepKey();
66
+ stepKeys[ls.id] = plaintext;
67
+ return {
68
+ id: ls.id,
69
+ taskId: ls.taskId,
70
+ parentPath: ls.parentPath,
71
+ title: ls.title,
72
+ path: ls.path,
73
+ orderIndex: ls.orderIndex,
74
+ dependsOn: ls.dependsOn,
75
+ status: 'current',
76
+ stepKeyHash: hash,
77
+ completedAt: null,
78
+ createdAt: ls.createdAt,
79
+ };
80
+ }
81
+ return {
82
+ id: ls.id,
83
+ taskId: ls.taskId,
84
+ parentPath: ls.parentPath,
85
+ title: ls.title,
86
+ path: ls.path,
87
+ orderIndex: ls.orderIndex,
88
+ dependsOn: ls.dependsOn,
89
+ status: 'pending',
90
+ stepKeyHash: null,
91
+ completedAt: null,
92
+ createdAt: ls.createdAt,
93
+ };
94
+ });
95
+ // 8. Write to database (atomic transaction)
96
+ createTask(task, steps);
97
+ // 9. Return result with session credentials (for CLI resume)
98
+ return {
99
+ content: [
100
+ {
101
+ type: 'text',
102
+ text: JSON.stringify({
103
+ taskId: task.id,
104
+ status: 'active',
105
+ session: {
106
+ sessionId: processSession.sessionId,
107
+ sessionSecret: processSession.sessionSecret,
108
+ recoveryToken: processSession.recoveryToken,
109
+ cliInstanceId: processSession.cliInstanceId,
110
+ },
111
+ currentSteps: initialCurrent.map(s => ({
112
+ stepId: s.id,
113
+ path: s.path,
114
+ index: s.orderIndex,
115
+ total: leafSteps.length,
116
+ })),
117
+ stepKeys: stepKeys,
118
+ }),
119
+ },
120
+ ],
121
+ };
122
+ });
123
+ }
124
+ //# sourceMappingURL=startPlan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startPlan.js","sourceRoot":"","sources":["../../src/tools/startPlan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ /** Nested step node — input format for gate_start_plan */
2
+ export interface PlanNode {
3
+ id?: string;
4
+ title: string;
5
+ children?: PlanNode[];
6
+ dependsOn?: string[];
7
+ /** Old key proving this step was completed in a previous task */
8
+ skipKey?: string;
9
+ /** The taskId from the previous (cancelled) task where skipKey was used */
10
+ skipTaskId?: string;
11
+ }
12
+ /** Leaf step after flattening the nested plan (one row in steps table) */
13
+ export interface LeafStep {
14
+ id: string;
15
+ taskId: string;
16
+ parentPath: string | null;
17
+ title: string;
18
+ path: string;
19
+ orderIndex: number;
20
+ dependsOn: string[];
21
+ status: 'pending' | 'current' | 'completed' | 'skipped';
22
+ completedAt: string | null;
23
+ createdAt: string;
24
+ }
25
+ /** Row shape for the tasks table */
26
+ export interface TaskRow {
27
+ id: string;
28
+ title: string;
29
+ status: 'active' | 'completed' | 'cancelled';
30
+ currentIndex: number;
31
+ totalSteps: number;
32
+ finalKeyHash: string | null;
33
+ sessionId: string | null;
34
+ createdAt: string;
35
+ updatedAt: string;
36
+ }
37
+ /** Row shape for the steps table (includes step_key_hash) */
38
+ export interface StepRow {
39
+ id: string;
40
+ taskId: string;
41
+ parentPath: string | null;
42
+ title: string;
43
+ path: string;
44
+ orderIndex: number;
45
+ dependsOn: string[];
46
+ status: 'pending' | 'current' | 'completed' | 'skipped';
47
+ stepKeyHash: string | null;
48
+ completedAt: string | null;
49
+ createdAt: string;
50
+ }
51
+ /** Row shape for the events table */
52
+ export interface EventRow {
53
+ id: string;
54
+ taskId: string;
55
+ stepId: string | null;
56
+ eventType: string;
57
+ payload: string | null;
58
+ createdAt: string;
59
+ }
60
+ /** Snapshot of the currently-active step returned by several tools */
61
+ export interface CurrentStepInfo {
62
+ stepId: string;
63
+ path: string;
64
+ index: number;
65
+ total: number;
66
+ }
67
+ export interface GateStartPlanInput {
68
+ title: string;
69
+ steps: PlanNode[];
70
+ }
71
+ export interface GateStartPlanOutput {
72
+ taskId: string;
73
+ status: 'active';
74
+ sessionId: string;
75
+ currentSteps: CurrentStepInfo[];
76
+ stepKeys: Record<string, string>;
77
+ }
78
+ export interface GateCurrentInput {
79
+ taskId: string;
80
+ }
81
+ export interface GateCurrentOutput {
82
+ taskId: string;
83
+ status: string;
84
+ currentSteps: CurrentStepInfo[];
85
+ }
86
+ export interface GateCheckpointInput {
87
+ taskId: string;
88
+ stepId: string;
89
+ stepKey: string;
90
+ }
91
+ export interface GateCheckpointOutput {
92
+ accepted: boolean;
93
+ completedStep?: {
94
+ stepId: string;
95
+ path: string;
96
+ };
97
+ nextSteps?: CurrentStepInfo[];
98
+ nextStepKeys?: Record<string, string>;
99
+ allStepsCompleted?: boolean;
100
+ taskKey?: string;
101
+ error?: string;
102
+ message?: string;
103
+ currentStep?: CurrentStepInfo;
104
+ pendingSteps?: CurrentStepInfo[];
105
+ }
106
+ export interface GateFinalizeInput {
107
+ taskId: string;
108
+ taskKey: string;
109
+ }
110
+ export interface GateFinalizeOutput {
111
+ accepted: boolean;
112
+ status?: string;
113
+ message?: string;
114
+ currentStep?: CurrentStepInfo;
115
+ pendingSteps?: CurrentStepInfo[];
116
+ nodeCompleted?: {
117
+ nodeId: string;
118
+ programId: string;
119
+ nodeKey: string;
120
+ };
121
+ programCompleted?: {
122
+ programId: string;
123
+ };
124
+ }
125
+ export interface GateActiveTaskOutput {
126
+ sessionId: string;
127
+ activeTasks: Array<{
128
+ taskId: string;
129
+ title: string;
130
+ status: string;
131
+ totalSteps: number;
132
+ completedSteps: number;
133
+ currentSteps: CurrentStepInfo[];
134
+ }>;
135
+ }
136
+ export interface GateCancelTaskInput {
137
+ taskId: string;
138
+ }
139
+ export interface GateCancelTaskOutput {
140
+ accepted: boolean;
141
+ message: string;
142
+ }
@@ -0,0 +1,6 @@
1
+ // ============================================================================
2
+ // Agent Step Gate — Core Types
3
+ // Phase 2: DAG step dependencies, multi-step support, multi-task support
4
+ // ============================================================================
5
+ export {};
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+BAA+B;AAC/B,yEAAyE;AACzE,+EAA+E"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "agent-step-gate",
3
+ "version": "0.3.0",
4
+ "description": "CLI + Skill-based Step Ledger & Key Gate for long-running multi-agent orchestration",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "step-gate": "dist/cli.js"
9
+ },
10
+ "repository": "github:3er1inWa11/Step-Gate-Skill",
11
+ "homepage": "https://github.com/3er1inWa11/Step-Gate-Skill#readme",
12
+ "keywords": [
13
+ "agent",
14
+ "orchestration",
15
+ "step-gate",
16
+ "dag",
17
+ "multi-agent",
18
+ "skill",
19
+ "checkpoint"
20
+ ],
21
+ "files": [
22
+ "dist/",
23
+ "scripts/",
24
+ "SKILL.md",
25
+ "Weaver.md",
26
+ "ARCHITECTURE.md"
27
+ ],
28
+ "license": "MIT",
29
+ "dependencies": {
30
+ "@modelcontextprotocol/sdk": "^1.0.0",
31
+ "better-sqlite3": "^11.0.0",
32
+ "zod": "^4.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/better-sqlite3": "^7.6.0",
36
+ "@types/node": "^20.0.0",
37
+ "typescript": "^5.5.0",
38
+ "vitest": "^2.0.0"
39
+ },
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "dev": "tsc --watch",
43
+ "start": "node dist/index.js",
44
+ "cli": "node dist/cli.js",
45
+ "test": "vitest run",
46
+ "test:watch": "vitest"
47
+ }
48
+ }