theslopmachine 0.7.0 → 0.7.2
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/README.md +1 -1
- package/RELEASE.md +2 -2
- package/assets/agents/developer.md +13 -13
- package/assets/agents/slopmachine-claude.md +7 -5
- package/assets/agents/slopmachine.md +6 -5
- package/assets/claude/agents/developer.md +6 -6
- package/assets/skills/clarification-gate/SKILL.md +9 -18
- package/assets/skills/claude-worker-management/SKILL.md +34 -22
- package/assets/skills/developer-session-lifecycle/SKILL.md +2 -1
- package/assets/skills/development-guidance/SKILL.md +3 -0
- package/assets/skills/evaluation-triage/SKILL.md +6 -4
- package/assets/skills/final-evaluation-orchestration/SKILL.md +16 -13
- package/assets/skills/hardening-gate/SKILL.md +3 -0
- package/assets/skills/integrated-verification/SKILL.md +2 -0
- package/assets/skills/planning-guidance/SKILL.md +1 -0
- package/assets/skills/submission-packaging/SKILL.md +6 -4
- package/assets/skills/verification-gates/SKILL.md +7 -2
- package/assets/slopmachine/test-coverage-prompt.md +561 -0
- package/assets/slopmachine/utils/claude_create_session.mjs +2 -2
- package/assets/slopmachine/utils/claude_live_common.mjs +8 -3
- package/assets/slopmachine/utils/claude_live_launch.mjs +9 -3
- package/assets/slopmachine/utils/claude_live_stop.mjs +1 -0
- package/assets/slopmachine/utils/claude_live_turn.mjs +37 -10
- package/assets/slopmachine/utils/claude_resume_session.mjs +2 -2
- package/assets/slopmachine/utils/claude_worker_common.mjs +140 -3
- package/assets/slopmachine/utils/package_claude_session.mjs +35 -8
- package/package.json +1 -1
- package/src/constants.js +2 -2
- package/src/init.js +7 -1
- package/src/install.js +94 -21
package/src/install.js
CHANGED
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
OPCODE_VERSION,
|
|
12
12
|
PACKAGE_ROOT,
|
|
13
13
|
REQUIRED_SKILL_DIRS,
|
|
14
|
-
REQUIRED_SLOPMACHINE_ROOT_FILES,
|
|
15
14
|
REQUIRED_SLOPMACHINE_FILES,
|
|
16
15
|
} from './constants.js'
|
|
17
16
|
import {
|
|
@@ -63,6 +62,41 @@ function getUnixBeadsBinDirs() {
|
|
|
63
62
|
]
|
|
64
63
|
}
|
|
65
64
|
|
|
65
|
+
function getUnixCommonBinDirs() {
|
|
66
|
+
const home = getHomeDir()
|
|
67
|
+
return [
|
|
68
|
+
path.join(home, '.local', 'bin'),
|
|
69
|
+
path.join(home, '.cargo', 'bin'),
|
|
70
|
+
'/opt/homebrew/bin',
|
|
71
|
+
'/usr/local/bin',
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function getWindowsCommonBinDirs() {
|
|
76
|
+
if (process.platform !== 'win32') {
|
|
77
|
+
return []
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const home = getHomeDir()
|
|
81
|
+
return [
|
|
82
|
+
process.env.LOCALAPPDATA ? path.join(process.env.LOCALAPPDATA, 'Programs') : null,
|
|
83
|
+
path.join(home, '.local', 'bin'),
|
|
84
|
+
path.join(home, '.cargo', 'bin'),
|
|
85
|
+
].filter(Boolean)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getCommonCommandCandidates(command) {
|
|
89
|
+
if (process.platform === 'win32') {
|
|
90
|
+
return getWindowsCommonBinDirs().flatMap((dir) => [
|
|
91
|
+
path.join(dir, `${command}.exe`),
|
|
92
|
+
path.join(dir, `${command}.cmd`),
|
|
93
|
+
path.join(dir, command),
|
|
94
|
+
])
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return getUnixCommonBinDirs().map((dir) => path.join(dir, command))
|
|
98
|
+
}
|
|
99
|
+
|
|
66
100
|
function getWindowsBeadsBinDirs() {
|
|
67
101
|
if (process.platform !== 'win32') {
|
|
68
102
|
return []
|
|
@@ -309,14 +343,57 @@ async function installBeadsOnUnix() {
|
|
|
309
343
|
return result
|
|
310
344
|
}
|
|
311
345
|
|
|
346
|
+
function getVersionArgs(command) {
|
|
347
|
+
if (command === 'tmux') {
|
|
348
|
+
return ['-V']
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (command === 'zip') {
|
|
352
|
+
return ['-v']
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return ['--version']
|
|
356
|
+
}
|
|
357
|
+
|
|
312
358
|
async function getCommandVersion(command, args = ['--version']) {
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
359
|
+
const resolved = await resolveCommand(command, {
|
|
360
|
+
additionalCandidates: getCommonCommandCandidates(command),
|
|
361
|
+
preferCandidates: true,
|
|
362
|
+
})
|
|
363
|
+
if (!resolved) return null
|
|
364
|
+
const versionArgs = args.length === 1 && args[0] === '--version' ? getVersionArgs(command) : args
|
|
365
|
+
const result = await runCommand(resolved, versionArgs)
|
|
316
366
|
if (result.code !== 0) return null
|
|
317
367
|
return (result.stdout || result.stderr).trim()
|
|
318
368
|
}
|
|
319
369
|
|
|
370
|
+
function extractSemver(value) {
|
|
371
|
+
const match = String(value || '').match(/\d+\.\d+\.\d+/)
|
|
372
|
+
return match ? match[0] : null
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function compareSemver(left, right) {
|
|
376
|
+
const leftParts = left.split('.').map((part) => Number.parseInt(part, 10))
|
|
377
|
+
const rightParts = right.split('.').map((part) => Number.parseInt(part, 10))
|
|
378
|
+
const length = Math.max(leftParts.length, rightParts.length)
|
|
379
|
+
for (let index = 0; index < length; index += 1) {
|
|
380
|
+
const a = leftParts[index] || 0
|
|
381
|
+
const b = rightParts[index] || 0
|
|
382
|
+
if (a > b) return 1
|
|
383
|
+
if (a < b) return -1
|
|
384
|
+
}
|
|
385
|
+
return 0
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function isVersionAtLeast(currentVersion, minimumVersion) {
|
|
389
|
+
const current = extractSemver(currentVersion)
|
|
390
|
+
const minimum = extractSemver(minimumVersion)
|
|
391
|
+
if (!current || !minimum) {
|
|
392
|
+
return false
|
|
393
|
+
}
|
|
394
|
+
return compareSemver(current, minimum) >= 0
|
|
395
|
+
}
|
|
396
|
+
|
|
320
397
|
async function getPythonVersion() {
|
|
321
398
|
const python3Version = await getCommandVersion('python3')
|
|
322
399
|
if (python3Version) {
|
|
@@ -430,19 +507,27 @@ async function tryInstallCoreDependency(name) {
|
|
|
430
507
|
async function ensureLatestOpencode(requiredVersion) {
|
|
431
508
|
const npmVersion = await getGlobalNpmPackageVersion('opencode-ai')
|
|
432
509
|
const commandPath = await resolveCommand('opencode')
|
|
510
|
+
const commandVersion = await getCommandVersion('opencode')
|
|
433
511
|
|
|
434
512
|
if (npmVersion) {
|
|
435
513
|
log(`opencode detected via global npm package: opencode-ai@${npmVersion}`)
|
|
436
|
-
if (requiredVersion
|
|
437
|
-
|
|
514
|
+
if (!requiredVersion || isVersionAtLeast(npmVersion, requiredVersion)) {
|
|
515
|
+
log(`Using existing opencode-ai@${npmVersion}`)
|
|
516
|
+
return
|
|
438
517
|
}
|
|
439
|
-
|
|
518
|
+
warn(`opencode version ${npmVersion} is below minimum supported version ${requiredVersion}`)
|
|
519
|
+
log('Updating opencode-ai via npm to reach the minimum supported version')
|
|
440
520
|
} else if (commandPath) {
|
|
441
521
|
log(`opencode command detected at ${commandPath}`)
|
|
442
|
-
|
|
522
|
+
if (!requiredVersion || (commandVersion && isVersionAtLeast(commandVersion, requiredVersion))) {
|
|
523
|
+
log(`Using existing opencode command${commandVersion ? `: ${commandVersion}` : ''}`)
|
|
524
|
+
return
|
|
525
|
+
}
|
|
526
|
+
warn(`opencode command version${commandVersion ? ` ${commandVersion}` : ''} is below minimum supported version ${requiredVersion}`)
|
|
527
|
+
log('Installing opencode-ai globally via npm so theslopmachine can manage a supported opencode install')
|
|
443
528
|
} else {
|
|
444
529
|
warn('opencode is not installed or not available in PATH')
|
|
445
|
-
log('Installing opencode-ai
|
|
530
|
+
log('Installing opencode-ai via npm')
|
|
446
531
|
}
|
|
447
532
|
|
|
448
533
|
const result = await tryInstallCoreDependency('opencode')
|
|
@@ -794,18 +879,6 @@ async function installSlopmachineAssets(paths) {
|
|
|
794
879
|
}
|
|
795
880
|
}
|
|
796
881
|
|
|
797
|
-
for (const relativePath of REQUIRED_SLOPMACHINE_ROOT_FILES) {
|
|
798
|
-
const targetPath = path.join(paths.slopmachineDir, relativePath)
|
|
799
|
-
const result = await copyFileReplacing(path.join(PACKAGE_ROOT, relativePath), targetPath)
|
|
800
|
-
if (result.replaced) {
|
|
801
|
-
log(`Refreshed asset: ${relativePath}`)
|
|
802
|
-
summary.refreshed.push(relativePath)
|
|
803
|
-
} else {
|
|
804
|
-
log(`Installed asset: ${relativePath}`)
|
|
805
|
-
summary.installed.push(relativePath)
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
|
|
809
882
|
return summary
|
|
810
883
|
}
|
|
811
884
|
|