@klaudworks/rmr 1.1.1 → 1.1.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 +8 -0
- package/dist/index.js +222 -6
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
|
|
9
9
|
Inspired by [snarktank/antfarm](https://github.com/snarktank/antfarm).
|
|
10
10
|
|
|
11
|
+
## Why rmr?
|
|
12
|
+
|
|
13
|
+
Coding agents produce slop. Not because they're bad, but because "go make it work" is a bad prompt, the same way it's a bad brief for a human developer. You wouldn't hand someone a one-liner and expect clean, well-structured code back. Yet that's how most people use coding agents today.
|
|
14
|
+
|
|
15
|
+
The fix is simple: break the work into steps. Plan first, then implement, then review. Loop back if the review finds problems. This is how good teams already work. rmr just lets you encode that process in a YAML file and run it automatically.
|
|
16
|
+
|
|
17
|
+
It doesn't care how you plan (markdown files, Beads, Linear, whatever) or which agent you use (Claude Code, Codex, OpenCode). You can mix and match harnesses within a single workflow too, like using Claude for planning and Codex for implementation. It just makes sure each step gets the right context, the output flows to the next step, and you can pause and pick up where you left off.
|
|
18
|
+
|
|
11
19
|
## Quick Start
|
|
12
20
|
|
|
13
21
|
**Instructions for humans**
|
package/dist/index.js
CHANGED
|
@@ -8041,6 +8041,15 @@ var isOptionSymbol = Symbol(`clipanion/isOption`);
|
|
|
8041
8041
|
function makeCommandOption(spec) {
|
|
8042
8042
|
return { ...spec, [isOptionSymbol]: true };
|
|
8043
8043
|
}
|
|
8044
|
+
function rerouteArguments(a, b) {
|
|
8045
|
+
if (typeof a === `undefined`)
|
|
8046
|
+
return [a, b];
|
|
8047
|
+
if (typeof a === `object` && a !== null && !Array.isArray(a)) {
|
|
8048
|
+
return [undefined, a];
|
|
8049
|
+
} else {
|
|
8050
|
+
return [a, b];
|
|
8051
|
+
}
|
|
8052
|
+
}
|
|
8044
8053
|
function cleanValidationError(message, { mergeName = false } = {}) {
|
|
8045
8054
|
const match = message.match(/^([^:]+): (.*)$/m);
|
|
8046
8055
|
if (!match)
|
|
@@ -8060,6 +8069,23 @@ ${errors.map((error) => `
|
|
|
8060
8069
|
- ${cleanValidationError(error)}`).join(``)}`);
|
|
8061
8070
|
}
|
|
8062
8071
|
}
|
|
8072
|
+
function applyValidator(name, value, validator) {
|
|
8073
|
+
if (typeof validator === `undefined`)
|
|
8074
|
+
return value;
|
|
8075
|
+
const errors = [];
|
|
8076
|
+
const coercions = [];
|
|
8077
|
+
const coercion = (v) => {
|
|
8078
|
+
const orig = value;
|
|
8079
|
+
value = v;
|
|
8080
|
+
return coercion.bind(null, orig);
|
|
8081
|
+
};
|
|
8082
|
+
const check = validator(value, { errors, coercions, coercion });
|
|
8083
|
+
if (!check)
|
|
8084
|
+
throw formatError(`Invalid value for ${name}`, errors);
|
|
8085
|
+
for (const [, op] of coercions)
|
|
8086
|
+
op();
|
|
8087
|
+
return value;
|
|
8088
|
+
}
|
|
8063
8089
|
|
|
8064
8090
|
// node_modules/clipanion/lib/advanced/Command.mjs
|
|
8065
8091
|
class Command {
|
|
@@ -9388,19 +9414,208 @@ VersionCommand.paths = [[`-v`], [`--version`]];
|
|
|
9388
9414
|
var exports_options = {};
|
|
9389
9415
|
__export(exports_options, {
|
|
9390
9416
|
rerouteArguments: () => rerouteArguments,
|
|
9391
|
-
makeCommandOption: () =>
|
|
9392
|
-
isOptionSymbol: () =>
|
|
9393
|
-
formatError: () =>
|
|
9394
|
-
cleanValidationError: () =>
|
|
9417
|
+
makeCommandOption: () => makeCommandOption,
|
|
9418
|
+
isOptionSymbol: () => isOptionSymbol,
|
|
9419
|
+
formatError: () => formatError,
|
|
9420
|
+
cleanValidationError: () => cleanValidationError,
|
|
9395
9421
|
applyValidator: () => applyValidator,
|
|
9396
9422
|
String: () => String2,
|
|
9397
9423
|
Rest: () => Rest,
|
|
9398
|
-
Proxy: () =>
|
|
9424
|
+
Proxy: () => Proxy,
|
|
9399
9425
|
Counter: () => Counter,
|
|
9400
9426
|
Boolean: () => Boolean2,
|
|
9401
9427
|
Array: () => Array2
|
|
9402
9428
|
});
|
|
9403
9429
|
|
|
9430
|
+
// node_modules/clipanion/lib/advanced/options/Array.mjs
|
|
9431
|
+
function Array2(descriptor, initialValueBase, optsBase) {
|
|
9432
|
+
const [initialValue, opts] = rerouteArguments(initialValueBase, optsBase !== null && optsBase !== undefined ? optsBase : {});
|
|
9433
|
+
const { arity = 1 } = opts;
|
|
9434
|
+
const optNames = descriptor.split(`,`);
|
|
9435
|
+
const nameSet = new Set(optNames);
|
|
9436
|
+
return makeCommandOption({
|
|
9437
|
+
definition(builder) {
|
|
9438
|
+
builder.addOption({
|
|
9439
|
+
names: optNames,
|
|
9440
|
+
arity,
|
|
9441
|
+
hidden: opts === null || opts === undefined ? undefined : opts.hidden,
|
|
9442
|
+
description: opts === null || opts === undefined ? undefined : opts.description,
|
|
9443
|
+
required: opts.required
|
|
9444
|
+
});
|
|
9445
|
+
},
|
|
9446
|
+
transformer(builder, key, state) {
|
|
9447
|
+
let usedName;
|
|
9448
|
+
let currentValue = typeof initialValue !== `undefined` ? [...initialValue] : undefined;
|
|
9449
|
+
for (const { name, value } of state.options) {
|
|
9450
|
+
if (!nameSet.has(name))
|
|
9451
|
+
continue;
|
|
9452
|
+
usedName = name;
|
|
9453
|
+
currentValue = currentValue !== null && currentValue !== undefined ? currentValue : [];
|
|
9454
|
+
currentValue.push(value);
|
|
9455
|
+
}
|
|
9456
|
+
if (typeof currentValue !== `undefined`) {
|
|
9457
|
+
return applyValidator(usedName !== null && usedName !== undefined ? usedName : key, currentValue, opts.validator);
|
|
9458
|
+
} else {
|
|
9459
|
+
return currentValue;
|
|
9460
|
+
}
|
|
9461
|
+
}
|
|
9462
|
+
});
|
|
9463
|
+
}
|
|
9464
|
+
// node_modules/clipanion/lib/advanced/options/Boolean.mjs
|
|
9465
|
+
function Boolean2(descriptor, initialValueBase, optsBase) {
|
|
9466
|
+
const [initialValue, opts] = rerouteArguments(initialValueBase, optsBase !== null && optsBase !== undefined ? optsBase : {});
|
|
9467
|
+
const optNames = descriptor.split(`,`);
|
|
9468
|
+
const nameSet = new Set(optNames);
|
|
9469
|
+
return makeCommandOption({
|
|
9470
|
+
definition(builder) {
|
|
9471
|
+
builder.addOption({
|
|
9472
|
+
names: optNames,
|
|
9473
|
+
allowBinding: false,
|
|
9474
|
+
arity: 0,
|
|
9475
|
+
hidden: opts.hidden,
|
|
9476
|
+
description: opts.description,
|
|
9477
|
+
required: opts.required
|
|
9478
|
+
});
|
|
9479
|
+
},
|
|
9480
|
+
transformer(builer, key, state) {
|
|
9481
|
+
let currentValue = initialValue;
|
|
9482
|
+
for (const { name, value } of state.options) {
|
|
9483
|
+
if (!nameSet.has(name))
|
|
9484
|
+
continue;
|
|
9485
|
+
currentValue = value;
|
|
9486
|
+
}
|
|
9487
|
+
return currentValue;
|
|
9488
|
+
}
|
|
9489
|
+
});
|
|
9490
|
+
}
|
|
9491
|
+
// node_modules/clipanion/lib/advanced/options/Counter.mjs
|
|
9492
|
+
function Counter(descriptor, initialValueBase, optsBase) {
|
|
9493
|
+
const [initialValue, opts] = rerouteArguments(initialValueBase, optsBase !== null && optsBase !== undefined ? optsBase : {});
|
|
9494
|
+
const optNames = descriptor.split(`,`);
|
|
9495
|
+
const nameSet = new Set(optNames);
|
|
9496
|
+
return makeCommandOption({
|
|
9497
|
+
definition(builder) {
|
|
9498
|
+
builder.addOption({
|
|
9499
|
+
names: optNames,
|
|
9500
|
+
allowBinding: false,
|
|
9501
|
+
arity: 0,
|
|
9502
|
+
hidden: opts.hidden,
|
|
9503
|
+
description: opts.description,
|
|
9504
|
+
required: opts.required
|
|
9505
|
+
});
|
|
9506
|
+
},
|
|
9507
|
+
transformer(builder, key, state) {
|
|
9508
|
+
let currentValue = initialValue;
|
|
9509
|
+
for (const { name, value } of state.options) {
|
|
9510
|
+
if (!nameSet.has(name))
|
|
9511
|
+
continue;
|
|
9512
|
+
currentValue !== null && currentValue !== undefined || (currentValue = 0);
|
|
9513
|
+
if (!value) {
|
|
9514
|
+
currentValue = 0;
|
|
9515
|
+
} else {
|
|
9516
|
+
currentValue += 1;
|
|
9517
|
+
}
|
|
9518
|
+
}
|
|
9519
|
+
return currentValue;
|
|
9520
|
+
}
|
|
9521
|
+
});
|
|
9522
|
+
}
|
|
9523
|
+
// node_modules/clipanion/lib/advanced/options/Rest.mjs
|
|
9524
|
+
function Rest(opts = {}) {
|
|
9525
|
+
return makeCommandOption({
|
|
9526
|
+
definition(builder, key) {
|
|
9527
|
+
var _a;
|
|
9528
|
+
builder.addRest({
|
|
9529
|
+
name: (_a = opts.name) !== null && _a !== undefined ? _a : key,
|
|
9530
|
+
required: opts.required
|
|
9531
|
+
});
|
|
9532
|
+
},
|
|
9533
|
+
transformer(builder, key, state) {
|
|
9534
|
+
const isRestPositional = (index) => {
|
|
9535
|
+
const positional = state.positionals[index];
|
|
9536
|
+
if (positional.extra === NoLimits)
|
|
9537
|
+
return true;
|
|
9538
|
+
if (positional.extra === false && index < builder.arity.leading.length)
|
|
9539
|
+
return true;
|
|
9540
|
+
return false;
|
|
9541
|
+
};
|
|
9542
|
+
let count = 0;
|
|
9543
|
+
while (count < state.positionals.length && isRestPositional(count))
|
|
9544
|
+
count += 1;
|
|
9545
|
+
return state.positionals.splice(0, count).map(({ value }) => value);
|
|
9546
|
+
}
|
|
9547
|
+
});
|
|
9548
|
+
}
|
|
9549
|
+
// node_modules/clipanion/lib/advanced/options/String.mjs
|
|
9550
|
+
function StringOption(descriptor, initialValueBase, optsBase) {
|
|
9551
|
+
const [initialValue, opts] = rerouteArguments(initialValueBase, optsBase !== null && optsBase !== undefined ? optsBase : {});
|
|
9552
|
+
const { arity = 1 } = opts;
|
|
9553
|
+
const optNames = descriptor.split(`,`);
|
|
9554
|
+
const nameSet = new Set(optNames);
|
|
9555
|
+
return makeCommandOption({
|
|
9556
|
+
definition(builder) {
|
|
9557
|
+
builder.addOption({
|
|
9558
|
+
names: optNames,
|
|
9559
|
+
arity: opts.tolerateBoolean ? 0 : arity,
|
|
9560
|
+
hidden: opts.hidden,
|
|
9561
|
+
description: opts.description,
|
|
9562
|
+
required: opts.required
|
|
9563
|
+
});
|
|
9564
|
+
},
|
|
9565
|
+
transformer(builder, key, state, context) {
|
|
9566
|
+
let usedName;
|
|
9567
|
+
let currentValue = initialValue;
|
|
9568
|
+
if (typeof opts.env !== `undefined` && context.env[opts.env]) {
|
|
9569
|
+
usedName = opts.env;
|
|
9570
|
+
currentValue = context.env[opts.env];
|
|
9571
|
+
}
|
|
9572
|
+
for (const { name, value } of state.options) {
|
|
9573
|
+
if (!nameSet.has(name))
|
|
9574
|
+
continue;
|
|
9575
|
+
usedName = name;
|
|
9576
|
+
currentValue = value;
|
|
9577
|
+
}
|
|
9578
|
+
if (typeof currentValue === `string`) {
|
|
9579
|
+
return applyValidator(usedName !== null && usedName !== undefined ? usedName : key, currentValue, opts.validator);
|
|
9580
|
+
} else {
|
|
9581
|
+
return currentValue;
|
|
9582
|
+
}
|
|
9583
|
+
}
|
|
9584
|
+
});
|
|
9585
|
+
}
|
|
9586
|
+
function StringPositional(opts = {}) {
|
|
9587
|
+
const { required = true } = opts;
|
|
9588
|
+
return makeCommandOption({
|
|
9589
|
+
definition(builder, key) {
|
|
9590
|
+
var _a;
|
|
9591
|
+
builder.addPositional({
|
|
9592
|
+
name: (_a = opts.name) !== null && _a !== undefined ? _a : key,
|
|
9593
|
+
required: opts.required
|
|
9594
|
+
});
|
|
9595
|
+
},
|
|
9596
|
+
transformer(builder, key, state) {
|
|
9597
|
+
var _a;
|
|
9598
|
+
for (let i = 0;i < state.positionals.length; ++i) {
|
|
9599
|
+
if (state.positionals[i].extra === NoLimits)
|
|
9600
|
+
continue;
|
|
9601
|
+
if (required && state.positionals[i].extra === true)
|
|
9602
|
+
continue;
|
|
9603
|
+
if (!required && state.positionals[i].extra === false)
|
|
9604
|
+
continue;
|
|
9605
|
+
const [positional] = state.positionals.splice(i, 1);
|
|
9606
|
+
return applyValidator((_a = opts.name) !== null && _a !== undefined ? _a : key, positional.value, opts.validator);
|
|
9607
|
+
}
|
|
9608
|
+
return;
|
|
9609
|
+
}
|
|
9610
|
+
});
|
|
9611
|
+
}
|
|
9612
|
+
function String2(descriptor, ...args) {
|
|
9613
|
+
if (typeof descriptor === `string`) {
|
|
9614
|
+
return StringOption(descriptor, ...args);
|
|
9615
|
+
} else {
|
|
9616
|
+
return StringPositional(descriptor);
|
|
9617
|
+
}
|
|
9618
|
+
}
|
|
9404
9619
|
// src/lib/errors.ts
|
|
9405
9620
|
class RmrError extends Error {
|
|
9406
9621
|
code;
|
|
@@ -11040,7 +11255,8 @@ var adapters = {
|
|
|
11040
11255
|
return { binary: "copilot", args: withModelArgs(options.model, args) };
|
|
11041
11256
|
},
|
|
11042
11257
|
buildResumeCommand(_sessionId, prompt, options) {
|
|
11043
|
-
const
|
|
11258
|
+
const auto = options.allowAll ? ["--allow-all", "--no-ask-user"] : [];
|
|
11259
|
+
const args = [...auto, "-p", prompt];
|
|
11044
11260
|
return { binary: "copilot", args: withModelArgs(options.model, args) };
|
|
11045
11261
|
},
|
|
11046
11262
|
createStreamParser: createPassthroughParser,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@klaudworks/rex",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@klaudworks/rex",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.2",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"clipanion": "^4.0.0-rc.4",
|
|
12
12
|
"yaml": "^2.8.2"
|