theslopmachine 1.0.2 → 1.0.3
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/assets/agents/developer.md +38 -32
- package/assets/agents/slopmachine-claude.md +36 -25
- package/assets/agents/slopmachine.md +61 -45
- package/assets/claude/agents/developer.md +27 -10
- package/assets/skills/claude-worker-management/SKILL.md +4 -4
- package/assets/skills/developer-session-lifecycle/SKILL.md +13 -3
- package/assets/skills/development-guidance/SKILL.md +24 -5
- package/assets/skills/evaluation-triage/SKILL.md +4 -4
- package/assets/skills/final-evaluation-orchestration/SKILL.md +29 -3
- package/assets/skills/integrated-verification/SKILL.md +24 -23
- package/assets/skills/p8-readiness-reconciliation/SKILL.md +98 -0
- package/assets/skills/planning-gate/SKILL.md +2 -2
- package/assets/skills/planning-guidance/SKILL.md +7 -4
- package/assets/skills/scaffold-guidance/SKILL.md +2 -0
- package/assets/skills/submission-packaging/SKILL.md +30 -3
- package/assets/skills/verification-gates/SKILL.md +11 -7
- package/assets/slopmachine/clarification-faithfulness-review-prompt.md +69 -45
- package/assets/slopmachine/clarifier-agent-prompt.md +46 -40
- package/assets/slopmachine/exact-readme-template.md +38 -11
- package/assets/slopmachine/owner-verification-checklist.md +2 -2
- package/assets/slopmachine/phase-1-design-prompt.md +94 -17
- package/assets/slopmachine/phase-1-design-template.md +124 -21
- package/assets/slopmachine/phase-2-execution-planning-prompt.md +155 -87
- package/assets/slopmachine/phase-2-plan-template.md +169 -81
- package/assets/slopmachine/scaffold-playbooks/selection-matrix.md +8 -1
- package/assets/slopmachine/scaffold-playbooks/tech-frontend-vue.md +2 -0
- package/assets/slopmachine/scaffold-playbooks/type-web-spa.md +1 -0
- package/assets/slopmachine/templates/AGENTS.md +18 -17
- package/assets/slopmachine/templates/CLAUDE.md +18 -17
- package/assets/slopmachine/templates/plan.md +115 -36
- package/package.json +9 -2
- package/src/constants.js +1 -0
- package/src/init.js +8 -0
- package/src/install.js +130 -0
- package/assets/slopmachine/utils/__pycache__/claude_live_hook.cpython-311.pyc +0 -0
- package/assets/slopmachine/utils/__pycache__/cleanup_delivery_artifacts.cpython-311.pyc +0 -0
- package/assets/slopmachine/utils/__pycache__/convert_ai_session.cpython-311.pyc +0 -0
- package/assets/slopmachine/utils/__pycache__/normalize_claude_session.cpython-311.pyc +0 -0
- package/assets/slopmachine/utils/__pycache__/strip_session_parent.cpython-311.pyc +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "theslopmachine",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "SlopMachine installer and project bootstrap CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,7 +17,14 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"bin",
|
|
19
19
|
"src",
|
|
20
|
-
"assets",
|
|
20
|
+
"assets/agents",
|
|
21
|
+
"assets/claude",
|
|
22
|
+
"assets/skills",
|
|
23
|
+
"assets/slopmachine/**/*.md",
|
|
24
|
+
"assets/slopmachine/**/*.js",
|
|
25
|
+
"assets/slopmachine/**/*.mjs",
|
|
26
|
+
"assets/slopmachine/**/*.py",
|
|
27
|
+
"assets/slopmachine/**/*.sh",
|
|
21
28
|
"README.md",
|
|
22
29
|
"RELEASE.md",
|
|
23
30
|
"MANUAL.md"
|
package/src/constants.js
CHANGED
|
@@ -42,6 +42,7 @@ export const REQUIRED_SLOPMACHINE_FILES = [
|
|
|
42
42
|
"frontend-evaluation-prompt.md",
|
|
43
43
|
"test-coverage-prompt.md",
|
|
44
44
|
"clarifier-agent-prompt.md",
|
|
45
|
+
"clarification-faithfulness-review-prompt.md",
|
|
45
46
|
"phase-1-design-prompt.md",
|
|
46
47
|
"phase-1-design-template.md",
|
|
47
48
|
"phase-2-execution-planning-prompt.md",
|
package/src/init.js
CHANGED
|
@@ -134,6 +134,12 @@ const PHASE_LABELS = {
|
|
|
134
134
|
P10: 'P10 Retrospective',
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
function assertSupportedPlatform() {
|
|
138
|
+
if (process.platform === 'win32') {
|
|
139
|
+
throw new Error('Native Windows init is not supported. Run theslopmachine from WSL, Linux, or macOS so tmux, Claude live lanes, RTK hooks, and Unix workflow tooling work reliably.')
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
137
143
|
function getUnixBrCommandCandidates(paths) {
|
|
138
144
|
return [
|
|
139
145
|
path.join(paths.home, '.local', 'bin', 'br'),
|
|
@@ -688,6 +694,8 @@ async function maybeOpenOpencode(targetPath, openAfterInit) {
|
|
|
688
694
|
}
|
|
689
695
|
|
|
690
696
|
export async function runInit(args = []) {
|
|
697
|
+
assertSupportedPlatform()
|
|
698
|
+
|
|
691
699
|
const paths = buildPaths()
|
|
692
700
|
const { openAfterInit, targetInput, adoptExisting, continueFromExisting, requestedStartPhase: rawRequestedStartPhase } = parseInitArgs(args)
|
|
693
701
|
const requestedStartPhase = normalizeRequestedStartPhase(rawRequestedStartPhase)
|
package/src/install.js
CHANGED
|
@@ -44,6 +44,12 @@ function assetsRoot() {
|
|
|
44
44
|
return path.join(PACKAGE_ROOT, 'assets')
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function assertSupportedPlatform() {
|
|
48
|
+
if (process.platform === 'win32') {
|
|
49
|
+
throw new Error('Native Windows setup is not supported. Run theslopmachine from WSL, Linux, or macOS so tmux, Claude live lanes, RTK hooks, and Unix workflow tooling work reliably.')
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
47
53
|
async function listSkillDirs(root) {
|
|
48
54
|
const entries = await fs.readdir(root, { withFileTypes: true })
|
|
49
55
|
return entries
|
|
@@ -147,6 +153,10 @@ function getCommonCommandCandidates(command) {
|
|
|
147
153
|
return getUnixCommonBinDirs().map((dir) => path.join(dir, command))
|
|
148
154
|
}
|
|
149
155
|
|
|
156
|
+
function getRtkCommandCandidates() {
|
|
157
|
+
return getCommonCommandCandidates('rtk')
|
|
158
|
+
}
|
|
159
|
+
|
|
150
160
|
function getWindowsBeadsBinDirs() {
|
|
151
161
|
if (process.platform !== 'win32') {
|
|
152
162
|
return []
|
|
@@ -277,6 +287,34 @@ async function ensureUnixBeadsPath() {
|
|
|
277
287
|
}
|
|
278
288
|
}
|
|
279
289
|
|
|
290
|
+
async function ensureUnixLocalBinPath() {
|
|
291
|
+
if (process.platform === 'win32') {
|
|
292
|
+
return
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const localBin = path.join(getHomeDir(), '.local', 'bin')
|
|
296
|
+
prependToProcessPath(localBin)
|
|
297
|
+
|
|
298
|
+
const shellProfile = process.env.SHELL && path.basename(process.env.SHELL) === 'bash'
|
|
299
|
+
? path.join(getHomeDir(), '.bashrc')
|
|
300
|
+
: path.join(getHomeDir(), '.zshrc')
|
|
301
|
+
const exportLine = 'export PATH="$HOME/.local/bin:$PATH"'
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
const existing = await fs.readFile(shellProfile, 'utf8').catch((error) => {
|
|
305
|
+
if (error && error.code === 'ENOENT') return ''
|
|
306
|
+
throw error
|
|
307
|
+
})
|
|
308
|
+
if (!existing.includes(exportLine)) {
|
|
309
|
+
const prefix = existing.endsWith('\n') || existing.length === 0 ? '' : '\n'
|
|
310
|
+
await fs.appendFile(shellProfile, `${prefix}${exportLine}\n`, 'utf8')
|
|
311
|
+
log(`Added ~/.local/bin to PATH in ${shellProfile}`)
|
|
312
|
+
}
|
|
313
|
+
} catch (error) {
|
|
314
|
+
warn(`Unable to persist ~/.local/bin in shell profile.${error instanceof Error ? ` ${error.message}` : ''}`)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
280
318
|
async function installBeadsOnWindows() {
|
|
281
319
|
const shell = await resolveCommand('pwsh') || await resolveCommand('powershell')
|
|
282
320
|
if (!shell) {
|
|
@@ -393,6 +431,92 @@ async function installBeadsOnUnix() {
|
|
|
393
431
|
return result
|
|
394
432
|
}
|
|
395
433
|
|
|
434
|
+
async function resolveRtkCommand() {
|
|
435
|
+
return resolveCommand('rtk', { additionalCandidates: getRtkCommandCandidates(), preferCandidates: true })
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
async function installRtk() {
|
|
439
|
+
const managers = await detectPackageManagers()
|
|
440
|
+
|
|
441
|
+
if (process.platform === 'darwin' && managers.brew) {
|
|
442
|
+
log('Installing rtk via Homebrew')
|
|
443
|
+
return runCommand('brew', ['install', 'rtk'], { stdio: 'inherit' })
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (process.platform !== 'win32') {
|
|
447
|
+
const shell = await resolveCommand('sh') || await findBashExecutable()
|
|
448
|
+
if (!shell) {
|
|
449
|
+
return { code: 1, stdout: '', stderr: 'sh or bash is required to run the rtk installer' }
|
|
450
|
+
}
|
|
451
|
+
if (!(await commandExists('curl'))) {
|
|
452
|
+
return { code: 1, stdout: '', stderr: 'curl is required to install rtk automatically' }
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
log('Installing rtk with the upstream install script')
|
|
456
|
+
const result = await runCommand(shell, ['-c', 'curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh'], { stdio: 'inherit' })
|
|
457
|
+
await ensureUnixLocalBinPath()
|
|
458
|
+
return result
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return { code: 1, stdout: '', stderr: 'No automated rtk install path for Windows. Install rtk.exe manually and add it to PATH.' }
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
async function ensureRtkInstalled() {
|
|
465
|
+
const existing = await resolveRtkCommand()
|
|
466
|
+
if (existing) {
|
|
467
|
+
const version = await getCommandVersion('rtk')
|
|
468
|
+
log(`rtk detected via ${existing}${version ? `: ${version}` : ''}`)
|
|
469
|
+
return existing
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
warn('rtk is not installed or not available in PATH')
|
|
473
|
+
const shouldInstall = await promptYesNo('Attempt to install rtk automatically?', true)
|
|
474
|
+
if (!shouldInstall) {
|
|
475
|
+
warn('Skipping rtk installation. Install rtk manually if you want token-compressed shell output.')
|
|
476
|
+
return null
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const result = await installRtk()
|
|
480
|
+
if (result.code !== 0) {
|
|
481
|
+
warn(`Automatic rtk installation failed.${result.stderr ? ` ${result.stderr}` : ''}`)
|
|
482
|
+
return null
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const installed = await resolveRtkCommand()
|
|
486
|
+
if (!installed) {
|
|
487
|
+
warn('rtk installation completed, but the `rtk` command is not visible in this shell PATH yet. Open a new terminal or ensure ~/.local/bin is in PATH.')
|
|
488
|
+
return null
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
const version = await getCommandVersion('rtk')
|
|
492
|
+
log(`Installed rtk via ${installed}${version ? `: ${version}` : ''}`)
|
|
493
|
+
return installed
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
async function runRtkInit(command, args, label) {
|
|
497
|
+
const result = await runCommand(command, args, { stdio: 'inherit' })
|
|
498
|
+
if (result.code !== 0) {
|
|
499
|
+
warn(`rtk ${label} initialization failed. Run \`${['rtk', ...args].join(' ')}\` manually after setup.`)
|
|
500
|
+
return false
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
log(`rtk ${label} initialized`)
|
|
504
|
+
return true
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
async function initializeRtk() {
|
|
508
|
+
const command = await ensureRtkInstalled()
|
|
509
|
+
if (!command) {
|
|
510
|
+
return { available: false, claude: false, opencode: false }
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
const nonInteractiveArgs = process.env.SLOPMACHINE_NONINTERACTIVE === '1' ? ['--auto-patch'] : []
|
|
514
|
+
const claude = await runRtkInit(command, ['init', '-g', ...nonInteractiveArgs], 'global Claude/default')
|
|
515
|
+
const opencode = await runRtkInit(command, ['init', '-g', '--opencode', ...nonInteractiveArgs], 'global OpenCode')
|
|
516
|
+
|
|
517
|
+
return { available: true, claude, opencode }
|
|
518
|
+
}
|
|
519
|
+
|
|
396
520
|
function getVersionArgs(command) {
|
|
397
521
|
if (command === 'tmux') {
|
|
398
522
|
return ['-V']
|
|
@@ -1132,6 +1256,8 @@ async function maybeCollectUploadToken() {
|
|
|
1132
1256
|
}
|
|
1133
1257
|
|
|
1134
1258
|
export async function runInstall() {
|
|
1259
|
+
assertSupportedPlatform()
|
|
1260
|
+
|
|
1135
1261
|
const paths = buildPaths()
|
|
1136
1262
|
section('Setup')
|
|
1137
1263
|
log(`Configuring theslopmachine in ${paths.home}`)
|
|
@@ -1151,6 +1277,7 @@ export async function runInstall() {
|
|
|
1151
1277
|
}
|
|
1152
1278
|
await ensureDependency({ name: 'opencode', checkCommand: 'opencode', requiredVersion: OPCODE_VERSION, installable: true })
|
|
1153
1279
|
await ensureDependency({ name: 'beads_rust (br)', checkCommand: 'br', requiredVersion: null, installable: true })
|
|
1280
|
+
const rtkSummary = await initializeRtk()
|
|
1154
1281
|
await checkDocker()
|
|
1155
1282
|
await ensureDependency({ name: 'tmux', checkCommand: 'tmux', requiredVersion: null, installable: process.platform !== 'win32' })
|
|
1156
1283
|
await checkClaudeCli()
|
|
@@ -1195,6 +1322,9 @@ export async function runInstall() {
|
|
|
1195
1322
|
console.log(`- Obsolete assets removed: ${obsoleteAssetRemovals.length}`)
|
|
1196
1323
|
console.log(`- Legacy items removed: ${legacySummary.removed.length}`)
|
|
1197
1324
|
console.log(`- Legacy items preserved: ${legacySummary.kept.length}`)
|
|
1325
|
+
console.log(`- RTK available: ${rtkSummary.available ? 'yes' : 'no'}`)
|
|
1326
|
+
console.log(`- RTK Claude/default hook initialized: ${rtkSummary.claude ? 'yes' : 'no'}`)
|
|
1327
|
+
console.log(`- RTK OpenCode hook initialized: ${rtkSummary.opencode ? 'yes' : 'no'}`)
|
|
1198
1328
|
if (archivedObsoleteItems.archiveRoot) {
|
|
1199
1329
|
console.log(`- Obsolete archive root: ${archivedObsoleteItems.archiveRoot}`)
|
|
1200
1330
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|