@haoyiyin/workflow 0.2.0 → 0.2.3

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 (62) hide show
  1. package/package.json +15 -10
  2. package/scripts/postinstall.js +2 -2
  3. package/src/agents/contracts.ts +559 -0
  4. package/src/agents/dispatcher-enhanced.ts +350 -0
  5. package/src/agents/dispatcher.ts +680 -0
  6. package/src/agents/index.ts +48 -0
  7. package/src/agents/resilience.ts +255 -0
  8. package/src/agents/token-budget.ts +83 -0
  9. package/src/agents/types.ts +73 -0
  10. package/src/guard/main-agent.ts +245 -0
  11. package/src/hooks/builtin/index.ts +8 -0
  12. package/src/hooks/builtin/on-error.ts +23 -0
  13. package/src/hooks/builtin/post-execute.ts +40 -0
  14. package/src/hooks/builtin/post-plan.ts +23 -0
  15. package/src/hooks/builtin/pre-execute.ts +30 -0
  16. package/src/hooks/builtin/pre-plan.ts +26 -0
  17. package/src/hooks/index.ts +7 -0
  18. package/src/hooks/loader.ts +98 -0
  19. package/src/hooks/manager.ts +99 -0
  20. package/src/hooks/types-enhanced.ts +38 -0
  21. package/src/hooks/types.ts +35 -0
  22. package/src/index.ts +127 -0
  23. package/src/persistence/index.ts +17 -0
  24. package/src/persistence/plan-md.ts +141 -0
  25. package/src/persistence/state-md.ts +167 -0
  26. package/src/persistence/types.ts +89 -0
  27. package/src/router/classifier.ts +610 -0
  28. package/src/router/guard.ts +483 -0
  29. package/src/router/index.ts +22 -0
  30. package/src/router/router.ts +108 -0
  31. package/src/router/types.ts +127 -0
  32. package/src/skills/agents-md/SKILL.md +45 -0
  33. package/src/skills/agents-md/index.ts +33 -0
  34. package/src/skills/execute-plan/SKILL.md +60 -0
  35. package/src/skills/execute-plan/index.ts +970 -0
  36. package/src/skills/index.ts +13 -0
  37. package/src/skills/quick-task/SKILL.md +54 -0
  38. package/src/skills/quick-task/index.ts +346 -0
  39. package/src/skills/registry.ts +59 -0
  40. package/src/skills/review-diff/SKILL.md +53 -0
  41. package/src/skills/review-diff/index.ts +394 -0
  42. package/src/skills/skill.ts +59 -0
  43. package/src/skills/systematic-debugging/SKILL.md +56 -0
  44. package/src/skills/systematic-debugging/index.ts +404 -0
  45. package/src/skills/tdd/SKILL.md +52 -0
  46. package/src/skills/tdd/index.ts +409 -0
  47. package/src/skills/to-plan/SKILL.md +56 -0
  48. package/src/skills/to-plan/index-enhanced.ts +551 -0
  49. package/src/skills/to-plan/index.ts +586 -0
  50. package/src/skills/types.ts +47 -0
  51. package/src/state/cleanup.ts +118 -0
  52. package/src/state/index.ts +8 -0
  53. package/src/state/manager.ts +96 -0
  54. package/src/state/persistence.ts +77 -0
  55. package/src/state/types.ts +30 -0
  56. package/src/state/validator.ts +78 -0
  57. package/src/types.ts +102 -0
  58. package/src/utils/compress.ts +347 -0
  59. package/src/utils/git.ts +82 -0
  60. package/src/utils/index.ts +6 -0
  61. package/src/utils/logger.ts +23 -0
  62. package/src/utils/paths.ts +55 -0
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Router system types - Controls all user input routing
3
+ */
4
+
5
+ import type { SubagentConfig, SubagentResult } from '../agents/types.js'
6
+
7
+ /** Classification of user intent */
8
+ export type IntentType =
9
+ | 'plan' // Needs planning (complex, multi-step)
10
+ | 'quick-task' // Small scoped task (trivial edit, small fix)
11
+ | 'execute' // Execute approved plan
12
+ | 'review' // Review code/diff
13
+ | 'debug' // Systematic debugging
14
+ | 'tdd' // Test-driven development
15
+ | 'general' // Catch-all for other queries
16
+
17
+ export interface IntentClassification {
18
+ type: IntentType
19
+ confidence: number // 0-1
20
+ reasoning: string
21
+ suggestedAgent: string
22
+ }
23
+
24
+ export interface RouterConfig {
25
+ /** Default model for subagents */
26
+ defaultModel: string
27
+ /** Threshold for routing to quick-task vs to-plan */
28
+ planningThreshold: number
29
+ /** Max tokens before forcing subagent dispatch */
30
+ maxMainAgentTokens: number
31
+ /** Whether to auto-route based on keywords */
32
+ autoRoute: boolean
33
+ }
34
+
35
+ export interface RoutingDecision {
36
+ /** The subagent to dispatch */
37
+ subagent: SubagentConfig
38
+ /** Contract/prompt for the subagent */
39
+ contract: SubagentContract
40
+ /** Whether to wait for result or stream */
41
+ async: boolean
42
+ }
43
+
44
+ export interface SubagentContract {
45
+ /** What this subagent is allowed to do */
46
+ permissions: PermissionSet
47
+ /** Exact prompt to send */
48
+ prompt: string
49
+ /** Required output format */
50
+ outputSchema?: Record<string, unknown>
51
+ /** Files this subagent owns */
52
+ owns: string[]
53
+ /** Files this subagent may read */
54
+ reads: string[]
55
+ }
56
+
57
+ export interface PermissionSet {
58
+ readFiles: boolean
59
+ searchCode: boolean
60
+ runCommands: boolean
61
+ writeFiles: boolean
62
+ gitOperations: boolean
63
+ }
64
+
65
+ export interface RouterResult {
66
+ decision: RoutingDecision
67
+ /** Estimated token usage */
68
+ estimatedTokens: number
69
+ /** Fallback if subagent fails */
70
+ fallbackStrategy: 'retry' | 'escalate' | 'abort'
71
+ }
72
+
73
+ export interface ExecutionResult {
74
+ success: boolean
75
+ result?: SubagentResult
76
+ error?: string
77
+ /** Tokens used by entire routing chain */
78
+ totalTokens: number
79
+ /** Time taken */
80
+ duration: number
81
+ }
82
+
83
+ /** Input to the router: raw request + classification context. */
84
+ export interface RouterInput {
85
+ /** Raw user request text */
86
+ request: string
87
+ /** Whether a plan file already exists */
88
+ planFileExists: boolean
89
+ /** Whether mid-execution of a plan */
90
+ isExecutingPlan: boolean
91
+ /** Whether there are uncommitted changes */
92
+ hasUncommittedChanges: boolean
93
+ /** Current git branch */
94
+ currentBranch?: string
95
+ /** Files mentioned by the user */
96
+ mentionedFiles: string[]
97
+ }
98
+
99
+ /** Output from the router: classification + full routing decision. */
100
+ export interface RouterOutput {
101
+ classification: IntentClassification
102
+ routing: RoutingDecision
103
+ confidence: number
104
+ matchedRule: string
105
+ }
106
+
107
+ /** Main Agent is NEVER allowed to do these */
108
+ export const MAIN_AGENT_PROHIBITED = {
109
+ readSourceFiles: true, // ❌ Cannot read .ts, .js, .py, etc.
110
+ searchCodebase: true, // ❌ Cannot search/grep
111
+ writeFiles: true, // ❌ Cannot write any files
112
+ runBuildCommands: true, // ❌ Cannot npm build, tsc, etc.
113
+ runTests: true, // ❌ Cannot run tests
114
+ editLargeFiles: true, // ❌ Cannot edit >50 lines
115
+ longRunningTasks: true, // ❌ Cannot run >30s tasks
116
+ }
117
+
118
+ /** Keywords that trigger specific routes */
119
+ export const ROUTE_KEYWORDS: Record<IntentType, string[]> = {
120
+ plan: ['plan', 'implement', 'add feature', 'refactor', 'migrate', 'create'],
121
+ 'quick-task': ['fix typo', 'rename', 'small change', 'quick', 'trivial'],
122
+ execute: ['execute', 'run plan', 'do plan', 'implement plan'],
123
+ review: ['review', 'check code', 'audit', 'review diff', 'cr'],
124
+ debug: ['debug', 'fix bug', 'investigate', 'root cause', 'flaky'],
125
+ tdd: ['tdd', 'test first', 'red green', 'write test'],
126
+ general: ['what', 'how', 'explain', 'tell me', 'search', 'find'],
127
+ }
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: agents-md
3
+ description: Create or update agent instruction files (CLAUDE.md, AGENTS.md, CONTEXT.md) from repo evidence.
4
+ requires: []
5
+ ---
6
+
7
+ ## ⛔ MAIN AGENT CONSTRAINT
8
+
9
+ You are a THIN DISPATCHER. Your ONLY job is to dispatch subagents.
10
+ You MUST NOT: read source files, search code, write/edit files, run tests, run git commands.
11
+ You MAY only: read plan/state files, dispatch subagents via Agent tool, relay results.
12
+ For EVERY user request (including this skill), dispatch a subagent. Never execute yourself.
13
+
14
+ ---
15
+
16
+ ## Use/Exclude Matrix
17
+
18
+ | Use When | Exclude When |
19
+ |---|---|
20
+ | Initializing or updating project agent instructions | File already exists and is comprehensive |
21
+ | New project onboarding | Project has no package.json or README |
22
+ | Adding CLAUDE.md to a repo | File was just created and needs no update |
23
+ | Updating after major tech stack change | Minor wording/polish changes |
24
+
25
+ ## Workflow
26
+
27
+ 1. **Collect Evidence** — Dispatch explorer subagent to read package.json, README, and any existing instruction file.
28
+ 2. **Write Instructions** — Dispatch implementer subagent to create/update the target file with Overview, Tech Stack, Commands, and Conventions sections.
29
+
30
+ ## Output Spec
31
+
32
+ | Field | Type | Description |
33
+ |---|---|---|
34
+ | `filePath` | string | Name of the created/updated file (CLAUDE.md, AGENTS.md, or CONTEXT.md) |
35
+ | `mode` | enum | `created` or `updated` |
36
+ | `evidence` | string[] | Source files used as evidence |
37
+ | `summary` | string | Human-readable result |
38
+
39
+ ## Error Handling
40
+
41
+ | Error | Action |
42
+ |---|---|
43
+ | Explorer fails to read sources | Write instructions based on available evidence only |
44
+ | Implementer fails to write file | Error propagates to caller |
45
+ | Target file type invalid | Zod schema rejects at input validation |
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod'
2
+ import { Skill } from '../skill.js'
3
+ import type { SkillContext } from '../types.js'
4
+ import { createDispatcher } from '../../agents/dispatcher.js'
5
+ import { createMainAgentGuard } from '../../guard/main-agent.js'
6
+
7
+ const P = { readFiles: true, searchCode: false, runCommands: false, writeFiles: false, gitOperations: false }
8
+ const PRW = { readFiles: true, searchCode: false, runCommands: false, writeFiles: true, gitOperations: false }
9
+
10
+ const AgentsMdInputSchema = z.object({ type: z.enum(['CLAUDE','AGENTS','CONTEXT']).default('CLAUDE'), update: z.boolean().default(false), model: z.string().optional() })
11
+ export class AgentsMdSkill extends Skill<any, any> {
12
+ constructor() { super({ name: 'agents-md', description: 'Create/update agent instructions', requires: [], inputSchema: AgentsMdInputSchema as any }) }
13
+ async execute(input: any, context: SkillContext): Promise<any> {
14
+ const { config, logger } = context
15
+ const dispatcher = createDispatcher(logger)
16
+ const guard = createMainAgentGuard({}, logger)
17
+ const filename = `${input.type}.md`
18
+ guard.activateEmbargo()
19
+ try {
20
+ const explore = await dispatcher.dispatch(
21
+ { role: 'explorer', model: input.model || config.defaultModel },
22
+ { permissions: P, prompt: `Collect repo evidence: package.json, README, configs.`, owns: [], reads: ['package.json','README.md',filename] },
23
+ )
24
+ await dispatcher.dispatch(
25
+ { role: 'implementer', model: input.model || 'sonnet' },
26
+ { permissions: PRW, prompt: `${input.update?'Update':'Create'} ${filename}. Evidence: ${explore.output.slice(0,3000)}. Include: Overview, Tech Stack, Commands, Conventions.`, owns: [filename], reads: [] },
27
+ )
28
+ return { filePath: filename, mode: input.update?'updated':'created', evidence: ['package.json'], rules: ['Overview'], assumptions: [], summary: `${filename} done` }
29
+ } finally { guard.deactivateEmbargo() }
30
+ }
31
+ }
32
+ export const agentsMdSkill = new AgentsMdSkill()
33
+ export default agentsMdSkill
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: execute-plan
3
+ description: Execute approved plans via 9-step isolated subagent dispatch with review, verification, auto-commit, and auto-merge.
4
+ requires: [to-plan, tdd, review-diff, systematic-debugging]
5
+ ---
6
+
7
+ ## ⛔ MAIN AGENT CONSTRAINT
8
+
9
+ You are a THIN DISPATCHER. Your ONLY job is to dispatch subagents.
10
+ You MUST NOT: read source files, search code, write/edit files, run tests, run git commands.
11
+ You MAY only: read plan/state files, dispatch subagents via Agent tool, relay results.
12
+ For EVERY user request (including this skill), dispatch a subagent. Never execute yourself.
13
+
14
+ ---
15
+
16
+ ## Use/Exclude Matrix
17
+
18
+ | Use When | Exclude When |
19
+ |---|---|
20
+ | Approved plan ready for execution | Plan not yet created or approved |
21
+ | Multi-task implementation with dependencies | Single trivial change (use quick-task) |
22
+ | Need review gate per task | No review requirement |
23
+ | Want auto-commit/merge on success | Manual commit workflow preferred |
24
+
25
+ ## Workflow
26
+
27
+ 1. **Parse Plan** — Read plan file, extract tasks with owns/reads/dependencies metadata.
28
+ 2. **Create State** — Build execution state tracking completed, failed, and in-progress tasks.
29
+ 3. **Execute Tasks** — Dispatch implementer subagents per task in dependency order, each in isolated worktree.
30
+ 4. **Review Each** — Dispatch reviewer subagent per completed task; BLOCKED tasks move to failed.
31
+ 5. **Integrate** — Collect approved changes; detect and report file-level conflicts.
32
+ 6. **Verify** — Dispatch verifier subagent to run full test suite and goal-backward check.
33
+ 7. **Auto-Commit** — If `config.autoMerge` and all tasks pass, commit changes via subagent.
34
+ 8. **Auto-Merge** — Detect base branch, merge feature branch back via subagent.
35
+ 9. **Cleanup** — If `config.autoCleanup`, archive plan and delete feature branch.
36
+
37
+ ## Output Spec
38
+
39
+ | Field | Type | Description |
40
+ |---|---|---|
41
+ | `status` | enum | `success`, `failure`, `partial` |
42
+ | `tasksCompleted` | number | Count of successfully completed tasks |
43
+ | `tasksFailed` | number | Count of failed/blocked tasks |
44
+ | `tasksTotal` | number | Total tasks in the plan |
45
+ | `summary` | string | Human-readable execution summary |
46
+ | `actions` | array | List of actions taken (commit, merge, archive) |
47
+ | `commitSha` | string? | Commit SHA if auto-committed |
48
+ | `baseBranch` | string? | Detected base branch for merge |
49
+ | `tokensUsed` | number | Total tokens consumed |
50
+
51
+ ## Error Handling
52
+
53
+ | Error | Action |
54
+ |---|---|
55
+ | Plan file not found | Throw with path; caller must verify path |
56
+ | Plan contains no parseable tasks | Throw; suggest re-running to-plan |
57
+ | Implementer subagent fails | Record in failed map; continue remaining tasks |
58
+ | Reviewer returns BLOCKED | Move task to failed with reviewer feedback |
59
+ | Verifier reports FAIL | Return partial status with failure details |
60
+ | Merge conflict during auto-merge | Report conflict; do NOT force-resolve |