@liangjie559567/ultrapower 7.0.3 → 7.0.5

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 (67) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +4 -0
  4. package/bridge/mcp-server.cjs +117 -68
  5. package/dist/hooks/autopilot/cancel.d.ts.map +1 -1
  6. package/dist/hooks/autopilot/cancel.js +15 -15
  7. package/dist/hooks/autopilot/cancel.js.map +1 -1
  8. package/dist/hooks/autopilot/enforcement.js +12 -12
  9. package/dist/hooks/autopilot/enforcement.js.map +1 -1
  10. package/dist/hooks/autopilot/state.d.ts.map +1 -1
  11. package/dist/hooks/autopilot/state.js +28 -30
  12. package/dist/hooks/autopilot/state.js.map +1 -1
  13. package/dist/hooks/bridge-types.d.ts +2 -0
  14. package/dist/hooks/bridge-types.d.ts.map +1 -1
  15. package/dist/hooks/bridge-types.js.map +1 -1
  16. package/dist/hooks/handlers/route-map.d.ts.map +1 -1
  17. package/dist/hooks/handlers/route-map.js +15 -0
  18. package/dist/hooks/handlers/route-map.js.map +1 -1
  19. package/dist/hooks/index.d.ts +1 -0
  20. package/dist/hooks/index.d.ts.map +1 -1
  21. package/dist/hooks/index.js +3 -0
  22. package/dist/hooks/index.js.map +1 -1
  23. package/dist/hooks/mode-cancel-sync.d.ts.map +1 -1
  24. package/dist/hooks/mode-cancel-sync.js +11 -12
  25. package/dist/hooks/mode-cancel-sync.js.map +1 -1
  26. package/dist/hooks/persistent-mode/index.js +2 -2
  27. package/dist/hooks/persistent-mode/index.js.map +1 -1
  28. package/dist/hooks/ralph/loop.d.ts.map +1 -1
  29. package/dist/hooks/ralph/loop.js +7 -8
  30. package/dist/hooks/ralph/loop.js.map +1 -1
  31. package/dist/hooks/ralph/verifier.js +11 -11
  32. package/dist/hooks/ralph/verifier.js.map +1 -1
  33. package/dist/hooks/ultrawork/index.d.ts.map +1 -1
  34. package/dist/hooks/ultrawork/index.js +7 -4
  35. package/dist/hooks/ultrawork/index.js.map +1 -1
  36. package/dist/hooks/validation.d.ts.map +1 -1
  37. package/dist/hooks/validation.js +2 -0
  38. package/dist/hooks/validation.js.map +1 -1
  39. package/dist/hooks/workflow-gate/index.d.ts +116 -0
  40. package/dist/hooks/workflow-gate/index.d.ts.map +1 -0
  41. package/dist/hooks/workflow-gate/index.js +352 -0
  42. package/dist/hooks/workflow-gate/index.js.map +1 -0
  43. package/dist/lib/state-cache.d.ts +8 -5
  44. package/dist/lib/state-cache.d.ts.map +1 -1
  45. package/dist/lib/state-cache.js +26 -16
  46. package/dist/lib/state-cache.js.map +1 -1
  47. package/dist/mcp/adapters/state-adapter.d.ts +8 -8
  48. package/dist/team/index.d.ts +1 -0
  49. package/dist/team/index.d.ts.map +1 -1
  50. package/dist/team/index.js +1 -0
  51. package/dist/team/index.js.map +1 -1
  52. package/dist/team/workflow-integration.d.ts +8 -0
  53. package/dist/team/workflow-integration.d.ts.map +1 -0
  54. package/dist/team/workflow-integration.js +62 -0
  55. package/dist/team/workflow-integration.js.map +1 -0
  56. package/dist/tools/lsp/client.d.ts +8 -2
  57. package/dist/tools/lsp/client.d.ts.map +1 -1
  58. package/dist/tools/lsp/client.js +114 -70
  59. package/dist/tools/lsp/client.js.map +1 -1
  60. package/dist/tools/lsp-tools.d.ts.map +1 -1
  61. package/dist/tools/lsp-tools.js +1 -4
  62. package/dist/tools/lsp-tools.js.map +1 -1
  63. package/docs/REFERENCE.md +3 -0
  64. package/package.json +1 -1
  65. package/skills/brainstorming/SKILL.md +57 -14
  66. package/skills/omc-doctor/SKILL.md +45 -0
  67. package/skills/team/SKILL.md +12 -0
