pi-crew 0.5.14 → 0.5.16
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.md +117 -0
- package/README.md +1 -1
- package/docs/pi-crew-v0.5.16-audit-fix-plan.md +35 -0
- package/docs/pi-crew-v0.5.17-audit-fix-plan.md +80 -0
- package/docs/skills/REFERENCE.md +11 -0
- package/package.json +1 -1
- package/skills/iterative-audit/SKILL.md +330 -0
- package/src/extension/management.ts +1 -1
- package/src/extension/plan-orchestrate.ts +0 -1
- package/src/extension/register.ts +16 -7
- package/src/extension/registration/viewers.ts +1 -1
- package/src/extension/run-index.ts +1 -1
- package/src/extension/team-tool/explain.ts +0 -1
- package/src/extension/team-tool/handle-schedule.ts +0 -1
- package/src/extension/team-tool/health-monitor.ts +0 -1
- package/src/extension/team-tool/run.ts +2 -2
- package/src/extension/team-tool/status.ts +1 -1
- package/src/extension/team-tool.ts +2 -30
- package/src/observability/exporters/otlp-exporter.ts +11 -1
- package/src/runtime/child-pi.ts +1 -1
- package/src/runtime/crash-recovery.ts +1 -1
- package/src/runtime/crew-agent-records.ts +23 -3
- package/src/runtime/crew-hooks.ts +1 -1
- package/src/runtime/handoff-manager.ts +0 -1
- package/src/runtime/heartbeat-watcher.ts +1 -1
- package/src/runtime/live-session-runtime.ts +0 -1
- package/src/runtime/loop-gates.ts +0 -1
- package/src/runtime/mcp-proxy.ts +2 -2
- package/src/runtime/pipeline-runner.ts +1 -2
- package/src/runtime/task-runner/live-executor.ts +1 -2
- package/src/runtime/task-runner.ts +1 -1
- package/src/state/jsonl-writer.ts +24 -0
- package/src/state/locks.ts +66 -35
- package/src/state/run-metrics.ts +1 -2
- package/src/state/schedule.ts +13 -5
- package/src/state/state-store.ts +1 -1
- package/src/tools/safe-bash.ts +0 -1
- package/src/ui/crew-widget.ts +2 -2
- package/src/ui/render-diff.ts +1 -1
- package/src/ui/run-dashboard.ts +1 -2
- package/src/ui/tool-render.ts +20 -3
- package/src/utils/conflict-detect.ts +0 -1
- package/src/utils/gh-protocol.ts +0 -2
package/src/state/schedule.ts
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* - parseRelativeTime(): "+10m" → ISO timestamp
|
|
8
8
|
* - parseInterval(): "5m" → milliseconds
|
|
9
9
|
*/
|
|
10
|
+
import * as fs from "node:fs";
|
|
11
|
+
import * as path from "node:path";
|
|
12
|
+
import { logInternalError } from "../utils/internal-error.ts";
|
|
10
13
|
|
|
11
14
|
import type { ScheduleStoreData, ScheduledTask } from "./types.ts";
|
|
12
15
|
|
|
@@ -88,8 +91,8 @@ export class ScheduleStore {
|
|
|
88
91
|
this.path = path;
|
|
89
92
|
this.data = { version: 1, jobs: [] };
|
|
90
93
|
try {
|
|
91
|
-
if (
|
|
92
|
-
const content =
|
|
94
|
+
if (fs.existsSync(path)) {
|
|
95
|
+
const content = fs.readFileSync(path, "utf-8");
|
|
93
96
|
const parsed = JSON.parse(content);
|
|
94
97
|
if (parsed && typeof parsed === "object" && "version" in parsed && "jobs" in parsed) {
|
|
95
98
|
this.data = parsed as ScheduleStoreData;
|
|
@@ -102,10 +105,15 @@ export class ScheduleStore {
|
|
|
102
105
|
|
|
103
106
|
private save(): void {
|
|
104
107
|
try {
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
fs.mkdirSync(path.dirname(this.path), { recursive: true });
|
|
109
|
+
fs.writeFileSync(this.path, JSON.stringify(this.data, null, 2), "utf-8");
|
|
107
110
|
} catch (error) {
|
|
108
|
-
|
|
111
|
+
// FIX (Round 21, L1): Use logInternalError for consistency with
|
|
112
|
+
// the rest of the codebase. Previously console.warn may not be
|
|
113
|
+
// visible in all environments (e.g. JSON-RPC mode, redirected
|
|
114
|
+
// stderr). Also import the dependency properly at the top of
|
|
115
|
+
// the file (this method used the legacy require() pattern).
|
|
116
|
+
logInternalError("schedule.save", error, `path=${this.path}`);
|
|
109
117
|
}
|
|
110
118
|
}
|
|
111
119
|
|
package/src/state/state-store.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import type { TeamRunManifest, TeamTaskState } from "./types.ts";
|
|
4
|
-
import { canTransitionRunStatus
|
|
4
|
+
import { canTransitionRunStatus } from "./contracts.ts";
|
|
5
5
|
import { unregisterActiveRun } from "./active-run-registry.ts";
|
|
6
6
|
import { atomicWriteJson, atomicWriteJsonAsync, atomicWriteJsonCoalesced, readJsonFile } from "./atomic-write.ts";
|
|
7
7
|
import { appendEvent } from "./event-log.ts";
|
package/src/tools/safe-bash.ts
CHANGED
package/src/ui/crew-widget.ts
CHANGED
|
@@ -9,8 +9,8 @@ import { getTaskUsage } from "../runtime/usage-tracker.ts";
|
|
|
9
9
|
import type { TeamRunManifest } from "../state/types.ts";
|
|
10
10
|
import type { ManifestCache } from "../runtime/manifest-cache.ts";
|
|
11
11
|
import { reconcileAllStaleRuns } from "../runtime/crash-recovery.ts";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { iconForStatus } from "./status-colors.ts";
|
|
13
|
+
import { truncate } from "../utils/visual.ts";
|
|
14
14
|
import type { CrewTheme } from "./theme-adapter.ts";
|
|
15
15
|
import { asCrewTheme, subscribeThemeChange } from "./theme-adapter.ts";
|
|
16
16
|
import { Box, Text } from "./layout-primitives.ts";
|
package/src/ui/render-diff.ts
CHANGED
|
@@ -18,7 +18,7 @@ function parseDiffLine(line: string): ParsedDiffLine | null {
|
|
|
18
18
|
return { prefix: match[1], lineNum: match[2], content: match[3] };
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
function replaceTabs(text: string): string {
|
|
21
|
+
export function replaceTabs(text: string): string {
|
|
22
22
|
return text.replace(/\t/g, " ");
|
|
23
23
|
}
|
|
24
24
|
|
package/src/ui/run-dashboard.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import type { TeamRunManifest, TeamTaskState, UsageState } from "../state/types.ts";
|
|
3
3
|
import { readCrewAgents } from "../runtime/crew-agent-records.ts";
|
|
4
|
-
import { getLiveAgentContextPercent
|
|
4
|
+
import { getLiveAgentContextPercent } from "../runtime/live-agent-manager.ts";
|
|
5
5
|
import type { CrewAgentRecord } from "../runtime/crew-agent-runtime.ts";
|
|
6
6
|
import { isDisplayActiveRun, isLikelyOrphanedActiveRun } from "../runtime/process-status.ts";
|
|
7
7
|
import { readJsonFileCoalesced } from "../utils/file-coalescer.ts";
|
|
@@ -11,7 +11,6 @@ import { applyStatusColor, iconForStatus, type RunStatus } from "./status-colors
|
|
|
11
11
|
import { pad, truncate, sanitizeLine } from "../utils/visual.ts";
|
|
12
12
|
import { Box, Text } from "./layout-primitives.ts";
|
|
13
13
|
import { DynamicCrewBorder } from "./dynamic-border.ts";
|
|
14
|
-
import { CrewFooter } from "./crew-footer.ts";
|
|
15
14
|
import { aggregateUsage } from "../state/usage.ts";
|
|
16
15
|
import { logInternalError } from "../utils/internal-error.ts";
|
|
17
16
|
import { renderAgentsPane } from "./dashboard-panes/agents-pane.ts";
|
package/src/ui/tool-render.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Container, Spacer, Text, visibleWidth } from "@earendil-works/pi-tui";
|
|
7
7
|
import type { CrewAgentRecord } from "../runtime/crew-agent-runtime.ts";
|
|
8
|
+
import { replaceTabs } from "./render-diff.ts";
|
|
8
9
|
|
|
9
10
|
// ── Types ──────────────────────────────────────────────────────────────
|
|
10
11
|
export interface Theme {
|
|
@@ -185,7 +186,15 @@ export function renderAgentProgress(
|
|
|
185
186
|
}
|
|
186
187
|
|
|
187
188
|
// Error
|
|
188
|
-
|
|
189
|
+
// FIX (Round 20, render-utils sanitization): Sanitize tool-error display so
|
|
190
|
+
// embedded tabs / control chars / newlines / very long strings cannot break
|
|
191
|
+
// the terminal layout. Mirrors the upstream oh-my-pi pattern at
|
|
192
|
+
// packages/coding-agent/src/tools/render-utils.ts:177-185:
|
|
193
|
+
// formatErrorMessage = replaceTabs(truncateToWidth(clean, LINE_CAP))
|
|
194
|
+
if (record.error) {
|
|
195
|
+
const clean = truncLine(replaceTabs(String(record.error)), innerW);
|
|
196
|
+
addLine(theme.fg("error", `Error: ${clean}`));
|
|
197
|
+
}
|
|
189
198
|
|
|
190
199
|
// Usage line
|
|
191
200
|
const usage = record.usage;
|
|
@@ -300,7 +309,12 @@ export function renderAgentToolResult(
|
|
|
300
309
|
const label = item.agentId || "agent";
|
|
301
310
|
c.addChild(new Text(`${icon} ${theme.fg("toolTitle", theme.bold(label))}`, 0, 0));
|
|
302
311
|
if (item.error) {
|
|
303
|
-
|
|
312
|
+
// FIX (Round 20, render-utils sanitization): Sanitize tool-error
|
|
313
|
+
// display so embedded tabs / newlines / very long strings cannot
|
|
314
|
+
// break the TUI border alignment. Mirrors upstream oh-my-pi
|
|
315
|
+
// render-utils.ts:177-185.
|
|
316
|
+
const clean = truncLine(replaceTabs(String(item.error)), w - 2);
|
|
317
|
+
c.addChild(new Text(theme.fg("error", ` Error: ${clean}`), 0, 0));
|
|
304
318
|
} else if (item.output) {
|
|
305
319
|
for (const line of item.output.split("\n").slice(0, 5))
|
|
306
320
|
c.addChild(new Text(theme.fg("dim", ` ${truncLine(line, w - 2)}`), 0, 0));
|
|
@@ -318,7 +332,10 @@ export function renderAgentToolResult(
|
|
|
318
332
|
const label = d.agentId;
|
|
319
333
|
c.addChild(new Text(`${icon} ${theme.fg("toolTitle", theme.bold(label))}`, 0, 0));
|
|
320
334
|
if (d.error) {
|
|
321
|
-
|
|
335
|
+
// FIX (Round 20, render-utils sanitization): Same sanitization as
|
|
336
|
+
// above — see renderAgentToolResult header comment.
|
|
337
|
+
const clean = truncLine(replaceTabs(String(d.error)), w - 2);
|
|
338
|
+
c.addChild(new Text(theme.fg("error", ` Error: ${clean}`), 0, 0));
|
|
322
339
|
} else if (d.output) {
|
|
323
340
|
for (const line of d.output.split("\n").slice(0, 5))
|
|
324
341
|
c.addChild(new Text(theme.fg("dim", ` ${truncLine(line, w - 2)}`), 0, 0));
|
package/src/utils/gh-protocol.ts
CHANGED
|
@@ -22,8 +22,6 @@
|
|
|
22
22
|
* Repo resolution: git remote get-url origin from cwd.
|
|
23
23
|
*/
|
|
24
24
|
import { execFileSync } from "node:child_process";
|
|
25
|
-
import { readFileSync } from "node:fs";
|
|
26
|
-
import * as path from "node:path";
|
|
27
25
|
|
|
28
26
|
/** Resolve the default repo from `git remote get-url origin` in cwd. */
|
|
29
27
|
export function resolveDefaultRepo(cwd: string): string {
|