oh-my-claude-sisyphus 3.8.16 → 3.9.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/agents/analyst.md +41 -0
- package/agents/architect.md +47 -2
- package/agents/critic.md +42 -0
- package/agents/deep-executor.md +193 -0
- package/agents/planner.md +82 -0
- package/bridge/mcp-server.cjs +181 -181
- package/commands/build-fix.md +3 -3
- package/commands/ralph.md +3 -3
- package/commands/ultraqa.md +4 -4
- package/commands/ultrawork.md +3 -3
- package/dist/__tests__/agent-registry.test.js +1 -1
- package/dist/__tests__/installer.test.js +8 -8
- package/dist/__tests__/installer.test.js.map +1 -1
- package/dist/__tests__/omc-tools-server.test.js +2 -2
- package/dist/__tests__/omc-tools-server.test.js.map +1 -1
- package/dist/__tests__/skills.test.js +5 -4
- package/dist/__tests__/skills.test.js.map +1 -1
- package/dist/agents/deep-executor.d.ts +15 -0
- package/dist/agents/deep-executor.d.ts.map +1 -0
- package/dist/agents/deep-executor.js +47 -0
- package/dist/agents/deep-executor.js.map +1 -0
- package/dist/agents/definitions.d.ts +16 -1
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +26 -1
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +1 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/cli/commands/doctor-conflicts.d.ts +55 -0
- package/dist/cli/commands/doctor-conflicts.d.ts.map +1 -0
- package/dist/cli/commands/doctor-conflicts.js +261 -0
- package/dist/cli/commands/doctor-conflicts.js.map +1 -0
- package/dist/cli/index.js +16 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/features/auto-update.d.ts +12 -0
- package/dist/features/auto-update.d.ts.map +1 -1
- package/dist/features/auto-update.js +4 -1
- package/dist/features/auto-update.js.map +1 -1
- package/dist/features/background-tasks.js +4 -4
- package/dist/features/context-injector/types.d.ts +1 -1
- package/dist/features/context-injector/types.d.ts.map +1 -1
- package/dist/features/task-decomposer/index.js +3 -3
- package/dist/features/task-decomposer/index.js.map +1 -1
- package/dist/features/verification/index.d.ts +3 -3
- package/dist/features/verification/index.js +3 -3
- package/dist/features/verification/index.js.map +1 -1
- package/dist/hooks/__tests__/bridge.test.d.ts +2 -0
- package/dist/hooks/__tests__/bridge.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/bridge.test.js +199 -0
- package/dist/hooks/__tests__/bridge.test.js.map +1 -0
- package/dist/hooks/autopilot/state.js +3 -3
- package/dist/hooks/beads-context/__tests__/index.test.d.ts +2 -0
- package/dist/hooks/beads-context/__tests__/index.test.d.ts.map +1 -0
- package/dist/hooks/beads-context/__tests__/index.test.js +150 -0
- package/dist/hooks/beads-context/__tests__/index.test.js.map +1 -0
- package/dist/hooks/beads-context/constants.d.ts +3 -0
- package/dist/hooks/beads-context/constants.d.ts.map +1 -0
- package/dist/hooks/beads-context/constants.js +35 -0
- package/dist/hooks/beads-context/constants.js.map +1 -0
- package/dist/hooks/beads-context/index.d.ts +21 -0
- package/dist/hooks/beads-context/index.d.ts.map +1 -0
- package/dist/hooks/beads-context/index.js +62 -0
- package/dist/hooks/beads-context/index.js.map +1 -0
- package/dist/hooks/beads-context/types.d.ts +7 -0
- package/dist/hooks/beads-context/types.d.ts.map +1 -0
- package/dist/hooks/beads-context/types.js +2 -0
- package/dist/hooks/beads-context/types.js.map +1 -0
- package/dist/hooks/bridge.d.ts +4 -0
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +76 -23
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/clear-suggestions/constants.d.ts +54 -0
- package/dist/hooks/clear-suggestions/constants.d.ts.map +1 -0
- package/dist/hooks/clear-suggestions/constants.js +102 -0
- package/dist/hooks/clear-suggestions/constants.js.map +1 -0
- package/dist/hooks/clear-suggestions/index.d.ts +61 -0
- package/dist/hooks/clear-suggestions/index.d.ts.map +1 -0
- package/dist/hooks/clear-suggestions/index.js +282 -0
- package/dist/hooks/clear-suggestions/index.js.map +1 -0
- package/dist/hooks/clear-suggestions/triggers.d.ts +65 -0
- package/dist/hooks/clear-suggestions/triggers.d.ts.map +1 -0
- package/dist/hooks/clear-suggestions/triggers.js +222 -0
- package/dist/hooks/clear-suggestions/triggers.js.map +1 -0
- package/dist/hooks/clear-suggestions/types.d.ts +92 -0
- package/dist/hooks/clear-suggestions/types.d.ts.map +1 -0
- package/dist/hooks/clear-suggestions/types.js +9 -0
- package/dist/hooks/clear-suggestions/types.js.map +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/permission-handler/index.d.ts.map +1 -1
- package/dist/hooks/permission-handler/index.js +3 -1
- package/dist/hooks/permission-handler/index.js.map +1 -1
- package/dist/hooks/setup/index.d.ts.map +1 -1
- package/dist/hooks/setup/index.js +12 -5
- package/dist/hooks/setup/index.js.map +1 -1
- package/dist/hooks/subagent-tracker/index.d.ts.map +1 -1
- package/dist/hooks/subagent-tracker/index.js +25 -9
- package/dist/hooks/subagent-tracker/index.js.map +1 -1
- package/dist/hooks/ultraqa/index.js +4 -4
- package/dist/hooks/ultraqa/index.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installer/__tests__/claude-md-merge.test.d.ts +6 -0
- package/dist/installer/__tests__/claude-md-merge.test.d.ts.map +1 -0
- package/dist/installer/__tests__/claude-md-merge.test.js +220 -0
- package/dist/installer/__tests__/claude-md-merge.test.js.map +1 -0
- package/dist/installer/__tests__/safe-installer.test.d.ts +6 -0
- package/dist/installer/__tests__/safe-installer.test.d.ts.map +1 -0
- package/dist/installer/__tests__/safe-installer.test.js +172 -0
- package/dist/installer/__tests__/safe-installer.test.js.map +1 -0
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +3 -1
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +27 -1
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +209 -85
- package/dist/installer/index.js.map +1 -1
- package/dist/mcp/omc-tools-server.d.ts +1 -1
- package/dist/mcp/omc-tools-server.d.ts.map +1 -1
- package/dist/mcp/omc-tools-server.js +3 -3
- package/dist/mcp/omc-tools-server.js.map +1 -1
- package/dist/mcp/standalone-server.js +1 -1
- package/dist/mcp/standalone-server.js.map +1 -1
- package/dist/verification/tier-selector.d.ts +40 -0
- package/dist/verification/tier-selector.d.ts.map +1 -0
- package/dist/verification/tier-selector.js +95 -0
- package/dist/verification/tier-selector.js.map +1 -0
- package/dist/verification/tier-selector.test.d.ts +2 -0
- package/dist/verification/tier-selector.test.d.ts.map +1 -0
- package/dist/verification/tier-selector.test.js +282 -0
- package/dist/verification/tier-selector.test.js.map +1 -0
- package/docs/AGENTS.md +1 -1
- package/docs/CLAUDE.md +90 -378
- package/docs/partials/agent-tiers.md +165 -0
- package/docs/partials/features.md +131 -0
- package/docs/partials/mode-hierarchy.md +120 -0
- package/docs/partials/mode-selection-guide.md +82 -0
- package/docs/partials/verification-tiers.md +107 -0
- package/docs/shared/agent-tiers.md +165 -0
- package/docs/shared/features.md +131 -0
- package/docs/shared/mode-hierarchy.md +120 -0
- package/docs/shared/mode-selection-guide.md +82 -0
- package/docs/shared/verification-tiers.md +107 -0
- package/package.json +4 -3
- package/scripts/compose-docs.mjs +44 -0
- package/scripts/keyword-detector.mjs +13 -3
- package/skills/build-fix/SKILL.md +8 -8
- package/skills/deep-executor/SKILL.md +50 -0
- package/skills/deepinit/SKILL.md +2 -2
- package/skills/ecomode/SKILL.md +58 -103
- package/skills/omc-setup/SKILL.md +197 -20
- package/skills/plan/SKILL.md +62 -0
- package/skills/project-session-manager/SKILL.md +87 -4
- package/skills/project-session-manager/lib/config.sh +54 -5
- package/skills/project-session-manager/lib/parse.sh +65 -11
- package/skills/project-session-manager/lib/providers/github.sh +52 -0
- package/skills/project-session-manager/lib/providers/interface.sh +76 -0
- package/skills/project-session-manager/lib/providers/jira.sh +79 -0
- package/skills/project-session-manager/lib/session.sh +49 -12
- package/skills/project-session-manager/lib/worktree.sh +37 -4
- package/skills/project-session-manager/psm.sh +116 -51
- package/skills/ralph/SKILL.md +44 -30
- package/skills/tdd/SKILL.md +2 -2
- package/skills/ultrapilot/SKILL.md +3 -3
- package/skills/ultraqa/SKILL.md +4 -4
- package/skills/ultrawork/SKILL.md +59 -69
- package/templates/hooks/keyword-detector.mjs +21 -13
- package/templates/hooks/lib/stdin.mjs +62 -0
- package/templates/hooks/persistent-mode.mjs +7 -8
- package/templates/hooks/post-tool-use.mjs +8 -10
- package/templates/hooks/pre-tool-use.mjs +9 -6
- package/templates/hooks/session-start.mjs +7 -8
|
@@ -1,105 +1,95 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ultrawork
|
|
3
|
-
description:
|
|
3
|
+
description: Parallel execution engine for high-throughput task completion
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Ultrawork Skill
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Parallel execution engine. This is a **COMPONENT**, not a standalone persistence mode.
|
|
9
9
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
This skill enhances Claude's capabilities by:
|
|
10
|
+
## What Ultrawork Provides
|
|
13
11
|
|
|
14
12
|
1. **Parallel Execution**: Running multiple agents simultaneously for independent tasks
|
|
15
|
-
2. **
|
|
16
|
-
3. **
|
|
17
|
-
4. **Persistence Enforcement**: Never stopping until all tasks are verified complete
|
|
18
|
-
5. **Smart Model Routing**: Using tiered agents to save tokens
|
|
19
|
-
|
|
20
|
-
## Smart Model Routing (CRITICAL - SAVE TOKENS)
|
|
21
|
-
|
|
22
|
-
**Choose tier based on task complexity: LOW (haiku) → MEDIUM (sonnet) → HIGH (opus)**
|
|
23
|
-
|
|
24
|
-
### Available Agents by Tier
|
|
13
|
+
2. **Background Operations**: Using `run_in_background: true` for long operations
|
|
14
|
+
3. **Smart Model Routing**: Using tiered agents to save tokens
|
|
25
15
|
|
|
26
|
-
|
|
27
|
-
|--------|-------------|-----------------|-------------|
|
|
28
|
-
| **Analysis** | `architect-low` | `architect-medium` | `architect` |
|
|
29
|
-
| **Execution** | `executor-low` | `executor` | `executor-high` |
|
|
30
|
-
| **Search** | `explore` | `explore-medium` | - |
|
|
31
|
-
| **Research** | `researcher-low` | `researcher` | - |
|
|
32
|
-
| **Frontend** | `designer-low` | `designer` | `designer-high` |
|
|
33
|
-
| **Docs** | `writer` | - | - |
|
|
34
|
-
| **Visual** | - | `vision` | - |
|
|
35
|
-
| **Planning** | - | - | `planner`, `critic`, `analyst` |
|
|
36
|
-
| **Testing** | - | `qa-tester` | - |
|
|
37
|
-
| **Security** | `security-reviewer-low` | - | `security-reviewer` |
|
|
38
|
-
| **Build** | `build-fixer-low` | `build-fixer` | - |
|
|
39
|
-
| **TDD** | `tdd-guide-low` | `tdd-guide` | - |
|
|
40
|
-
| **Code Review** | `code-reviewer-low` | - | `code-reviewer` |
|
|
16
|
+
## What Ultrawork Does NOT Provide
|
|
41
17
|
|
|
42
|
-
|
|
18
|
+
- **Persistence**: Use `ralph` for "don't stop until done" behavior
|
|
19
|
+
- **Verification Loop**: Use `ralph` for mandatory architect verification
|
|
20
|
+
- **State Management**: Use `ralph` or `autopilot` for session persistence
|
|
43
21
|
|
|
44
|
-
|
|
45
|
-
|-----------------|------|----------|
|
|
46
|
-
| Simple lookups | LOW | "What does this function return?", "Find where X is defined" |
|
|
47
|
-
| Standard work | MEDIUM | "Add error handling", "Implement this feature" |
|
|
48
|
-
| Complex analysis | HIGH | "Debug this race condition", "Refactor auth module across 5 files" |
|
|
22
|
+
## Usage
|
|
49
23
|
|
|
50
|
-
|
|
24
|
+
Ultrawork is automatically activated by:
|
|
25
|
+
- `ralph` (for persistent parallel work)
|
|
26
|
+
- `autopilot` (for autonomous parallel work)
|
|
27
|
+
- Direct invocation when you want parallel-only execution with manual oversight
|
|
51
28
|
|
|
52
|
-
|
|
29
|
+
## Smart Model Routing
|
|
53
30
|
|
|
31
|
+
**FIRST ACTION:** Before delegating any work, read the agent reference file:
|
|
54
32
|
```
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// Standard implementation → MEDIUM tier
|
|
59
|
-
Task(subagent_type="oh-my-claudecode:executor", model="sonnet", prompt="Add error handling to login")
|
|
60
|
-
|
|
61
|
-
// Complex refactoring → HIGH tier
|
|
62
|
-
Task(subagent_type="oh-my-claudecode:executor-high", model="opus", prompt="Refactor auth module using JWT across 5 files")
|
|
33
|
+
Read file: docs/shared/agent-tiers.md
|
|
34
|
+
```
|
|
35
|
+
This provides the complete agent tier matrix, MCP tool assignments, and selection guidance.
|
|
63
36
|
|
|
64
|
-
|
|
65
|
-
Task(subagent_type="oh-my-claudecode:explore", model="haiku", prompt="Find where UserService is defined")
|
|
37
|
+
**CRITICAL: Always pass `model` parameter explicitly!**
|
|
66
38
|
|
|
67
|
-
|
|
68
|
-
Task(subagent_type="oh-my-claudecode:
|
|
39
|
+
```
|
|
40
|
+
Task(subagent_type="oh-my-claudecode:architect-low", model="haiku", prompt="...")
|
|
41
|
+
Task(subagent_type="oh-my-claudecode:executor", model="sonnet", prompt="...")
|
|
42
|
+
Task(subagent_type="oh-my-claudecode:architect", model="opus", prompt="...")
|
|
69
43
|
```
|
|
70
44
|
|
|
71
45
|
## Background Execution Rules
|
|
72
46
|
|
|
73
47
|
**Run in Background** (set `run_in_background: true`):
|
|
74
|
-
- Package installation
|
|
75
|
-
- Build processes
|
|
76
|
-
- Test suites
|
|
77
|
-
- Docker operations: docker build, docker pull
|
|
48
|
+
- Package installation (npm install, pip install, cargo build, etc.)
|
|
49
|
+
- Build processes (project build command, make, etc.)
|
|
50
|
+
- Test suites (project test command, etc.)
|
|
78
51
|
|
|
79
52
|
**Run Blocking** (foreground):
|
|
80
53
|
- Quick status checks: git status, ls, pwd
|
|
81
54
|
- File reads, edits
|
|
82
55
|
- Simple commands
|
|
83
56
|
|
|
84
|
-
##
|
|
57
|
+
## Relationship to Other Modes
|
|
85
58
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
59
|
+
```
|
|
60
|
+
ralph (persistence wrapper)
|
|
61
|
+
└── includes: ultrawork (this skill)
|
|
62
|
+
└── provides: parallel execution only
|
|
63
|
+
|
|
64
|
+
autopilot (autonomous execution)
|
|
65
|
+
└── includes: ralph
|
|
66
|
+
└── includes: ultrawork (this skill)
|
|
91
67
|
|
|
92
|
-
|
|
68
|
+
ecomode (token efficiency)
|
|
69
|
+
└── modifies: ultrawork's model selection
|
|
70
|
+
```
|
|
93
71
|
|
|
94
|
-
##
|
|
72
|
+
## When to Use Ultrawork Directly
|
|
95
73
|
|
|
96
|
-
|
|
74
|
+
Use ultrawork directly when you want:
|
|
75
|
+
- Parallel execution without persistence guarantees
|
|
76
|
+
- Manual oversight over completion
|
|
77
|
+
- Quick parallel tasks where you'll verify yourself
|
|
97
78
|
|
|
98
|
-
|
|
79
|
+
Use `ralph` instead when you want:
|
|
80
|
+
- Verified completion (architect check)
|
|
81
|
+
- Automatic retry on failure
|
|
82
|
+
- Session persistence for resume
|
|
99
83
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
84
|
+
## Completion Verification (Direct Invocations)
|
|
85
|
+
|
|
86
|
+
When ultrawork is invoked directly (not via ralph), apply lightweight verification before claiming completion:
|
|
87
|
+
|
|
88
|
+
### Quick Verification Checklist
|
|
89
|
+
- [ ] **BUILD:** Project type check/build command passes
|
|
90
|
+
- [ ] **TESTS:** Run affected tests, all pass
|
|
91
|
+
- [ ] **ERRORS:** No new errors introduced
|
|
92
|
+
|
|
93
|
+
This is lighter than ralph's full verification but ensures basic quality for direct ultrawork usage.
|
|
104
94
|
|
|
105
|
-
|
|
95
|
+
For full persistence and comprehensive verification, use `ralph` mode instead.
|
|
@@ -24,8 +24,15 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import { writeFileSync, mkdirSync, existsSync, unlinkSync } from 'fs';
|
|
27
|
-
import { join } from 'path';
|
|
27
|
+
import { join, dirname } from 'path';
|
|
28
28
|
import { homedir } from 'os';
|
|
29
|
+
import { fileURLToPath } from 'url';
|
|
30
|
+
|
|
31
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
32
|
+
const __dirname = dirname(__filename);
|
|
33
|
+
|
|
34
|
+
// Dynamic import for the shared stdin module
|
|
35
|
+
const { readStdin } = await import(join(__dirname, 'lib', 'stdin.mjs'));
|
|
29
36
|
|
|
30
37
|
const ULTRATHINK_MESSAGE = `<think-mode>
|
|
31
38
|
|
|
@@ -44,15 +51,6 @@ Use your extended thinking capabilities to provide the most thorough and well-re
|
|
|
44
51
|
---
|
|
45
52
|
`;
|
|
46
53
|
|
|
47
|
-
// Read all stdin
|
|
48
|
-
async function readStdin() {
|
|
49
|
-
const chunks = [];
|
|
50
|
-
for await (const chunk of process.stdin) {
|
|
51
|
-
chunks.push(chunk);
|
|
52
|
-
}
|
|
53
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
54
|
// Extract prompt from various JSON structures
|
|
57
55
|
function extractPrompt(input) {
|
|
58
56
|
try {
|
|
@@ -73,10 +71,20 @@ function extractPrompt(input) {
|
|
|
73
71
|
}
|
|
74
72
|
}
|
|
75
73
|
|
|
76
|
-
//
|
|
77
|
-
function
|
|
74
|
+
// Sanitize text to prevent false positives from code blocks, XML tags, URLs, and file paths
|
|
75
|
+
function sanitizeForKeywordDetection(text) {
|
|
78
76
|
return text
|
|
77
|
+
// 1. Strip XML-style tag blocks: <tag-name ...>...</tag-name> (multi-line, greedy on tag name)
|
|
78
|
+
.replace(/<(\w[\w-]*)[\s>][\s\S]*?<\/\1>/g, '')
|
|
79
|
+
// 2. Strip self-closing XML tags: <tag-name />, <tag-name attr="val" />
|
|
80
|
+
.replace(/<\w[\w-]*(?:\s[^>]*)?\s*\/>/g, '')
|
|
81
|
+
// 3. Strip URLs: http://... or https://... up to whitespace
|
|
82
|
+
.replace(/https?:\/\/[^\s)>\]]+/g, '')
|
|
83
|
+
// 4. Strip file paths: /foo/bar/baz or foo/bar/baz (using lookbehind to avoid consuming leading char)
|
|
84
|
+
.replace(/(?<=^|[\s"'`(])(?:\/)?(?:[\w.-]+\/)+[\w.-]+/gm, '')
|
|
85
|
+
// 5. Strip markdown code blocks (existing)
|
|
79
86
|
.replace(/```[\s\S]*?```/g, '')
|
|
87
|
+
// 6. Strip inline code (existing)
|
|
80
88
|
.replace(/`[^`]+`/g, '');
|
|
81
89
|
}
|
|
82
90
|
|
|
@@ -225,7 +233,7 @@ async function main() {
|
|
|
225
233
|
return;
|
|
226
234
|
}
|
|
227
235
|
|
|
228
|
-
const cleanPrompt =
|
|
236
|
+
const cleanPrompt = sanitizeForKeywordDetection(prompt).toLowerCase();
|
|
229
237
|
|
|
230
238
|
// Collect all matching keywords
|
|
231
239
|
const matches = [];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared stdin utilities for OMC hooks
|
|
3
|
+
* Provides timeout-protected stdin reading to prevent hangs on Linux
|
|
4
|
+
* See: https://github.com/Yeachan-Heo/oh-my-claudecode/issues/240
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Read all stdin with timeout to prevent indefinite hang on Linux.
|
|
9
|
+
*
|
|
10
|
+
* The blocking `for await (const chunk of process.stdin)` pattern waits
|
|
11
|
+
* indefinitely for EOF. On Linux, if the parent process doesn't properly
|
|
12
|
+
* close stdin, this hangs forever. This function uses event-based reading
|
|
13
|
+
* with a timeout as a safety net.
|
|
14
|
+
*
|
|
15
|
+
* @param {number} timeoutMs - Maximum time to wait for stdin (default: 5000ms)
|
|
16
|
+
* @returns {Promise<string>} - The stdin content, or empty string on error/timeout
|
|
17
|
+
*/
|
|
18
|
+
export async function readStdin(timeoutMs = 5000) {
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
const chunks = [];
|
|
21
|
+
let settled = false;
|
|
22
|
+
|
|
23
|
+
const timeout = setTimeout(() => {
|
|
24
|
+
if (!settled) {
|
|
25
|
+
settled = true;
|
|
26
|
+
process.stdin.removeAllListeners();
|
|
27
|
+
process.stdin.destroy();
|
|
28
|
+
resolve(Buffer.concat(chunks).toString('utf-8'));
|
|
29
|
+
}
|
|
30
|
+
}, timeoutMs);
|
|
31
|
+
|
|
32
|
+
process.stdin.on('data', (chunk) => {
|
|
33
|
+
chunks.push(chunk);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
process.stdin.on('end', () => {
|
|
37
|
+
if (!settled) {
|
|
38
|
+
settled = true;
|
|
39
|
+
clearTimeout(timeout);
|
|
40
|
+
resolve(Buffer.concat(chunks).toString('utf-8'));
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
process.stdin.on('error', () => {
|
|
45
|
+
if (!settled) {
|
|
46
|
+
settled = true;
|
|
47
|
+
clearTimeout(timeout);
|
|
48
|
+
resolve('');
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// If stdin is already ended (e.g. empty pipe), 'end' fires immediately
|
|
53
|
+
// But if stdin is a TTY or never piped, we need the timeout as safety net
|
|
54
|
+
if (process.stdin.readableEnded) {
|
|
55
|
+
if (!settled) {
|
|
56
|
+
settled = true;
|
|
57
|
+
clearTimeout(timeout);
|
|
58
|
+
resolve(Buffer.concat(chunks).toString('utf-8'));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -9,16 +9,15 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { existsSync, readFileSync, writeFileSync, readdirSync, mkdirSync } from 'fs';
|
|
12
|
-
import { join } from 'path';
|
|
12
|
+
import { join, dirname } from 'path';
|
|
13
13
|
import { homedir } from 'os';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
21
|
-
}
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = dirname(__filename);
|
|
18
|
+
|
|
19
|
+
// Dynamic import for the shared stdin module
|
|
20
|
+
const { readStdin } = await import(join(__dirname, 'lib', 'stdin.mjs'));
|
|
22
21
|
|
|
23
22
|
function readJsonFile(path) {
|
|
24
23
|
try {
|
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
// Saves to .omc/notepad.md for compaction-resilient memory
|
|
5
5
|
|
|
6
6
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
|
|
13
|
+
// Dynamic import for the shared stdin module
|
|
14
|
+
const { readStdin } = await import(join(__dirname, 'lib', 'stdin.mjs'));
|
|
8
15
|
|
|
9
16
|
// Constants
|
|
10
17
|
const NOTEPAD_TEMPLATE = '# Notepad\n' +
|
|
@@ -16,15 +23,6 @@ const NOTEPAD_TEMPLATE = '# Notepad\n' +
|
|
|
16
23
|
'## MANUAL\n' +
|
|
17
24
|
'<!-- User content. Never auto-pruned. -->\n';
|
|
18
25
|
|
|
19
|
-
// Read all stdin
|
|
20
|
-
async function readStdin() {
|
|
21
|
-
const chunks = [];
|
|
22
|
-
for await (const chunk of process.stdin) {
|
|
23
|
-
chunks.push(chunk);
|
|
24
|
-
}
|
|
25
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
26
|
// Initialize notepad.md if needed
|
|
29
27
|
function initNotepad(directory) {
|
|
30
28
|
const sisyphusDir = join(directory, '.omc');
|
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import * as path from 'path';
|
|
8
|
+
import { dirname } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
|
|
14
|
+
// Dynamic import for the shared stdin module
|
|
15
|
+
const { readStdin } = await import(path.join(__dirname, 'lib', 'stdin.mjs'));
|
|
8
16
|
|
|
9
17
|
// Allowed path patterns (no warning)
|
|
10
18
|
const ALLOWED_PATH_PATTERNS = [
|
|
@@ -70,12 +78,7 @@ This is a soft warning. Operation will proceed.`;
|
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
async function main() {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// Read stdin
|
|
76
|
-
for await (const chunk of process.stdin) {
|
|
77
|
-
input += chunk;
|
|
78
|
-
}
|
|
81
|
+
const input = await readStdin();
|
|
79
82
|
|
|
80
83
|
let data;
|
|
81
84
|
try {
|
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|
// Cross-platform: Windows, macOS, Linux
|
|
5
5
|
|
|
6
6
|
import { existsSync, readFileSync, readdirSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
-
import { join } from 'path';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
8
|
import { homedir } from 'os';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return Buffer.concat(chunks).toString('utf-8');
|
|
16
|
-
}
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
|
|
14
|
+
// Dynamic import for the shared stdin module
|
|
15
|
+
const { readStdin } = await import(join(__dirname, 'lib', 'stdin.mjs'));
|
|
17
16
|
|
|
18
17
|
function readJsonFile(path) {
|
|
19
18
|
try {
|