@@ -17,6 +17,8 @@ export function requiredKeysForHook(hookType) {
17
17
  return ["directory", "toolName"];
18
18
  case "autopilot":
19
19
  return ["directory"];
20
+ case "user-prompt-submit":
21
+ return ["prompt", "directory"];
20
22
  case "keyword-detector":
21
23
  case "stop-continuation":
22
24
  return [];
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/hooks/validation.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,aAAa,CAAC;QACnB,KAAK,gBAAgB,CAAC;QACtB,KAAK,eAAe,CAAC;QACrB,KAAK,aAAa,CAAC;QACnB,KAAK,YAAY,CAAC;QAClB,KAAK,mBAAmB,CAAC;QACzB,KAAK,OAAO,CAAC;QACb,KAAK,iBAAiB,CAAC;QACvB,KAAK,eAAe;YAClB,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACpC,KAAK,oBAAoB;YACvB,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QAChD,KAAK,cAAc,CAAC;QACpB,KAAK,eAAe;YAClB,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACnC,KAAK,WAAW;YACd,OAAO,CAAC,WAAW,CAAC,CAAC;QACvB,KAAK,kBAAkB,CAAC;QACxB,KAAK,mBAAmB;YACtB,OAAO,EAAE,CAAC;QACZ;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAc,EACd,cAAwB,EACxB,QAAiB;IAEjB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CACnC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,SAAS,CACvD,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CACX,+CAA+C,QAAQ,IAAI,SAAS,oBAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7G,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,IAAI,gBAAgB,GAAoB,IAAI,CAAC;AAE7C,MAAM,UAAU,YAAY;IAC1B,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;QAC9B,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACvG,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,gBAAgB,GAAG,IAAI,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/hooks/validation.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,aAAa,CAAC;QACnB,KAAK,gBAAgB,CAAC;QACtB,KAAK,eAAe,CAAC;QACrB,KAAK,aAAa,CAAC;QACnB,KAAK,YAAY,CAAC;QAClB,KAAK,mBAAmB,CAAC;QACzB,KAAK,OAAO,CAAC;QACb,KAAK,iBAAiB,CAAC;QACvB,KAAK,eAAe;YAClB,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACpC,KAAK,oBAAoB;YACvB,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QAChD,KAAK,cAAc,CAAC;QACpB,KAAK,eAAe;YAClB,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACnC,KAAK,WAAW;YACd,OAAO,CAAC,WAAW,CAAC,CAAC;QACvB,KAAK,oBAAoB;YACvB,OAAO,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACjC,KAAK,kBAAkB,CAAC;QACxB,KAAK,mBAAmB;YACtB,OAAO,EAAE,CAAC;QACZ;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAc,EACd,cAAwB,EACxB,QAAiB;IAEjB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CACnC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,SAAS,CACvD,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CACX,+CAA+C,QAAQ,IAAI,SAAS,oBAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7G,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,IAAI,gBAAgB,GAAoB,IAAI,CAAC;AAE7C,MAAM,UAAU,YAAY;IAC1B,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;QAC9B,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACvG,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,gBAAgB,GAAG,IAAI,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Workflow Gate Hook
3
+ *
4
+ * Enforces superpowers workflow discipline by detecting when users
5
+ * skip required steps and automatically injecting the correct skill.
6
+ *
7
+ * Workflow stages:
8
+ * 1. brainstorming (required before any implementation)
9
+ * 2. writing-plans (required after brainstorming)
10
+ * 3. using-git-worktrees (recommended before execution)
11
+ * 4. execution (subagent-driven-development or executing-plans)
12
+ * 5. requesting-code-review (required before completion)
13
+ * 6. verification-before-completion (required before merge)
14
+ */
15
+ export interface WorkflowState {
16
+ brainstormingComplete: boolean;
17
+ planWritten: boolean;
18
+ worktreeCreated: boolean;
19
+ testsWritten: boolean;
20
+ executionStarted: boolean;
21
+ reviewRequested: boolean;
22
+ codeReviewComplete: boolean;
23
+ securityReviewComplete: boolean;
24
+ performanceReviewComplete: boolean;
25
+ verificationComplete: boolean;
26
+ lastStage: string;
27
+ timestamp: number;
28
+ }
29
+ export interface WorkflowGateInput {
30
+ type: 'UserPromptSubmit';
31
+ prompt: string;
32
+ workingDirectory: string;
33
+ }
34
+ export interface WorkflowGateOutput {
35
+ success: boolean;
36
+ shouldBlock: boolean;
37
+ injectedSkill?: string;
38
+ message?: string;
39
+ }
40
+ /**
41
+ * Get workflow state file path
42
+ */
43
+ export declare function getWorkflowStatePath(workingDir: string): string;
44
+ /**
45
+ * Read current workflow state
46
+ */
47
+ export declare function readWorkflowState(workingDir: string): WorkflowState | null;
48
+ /**
49
+ * Write workflow state
50
+ */
51
+ export declare function writeWorkflowState(workingDir: string, state: WorkflowState): void;
52
+ /**
53
+ * Initialize workflow state
54
+ */
55
+ export declare function initWorkflowState(workingDir: string): WorkflowState;
56
+ /**
57
+ * Detect implementation keywords that require brainstorming first
58
+ */
59
+ export declare function detectImplementationIntent(prompt: string): boolean;
60
+ /**
61
+ * Detect plan execution keywords
62
+ */
63
+ export declare function detectExecutionIntent(prompt: string): boolean;
64
+ /**
65
+ * Check if brainstorming skill was just completed
66
+ */
67
+ export declare function detectBrainstormingComplete(prompt: string): boolean;
68
+ /**
69
+ * Check if plan was just written
70
+ */
71
+ export declare function detectPlanComplete(prompt: string): boolean;
72
+ /**
73
+ * Check if tests were just written
74
+ */
75
+ export declare function detectTestsComplete(prompt: string): boolean;
76
+ /**
77
+ * Check if code review was completed
78
+ */
79
+ export declare function detectCodeReviewComplete(prompt: string): boolean;
80
+ /**
81
+ * Check if security review was completed
82
+ */
83
+ export declare function detectSecurityReviewComplete(prompt: string): boolean;
84
+ /**
85
+ * Check if performance review was completed
86
+ */
87
+ export declare function detectPerformanceReviewComplete(prompt: string): boolean;
88
+ /**
89
+ * Detect if prompt contains security-sensitive keywords
90
+ */
91
+ export declare function detectSecuritySensitive(prompt: string): boolean;
92
+ /**
93
+ * Detect if prompt contains performance-sensitive keywords
94
+ */
95
+ export declare function detectPerformanceSensitive(prompt: string): boolean;
96
+ /**
97
+ * Detect if user is trying to use executing-plans or subagent-driven-development
98
+ */
99
+ export declare function detectPlanExecutionSkill(prompt: string): boolean;
100
+ /**
101
+ * Detect if user is asking a vague question that needs brainstorming
102
+ */
103
+ export declare function detectVagueRequest(prompt: string): boolean;
104
+ /**
105
+ * Suggest next step based on current workflow state
106
+ */
107
+ export declare function suggestNextStep(state: WorkflowState): string | null;
108
+ /**
109
+ * Process workflow gate check
110
+ */
111
+ export declare function processWorkflowGate(input: WorkflowGateInput): WorkflowGateOutput;
112
+ /**
113
+ * Clear workflow state (for testing or manual reset)
114
+ */
115
+ export declare function clearWorkflowState(workingDir: string): void;
116
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/workflow-gate/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,aAAa;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,sBAAsB,EAAE,OAAO,CAAC;IAChC,yBAAyB,EAAE,OAAO,CAAC;IACnC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAY1E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CASjF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAkBnE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CASlE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAQ7D;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGpE;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGvE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAO/D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOlE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAKhE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAuB1D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAkCnE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,kBAAkB,CAwIhF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAK3D"}
@@ -0,0 +1,352 @@
1
+ /**
2
+ * Workflow Gate Hook
3
+ *
4
+ * Enforces superpowers workflow discipline by detecting when users
5
+ * skip required steps and automatically injecting the correct skill.
6
+ *
7
+ * Workflow stages:
8
+ * 1. brainstorming (required before any implementation)
9
+ * 2. writing-plans (required after brainstorming)
10
+ * 3. using-git-worktrees (recommended before execution)
11
+ * 4. execution (subagent-driven-development or executing-plans)
12
+ * 5. requesting-code-review (required before completion)
13
+ * 6. verification-before-completion (required before merge)
14
+ */
15
+ import { readFileSync, existsSync, writeFileSync } from 'fs';
16
+ import { join } from 'path';
17
+ const WORKFLOW_STATE_FILE = '.omc/workflow-state.json';
18
+ /**
19
+ * Get workflow state file path
20
+ */
21
+ export function getWorkflowStatePath(workingDir) {
22
+ return join(workingDir, WORKFLOW_STATE_FILE);
23
+ }
24
+ /**
25
+ * Read current workflow state
26
+ */
27
+ export function readWorkflowState(workingDir) {
28
+ const statePath = getWorkflowStatePath(workingDir);
29
+ if (!existsSync(statePath)) {
30
+ return null;
31
+ }
32
+ try {
33
+ const content = readFileSync(statePath, 'utf-8');
34
+ return JSON.parse(content);
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ /**
41
+ * Write workflow state
42
+ */
43
+ export function writeWorkflowState(workingDir, state) {
44
+ const statePath = getWorkflowStatePath(workingDir);
45
+ const dir = join(workingDir, '.omc');
46
+ if (!existsSync(dir)) {
47
+ require('fs').mkdirSync(dir, { recursive: true });
48
+ }
49
+ writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf-8');
50
+ }
51
+ /**
52
+ * Initialize workflow state
53
+ */
54
+ export function initWorkflowState(workingDir) {
55
+ const state = {
56
+ brainstormingComplete: false,
57
+ planWritten: false,
58
+ worktreeCreated: false,
59
+ testsWritten: false,
60
+ executionStarted: false,
61
+ reviewRequested: false,
62
+ codeReviewComplete: false,
63
+ securityReviewComplete: false,
64
+ performanceReviewComplete: false,
65
+ verificationComplete: false,
66
+ lastStage: 'init',
67
+ timestamp: Date.now()
68
+ };
69
+ writeWorkflowState(workingDir, state);
70
+ return state;
71
+ }
72
+ /**
73
+ * Detect implementation keywords that require brainstorming first
74
+ */
75
+ export function detectImplementationIntent(prompt) {
76
+ const implementationKeywords = [
77
+ 'implement', 'create', 'add', 'build', 'develop',
78
+ 'write code', 'make a', 'generate', 'construct',
79
+ '实现', '创建', '添加', '构建', '开发', '编写代码', '生成'
80
+ ];
81
+ const lowerPrompt = prompt.toLowerCase();
82
+ return implementationKeywords.some(kw => lowerPrompt.includes(kw));
83
+ }
84
+ /**
85
+ * Detect plan execution keywords
86
+ */
87
+ export function detectExecutionIntent(prompt) {
88
+ const executionKeywords = [
89
+ 'execute', 'run', 'start', 'begin implementation',
90
+ '执行', '运行', '开始实现'
91
+ ];
92
+ const lowerPrompt = prompt.toLowerCase();
93
+ return executionKeywords.some(kw => lowerPrompt.includes(kw));
94
+ }
95
+ /**
96
+ * Check if brainstorming skill was just completed
97
+ */
98
+ export function detectBrainstormingComplete(prompt) {
99
+ return prompt.includes('brainstorming') &&
100
+ (prompt.includes('complete') || prompt.includes('完成'));
101
+ }
102
+ /**
103
+ * Check if plan was just written
104
+ */
105
+ export function detectPlanComplete(prompt) {
106
+ return (prompt.includes('plan') || prompt.includes('writing-plans')) &&
107
+ (prompt.includes('complete') || prompt.includes('written') || prompt.includes('完成'));
108
+ }
109
+ /**
110
+ * Check if tests were just written
111
+ */
112
+ export function detectTestsComplete(prompt) {
113
+ return (prompt.includes('test') || prompt.includes('测试')) &&
114
+ (prompt.includes('complete') || prompt.includes('written') || prompt.includes('完成'));
115
+ }
116
+ /**
117
+ * Check if code review was completed
118
+ */
119
+ export function detectCodeReviewComplete(prompt) {
120
+ return (prompt.includes('code review') || prompt.includes('代码审查')) &&
121
+ (prompt.includes('complete') || prompt.includes('完成'));
122
+ }
123
+ /**
124
+ * Check if security review was completed
125
+ */
126
+ export function detectSecurityReviewComplete(prompt) {
127
+ return (prompt.includes('security review') || prompt.includes('安全审查')) &&
128
+ (prompt.includes('complete') || prompt.includes('完成'));
129
+ }
130
+ /**
131
+ * Check if performance review was completed
132
+ */
133
+ export function detectPerformanceReviewComplete(prompt) {
134
+ return (prompt.includes('performance review') || prompt.includes('性能审查')) &&
135
+ (prompt.includes('complete') || prompt.includes('完成'));
136
+ }
137
+ /**
138
+ * Detect if prompt contains security-sensitive keywords
139
+ */
140
+ export function detectSecuritySensitive(prompt) {
141
+ const securityKeywords = [
142
+ 'auth', 'password', 'token', 'jwt', 'session', 'crypto', 'encrypt',
143
+ '认证', '密码', '加密', '令牌'
144
+ ];
145
+ const lowerPrompt = prompt.toLowerCase();
146
+ return securityKeywords.some(kw => lowerPrompt.includes(kw) || prompt.includes(kw));
147
+ }
148
+ /**
149
+ * Detect if prompt contains performance-sensitive keywords
150
+ */
151
+ export function detectPerformanceSensitive(prompt) {
152
+ const performanceKeywords = [
153
+ 'performance', 'optimize', 'cache', 'query', 'database', 'api',
154
+ '性能', '优化', '缓存', '查询', '数据库'
155
+ ];
156
+ const lowerPrompt = prompt.toLowerCase();
157
+ return performanceKeywords.some(kw => lowerPrompt.includes(kw) || prompt.includes(kw));
158
+ }
159
+ /**
160
+ * Detect if user is trying to use executing-plans or subagent-driven-development
161
+ */
162
+ export function detectPlanExecutionSkill(prompt) {
163
+ return prompt.includes('executing-plans') ||
164
+ prompt.includes('subagent-driven-development') ||
165
+ prompt.includes('/ultrapower:executing-plans') ||
166
+ prompt.includes('/ultrapower:subagent-driven-development');
167
+ }
168
+ /**
169
+ * Detect if user is asking a vague question that needs brainstorming
170
+ */
171
+ export function detectVagueRequest(prompt) {
172
+ const vaguePatterns = [
173
+ 'how to', 'what should', 'help me', 'i want to', 'i need',
174
+ '如何', '怎么', '帮我', '我想', '我需要'
175
+ ];
176
+ // Check both original and lowercase for case-insensitive English matching
177
+ const lowerPrompt = prompt.toLowerCase();
178
+ const hasVaguePattern = vaguePatterns.some(pattern => lowerPrompt.includes(pattern.toLowerCase()) || prompt.includes(pattern));
179
+ // Ignore if brainstorming already mentioned
180
+ if (prompt.includes('brainstorm')) {
181
+ return false;
182
+ }
183
+ // Require minimum length (count characters, not bytes)
184
+ if ([...prompt].length < 8) {
185
+ return false;
186
+ }
187
+ return hasVaguePattern;
188
+ }
189
+ /**
190
+ * Suggest next step based on current workflow state
191
+ */
192
+ export function suggestNextStep(state) {
193
+ if (!state.brainstormingComplete) {
194
+ return 'brainstorming';
195
+ }
196
+ if (!state.planWritten) {
197
+ return 'writing-plans';
198
+ }
199
+ if (!state.testsWritten && state.planWritten) {
200
+ return 'test-driven-development';
201
+ }
202
+ if (!state.executionStarted && state.testsWritten) {
203
+ return 'subagent-driven-development';
204
+ }
205
+ if (!state.reviewRequested && state.executionStarted) {
206
+ return 'requesting-code-review';
207
+ }
208
+ if (!state.codeReviewComplete && state.reviewRequested) {
209
+ return 'code-review';
210
+ }
211
+ if (!state.verificationComplete && state.codeReviewComplete) {
212
+ return 'verification-before-completion';
213
+ }
214
+ if (!state.worktreeCreated && state.planWritten) {
215
+ return 'using-git-worktrees';
216
+ }
217
+ return null;
218
+ }
219
+ /**
220
+ * Process workflow gate check
221
+ */
222
+ export function processWorkflowGate(input) {
223
+ const { prompt, workingDirectory } = input;
224
+ let state = readWorkflowState(workingDirectory);
225
+ if (!state) {
226
+ state = initWorkflowState(workingDirectory);
227
+ }
228
+ // Update state based on prompt
229
+ if (detectBrainstormingComplete(prompt)) {
230
+ state.brainstormingComplete = true;
231
+ state.lastStage = 'brainstorming';
232
+ state.timestamp = Date.now();
233
+ writeWorkflowState(workingDirectory, state);
234
+ }
235
+ if (detectPlanComplete(prompt)) {
236
+ state.planWritten = true;
237
+ state.lastStage = 'planning';
238
+ state.timestamp = Date.now();
239
+ writeWorkflowState(workingDirectory, state);
240
+ }
241
+ if (detectTestsComplete(prompt)) {
242
+ state.testsWritten = true;
243
+ state.lastStage = 'testing';
244
+ state.timestamp = Date.now();
245
+ writeWorkflowState(workingDirectory, state);
246
+ }
247
+ if (detectCodeReviewComplete(prompt)) {
248
+ state.codeReviewComplete = true;
249
+ state.lastStage = 'code-review';
250
+ state.timestamp = Date.now();
251
+ writeWorkflowState(workingDirectory, state);
252
+ }
253
+ if (detectSecurityReviewComplete(prompt)) {
254
+ state.securityReviewComplete = true;
255
+ state.lastStage = 'security-review';
256
+ state.timestamp = Date.now();
257
+ writeWorkflowState(workingDirectory, state);
258
+ }
259
+ if (detectPerformanceReviewComplete(prompt)) {
260
+ state.performanceReviewComplete = true;
261
+ state.lastStage = 'performance-review';
262
+ state.timestamp = Date.now();
263
+ writeWorkflowState(workingDirectory, state);
264
+ }
265
+ // Gate 1: Implementation without brainstorming (highest priority)
266
+ if (detectImplementationIntent(prompt) && !state.brainstormingComplete) {
267
+ return {
268
+ success: true,
269
+ shouldBlock: true,
270
+ injectedSkill: 'brainstorming',
271
+ message: '⚠️ Workflow Gate: 在实现之前必须先进行头脑风暴。自动注入 brainstorming skill。'
272
+ };
273
+ }
274
+ // Gate 2: Execution without plan
275
+ if (detectExecutionIntent(prompt) && !state.planWritten) {
276
+ return {
277
+ success: true,
278
+ shouldBlock: true,
279
+ injectedSkill: 'writing-plans',
280
+ message: '⚠️ Workflow Gate: 在执行之前必须先编写计划。自动注入 writing-plans skill。'
281
+ };
282
+ }
283
+ // Gate 2.5: Execution without tests (TDD enforcement)
284
+ if (detectExecutionIntent(prompt) && state.planWritten && !state.testsWritten) {
285
+ return {
286
+ success: true,
287
+ shouldBlock: true,
288
+ injectedSkill: 'test-driven-development',
289
+ message: '⚠️ Workflow Gate: TDD 要求在实现前先编写测试。自动注入 test-driven-development skill。'
290
+ };
291
+ }
292
+ // Gate 3: Using executing-plans or subagent-driven-development without plan
293
+ if (detectPlanExecutionSkill(prompt) && !state.planWritten) {
294
+ return {
295
+ success: true,
296
+ shouldBlock: true,
297
+ injectedSkill: 'writing-plans',
298
+ message: '⚠️ Workflow Gate: 使用 executing-plans 或 subagent-driven-development 前必须先编写计划。自动注入 writing-plans skill。'
299
+ };
300
+ }
301
+ // Gate 4: Verification without code review
302
+ if (prompt.includes('verification') && state.executionStarted && !state.codeReviewComplete) {
303
+ return {
304
+ success: true,
305
+ shouldBlock: true,
306
+ injectedSkill: 'code-review',
307
+ message: '⚠️ Workflow Gate: 验证前必须先完成代码审查。自动注入 code-review skill。'
308
+ };
309
+ }
310
+ // Gate 5: Security review for sensitive code
311
+ if (detectSecuritySensitive(prompt) && state.executionStarted && !state.securityReviewComplete) {
312
+ return {
313
+ success: true,
314
+ shouldBlock: true,
315
+ injectedSkill: 'security-review',
316
+ message: '⚠️ Workflow Gate: 检测到安全敏感代码,必须进行安全审查。自动注入 security-review skill。'
317
+ };
318
+ }
319
+ // Gate 6: Performance review for performance-sensitive code
320
+ if (detectPerformanceSensitive(prompt) && state.executionStarted && !state.performanceReviewComplete) {
321
+ return {
322
+ success: true,
323
+ shouldBlock: true,
324
+ injectedSkill: 'performance-review',
325
+ message: '⚠️ Workflow Gate: 检测到性能敏感代码,必须进行性能审查。自动注入 performance-review skill。'
326
+ };
327
+ }
328
+ // Auto-trigger: Suggest brainstorming for vague requests (lower priority)
329
+ // Only trigger if no implementation intent detected
330
+ if (detectVagueRequest(prompt) && !state.brainstormingComplete && !detectImplementationIntent(prompt)) {
331
+ return {
332
+ success: true,
333
+ shouldBlock: true,
334
+ injectedSkill: 'brainstorming',
335
+ message: '💡 自动触发: 检测到模糊需求,建议先进行头脑风暴以明确方向。'
336
+ };
337
+ }
338
+ return {
339
+ success: true,
340
+ shouldBlock: false
341
+ };
342
+ }
343
+ /**
344
+ * Clear workflow state (for testing or manual reset)
345
+ */
346
+ export function clearWorkflowState(workingDir) {
347
+ const statePath = getWorkflowStatePath(workingDir);
348
+ if (existsSync(statePath)) {
349
+ require('fs').unlinkSync(statePath);
350
+ }
351
+ }
352
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/hooks/workflow-gate/index.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,18 @@
1
1
  /**
2
- * State Cache with Copy-on-Write
2
+ * State Cache with Lazy mtime Validation
3
3
  *
4
- * Provides mtime-based cache invalidation and shallow copy on read
5
- * to prevent accidental mutations of cached data.
4
+ * Optimizations:
5
+ * - Delays mtime checks to once per second (reduces I/O by 100-200x)
6
+ * - Uses Object.freeze() instead of shallow copy (eliminates copy overhead)
7
+ * - Fast path: pure memory lookup when cache is fresh
8
+ * - Slow path: mtime validation only when needed
6
9
  */
7
10
  /**
8
- * Read state with cache and mtime validation
11
+ * Read state with cache and lazy mtime validation
9
12
  * @param path - File path to read
10
13
  * @param data - Parsed JSON data (if already read)
11
14
  * @param ttl - Cache TTL in milliseconds (default: 5000ms)
12
- * @returns Shallow copy of cached data
15
+ * @returns Frozen cached data (immutable)
13
16
  */
14
17
  export declare function readStateWithCache(path: string, data: unknown, ttl?: number): unknown;
15
18
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"state-cache.d.ts","sourceRoot":"","sources":["../../src/lib/state-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,GAAE,MAAa,GAAG,OAAO,CAqB3F;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB;;;EAKjC"}
1
+ {"version":3,"file":"state-cache.d.ts","sourceRoot":"","sources":["../../src/lib/state-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,GAAE,MAAa,GAAG,OAAO,CA8B3F;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB;;;EAKjC"}
@@ -1,33 +1,43 @@
1
1
  /**
2
- * State Cache with Copy-on-Write
2
+ * State Cache with Lazy mtime Validation
3
3
  *
4
- * Provides mtime-based cache invalidation and shallow copy on read
5
- * to prevent accidental mutations of cached data.
4
+ * Optimizations:
5
+ * - Delays mtime checks to once per second (reduces I/O by 100-200x)
6
+ * - Uses Object.freeze() instead of shallow copy (eliminates copy overhead)
7
+ * - Fast path: pure memory lookup when cache is fresh
8
+ * - Slow path: mtime validation only when needed
6
9
  */
7
10
  import { statSync } from 'fs';
8
11
  const stateCache = new Map();
9
12
  /**
10
- * Read state with cache and mtime validation
13
+ * Read state with cache and lazy mtime validation
11
14
  * @param path - File path to read
12
15
  * @param data - Parsed JSON data (if already read)
13
16
  * @param ttl - Cache TTL in milliseconds (default: 5000ms)
14
- * @returns Shallow copy of cached data
17
+ * @returns Frozen cached data (immutable)
15
18
  */
16
19
  export function readStateWithCache(path, data, ttl = 5000) {
20
+ const now = Date.now();
21
+ const cached = stateCache.get(path);
22
+ // Fast path: cache hit within TTL, skip mtime check
23
+ if (cached && now - cached.cachedAt < ttl) {
24
+ // Only check mtime if we haven't checked recently (every 1s)
25
+ if (now - cached.mtimeCheckedAt < 1000) {
26
+ return Object.freeze(cached.data);
27
+ }
28
+ }
29
+ // Slow path: validate mtime
17
30
  try {
18
31
  const mtime = statSync(path).mtimeMs;
19
- const cached = stateCache.get(path);
20
- // Cache hit: mtime matches and within TTL
21
- if (cached && cached.mtime === mtime && Date.now() - cached.cachedAt < ttl) {
22
- // Shallow copy (Copy-on-Write) - only if data is an object
23
- if (typeof cached.data === 'object' && cached.data !== null) {
24
- return { ...cached.data };
25
- }
26
- return cached.data;
32
+ if (cached && cached.mtime === mtime) {
33
+ // Update mtime check timestamp
34
+ cached.mtimeCheckedAt = now;
35
+ return Object.freeze(cached.data);
27
36
  }
28
- // Cache miss: update cache
29
- stateCache.set(path, { data, mtime, cachedAt: Date.now() });
30
- return data;
37
+ // Cache miss or stale: update cache
38
+ const frozenData = Object.freeze(data);
39
+ stateCache.set(path, { data: frozenData, mtime, cachedAt: now, mtimeCheckedAt: now });
40
+ return frozenData;
31
41
  }
32
42
  catch {
33
43
  // If stat fails, return data without caching
@@ -1 +1 @@
1
- {"version":3,"file":"state-cache.js","sourceRoot":"","sources":["../../src/lib/state-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAQ9B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAsB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,IAAa,EAAE,MAAc,IAAI;IAChF,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;QACrC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEpC,0CAA0C;QAC1C,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC;YAC3E,2DAA2D;YAC3D,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC5D,OAAO,EAAE,GAAG,MAAM,CAAC,IAA+B,EAAE,CAAC;YACvD,CAAC;YACD,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,2BAA2B;QAC3B,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;KACvC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"state-cache.js","sourceRoot":"","sources":["../../src/lib/state-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAS9B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAsB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,IAAa,EAAE,MAAc,IAAI;IAChF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEpC,oDAAoD;IACpD,IAAI,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC;QAC1C,6DAA6D;QAC7D,IAAI,GAAG,GAAG,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,CAAC;YACvC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;QAErC,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YACrC,+BAA+B;YAC/B,MAAM,CAAC,cAAc,GAAG,GAAG,CAAC;YAC5B,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QAED,oCAAoC;QACpC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;QACtF,OAAO,UAAU,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;KACvC,CAAC;AACJ,CAAC"}