Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .agents/skills/harness-git-commit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ Deterministic commits via bundled CLI. Config merges **project** `.pi/auto-commi
```bash
node "$UP_PKG/.pi/scripts/harness-auto-commit-bootstrap.mjs"
```
3. Stage files: `git add …` (CLI does not stage).
4. Commit via CLI (examples):
3. When `branch.strategy` is `auto-feature-branch`, ensure working branch before execute:
```bash
node "$UP_PKG/.pi/scripts/harness-git-branch.mjs" \
--run-id "<run_id>" --run-dir "<run_dir>" --project-root "<project_root>"
```
4. Stage files: `git add …` (CLI does not stage).
5. Commit via CLI (examples):
```bash
# Conventional subject from config template
node "$UP_PKG/.pi/scripts/harness-git-commit.mjs" \
Expand All @@ -41,6 +46,10 @@ Deterministic commits via bundled CLI. Config merges **project** `.pi/auto-commi
# Amend: preserve body, ensure trailer
node "$UP_PKG/.pi/scripts/harness-git-commit.mjs" --amend --message "$(git log -1 --format=%B)"

# Scoped commit (ignores other staged paths)
node "$UP_PKG/.pi/scripts/harness-git-commit.mjs" \
--only-path "path/to/file.ts" --type chore --scope harness --subject "scoped change"

# Preview only
node "$UP_PKG/.pi/scripts/harness-git-commit.mjs" --dry-run --subject "preview"
```
Expand All @@ -55,6 +64,8 @@ Deterministic commits via bundled CLI. Config merges **project** `.pi/auto-commi
| `message.coAuthorTrailer` | `Co-authored-by: {login} <{email}>` |
| `coAuthor.login` / `coAuthor.email` | Attribution (project overrides package) |
| `coAuthor.required` | When false, skip trailer (default true) |
| `branch.strategy` | `auto-feature-branch` creates `harness/<run-id>` from protected branches |
| `branch.protected` | Branch globs that trigger auto feature branch (default main/master/release/*) |

Edit project file to change format or co-author for external repos.

Expand Down
2 changes: 2 additions & 0 deletions .pi/agents/harness/running/executor.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Implement the approved plan with surgical diffs and strict scope control. The pa

When spawn context sets `mode: repair`, read `repair_brief_path` (typically `artifacts/repair-brief.yaml`). Fix only what the brief lists — failed acceptance checks, `fix_directives`, and `priority_lake_ids`. Directives prefixed `[sentrux:…]` come from `artifacts/sentrux-repair-plan.yaml` (merged by the parent); treat them as structural fixes before widening scope. Optional context: `artifacts/sentrux-diagnostics.json` for hotspot ordering only — do not re-run Sentrux CLI unless the brief asks. Do **not** widen scope beyond `plan_packet_path`. Set `repair_attempt` in handoff metadata when the schema allows.

**Repro gate:** When `must_pass_before_handoff: true`, run every `repro_commands` entry from the brief (shell-safe commands only) before `submit_executor_handoff`. Record outcomes in `validation_summary`. If a step is non-shell (`repro_skipped`), document why and still run `verification_commands` when listed.

## Process

1. Read the approved `PlanPacket` at `plan_packet_path` from spawn context; extract allowed scope before any mutation. Approval is recorded in `run-context.yaml` (`plan_ready: true`) and subprocess policy bootstrap — not as a field inside `plan-packet.yaml`.
Expand Down
25 changes: 17 additions & 8 deletions .pi/extensions/harness-debate-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,25 @@ function registerHarnessDebateHandler1(pi: ExtensionAPI) {
if (applied.length === 0) return;

const status = await getPlanDebateRoundStatus(rd, lastRound, runId);
const nextBody = [
"**Debate lane auto-applied from subagent output**",
...applied,
"",
status.next_tool
? `**Required next tool (do not stop with prose only):** ${status.next_tool}`
: "Check harness_debate_round_status for this round.",
].join("\n");
if (isHarnessNonInteractive()) {
pi.appendEntry("harness-debate-next-step", {
applied,
status,
recorded_at: new Date().toISOString(),
});
return;
}
pi.sendMessage({
customType: "harness-debate-next-step",
content: [
"**Debate lane auto-applied from subagent output**",
...applied,
"",
status.next_tool
? `**Required next tool (do not stop with prose only):** ${status.next_tool}`
: "Check harness_debate_round_status for this round.",
].join("\n"),
content: nextBody,
display: true,
details: { applied, status },
});
Expand Down
28 changes: 26 additions & 2 deletions .pi/extensions/harness-live-widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import type {
ExtensionContext,
} from "@earendil-works/pi-coding-agent";
import { isHarnessProjectEnabled } from "../lib/harness-project-config.js";
import { evaluateCrossSessionResume } from "../lib/harness-run-context.js";
import {
evaluateCrossSessionResume,
hasConfirmedClearAfterLatestRunContext,
isRunIdTombstonedByConfirmedHarnessClear,
runIdFromCrossSessionResumeCommand,
} from "../lib/harness-run-context.js";
import { buildHarnessProgressStatusLine } from "../lib/harness-subagent-progress.js";
import {
deriveHarnessStatusHint,
Expand Down Expand Up @@ -308,7 +313,7 @@ export default function harnessLiveWidget(pi: ExtensionAPI) {
});

pi.events.on("harness-run-context:updated", () => {
stateStore.setCrossSessionResumeCommand(null);
stateStore.acknowledgeRunContextUpdated();
if (mountCtx) scheduleRefresh(mountCtx);
});

Expand All @@ -327,9 +332,28 @@ export default function harnessLiveWidget(pi: ExtensionAPI) {
: null;
const cmd =
typeof data?.resume_command === "string" ? data.resume_command : null;
if (mountCtx) {
const entries = mountCtx.sessionManager.getEntries();
const runId = runIdFromCrossSessionResumeCommand(cmd);
if (
hasConfirmedClearAfterLatestRunContext(entries) ||
(runId
? isRunIdTombstonedByConfirmedHarnessClear(entries, runId)
: false)
) {
stateStore.clearActiveRunState(entries.length);
scheduleRefresh(mountCtx);
return;
}
}
stateStore.setCrossSessionResumeCommand(cmd);
if (mountCtx) scheduleRefresh(mountCtx);
});
pi.events.on("harness-runs-cleared", () => {
const entryCount = mountCtx?.sessionManager.getEntries().length ?? 0;
stateStore.clearActiveRunState(entryCount);
if (mountCtx) scheduleRefresh(mountCtx);
});

pi.events.on("harness-project-enabled:changed", (payload: unknown) => {
const data =
Expand Down
Loading
Loading