@klaudworks/rmr 1.0.0 → 1.0.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/dist/index.js CHANGED
@@ -10921,23 +10921,31 @@ class CompletionCommand extends BaseCommand {
10921
10921
  }
10922
10922
 
10923
10923
  // src/lib/run-state.ts
10924
- import { readFile, writeFile } from "node:fs/promises";
10924
+ import { appendFile, readFile, writeFile } from "node:fs/promises";
10925
10925
  import { resolve as resolve3 } from "node:path";
10926
10926
  function pad(input) {
10927
10927
  return String(input).padStart(2, "0");
10928
10928
  }
10929
10929
  function generateRunId(now = new Date) {
10930
- const yyyy = now.getUTCFullYear();
10931
- const mm = pad(now.getUTCMonth() + 1);
10932
- const dd = pad(now.getUTCDate());
10933
- const hh = pad(now.getUTCHours());
10934
- const min = pad(now.getUTCMinutes());
10935
- const sec = pad(now.getUTCSeconds());
10936
- return `${yyyy}${mm}${dd}-${hh}${min}${sec}Z`;
10930
+ const yyyy = now.getFullYear();
10931
+ const mm = pad(now.getMonth() + 1);
10932
+ const dd = pad(now.getDate());
10933
+ const hh = pad(now.getHours());
10934
+ const min = pad(now.getMinutes());
10935
+ const sec = pad(now.getSeconds());
10936
+ return `${yyyy}${mm}${dd}-${hh}${min}${sec}`;
10937
10937
  }
10938
10938
  function runFilePath(config, runId) {
10939
10939
  return resolve3(config.runsDir, `${runId}.json`);
10940
10940
  }
