Skip to content

Release v0.3 operational memory - #39

Merged
theDakshJaitly merged 9 commits into
mainfrom
codex/0.3-operational-memory
May 14, 2026
Merged

Release v0.3 operational memory#39
theDakshJaitly merged 9 commits into
mainfrom
codex/0.3-operational-memory

Conversation

@theDakshJaitly

Copy link
Copy Markdown
Collaborator

Summary

Prepares the mex v0.3 operational-memory release on top of the stable v0.2 architecture.

This includes:

  • agent-memory setup mode for persistent-agent / homelab / OpenClaw-style workspaces
  • heartbeat checks and mex watch --interval
  • append-only event log with mex log and mex timeline
  • mex doctor, shell completions, and improved check output
  • Ink TUI dashboard shipped through bare mex and mex tui
  • npm release prep for promexeus@0.3.5
  • copy-ready GitHub release notes in RELEASE_NOTES.md

Release Notes

Full release notes are in RELEASE_NOTES.md and cover:

  • agent memory layer
  • heartbeat / scheduled checks
  • TUI dashboard
  • OpenClaw and persistent-agent usage
  • upgrade instructions
  • compatibility and deferred architecture work

Verification

  • npm run typecheck
  • npm test — 138 passing
  • npm run build
  • node dist/cli.js --version0.3.5
  • npm --cache /private/tmp/mex-npm-cache pack --dry-runpromexeus-0.3.5.tgz
  • git diff --check
  • manual TTY smoke for node dist/cli.js tui

Copilot AI review requested due to automatic review settings May 14, 2026 01:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Prepares the promexeus@0.3.5 release that turns mex from a drift-aware scaffold CLI into a small operational-memory layer. It adds an agent-memory setup mode, an Ink-based TUI, heartbeat checks, an append-only event log, a doctor command, shell completions, severity-grouped reporter output, and tunable .mex/config.json for staleness/watch/heartbeat.

Changes:

  • New runtime surface: mex tui, mex heartbeat, mex log, mex timeline, mex doctor, mex completion, mex watch --interval, mex setup --mode agent-memory.
  • New modules src/tui.ts, src/heartbeat.ts, src/events.ts, src/doctor.ts; src/reporter.ts regrouped by severity with remediation hints; config loader extended for watch/heartbeat.
  • Release bookkeeping: version 0.3.3 → 0.3.5, new agent-memory templates, GROW-loop rewording across tool configs, RELEASE_NOTES.md/CHANGELOG, new Ink/React deps and lockfile churn.

Reviewed changes

