oh-my-claude-sisyphus 3.2.5 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +37 -2
  2. package/agents/scientist-high.md +1003 -0
  3. package/agents/scientist-low.md +232 -0
  4. package/agents/scientist.md +1180 -0
  5. package/bridge/__pycache__/gyoshu_bridge.cpython-310.pyc +0 -0
  6. package/bridge/gyoshu_bridge.py +846 -0
  7. package/commands/research.md +511 -0
  8. package/dist/agents/definitions.d.ts +9 -0
  9. package/dist/agents/definitions.d.ts.map +1 -1
  10. package/dist/agents/definitions.js +25 -0
  11. package/dist/agents/definitions.js.map +1 -1
  12. package/dist/agents/index.d.ts +2 -1
  13. package/dist/agents/index.d.ts.map +1 -1
  14. package/dist/agents/index.js +2 -1
  15. package/dist/agents/index.js.map +1 -1
  16. package/dist/agents/scientist.d.ts +16 -0
  17. package/dist/agents/scientist.d.ts.map +1 -0
  18. package/dist/agents/scientist.js +370 -0
  19. package/dist/agents/scientist.js.map +1 -0
  20. package/dist/lib/atomic-write.d.ts +29 -0
  21. package/dist/lib/atomic-write.d.ts.map +1 -0
  22. package/dist/lib/atomic-write.js +111 -0
  23. package/dist/lib/atomic-write.js.map +1 -0
  24. package/dist/tools/index.d.ts +1 -0
  25. package/dist/tools/index.d.ts.map +1 -1
  26. package/dist/tools/index.js +4 -1
  27. package/dist/tools/index.js.map +1 -1
  28. package/dist/tools/python-repl/bridge-manager.d.ts +65 -0
  29. package/dist/tools/python-repl/bridge-manager.d.ts.map +1 -0
  30. package/dist/tools/python-repl/bridge-manager.js +478 -0
  31. package/dist/tools/python-repl/bridge-manager.js.map +1 -0
  32. package/dist/tools/python-repl/index.d.ts +40 -0
  33. package/dist/tools/python-repl/index.d.ts.map +1 -0
  34. package/dist/tools/python-repl/index.js +36 -0
  35. package/dist/tools/python-repl/index.js.map +1 -0
  36. package/dist/tools/python-repl/paths.d.ts +84 -0
  37. package/dist/tools/python-repl/paths.d.ts.map +1 -0
  38. package/dist/tools/python-repl/paths.js +213 -0
  39. package/dist/tools/python-repl/paths.js.map +1 -0
  40. package/dist/tools/python-repl/session-lock.d.ts +111 -0
  41. package/dist/tools/python-repl/session-lock.d.ts.map +1 -0
  42. package/dist/tools/python-repl/session-lock.js +510 -0
  43. package/dist/tools/python-repl/session-lock.js.map +1 -0
  44. package/dist/tools/python-repl/socket-client.d.ts +42 -0
  45. package/dist/tools/python-repl/socket-client.d.ts.map +1 -0
  46. package/dist/tools/python-repl/socket-client.js +157 -0
  47. package/dist/tools/python-repl/socket-client.js.map +1 -0
  48. package/dist/tools/python-repl/tool.d.ts +100 -0
  49. package/dist/tools/python-repl/tool.d.ts.map +1 -0
  50. package/dist/tools/python-repl/tool.js +575 -0
  51. package/dist/tools/python-repl/tool.js.map +1 -0
  52. package/dist/tools/python-repl/types.d.ts +95 -0
  53. package/dist/tools/python-repl/types.d.ts.map +1 -0
  54. package/dist/tools/python-repl/types.js +2 -0
  55. package/dist/tools/python-repl/types.js.map +1 -0
  56. package/package.json +2 -1
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Path utilities for Python REPL tool
3
+ *
4
+ * Provides secure path resolution for session directories, sockets, and metadata.
5
+ * Uses OS-appropriate runtime directories outside the project root.
6
+ */
7
+ import * as fs from "fs";
8
+ import * as path from "path";
9
+ import * as os from "os";
10
+ import * as crypto from "crypto";
11
+ // =============================================================================
12
+ // CONSTANTS
13
+ // =============================================================================
14
+ /**
15
+ * Maximum length for Unix socket paths (Linux: 108, macOS: 104).
16
+ * We use a conservative value that works on both platforms.
17
+ */
18
+ const MAX_SOCKET_PATH_LENGTH = 100;
19
+ /**
20
+ * Length of the short session ID hash used for socket paths.
21
+ * 12 hex chars = 6 bytes = 281 trillion possible values, negligible collision risk.
22
+ */
23
+ const SHORT_SESSION_ID_LENGTH = 12;
24
+ /**
25
+ * Windows reserved device names that cannot be used as file names.
26
+ * These names cause issues on Windows regardless of file extension.
27
+ * Applied unconditionally (portable-safe) to prevent cross-platform issues.
28
+ */
29
+ const WINDOWS_RESERVED_NAMES = new Set([
30
+ // Standard reserved device names
31
+ 'CON', 'PRN', 'AUX', 'NUL',
32
+ 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
33
+ 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9',
34
+ ]);
35
+ // =============================================================================
36
+ // RUNTIME DIRECTORY RESOLUTION
37
+ // =============================================================================
38
+ /**
39
+ * Validate XDG_RUNTIME_DIR security properties.
40
+ * On multi-user systems, XDG_RUNTIME_DIR can be poisoned if not validated.
41
+ * @param dir - XDG_RUNTIME_DIR path to validate
42
+ * @returns true if the directory is secure (exists, not symlink, owned by uid, mode 0700)
43
+ */
44
+ function isSecureRuntimeDir(dir) {
45
+ // Must be absolute path (prevents XDG_RUNTIME_DIR="." exploits)
46
+ if (!path.isAbsolute(dir))
47
+ return false;
48
+ try {
49
+ const stat = fs.lstatSync(dir);
50
+ if (!stat.isDirectory() || stat.isSymbolicLink())
51
+ return false;
52
+ if (stat.uid !== process.getuid?.())
53
+ return false;
54
+ if ((stat.mode & 0o777) !== 0o700)
55
+ return false;
56
+ return true;
57
+ }
58
+ catch {
59
+ return false;
60
+ }
61
+ }
62
+ /**
63
+ * Get the path to the runtime directory.
64
+ * Contains ephemeral session data like locks and sockets.
65
+ * Uses OS-appropriate temp directories.
66
+ *
67
+ * Priority:
68
+ * 1. XDG_RUNTIME_DIR/omc (Linux standard, usually /run/user/{uid})
69
+ * 2. Platform-specific user cache directory
70
+ * 3. os.tmpdir() fallback
71
+ *
72
+ * @returns Path to runtime directory
73
+ *
74
+ * @example
75
+ * getRuntimeDir();
76
+ * // Linux with XDG: '/run/user/1000/omc'
77
+ * // macOS: '~/Library/Caches/omc/runtime'
78
+ * // Fallback: '/tmp/omc/runtime'
79
+ */
80
+ export function getRuntimeDir() {
81
+ // Priority 1: XDG_RUNTIME_DIR (Linux standard, usually /run/user/{uid})
82
+ const xdgRuntime = process.env.XDG_RUNTIME_DIR;
83
+ if (xdgRuntime && isSecureRuntimeDir(xdgRuntime)) {
84
+ return path.join(xdgRuntime, "omc");
85
+ }
86
+ // Priority 2: Platform-specific user cache directory
87
+ const platform = process.platform;
88
+ if (platform === "darwin") {
89
+ return path.join(os.homedir(), "Library", "Caches", "omc", "runtime");
90
+ }
91
+ else if (platform === "linux") {
92
+ // Linux fallback - use /tmp (XDG validation failed)
93
+ return path.join("/tmp", "omc", "runtime");
94
+ }
95
+ // Priority 3: Final fallback to os.tmpdir() for any other platform
96
+ return path.join(os.tmpdir(), "omc", "runtime");
97
+ }
98
+ // =============================================================================
99
+ // SESSION PATH UTILITIES
100
+ // =============================================================================
101
+ /**
102
+ * Shorten a session ID to fit within Unix socket path constraints.
103
+ * Uses SHA256 hash truncated to 12 hex chars (48 bits).
104
+ *
105
+ * Unix sockets have path length limits (UNIX_PATH_MAX):
106
+ * - Linux: 108 bytes
107
+ * - macOS: 104 bytes
108
+ *
109
+ * SECURITY: Always hashes the input, even for short IDs.
110
+ * This prevents path traversal attacks via malicious short IDs like ".." or "../x".
111
+ *
112
+ * @param sessionId - Original session identifier (can be any length)
113
+ * @returns Short identifier (12 hex chars) suitable for socket paths
114
+ */
115
+ export function shortenSessionId(sessionId) {
116
+ // SECURITY: Always hash - do not return raw input even for short IDs
117
+ // This prevents traversal attacks like "../.." which is only 5 chars
118
+ return crypto
119
+ .createHash("sha256")
120
+ .update(sessionId)
121
+ .digest("hex")
122
+ .slice(0, SHORT_SESSION_ID_LENGTH);
123
+ }
124
+ /**
125
+ * Get the path to a specific session's runtime directory.
126
+ * Uses shortened session ID to ensure socket paths stay within limits.
127
+ *
128
+ * @param sessionId - Unique identifier for the session
129
+ * @returns Path to runtime/{shortId}/ in OS temp directory
130
+ */
131
+ export function getSessionDir(sessionId) {
132
+ const shortId = shortenSessionId(sessionId);
133
+ return path.join(getRuntimeDir(), shortId);
134
+ }
135
+ /**
136
+ * Get the path to a session's bridge socket.
137
+ * Path is kept short to respect Unix socket path limits (~108 bytes).
138
+ *
139
+ * @param sessionId - Unique identifier for the session
140
+ * @returns Path to bridge.sock in session's runtime directory
141
+ */
142
+ export function getBridgeSocketPath(sessionId) {
143
+ return path.join(getSessionDir(sessionId), "bridge.sock");
144
+ }
145
+ /**
146
+ * Get the path to a session's bridge metadata file.
147
+ *
148
+ * @param sessionId - Unique identifier for the session
149
+ * @returns Path to bridge_meta.json in session's runtime directory
150
+ */
151
+ export function getBridgeMetaPath(sessionId) {
152
+ return path.join(getSessionDir(sessionId), "bridge_meta.json");
153
+ }
154
+ /**
155
+ * Get the path to a session's lock file.
156
+ *
157
+ * @param sessionId - Unique identifier for the session
158
+ * @returns Path to session.lock in session's runtime directory
159
+ */
160
+ export function getSessionLockPath(sessionId) {
161
+ return path.join(getSessionDir(sessionId), "session.lock");
162
+ }
163
+ // =============================================================================
164
+ // PATH VALIDATION
165
+ // =============================================================================
166
+ /**
167
+ * Validates that a path segment is safe to use in file paths.
168
+ * Prevents directory traversal and path injection attacks.
169
+ *
170
+ * @param segment - The path segment to validate (e.g., session ID, file name)
171
+ * @param name - Name of the parameter for error messages (e.g., "sessionId", "filename")
172
+ * @throws Error if segment is invalid
173
+ *
174
+ * @example
175
+ * validatePathSegment("my-session-123", "sessionId"); // OK
176
+ * validatePathSegment("../evil", "sessionId"); // throws Error
177
+ */
178
+ export function validatePathSegment(segment, name) {
179
+ if (!segment || typeof segment !== "string") {
180
+ throw new Error(`${name} is required and must be a string`);
181
+ }
182
+ if (segment.trim().length === 0) {
183
+ throw new Error(`Invalid ${name}: cannot be empty or whitespace`);
184
+ }
185
+ // Normalize Unicode to prevent bypass via alternative representations
186
+ const normalized = segment.normalize("NFC");
187
+ // Prevent path traversal attacks
188
+ // Block both ".." (parent directory) and path separators
189
+ if (normalized.includes("..") || normalized.includes("/") || normalized.includes("\\")) {
190
+ throw new Error(`Invalid ${name}: contains path traversal characters`);
191
+ }
192
+ // Prevent null bytes
193
+ if (normalized.includes("\0")) {
194
+ throw new Error(`Invalid ${name}: contains null byte`);
195
+ }
196
+ // Limit byte length (filesystems typically limit to 255 bytes, not chars)
197
+ if (Buffer.byteLength(normalized, "utf8") > 255) {
198
+ throw new Error(`Invalid ${name}: exceeds maximum length of 255 bytes`);
199
+ }
200
+ // Reject Windows reserved device names (portable-safe)
201
+ // Handle COM1.txt, NUL.txt etc (anything starting with reserved name + optional extension)
202
+ // Trim trailing spaces/dots from baseName to prevent bypass via "CON .txt" or "NUL..txt"
203
+ const upperSegment = normalized.toUpperCase();
204
+ const baseName = upperSegment.split('.')[0].replace(/[ .]+$/, "");
205
+ if (WINDOWS_RESERVED_NAMES.has(baseName)) {
206
+ throw new Error(`${name} contains Windows reserved name: ${segment}`);
207
+ }
208
+ // Reject trailing dots or spaces (Windows path confusion)
209
+ if (normalized.endsWith('.') || normalized.endsWith(' ')) {
210
+ throw new Error(`${name} has trailing dot or space: ${segment}`);
211
+ }
212
+ }
213
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/tools/python-repl/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Session Lock - Cross-platform file-based session locking
3
+ *
4
+ * Provides single-writer enforcement per session with:
5
+ * - PID-reuse safety via process start time verification
6
+ * - Cross-platform support (Linux, macOS)
7
+ * - Stale lock detection and safe breaking
8
+ * - Request queuing with timeout
9
+ */
10
+ import { LockInfo } from './types.js';
11
+ export declare class LockTimeoutError extends Error {
12
+ readonly lockPath: string;
13
+ readonly timeout: number;
14
+ readonly lastHolder?: LockInfo | undefined;
15
+ constructor(lockPath: string, timeout: number, lastHolder?: LockInfo | undefined);
16
+ }
17
+ export declare class LockError extends Error {
18
+ constructor(message: string);
19
+ }
20
+ export interface LockResult {
21
+ acquired: boolean;
22
+ reason?: 'success' | 'held_by_other' | 'stale_broken' | 'error';
23
+ holder?: LockInfo;
24
+ }
25
+ /**
26
+ * Get the start time of the current process.
27
+ * Used when creating lock files to enable PID reuse detection.
28
+ */
29
+ export declare function getCurrentProcessStartTime(): Promise<number | undefined>;
30
+ /**
31
+ * Check if a process is alive with PID-reuse detection via start time comparison.
32
+ *
33
+ * @param pid - Process ID to check
34
+ * @param recordedStartTime - Start time recorded when lock was acquired
35
+ * @returns true if process is alive AND start time matches (or wasn't recorded)
36
+ */
37
+ export declare function isProcessAlive(pid: number, recordedStartTime?: number): Promise<boolean>;
38
+ /**
39
+ * SessionLock manages a single lock file for session coordination.
40
+ *
41
+ * @example
42
+ * const lock = new SessionLock('my-session-id');
43
+ * try {
44
+ * await lock.acquire();
45
+ * // ... do work ...
46
+ * } finally {
47
+ * await lock.release();
48
+ * }
49
+ */
50
+ export declare class SessionLock {
51
+ private lockPath;
52
+ private lockId;
53
+ private held;
54
+ private lockInfo;
55
+ constructor(sessionId: string);
56
+ /**
57
+ * Acquire lock with timeout (default 30s).
58
+ * Blocks until lock is acquired or timeout is reached.
59
+ *
60
+ * @param timeout - Maximum time to wait in milliseconds
61
+ * @throws LockTimeoutError if lock cannot be acquired within timeout
62
+ */
63
+ acquire(timeout?: number): Promise<void>;
64
+ /**
65
+ * Try to acquire lock (non-blocking).
66
+ * Returns immediately with result indicating success or failure.
67
+ */
68
+ tryAcquire(): Promise<LockResult>;
69
+ /**
70
+ * Release held lock.
71
+ * Safe to call multiple times - subsequent calls are no-ops.
72
+ */
73
+ release(): Promise<void>;
74
+ /**
75
+ * Force break a stale lock.
76
+ * USE WITH CAUTION: This will break the lock regardless of who holds it.
77
+ * Should only be used for recovery from known stale states.
78
+ */
79
+ forceBreak(): Promise<void>;
80
+ /**
81
+ * Check if lock is held by us.
82
+ */
83
+ isHeld(): boolean;
84
+ /**
85
+ * Get the lock file path.
86
+ */
87
+ getLockPath(): string;
88
+ /**
89
+ * Get current lock info (if held).
90
+ */
91
+ getLockInfo(): LockInfo | null;
92
+ }
93
+ /**
94
+ * Execute a function while holding a lock, releasing automatically on completion.
95
+ *
96
+ * @example
97
+ * await withLock('session-id', async () => {
98
+ * // ... critical section ...
99
+ * });
100
+ */
101
+ export declare function withLock<T>(sessionId: string, fn: () => Promise<T>, timeout?: number): Promise<T>;
102
+ /**
103
+ * Get the current status of a session lock.
104
+ */
105
+ export declare function getLockStatus(sessionId: string): Promise<{
106
+ locked: boolean;
107
+ lockInfo: LockInfo | null;
108
+ canBreak: boolean;
109
+ ownedByUs: boolean;
110
+ }>;
111
+ //# sourceMappingURL=session-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-lock.d.ts","sourceRoot":"","sources":["../../../src/tools/python-repl/session-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmBtC,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,QAAQ,EAAE,MAAM;aAChB,OAAO,EAAE,MAAM;aACf,UAAU,CAAC,EAAE,QAAQ;gBAFrB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,QAAQ,YAAA;CAWxC;AAED,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAMD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,GAAG,eAAe,GAAG,cAAc,GAAG,OAAO,CAAC;IAChE,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB;AAmED;;;GAGG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW9E;AAMD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA0C9F;AA4HD;;;;;;;;;;;GAWG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAyB;gBAE7B,SAAS,EAAE,MAAM;IAK7B;;;;;;OAMG;IACG,OAAO,CAAC,OAAO,GAAE,MAAmC,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB1E;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC;IA2EvC;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB9B;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAYjC;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,WAAW,IAAI,QAAQ,GAAG,IAAI;CAG/B;AAUD;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,MAAmC,GAC3C,OAAO,CAAC,CAAC,CAAC,CAQZ;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC,CAsBD"}