@piagent/platform 1.8.0 → 1.9.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/AGENTS.md +7 -0
- package/CHANGELOG.md +132 -2
- package/README.md +45 -70
- package/README.vi.md +34 -61
- package/architecture/layers.json +16 -3
- package/catalog/capabilities.json +14 -7
- package/catalog/claude-model-additions.json +42 -0
- package/docs/auto-delegation-policy.md +2 -0
- package/docs/command-reference-vietnamese.md +68 -90
- package/docs/context-window-policy.md +5 -5
- package/docs/distribution-standard.md +13 -16
- package/docs/en/architecture.md +9 -1
- package/docs/herdr-workflow.md +2 -3
- package/docs/languages.json +4 -4
- package/docs/managed-local-acceptance.md +403 -0
- package/docs/mcp-and-tools.md +5 -7
- package/docs/memory-policy.md +3 -3
- package/docs/model-options.md +2 -2
- package/docs/oauth-providers.md +1 -1
- package/docs/operator-manual-vietnamese.md +82 -127
- package/docs/package-architecture-notes.md +4 -4
- package/docs/piagent-core-improvement-plan.md +3 -5
- package/docs/piagent-core-plan-checkpoint-2026-09-06.json +2 -13
- package/docs/piagent-runtime-benchmark-execution-plan.md +10 -8
- package/docs/project-adapters.md +3 -3
- package/docs/project-onboarding.md +15 -16
- package/docs/publishing-for-teams.md +3 -1
- package/docs/quality-benchmark.md +2 -0
- package/docs/quickstart-vietnamese.md +23 -24
- package/docs/release-install-policy.md +3 -2
- package/docs/research/harness-next-evidence-review.md +7 -7
- package/docs/runtime-harness-standard.md +2 -0
- package/docs/runtime-policy-design.md +2 -0
- package/docs/runtime-quality-baseline.md +2 -0
- package/docs/subagent-orchestration-capabilities.md +1 -1
- package/docs/subagents-and-multiagent.md +10 -8
- package/docs/task-implementation-contract.md +2 -0
- package/docs/task-lifecycle-vietnamese.md +2 -0
- package/docs/team-onboarding.md +28 -59
- package/docs/usage-observability.md +2 -2
- package/docs/vi/architecture.md +9 -1
- package/docs/workflow-recipes.md +6 -10
- package/docs-site/architecture.html +4 -3
- package/docs-site/assets/docs.css +80 -0
- package/docs-site/benchmark.html +7 -1
- package/docs-site/commands.html +37 -23
- package/docs-site/content/architecture.html +2 -2
- package/docs-site/content/benchmark.html +5 -0
- package/docs-site/content/commands.html +35 -22
- package/docs-site/content/ecosystem.html +144 -0
- package/docs-site/content/en/architecture.html +1 -1
- package/docs-site/content/en/benchmark.html +5 -0
- package/docs-site/content/en/commands.html +30 -13
- package/docs-site/content/en/ecosystem.html +144 -0
- package/docs-site/content/en/index.html +24 -9
- package/docs-site/content/en/quickstart.html +10 -12
- package/docs-site/content/en/security.html +1 -1
- package/docs-site/content/en/team.html +2 -2
- package/docs-site/content/en/whats-new.html +92 -1
- package/docs-site/content/en/workflows.html +29 -31
- package/docs-site/content/index.html +24 -9
- package/docs-site/content/quickstart.html +10 -12
- package/docs-site/content/security.html +2 -2
- package/docs-site/content/team.html +2 -2
- package/docs-site/content/whats-new.html +92 -1
- package/docs-site/content/workflows.html +36 -38
- package/docs-site/context-engine.html +2 -1
- package/docs-site/ecosystem.html +283 -0
- package/docs-site/en/architecture.html +3 -2
- package/docs-site/en/benchmark.html +7 -1
- package/docs-site/en/commands.html +32 -14
- package/docs-site/en/context-engine.html +2 -1
- package/docs-site/en/ecosystem.html +283 -0
- package/docs-site/en/index.html +30 -14
- package/docs-site/en/mcp-approval.html +2 -1
- package/docs-site/en/mcp-auth.html +2 -1
- package/docs-site/en/mcp-servers.html +2 -1
- package/docs-site/en/mcp.html +2 -1
- package/docs-site/en/permissions.html +2 -1
- package/docs-site/en/profiles.html +2 -1
- package/docs-site/en/quickstart.html +17 -18
- package/docs-site/en/runtime.html +2 -1
- package/docs-site/en/scope.html +2 -1
- package/docs-site/en/security.html +6 -5
- package/docs-site/en/team.html +4 -3
- package/docs-site/en/whats-new.html +100 -8
- package/docs-site/en/workflows.html +34 -35
- package/docs-site/index.html +30 -14
- package/docs-site/mcp-approval.html +2 -1
- package/docs-site/mcp-auth.html +2 -1
- package/docs-site/mcp-servers.html +2 -1
- package/docs-site/mcp.html +2 -1
- package/docs-site/permissions.html +2 -1
- package/docs-site/profiles.html +2 -1
- package/docs-site/quickstart.html +17 -18
- package/docs-site/runtime.html +2 -1
- package/docs-site/scope.html +2 -1
- package/docs-site/security.html +7 -6
- package/docs-site/team.html +4 -3
- package/docs-site/whats-new.html +100 -8
- package/docs-site/workflows.html +41 -42
- package/evals/fs5-causal-arm.v1.json +2 -2
- package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +17 -0
- package/evals/private-holdout-v1/public-exposure.v2.json +2 -2
- package/package.json +8 -7
- package/packages/piagent-core/README.md +15 -23
- package/packages/piagent-core/docs/context-efficiency-improvement-plan.md +2 -0
- package/packages/piagent-core/extensions/experiment-loop-policy.ts +75 -0
- package/packages/piagent-core/extensions/local-state-path.js +15 -0
- package/packages/piagent-core/extensions/piagent-guard.ts +108 -960
- package/packages/piagent-core/extensions/policy-core.js +2 -2
- package/packages/piagent-core/extensions/source-checkout-paths.ts +54 -0
- package/packages/piagent-core/managed/broker-client.mjs +49 -0
- package/packages/piagent-core/managed/capabilities.mjs +28 -0
- package/packages/piagent-core/managed/client-agent.mjs +6 -0
- package/packages/piagent-core/managed/compaction.mjs +63 -0
- package/packages/piagent-core/managed/doctor.mjs +107 -0
- package/packages/piagent-core/managed/helper-roles.mjs +57 -0
- package/packages/piagent-core/managed/native-catalog.mjs +42 -0
- package/packages/piagent-core/managed/patch-snapshot.mjs +48 -0
- package/packages/piagent-core/managed/repository-operation.mjs +84 -0
- package/packages/piagent-core/managed/request-stream.mjs +130 -0
- package/packages/piagent-core/managed/resource-loader.mjs +42 -0
- package/packages/piagent-core/managed/review-snapshot-worker.mjs +27 -0
- package/packages/piagent-core/managed/sandbox-diagnostic.mjs +12 -0
- package/packages/piagent-core/managed/search-fallback.mjs +93 -0
- package/packages/piagent-core/managed/session.mjs +493 -0
- package/packages/piagent-core/managed/store.d.mts +3 -0
- package/packages/piagent-core/managed/store.mjs +64 -0
- package/packages/piagent-core/managed/tool-boundary.mjs +275 -0
- package/packages/piagent-core/managed/tool-worker.mjs +36 -0
- package/packages/piagent-core/managed/toolchain.mjs +120 -0
- package/packages/piagent-core/managed/web-fetch.mjs +105 -0
- package/packages/piagent-core/managed/web-search.mjs +131 -0
- package/packages/piagent-core/managed/workflow.mjs +326 -0
- package/packages/piagent-core/package.json +2 -5
- package/packages/piagent-core/policies/base-policy.json +80 -26
- package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +3 -3
- package/packages/piagent-core/runtime/hooks/input-hook.ts +35 -196
- package/packages/piagent-core/runtime/hooks/session-start-hook.ts +2 -0
- package/packages/piagent-core/runtime/inspection/approval-broker.ts +9 -1
- package/packages/piagent-core/runtime/managed-failure.d.mts +10 -0
- package/packages/piagent-core/runtime/managed-failure.mjs +166 -0
- package/packages/piagent-core/runtime/orchestration/minimal-delegation-policy.ts +8 -29
- package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +1 -1
- package/packages/piagent-core/runtime/policy/block-remedy.ts +5 -3
- package/packages/piagent-core/runtime/registration/context-commands.ts +1 -1
- package/packages/piagent-core/runtime/registration/knowledge-tools.ts +7 -7
- package/packages/piagent-core/runtime/registration/policy-tools.ts +2 -2
- package/packages/piagent-core/runtime/registration/session-commands.ts +11 -26
- package/packages/piagent-core/runtime/registration/task-evidence-tools.ts +1 -1
- package/packages/piagent-core/runtime/session/system-prompt.ts +6 -7
- package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +6 -6
- package/packages/piagent-core/runtime/workflows/webui-workflow.ts +6 -11
- package/packages/piagent-core/security/sensitive-text.js +9 -0
- package/packages/piagent-core/skills/piagent-ops/SKILL.md +8 -10
- package/packages/piagent-core/skills/test-audit/SKILL.md +101 -0
- package/packages/piagent-core/subagents/piagent-planner.md +1 -1
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-DMU7Xe_O.js → MarkdownMessage-BRPIMCRh.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/index-DNJ1vH5d.js +228 -0
- package/packages/piagent-webui/dist/client/assets/{index-DVahUVWy.css → index-DgSmcnP8.css} +1 -1
- package/packages/piagent-webui/dist/client/index.html +2 -2
- package/packages/piagent-webui/extension/piagent-webui.ts +11 -11
- package/packages/piagent-webui/extension/session-stream-adapter.ts +3 -1
- package/packages/piagent-webui/extension/terminal-session-adapter.ts +6 -1
- package/packages/piagent-webui/gateway/company-relay.ts +308 -0
- package/packages/piagent-webui/gateway/control-socket.ts +39 -12
- package/packages/piagent-webui/gateway/gateway-service.ts +109 -28
- package/packages/piagent-webui/gateway/gateway-session-stream.ts +58 -2
- package/packages/piagent-webui/gateway/managed-gateway.mjs +41 -0
- package/packages/piagent-webui/gateway/managed-launch.ts +145 -0
- package/packages/piagent-webui/gateway/managed-projection.ts +20 -0
- package/packages/piagent-webui/gateway/pi-host.ts +22 -4
- package/packages/piagent-webui/gateway/runtime-session-controls.ts +5 -2
- package/packages/piagent-webui/gateway/session-approval-authority.ts +28 -0
- package/packages/piagent-webui/gateway/session-catalog.ts +11 -3
- package/packages/piagent-webui/gateway/session-command-controller.ts +8 -2
- package/packages/piagent-webui/gateway/session-file-facts.ts +25 -0
- package/packages/piagent-webui/gateway/session-inspection-registry.ts +40 -9
- package/packages/piagent-webui/gateway/session-list-cache.ts +68 -0
- package/packages/piagent-webui/gateway/session-runtime-ownership.ts +8 -1
- package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +20 -27
- package/packages/piagent-webui/ownership/managed-terminal-lease.ts +27 -0
- package/packages/piagent-webui/ownership/profile-state.ts +2 -0
- package/packages/piagent-webui/ownership/session-lease-store.ts +22 -1
- package/packages/piagent-webui/server/approval-projection.ts +9 -0
- package/packages/piagent-webui/server/core-inspection-provider.ts +4 -9
- package/packages/piagent-webui/server/loopback-server.ts +37 -1
- package/packages/piagent-webui/server/message-stop-reason.ts +11 -0
- package/packages/piagent-webui/server/tool-call-summary.ts +185 -0
- package/packages/piagent-webui/server/transcript-projection.ts +86 -3
- package/packs/engineering-base/pack.json +4 -0
- package/schemas/piagent-webui/runtime-command-v1.schema.json +1 -2
- package/schemas/piagent-webui/session-catalog-v1.schema.json +8 -0
- package/schemas/piagent-webui/transcript-v1.schema.json +94 -1
- package/scripts/build-docs-site.mjs +23 -12
- package/scripts/check-public-wording.mjs +5 -6
- package/scripts/check-runtime-advisories.mjs +23 -6
- package/scripts/claude-model-additions.mjs +33 -0
- package/scripts/configure-model-scope.sh +30 -6
- package/scripts/configure-subagents.sh +1 -1
- package/scripts/explain-command.mjs +5 -6
- package/scripts/init-project.sh +0 -2
- package/scripts/install-global.sh +3 -2
- package/scripts/model-scope-prune.mjs +75 -0
- package/scripts/phase-tools-evaluation.mjs +9 -4
- package/scripts/piagent-cli.mjs +51 -2
- package/scripts/piagent-dashboard.mjs +27 -4
- package/scripts/piagent-installations.mjs +26 -0
- package/scripts/piagent-studio.mjs +155 -0
- package/scripts/runtime-advisory-exceptions.json +29 -0
- package/scripts/setup.sh +10 -6
- package/scripts/team-doctor.sh +20 -1
- package/scripts/typescript-loader.mjs +6 -0
- package/scripts/verify-local.sh +2 -2
- package/templates/global/settings.json +3 -1
- package/templates/project/.pi/project-context.md +3 -3
- package/templates/project/AGENTS.md +4 -5
- package/docs/piagent-core-reasoning-research-2026-09-06.md +0 -225
- package/docs/piagent-core-research-sources-2026-09-06.json +0 -416
- package/packages/piagent-webui/dist/client/assets/index-Cui9AAV_.js +0 -176
|
@@ -7,8 +7,8 @@ Shared Pi package for reusable project workflows.
|
|
|
7
7
|
- `extensions/piagent-guard.ts`: Pi extension composition root and registration order.
|
|
8
8
|
- `runtime/`: Pi-facing session, usage, log-compaction, and workflow input adapters. New command/tool/hook modules belong here.
|
|
9
9
|
- `extensions/*.js|ts`: legacy-location core services for policy, context, task lifecycle, state, and document intake; only `piagent-guard.ts` is loaded as an extension.
|
|
10
|
-
- `prompts/*.md`: workflow
|
|
11
|
-
- `skills/piagent-ops/SKILL.md`: operator-invoked reference for
|
|
10
|
+
- `prompts/*.md`: historical workflow prompt templates; Pi no longer loads them (retired in 1.9.0).
|
|
11
|
+
- `skills/piagent-ops/SKILL.md`: operator-invoked reference for permission, risk, and blocked-call controls; ordinary work does not load it.
|
|
12
12
|
- `skills/piagent-source-cache/`: local cache for user-provided external source repositories.
|
|
13
13
|
- `subagents/*.md`: piagent roles for `pi-subagents`.
|
|
14
14
|
- `benchmark/benchmark-core.js`: deterministic suite validation, evidence scoring, and paired usage comparison for `piagent-benchmark`; `benchmark-report.js` renders the human/HTML reports.
|
|
@@ -76,13 +76,11 @@ Legacy aliases still work: `/permission-status`, `/read-only`, `/workspace-write
|
|
|
76
76
|
- `piagent_exec_policy_check`
|
|
77
77
|
- `piagent_context_budget`
|
|
78
78
|
- `piagent_tool_policy_check`
|
|
79
|
-
- `piagent_task_gate_check`
|
|
80
79
|
- `piagent_usage_snapshot`
|
|
81
80
|
- `piagent_context_preflight`
|
|
82
81
|
- `piagent_memory_status`
|
|
83
82
|
- `piagent_memory_note`
|
|
84
83
|
- `piagent_memory_search`
|
|
85
|
-
- `piagent_memory_citation_record`
|
|
86
84
|
- `piagent_context_index_status`
|
|
87
85
|
- `piagent_context_index_record`
|
|
88
86
|
- `piagent_context_index_search`
|
|
@@ -92,40 +90,34 @@ Legacy aliases still work: `/permission-status`, `/read-only`, `/workspace-write
|
|
|
92
90
|
- `piagent_profile_tech_apply`
|
|
93
91
|
- `piagent_profile_tech_context_record`
|
|
94
92
|
- `piagent_project_onboarding_record`
|
|
95
|
-
- `piagent_task_start`
|
|
96
|
-
- `piagent_task_progress`
|
|
97
93
|
- `piagent_source_checkout`
|
|
98
94
|
- `piagent_document_read` — reads `.md`/`.txt`/`.csv`/`.json`/`.yaml`/`.pdf`/`.docx` from the project or a granted `additionalReadRoots` directory; read-only, and `protectedPaths` still wins
|
|
99
|
-
- `
|
|
100
|
-
- `piagent_verify_record` — records verify evidence only after matching an observed bash tool result after task start
|
|
101
|
-
- `piagent_trace_record`
|
|
95
|
+
- `piagent_wait`
|
|
102
96
|
|
|
103
|
-
These tools are registered capabilities, not a per-task call sequence.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
`
|
|
107
|
-
|
|
108
|
-
|
|
97
|
+
These tools are registered capabilities, not a per-task call sequence. Since
|
|
98
|
+
1.9.0 a turn is freeform: no task contract is created and the task, trace,
|
|
99
|
+
verify, gate and memory-citation tools (`piagent_task_start`, `piagent_task_progress`,
|
|
100
|
+
`piagent_task_gate_check`, `piagent_context_record`, `piagent_verify_record`,
|
|
101
|
+
`piagent_trace_record`, `piagent_memory_citation_record`) are no longer published. Diagnostic groups load only
|
|
102
|
+
when requested.
|
|
109
103
|
|
|
110
|
-
## Runtime commands
|
|
104
|
+
## Runtime commands
|
|
105
|
+
|
|
106
|
+
Work is requested in plain language. The commands below run without a model turn.
|
|
111
107
|
|
|
112
|
-
- `/commands`: runtime menu/help for terminal, Pi, MCP, model, memory, session, context, permission, and subagent commands.
|
|
113
|
-
- `/workflow`: one launcher for task, scout, BE-to-FE, discuss, plan, review, commit, PR, platform-improve, and onboarding workflows.
|
|
114
108
|
- `/usage`: runtime usage namespace for live snapshot, history hint, preflight, compact, compact-log captures, and context efficiency.
|
|
115
109
|
- Pi native `/name`: set the current session name for Agent Watch/report mapping; Piagent observes the native rename event and keeps `/setname` as a compatibility alias.
|
|
116
|
-
- `/fresh`: open a fresh governed session for any canonical `/workflow` option; `/fresh help` lists the current catalog.
|
|
117
110
|
- `/context`: runtime context namespace for index/rebuild/search/pack/test-impact/efficiency, task preflight, and semantic compact.
|
|
118
111
|
- `/permission`: runtime permission namespace for status/read-only/workspace-write/full-access.
|
|
119
|
-
- `/onboard`: runtime onboarding namespace; `run` launches the first-read onboarding workflow.
|
|
120
112
|
- `/context-index`: legacy alias for `/context index/search`.
|
|
121
113
|
- `/profile`: show a short profile status, list options, apply a profile directly, or run select-style profile/tech setup without a model follow-up. Short aliases include `fe`, `be`, `full`, and `be-fe`.
|
|
122
114
|
- `/profile tech`: show/select/apply the project tech stack for the active profile; fullstack setup selects frontend, backend, and database tech.
|
|
123
115
|
- `/memory` or `/memory-policy`: inspect project memory policy and explicit remember workflow.
|
|
124
|
-
- `/model-options`: show model selector, scoped models, thinking levels, and benchmark discipline without a model follow-up.
|
|
125
116
|
- `/logs`: short alias for `/usage logs`.
|
|
126
117
|
- `/task-preflight`: legacy alias for `/context preflight`.
|
|
127
|
-
- `/
|
|
128
|
-
|
|
118
|
+
- `/piagent-status`, `/piagent-inspector`, `/piagent-orchestration`, `/piagent-mcp`, `/fast`: status, session inspector, helper policy, MCP governance and Codex Fast tier.
|
|
119
|
+
|
|
120
|
+
Retired in 1.9.0: `/workflow`, `/fresh` (and `/fresh-*`), `/onboard`, `/commands`, `/model-options` and the prompt-template aliases (`/task`, `/scout`, `/be-to-fe`, `/platform-improve`, `/commit`, `/pr`, `/plan`, `/discuss`, `/review`). Project onboarding is a plain request; the agent records it with `piagent_project_onboarding_record`.
|
|
129
121
|
|
|
130
122
|
## Subagents
|
|
131
123
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Context Efficiency Improvement Plan
|
|
2
2
|
|
|
3
|
+
> **Design record from before 1.9.0.** The task contract, workflow commands (`/workflow`, `/task`, `/fresh`, `/onboard`) and task/trace/verify tools described here were retired on 2026-09-30; sessions are freeform and the guard keeps its path, permission, confirmation, context-budget and stale-edit checks. Kept for reference. Current behavior: [README](../../../README.md).
|
|
4
|
+
|
|
3
5
|
## Status
|
|
4
6
|
|
|
5
7
|
- **Scope:** `packages/piagent-core`
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
// Experiment-loop tools (an optional Pi package may add them): run_experiment
|
|
6
|
+
// runs `bash -c <command>` itself, so the guard checks that command like any
|
|
7
|
+
// shell command (see SHELL_TOOL_NAMES). log_experiment then commits every
|
|
8
|
+
// change when an idea is kept (`git add -A`, `git commit`) and erases every
|
|
9
|
+
// uncommitted change when it is dropped (`git checkout -- .`, `git clean -fd`),
|
|
10
|
+
// outside the guard. The loop is therefore allowed only where those commands
|
|
11
|
+
// cannot destroy the member's work: in the session folder itself, on an
|
|
12
|
+
// `experiment/` branch or in a linked worktree, starting from a tree with
|
|
13
|
+
// nothing uncommitted.
|
|
14
|
+
export const EXPERIMENT_LOOP_TOOLS = new Set(["init_experiment", "run_experiment", "log_experiment"]);
|
|
15
|
+
|
|
16
|
+
// The loop's own files live in `.auto/` and survive a discard, so they may be
|
|
17
|
+
// uncommitted. Files of any other layout count as project files: the safe side.
|
|
18
|
+
const EXPERIMENT_FILES = /^\.auto\//;
|
|
19
|
+
const EXPERIMENT_BRANCH = "experiment/";
|
|
20
|
+
const DEDICATED_TREE = "Run the loop on a branch or worktree of its own, with nothing uncommitted: `git switch -c experiment/<goal>`, "
|
|
21
|
+
+ "or `git worktree add ../<repo>-experiment -b experiment/<goal>` and start Pi in that folder. Your other changes stay untouched.";
|
|
22
|
+
|
|
23
|
+
type Decision = { block: true; reason: string } | undefined;
|
|
24
|
+
|
|
25
|
+
// Trimmed at the end only: `git status --porcelain` lines start with a space.
|
|
26
|
+
function git(cwd: string, args: string[]): string | null {
|
|
27
|
+
try {
|
|
28
|
+
return execFileSync("git", ["-C", cwd, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5_000 }).trimEnd();
|
|
29
|
+
} catch { return null; }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// `workingDir` from the loop's config (`.auto/config.json`), resolved the way
|
|
33
|
+
// the loop resolves it.
|
|
34
|
+
function configuredWorkingDir(cwd: string): string | null {
|
|
35
|
+
const file = path.join(cwd, ".auto", "config.json");
|
|
36
|
+
if (!fs.existsSync(file)) return null;
|
|
37
|
+
try {
|
|
38
|
+
const value = JSON.parse(fs.readFileSync(file, "utf8"))?.workingDir;
|
|
39
|
+
return typeof value === "string" && value.trim() ? path.resolve(cwd, value) : null;
|
|
40
|
+
} catch { return null; }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Files with uncommitted changes, other than the loop's own.
|
|
44
|
+
export function uncommittedProjectFiles(cwd: string): string[] {
|
|
45
|
+
return (git(cwd, ["status", "--porcelain", "--untracked-files=all"]) ?? "").split("\n").filter(Boolean)
|
|
46
|
+
.map((line) => line.slice(3)).filter((file) => !EXPERIMENT_FILES.test(file));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function experimentLoopDecision(cwd: string, toolName: string): Decision {
|
|
50
|
+
if (!EXPERIMENT_LOOP_TOOLS.has(toolName)) return undefined;
|
|
51
|
+
const workingDir = configuredWorkingDir(cwd);
|
|
52
|
+
if (workingDir && path.resolve(workingDir) !== path.resolve(cwd)) {
|
|
53
|
+
return { block: true, reason: `Blocked ${toolName}: the experiment config moves its commands to ${workingDir}. `
|
|
54
|
+
+ "Start Pi in that folder instead, so the guard checks each command where it runs." };
|
|
55
|
+
}
|
|
56
|
+
if (toolName === "run_experiment") return undefined;
|
|
57
|
+
const gitDir = git(cwd, ["rev-parse", "--absolute-git-dir"]);
|
|
58
|
+
if (gitDir === null) {
|
|
59
|
+
return { block: true, reason: `Blocked ${toolName}: the experiment loop commits and reverts with git, and this folder is not a git repository.` };
|
|
60
|
+
}
|
|
61
|
+
const commonDir = git(cwd, ["rev-parse", "--path-format=absolute", "--git-common-dir"]);
|
|
62
|
+
const branch = git(cwd, ["symbolic-ref", "--quiet", "--short", "HEAD"]);
|
|
63
|
+
const linkedWorktree = commonDir !== null && path.resolve(commonDir) !== path.resolve(gitDir);
|
|
64
|
+
if (!linkedWorktree && !branch?.startsWith(EXPERIMENT_BRANCH)) {
|
|
65
|
+
return { block: true, reason: `Blocked ${toolName}: log_experiment commits every change when an idea is kept and erases every uncommitted change when it is discarded, and this is ${branch ? `branch ${branch}` : "a detached checkout"}. ${DEDICATED_TREE}` };
|
|
66
|
+
}
|
|
67
|
+
if (toolName === "init_experiment") {
|
|
68
|
+
const dirty = uncommittedProjectFiles(cwd);
|
|
69
|
+
if (dirty.length > 0) {
|
|
70
|
+
return { block: true, reason: `Blocked init_experiment: ${dirty.length} uncommitted change(s) (${dirty.slice(0, 3).join(", ")}${dirty.length > 3 ? ", …" : ""}) `
|
|
71
|
+
+ "would be erased by the first discarded experiment. Commit or stash them first, then start the loop." };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
@@ -46,9 +46,24 @@ export function resolveLocalStatePath(projectRoot, target, options = {}) {
|
|
|
46
46
|
return path.join(canonicalRoot, ...segments);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
// Runtime state is local evidence, never source. A project that never ran
|
|
50
|
+
// setup has no `.pi/.gitignore`, so `git status` listed the state and
|
|
51
|
+
// `git add -A` swept it into commits. The state root ignores itself instead.
|
|
52
|
+
const STATE_ROOT_IGNORE = "# Piagent runtime state: local only, never committed.\n*\n";
|
|
53
|
+
export function ensureStateRootIgnored(projectRoot) {
|
|
54
|
+
try {
|
|
55
|
+
const root = resolveLocalStatePath(projectRoot, path.join(projectRoot, ".pi", "piagent-state"), { label: "Piagent state root" });
|
|
56
|
+
fs.mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
57
|
+
fs.writeFileSync(path.join(root, ".gitignore"), STATE_ROOT_IGNORE, { flag: "wx", mode: 0o600 });
|
|
58
|
+
} catch {
|
|
59
|
+
// Already present, or the project refuses state (symlinked or read-only); either way nothing to add.
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
49
63
|
export function ensurePrivateStateDirectory(projectRoot, directory, label = "Local state directory") {
|
|
50
64
|
const target = resolveLocalStatePath(projectRoot, directory, { label });
|
|
51
65
|
fs.mkdirSync(target, { recursive: true, mode: 0o700 });
|
|
66
|
+
if (path.relative(path.join(fs.realpathSync.native(path.resolve(projectRoot)), ".pi", "piagent-state"), target).split(path.sep)[0] !== "..") ensureStateRootIgnored(projectRoot);
|
|
52
67
|
const verified = resolveLocalStatePath(projectRoot, directory, { label, kind: "directory" });
|
|
53
68
|
try {
|
|
54
69
|
fs.chmodSync(verified, 0o700);
|