@caupulican/pi-adaptative 0.81.41 → 0.81.42
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 +16 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/text.py +5 -1
- package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +3 -3
- package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +8 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +26 -3
- package/dist/bundled-resources/runtimes/pi-shell-engine/expand.py +3 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/main.py +4 -1
- package/dist/bundled-resources/runtimes/pi-shell-engine/state.py +2 -1
- package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +2 -0
- package/dist/core/agent-paths.d.ts +32 -0
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +65 -0
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/agent-session-contracts.d.ts +19 -1
- package/dist/core/agent-session-contracts.d.ts.map +1 -1
- package/dist/core/agent-session-contracts.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +4 -9
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/contracts.d.ts +2 -0
- package/dist/core/autonomy/contracts.d.ts.map +1 -1
- package/dist/core/autonomy/contracts.js.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.d.ts.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.js +4 -9
- package/dist/core/autonomy/envelope-enforcement.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +3 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +17 -4
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/path-scope.d.ts +14 -0
- package/dist/core/autonomy/path-scope.d.ts.map +1 -1
- package/dist/core/autonomy/path-scope.js +37 -6
- package/dist/core/autonomy/path-scope.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +27 -1
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +32 -1
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/delegation/managed-lane-controller.d.ts +11 -1
- package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -1
- package/dist/core/delegation/managed-lane-controller.js +84 -41
- package/dist/core/delegation/managed-lane-controller.js.map +1 -1
- package/dist/core/delegation/session-worker-claim.d.ts.map +1 -1
- package/dist/core/delegation/session-worker-claim.js +4 -3
- package/dist/core/delegation/session-worker-claim.js.map +1 -1
- package/dist/core/delegation/worker-action-journal.d.ts +73 -0
- package/dist/core/delegation/worker-action-journal.d.ts.map +1 -0
- package/dist/core/delegation/worker-action-journal.js +297 -0
- package/dist/core/delegation/worker-action-journal.js.map +1 -0
- package/dist/core/delegation/worker-actions.d.ts +36 -1
- package/dist/core/delegation/worker-actions.d.ts.map +1 -1
- package/dist/core/delegation/worker-actions.js +171 -46
- package/dist/core/delegation/worker-actions.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +75 -0
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-agent-control-coordinator.js +218 -0
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-agent-control.d.ts +66 -0
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -0
- package/dist/core/delegation/worker-agent-control.js +163 -0
- package/dist/core/delegation/worker-agent-control.js.map +1 -0
- package/dist/core/delegation/worker-attempt-executor.d.ts +80 -0
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -0
- package/dist/core/delegation/worker-attempt-executor.js +343 -0
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -0
- package/dist/core/delegation/worker-claim.d.ts +30 -0
- package/dist/core/delegation/worker-claim.d.ts.map +1 -1
- package/dist/core/delegation/worker-claim.js +205 -53
- package/dist/core/delegation/worker-claim.js.map +1 -1
- package/dist/core/delegation/worker-conversation-store.d.ts +116 -0
- package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -0
- package/dist/core/delegation/worker-conversation-store.js +442 -0
- package/dist/core/delegation/worker-conversation-store.js.map +1 -0
- package/dist/core/delegation/worker-delegation-controller.d.ts +21 -5
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +386 -251
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-delegation-request.d.ts +14 -0
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts +4 -2
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.js +16 -6
- package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -1
- package/dist/core/delegation/worker-execution-policy.d.ts +2 -1
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
- package/dist/core/delegation/worker-execution-policy.js +5 -7
- package/dist/core/delegation/worker-execution-policy.js.map +1 -1
- package/dist/core/delegation/worker-lifecycle.d.ts +44 -1
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
- package/dist/core/delegation/worker-lifecycle.js +120 -0
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-process-owner.d.ts +18 -0
- package/dist/core/delegation/worker-process-owner.d.ts.map +1 -0
- package/dist/core/delegation/worker-process-owner.js +54 -0
- package/dist/core/delegation/worker-process-owner.js.map +1 -0
- package/dist/core/delegation/worker-profile-resolver.d.ts +5 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.js +8 -0
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.d.ts +54 -0
- package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-recovery-coordinator.js +181 -0
- package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-resource-catalog.d.ts +32 -0
- package/dist/core/delegation/worker-resource-catalog.d.ts.map +1 -0
- package/dist/core/delegation/worker-resource-catalog.js +116 -0
- package/dist/core/delegation/worker-resource-catalog.js.map +1 -0
- package/dist/core/delegation/worker-resource-materializer.d.ts +47 -0
- package/dist/core/delegation/worker-resource-materializer.d.ts.map +1 -0
- package/dist/core/delegation/worker-resource-materializer.js +137 -0
- package/dist/core/delegation/worker-resource-materializer.js.map +1 -0
- package/dist/core/delegation/worker-runner.d.ts +3 -1
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +189 -54
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-terminal-finalizer.d.ts +23 -0
- package/dist/core/delegation/worker-terminal-finalizer.d.ts.map +1 -0
- package/dist/core/delegation/worker-terminal-finalizer.js +12 -0
- package/dist/core/delegation/worker-terminal-finalizer.js.map +1 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +38 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.js +107 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-write-reservation.d.ts +90 -0
- package/dist/core/delegation/worker-write-reservation.d.ts.map +1 -0
- package/dist/core/delegation/worker-write-reservation.js +348 -0
- package/dist/core/delegation/worker-write-reservation.js.map +1 -0
- package/dist/core/models/model-endpoint.d.ts +3 -0
- package/dist/core/models/model-endpoint.d.ts.map +1 -0
- package/dist/core/models/model-endpoint.js +11 -0
- package/dist/core/models/model-endpoint.js.map +1 -0
- package/dist/core/orchestration/agent-resume.d.ts +2 -0
- package/dist/core/orchestration/agent-resume.d.ts.map +1 -1
- package/dist/core/orchestration/agent-resume.js +7 -0
- package/dist/core/orchestration/agent-resume.js.map +1 -1
- package/dist/core/orchestration/attempt-usage.d.ts +28 -0
- package/dist/core/orchestration/attempt-usage.d.ts.map +1 -0
- package/dist/core/orchestration/attempt-usage.js +168 -0
- package/dist/core/orchestration/attempt-usage.js.map +1 -0
- package/dist/core/orchestration/capability-gateway.d.ts +19 -1
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +128 -28
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +35 -0
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +17 -0
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/delegation-ledger.d.ts +17 -2
- package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
- package/dist/core/orchestration/delegation-ledger.js +78 -3
- package/dist/core/orchestration/delegation-ledger.js.map +1 -1
- package/dist/core/orchestration/event-store.d.ts +1 -0
- package/dist/core/orchestration/event-store.d.ts.map +1 -1
- package/dist/core/orchestration/event-store.js +78 -38
- package/dist/core/orchestration/event-store.js.map +1 -1
- package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
- package/dist/core/orchestration/profile-registry.js +81 -41
- package/dist/core/orchestration/profile-registry.js.map +1 -1
- package/dist/core/orchestration/profile-store.d.ts.map +1 -1
- package/dist/core/orchestration/profile-store.js +18 -4
- package/dist/core/orchestration/profile-store.js.map +1 -1
- package/dist/core/orchestration/risk-budget.d.ts +2 -0
- package/dist/core/orchestration/risk-budget.d.ts.map +1 -1
- package/dist/core/orchestration/risk-budget.js +26 -0
- package/dist/core/orchestration/risk-budget.js.map +1 -1
- package/dist/core/orchestration/task-runtime.d.ts +13 -1
- package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
- package/dist/core/orchestration/task-runtime.js +127 -16
- package/dist/core/orchestration/task-runtime.js.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.d.ts +3 -1
- package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.js +75 -23
- package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
- package/dist/core/orchestration/worker-result-adapter.d.ts +9 -3
- package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -1
- package/dist/core/orchestration/worker-result-adapter.js +167 -14
- package/dist/core/orchestration/worker-result-adapter.js.map +1 -1
- package/dist/core/reflection-controller.d.ts +1 -1
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +90 -54
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/research/evidence-bundle.d.ts +20 -0
- package/dist/core/research/evidence-bundle.d.ts.map +1 -1
- package/dist/core/research/evidence-bundle.js +173 -69
- package/dist/core/research/evidence-bundle.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +7 -0
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +15 -1
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/session-artifact-bundle.d.ts +35 -0
- package/dist/core/session-artifact-bundle.d.ts.map +1 -0
- package/dist/core/session-artifact-bundle.js +61 -0
- package/dist/core/session-artifact-bundle.js.map +1 -0
- package/dist/core/tools/delegate-status.d.ts +6 -1
- package/dist/core/tools/delegate-status.d.ts.map +1 -1
- package/dist/core/tools/delegate-status.js +100 -18
- package/dist/core/tools/delegate-status.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +9 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +323 -61
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/run-process.d.ts +1 -1
- package/dist/core/tools/run-process.d.ts.map +1 -1
- package/dist/core/tools/run-process.js +69 -9
- package/dist/core/tools/run-process.js.map +1 -1
- package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
- package/dist/core/tools/shell-contract-router.js +12 -5
- package/dist/core/tools/shell-contract-router.js.map +1 -1
- package/dist/core/util/bounded-file.d.ts +15 -0
- package/dist/core/util/bounded-file.d.ts.map +1 -0
- package/dist/core/util/bounded-file.js +120 -0
- package/dist/core/util/bounded-file.js.map +1 -0
- package/dist/core/util/bounded-jsonl.d.ts.map +1 -1
- package/dist/core/util/bounded-jsonl.js +119 -9
- package/dist/core/util/bounded-jsonl.js.map +1 -1
- package/dist/core/util/bounded-value.d.ts +3 -0
- package/dist/core/util/bounded-value.d.ts.map +1 -0
- package/dist/core/util/bounded-value.js +12 -0
- package/dist/core/util/bounded-value.js.map +1 -0
- package/dist/core/util/value-guards.d.ts +2 -0
- package/dist/core/util/value-guards.d.ts.map +1 -1
- package/dist/core/util/value-guards.js +5 -0
- package/dist/core/util/value-guards.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +27 -44
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/docs/tool-repair.md +3 -0
- package/docs/windows.md +4 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## [0.81.42] - 2026-07-27
|
|
2
|
+
|
|
3
|
+
### Changed
|
|
4
|
+
|
|
5
|
+
- Rebuilt delegated workers around immutable owner-authored execution contracts, durable logical-agent identities, resumable conversations and mailboxes, fenced write reservations, bounded resource materialization, verified model-pinned compaction, and event-driven terminal handoffs.
|
|
6
|
+
- Consolidated session-owned orchestration events, actions, mailboxes, conversations, and deletion under one bounded artifact bundle while keeping cross-session write reservations globally coordinated.
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- Made the Windows shell engine preserve `$?`, support controlled `exit`, and accept `head`/`tail -N`, so diagnostic-capture command chains complete with a terminal result instead of losing status or treating `exit` as an external command.
|
|
11
|
+
- Added a provider- and tool-neutral WSL incident collector that packages the latest human session, recovery and orchestration records, explicitly requested command logs, TUI evidence, boot identity, installed-runtime hashes, bounded kernel diagnostics, and relevant Windows host events without collecting credential stores or emitting false missing-log warnings.
|
|
12
|
+
- Made pre-start worker failures publish exactly one durable terminal handoff, rejected malformed typed result envelopes, and handled null or Buffer filesystem watcher filenames on Windows.
|
|
13
|
+
- Made orchestration session paths portable across Windows and POSIX and bounded profile, process, event, result, and cumulative usage payloads at their owning contracts.
|
|
14
|
+
- Kept explicit empty worker tool surfaces inside the repair loop and persisted immediate or argument-repaired tool requests in durable execution order, preventing unavailable-tool calls from collapsing into completion errors or divergent transcripts.
|
|
15
|
+
- Preserved bounded host-observed changed-file progress when an agent-bound worker is suspended, so owner-session disposal remains resumable without fabricating terminal parent-session records.
|
|
16
|
+
|
|
1
17
|
## [0.81.41] - 2026-07-27
|
|
2
18
|
|
|
3
19
|
### Added
|
|
@@ -97,7 +97,7 @@ def cat(ctx: "BuiltinContext") -> int:
|
|
|
97
97
|
|
|
98
98
|
|
|
99
99
|
def _parse_n_flag(name: str, argv: list[str]) -> tuple[int, list[str]]:
|
|
100
|
-
"""Parse `[-n N] [FILE]
|
|
100
|
+
"""Parse `[-n N|-N] [FILE]`. Any other flag/form -> unsupported-flag."""
|
|
101
101
|
n = 10
|
|
102
102
|
operands: list[str] = []
|
|
103
103
|
args = argv[1:]
|
|
@@ -118,6 +118,10 @@ def _parse_n_flag(name: str, argv: list[str]) -> tuple[int, list[str]]:
|
|
|
118
118
|
n = _parse_int_operand(name, a[2:])
|
|
119
119
|
i += 1
|
|
120
120
|
continue
|
|
121
|
+
if len(a) > 1 and a[0] == "-" and a[1:].isdigit():
|
|
122
|
+
n = int(a[1:])
|
|
123
|
+
i += 1
|
|
124
|
+
continue
|
|
121
125
|
if a.startswith("-") and a != "-":
|
|
122
126
|
_refuse_flag(name, a)
|
|
123
127
|
operands.append(a)
|
|
@@ -46,7 +46,7 @@ class ExecContext:
|
|
|
46
46
|
stderr: BinaryIO | int | None = None
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
STATE_BUILTINS = {"cd", "export", "unset"}
|
|
49
|
+
# Executor-owned builtins are NOT in commands/REGISTRY: state mutators and `exit`
|
|
50
|
+
# need ShellState/control-flow access, while the runner needs the executor.
|
|
51
|
+
STATE_BUILTINS = {"cd", "export", "unset", "exit"}
|
|
52
52
|
RUNNER_BUILTINS = {"xargs"}
|
|
@@ -47,3 +47,11 @@ class UnsupportedConstruct(Exception):
|
|
|
47
47
|
self.code = "unsupported"
|
|
48
48
|
self.construct = construct
|
|
49
49
|
self.message = message
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ShellExit(Exception):
|
|
53
|
+
"""Controlled `exit` request carried to the nearest shell boundary."""
|
|
54
|
+
|
|
55
|
+
def __init__(self, exit_code: int) -> None:
|
|
56
|
+
super().__init__(exit_code)
|
|
57
|
+
self.exit_code = exit_code
|
|
@@ -17,7 +17,7 @@ import parser as parser_module
|
|
|
17
17
|
import proc
|
|
18
18
|
import tokens as tokens_module
|
|
19
19
|
from context import RUNNER_BUILTINS, STATE_BUILTINS, BuiltinContext, ExecContext
|
|
20
|
-
from errors import UnsupportedConstruct
|
|
20
|
+
from errors import ShellExit, UnsupportedConstruct
|
|
21
21
|
from state import ShellState
|
|
22
22
|
|
|
23
23
|
DEVNULL = os.devnull
|
|
@@ -209,6 +209,7 @@ def execute(list_node: nodes.CommandList, ctx: ExecContext) -> int:
|
|
|
209
209
|
exit_code = 0
|
|
210
210
|
for entry in list_node.entries:
|
|
211
211
|
exit_code = _execute_andor(entry, ctx)
|
|
212
|
+
ctx.state.last_exit_code = exit_code
|
|
212
213
|
return exit_code
|
|
213
214
|
|
|
214
215
|
|
|
@@ -222,6 +223,7 @@ def _execute_andor(andor: nodes.AndOr, ctx: ExecContext) -> int:
|
|
|
222
223
|
if operator == "||" and exit_code == 0:
|
|
223
224
|
continue
|
|
224
225
|
exit_code = _execute_pipeline(pipeline, ctx)
|
|
226
|
+
ctx.state.last_exit_code = exit_code
|
|
225
227
|
return exit_code
|
|
226
228
|
|
|
227
229
|
|
|
@@ -310,6 +312,8 @@ def _run_pipeline_elements(elements: list, ctx: ExecContext) -> int:
|
|
|
310
312
|
# fabricated exit-0/empty-output success.
|
|
311
313
|
refusals[idx] = exc
|
|
312
314
|
results[idx] = 1
|
|
315
|
+
except ShellExit as exc:
|
|
316
|
+
results[idx] = exc.exit_code
|
|
313
317
|
except BaseException as exc: # noqa: BLE001 - any other stage failure must not crash the engine
|
|
314
318
|
# Any OTHER exception is a real per-stage failure, not a refusal: it
|
|
315
319
|
# gets a named, actionable one-line message on the merged sink (never
|
|
@@ -477,7 +481,10 @@ def _execute_subshell(node: nodes.Subshell, ctx: ExecContext, stdin_stream, stdo
|
|
|
477
481
|
)
|
|
478
482
|
isolated_state = ctx.state.copy()
|
|
479
483
|
inner_ctx = _sub_ctx(ctx, isolated_state, r_in, r_out, r_err)
|
|
480
|
-
|
|
484
|
+
try:
|
|
485
|
+
return execute(node.body, inner_ctx)
|
|
486
|
+
except ShellExit as exc:
|
|
487
|
+
return exc.exit_code
|
|
481
488
|
finally:
|
|
482
489
|
tracker.close()
|
|
483
490
|
|
|
@@ -569,6 +576,19 @@ def _as_stream(fd_or_stream: BinaryIO | int, mode: str) -> BinaryIO:
|
|
|
569
576
|
|
|
570
577
|
|
|
571
578
|
def _run_state_builtin(name: str, argv: list[str], ctx: ExecContext, out_stream: BinaryIO | int) -> int:
|
|
579
|
+
if name == "exit":
|
|
580
|
+
if len(argv) > 2:
|
|
581
|
+
_write_merged(out_stream, b"exit: too many arguments\n", ctx)
|
|
582
|
+
raise ShellExit(1)
|
|
583
|
+
if len(argv) == 1:
|
|
584
|
+
raise ShellExit(ctx.state.last_exit_code)
|
|
585
|
+
try:
|
|
586
|
+
exit_code = int(argv[1], 10)
|
|
587
|
+
except ValueError:
|
|
588
|
+
_write_merged(out_stream, f"exit: {argv[1]}: numeric argument required\n".encode("utf-8"), ctx)
|
|
589
|
+
raise ShellExit(2)
|
|
590
|
+
raise ShellExit(exit_code & 0xFF)
|
|
591
|
+
|
|
572
592
|
if name == "cd":
|
|
573
593
|
target = argv[1] if len(argv) > 1 else ctx.state.env.get("HOME")
|
|
574
594
|
print_new_cwd = argv[1:2] == ["-"]
|
|
@@ -729,6 +749,9 @@ def run_command_substitution(src: str, ctx: ExecContext) -> tuple[str, int]:
|
|
|
729
749
|
deadline=ctx.deadline,
|
|
730
750
|
stderr=ctx.stderr,
|
|
731
751
|
)
|
|
732
|
-
|
|
752
|
+
try:
|
|
753
|
+
exit_code = execute(ast, sub_ctx)
|
|
754
|
+
except ShellExit as exc:
|
|
755
|
+
exit_code = exc.exit_code
|
|
733
756
|
text = buffer.getvalue().decode("utf-8", errors="replace")
|
|
734
757
|
return text.rstrip("\n"), exit_code
|
|
@@ -97,6 +97,9 @@ def _resolve_param(name: str, op: str | None, arg: Word | None, ctx: "ExecContex
|
|
|
97
97
|
split_and_glob_eligible is False here always; callers decide splitting based on
|
|
98
98
|
quoting context (Raw vs DQ), not on the parameter's own nature.
|
|
99
99
|
"""
|
|
100
|
+
if name == "?" and op is None:
|
|
101
|
+
return str(ctx.state.last_exit_code), False
|
|
102
|
+
|
|
100
103
|
env = ctx.state.env
|
|
101
104
|
if op == "#len":
|
|
102
105
|
value = env.get(name, "")
|
|
@@ -17,7 +17,7 @@ import exec as exec_module
|
|
|
17
17
|
import parser as parser_module
|
|
18
18
|
import tokens as tokens_module
|
|
19
19
|
from context import ExecContext
|
|
20
|
-
from errors import UnsupportedConstruct
|
|
20
|
+
from errors import ShellExit, UnsupportedConstruct
|
|
21
21
|
from expand import ParamExpansionError
|
|
22
22
|
from state import ShellState
|
|
23
23
|
|
|
@@ -97,6 +97,9 @@ def main() -> int:
|
|
|
97
97
|
tokens = tokens_module.tokenize(command)
|
|
98
98
|
ast = parser_module.parse(tokens)
|
|
99
99
|
exit_code = exec_module.execute(ast, ctx)
|
|
100
|
+
except ShellExit as exc:
|
|
101
|
+
_write_frame(exc.exit_code, state.cwd, state.delta(original_env), None)
|
|
102
|
+
return 0
|
|
100
103
|
except UnsupportedConstruct as exc:
|
|
101
104
|
output.write(exc.message.encode("utf-8", errors="replace"))
|
|
102
105
|
_write_frame(
|
|
@@ -64,6 +64,7 @@ class ShellState:
|
|
|
64
64
|
|
|
65
65
|
cwd: str
|
|
66
66
|
env: ShellEnvironment = field(default_factory=ShellEnvironment)
|
|
67
|
+
last_exit_code: int = 0
|
|
67
68
|
|
|
68
69
|
def __post_init__(self) -> None:
|
|
69
70
|
if not isinstance(self.env, ShellEnvironment):
|
|
@@ -71,7 +72,7 @@ class ShellState:
|
|
|
71
72
|
|
|
72
73
|
def copy(self) -> "ShellState":
|
|
73
74
|
"""Return an independent copy (used for subshell isolation)."""
|
|
74
|
-
return ShellState(cwd=self.cwd, env=self.env.copy())
|
|
75
|
+
return ShellState(cwd=self.cwd, env=self.env.copy(), last_exit_code=self.last_exit_code)
|
|
75
76
|
|
|
76
77
|
def chdir(self, path: str) -> None:
|
|
77
78
|
"""Validate `path` exists and is a directory, then update cwd + OLDPWD."""
|
|
@@ -294,6 +294,8 @@ def _scan_dollar_form(src: str, pos: int) -> tuple[Segment, int]:
|
|
|
294
294
|
)
|
|
295
295
|
close = _find_closing_paren(src, pos + 2)
|
|
296
296
|
return CmdSub(src=src[pos + 2 : close]), close + 1
|
|
297
|
+
if nxt == "?":
|
|
298
|
+
return Param(name="?", op=None, arg=None), pos + 2
|
|
297
299
|
if nxt and (_IDENT_START_RE.match(nxt)):
|
|
298
300
|
m = _IDENT_RE.match(src, pos + 1)
|
|
299
301
|
assert m is not None
|
|
@@ -39,6 +39,38 @@ export declare function runtimesDir(kind: string, agentDir: string): string;
|
|
|
39
39
|
export declare function modelsDir(kind: string, agentDir: string): string;
|
|
40
40
|
/** `<agentDir>/sessions` -- session transcript storage (large, established; not a "loose file"). */
|
|
41
41
|
export declare function sessionsDir(agentDir: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* `<agentDir>/state/orchestration/sessions/<session-key>` -- the one durable control-plane
|
|
44
|
+
* bundle owned by a foreground session. Event state, worker mailboxes, mutation journals, and
|
|
45
|
+
* worker transcripts must stay beneath this boundary so explicit session deletion can remove
|
|
46
|
+
* exactly its companion artifacts without scanning global state.
|
|
47
|
+
*/
|
|
48
|
+
export declare function orchestrationSessionsDir(agentDir: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* `<agentDir>/state/orchestration/sessions/<session-key>` -- the one durable control-plane
|
|
51
|
+
* bundle owned by a foreground session.
|
|
52
|
+
*/
|
|
53
|
+
export declare function orchestrationSessionDir(agentDir: string, parentSessionId: string): string;
|
|
54
|
+
/** `<orchestrationSessionDir>/events` -- append-only event tail, snapshot, cursor, and idempotency state. */
|
|
55
|
+
export declare function orchestrationEventStoreDir(agentDir: string, parentSessionId: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* `<orchestrationSessionDir>/worker-conversations` -- durable Pi worker transcripts owned by one
|
|
58
|
+
* foreground session. Worker conversations remain in SessionManager's established JSONL format,
|
|
59
|
+
* but are intentionally outside the foreground session picker namespace.
|
|
60
|
+
*/
|
|
61
|
+
export declare function workerConversationSessionsDir(agentDir: string, parentSessionId: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* `<orchestrationSessionDir>/worker-mailboxes/<scope-digest>.json` -- durable bounded control
|
|
64
|
+
* messages for one logical worker. Identity stays hashed so neither agent ids nor project paths
|
|
65
|
+
* become path segments.
|
|
66
|
+
*/
|
|
67
|
+
export declare function workerAgentMailboxFile(agentDir: string, parentSessionId: string, scopeDigest: string): string;
|
|
68
|
+
/**
|
|
69
|
+
* `<orchestrationSessionDir>/worker-actions/<scope-digest>.json` -- durable, bounded mutation
|
|
70
|
+
* intents and receipts for one fenced worker attempt. The opaque digest intentionally keeps task
|
|
71
|
+
* identifiers out of filesystem path segments and works on Windows and WSL.
|
|
72
|
+
*/
|
|
73
|
+
export declare function workerActionJournalFile(agentDir: string, parentSessionId: string, scopeDigest: string): string;
|
|
42
74
|
/** `<agentDir>/npm` -- managed npm package installs. */
|
|
43
75
|
export declare function npmDir(agentDir: string): string;
|
|
44
76
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-paths.d.ts","sourceRoot":"","sources":["../../src/core/agent-paths.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Typed path SSOT for everything machine-managed under `<agentDir>` (`~/.pi/agent/` by default,\n * `getAgentDir()` in `../config.ts`). Every writer that persists machine data (stores, caches, managed\n * runtimes/models, cross-process coordination) MUST resolve its path through one of the accessors\n * below instead of hand-rolling `join(agentDir, …)` — that ad-hoc pattern is exactly how root-level\n * stragglers like `trust.json` accumulated, and nothing stopped the next writer from doing it again.\n *\n * Canonical layout:\n * ```\n * <agentDir>/\n * auth.json settings.json models.json keybindings.json MEMORY.md USER.md SYSTEM.md … user CONFIG/MEMORY (root, kept)\n * okf-memory/ authored memory (root, kept)\n * skills/ extensions/ prompts/ themes/ profiles/ user RESOURCES (root, kept)\n * profiles/directories/<workspace-hash>/settings.json directory overlays\n * state/ durable machine state (model adaptation/fitness, tool performance,\n * learning observations, trust decisions, config backups, …) -- stateDir/stateFile\n * cache/ rebuildable, safe to delete (tool-path probes, jiti transform cache, uv) -- cacheDir/cacheFile\n * work/ transient/scratch, delegated to work-directory.ts (tenant/run/lease),\n * including context/sessions/<session-id>/{gc,artifacts} -- re-exported below\n * runtimes/<kind> models/<kind> -- runtimesDir/modelsDir\n * npm/ git/ sessions/ -- npmDir/gitDir/sessionsDir\n * worktrees/<repo-slug>/<laneKey> durable lane checkouts (core/worktree-sync) -- worktreesDir\n * ```\n *\n * Every accessor takes `agentDir` as an explicit, required first argument -- deliberately mirroring\n * `work-directory.ts`'s existing `getWorkRoot(agentDir)` convention rather than defaulting to\n * `getAgentDir()` internally. Several real callers (stores' `forAgentDir`, test harnesses with a temp\n * agentDir) build paths for a NON-default agentDir; a hidden default would silently resolve the wrong\n * root for those callers instead of failing loudly. Callers operating on the process-wide default pass\n * `getAgentDir()` explicitly at the call site.\n *\n * These accessors are pure path builders -- no directory creation, no I/O. Every existing writer\n * already creates its parent directory at write time (see `util/atomic-file.ts`'s\n * `mkdirSync(dirname(filePath), { recursive: true })`), so duplicating that here would be redundant\n * and would blur the \"pure function\" contract readers rely on.\n */\nimport { join } from \"node:path\";\nimport {\n\tacquireWorkRun,\n\tassertPortablePathSegment,\n\tboundedWorkRetention,\n\tcreateWorkRunId,\n\tgetProcessWorkRun,\n\tgetWorkRoot,\n\tgetWorkRunDir,\n\tgetWorkTenantDir,\n\thasActiveWorkRunLease,\n\tpruneWorkTenant,\n} from \"../utils/work-directory.ts\";\nimport { getReloadCoordinationDir } from \"./reload-blockers.ts\";\n\n/** Root entries reserved for user-authored configuration and memory. */\nexport const AGENT_ROOT_FILE_NAMES = [\n\t\"auth.json\",\n\t\"settings.json\",\n\t\"models.json\",\n\t\"keybindings.json\",\n\t\"MEMORY.md\",\n\t\"USER.md\",\n\t\"SYSTEM.md\",\n\t\"APPEND_SYSTEM.md\",\n] as const;\n\n/** Root entries reserved for user resources and machine-managed storage classes. */\nexport const AGENT_ROOT_DIRECTORY_NAMES = [\n\t\"okf-memory\",\n\t\"skills\",\n\t\"extensions\",\n\t\"prompts\",\n\t\"themes\",\n\t\"profiles\",\n\t\"state\",\n\t\"cache\",\n\t\"bin\",\n\t\"work\",\n\t\"runtimes\",\n\t\"models\",\n\t\"sessions\",\n\t\"npm\",\n\t\"git\",\n\t\"worktrees\",\n] as const;\n\nconst AGENT_ROOT_ENTRY_NAMES = new Set<string>([...AGENT_ROOT_FILE_NAMES, ...AGENT_ROOT_DIRECTORY_NAMES]);\n\nexport function isCanonicalAgentRootEntry(name: string): boolean {\n\treturn AGENT_ROOT_ENTRY_NAMES.has(name);\n}\n\n/** `<agentDir>/<name>` -- a root-level user config/memory file (auth.json, settings.json, MEMORY.md, …). */\nexport function configFile(agentDir: string, name: string): string {\n\treturn join(agentDir, name);\n}\n\n/** `<agentDir>/okf-memory` -- user-authored durable OKF memory documents. */\nexport function okfMemoryDir(agentDir: string): string {\n\treturn join(agentDir, \"okf-memory\");\n}\n\n/** `<agentDir>/state` -- durable machine-managed state. Deleting it loses real history, not just cache. */\nexport function stateDir(agentDir: string): string {\n\treturn join(agentDir, \"state\");\n}\n\n/** `<agentDir>/state/<segments…>` */\nexport function stateFile(agentDir: string, ...segments: string[]): string {\n\treturn join(stateDir(agentDir), ...segments);\n}\n\n/** `<agentDir>/state/attachments` -- bounded, session-keyed clipboard image attachments. */\nexport function attachmentsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"attachments\");\n}\n\n/** `<agentDir>/state/secrets` -- encrypted credential vault and owner-approved materializations. */\nexport function secretsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"secrets\");\n}\n\n/** `<agentDir>/state/secrets/vault.json` -- encrypted, versioned generic credential vault. */\nexport function secretVaultFile(agentDir: string): string {\n\treturn join(secretsDir(agentDir), \"vault.json\");\n}\n\n/** `<agentDir>/state/secrets/materialized` -- private generated dotenv files, grouped by profile. */\nexport function managedSecretEnvDir(agentDir: string): string {\n\treturn join(secretsDir(agentDir), \"materialized\");\n}\n\n/** `<agentDir>/state/extensions/<namespace>` -- durable state owned by one extension. */\nexport function extensionStateDir(agentDir: string, namespace: string): string {\n\tassertPortablePathSegment(\"Extension namespace\", namespace);\n\treturn stateFile(agentDir, \"extensions\", namespace);\n}\n\n/** `<agentDir>/state/backups/config` -- explicit user-requested configuration snapshots. */\nexport function configBackupsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"backups\", \"config\");\n}\n\n/** `<agentDir>/cache` -- rebuildable; safe to delete (the next run just re-probes/recomputes). */\nexport function cacheDir(agentDir: string): string {\n\treturn join(agentDir, \"cache\");\n}\n\n/** `<agentDir>/cache/<segments…>` */\nexport function cacheFile(agentDir: string, ...segments: string[]): string {\n\treturn join(cacheDir(agentDir), ...segments);\n}\n\n/** `<agentDir>/cache/extensions/<namespace>` -- rebuildable cache owned by one extension. */\nexport function extensionCacheDir(agentDir: string, namespace: string): string {\n\tassertPortablePathSegment(\"Extension namespace\", namespace);\n\treturn cacheFile(agentDir, \"extensions\", namespace);\n}\n\n/** `<agentDir>/bin` -- managed executable helpers (fd, rg). */\nexport function binDir(agentDir: string): string {\n\treturn join(agentDir, \"bin\");\n}\n\n/** `<agentDir>/runtimes/<kind>` -- a managed runtime install (ollama, python, prism-llamacpp, needle, …). */\nexport function runtimesDir(kind: string, agentDir: string): string {\n\treturn join(agentDir, \"runtimes\", kind);\n}\n\n/** `<agentDir>/models/<kind>` -- downloaded model weights, grouped by provider/runtime. */\nexport function modelsDir(kind: string, agentDir: string): string {\n\treturn join(agentDir, \"models\", kind);\n}\n\n/** `<agentDir>/sessions` -- session transcript storage (large, established; not a \"loose file\"). */\nexport function sessionsDir(agentDir: string): string {\n\treturn join(agentDir, \"sessions\");\n}\n\n/** `<agentDir>/npm` -- managed npm package installs. */\nexport function npmDir(agentDir: string): string {\n\treturn join(agentDir, \"npm\");\n}\n\n/**\n * `<agentDir>/worktrees` -- lane worktree checkouts for the worktree-sync subsystem\n * (`core/worktree-sync/`), grouped as `worktrees/<repo-slug>/<laneKey>`. These hold REAL\n * uncommitted agent work, so they are durable like `state/` -- never under transient `work/`,\n * whose retention would silently eat in-progress code.\n */\nexport function worktreesDir(agentDir: string): string {\n\treturn join(agentDir, \"worktrees\");\n}\n\n/** `<agentDir>/git` -- managed git-sourced package installs. */\nexport function gitDir(agentDir: string): string {\n\treturn join(agentDir, \"git\");\n}\n\nexport type AgentResourceKind = \"skills\" | \"prompts\" | \"themes\" | \"extensions\" | \"profiles\";\n\n/** `<agentDir>/<kind>` -- a user-managed resource directory. Root, kept: moving it breaks users. */\nexport function resourceDir(kind: AgentResourceKind, agentDir: string): string {\n\treturn join(agentDir, kind);\n}\n\n/** `<agentDir>/profiles/directories` -- durable per-directory resource-profile overlays. */\nexport function directoryProfilesDir(agentDir: string): string {\n\treturn join(resourceDir(\"profiles\", agentDir), \"directories\");\n}\n\n/**\n * `work/` is a mature transient/scratch root with its own tenant/run/lease/retention machinery\n * (`utils/work-directory.ts`). The SSOT delegates to it wholesale instead of reimplementing -- these\n * are straight re-exports so every category (state/cache/work/runtimes/models/…) is reachable from one\n * module without duplicating `work-directory.ts`'s logic.\n */\nexport {\n\tgetWorkRoot,\n\tassertPortablePathSegment,\n\tboundedWorkRetention,\n\tgetWorkTenantDir,\n\tgetWorkRunDir,\n\tgetProcessWorkRun,\n\thasActiveWorkRunLease,\n\tacquireWorkRun,\n\tcreateWorkRunId,\n\tpruneWorkTenant,\n};\nexport type { AcquireWorkRunOptions, WorkRetentionOptions, WorkRunLease } from \"../utils/work-directory.ts\";\n\n/**\n * `work/reload-coordination` -- cross-process reload/live-op coordination state. Already correctly\n * work-scoped (defined in `reload-blockers.ts`, its natural home given the surrounding reload-gate\n * logic there); re-exported here under the taxonomy's canonical name for SSOT discoverability.\n */\nexport const reloadCoordinationDir = getReloadCoordinationDir;\n"]}
|
|
1
|
+
{"version":3,"file":"agent-paths.d.ts","sourceRoot":"","sources":["../../src/core/agent-paths.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Typed path SSOT for everything machine-managed under `<agentDir>` (`~/.pi/agent/` by default,\n * `getAgentDir()` in `../config.ts`). Every writer that persists machine data (stores, caches, managed\n * runtimes/models, cross-process coordination) MUST resolve its path through one of the accessors\n * below instead of hand-rolling `join(agentDir, …)` — that ad-hoc pattern is exactly how root-level\n * stragglers like `trust.json` accumulated, and nothing stopped the next writer from doing it again.\n *\n * Canonical layout:\n * ```\n * <agentDir>/\n * auth.json settings.json models.json keybindings.json MEMORY.md USER.md SYSTEM.md … user CONFIG/MEMORY (root, kept)\n * okf-memory/ authored memory (root, kept)\n * skills/ extensions/ prompts/ themes/ profiles/ user RESOURCES (root, kept)\n * profiles/directories/<workspace-hash>/settings.json directory overlays\n * state/ durable machine state (model adaptation/fitness, tool performance,\n * learning observations, trust decisions, config backups, …) -- stateDir/stateFile\n * cache/ rebuildable, safe to delete (tool-path probes, jiti transform cache, uv) -- cacheDir/cacheFile\n * work/ transient/scratch, delegated to work-directory.ts (tenant/run/lease),\n * including context/sessions/<session-id>/{gc,artifacts} -- re-exported below\n * runtimes/<kind> models/<kind> -- runtimesDir/modelsDir\n * npm/ git/ sessions/ -- npmDir/gitDir/sessionsDir\n * state/orchestration/sessions/<session-key>/ -- one foreground-session-owned\n * control-plane bundle\n * worktrees/<repo-slug>/<laneKey> durable lane checkouts (core/worktree-sync) -- worktreesDir\n * ```\n *\n * Every accessor takes `agentDir` as an explicit, required first argument -- deliberately mirroring\n * `work-directory.ts`'s existing `getWorkRoot(agentDir)` convention rather than defaulting to\n * `getAgentDir()` internally. Several real callers (stores' `forAgentDir`, test harnesses with a temp\n * agentDir) build paths for a NON-default agentDir; a hidden default would silently resolve the wrong\n * root for those callers instead of failing loudly. Callers operating on the process-wide default pass\n * `getAgentDir()` explicitly at the call site.\n *\n * These accessors are pure path builders -- no directory creation, no I/O. Every existing writer\n * already creates its parent directory at write time (see `util/atomic-file.ts`'s\n * `mkdirSync(dirname(filePath), { recursive: true })`), so duplicating that here would be redundant\n * and would blur the \"pure function\" contract readers rely on.\n */\nimport { createHash } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tacquireWorkRun,\n\tassertPortablePathSegment,\n\tboundedWorkRetention,\n\tcreateWorkRunId,\n\tgetProcessWorkRun,\n\tgetWorkRoot,\n\tgetWorkRunDir,\n\tgetWorkTenantDir,\n\thasActiveWorkRunLease,\n\tpruneWorkTenant,\n} from \"../utils/work-directory.ts\";\nimport { getReloadCoordinationDir } from \"./reload-blockers.ts\";\nimport { requireBoundedTrimmedText } from \"./util/bounded-value.ts\";\n\n/** Root entries reserved for user-authored configuration and memory. */\nexport const AGENT_ROOT_FILE_NAMES = [\n\t\"auth.json\",\n\t\"settings.json\",\n\t\"models.json\",\n\t\"keybindings.json\",\n\t\"MEMORY.md\",\n\t\"USER.md\",\n\t\"SYSTEM.md\",\n\t\"APPEND_SYSTEM.md\",\n] as const;\n\n/** Root entries reserved for user resources and machine-managed storage classes. */\nexport const AGENT_ROOT_DIRECTORY_NAMES = [\n\t\"okf-memory\",\n\t\"skills\",\n\t\"extensions\",\n\t\"prompts\",\n\t\"themes\",\n\t\"profiles\",\n\t\"state\",\n\t\"cache\",\n\t\"bin\",\n\t\"work\",\n\t\"runtimes\",\n\t\"models\",\n\t\"sessions\",\n\t\"npm\",\n\t\"git\",\n\t\"worktrees\",\n] as const;\n\nconst AGENT_ROOT_ENTRY_NAMES = new Set<string>([...AGENT_ROOT_FILE_NAMES, ...AGENT_ROOT_DIRECTORY_NAMES]);\n\nexport function isCanonicalAgentRootEntry(name: string): boolean {\n\treturn AGENT_ROOT_ENTRY_NAMES.has(name);\n}\n\n/** `<agentDir>/<name>` -- a root-level user config/memory file (auth.json, settings.json, MEMORY.md, …). */\nexport function configFile(agentDir: string, name: string): string {\n\treturn join(agentDir, name);\n}\n\n/** `<agentDir>/okf-memory` -- user-authored durable OKF memory documents. */\nexport function okfMemoryDir(agentDir: string): string {\n\treturn join(agentDir, \"okf-memory\");\n}\n\n/** `<agentDir>/state` -- durable machine-managed state. Deleting it loses real history, not just cache. */\nexport function stateDir(agentDir: string): string {\n\treturn join(agentDir, \"state\");\n}\n\n/** `<agentDir>/state/<segments…>` */\nexport function stateFile(agentDir: string, ...segments: string[]): string {\n\treturn join(stateDir(agentDir), ...segments);\n}\n\n/** `<agentDir>/state/attachments` -- bounded, session-keyed clipboard image attachments. */\nexport function attachmentsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"attachments\");\n}\n\n/** `<agentDir>/state/secrets` -- encrypted credential vault and owner-approved materializations. */\nexport function secretsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"secrets\");\n}\n\n/** `<agentDir>/state/secrets/vault.json` -- encrypted, versioned generic credential vault. */\nexport function secretVaultFile(agentDir: string): string {\n\treturn join(secretsDir(agentDir), \"vault.json\");\n}\n\n/** `<agentDir>/state/secrets/materialized` -- private generated dotenv files, grouped by profile. */\nexport function managedSecretEnvDir(agentDir: string): string {\n\treturn join(secretsDir(agentDir), \"materialized\");\n}\n\n/** `<agentDir>/state/extensions/<namespace>` -- durable state owned by one extension. */\nexport function extensionStateDir(agentDir: string, namespace: string): string {\n\tassertPortablePathSegment(\"Extension namespace\", namespace);\n\treturn stateFile(agentDir, \"extensions\", namespace);\n}\n\n/** `<agentDir>/state/backups/config` -- explicit user-requested configuration snapshots. */\nexport function configBackupsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"backups\", \"config\");\n}\n\n/** `<agentDir>/cache` -- rebuildable; safe to delete (the next run just re-probes/recomputes). */\nexport function cacheDir(agentDir: string): string {\n\treturn join(agentDir, \"cache\");\n}\n\n/** `<agentDir>/cache/<segments…>` */\nexport function cacheFile(agentDir: string, ...segments: string[]): string {\n\treturn join(cacheDir(agentDir), ...segments);\n}\n\n/** `<agentDir>/cache/extensions/<namespace>` -- rebuildable cache owned by one extension. */\nexport function extensionCacheDir(agentDir: string, namespace: string): string {\n\tassertPortablePathSegment(\"Extension namespace\", namespace);\n\treturn cacheFile(agentDir, \"extensions\", namespace);\n}\n\n/** `<agentDir>/bin` -- managed executable helpers (fd, rg). */\nexport function binDir(agentDir: string): string {\n\treturn join(agentDir, \"bin\");\n}\n\n/** `<agentDir>/runtimes/<kind>` -- a managed runtime install (ollama, python, prism-llamacpp, needle, …). */\nexport function runtimesDir(kind: string, agentDir: string): string {\n\treturn join(agentDir, \"runtimes\", kind);\n}\n\n/** `<agentDir>/models/<kind>` -- downloaded model weights, grouped by provider/runtime. */\nexport function modelsDir(kind: string, agentDir: string): string {\n\treturn join(agentDir, \"models\", kind);\n}\n\n/** `<agentDir>/sessions` -- session transcript storage (large, established; not a \"loose file\"). */\nexport function sessionsDir(agentDir: string): string {\n\treturn join(agentDir, \"sessions\");\n}\n\nfunction orchestrationSessionKey(parentSessionId: string): string {\n\tconst normalized = requireBoundedTrimmedText(parentSessionId, 512, \"Parent session id\");\n\tconst readable =\n\t\tencodeURIComponent(normalized)\n\t\t\t.replaceAll(\"%\", \"_\")\n\t\t\t// encodeURIComponent deliberately leaves `*` unescaped, but Windows forbids it in paths.\n\t\t\t// Restrict the readable prefix to a portable ASCII subset; the digest retains exact identity.\n\t\t\t.replaceAll(/[^a-zA-Z0-9._~-]/g, \"_\")\n\t\t\t.slice(0, 80) || \"session\";\n\tconst digest = createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n\treturn `${readable}-${digest}`;\n}\n\n/**\n * `<agentDir>/state/orchestration/sessions/<session-key>` -- the one durable control-plane\n * bundle owned by a foreground session. Event state, worker mailboxes, mutation journals, and\n * worker transcripts must stay beneath this boundary so explicit session deletion can remove\n * exactly its companion artifacts without scanning global state.\n */\nexport function orchestrationSessionsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"orchestration\", \"sessions\");\n}\n\n/**\n * `<agentDir>/state/orchestration/sessions/<session-key>` -- the one durable control-plane\n * bundle owned by a foreground session.\n */\nexport function orchestrationSessionDir(agentDir: string, parentSessionId: string): string {\n\treturn join(orchestrationSessionsDir(agentDir), orchestrationSessionKey(parentSessionId));\n}\n\n/** `<orchestrationSessionDir>/events` -- append-only event tail, snapshot, cursor, and idempotency state. */\nexport function orchestrationEventStoreDir(agentDir: string, parentSessionId: string): string {\n\treturn join(orchestrationSessionDir(agentDir, parentSessionId), \"events\");\n}\n\n/**\n * `<orchestrationSessionDir>/worker-conversations` -- durable Pi worker transcripts owned by one\n * foreground session. Worker conversations remain in SessionManager's established JSONL format,\n * but are intentionally outside the foreground session picker namespace.\n */\nexport function workerConversationSessionsDir(agentDir: string, parentSessionId: string): string {\n\treturn join(orchestrationSessionDir(agentDir, parentSessionId), \"worker-conversations\");\n}\n\n/**\n * `<orchestrationSessionDir>/worker-mailboxes/<scope-digest>.json` -- durable bounded control\n * messages for one logical worker. Identity stays hashed so neither agent ids nor project paths\n * become path segments.\n */\nexport function workerAgentMailboxFile(agentDir: string, parentSessionId: string, scopeDigest: string): string {\n\tif (!/^[a-f0-9]{32,64}$/i.test(scopeDigest)) {\n\t\tthrow new TypeError(\"Worker agent mailbox scope digest must be a hexadecimal SHA-256 prefix.\");\n\t}\n\treturn join(\n\t\torchestrationSessionDir(agentDir, parentSessionId),\n\t\t\"worker-mailboxes\",\n\t\t`${scopeDigest.toLowerCase()}.json`,\n\t);\n}\n\n/**\n * `<orchestrationSessionDir>/worker-actions/<scope-digest>.json` -- durable, bounded mutation\n * intents and receipts for one fenced worker attempt. The opaque digest intentionally keeps task\n * identifiers out of filesystem path segments and works on Windows and WSL.\n */\nexport function workerActionJournalFile(agentDir: string, parentSessionId: string, scopeDigest: string): string {\n\tif (!/^[a-f0-9]{32,64}$/i.test(scopeDigest)) {\n\t\tthrow new TypeError(\"Worker action journal scope digest must be a hexadecimal SHA-256 prefix.\");\n\t}\n\treturn join(\n\t\torchestrationSessionDir(agentDir, parentSessionId),\n\t\t\"worker-actions\",\n\t\t`${scopeDigest.toLowerCase()}.json`,\n\t);\n}\n\n/** `<agentDir>/npm` -- managed npm package installs. */\nexport function npmDir(agentDir: string): string {\n\treturn join(agentDir, \"npm\");\n}\n\n/**\n * `<agentDir>/worktrees` -- lane worktree checkouts for the worktree-sync subsystem\n * (`core/worktree-sync/`), grouped as `worktrees/<repo-slug>/<laneKey>`. These hold REAL\n * uncommitted agent work, so they are durable like `state/` -- never under transient `work/`,\n * whose retention would silently eat in-progress code.\n */\nexport function worktreesDir(agentDir: string): string {\n\treturn join(agentDir, \"worktrees\");\n}\n\n/** `<agentDir>/git` -- managed git-sourced package installs. */\nexport function gitDir(agentDir: string): string {\n\treturn join(agentDir, \"git\");\n}\n\nexport type AgentResourceKind = \"skills\" | \"prompts\" | \"themes\" | \"extensions\" | \"profiles\";\n\n/** `<agentDir>/<kind>` -- a user-managed resource directory. Root, kept: moving it breaks users. */\nexport function resourceDir(kind: AgentResourceKind, agentDir: string): string {\n\treturn join(agentDir, kind);\n}\n\n/** `<agentDir>/profiles/directories` -- durable per-directory resource-profile overlays. */\nexport function directoryProfilesDir(agentDir: string): string {\n\treturn join(resourceDir(\"profiles\", agentDir), \"directories\");\n}\n\n/**\n * `work/` is a mature transient/scratch root with its own tenant/run/lease/retention machinery\n * (`utils/work-directory.ts`). The SSOT delegates to it wholesale instead of reimplementing -- these\n * are straight re-exports so every category (state/cache/work/runtimes/models/…) is reachable from one\n * module without duplicating `work-directory.ts`'s logic.\n */\nexport {\n\tgetWorkRoot,\n\tassertPortablePathSegment,\n\tboundedWorkRetention,\n\tgetWorkTenantDir,\n\tgetWorkRunDir,\n\tgetProcessWorkRun,\n\thasActiveWorkRunLease,\n\tacquireWorkRun,\n\tcreateWorkRunId,\n\tpruneWorkTenant,\n};\nexport type { AcquireWorkRunOptions, WorkRetentionOptions, WorkRunLease } from \"../utils/work-directory.ts\";\n\n/**\n * `work/reload-coordination` -- cross-process reload/live-op coordination state. Already correctly\n * work-scoped (defined in `reload-blockers.ts`, its natural home given the surrounding reload-gate\n * logic there); re-exported here under the taxonomy's canonical name for SSOT discoverability.\n */\nexport const reloadCoordinationDir = getReloadCoordinationDir;\n"]}
|
package/dist/core/agent-paths.js
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
* including context/sessions/<session-id>/{gc,artifacts} -- re-exported below
|
|
20
20
|
* runtimes/<kind> models/<kind> -- runtimesDir/modelsDir
|
|
21
21
|
* npm/ git/ sessions/ -- npmDir/gitDir/sessionsDir
|
|
22
|
+
* state/orchestration/sessions/<session-key>/ -- one foreground-session-owned
|
|
23
|
+
* control-plane bundle
|
|
22
24
|
* worktrees/<repo-slug>/<laneKey> durable lane checkouts (core/worktree-sync) -- worktreesDir
|
|
23
25
|
* ```
|
|
24
26
|
*
|
|
@@ -34,9 +36,11 @@
|
|
|
34
36
|
* `mkdirSync(dirname(filePath), { recursive: true })`), so duplicating that here would be redundant
|
|
35
37
|
* and would blur the "pure function" contract readers rely on.
|
|
36
38
|
*/
|
|
39
|
+
import { createHash } from "node:crypto";
|
|
37
40
|
import { join } from "node:path";
|
|
38
41
|
import { acquireWorkRun, assertPortablePathSegment, boundedWorkRetention, createWorkRunId, getProcessWorkRun, getWorkRoot, getWorkRunDir, getWorkTenantDir, hasActiveWorkRunLease, pruneWorkTenant, } from "../utils/work-directory.js";
|
|
39
42
|
import { getReloadCoordinationDir } from "./reload-blockers.js";
|
|
43
|
+
import { requireBoundedTrimmedText } from "./util/bounded-value.js";
|
|
40
44
|
/** Root entries reserved for user-authored configuration and memory. */
|
|
41
45
|
export const AGENT_ROOT_FILE_NAMES = [
|
|
42
46
|
"auth.json",
|
|
@@ -141,6 +145,67 @@ export function modelsDir(kind, agentDir) {
|
|
|
141
145
|
export function sessionsDir(agentDir) {
|
|
142
146
|
return join(agentDir, "sessions");
|
|
143
147
|
}
|
|
148
|
+
function orchestrationSessionKey(parentSessionId) {
|
|
149
|
+
const normalized = requireBoundedTrimmedText(parentSessionId, 512, "Parent session id");
|
|
150
|
+
const readable = encodeURIComponent(normalized)
|
|
151
|
+
.replaceAll("%", "_")
|
|
152
|
+
// encodeURIComponent deliberately leaves `*` unescaped, but Windows forbids it in paths.
|
|
153
|
+
// Restrict the readable prefix to a portable ASCII subset; the digest retains exact identity.
|
|
154
|
+
.replaceAll(/[^a-zA-Z0-9._~-]/g, "_")
|
|
155
|
+
.slice(0, 80) || "session";
|
|
156
|
+
const digest = createHash("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
157
|
+
return `${readable}-${digest}`;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* `<agentDir>/state/orchestration/sessions/<session-key>` -- the one durable control-plane
|
|
161
|
+
* bundle owned by a foreground session. Event state, worker mailboxes, mutation journals, and
|
|
162
|
+
* worker transcripts must stay beneath this boundary so explicit session deletion can remove
|
|
163
|
+
* exactly its companion artifacts without scanning global state.
|
|
164
|
+
*/
|
|
165
|
+
export function orchestrationSessionsDir(agentDir) {
|
|
166
|
+
return stateFile(agentDir, "orchestration", "sessions");
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* `<agentDir>/state/orchestration/sessions/<session-key>` -- the one durable control-plane
|
|
170
|
+
* bundle owned by a foreground session.
|
|
171
|
+
*/
|
|
172
|
+
export function orchestrationSessionDir(agentDir, parentSessionId) {
|
|
173
|
+
return join(orchestrationSessionsDir(agentDir), orchestrationSessionKey(parentSessionId));
|
|
174
|
+
}
|
|
175
|
+
/** `<orchestrationSessionDir>/events` -- append-only event tail, snapshot, cursor, and idempotency state. */
|
|
176
|
+
export function orchestrationEventStoreDir(agentDir, parentSessionId) {
|
|
177
|
+
return join(orchestrationSessionDir(agentDir, parentSessionId), "events");
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* `<orchestrationSessionDir>/worker-conversations` -- durable Pi worker transcripts owned by one
|
|
181
|
+
* foreground session. Worker conversations remain in SessionManager's established JSONL format,
|
|
182
|
+
* but are intentionally outside the foreground session picker namespace.
|
|
183
|
+
*/
|
|
184
|
+
export function workerConversationSessionsDir(agentDir, parentSessionId) {
|
|
185
|
+
return join(orchestrationSessionDir(agentDir, parentSessionId), "worker-conversations");
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* `<orchestrationSessionDir>/worker-mailboxes/<scope-digest>.json` -- durable bounded control
|
|
189
|
+
* messages for one logical worker. Identity stays hashed so neither agent ids nor project paths
|
|
190
|
+
* become path segments.
|
|
191
|
+
*/
|
|
192
|
+
export function workerAgentMailboxFile(agentDir, parentSessionId, scopeDigest) {
|
|
193
|
+
if (!/^[a-f0-9]{32,64}$/i.test(scopeDigest)) {
|
|
194
|
+
throw new TypeError("Worker agent mailbox scope digest must be a hexadecimal SHA-256 prefix.");
|
|
195
|
+
}
|
|
196
|
+
return join(orchestrationSessionDir(agentDir, parentSessionId), "worker-mailboxes", `${scopeDigest.toLowerCase()}.json`);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* `<orchestrationSessionDir>/worker-actions/<scope-digest>.json` -- durable, bounded mutation
|
|
200
|
+
* intents and receipts for one fenced worker attempt. The opaque digest intentionally keeps task
|
|
201
|
+
* identifiers out of filesystem path segments and works on Windows and WSL.
|
|
202
|
+
*/
|
|
203
|
+
export function workerActionJournalFile(agentDir, parentSessionId, scopeDigest) {
|
|
204
|
+
if (!/^[a-f0-9]{32,64}$/i.test(scopeDigest)) {
|
|
205
|
+
throw new TypeError("Worker action journal scope digest must be a hexadecimal SHA-256 prefix.");
|
|
206
|
+
}
|
|
207
|
+
return join(orchestrationSessionDir(agentDir, parentSessionId), "worker-actions", `${scopeDigest.toLowerCase()}.json`);
|
|
208
|
+
}
|
|
144
209
|
/** `<agentDir>/npm` -- managed npm package installs. */
|
|
145
210
|
export function npmDir(agentDir) {
|
|
146
211
|
return join(agentDir, "npm");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-paths.js","sourceRoot":"","sources":["../../src/core/agent-paths.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Typed path SSOT for everything machine-managed under `<agentDir>` (`~/.pi/agent/` by default,\n * `getAgentDir()` in `../config.ts`). Every writer that persists machine data (stores, caches, managed\n * runtimes/models, cross-process coordination) MUST resolve its path through one of the accessors\n * below instead of hand-rolling `join(agentDir, …)` — that ad-hoc pattern is exactly how root-level\n * stragglers like `trust.json` accumulated, and nothing stopped the next writer from doing it again.\n *\n * Canonical layout:\n * ```\n * <agentDir>/\n * auth.json settings.json models.json keybindings.json MEMORY.md USER.md SYSTEM.md … user CONFIG/MEMORY (root, kept)\n * okf-memory/ authored memory (root, kept)\n * skills/ extensions/ prompts/ themes/ profiles/ user RESOURCES (root, kept)\n * profiles/directories/<workspace-hash>/settings.json directory overlays\n * state/ durable machine state (model adaptation/fitness, tool performance,\n * learning observations, trust decisions, config backups, …) -- stateDir/stateFile\n * cache/ rebuildable, safe to delete (tool-path probes, jiti transform cache, uv) -- cacheDir/cacheFile\n * work/ transient/scratch, delegated to work-directory.ts (tenant/run/lease),\n * including context/sessions/<session-id>/{gc,artifacts} -- re-exported below\n * runtimes/<kind> models/<kind> -- runtimesDir/modelsDir\n * npm/ git/ sessions/ -- npmDir/gitDir/sessionsDir\n * worktrees/<repo-slug>/<laneKey> durable lane checkouts (core/worktree-sync) -- worktreesDir\n * ```\n *\n * Every accessor takes `agentDir` as an explicit, required first argument -- deliberately mirroring\n * `work-directory.ts`'s existing `getWorkRoot(agentDir)` convention rather than defaulting to\n * `getAgentDir()` internally. Several real callers (stores' `forAgentDir`, test harnesses with a temp\n * agentDir) build paths for a NON-default agentDir; a hidden default would silently resolve the wrong\n * root for those callers instead of failing loudly. Callers operating on the process-wide default pass\n * `getAgentDir()` explicitly at the call site.\n *\n * These accessors are pure path builders -- no directory creation, no I/O. Every existing writer\n * already creates its parent directory at write time (see `util/atomic-file.ts`'s\n * `mkdirSync(dirname(filePath), { recursive: true })`), so duplicating that here would be redundant\n * and would blur the \"pure function\" contract readers rely on.\n */\nimport { join } from \"node:path\";\nimport {\n\tacquireWorkRun,\n\tassertPortablePathSegment,\n\tboundedWorkRetention,\n\tcreateWorkRunId,\n\tgetProcessWorkRun,\n\tgetWorkRoot,\n\tgetWorkRunDir,\n\tgetWorkTenantDir,\n\thasActiveWorkRunLease,\n\tpruneWorkTenant,\n} from \"../utils/work-directory.ts\";\nimport { getReloadCoordinationDir } from \"./reload-blockers.ts\";\n\n/** Root entries reserved for user-authored configuration and memory. */\nexport const AGENT_ROOT_FILE_NAMES = [\n\t\"auth.json\",\n\t\"settings.json\",\n\t\"models.json\",\n\t\"keybindings.json\",\n\t\"MEMORY.md\",\n\t\"USER.md\",\n\t\"SYSTEM.md\",\n\t\"APPEND_SYSTEM.md\",\n] as const;\n\n/** Root entries reserved for user resources and machine-managed storage classes. */\nexport const AGENT_ROOT_DIRECTORY_NAMES = [\n\t\"okf-memory\",\n\t\"skills\",\n\t\"extensions\",\n\t\"prompts\",\n\t\"themes\",\n\t\"profiles\",\n\t\"state\",\n\t\"cache\",\n\t\"bin\",\n\t\"work\",\n\t\"runtimes\",\n\t\"models\",\n\t\"sessions\",\n\t\"npm\",\n\t\"git\",\n\t\"worktrees\",\n] as const;\n\nconst AGENT_ROOT_ENTRY_NAMES = new Set<string>([...AGENT_ROOT_FILE_NAMES, ...AGENT_ROOT_DIRECTORY_NAMES]);\n\nexport function isCanonicalAgentRootEntry(name: string): boolean {\n\treturn AGENT_ROOT_ENTRY_NAMES.has(name);\n}\n\n/** `<agentDir>/<name>` -- a root-level user config/memory file (auth.json, settings.json, MEMORY.md, …). */\nexport function configFile(agentDir: string, name: string): string {\n\treturn join(agentDir, name);\n}\n\n/** `<agentDir>/okf-memory` -- user-authored durable OKF memory documents. */\nexport function okfMemoryDir(agentDir: string): string {\n\treturn join(agentDir, \"okf-memory\");\n}\n\n/** `<agentDir>/state` -- durable machine-managed state. Deleting it loses real history, not just cache. */\nexport function stateDir(agentDir: string): string {\n\treturn join(agentDir, \"state\");\n}\n\n/** `<agentDir>/state/<segments…>` */\nexport function stateFile(agentDir: string, ...segments: string[]): string {\n\treturn join(stateDir(agentDir), ...segments);\n}\n\n/** `<agentDir>/state/attachments` -- bounded, session-keyed clipboard image attachments. */\nexport function attachmentsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"attachments\");\n}\n\n/** `<agentDir>/state/secrets` -- encrypted credential vault and owner-approved materializations. */\nexport function secretsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"secrets\");\n}\n\n/** `<agentDir>/state/secrets/vault.json` -- encrypted, versioned generic credential vault. */\nexport function secretVaultFile(agentDir: string): string {\n\treturn join(secretsDir(agentDir), \"vault.json\");\n}\n\n/** `<agentDir>/state/secrets/materialized` -- private generated dotenv files, grouped by profile. */\nexport function managedSecretEnvDir(agentDir: string): string {\n\treturn join(secretsDir(agentDir), \"materialized\");\n}\n\n/** `<agentDir>/state/extensions/<namespace>` -- durable state owned by one extension. */\nexport function extensionStateDir(agentDir: string, namespace: string): string {\n\tassertPortablePathSegment(\"Extension namespace\", namespace);\n\treturn stateFile(agentDir, \"extensions\", namespace);\n}\n\n/** `<agentDir>/state/backups/config` -- explicit user-requested configuration snapshots. */\nexport function configBackupsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"backups\", \"config\");\n}\n\n/** `<agentDir>/cache` -- rebuildable; safe to delete (the next run just re-probes/recomputes). */\nexport function cacheDir(agentDir: string): string {\n\treturn join(agentDir, \"cache\");\n}\n\n/** `<agentDir>/cache/<segments…>` */\nexport function cacheFile(agentDir: string, ...segments: string[]): string {\n\treturn join(cacheDir(agentDir), ...segments);\n}\n\n/** `<agentDir>/cache/extensions/<namespace>` -- rebuildable cache owned by one extension. */\nexport function extensionCacheDir(agentDir: string, namespace: string): string {\n\tassertPortablePathSegment(\"Extension namespace\", namespace);\n\treturn cacheFile(agentDir, \"extensions\", namespace);\n}\n\n/** `<agentDir>/bin` -- managed executable helpers (fd, rg). */\nexport function binDir(agentDir: string): string {\n\treturn join(agentDir, \"bin\");\n}\n\n/** `<agentDir>/runtimes/<kind>` -- a managed runtime install (ollama, python, prism-llamacpp, needle, …). */\nexport function runtimesDir(kind: string, agentDir: string): string {\n\treturn join(agentDir, \"runtimes\", kind);\n}\n\n/** `<agentDir>/models/<kind>` -- downloaded model weights, grouped by provider/runtime. */\nexport function modelsDir(kind: string, agentDir: string): string {\n\treturn join(agentDir, \"models\", kind);\n}\n\n/** `<agentDir>/sessions` -- session transcript storage (large, established; not a \"loose file\"). */\nexport function sessionsDir(agentDir: string): string {\n\treturn join(agentDir, \"sessions\");\n}\n\n/** `<agentDir>/npm` -- managed npm package installs. */\nexport function npmDir(agentDir: string): string {\n\treturn join(agentDir, \"npm\");\n}\n\n/**\n * `<agentDir>/worktrees` -- lane worktree checkouts for the worktree-sync subsystem\n * (`core/worktree-sync/`), grouped as `worktrees/<repo-slug>/<laneKey>`. These hold REAL\n * uncommitted agent work, so they are durable like `state/` -- never under transient `work/`,\n * whose retention would silently eat in-progress code.\n */\nexport function worktreesDir(agentDir: string): string {\n\treturn join(agentDir, \"worktrees\");\n}\n\n/** `<agentDir>/git` -- managed git-sourced package installs. */\nexport function gitDir(agentDir: string): string {\n\treturn join(agentDir, \"git\");\n}\n\nexport type AgentResourceKind = \"skills\" | \"prompts\" | \"themes\" | \"extensions\" | \"profiles\";\n\n/** `<agentDir>/<kind>` -- a user-managed resource directory. Root, kept: moving it breaks users. */\nexport function resourceDir(kind: AgentResourceKind, agentDir: string): string {\n\treturn join(agentDir, kind);\n}\n\n/** `<agentDir>/profiles/directories` -- durable per-directory resource-profile overlays. */\nexport function directoryProfilesDir(agentDir: string): string {\n\treturn join(resourceDir(\"profiles\", agentDir), \"directories\");\n}\n\n/**\n * `work/` is a mature transient/scratch root with its own tenant/run/lease/retention machinery\n * (`utils/work-directory.ts`). The SSOT delegates to it wholesale instead of reimplementing -- these\n * are straight re-exports so every category (state/cache/work/runtimes/models/…) is reachable from one\n * module without duplicating `work-directory.ts`'s logic.\n */\nexport {\n\tgetWorkRoot,\n\tassertPortablePathSegment,\n\tboundedWorkRetention,\n\tgetWorkTenantDir,\n\tgetWorkRunDir,\n\tgetProcessWorkRun,\n\thasActiveWorkRunLease,\n\tacquireWorkRun,\n\tcreateWorkRunId,\n\tpruneWorkTenant,\n};\nexport type { AcquireWorkRunOptions, WorkRetentionOptions, WorkRunLease } from \"../utils/work-directory.ts\";\n\n/**\n * `work/reload-coordination` -- cross-process reload/live-op coordination state. Already correctly\n * work-scoped (defined in `reload-blockers.ts`, its natural home given the surrounding reload-gate\n * logic there); re-exported here under the taxonomy's canonical name for SSOT discoverability.\n */\nexport const reloadCoordinationDir = getReloadCoordinationDir;\n"]}
|
|
1
|
+
{"version":3,"file":"agent-paths.js","sourceRoot":"","sources":["../../src/core/agent-paths.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Typed path SSOT for everything machine-managed under `<agentDir>` (`~/.pi/agent/` by default,\n * `getAgentDir()` in `../config.ts`). Every writer that persists machine data (stores, caches, managed\n * runtimes/models, cross-process coordination) MUST resolve its path through one of the accessors\n * below instead of hand-rolling `join(agentDir, …)` — that ad-hoc pattern is exactly how root-level\n * stragglers like `trust.json` accumulated, and nothing stopped the next writer from doing it again.\n *\n * Canonical layout:\n * ```\n * <agentDir>/\n * auth.json settings.json models.json keybindings.json MEMORY.md USER.md SYSTEM.md … user CONFIG/MEMORY (root, kept)\n * okf-memory/ authored memory (root, kept)\n * skills/ extensions/ prompts/ themes/ profiles/ user RESOURCES (root, kept)\n * profiles/directories/<workspace-hash>/settings.json directory overlays\n * state/ durable machine state (model adaptation/fitness, tool performance,\n * learning observations, trust decisions, config backups, …) -- stateDir/stateFile\n * cache/ rebuildable, safe to delete (tool-path probes, jiti transform cache, uv) -- cacheDir/cacheFile\n * work/ transient/scratch, delegated to work-directory.ts (tenant/run/lease),\n * including context/sessions/<session-id>/{gc,artifacts} -- re-exported below\n * runtimes/<kind> models/<kind> -- runtimesDir/modelsDir\n * npm/ git/ sessions/ -- npmDir/gitDir/sessionsDir\n * state/orchestration/sessions/<session-key>/ -- one foreground-session-owned\n * control-plane bundle\n * worktrees/<repo-slug>/<laneKey> durable lane checkouts (core/worktree-sync) -- worktreesDir\n * ```\n *\n * Every accessor takes `agentDir` as an explicit, required first argument -- deliberately mirroring\n * `work-directory.ts`'s existing `getWorkRoot(agentDir)` convention rather than defaulting to\n * `getAgentDir()` internally. Several real callers (stores' `forAgentDir`, test harnesses with a temp\n * agentDir) build paths for a NON-default agentDir; a hidden default would silently resolve the wrong\n * root for those callers instead of failing loudly. Callers operating on the process-wide default pass\n * `getAgentDir()` explicitly at the call site.\n *\n * These accessors are pure path builders -- no directory creation, no I/O. Every existing writer\n * already creates its parent directory at write time (see `util/atomic-file.ts`'s\n * `mkdirSync(dirname(filePath), { recursive: true })`), so duplicating that here would be redundant\n * and would blur the \"pure function\" contract readers rely on.\n */\nimport { createHash } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tacquireWorkRun,\n\tassertPortablePathSegment,\n\tboundedWorkRetention,\n\tcreateWorkRunId,\n\tgetProcessWorkRun,\n\tgetWorkRoot,\n\tgetWorkRunDir,\n\tgetWorkTenantDir,\n\thasActiveWorkRunLease,\n\tpruneWorkTenant,\n} from \"../utils/work-directory.ts\";\nimport { getReloadCoordinationDir } from \"./reload-blockers.ts\";\nimport { requireBoundedTrimmedText } from \"./util/bounded-value.ts\";\n\n/** Root entries reserved for user-authored configuration and memory. */\nexport const AGENT_ROOT_FILE_NAMES = [\n\t\"auth.json\",\n\t\"settings.json\",\n\t\"models.json\",\n\t\"keybindings.json\",\n\t\"MEMORY.md\",\n\t\"USER.md\",\n\t\"SYSTEM.md\",\n\t\"APPEND_SYSTEM.md\",\n] as const;\n\n/** Root entries reserved for user resources and machine-managed storage classes. */\nexport const AGENT_ROOT_DIRECTORY_NAMES = [\n\t\"okf-memory\",\n\t\"skills\",\n\t\"extensions\",\n\t\"prompts\",\n\t\"themes\",\n\t\"profiles\",\n\t\"state\",\n\t\"cache\",\n\t\"bin\",\n\t\"work\",\n\t\"runtimes\",\n\t\"models\",\n\t\"sessions\",\n\t\"npm\",\n\t\"git\",\n\t\"worktrees\",\n] as const;\n\nconst AGENT_ROOT_ENTRY_NAMES = new Set<string>([...AGENT_ROOT_FILE_NAMES, ...AGENT_ROOT_DIRECTORY_NAMES]);\n\nexport function isCanonicalAgentRootEntry(name: string): boolean {\n\treturn AGENT_ROOT_ENTRY_NAMES.has(name);\n}\n\n/** `<agentDir>/<name>` -- a root-level user config/memory file (auth.json, settings.json, MEMORY.md, …). */\nexport function configFile(agentDir: string, name: string): string {\n\treturn join(agentDir, name);\n}\n\n/** `<agentDir>/okf-memory` -- user-authored durable OKF memory documents. */\nexport function okfMemoryDir(agentDir: string): string {\n\treturn join(agentDir, \"okf-memory\");\n}\n\n/** `<agentDir>/state` -- durable machine-managed state. Deleting it loses real history, not just cache. */\nexport function stateDir(agentDir: string): string {\n\treturn join(agentDir, \"state\");\n}\n\n/** `<agentDir>/state/<segments…>` */\nexport function stateFile(agentDir: string, ...segments: string[]): string {\n\treturn join(stateDir(agentDir), ...segments);\n}\n\n/** `<agentDir>/state/attachments` -- bounded, session-keyed clipboard image attachments. */\nexport function attachmentsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"attachments\");\n}\n\n/** `<agentDir>/state/secrets` -- encrypted credential vault and owner-approved materializations. */\nexport function secretsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"secrets\");\n}\n\n/** `<agentDir>/state/secrets/vault.json` -- encrypted, versioned generic credential vault. */\nexport function secretVaultFile(agentDir: string): string {\n\treturn join(secretsDir(agentDir), \"vault.json\");\n}\n\n/** `<agentDir>/state/secrets/materialized` -- private generated dotenv files, grouped by profile. */\nexport function managedSecretEnvDir(agentDir: string): string {\n\treturn join(secretsDir(agentDir), \"materialized\");\n}\n\n/** `<agentDir>/state/extensions/<namespace>` -- durable state owned by one extension. */\nexport function extensionStateDir(agentDir: string, namespace: string): string {\n\tassertPortablePathSegment(\"Extension namespace\", namespace);\n\treturn stateFile(agentDir, \"extensions\", namespace);\n}\n\n/** `<agentDir>/state/backups/config` -- explicit user-requested configuration snapshots. */\nexport function configBackupsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"backups\", \"config\");\n}\n\n/** `<agentDir>/cache` -- rebuildable; safe to delete (the next run just re-probes/recomputes). */\nexport function cacheDir(agentDir: string): string {\n\treturn join(agentDir, \"cache\");\n}\n\n/** `<agentDir>/cache/<segments…>` */\nexport function cacheFile(agentDir: string, ...segments: string[]): string {\n\treturn join(cacheDir(agentDir), ...segments);\n}\n\n/** `<agentDir>/cache/extensions/<namespace>` -- rebuildable cache owned by one extension. */\nexport function extensionCacheDir(agentDir: string, namespace: string): string {\n\tassertPortablePathSegment(\"Extension namespace\", namespace);\n\treturn cacheFile(agentDir, \"extensions\", namespace);\n}\n\n/** `<agentDir>/bin` -- managed executable helpers (fd, rg). */\nexport function binDir(agentDir: string): string {\n\treturn join(agentDir, \"bin\");\n}\n\n/** `<agentDir>/runtimes/<kind>` -- a managed runtime install (ollama, python, prism-llamacpp, needle, …). */\nexport function runtimesDir(kind: string, agentDir: string): string {\n\treturn join(agentDir, \"runtimes\", kind);\n}\n\n/** `<agentDir>/models/<kind>` -- downloaded model weights, grouped by provider/runtime. */\nexport function modelsDir(kind: string, agentDir: string): string {\n\treturn join(agentDir, \"models\", kind);\n}\n\n/** `<agentDir>/sessions` -- session transcript storage (large, established; not a \"loose file\"). */\nexport function sessionsDir(agentDir: string): string {\n\treturn join(agentDir, \"sessions\");\n}\n\nfunction orchestrationSessionKey(parentSessionId: string): string {\n\tconst normalized = requireBoundedTrimmedText(parentSessionId, 512, \"Parent session id\");\n\tconst readable =\n\t\tencodeURIComponent(normalized)\n\t\t\t.replaceAll(\"%\", \"_\")\n\t\t\t// encodeURIComponent deliberately leaves `*` unescaped, but Windows forbids it in paths.\n\t\t\t// Restrict the readable prefix to a portable ASCII subset; the digest retains exact identity.\n\t\t\t.replaceAll(/[^a-zA-Z0-9._~-]/g, \"_\")\n\t\t\t.slice(0, 80) || \"session\";\n\tconst digest = createHash(\"sha256\").update(normalized).digest(\"hex\").slice(0, 16);\n\treturn `${readable}-${digest}`;\n}\n\n/**\n * `<agentDir>/state/orchestration/sessions/<session-key>` -- the one durable control-plane\n * bundle owned by a foreground session. Event state, worker mailboxes, mutation journals, and\n * worker transcripts must stay beneath this boundary so explicit session deletion can remove\n * exactly its companion artifacts without scanning global state.\n */\nexport function orchestrationSessionsDir(agentDir: string): string {\n\treturn stateFile(agentDir, \"orchestration\", \"sessions\");\n}\n\n/**\n * `<agentDir>/state/orchestration/sessions/<session-key>` -- the one durable control-plane\n * bundle owned by a foreground session.\n */\nexport function orchestrationSessionDir(agentDir: string, parentSessionId: string): string {\n\treturn join(orchestrationSessionsDir(agentDir), orchestrationSessionKey(parentSessionId));\n}\n\n/** `<orchestrationSessionDir>/events` -- append-only event tail, snapshot, cursor, and idempotency state. */\nexport function orchestrationEventStoreDir(agentDir: string, parentSessionId: string): string {\n\treturn join(orchestrationSessionDir(agentDir, parentSessionId), \"events\");\n}\n\n/**\n * `<orchestrationSessionDir>/worker-conversations` -- durable Pi worker transcripts owned by one\n * foreground session. Worker conversations remain in SessionManager's established JSONL format,\n * but are intentionally outside the foreground session picker namespace.\n */\nexport function workerConversationSessionsDir(agentDir: string, parentSessionId: string): string {\n\treturn join(orchestrationSessionDir(agentDir, parentSessionId), \"worker-conversations\");\n}\n\n/**\n * `<orchestrationSessionDir>/worker-mailboxes/<scope-digest>.json` -- durable bounded control\n * messages for one logical worker. Identity stays hashed so neither agent ids nor project paths\n * become path segments.\n */\nexport function workerAgentMailboxFile(agentDir: string, parentSessionId: string, scopeDigest: string): string {\n\tif (!/^[a-f0-9]{32,64}$/i.test(scopeDigest)) {\n\t\tthrow new TypeError(\"Worker agent mailbox scope digest must be a hexadecimal SHA-256 prefix.\");\n\t}\n\treturn join(\n\t\torchestrationSessionDir(agentDir, parentSessionId),\n\t\t\"worker-mailboxes\",\n\t\t`${scopeDigest.toLowerCase()}.json`,\n\t);\n}\n\n/**\n * `<orchestrationSessionDir>/worker-actions/<scope-digest>.json` -- durable, bounded mutation\n * intents and receipts for one fenced worker attempt. The opaque digest intentionally keeps task\n * identifiers out of filesystem path segments and works on Windows and WSL.\n */\nexport function workerActionJournalFile(agentDir: string, parentSessionId: string, scopeDigest: string): string {\n\tif (!/^[a-f0-9]{32,64}$/i.test(scopeDigest)) {\n\t\tthrow new TypeError(\"Worker action journal scope digest must be a hexadecimal SHA-256 prefix.\");\n\t}\n\treturn join(\n\t\torchestrationSessionDir(agentDir, parentSessionId),\n\t\t\"worker-actions\",\n\t\t`${scopeDigest.toLowerCase()}.json`,\n\t);\n}\n\n/** `<agentDir>/npm` -- managed npm package installs. */\nexport function npmDir(agentDir: string): string {\n\treturn join(agentDir, \"npm\");\n}\n\n/**\n * `<agentDir>/worktrees` -- lane worktree checkouts for the worktree-sync subsystem\n * (`core/worktree-sync/`), grouped as `worktrees/<repo-slug>/<laneKey>`. These hold REAL\n * uncommitted agent work, so they are durable like `state/` -- never under transient `work/`,\n * whose retention would silently eat in-progress code.\n */\nexport function worktreesDir(agentDir: string): string {\n\treturn join(agentDir, \"worktrees\");\n}\n\n/** `<agentDir>/git` -- managed git-sourced package installs. */\nexport function gitDir(agentDir: string): string {\n\treturn join(agentDir, \"git\");\n}\n\nexport type AgentResourceKind = \"skills\" | \"prompts\" | \"themes\" | \"extensions\" | \"profiles\";\n\n/** `<agentDir>/<kind>` -- a user-managed resource directory. Root, kept: moving it breaks users. */\nexport function resourceDir(kind: AgentResourceKind, agentDir: string): string {\n\treturn join(agentDir, kind);\n}\n\n/** `<agentDir>/profiles/directories` -- durable per-directory resource-profile overlays. */\nexport function directoryProfilesDir(agentDir: string): string {\n\treturn join(resourceDir(\"profiles\", agentDir), \"directories\");\n}\n\n/**\n * `work/` is a mature transient/scratch root with its own tenant/run/lease/retention machinery\n * (`utils/work-directory.ts`). The SSOT delegates to it wholesale instead of reimplementing -- these\n * are straight re-exports so every category (state/cache/work/runtimes/models/…) is reachable from one\n * module without duplicating `work-directory.ts`'s logic.\n */\nexport {\n\tgetWorkRoot,\n\tassertPortablePathSegment,\n\tboundedWorkRetention,\n\tgetWorkTenantDir,\n\tgetWorkRunDir,\n\tgetProcessWorkRun,\n\thasActiveWorkRunLease,\n\tacquireWorkRun,\n\tcreateWorkRunId,\n\tpruneWorkTenant,\n};\nexport type { AcquireWorkRunOptions, WorkRetentionOptions, WorkRunLease } from \"../utils/work-directory.ts\";\n\n/**\n * `work/reload-coordination` -- cross-process reload/live-op coordination state. Already correctly\n * work-scoped (defined in `reload-blockers.ts`, its natural home given the surrounding reload-gate\n * logic there); re-exported here under the taxonomy's canonical name for SSOT discoverability.\n */\nexport const reloadCoordinationDir = getReloadCoordinationDir;\n"]}
|
|
@@ -225,8 +225,10 @@ export interface SpawnedUsageTotals {
|
|
|
225
225
|
}
|
|
226
226
|
export interface IsolatedCompletionOptions {
|
|
227
227
|
systemPrompt: string;
|
|
228
|
-
/**
|
|
228
|
+
/** New child-owned prompt messages for this call; foreground session history is never inherited. */
|
|
229
229
|
messages: Message[];
|
|
230
|
+
/** Previously persisted child history. Omission preserves fresh one-shot behavior. */
|
|
231
|
+
history?: Message[];
|
|
230
232
|
model?: Model<Api>;
|
|
231
233
|
thinkingLevel?: ThinkingLevel;
|
|
232
234
|
maxTokens?: number;
|
|
@@ -240,6 +242,20 @@ export interface IsolatedCompletionOptions {
|
|
|
240
242
|
beforeToolCall?: AgentLoopConfig["beforeToolCall"];
|
|
241
243
|
/** Child-only result observer. */
|
|
242
244
|
afterToolCall?: AgentLoopConfig["afterToolCall"];
|
|
245
|
+
/**
|
|
246
|
+
* Durable child transcript sink. Message-end ordering means an assistant tool request is recorded
|
|
247
|
+
* before execution starts and each tool result is recorded before the next provider request.
|
|
248
|
+
* Throwing aborts the child loop; continuing without durable history would make replay unsafe.
|
|
249
|
+
*/
|
|
250
|
+
onMessage?: (message: Message) => Promise<void> | void;
|
|
251
|
+
/** Durable mid-run steering inbox owned by the child conversation. */
|
|
252
|
+
getSteeringMessages?: AgentLoopConfig["getSteeringMessages"];
|
|
253
|
+
/** Durable post-turn follow-up inbox owned by the child conversation. */
|
|
254
|
+
getFollowUpMessages?: AgentLoopConfig["getFollowUpMessages"];
|
|
255
|
+
/** Child-owned provider projection, invoked before every request without mutating raw history. */
|
|
256
|
+
transformContext?: AgentLoopConfig["transformContext"];
|
|
257
|
+
/** Request-local budget/authority check, invoked immediately before every child provider transport. */
|
|
258
|
+
requestPreflight?: AgentLoopConfig["requestPreflight"];
|
|
243
259
|
signal?: AbortSignal;
|
|
244
260
|
/** Required cache policy; isolated calls never inherit a provider default implicitly. */
|
|
245
261
|
cacheRetention: CacheRetention;
|
|
@@ -252,6 +268,8 @@ export interface IsolatedCompletionResult {
|
|
|
252
268
|
text: string;
|
|
253
269
|
usage: Usage;
|
|
254
270
|
stopReason: StopReason;
|
|
271
|
+
/** Complete child-owned conversation; isolated calls never expose foreground history. */
|
|
272
|
+
messages?: Message[];
|
|
255
273
|
}
|
|
256
274
|
export interface ResearchLaneRunOutcome {
|
|
257
275
|
started: boolean;
|