10941
+ function runLogPath(config, runId) {
10942
+ return resolve3(config.runsDir, `${runId}.log`);
10943
+ }
10944
+ async function appendToRunLog(config, runId, content) {
10945
+ const path = runLogPath(config, runId);
10946
+ await appendFile(path, content, "utf8");
10947
+ return path;
10948
+ }
10941
10949
  function createInitialRunState(options) {
10942
10950
  const firstStep = options.workflow.steps[0];
10943
10951
  if (!firstStep) {
@@ -11219,7 +11227,7 @@ var adapters = {
11219
11227
  },
11220
11228
  createStreamParser: createOpenCodeStreamParser,
11221
11229
  resumeTemplate(sessionId) {
11222
- return `opencode run --session ${sessionId}`;
11230
+ return `opencode --session ${sessionId}`;
11223
11231
  }
11224
11232
  },
11225
11233
  codex: {
@@ -11236,7 +11244,7 @@ var adapters = {
11236
11244
  },
11237
11245
  createStreamParser: createCodexStreamParser,
11238
11246
  resumeTemplate(sessionId) {
11239
- return `codex exec resume ${sessionId} "<prompt>"`;
11247
+ return `codex resume ${sessionId}`;
11240
11248
  }
11241
11249
  },
11242
11250
  copilot: {
@@ -11472,6 +11480,19 @@ function applyOutputToContext(context, stepId, values) {
11472
11480
  context[`${stepId}.${key}`] = value;
11473
11481
  }
11474
11482
  }
11483
+ function formatStepLogEntry(params) {
11484
+ const separator = `${"=".repeat(80)}
11485
+ `;
11486
+ const output = params.combinedOutput.length > 0 ? params.combinedOutput.endsWith(`
11487
+ `) ? params.combinedOutput : `${params.combinedOutput}
11488
+ ` : `
11489
+ `;
11490
+ return `${separator}STEP: ${params.stepId} (step ${params.stepNumber}) | Started: ${params.startedAt}
11491
+ ` + `${separator}` + `${output}
11492
+ ` + `${separator}STEP: ${params.stepId} (step ${params.stepNumber}) | Completed: ${params.completedAt} | Status: ${params.status}
11493
+ ` + `${separator}
11494
+ `;
11495
+ }
11475
11496
  async function runWorkflow(config, workflow, runState, options) {
11476
11497
  if (options.overrides?.stepId) {
11477
11498
  runState.current_step = options.overrides.stepId;
@@ -11516,6 +11537,15 @@ Note: ${injectedHint}` : resolvedPrompt;
11516
11537
  runState.last_harness.session_id = result.sessionId;
11517
11538
  }
11518
11539
  if (result.exitCode !== 0) {
11540
+ const completedAt = new Date().toISOString();
11541
+ await appendToRunLog(config, runState.run_id, formatStepLogEntry({
11542
+ stepId: step.id,
11543
+ stepNumber,
11544
+ startedAt: stepStartedAt,
11545
+ completedAt,
11546
+ status: "paused",
11547
+ combinedOutput: result.combinedOutput
11548
+ }));
11519
11549
  await pauseRun(config, runState, harnessExitReason({
11520
11550
  stepId: step.id,
11521
11551
  harness,
@@ -11527,6 +11557,15 @@ Note: ${injectedHint}` : resolvedPrompt;
11527
11557
  return runState;
11528
11558
  }
11529
11559
  if (result.combinedOutput.includes(HUMAN_SENTINEL)) {
11560
+ const completedAt = new Date().toISOString();
11561
+ await appendToRunLog(config, runState.run_id, formatStepLogEntry({
11562
+ stepId: step.id,
11563
+ stepNumber,
11564
+ startedAt: stepStartedAt,
11565
+ completedAt,
11566
+ status: "paused",
11567
+ combinedOutput: result.combinedOutput
11568
+ }));
11530
11569
  await pauseRun(config, runState, `HUMAN_INTERVENTION_REQUIRED at step "${step.id}".`, harness, runState.last_harness.session_id);
11531
11570
  return runState;
11532
11571
  }
@@ -11536,6 +11575,15 @@ Note: ${injectedHint}` : resolvedPrompt;
11536
11575
  validateRequiredOutputKeys(stepOutput, step.requires.outputs);
11537
11576
  } catch (error) {
11538
11577
  const message = error instanceof Error ? error.message : "Failed to parse step output.";
11578
+ const completedAt = new Date().toISOString();
11579
+ await appendToRunLog(config, runState.run_id, formatStepLogEntry({
11580
+ stepId: step.id,
11581
+ stepNumber,
11582
+ startedAt: stepStartedAt,
11583
+ completedAt,
11584
+ status: "paused",
11585
+ combinedOutput: result.combinedOutput
11586
+ }));
11539
11587
  await pauseRun(config, runState, message, harness, runState.last_harness.session_id);
11540
11588
  return runState;
11541
11589
  }
@@ -11543,19 +11591,46 @@ Note: ${injectedHint}` : resolvedPrompt;
11543
11591
  applyOutputToContext(runState.context, step.id, stepOutput.values);
11544
11592
  const nextState = stepOutput.next_state ?? step.next_step;
11545
11593
  if (!isValidTarget(workflow, nextState)) {
11594
+ const completedAt = new Date().toISOString();
11595
+ await appendToRunLog(config, runState.run_id, formatStepLogEntry({
11596
+ stepId: step.id,
11597
+ stepNumber,
11598
+ startedAt: stepStartedAt,
11599
+ completedAt,
11600
+ status: "paused",
11601
+ combinedOutput: result.combinedOutput
11602
+ }));
11546
11603
  await pauseRun(config, runState, `Invalid next_state "${nextState}" at step "${step.id}".`, harness, runState.last_harness.session_id);
11547
11604
  return runState;
11548
11605
  }
11549
11606
  if (nextState === "human_intervention") {
11607
+ const completedAt = new Date().toISOString();
11608
+ await appendToRunLog(config, runState.run_id, formatStepLogEntry({
11609
+ stepId: step.id,
11610
+ stepNumber,
11611
+ startedAt: stepStartedAt,
11612
+ completedAt,
11613
+ status: "paused",
11614
+ combinedOutput: result.combinedOutput
11615
+ }));
11550
11616
  await pauseRun(config, runState, `Step "${step.id}" requested human intervention.`, harness, runState.last_harness.session_id);
11551
11617
  return runState;
11552
11618
  }
11619
+ const stepCompletedAt = new Date().toISOString();
11620
+ await appendToRunLog(config, runState.run_id, formatStepLogEntry({
11621
+ stepId: step.id,
11622
+ stepNumber,
11623
+ startedAt: stepStartedAt,
11624
+ completedAt: stepCompletedAt,
11625
+ status: "success",
11626
+ combinedOutput: result.combinedOutput
11627
+ }));
11553
11628
  const stepExecution = {
11554
11629
  step_number: stepNumber,
11555
11630
  step_id: step.id,
11556
11631
  session_id: runState.last_harness?.session_id ?? null,
11557
11632
  started_at: stepStartedAt,
11558
- completed_at: new Date().toISOString()
11633
+ completed_at: stepCompletedAt
11559
11634
  };
11560
11635
  runState.step_history.push(stepExecution);
11561
11636
  stepNumber++;
@@ -11839,15 +11914,15 @@ class ContinueCommand extends BaseCommand {
11839
11914
  description: "Resume a previously created run by run id.",
11840
11915
  details: "Loads `.rmr/runs/<run-id>.json` and continues orchestration from the stored step unless overridden. If a harness session id exists (or is provided), rmr attempts harness resume first.",
11841
11916
  examples: [
11842
- ["Resume a paused run", "$0 continue 20260316-153210Z"],
11843
- ["Resume from a specific step", "$0 continue 20260316-153210Z --step verify"],
11917
+ ["Resume a paused run", "$0 continue 20260316-153210"],
11918
+ ["Resume from a specific step", "$0 continue 20260316-153210 --step verify"],
11844
11919
  [
11845
11920
  "Resume with a hint",
11846
- '$0 continue 20260316-153210Z --hint "Plan mode only: read and propose changes, do not edit files."'
11921
+ '$0 continue 20260316-153210 --hint "Plan mode only: read and propose changes, do not edit files."'
11847
11922
  ],
11848
11923
  [
11849
11924
  "Force session override",
11850
- "$0 continue 20260316-153210Z --session-id abc123"
11925
+ "$0 continue 20260316-153210 --session-id abc123"
11851
11926
  ]
11852
11927
  ]
11853
11928
  });
@@ -1,14 +1,3 @@
1
- # Feature development workflow for rmr.
2
- # Three steps: plan (research + plan), implement, verify (review).
3
- # The verify step can loop back to implement or escalate to human intervention.
4
- #
5
- # Prompt files are co-located with this workflow in the same folder.
6
- # Template variables reference step outputs: {{step_id.key}}
7
- #
8
- # Routing is controlled by <rmr:next_state> in agent output.
9
- # The planner can reject a task by setting next_state=done.
10
- # The reviewer can request changes by setting next_state=implement.
11
-
12
1
  id: feature-dev
13
2
  name: Feature Development
14
3
  harness: claude
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@klaudworks/rex",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@klaudworks/rex",
9
- "version": "1.0.0",
9
+ "version": "1.0.1",
10
10
  "dependencies": {
11
11
  "clipanion": "^4.0.0-rc.4",
12
12
  "yaml": "^2.8.2"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klaudworks/rmr",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Define multi-step coding workflows for AI agents",
5
5
  "license": "MIT",
6
6
  "repository": {