@liangjie559567/ultrapower 5.0.21 → 5.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/commands/ax-analyze-error.md +0 -1
- package/commands/ax-context.md +0 -1
- package/commands/ax-decompose.md +0 -1
- package/commands/ax-draft.md +0 -1
- package/commands/ax-evolution.md +0 -1
- package/commands/ax-evolve.md +0 -1
- package/commands/ax-export.md +0 -1
- package/commands/ax-implement.md +0 -1
- package/commands/ax-knowledge.md +0 -1
- package/commands/ax-reflect.md +0 -1
- package/commands/ax-review.md +0 -1
- package/commands/ax-rollback.md +0 -1
- package/commands/ax-status.md +0 -1
- package/commands/ax-suspend.md +0 -1
- package/commands/brainstorm.md +0 -1
- package/commands/execute-plan.md +0 -1
- package/commands/write-plan.md +0 -1
- package/dist/__tests__/validateMode.test.d.ts +2 -0
- package/dist/__tests__/validateMode.test.d.ts.map +1 -0
- package/dist/__tests__/validateMode.test.js +100 -0
- package/dist/__tests__/validateMode.test.js.map +1 -0
- package/dist/lib/validateMode.d.ts +49 -0
- package/dist/lib/validateMode.d.ts.map +1 -0
- package/dist/lib/validateMode.js +68 -0
- package/dist/lib/validateMode.js.map +1 -0
- package/docs/CLAUDE.md +1 -1
- package/docs/prd/ultrapower-standards-draft.md +191 -0
- package/docs/prd/ultrapower-standards-rough.md +560 -0
- package/docs/reviews/ultrapower-standards/review_critic.md +230 -0
- package/docs/reviews/ultrapower-standards/review_domain.md +243 -0
- package/docs/reviews/ultrapower-standards/review_product.md +102 -0
- package/docs/reviews/ultrapower-standards/review_tech.md +142 -0
- package/docs/reviews/ultrapower-standards/review_ux.md +110 -0
- package/docs/reviews/ultrapower-standards/summary.md +85 -0
- package/docs/standards/README.md +85 -0
- package/docs/standards/agent-lifecycle.md +445 -0
- package/docs/standards/anti-patterns.md +365 -0
- package/docs/standards/audit-report.md +388 -0
- package/docs/standards/contribution-guide.md +208 -0
- package/docs/standards/hook-execution-order.md +320 -0
- package/docs/standards/runtime-protection.md +336 -0
- package/docs/standards/state-machine.md +316 -0
- package/docs/standards/templates/agent-template.md +63 -0
- package/docs/standards/templates/hook-template.md +74 -0
- package/docs/standards/templates/skill-template.md +48 -0
- package/docs/standards/user-guide.md +290 -0
- package/docs/tasks/ultrapower-standards/manifest.md +441 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultrapower",
|
|
3
3
|
"description": "Disciplined multi-agent orchestration: workflow enforcement + parallel execution. Combines superpowers' TDD/debugging discipline with OMC's multi-agent execution capabilities.",
|
|
4
|
-
"version": "5.0.
|
|
4
|
+
"version": "5.0.23",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Jesse Vincent & oh-my-claudecode contributors"
|
|
7
7
|
},
|
package/commands/ax-context.md
CHANGED
package/commands/ax-decompose.md
CHANGED
package/commands/ax-draft.md
CHANGED
package/commands/ax-evolution.md
CHANGED
package/commands/ax-evolve.md
CHANGED
package/commands/ax-export.md
CHANGED
package/commands/ax-implement.md
CHANGED
package/commands/ax-knowledge.md
CHANGED
package/commands/ax-reflect.md
CHANGED
package/commands/ax-review.md
CHANGED
package/commands/ax-rollback.md
CHANGED
package/commands/ax-status.md
CHANGED
package/commands/ax-suspend.md
CHANGED
package/commands/brainstorm.md
CHANGED
package/commands/execute-plan.md
CHANGED
package/commands/write-plan.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateMode.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/validateMode.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { validateMode, assertValidMode, VALID_MODES } from '../lib/validateMode.js';
|
|
3
|
+
describe('validateMode', () => {
|
|
4
|
+
it('should return true for all 8 valid modes', () => {
|
|
5
|
+
const expected = ['autopilot', 'ultrapilot', 'team', 'pipeline', 'ralph', 'ultrawork', 'ultraqa', 'swarm'];
|
|
6
|
+
expect(VALID_MODES).toHaveLength(8);
|
|
7
|
+
for (const mode of expected) {
|
|
8
|
+
expect(validateMode(mode)).toBe(true);
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
it('should return false for unknown mode strings', () => {
|
|
12
|
+
expect(validateMode('unknown')).toBe(false);
|
|
13
|
+
expect(validateMode('auto')).toBe(false);
|
|
14
|
+
expect(validateMode('AUTOPILOT')).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
it('should return false for path traversal attempts', () => {
|
|
17
|
+
expect(validateMode('../../etc/passwd')).toBe(false);
|
|
18
|
+
expect(validateMode('../autopilot')).toBe(false);
|
|
19
|
+
expect(validateMode('autopilot/../../../etc')).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
it('should return false for empty string', () => {
|
|
22
|
+
expect(validateMode('')).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
it('should return false for non-string types', () => {
|
|
25
|
+
expect(validateMode(null)).toBe(false);
|
|
26
|
+
expect(validateMode(undefined)).toBe(false);
|
|
27
|
+
expect(validateMode(42)).toBe(false);
|
|
28
|
+
expect(validateMode({})).toBe(false);
|
|
29
|
+
expect(validateMode([])).toBe(false);
|
|
30
|
+
expect(validateMode(true)).toBe(false);
|
|
31
|
+
expect(validateMode(Symbol('autopilot'))).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
it('should return false for whitespace-only strings', () => {
|
|
34
|
+
expect(validateMode(' ')).toBe(false);
|
|
35
|
+
expect(validateMode('\t')).toBe(false);
|
|
36
|
+
expect(validateMode('\n')).toBe(false);
|
|
37
|
+
expect(validateMode(' ')).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
it('should return false for null byte injection', () => {
|
|
40
|
+
expect(validateMode('autopilot\x00')).toBe(false);
|
|
41
|
+
expect(validateMode('autopilot\x00../../etc')).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
it('should return false for prototype pollution vectors', () => {
|
|
44
|
+
expect(validateMode('__proto__')).toBe(false);
|
|
45
|
+
expect(validateMode('constructor')).toBe(false);
|
|
46
|
+
expect(validateMode('prototype')).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
it('should handle very long strings without throwing', () => {
|
|
49
|
+
const longString = 'a'.repeat(1_000_000);
|
|
50
|
+
expect(validateMode(longString)).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe('assertValidMode', () => {
|
|
54
|
+
it('should return the mode string for valid modes', () => {
|
|
55
|
+
expect(assertValidMode('autopilot')).toBe('autopilot');
|
|
56
|
+
expect(assertValidMode('swarm')).toBe('swarm');
|
|
57
|
+
expect(assertValidMode('ralph')).toBe('ralph');
|
|
58
|
+
});
|
|
59
|
+
it('should throw for invalid mode strings', () => {
|
|
60
|
+
expect(() => assertValidMode('unknown')).toThrow('Invalid mode');
|
|
61
|
+
expect(() => assertValidMode('../../etc')).toThrow('Invalid mode');
|
|
62
|
+
});
|
|
63
|
+
it('should throw for non-string input', () => {
|
|
64
|
+
expect(() => assertValidMode(null)).toThrow('Invalid mode');
|
|
65
|
+
expect(() => assertValidMode(undefined)).toThrow('Invalid mode');
|
|
66
|
+
});
|
|
67
|
+
it('error message should list valid modes', () => {
|
|
68
|
+
expect(() => assertValidMode('bad')).toThrow('autopilot');
|
|
69
|
+
});
|
|
70
|
+
it('error message should truncate very long input to prevent DoS', () => {
|
|
71
|
+
const longInput = 'x'.repeat(1_000_000);
|
|
72
|
+
let errorMessage = '';
|
|
73
|
+
try {
|
|
74
|
+
assertValidMode(longInput);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
errorMessage = e.message;
|
|
78
|
+
}
|
|
79
|
+
expect(errorMessage.length).toBeLessThan(500);
|
|
80
|
+
expect(errorMessage).toContain('truncated');
|
|
81
|
+
});
|
|
82
|
+
it('error message should not expose raw non-string input verbatim', () => {
|
|
83
|
+
const obj = { secret: 'password123' };
|
|
84
|
+
let errorMessage = '';
|
|
85
|
+
try {
|
|
86
|
+
assertValidMode(obj);
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
errorMessage = e.message;
|
|
90
|
+
}
|
|
91
|
+
expect(errorMessage).not.toContain('password123');
|
|
92
|
+
});
|
|
93
|
+
it('returned value should be usable in path construction without traversal risk', () => {
|
|
94
|
+
const mode = assertValidMode('autopilot');
|
|
95
|
+
const path = `.omc/state/${mode}-state.json`;
|
|
96
|
+
expect(path).toBe('.omc/state/autopilot-state.json');
|
|
97
|
+
expect(path).not.toContain('..');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=validateMode.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateMode.test.js","sourceRoot":"","sources":["../../src/__tests__/validateMode.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEpF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,QAAQ,GAAG,CAAC,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC3G,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,MAAM,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACvD,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC5D,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,YAAY,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,eAAe,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,YAAY,GAAI,CAAW,CAAC,OAAO,CAAC;QACtC,CAAC;QACD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QACtC,IAAI,YAAY,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,eAAe,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,YAAY,GAAI,CAAW,CAAC,OAAO,CAAC;QACtC,CAAC;QACD,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,MAAM,IAAI,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,cAAc,IAAI,aAAa,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mode parameter validation for ultrapower.
|
|
3
|
+
* Prevents path traversal attacks by enforcing a strict whitelist of valid mode names.
|
|
4
|
+
*
|
|
5
|
+
* Security boundary: mode values are used to construct file paths like
|
|
6
|
+
* `.omc/state/${mode}-state.json`. Direct string interpolation without
|
|
7
|
+
* validation would allow path traversal (e.g., mode = "../../etc/passwd").
|
|
8
|
+
*
|
|
9
|
+
* Source of truth: src/hooks/mode-registry/index.ts
|
|
10
|
+
* Spec: docs/standards/runtime-protection.md §2.4
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* All valid execution mode names (8 total).
|
|
14
|
+
* Derived from src/hooks/mode-registry/index.ts.
|
|
15
|
+
* Note (D-03): PRD originally listed 7 modes; 'swarm' was added, making 8.
|
|
16
|
+
*/
|
|
17
|
+
export declare const VALID_MODES: readonly ["autopilot", "ultrapilot", "team", "pipeline", "ralph", "ultrawork", "ultraqa", "swarm"];
|
|
18
|
+
/** Union type of all valid mode strings. */
|
|
19
|
+
export type ValidMode = (typeof VALID_MODES)[number];
|
|
20
|
+
/**
|
|
21
|
+
* Check whether a string is a valid mode name.
|
|
22
|
+
*
|
|
23
|
+
* @param mode - Untrusted input to validate
|
|
24
|
+
* @returns `true` if `mode` is one of the 8 valid modes, `false` otherwise
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* validateMode('autopilot') // true
|
|
28
|
+
* validateMode('../../etc') // false
|
|
29
|
+
* validateMode('') // false
|
|
30
|
+
*/
|
|
31
|
+
export declare function validateMode(mode: unknown): mode is ValidMode;
|
|
32
|
+
/**
|
|
33
|
+
* Assert that a string is a valid mode name, throwing on invalid input.
|
|
34
|
+
* Use this when constructing file paths from user-supplied mode values.
|
|
35
|
+
*
|
|
36
|
+
* @param mode - Untrusted input to validate
|
|
37
|
+
* @returns The validated mode string (narrowed to `ValidMode`)
|
|
38
|
+
* @throws {Error} If `mode` is not a valid mode name
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // Safe path construction
|
|
42
|
+
* const validMode = assertValidMode(mode);
|
|
43
|
+
* const stateFilePath = `.omc/state/${validMode}-state.json`;
|
|
44
|
+
*
|
|
45
|
+
* // ❌ Never do this — path traversal risk:
|
|
46
|
+
* // const stateFilePath = `.omc/state/${mode}-state.json`;
|
|
47
|
+
*/
|
|
48
|
+
export declare function assertValidMode(mode: unknown): ValidMode;
|
|
49
|
+
//# sourceMappingURL=validateMode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateMode.d.ts","sourceRoot":"","sources":["../../src/lib/validateMode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,oGASd,CAAC;AAEX,4CAA4C;AAC5C,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,SAAS,CAE7D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAYxD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mode parameter validation for ultrapower.
|
|
3
|
+
* Prevents path traversal attacks by enforcing a strict whitelist of valid mode names.
|
|
4
|
+
*
|
|
5
|
+
* Security boundary: mode values are used to construct file paths like
|
|
6
|
+
* `.omc/state/${mode}-state.json`. Direct string interpolation without
|
|
7
|
+
* validation would allow path traversal (e.g., mode = "../../etc/passwd").
|
|
8
|
+
*
|
|
9
|
+
* Source of truth: src/hooks/mode-registry/index.ts
|
|
10
|
+
* Spec: docs/standards/runtime-protection.md §2.4
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* All valid execution mode names (8 total).
|
|
14
|
+
* Derived from src/hooks/mode-registry/index.ts.
|
|
15
|
+
* Note (D-03): PRD originally listed 7 modes; 'swarm' was added, making 8.
|
|
16
|
+
*/
|
|
17
|
+
export const VALID_MODES = [
|
|
18
|
+
'autopilot',
|
|
19
|
+
'ultrapilot',
|
|
20
|
+
'team',
|
|
21
|
+
'pipeline',
|
|
22
|
+
'ralph',
|
|
23
|
+
'ultrawork',
|
|
24
|
+
'ultraqa',
|
|
25
|
+
'swarm',
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Check whether a string is a valid mode name.
|
|
29
|
+
*
|
|
30
|
+
* @param mode - Untrusted input to validate
|
|
31
|
+
* @returns `true` if `mode` is one of the 8 valid modes, `false` otherwise
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* validateMode('autopilot') // true
|
|
35
|
+
* validateMode('../../etc') // false
|
|
36
|
+
* validateMode('') // false
|
|
37
|
+
*/
|
|
38
|
+
export function validateMode(mode) {
|
|
39
|
+
return typeof mode === 'string' && VALID_MODES.includes(mode);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Assert that a string is a valid mode name, throwing on invalid input.
|
|
43
|
+
* Use this when constructing file paths from user-supplied mode values.
|
|
44
|
+
*
|
|
45
|
+
* @param mode - Untrusted input to validate
|
|
46
|
+
* @returns The validated mode string (narrowed to `ValidMode`)
|
|
47
|
+
* @throws {Error} If `mode` is not a valid mode name
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // Safe path construction
|
|
51
|
+
* const validMode = assertValidMode(mode);
|
|
52
|
+
* const stateFilePath = `.omc/state/${validMode}-state.json`;
|
|
53
|
+
*
|
|
54
|
+
* // ❌ Never do this — path traversal risk:
|
|
55
|
+
* // const stateFilePath = `.omc/state/${mode}-state.json`;
|
|
56
|
+
*/
|
|
57
|
+
export function assertValidMode(mode) {
|
|
58
|
+
if (!validateMode(mode)) {
|
|
59
|
+
// Truncate input to prevent DoS via memory amplification and avoid
|
|
60
|
+
// leaking large attacker-controlled payloads into logs/notifications.
|
|
61
|
+
const raw = typeof mode === 'string' ? mode : String(mode);
|
|
62
|
+
const display = raw.length > 50 ? `${raw.slice(0, 50)}...(truncated)` : raw;
|
|
63
|
+
throw new Error(`Invalid mode: "${display}". ` +
|
|
64
|
+
`Valid modes are: ${VALID_MODES.join(', ')}`);
|
|
65
|
+
}
|
|
66
|
+
return mode;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=validateMode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateMode.js","sourceRoot":"","sources":["../../src/lib/validateMode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,YAAY;IACZ,MAAM;IACN,UAAU;IACV,OAAO;IACP,WAAW;IACX,SAAS;IACT,OAAO;CACC,CAAC;AAKX;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAK,WAAiC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACvF,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,IAAa;IAC3C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,mEAAmE;QACnE,sEAAsE;QACtE,MAAM,GAAG,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC;QAC5E,MAAM,IAAI,KAAK,CACb,kBAAkB,OAAO,KAAK;YAC5B,oBAAoB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/C,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/docs/CLAUDE.md
CHANGED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# PRD: ultrapower 全链路规范体系 - Draft
|
|
2
|
+
|
|
3
|
+
> **状态**: DRAFT
|
|
4
|
+
> **作者**: Product Design Expert (axiom-product-designer)
|
|
5
|
+
> **版本**: 0.1
|
|
6
|
+
> **日期**: 2026-02-26
|
|
7
|
+
> **项目**: ultrapower v5.0.21
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. 背景与目标
|
|
12
|
+
|
|
13
|
+
### 1.1 背景
|
|
14
|
+
|
|
15
|
+
ultrapower(OMC)是 Claude Code 的多 agent 编排框架,当前版本 v5.0.21 已具备完整的 agent 目录、skill 体系和 hook 机制。随着功能复杂度提升,三类系统性问题开始显现:
|
|
16
|
+
|
|
17
|
+
- **运行时 BUG**:Hook 执行顺序不确定、状态文件并发读写冲突、Agent 生命周期管理缺失(参考已知问题:2026-02-12 Race Condition)
|
|
18
|
+
- **使用混乱**:用户不清楚何时用 skill、何时用 agent、何时用 MCP,导致错误路由和资源浪费
|
|
19
|
+
- **贡献无序**:新增 skill/agent/hook 缺乏统一模板和检查清单,引入不一致的实现模式
|
|
20
|
+
|
|
21
|
+
### 1.2 目标
|
|
22
|
+
|
|
23
|
+
建立覆盖全链路的规范体系,使 ultrapower 从"能用"升级为"可靠、易用、可扩展"。
|
|
24
|
+
|
|
25
|
+
### 1.3 成功指标
|
|
26
|
+
|
|
27
|
+
| 指标 | 当前状态 | 目标 |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| 并发场景有明确处理指引 | 无 | 100% 覆盖 |
|
|
30
|
+
| 新用户选出正确 skill 的时间 | 未知 | ≤ 5 分钟 |
|
|
31
|
+
| 新增 skill 有完整检查清单 | 无 | 100% 覆盖 |
|
|
32
|
+
| 三类 BUG 来源有对应规范 | 无 | 全覆盖 |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 2. 用户故事
|
|
37
|
+
|
|
38
|
+
| 角色 | 目标 | 收益 |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| 框架使用者(新用户) | 快速判断应该调用哪个 skill 或 agent | 5 分钟内做出正确决策,不走弯路 |
|
|
41
|
+
| 框架使用者(老用户) | 在并发/复杂场景下得到明确的操作指引 | 避免状态冲突和运行时错误 |
|
|
42
|
+
| 框架贡献者 | 按照统一模板新增 skill/agent/hook | 一次通过代码审查,不引入不一致模式 |
|
|
43
|
+
| 框架维护者 | 快速定位 BUG 根因并有规范可依 | 减少排查时间,修复有据可查 |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 3. 高层需求(MVP)
|
|
48
|
+
|
|
49
|
+
### P0 - 运行时防护规范(必须交付)
|
|
50
|
+
|
|
51
|
+
1. **Hook 执行顺序规范**:定义 PreToolUse / PostToolUse / Stop 三类 hook 的触发时序、优先级和互斥规则
|
|
52
|
+
2. **状态文件读写规范**:明确 `.omc/state/` 下各文件的读写锁策略,禁止并发写入同一状态文件
|
|
53
|
+
3. **Agent 生命周期规范**:定义 agent 从 spawn 到 shutdown 的标准状态机,包含超时和异常退出处理
|
|
54
|
+
|
|
55
|
+
### P1 - 用户使用规范(核心体验)
|
|
56
|
+
|
|
57
|
+
4. **Skill 调用决策树**:提供可视化决策流程,帮助用户在 skill / agent / MCP 三者间做出正确选择
|
|
58
|
+
5. **Agent 路由规范**:明确各 agent 角色的适用场景边界,避免错误路由(如用 executor 做分析)
|
|
59
|
+
6. **常见反模式清单**:列举并解释 10 个最常见的错误用法,每条附正确替代方案
|
|
60
|
+
|
|
61
|
+
### P2 - 开发贡献规范(生态健康)
|
|
62
|
+
|
|
63
|
+
7. **Skill 标准模板**:包含触发词、约束、输出格式、测试用例的完整模板
|
|
64
|
+
8. **Agent 标准模板**:包含角色定义、工具权限、输入输出契约的标准结构
|
|
65
|
+
9. **Hook 标准模板**:包含事件类型、必需字段、错误处理的标准结构
|
|
66
|
+
10. **贡献检查清单**:新增任何组件前必须通过的 checklist(含测试要求和版本兼容性验证)
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 4. 业务流程
|
|
71
|
+
|
|
72
|
+
### 4.1 用户使用决策流程
|
|
73
|
+
|
|
74
|
+
```mermaid
|
|
75
|
+
graph TD
|
|
76
|
+
A[用户有任务] --> B{任务类型判断}
|
|
77
|
+
B --> |简单单步操作| C[直接处理]
|
|
78
|
+
B --> |需要代码实现| D{复杂度判断}
|
|
79
|
+
B --> |需要分析/规划| E[MCP 工具优先]
|
|
80
|
+
B --> |多文件/多领域| F[Team 模式]
|
|
81
|
+
|
|
82
|
+
D --> |标准实现| G[executor / sonnet]
|
|
83
|
+
D --> |复杂自主任务| H[deep-executor / opus]
|
|
84
|
+
|
|
85
|
+
E --> |文档查找| I[Context7 MCP]
|
|
86
|
+
E --> |架构分析| J[ask_codex]
|
|
87
|
+
E --> |UI/设计| K[ask_gemini]
|
|
88
|
+
|
|
89
|
+
F --> L[team-plan]
|
|
90
|
+
L --> M[team-prd]
|
|
91
|
+
M --> N[team-exec]
|
|
92
|
+
N --> O[team-verify]
|
|
93
|
+
O --> |通过| P[complete]
|
|
94
|
+
O --> |失败| Q[team-fix]
|
|
95
|
+
Q --> N
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 4.2 运行时状态机(Agent 生命周期)
|
|
99
|
+
|
|
100
|
+
```mermaid
|
|
101
|
+
stateDiagram-v2
|
|
102
|
+
[*] --> SPAWNED : Task() 调用
|
|
103
|
+
SPAWNED --> RUNNING : 工具调用开始
|
|
104
|
+
RUNNING --> WAITING : 等待用户输入
|
|
105
|
+
WAITING --> RUNNING : 收到输入
|
|
106
|
+
RUNNING --> IDLE : 当前 turn 结束
|
|
107
|
+
IDLE --> RUNNING : 收到新消息
|
|
108
|
+
IDLE --> SHUTDOWN : shutdown_request
|
|
109
|
+
RUNNING --> ERROR : 异常/超时
|
|
110
|
+
ERROR --> SHUTDOWN : 错误处理完成
|
|
111
|
+
SHUTDOWN --> [*]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 4.3 Hook 执行时序
|
|
115
|
+
|
|
116
|
+
```mermaid
|
|
117
|
+
sequenceDiagram
|
|
118
|
+
participant U as 用户
|
|
119
|
+
participant C as Claude
|
|
120
|
+
participant H as Hook 系统
|
|
121
|
+
participant S as 状态文件
|
|
122
|
+
|
|
123
|
+
U->>C: 发送指令
|
|
124
|
+
C->>H: PreToolUse hook
|
|
125
|
+
H->>S: 读取状态(只读)
|
|
126
|
+
H-->>C: hook success / block
|
|
127
|
+
C->>C: 执行工具调用
|
|
128
|
+
C->>H: PostToolUse hook
|
|
129
|
+
H->>S: 写入状态(加锁)
|
|
130
|
+
S-->>H: 写入完成
|
|
131
|
+
H-->>C: hook success
|
|
132
|
+
C->>H: Stop hook(turn 结束)
|
|
133
|
+
H->>S: 清理临时状态
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 5. 非功能需求
|
|
139
|
+
|
|
140
|
+
| 类别 | 要求 |
|
|
141
|
+
| --- | --- |
|
|
142
|
+
| 可读性 | 所有规范文档使用中文,代码示例使用英文 |
|
|
143
|
+
| 可维护性 | 规范文档与代码同仓库,随版本迭代更新 |
|
|
144
|
+
| 向后兼容 | P0/P1 规范不得破坏现有 v5.0.x 用户的使用习惯 |
|
|
145
|
+
| 可发现性 | 规范入口在 README 和 CLAUDE.md 中有明确链接 |
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 6. 验收标准
|
|
150
|
+
|
|
151
|
+
| 编号 | 验收项 | 验证方法 |
|
|
152
|
+
| --- | --- | --- |
|
|
153
|
+
| AC-01 | 并发场景有明确处理指引 | 检查 P0 规范是否覆盖:并行 agent 写同一状态文件的场景 |
|
|
154
|
+
| AC-02 | 新用户 5 分钟内选出正确 skill | 用户测试:给出 3 个典型场景,新用户按决策树选择,准确率 ≥ 80% |
|
|
155
|
+
| AC-03 | 新增 skill 有完整检查清单 | 检查 P2 checklist 是否包含:触发词、测试用例、版本兼容性三项 |
|
|
156
|
+
| AC-04 | 三类 BUG 来源均有对应规范 | 逐一映射:运行时 BUG → P0,使用混乱 → P1,贡献无序 → P2 |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 7. Impact Scope(影响文件范围)
|
|
161
|
+
|
|
162
|
+
本 PRD 实现后,预期新增/修改的文件范围:
|
|
163
|
+
|
|
164
|
+
**新增文件(规范文档):**
|
|
165
|
+
- `docs/standards/runtime-protection.md` — P0 运行时防护规范
|
|
166
|
+
- `docs/standards/user-guide.md` — P1 用户使用规范(含决策树)
|
|
167
|
+
- `docs/standards/contribution-guide.md` — P2 开发贡献规范
|
|
168
|
+
- `docs/standards/templates/skill-template.md` — Skill 标准模板
|
|
169
|
+
- `docs/standards/templates/agent-template.md` — Agent 标准模板
|
|
170
|
+
- `docs/standards/templates/hook-template.md` — Hook 标准模板
|
|
171
|
+
|
|
172
|
+
**修改文件(入口链接):**
|
|
173
|
+
- `README.md` — 添加规范文档入口
|
|
174
|
+
- `CLAUDE.md` — 添加规范引用
|
|
175
|
+
|
|
176
|
+
**不在范围内(v2 延期):**
|
|
177
|
+
- 自动化规范检查工具(lint 插件)
|
|
178
|
+
- 规范合规性 CI 检查
|
|
179
|
+
- 多语言版本(英文版)
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 8. 暂不包含(v2 延期)
|
|
184
|
+
|
|
185
|
+
- 自动化规范合规检查(需要额外工具链投入)
|
|
186
|
+
- 英文版规范文档(当前用户群以中文为主)
|
|
187
|
+
- 视频教程或交互式引导(超出文档范围)
|
|
188
|
+
- 规范覆盖率度量仪表盘
|
|
189
|
+
- 历史 BUG 的规范回溯标注
|
|
190
|
+
|
|
191
|
+
|