openrune 0.2.2 ā 0.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.
- package/bin/rune.js +76 -2
- package/package.json +1 -1
package/bin/rune.js
CHANGED
|
@@ -656,8 +656,9 @@ function openRune(file) {
|
|
|
656
656
|
|
|
657
657
|
function runRune(file, restArgs) {
|
|
658
658
|
if (!file) {
|
|
659
|
-
console.log('Usage: rune run <file.rune> "prompt" [--output json|text]')
|
|
659
|
+
console.log('Usage: rune run <file.rune> "prompt" [--auto] [--output json|text]')
|
|
660
660
|
console.log('Example: rune run reviewer.rune "Review the latest commit"')
|
|
661
|
+
console.log(' rune run coder.rune "Build a REST API server" --auto')
|
|
661
662
|
process.exit(1)
|
|
662
663
|
}
|
|
663
664
|
|
|
@@ -670,10 +671,13 @@ function runRune(file, restArgs) {
|
|
|
670
671
|
// Parse args: prompt and flags
|
|
671
672
|
let prompt = ''
|
|
672
673
|
let outputFormat = 'text'
|
|
674
|
+
let autoMode = false
|
|
673
675
|
for (let i = 0; i < restArgs.length; i++) {
|
|
674
676
|
if (restArgs[i] === '--output' && restArgs[i + 1]) {
|
|
675
677
|
outputFormat = restArgs[i + 1]
|
|
676
678
|
i++
|
|
679
|
+
} else if (restArgs[i] === '--auto') {
|
|
680
|
+
autoMode = true
|
|
677
681
|
} else if (!prompt) {
|
|
678
682
|
prompt = restArgs[i]
|
|
679
683
|
}
|
|
@@ -710,7 +714,76 @@ function runRune(file, restArgs) {
|
|
|
710
714
|
|
|
711
715
|
const systemPrompt = systemParts.join('\n')
|
|
712
716
|
|
|
713
|
-
//
|
|
717
|
+
// Auto mode: agent can read/write files, run commands, fix errors autonomously
|
|
718
|
+
if (autoMode) {
|
|
719
|
+
console.log(`š® [auto] ${rune.name} is working on: ${prompt}\n`)
|
|
720
|
+
|
|
721
|
+
const claudeArgs = ['-p', '--print',
|
|
722
|
+
'--permission-mode', 'auto',
|
|
723
|
+
'--verbose',
|
|
724
|
+
'--output-format', 'stream-json',
|
|
725
|
+
]
|
|
726
|
+
if (systemPrompt) {
|
|
727
|
+
claudeArgs.push('--system-prompt', systemPrompt)
|
|
728
|
+
}
|
|
729
|
+
claudeArgs.push(prompt)
|
|
730
|
+
|
|
731
|
+
const child = spawn('claude', claudeArgs, {
|
|
732
|
+
cwd: folderPath,
|
|
733
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
734
|
+
env: { ...process.env },
|
|
735
|
+
})
|
|
736
|
+
|
|
737
|
+
let fullOutput = ''
|
|
738
|
+
|
|
739
|
+
child.stdout.on('data', (data) => {
|
|
740
|
+
const lines = data.toString().split('\n').filter(Boolean)
|
|
741
|
+
for (const line of lines) {
|
|
742
|
+
try {
|
|
743
|
+
const event = JSON.parse(line)
|
|
744
|
+
|
|
745
|
+
if (event.type === 'assistant' && event.subtype === 'tool_use') {
|
|
746
|
+
const tool = event.tool_name || event.name || 'unknown'
|
|
747
|
+
const input = event.input || {}
|
|
748
|
+
if (tool === 'Bash') {
|
|
749
|
+
console.log(` ā¶ Bash: ${(input.command || '').slice(0, 120)}`)
|
|
750
|
+
} else if (tool === 'Write') {
|
|
751
|
+
console.log(` ā¶ Write: ${input.file_path || ''}`)
|
|
752
|
+
} else if (tool === 'Edit') {
|
|
753
|
+
console.log(` ā¶ Edit: ${input.file_path || ''}`)
|
|
754
|
+
} else if (tool === 'Read') {
|
|
755
|
+
console.log(` ā¶ Read: ${input.file_path || ''}`)
|
|
756
|
+
} else {
|
|
757
|
+
console.log(` ā¶ ${tool}`)
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
if (event.type === 'result') {
|
|
762
|
+
fullOutput = event.result || ''
|
|
763
|
+
console.log(`\n${fullOutput}`)
|
|
764
|
+
}
|
|
765
|
+
} catch {}
|
|
766
|
+
}
|
|
767
|
+
})
|
|
768
|
+
|
|
769
|
+
child.stderr.on('data', (d) => { process.stderr.write(d) })
|
|
770
|
+
|
|
771
|
+
child.on('close', (code) => {
|
|
772
|
+
// Save to history
|
|
773
|
+
rune.history = rune.history || []
|
|
774
|
+
rune.history.push({ role: 'user', text: prompt, ts: Date.now() })
|
|
775
|
+
rune.history.push({ role: 'assistant', text: fullOutput.trim(), ts: Date.now() })
|
|
776
|
+
fs.writeFileSync(filePath, JSON.stringify(rune, null, 2))
|
|
777
|
+
|
|
778
|
+
if (code !== 0) console.error(`\n ā ļø Agent exited with code ${code}`)
|
|
779
|
+
else console.log(`\nā ${rune.name} finished`)
|
|
780
|
+
process.exit(code || 0)
|
|
781
|
+
})
|
|
782
|
+
|
|
783
|
+
return
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// Normal mode: print-only, no tool execution
|
|
714
787
|
const claudeArgs = ['-p', '--print']
|
|
715
788
|
if (systemPrompt) {
|
|
716
789
|
claudeArgs.push('--system-prompt', systemPrompt)
|
|
@@ -1133,6 +1206,7 @@ Usage:
|
|
|
1133
1206
|
--role "description" Set the agent's role
|
|
1134
1207
|
rune open <file.rune> Open a .rune file (desktop GUI)
|
|
1135
1208
|
rune run <file.rune> "prompt" Run agent headlessly (no GUI)
|
|
1209
|
+
--auto Auto mode: agent writes files, runs commands, fixes errors
|
|
1136
1210
|
--output json|text Output format (default: text)
|
|
1137
1211
|
rune pipe <a.rune> <b.rune> ... "prompt" Chain agents in a pipeline
|
|
1138
1212
|
--output json|text Output format (default: text)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openrune",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Rune ā File-based AI Agent Harness for Claude Code",
|
|
5
5
|
"keywords": ["ai", "agent", "claude", "desktop", "electron", "mcp", "claude-code", "harness", "automation"],
|
|
6
6
|
"repository": {
|