@ouro.bot/cli 0.1.0-alpha.281 → 0.1.0-alpha.282
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/changelog.json +9 -3
- package/dist/heart/core.js +1 -0
- package/dist/senses/cli.js +6 -0
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.282",
|
|
6
|
+
"changes": [
|
|
7
|
+
"feat(cli): crash-resilient sessions \u2014 saves after each tool result, repairs orphaned tool calls on resume."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.281",
|
|
6
12
|
"changes": [
|
|
7
|
-
"feat(bundle): new `src/heart/bundle-state.ts` module exports `detectBundleState(agentRoot)` which returns a structured `BundleStateIssue[]` describing git-level problems the agent can remediate. Enum cases: `not_a_git_repo`, `no_remote_configured`, `first_commit_never_happened`, `pending_sync_exists`. Detection never throws
|
|
8
|
-
"feat(bundle): `StartOfTurnPacket` gains an optional `bundleState?: BundleStateIssue[]` field, populated by the senses pipeline in `handleInboundTurn` at packet assembly time. Renders via a new `case \"bundleState\":` branch in `formatSections` with the `**Bundle:**` prefix, at the same priority tier as the legacy `syncFailure` free-form string (priority 7, truncated last). The two signals coexist during the transition
|
|
13
|
+
"feat(bundle): new `src/heart/bundle-state.ts` module exports `detectBundleState(agentRoot)` which returns a structured `BundleStateIssue[]` describing git-level problems the agent can remediate. Enum cases: `not_a_git_repo`, `no_remote_configured`, `first_commit_never_happened`, `pending_sync_exists`. Detection never throws \u2014 every git call is wrapped in try/catch so a broken bundle degrades to a clear signal rather than crashing the turn pipeline. Also exports `renderBundleStateHint(issues)` which produces first-person remediation guidance (per the memory rule) that tells the agent to call `bundle_check_sync_status` and the `bundle_*` tools shipping in a follow-up PR.",
|
|
14
|
+
"feat(bundle): `StartOfTurnPacket` gains an optional `bundleState?: BundleStateIssue[]` field, populated by the senses pipeline in `handleInboundTurn` at packet assembly time. Renders via a new `case \"bundleState\":` branch in `formatSections` with the `**Bundle:**` prefix, at the same priority tier as the legacy `syncFailure` free-form string (priority 7, truncated last). The two signals coexist during the transition \u2014 `syncFailure` is still emitted by sync.ts for humans, while `bundleState` is the structured form the agent pattern-matches on. Deferred to follow-up: `pending-sync.json` schema extension with `classification` / `conflictFiles` so sync.ts can distinguish push-rejected from pull-rebase-conflict."
|
|
9
15
|
]
|
|
10
16
|
},
|
|
11
17
|
{
|
|
12
18
|
"version": "0.1.0-alpha.280",
|
|
13
19
|
"changes": [
|
|
14
|
-
"chore(tests): prod-path isolation ratchet + tmpBundle leak guard + no-rm-rf contract. Extends `src/__tests__/heart/daemon/test-isolation.contract.test.ts` with three new rules and adds a runtime leak guard. (1) Three new prod-path block rules mirror the existing ~/AgentBundles check: no test file may construct a write path under `~/.ouro-cli`, `~/.agentsecrets`, or `~/.claude` without mocking fs. Each rule has its own empty-seeded ratchet allowlist (except `.ouro-cli` and `.agentsecrets` which are seeded with the pre-existing offenders that this rule newly catches
|
|
20
|
+
"chore(tests): prod-path isolation ratchet + tmpBundle leak guard + no-rm-rf contract. Extends `src/__tests__/heart/daemon/test-isolation.contract.test.ts` with three new rules and adds a runtime leak guard. (1) Three new prod-path block rules mirror the existing ~/AgentBundles check: no test file may construct a write path under `~/.ouro-cli`, `~/.agentsecrets`, or `~/.claude` without mocking fs. Each rule has its own empty-seeded ratchet allowlist (except `.ouro-cli` and `.agentsecrets` which are seeded with the pre-existing offenders that this rule newly catches \u2014 follow-up PRs can convert those to mocked-fs and ratchet down). The path-scan loop is factored into a shared `runProdPathCheck` helper. (2) New Directive-A contract rule: agent-callable production code under `src/` (excluding `src/__tests__/`) must not call `fs.rmSync(..., { recursive: true })` or shell out to `rm -rf` / `rm -fr` / `rm --recursive --force`. The rule is about making deletion auditable and interruptible: an agent should enumerate the files it wants to delete instead of recursively blasting a directory. Four legitimate infrastructure callsites are on `RM_RECURSIVE_ALLOWLIST` with explicit justifications: specialist-tools.ts (adoption rollback), ouro-version-manager.ts (CLI version pruning), ouro-uti.ts (macOS icon pipeline), cli-defaults.ts (self-setup temp dir). Three files that are themselves the rm-rf enforcement layer (guardrails.ts, shell-sessions.ts, prompt.ts) are in `RM_RULE_ENFORCEMENT_FILES` and skipped by the scan since they contain the literal \"rm -rf\" only as regex patterns or prompt strings designed to BLOCK the call. (3) `createTmpBundle` in `src/__tests__/test-helpers/tmpdir-bundle.ts` now tracks live handles in a module-level `_liveHandles: Set<TmpBundleHandle>`. `cleanup()` removes the handle from the set; a new `__getLiveTmpBundleHandles()` export returns a readonly view. (4) `src/__tests__/nerves/global-capture.ts` adds a global vitest `afterEach` leak guard that iterates `__getLiveTmpBundleHandles` and calls `cleanup()` on any remaining handles, logging a `console.warn` naming the test that leaked them. Runs AFTER the pairing guard from alpha.276 so pairing failures surface first. Both guards co-exist cleanly."
|
|
15
21
|
]
|
|
16
22
|
},
|
|
17
23
|
{
|
package/dist/heart/core.js
CHANGED
|
@@ -911,6 +911,7 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
911
911
|
callbacks.onToolEnd(tc.name, (0, tools_1.buildToolResultSummary)(tc.name, args, toolResult, success), success);
|
|
912
912
|
messages.push({ role: "tool", tool_call_id: tc.id, content: toolResult });
|
|
913
913
|
providerRuntime.appendToolOutput(tc.id, toolResult);
|
|
914
|
+
callbacks.onToolResult?.(messages);
|
|
914
915
|
}
|
|
915
916
|
}
|
|
916
917
|
}
|
package/dist/senses/cli.js
CHANGED
|
@@ -976,6 +976,8 @@ async function main(agentName, options) {
|
|
|
976
976
|
const sessionMessages = existing?.messages && existing.messages.length > 0
|
|
977
977
|
? existing.messages
|
|
978
978
|
: [{ role: "system", content: await (0, prompt_1.buildSystem)("cli", {}, resolvedContext) }];
|
|
979
|
+
// Repair any orphaned tool calls from a crash mid-turn
|
|
980
|
+
(0, core_1.repairOrphanedToolCalls)(sessionMessages);
|
|
979
981
|
// Per-turn pipeline input: CLI capabilities and pending dir
|
|
980
982
|
const cliCapabilities = (0, channel_1.getChannelCapabilities)("cli");
|
|
981
983
|
const currentAgentName = (0, identity_1.getAgentName)();
|
|
@@ -1002,6 +1004,10 @@ async function main(agentName, options) {
|
|
|
1002
1004
|
/* v8 ignore start -- failover-aware callback wrapper: tested via pipeline integration @preserve */
|
|
1003
1005
|
const failoverAwareCallbacks = {
|
|
1004
1006
|
...callbacks,
|
|
1007
|
+
// Save session after each tool result for crash recovery
|
|
1008
|
+
onToolResult: (turnMessages) => {
|
|
1009
|
+
(0, context_1.postTurn)(turnMessages, sessPath, undefined, undefined, sessionState);
|
|
1010
|
+
},
|
|
1005
1011
|
onError: (error, severity) => {
|
|
1006
1012
|
if (severity === "terminal" && failoverState) {
|
|
1007
1013
|
capturedTerminalError = error;
|