@gotgenes/pi-permission-system 31.0.2 → 31.1.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/CHANGELOG.md +23 -0
- package/dist/public.d.ts +15 -15
- package/docs/configuration.md +6 -2
- package/docs/cross-extension-api.md +1 -1
- package/docs/session-approvals.md +2 -2
- package/package.json +1 -1
- package/src/access-intent/access-intent.ts +1 -1
- package/src/access-intent/bash/bash-path-resolver.ts +11 -14
- package/src/access-intent/bash/command-enumeration.ts +6 -12
- package/src/access-intent/bash/msys-bash-tokens.ts +1 -1
- package/src/access-intent/bash/nested-execution.ts +1 -1
- package/src/access-intent/bash/node-text.ts +2 -2
- package/src/access-intent/bash/parser.ts +1 -1
- package/src/access-intent/bash/program.ts +4 -7
- package/src/access-intent/bash/redirect-analysis.ts +2 -2
- package/src/access-intent/bash/shell-variable-expansion.ts +1 -1
- package/src/access-intent/bash/sync-commands.ts +2 -5
- package/src/access-intent/bash/token-collection.ts +6 -9
- package/src/access-intent/bash/wrapper-analysis.ts +1 -1
- package/src/access-intent/input-normalizer.ts +2 -2
- package/src/access-intent/path-normalization.ts +1 -1
- package/src/access-intent/path-surfaces.ts +1 -1
- package/src/access-intent/tool-input-path.ts +1 -1
- package/src/access-intent/tool-kind.ts +1 -1
- package/src/authority/approval-escalator.ts +13 -13
- package/src/authority/authorizer-chain.ts +1 -1
- package/src/authority/authorizer-registry.ts +1 -1
- package/src/authority/authorizer-selection.ts +1 -1
- package/src/authority/authorizer.ts +9 -9
- package/src/authority/decision-resolution.ts +2 -5
- package/src/authority/denying-authorizer.ts +1 -1
- package/src/authority/forwarded-request-server.ts +21 -24
- package/src/authority/forwarder-context.ts +2 -2
- package/src/authority/forwarding-io.ts +14 -12
- package/src/authority/forwarding-liveness.ts +5 -8
- package/src/authority/forwarding-manager.ts +1 -1
- package/src/authority/inherited-registrations.ts +2 -2
- package/src/authority/local-user-authorizer.ts +13 -13
- package/src/authority/permission-dialog.ts +2 -2
- package/src/authority/permission-forwarding.ts +6 -3
- package/src/authority/permission-prompt-component.ts +12 -15
- package/src/authority/permission-prompt-decision.ts +2 -2
- package/src/authority/permission-prompter.ts +8 -8
- package/src/authority/subagent-context.ts +3 -3
- package/src/authority/subagent-detection.ts +3 -3
- package/src/{config-loader.ts → config/config-loader.ts} +3 -3
- package/src/{config-modal.ts → config/config-modal.ts} +1 -2
- package/src/{config-reporter.ts → config/config-reporter.ts} +1 -1
- package/src/{config-store.ts → config/config-store.ts} +1 -2
- package/src/{extension-config.ts → config/extension-config.ts} +4 -4
- package/src/{extension-paths.ts → config/extension-paths.ts} +1 -1
- package/src/{policy-loader.ts → config/policy-loader.ts} +2 -2
- package/src/{skill-prompt-sanitizer.ts → exposure/skill-prompt-sanitizer.ts} +2 -2
- package/src/{tool-registry.ts → exposure/tool-registry.ts} +1 -1
- package/src/exposure/tool-surface-baseline.ts +101 -0
- package/src/handlers/before-agent-start.ts +48 -21
- package/src/handlers/gates/bash-command.ts +2 -2
- package/src/handlers/gates/bash-external-directory.ts +3 -3
- package/src/handlers/gates/bash-path-extractor.ts +1 -1
- package/src/handlers/gates/bash-path.ts +4 -4
- package/src/handlers/gates/descriptor.ts +2 -2
- package/src/handlers/gates/external-directory-policy.ts +2 -2
- package/src/handlers/gates/external-directory.ts +4 -4
- package/src/handlers/gates/helpers.ts +1 -1
- package/src/handlers/gates/path.ts +4 -4
- package/src/handlers/gates/runner.ts +4 -4
- package/src/handlers/gates/skill-read.ts +3 -3
- package/src/handlers/gates/tool-call-gate-pipeline.ts +7 -7
- package/src/handlers/gates/tool.ts +3 -3
- package/src/handlers/lifecycle.ts +6 -7
- package/src/handlers/permission-gate-handler.ts +11 -11
- package/src/handlers/session-turn-prep.ts +1 -1
- package/src/handlers/tool-call-boundary.ts +3 -3
- package/src/index.ts +40 -39
- package/src/{decision-reporter.ts → logging/decision-reporter.ts} +1 -1
- package/src/{logging.ts → logging/logging.ts} +1 -1
- package/src/{session-logger.ts → logging/session-logger.ts} +14 -5
- package/src/path/approval-pattern.ts +1 -1
- package/src/path/canonicalize-path.ts +1 -1
- package/src/path/path-containment.ts +2 -2
- package/src/path/path-flavor.ts +1 -1
- package/src/{path-normalizer.ts → path/path-normalizer.ts} +6 -8
- package/src/path/pi-infrastructure-read.ts +3 -3
- package/src/{normalize.ts → policy/normalize.ts} +2 -2
- package/src/{permission-gate.ts → policy/permission-gate.ts} +1 -1
- package/src/{permission-manager.ts → policy/permission-manager.ts} +21 -15
- package/src/{permission-merge.ts → policy/permission-merge.ts} +1 -1
- package/src/{permission-resolver.ts → policy/permission-resolver.ts} +5 -5
- package/src/{rule.ts → policy/rule.ts} +3 -4
- package/src/{scope-merge.ts → policy/scope-merge.ts} +3 -3
- package/src/{synthesize.ts → policy/synthesize.ts} +1 -1
- package/src/{wildcard-matcher.ts → policy/wildcard-matcher.ts} +1 -1
- package/src/presentation/agent-renderer.ts +5 -5
- package/src/presentation/dialog-renderer.ts +3 -3
- package/src/presentation/fact-vocabulary.ts +1 -4
- package/src/presentation/forwarded-ask-payload.ts +1 -4
- package/src/presentation/path-ask-payload.ts +2 -5
- package/src/{pattern-suggest.ts → presentation/pattern-suggest.ts} +6 -3
- package/src/{permission-prompts.ts → presentation/permission-prompts.ts} +1 -1
- package/src/presentation/review-log-renderer.ts +1 -1
- package/src/presentation/skill-ask-payload.ts +3 -3
- package/src/presentation/tool-ask-payload.ts +3 -6
- package/src/{bash-advisory-check.ts → service/bash-advisory-check.ts} +1 -1
- package/src/{permissions-service.ts → service/permissions-service.ts} +10 -10
- package/src/{service-lifecycle.ts → service/service-lifecycle.ts} +5 -5
- package/src/service.ts +18 -18
- package/src/{permission-session.ts → session/permission-session.ts} +39 -15
- package/src/{session-approval.ts → session/session-approval.ts} +2 -2
- package/src/{session-rules.ts → session/session-rules.ts} +1 -1
- package/src/{builtin-tool-input-formatters.ts → tool-input/builtin-tool-input-formatters.ts} +1 -1
- package/src/{tool-input-preview.ts → tool-input/tool-input-preview.ts} +2 -2
- package/src/{tool-input-prompt-formatters.ts → tool-input/tool-input-prompt-formatters.ts} +1 -1
- package/src/{tool-preview-formatter.ts → tool-input/tool-preview-formatter.ts} +3 -3
- package/src/types.ts +2 -2
- /package/src/{async-cache.ts → access-intent/bash/async-cache.ts} +0 -0
- /package/src/{bash-arity.ts → access-intent/bash/bash-arity.ts} +0 -0
- /package/src/{config-paths.ts → config/config-paths.ts} +0 -0
- /package/src/{config-schema.ts → config/config-schema.ts} +0 -0
- /package/src/{status.ts → config/status.ts} +0 -0
- /package/src/{yaml-frontmatter.ts → config/yaml-frontmatter.ts} +0 -0
- /package/src/{system-prompt-sanitizer.ts → exposure/system-prompt-sanitizer.ts} +0 -0
- /package/src/{decision-audit.ts → logging/decision-audit.ts} +0 -0
- /package/src/{json-safe-stringify.ts → logging/json-safe-stringify.ts} +0 -0
- /package/src/{log-field-cap.ts → logging/log-field-cap.ts} +0 -0
- /package/src/{log-file-permissions.ts → logging/log-file-permissions.ts} +0 -0
- /package/src/{log-redaction.ts → logging/log-redaction.ts} +0 -0
- /package/src/{expand-home.ts → path/expand-home.ts} +0 -0
- /package/src/{node-modules-discovery.ts → path/node-modules-discovery.ts} +0 -0
- /package/src/{safe-system-paths.ts → path/safe-system-paths.ts} +0 -0
- /package/src/{restrictiveness.ts → policy/restrictiveness.ts} +0 -0
- /package/src/{permission-events.ts → service/permission-events.ts} +0 -0
- /package/src/{permission-ui-prompt.ts → service/permission-ui-prompt.ts} +0 -0
- /package/src/{active-agent.ts → session/active-agent.ts} +0 -0
- /package/src/{approval-grant.ts → session/approval-grant.ts} +0 -0
- /package/src/{session-approval-recorder.ts → session/session-approval-recorder.ts} +0 -0
- /package/src/{session-identity.ts → session/session-identity.ts} +0 -0
- /package/src/{tool-access-extractor-registry.ts → tool-input/tool-access-extractor-registry.ts} +0 -0
- /package/src/{tool-input-formatter-registry.ts → tool-input/tool-input-formatter-registry.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [31.1.1](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v31.1.0...pi-permission-system-v31.1.1) (2026-09-05)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
* **pi-permission-system:** record the directory vocabulary and mark Phase 14 Step 13 ([72a3c0d](https://github.com/gotgenes/pi-packages/commit/72a3c0d83eed5489874d93404f4277797e193649)), closes [#837](https://github.com/gotgenes/pi-packages/issues/837)
|
|
14
|
+
|
|
15
|
+
## [31.1.0](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v31.0.2...pi-permission-system-v31.1.0) (2026-09-04)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* **pi-permission-system:** record every change to the effective tool surface in the debug log ([bf0331a](https://github.com/gotgenes/pi-packages/commit/bf0331a26ace5dcee7f6a26064af1251fecaaa41))
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* **pi-permission-system:** restore a tool when its deny rule is relaxed mid-session ([190a25e](https://github.com/gotgenes/pi-packages/commit/190a25eccdcd5101badf6266f10142c809296983))
|
|
25
|
+
* **pi-permission-system:** forget a withheld tool that pi has unregistered ([404d819](https://github.com/gotgenes/pi-packages/commit/404d8194f9763ee8a228bd36176c5adbb944464c)), closes [#873](https://github.com/gotgenes/pi-packages/issues/873)
|
|
26
|
+
|
|
27
|
+
### Documentation
|
|
28
|
+
|
|
29
|
+
* **pi-permission-system:** document the tool-surface baseline ([0997065](https://github.com/gotgenes/pi-packages/commit/09970655c60bfe14c5a38b986301c480ed19f316))
|
|
30
|
+
|
|
8
31
|
## [31.0.2](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v31.0.1...pi-permission-system-v31.0.2) (2026-09-04)
|
|
9
32
|
|
|
10
33
|
|
package/dist/public.d.ts
CHANGED
|
@@ -1,20 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* One session-approval grant: a wildcard pattern approved on one surface.
|
|
5
|
-
*
|
|
6
|
-
* A gate proves a direction per accessed path (ADR 0013 §7), so an ask whose
|
|
7
|
-
* paths disagree records a surface per pattern rather than one for all of them
|
|
8
|
-
* (#810). This lives in its own module because both the {@link SessionApproval}
|
|
9
|
-
* value object and the forwarded wire type name it, and those two already
|
|
10
|
-
* import in one direction.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
interface ApprovalGrant {
|
|
14
|
-
readonly surface: string;
|
|
15
|
-
readonly pattern: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
3
|
declare const permissionStateSchema: z.ZodUnion<readonly [z.ZodLiteral<"allow">, z.ZodLiteral<"deny">, z.ZodLiteral<"ask">]>;
|
|
19
4
|
/** A permission decision. */
|
|
20
5
|
type PermissionState = z.infer<typeof permissionStateSchema>;
|
|
@@ -329,6 +314,21 @@ interface PermissionDecisionEvent {
|
|
|
329
314
|
forwarding?: ForwardedPromptContext | null;
|
|
330
315
|
}
|
|
331
316
|
|
|
317
|
+
/**
|
|
318
|
+
* One session-approval grant: a wildcard pattern approved on one surface.
|
|
319
|
+
*
|
|
320
|
+
* A gate proves a direction per accessed path (ADR 0013 §7), so an ask whose
|
|
321
|
+
* paths disagree records a surface per pattern rather than one for all of them
|
|
322
|
+
* (#810). This lives in its own module because both the {@link SessionApproval}
|
|
323
|
+
* value object and the forwarded wire type name it, and those two already
|
|
324
|
+
* import in one direction.
|
|
325
|
+
*/
|
|
326
|
+
|
|
327
|
+
interface ApprovalGrant {
|
|
328
|
+
readonly surface: string;
|
|
329
|
+
readonly pattern: string;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
332
|
/**
|
|
333
333
|
* The child's session-approval suggestion, relayed to the serving node so a
|
|
334
334
|
* human who grants "the whole session" records the same grants the child would
|
package/docs/configuration.md
CHANGED
|
@@ -1165,9 +1165,13 @@ Additional behaviors:
|
|
|
1165
1165
|
|
|
1166
1166
|
- Unknown/unregistered tools are blocked before permission checks (prevents bypass attempts)
|
|
1167
1167
|
- Tool filtering is restrict-only: the active set starts from pi's already-active tools (`pi.getActiveTools()`) and only ever has denied tools removed — the permission system never activates a tool pi left off by default (e.g. `find`, `grep`, `ls`)
|
|
1168
|
+
- Policy is applied to the tool surface pi has activated over the session, not to the previous turn's filtered result, so removing a `deny` rule restores the tool it had hidden without restarting pi.
|
|
1169
|
+
A tool that stops being active for any other reason (another extension deactivating it, pi unregistering it) is not restored.
|
|
1170
|
+
- On the turn a tool is restored, it is callable immediately but its `Available tools:` line reappears one turn later: pi builds the prompt an extension receives before the extension runs, so the line is only regenerated once the restored tool is already active
|
|
1168
1171
|
- A tool is removed only when every value under its surface resolves to `deny`; a surface with any reachable `allow` or `ask` pattern stays available (see [Tool Surfaces](#tool-surfaces))
|
|
1169
1172
|
- The `Available tools:` system prompt section is narrowed to match the filtered active tool set: denied tools' lines are dropped, the rest are kept, and the section is removed entirely only when no tool is allowed
|
|
1170
|
-
- The narrowed prompt is recomputed and returned on every turn but is byte-stable for a stable policy/agent, so the provider's prompt cache (tools + system prefix) is preserved rather than rewritten each turn
|
|
1173
|
+
- The narrowed prompt is recomputed and returned on every turn but is byte-stable for a stable policy/agent, so the provider's prompt cache (tools + system prefix) is preserved rather than rewritten each turn.
|
|
1174
|
+
A policy change is an intentional cache transition, as a mid-session agent switch already is.
|
|
1171
1175
|
- Extension-provided tools like `task`, `mcp`, and third-party tools are handled by exact registered name
|
|
1172
1176
|
- Generic extension-tool approval prompts include a bounded input preview; built-in file tools use concise human-readable summaries
|
|
1173
1177
|
- Permission review logs include `toolInputPreview` values for non-bash/non-MCP tool calls, with sensitive-keyed values masked and every value bounded by `reviewLogFieldMaxWidth` (see [Log file sensitivity](#log-file-sensitivity))
|
|
@@ -1230,4 +1234,4 @@ npx --yes ajv-cli@5 validate \
|
|
|
1230
1234
|
|
|
1231
1235
|
The well-known surface keys — `*`, `path`, `external_directory`, `bash`, `mcp`, `skill`, and the four directional keys — are named properties in the schema, so an editor completes them and shows each key's own documentation on hover; any other registered tool name still validates as a surface.
|
|
1232
1236
|
|
|
1233
|
-
The schema is generated from the extension's zod source of truth (`src/config-schema.ts`); regenerate it with `pnpm run gen:schema` after changing the config shape.
|
|
1237
|
+
The schema is generated from the extension's zod source of truth (`src/config/config-schema.ts`); regenerate it with `pnpm run gen:schema` after changing the config shape.
|
|
@@ -280,7 +280,7 @@ Re-register on every initialization (as above) rather than once globally; the di
|
|
|
280
280
|
|
|
281
281
|
A built-in formatter is registered for the `"mcp"` tool at startup (through this same public API).
|
|
282
282
|
It renders a compact `with key: value, …` summary of the call's `arguments` and returns `undefined` when there are no arguments, leaving the MCP target prompt unchanged.
|
|
283
|
-
This is the reference implementation for the seam — see `src/builtin-tool-input-formatters.ts`.
|
|
283
|
+
This is the reference implementation for the seam — see `src/tool-input/builtin-tool-input-formatters.ts`.
|
|
284
284
|
|
|
285
285
|
#### `registerToolAccessExtractor`
|
|
286
286
|
|
|
@@ -62,7 +62,7 @@ The suggested pattern is surface-specific:
|
|
|
62
62
|
|
|
63
63
|
## Bash Arity Table
|
|
64
64
|
|
|
65
|
-
Bash pattern suggestions use a curated arity dictionary (`src/bash-arity.ts`) to determine how many tokens define the "human-understandable subcommand."
|
|
65
|
+
Bash pattern suggestions use a curated arity dictionary (`src/access-intent/bash/bash-arity.ts`) to determine how many tokens define the "human-understandable subcommand."
|
|
66
66
|
Longest matching prefix wins, so `npm run` (arity 3) takes precedence over `npm` (arity 2).
|
|
67
67
|
Unknown commands default to arity 1 (first word only).
|
|
68
68
|
|
|
@@ -76,7 +76,7 @@ Unknown commands default to arity 1 (first word only).
|
|
|
76
76
|
| `mytool --verbose` | (unknown) → 1 | `mytool *` |
|
|
77
77
|
|
|
78
78
|
The arity table covers common CLI tools including git, npm/pnpm/yarn/bun, docker, cargo, go, kubectl, gh, and others.
|
|
79
|
-
To add an entry, open `src/bash-arity.ts` and add a key/arity pair to the `ARITY` object.
|
|
79
|
+
To add an entry, open `src/access-intent/bash/bash-arity.ts` and add a key/arity pair to the `ARITY` object.
|
|
80
80
|
Put the most specific multi-word prefix first (e.g. `"npm run": 3`) before the shorter fallback (`"npm": 2`).
|
|
81
81
|
|
|
82
82
|
## Review Log Entries
|
package/package.json
CHANGED
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
import type { AccessPath } from "#src/access-intent/access-path";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
mergeTokenEffects,
|
|
4
|
+
type TokenEffect,
|
|
5
|
+
UNPROVEN_EFFECT,
|
|
6
|
+
} from "#src/access-intent/effect";
|
|
7
|
+
import { normalizePathPolicyLiteral } from "#src/access-intent/path-normalization";
|
|
8
|
+
import type { PathNormalizer } from "#src/path/path-normalizer";
|
|
9
|
+
import { isSafeSystemPath } from "#src/path/safe-system-paths";
|
|
10
|
+
import { ARG_NODE_TYPES, SKIP_SUBTREE_TYPES } from "./node-text";
|
|
11
|
+
import type { TSNode } from "./parser";
|
|
7
12
|
import {
|
|
8
13
|
classifyBareTokenCandidate,
|
|
9
14
|
classifyTokenAsPathCandidate,
|
|
10
15
|
classifyTokenAsRuleCandidate,
|
|
11
|
-
} from "
|
|
16
|
+
} from "./token-classification";
|
|
12
17
|
import {
|
|
13
18
|
collectCommandTokens,
|
|
14
19
|
collectPathCandidateTokens,
|
|
15
20
|
collectRedirectTokens,
|
|
16
21
|
extractCommandName,
|
|
17
22
|
type PathToken,
|
|
18
|
-
} from "
|
|
19
|
-
import {
|
|
20
|
-
mergeTokenEffects,
|
|
21
|
-
type TokenEffect,
|
|
22
|
-
UNPROVEN_EFFECT,
|
|
23
|
-
} from "#src/access-intent/effect";
|
|
24
|
-
import { normalizePathPolicyLiteral } from "#src/access-intent/path-normalization";
|
|
25
|
-
import type { PathNormalizer } from "#src/path-normalizer";
|
|
26
|
-
import { isSafeSystemPath } from "#src/safe-system-paths";
|
|
23
|
+
} from "./token-collection";
|
|
27
24
|
|
|
28
25
|
// ── Internal types ───────────────────────────────────────────────────────────
|
|
29
26
|
|
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "
|
|
5
|
-
import {
|
|
6
|
-
parseUnresolvedWithin,
|
|
7
|
-
type TSNode,
|
|
8
|
-
} from "#src/access-intent/bash/parser";
|
|
9
|
-
import { redirectMayWriteFile } from "#src/access-intent/bash/redirect-analysis";
|
|
1
|
+
import type { BashCommandContext, FloorExemption } from "#src/types";
|
|
2
|
+
import { EXECUTION_HOST_TYPES, forEachExecutionIn } from "./nested-execution";
|
|
3
|
+
import { parseUnresolvedWithin, type TSNode } from "./parser";
|
|
4
|
+
import { redirectMayWriteFile } from "./redirect-analysis";
|
|
10
5
|
import {
|
|
11
6
|
type CommandWord,
|
|
12
7
|
classifyWrapperWords,
|
|
13
8
|
executedUnitOf,
|
|
14
9
|
isTransparentWrapper,
|
|
15
10
|
type WrapperKind,
|
|
16
|
-
} from "
|
|
17
|
-
import type { BashCommandContext, FloorExemption } from "#src/types";
|
|
11
|
+
} from "./wrapper-analysis";
|
|
18
12
|
|
|
19
|
-
export type { WrapperKind } from "
|
|
13
|
+
export type { WrapperKind } from "./wrapper-analysis";
|
|
20
14
|
|
|
21
15
|
// ── Command type ─────────────────────────────────────────────────────────────
|
|
22
16
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* module so the shape knowledge is unit-testable in isolation (no filesystem,
|
|
8
8
|
* no platform read).
|
|
9
9
|
*/
|
|
10
|
-
import { isSafeSystemPath } from "#src/safe-system-paths";
|
|
10
|
+
import { isSafeSystemPath } from "#src/path/safe-system-paths";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* The MSYS interpretation of a win32 bash token:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TSNode } from "
|
|
2
|
-
import { resolvePlainVariableExpansion } from "
|
|
1
|
+
import type { TSNode } from "./parser";
|
|
2
|
+
import { resolvePlainVariableExpansion } from "./shell-variable-expansion";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Node types whose text content is never a command argument, so no path
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
+
import type { PathNormalizer } from "#src/path/path-normalizer";
|
|
1
2
|
import {
|
|
2
3
|
type BashExternalPath,
|
|
3
4
|
BashPathResolver,
|
|
4
5
|
type BashPathRuleCandidate,
|
|
5
|
-
} from "
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
collectCommands,
|
|
9
|
-
} from "#src/access-intent/bash/command-enumeration";
|
|
10
|
-
import { getParser } from "#src/access-intent/bash/parser";
|
|
11
|
-
import type { PathNormalizer } from "#src/path-normalizer";
|
|
6
|
+
} from "./bash-path-resolver";
|
|
7
|
+
import { type BashCommand, collectCommands } from "./command-enumeration";
|
|
8
|
+
import { getParser } from "./parser";
|
|
12
9
|
|
|
13
10
|
export type { BashCommand, BashExternalPath, BashPathRuleCandidate };
|
|
14
11
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { redirectDestinationEffect } from "#src/access-intent/bash/command-effects";
|
|
2
|
-
import { parseUnresolvedAt, type TSNode } from "#src/access-intent/bash/parser";
|
|
3
1
|
import { type TokenEffect, UNPROVEN_EFFECT } from "#src/access-intent/effect";
|
|
2
|
+
import { redirectDestinationEffect } from "./command-effects";
|
|
3
|
+
import { parseUnresolvedAt, type TSNode } from "./parser";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* What a redirect node in the parse tree proves.
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
collectCommands,
|
|
4
|
-
} from "#src/access-intent/bash/command-enumeration";
|
|
5
|
-
import { getWarmBashParser } from "#src/access-intent/bash/parser";
|
|
1
|
+
import { type BashCommand, collectCommands } from "./command-enumeration";
|
|
2
|
+
import { getWarmBashParser } from "./parser";
|
|
6
3
|
|
|
7
4
|
/**
|
|
8
5
|
* Synchronously enumerate the command-pattern units of a bash command using the
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
forEachExecutionIn,
|
|
6
|
-
} from "#src/access-intent/bash/nested-execution";
|
|
2
|
+
import { type TokenEffect, UNPROVEN_EFFECT } from "#src/access-intent/effect";
|
|
3
|
+
import { proveCommandEffect } from "./command-effects";
|
|
4
|
+
import { EXECUTION_HOST_TYPES, forEachExecutionIn } from "./nested-execution";
|
|
7
5
|
import {
|
|
8
6
|
ARG_NODE_TYPES,
|
|
9
7
|
resolveNodeText,
|
|
10
8
|
SKIP_SUBTREE_TYPES,
|
|
11
|
-
} from "
|
|
12
|
-
import type { TSNode } from "
|
|
13
|
-
import { redirectEffectForDestination } from "
|
|
14
|
-
import { type TokenEffect, UNPROVEN_EFFECT } from "#src/access-intent/effect";
|
|
9
|
+
} from "./node-text";
|
|
10
|
+
import type { TSNode } from "./parser";
|
|
11
|
+
import { redirectEffectForDestination } from "./redirect-analysis";
|
|
15
12
|
|
|
16
13
|
/**
|
|
17
14
|
* A collected path-candidate token paired with the effect its position proved.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* classifiers over the same vocabulary would drift.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { proveCommandEffect } from "
|
|
12
|
+
import { proveCommandEffect } from "./command-effects";
|
|
13
13
|
|
|
14
14
|
/** One word of a command unit: its text, and its offset into the unit's text. */
|
|
15
15
|
export interface CommandWord {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { stripBashCommentLines } from "#src/bash-arity";
|
|
2
|
-
import type { PathNormalizer } from "#src/path-normalizer";
|
|
1
|
+
import { stripBashCommentLines } from "#src/access-intent/bash/bash-arity";
|
|
2
|
+
import type { PathNormalizer } from "#src/path/path-normalizer";
|
|
3
3
|
import { getNonEmptyString, toRecord } from "#src/value-guards";
|
|
4
4
|
import type { AccessIntent, ResolvedAccessIntent } from "./access-intent";
|
|
5
5
|
import { createMcpPermissionTargets } from "./mcp-targets";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ToolAccessExtractorLookup } from "#src/tool-access-extractor-registry";
|
|
1
|
+
import type { ToolAccessExtractorLookup } from "#src/tool-input/tool-access-extractor-registry";
|
|
2
2
|
import { getNonEmptyString, toRecord } from "#src/value-guards";
|
|
3
3
|
import { classifyToolKind } from "./tool-kind";
|
|
4
4
|
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import type { DebugReviewLogger } from "#src/logging/session-logger";
|
|
4
|
+
import { createPermissionRequestId } from "#src/permission-request-id";
|
|
5
|
+
import type { PromptPayload } from "#src/presentation/prompt-payload";
|
|
6
|
+
import { buildUiPrompt } from "#src/service/permission-ui-prompt";
|
|
3
7
|
import {
|
|
4
8
|
getActiveAgentName,
|
|
5
9
|
getActiveAgentNameFromSystemPrompt,
|
|
6
|
-
} from "#src/active-agent";
|
|
10
|
+
} from "#src/session/active-agent";
|
|
11
|
+
import { toRecord } from "#src/value-guards";
|
|
12
|
+
import type { TerminalAuthorizer } from "./authorizer";
|
|
7
13
|
import {
|
|
8
14
|
type ForwarderContext,
|
|
9
15
|
getCwd,
|
|
10
16
|
getSessionId,
|
|
11
|
-
} from "
|
|
17
|
+
} from "./forwarder-context";
|
|
12
18
|
import {
|
|
13
19
|
cleanupPermissionForwardingLocationIfEmpty,
|
|
14
20
|
ensurePermissionForwardingLocation,
|
|
@@ -18,9 +24,9 @@ import {
|
|
|
18
24
|
safeDeleteFile,
|
|
19
25
|
sleep,
|
|
20
26
|
writeJsonFileAtomic,
|
|
21
|
-
} from "
|
|
22
|
-
import type { TargetServingLookup } from "
|
|
23
|
-
import type { PermissionPromptDecision } from "
|
|
27
|
+
} from "./forwarding-io";
|
|
28
|
+
import type { TargetServingLookup } from "./forwarding-liveness";
|
|
29
|
+
import type { PermissionPromptDecision } from "./permission-dialog";
|
|
24
30
|
import {
|
|
25
31
|
type ForwardedAccessFacts,
|
|
26
32
|
type ForwardedPermissionRequest,
|
|
@@ -33,15 +39,9 @@ import {
|
|
|
33
39
|
type PermissionForwardingTarget,
|
|
34
40
|
resolvePermissionForwardingTarget,
|
|
35
41
|
SUBAGENT_PARENT_SESSION_ENV_CANDIDATES,
|
|
36
|
-
} from "
|
|
37
|
-
import type { SubagentSessionRegistry } from "#src/authority/subagent-registry";
|
|
38
|
-
import { createPermissionRequestId } from "#src/permission-request-id";
|
|
39
|
-
import { buildUiPrompt } from "#src/permission-ui-prompt";
|
|
40
|
-
import type { PromptPayload } from "#src/presentation/prompt-payload";
|
|
41
|
-
import type { DebugReviewLogger } from "#src/session-logger";
|
|
42
|
-
import { toRecord } from "#src/value-guards";
|
|
43
|
-
import type { TerminalAuthorizer } from "./authorizer";
|
|
42
|
+
} from "./permission-forwarding";
|
|
44
43
|
import type { PromptPermissionDetails } from "./permission-prompter";
|
|
44
|
+
import type { SubagentSessionRegistry } from "./subagent-registry";
|
|
45
45
|
|
|
46
46
|
// ── Module-private helpers ────────────────────────────────────────────────
|
|
47
47
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { DecisionSource } from "#src/authority/decision-source";
|
|
2
1
|
import type { AuthorizerLog, PermissionQuery } from "#src/service";
|
|
3
2
|
import type {
|
|
4
3
|
AuthorizerVerdict,
|
|
5
4
|
NamedAuthorizer,
|
|
6
5
|
TerminalAuthorizer,
|
|
7
6
|
} from "./authorizer";
|
|
7
|
+
import type { DecisionSource } from "./decision-source";
|
|
8
8
|
import {
|
|
9
9
|
createDeniedPermissionDecision,
|
|
10
10
|
type PermissionPromptDecision,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* the registration (ADR 0012 decision 4).
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import type { ReviewLogger } from "#src/session-logger";
|
|
20
|
+
import type { ReviewLogger } from "#src/logging/session-logger";
|
|
21
21
|
import type { Authorizer } from "./authorizer";
|
|
22
22
|
import type { AdjudicationRole } from "./authorizer-selection";
|
|
23
23
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type { PermissionPromptDecision } from "#src/authority/permission-dialog";
|
|
3
2
|
import type { PermissionQuery } from "#src/service";
|
|
4
3
|
import {
|
|
5
4
|
type AuthorizerSelectionDeps,
|
|
@@ -10,6 +9,7 @@ import {
|
|
|
10
9
|
import { composeAuthorizerChain } from "./authorizer-chain";
|
|
11
10
|
import type { AuthorizerLookup } from "./authorizer-registry";
|
|
12
11
|
import { encloseInDelegationEnvelope } from "./delegation-envelope";
|
|
12
|
+
import type { PermissionPromptDecision } from "./permission-dialog";
|
|
13
13
|
import type {
|
|
14
14
|
PermissionPrompterApi,
|
|
15
15
|
PromptPermissionDetails,
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type {
|
|
3
|
-
import type { PermissionPromptDecision } from "#src/authority/permission-dialog";
|
|
4
|
-
import type {
|
|
5
|
-
PromptPreferences,
|
|
6
|
-
requestPermissionDecision,
|
|
7
|
-
} from "#src/authority/permission-prompt-component";
|
|
8
|
-
import type { SubagentSessionRegistry } from "#src/authority/subagent-registry";
|
|
9
|
-
import type { PermissionEventBus } from "#src/permission-events";
|
|
2
|
+
import type { DebugReviewLogger } from "#src/logging/session-logger";
|
|
10
3
|
import type { AuthorizerLog, PermissionQuery } from "#src/service";
|
|
11
|
-
import type {
|
|
4
|
+
import type { PermissionEventBus } from "#src/service/permission-events";
|
|
12
5
|
import { ParentAuthorizer } from "./approval-escalator";
|
|
13
6
|
import { DenyingAuthorizer } from "./denying-authorizer";
|
|
7
|
+
import type { TargetServingLookup } from "./forwarding-liveness";
|
|
14
8
|
import { LocalUserAuthorizer } from "./local-user-authorizer";
|
|
9
|
+
import type { PermissionPromptDecision } from "./permission-dialog";
|
|
10
|
+
import type {
|
|
11
|
+
PromptPreferences,
|
|
12
|
+
requestPermissionDecision,
|
|
13
|
+
} from "./permission-prompt-component";
|
|
15
14
|
import type { PromptPermissionDetails } from "./permission-prompter";
|
|
16
15
|
import type { SubagentDetector } from "./subagent-detection";
|
|
16
|
+
import type { SubagentSessionRegistry } from "./subagent-registry";
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* A non-terminal chain link's ruling on an `ask`: decide (`allow`/`deny`) or
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
effectiveDecider,
|
|
4
|
-
} from "#src/authority/decision-source";
|
|
5
|
-
import type { PermissionDecisionResolution } from "#src/permission-events";
|
|
1
|
+
import type { PermissionDecisionResolution } from "#src/service/permission-events";
|
|
2
|
+
import { type DecisionSource, effectiveDecider } from "./decision-source";
|
|
6
3
|
|
|
7
4
|
/** What became of the request, as the gate that ran it observed. */
|
|
8
5
|
export interface DecisionOutcome {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PermissionPromptDecision } from "#src/authority/permission-dialog";
|
|
2
1
|
import type { TerminalAuthorizer } from "./authorizer";
|
|
2
|
+
import type { PermissionPromptDecision } from "./permission-dialog";
|
|
3
3
|
|
|
4
4
|
/** Why this authorizer denies; the provenance record's `reason` (#726). */
|
|
5
5
|
const NO_AUTHORITY_REASON = "No live authority was reachable for this session";
|
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
type ForwarderContext,
|
|
6
|
-
getSessionId,
|
|
7
|
-
} from "#src/authority/forwarder-context";
|
|
8
|
-
import {
|
|
9
|
-
createDeniedPermissionDecision,
|
|
10
|
-
type PermissionPromptDecision,
|
|
11
|
-
} from "#src/authority/permission-dialog";
|
|
12
|
-
import {
|
|
13
|
-
type ForwardedAccessFacts,
|
|
14
|
-
type ForwardedAccessIntent,
|
|
15
|
-
type ForwardedPermissionRequest,
|
|
16
|
-
type ForwardedPermissionResponse,
|
|
17
|
-
isForwardedPermissionRequestForSession,
|
|
18
|
-
type PermissionForwardingLocation,
|
|
19
|
-
} from "#src/authority/permission-forwarding";
|
|
20
|
-
import type { SubagentSessionRegistry } from "#src/authority/subagent-registry";
|
|
21
|
-
import type { DecisionBroadcaster } from "#src/decision-reporter";
|
|
22
|
-
import type { PermissionDecisionEvent } from "#src/permission-events";
|
|
2
|
+
import type { DecisionBroadcaster } from "#src/logging/decision-reporter";
|
|
3
|
+
import type { DebugReviewLogger } from "#src/logging/session-logger";
|
|
23
4
|
import { buildForwardedAskPayload } from "#src/presentation/forwarded-ask-payload";
|
|
24
|
-
import {
|
|
25
|
-
import
|
|
26
|
-
import type {
|
|
5
|
+
import type { PermissionDecisionEvent } from "#src/service/permission-events";
|
|
6
|
+
import { SessionApproval } from "#src/session/session-approval";
|
|
7
|
+
import type { SessionApprovalRecorder } from "#src/session/session-approval-recorder";
|
|
27
8
|
import type { PermissionCheckResult } from "#src/types";
|
|
28
9
|
import type { AskEscalator } from "./authorizer-selection";
|
|
10
|
+
import { resolutionFor } from "./decision-resolution";
|
|
11
|
+
import type { DecisionSource } from "./decision-source";
|
|
12
|
+
import { type ForwarderContext, getSessionId } from "./forwarder-context";
|
|
29
13
|
import {
|
|
30
14
|
cleanupPermissionForwardingLocationIfEmpty,
|
|
31
15
|
ensureDirectoryExists,
|
|
@@ -38,7 +22,20 @@ import {
|
|
|
38
22
|
safeDeleteFile,
|
|
39
23
|
writeJsonFileAtomic,
|
|
40
24
|
} from "./forwarding-io";
|
|
25
|
+
import {
|
|
26
|
+
createDeniedPermissionDecision,
|
|
27
|
+
type PermissionPromptDecision,
|
|
28
|
+
} from "./permission-dialog";
|
|
29
|
+
import {
|
|
30
|
+
type ForwardedAccessFacts,
|
|
31
|
+
type ForwardedAccessIntent,
|
|
32
|
+
type ForwardedPermissionRequest,
|
|
33
|
+
type ForwardedPermissionResponse,
|
|
34
|
+
isForwardedPermissionRequestForSession,
|
|
35
|
+
type PermissionForwardingLocation,
|
|
36
|
+
} from "./permission-forwarding";
|
|
41
37
|
import type { PromptPermissionDetails } from "./permission-prompter";
|
|
38
|
+
import type { SubagentSessionRegistry } from "./subagent-registry";
|
|
42
39
|
|
|
43
40
|
/**
|
|
44
41
|
* Narrow seam describing what `ForwardingManager` needs from the server: a
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { SessionEntryView } from "#src/active-agent";
|
|
2
|
-
import type { PermissionDecisionUi } from "
|
|
1
|
+
import type { SessionEntryView } from "#src/session/active-agent";
|
|
2
|
+
import type { PermissionDecisionUi } from "./permission-dialog";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Narrow context the forwarding subsystem reads: the UI gate (`hasUI`), the
|
|
@@ -8,10 +8,19 @@ import {
|
|
|
8
8
|
unlinkSync,
|
|
9
9
|
writeFileSync,
|
|
10
10
|
} from "node:fs";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
import {
|
|
12
|
+
OWNER_ONLY_DIRECTORY_MODE,
|
|
13
|
+
OWNER_ONLY_FILE_MODE,
|
|
14
|
+
} from "#src/logging/log-file-permissions";
|
|
15
|
+
import type { DebugReviewLogger } from "#src/logging/session-logger";
|
|
16
|
+
import { asPromptPayload } from "#src/presentation/prompt-payload";
|
|
17
|
+
import type { PermissionUiPromptSource } from "#src/service/permission-events";
|
|
18
|
+
import {
|
|
19
|
+
type ApprovalGrant,
|
|
20
|
+
isSessionGrantWidth,
|
|
21
|
+
} from "#src/session/approval-grant";
|
|
22
|
+
import { asDecisionSource } from "./decision-source";
|
|
23
|
+
import { isPermissionDecisionState } from "./permission-dialog";
|
|
15
24
|
import {
|
|
16
25
|
createPermissionForwardingLocation,
|
|
17
26
|
type ForwardedAccessIntent,
|
|
@@ -19,14 +28,7 @@ import {
|
|
|
19
28
|
type ForwardedPermissionResponse,
|
|
20
29
|
type ForwardedSessionApproval,
|
|
21
30
|
type PermissionForwardingLocation,
|
|
22
|
-
} from "
|
|
23
|
-
import {
|
|
24
|
-
OWNER_ONLY_DIRECTORY_MODE,
|
|
25
|
-
OWNER_ONLY_FILE_MODE,
|
|
26
|
-
} from "#src/log-file-permissions";
|
|
27
|
-
import type { PermissionUiPromptSource } from "#src/permission-events";
|
|
28
|
-
import { asPromptPayload } from "#src/presentation/prompt-payload";
|
|
29
|
-
import type { DebugReviewLogger } from "#src/session-logger";
|
|
31
|
+
} from "./permission-forwarding";
|
|
30
32
|
|
|
31
33
|
/** Valid `permissions:ui_prompt` source values, for tolerant request reads. */
|
|
32
34
|
const UI_PROMPT_SOURCES = [
|