Copilot reviewed 31 out of 32 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
package.json / package-lock.json Version bump to 0.3.5 and Ink/React dependency additions
CHANGELOG.md / RELEASE_NOTES.md / README.md Release prose for 0.3 operational memory
src/cli.ts Wires up tui, log, timeline, heartbeat, doctor, completion, setup --mode, watch --interval
src/tui.ts New Ink-based dashboard, summary, status panels, log flow
src/heartbeat.ts New heartbeat checker for scaffold staleness and memory cleanup
src/events.ts New JSONL event log + timeline
src/doctor.ts New friendly health summary
src/setup/index.ts, src/setup/prompts.ts Agent-memory setup mode and prompt
src/watch.ts New --interval heartbeat loop alongside hook install
src/reporter.ts Group issues by severity, add remediation hints
src/config.ts, src/types.ts Watch/heartbeat config types + loaders
src/drift/index.ts, src/drift/checkers/staleness.ts last_updated frontmatter staleness signal, symlink-following scaffold scan
templates/* GROW rewording, new agent-memory ROUTER/AGENTS/HEARTBEAT templates
test/*.test.ts Tests for tui, events, heartbeat, staleness frontmatter, and watch/heartbeat config

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread package.json
Comment thread CHANGELOG.md
Comment thread src/doctor.ts Outdated
Comment thread src/config.ts
Comment thread src/watch.ts
Comment thread src/cli.ts
Comment on lines +136 to +198
// ── Agent Memory Events ──
program
.command("log <message>")
.description("Append a decision, note, risk, or todo to the mex event log")
.option("--type <type>", "Event type: decision, note, risk, todo", "note")
.option("--file <path>", "Related file path (repeatable)", (value, prev: string[]) => [...prev, value], [])
.action(async (message, opts) => {
try {
const config = findConfig();
const { runLog } = await import("./events.js");
await runLog(config, message, { kind: opts.type, files: opts.file });
} catch (err) {
console.error((err as Error).message);
process.exit(1);
}
});

program
.command("timeline")
.description("Show recent mex event log entries")
.option("--json", "Output events as JSON")
.option("--since <date>", "Filter from YYYY-MM-DD or relative Nd, e.g. 30d")
.option("--type <type>", "Filter by event type")
.option("--limit <n>", "Maximum number of entries", parsePositiveIntArg)
.action(async (opts) => {
try {
const config = findConfig();
const { runTimeline } = await import("./events.js");
await runTimeline(config, opts);
} catch (err) {
console.error((err as Error).message);
process.exit(1);
}
});

program
.command("heartbeat")
.description("Run lightweight agent-memory health checks once")
.option("--json", "Output heartbeat report as JSON")
.action(async (opts) => {
try {
const config = findConfig();
const { runHeartbeat } = await import("./heartbeat.js");
await runHeartbeat(config, { json: opts.json });
} catch (err) {
console.error((err as Error).message);
process.exit(1);
}
});

program
.command("doctor")
.description("Run a friendly scaffold health diagnostic")
.action(async () => {
try {
const config = findConfig();
const { runDoctor } = await import("./doctor.js");
await runDoctor(config);
} catch (err) {
console.error((err as Error).message);
process.exit(1);
}
});
Comment thread src/config.ts
Comment on lines +163 to +166
function readPositiveNumber(v: unknown): number | undefined {
if (typeof v === "number" && Number.isFinite(v) && v > 0) return v;
return undefined;
}
Comment thread src/heartbeat.ts
Comment on lines +63 to +73
function scaffoldHeartbeatFiles(scaffoldRoot: string): string[] {
const patterns = ["ROUTER.md", "AGENTS.md", "context/*.md", "patterns/*.md"];
return patterns.flatMap((pattern) =>
globSync(pattern, {
cwd: scaffoldRoot,
absolute: true,
follow: true,
nodir: true,
}),
);
}
Comment thread src/heartbeat.ts
Comment on lines +39 to +60
const staleFiles = scaffoldHeartbeatFiles(config.scaffoldRoot)
.map((file) => {
const fm = parseFrontmatter(file);
const days = daysSinceFrontmatterDate(
typeof fm?.last_updated === "string" ? fm.last_updated : undefined,
now,
);
return days !== null && days > staleDays
? { file: relative(config.scaffoldRoot, file), days }
: null;
})
.filter((v): v is { file: string; days: number } => Boolean(v));

const memoryCleanupDue = isMemoryCleanupDue(config.projectRoot, memoryCleanupDays, now);
const oldDailyMemoryFiles = oldMemoryFiles(config.projectRoot, dailyRetentionDays, now);

return {
ok: staleFiles.length === 0 && !memoryCleanupDue && oldDailyMemoryFiles.length === 0,
staleFiles,
memoryCleanupDue,
oldDailyMemoryFiles,
};
Comment thread src/tui.ts Outdated
@theDakshJaitly

Copy link
Copy Markdown
Collaborator Author

Addressed the actionable release-blocking review feedback in 66fe95d:\n\n- reconciled changelog history by renaming the old 0.4.0 entry to 0.3.4\n- made mex doctor report whether .mex/config.json actually exists\n- parsed persisted config once in findConfig\n- changed watch --interval to non-overlapping recursive scheduling with SIGINT/SIGTERM cleanup\n- wrapped TUI event logging failures in a friendly notice\n- removed dynamic computed-key TUI log-field updates\n- fixed TUI pluralization\n- added Commander help-after-error and smoke-tested mex bogus\n- cleaned up reporter indentation and setup-mode branching\n\nLeaving the remaining suggestions open as non-blocking/future-scope: CLI-level option tests, zero-day heartbeat thresholds, symlink realpath de-duping, and an optional heartbeat hint for legacy scaffolds without last_updated.

@theDakshJaitly
theDakshJaitly merged commit 612a4d0 into main May 14, 2026
2 checks passed
theDakshJaitly added a commit that referenced this pull request May 25, 2026
…#47)

Per #43, mex log and mex timeline have direct module tests in
test/events.test.ts but no Commander-level coverage. The risky areas
called out in the Copilot review on #39 (invalid --type, repeated --file
accumulator, --limit parsing through parsePositiveIntArg, parseAsync
wiring) had no regression net.

This PR adds test/cli.test.ts covering:

- parsePositiveIntArg + parseIntArg direct tests for positive / zero /
  negative / non-numeric inputs.
- mex log via parseAsync: default --type=note, repeated --file
  accumulates, --type decision propagates, invalid --type is rejected at
  the handler layer.
- mex timeline via parseAsync: --limit parses as integer, --limit 0 and
  --limit foo throw, --json / --since / --type flags propagate.

Each Commander test rebuilds the command locally rather than importing
program from src/cli.ts (which calls program.parse() at import time).
src/cli.ts exports parsePositiveIntArg and parseIntArg so the parser
helpers can be tested directly.

patterns/cli-option-parsing-tests.md captures the approach per the
AGENTS.md After Every Task rule.

Fixes #43

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Daksh Jaitly <thedakshjaitly@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants