@gotgenes/pi-permission-system 31.1.0 → 31.1.2

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.
Files changed (138) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/public.d.ts +15 -15
  3. package/docs/configuration.md +1 -1
  4. package/docs/cross-extension-api.md +1 -1
  5. package/docs/session-approvals.md +2 -2
  6. package/package.json +2 -1
  7. package/src/access-intent/access-intent.ts +1 -1
  8. package/src/access-intent/bash/bash-path-resolver.ts +11 -14
  9. package/src/access-intent/bash/command-enumeration.ts +6 -12
  10. package/src/access-intent/bash/msys-bash-tokens.ts +1 -1
  11. package/src/access-intent/bash/nested-execution.ts +1 -1
  12. package/src/access-intent/bash/node-text.ts +2 -2
  13. package/src/access-intent/bash/parser.ts +1 -1
  14. package/src/access-intent/bash/program.ts +4 -7
  15. package/src/access-intent/bash/redirect-analysis.ts +2 -2
  16. package/src/access-intent/bash/shell-variable-expansion.ts +1 -1
  17. package/src/access-intent/bash/sync-commands.ts +2 -5
  18. package/src/access-intent/bash/token-collection.ts +6 -9
  19. package/src/access-intent/bash/wrapper-analysis.ts +1 -1
  20. package/src/access-intent/input-normalizer.ts +2 -2
  21. package/src/access-intent/path-normalization.ts +1 -1
  22. package/src/access-intent/path-surfaces.ts +1 -1
  23. package/src/access-intent/tool-input-path.ts +1 -1
  24. package/src/access-intent/tool-kind.ts +1 -1
  25. package/src/authority/approval-escalator.ts +13 -13
  26. package/src/authority/authorizer-chain.ts +1 -1
  27. package/src/authority/authorizer-registry.ts +1 -1
  28. package/src/authority/authorizer-selection.ts +1 -1
  29. package/src/authority/authorizer.ts +9 -9
  30. package/src/authority/decision-resolution.ts +2 -5
  31. package/src/authority/denying-authorizer.ts +1 -1
  32. package/src/authority/forwarded-request-server.ts +21 -24
  33. package/src/authority/forwarder-context.ts +2 -2
  34. package/src/authority/forwarding-io.ts +14 -12
  35. package/src/authority/forwarding-liveness.ts +5 -8
  36. package/src/authority/forwarding-manager.ts +1 -1
  37. package/src/authority/inherited-registrations.ts +2 -2
  38. package/src/authority/local-user-authorizer.ts +13 -13
  39. package/src/authority/permission-dialog.ts +2 -2
  40. package/src/authority/permission-forwarding.ts +6 -3
  41. package/src/authority/permission-prompt-component.ts +12 -15
  42. package/src/authority/permission-prompt-decision.ts +2 -2
  43. package/src/authority/permission-prompter.ts +8 -8
  44. package/src/authority/subagent-context.ts +3 -3
  45. package/src/authority/subagent-detection.ts +3 -3
  46. package/src/{config-loader.ts → config/config-loader.ts} +3 -3
  47. package/src/{config-modal.ts → config/config-modal.ts} +1 -2
  48. package/src/{config-reporter.ts → config/config-reporter.ts} +1 -1
  49. package/src/{config-store.ts → config/config-store.ts} +1 -2
  50. package/src/{extension-config.ts → config/extension-config.ts} +4 -4
  51. package/src/{extension-paths.ts → config/extension-paths.ts} +1 -1
  52. package/src/{policy-loader.ts → config/policy-loader.ts} +2 -2
  53. package/src/{skill-prompt-sanitizer.ts → exposure/skill-prompt-sanitizer.ts} +2 -2
  54. package/src/{tool-registry.ts → exposure/tool-registry.ts} +1 -1
  55. package/src/handlers/before-agent-start.ts +11 -8
  56. package/src/handlers/gates/bash-command.ts +2 -2
  57. package/src/handlers/gates/bash-external-directory.ts +3 -3
  58. package/src/handlers/gates/bash-path-extractor.ts +1 -1
  59. package/src/handlers/gates/bash-path.ts +4 -4
  60. package/src/handlers/gates/descriptor.ts +2 -2
  61. package/src/handlers/gates/external-directory-policy.ts +2 -2
  62. package/src/handlers/gates/external-directory.ts +4 -4
  63. package/src/handlers/gates/helpers.ts +1 -1
  64. package/src/handlers/gates/path.ts +4 -4
  65. package/src/handlers/gates/runner.ts +4 -4
  66. package/src/handlers/gates/skill-read.ts +3 -3
  67. package/src/handlers/gates/tool-call-gate-pipeline.ts +7 -7
  68. package/src/handlers/gates/tool.ts +3 -3
  69. package/src/handlers/lifecycle.ts +6 -7
  70. package/src/handlers/permission-gate-handler.ts +11 -11
  71. package/src/handlers/session-turn-prep.ts +1 -1
  72. package/src/handlers/tool-call-boundary.ts +3 -3
  73. package/src/index.ts +39 -39
  74. package/src/{decision-reporter.ts → logging/decision-reporter.ts} +1 -1
  75. package/src/{logging.ts → logging/logging.ts} +1 -1
  76. package/src/{session-logger.ts → logging/session-logger.ts} +5 -2
  77. package/src/path/approval-pattern.ts +1 -1
  78. package/src/path/canonicalize-path.ts +1 -1
  79. package/src/path/path-containment.ts +2 -2
  80. package/src/path/path-flavor.ts +1 -1
  81. package/src/{path-normalizer.ts → path/path-normalizer.ts} +6 -8
  82. package/src/path/pi-infrastructure-read.ts +3 -3
  83. package/src/{normalize.ts → policy/normalize.ts} +2 -2
  84. package/src/{permission-gate.ts → policy/permission-gate.ts} +1 -1
  85. package/src/{permission-manager.ts → policy/permission-manager.ts} +21 -15
  86. package/src/{permission-merge.ts → policy/permission-merge.ts} +1 -1
  87. package/src/{permission-resolver.ts → policy/permission-resolver.ts} +5 -5
  88. package/src/{rule.ts → policy/rule.ts} +3 -4
  89. package/src/{scope-merge.ts → policy/scope-merge.ts} +3 -3
  90. package/src/{synthesize.ts → policy/synthesize.ts} +1 -1
  91. package/src/{wildcard-matcher.ts → policy/wildcard-matcher.ts} +1 -1
  92. package/src/presentation/agent-renderer.ts +5 -5
  93. package/src/presentation/dialog-renderer.ts +3 -3
  94. package/src/presentation/fact-vocabulary.ts +1 -4
  95. package/src/presentation/forwarded-ask-payload.ts +1 -4
  96. package/src/presentation/path-ask-payload.ts +2 -5
  97. package/src/{pattern-suggest.ts → presentation/pattern-suggest.ts} +6 -3
  98. package/src/{permission-prompts.ts → presentation/permission-prompts.ts} +1 -1
  99. package/src/presentation/review-log-renderer.ts +1 -1
  100. package/src/presentation/skill-ask-payload.ts +3 -3
  101. package/src/presentation/tool-ask-payload.ts +3 -6
  102. package/src/{bash-advisory-check.ts → service/bash-advisory-check.ts} +1 -1
  103. package/src/{permissions-service.ts → service/permissions-service.ts} +10 -10
  104. package/src/{service-lifecycle.ts → service/service-lifecycle.ts} +5 -5
  105. package/src/service.ts +18 -18
  106. package/src/{permission-session.ts → session/permission-session.ts} +19 -20
  107. package/src/{session-approval.ts → session/session-approval.ts} +2 -2
  108. package/src/{session-rules.ts → session/session-rules.ts} +1 -1
  109. package/src/{builtin-tool-input-formatters.ts → tool-input/builtin-tool-input-formatters.ts} +1 -1
  110. package/src/{tool-input-preview.ts → tool-input/tool-input-preview.ts} +2 -2
  111. package/src/{tool-input-prompt-formatters.ts → tool-input/tool-input-prompt-formatters.ts} +1 -1
  112. package/src/{tool-preview-formatter.ts → tool-input/tool-preview-formatter.ts} +3 -3
  113. package/src/types.ts +2 -2
  114. /package/src/{async-cache.ts → access-intent/bash/async-cache.ts} +0 -0
  115. /package/src/{bash-arity.ts → access-intent/bash/bash-arity.ts} +0 -0
  116. /package/src/{config-paths.ts → config/config-paths.ts} +0 -0
  117. /package/src/{config-schema.ts → config/config-schema.ts} +0 -0
  118. /package/src/{status.ts → config/status.ts} +0 -0
  119. /package/src/{yaml-frontmatter.ts → config/yaml-frontmatter.ts} +0 -0
  120. /package/src/{system-prompt-sanitizer.ts → exposure/system-prompt-sanitizer.ts} +0 -0
  121. /package/src/{tool-surface-baseline.ts → exposure/tool-surface-baseline.ts} +0 -0
  122. /package/src/{decision-audit.ts → logging/decision-audit.ts} +0 -0
  123. /package/src/{json-safe-stringify.ts → logging/json-safe-stringify.ts} +0 -0
  124. /package/src/{log-field-cap.ts → logging/log-field-cap.ts} +0 -0
  125. /package/src/{log-file-permissions.ts → logging/log-file-permissions.ts} +0 -0
  126. /package/src/{log-redaction.ts → logging/log-redaction.ts} +0 -0
  127. /package/src/{expand-home.ts → path/expand-home.ts} +0 -0
  128. /package/src/{node-modules-discovery.ts → path/node-modules-discovery.ts} +0 -0
  129. /package/src/{safe-system-paths.ts → path/safe-system-paths.ts} +0 -0
  130. /package/src/{restrictiveness.ts → policy/restrictiveness.ts} +0 -0
  131. /package/src/{permission-events.ts → service/permission-events.ts} +0 -0
  132. /package/src/{permission-ui-prompt.ts → service/permission-ui-prompt.ts} +0 -0
  133. /package/src/{active-agent.ts → session/active-agent.ts} +0 -0
  134. /package/src/{approval-grant.ts → session/approval-grant.ts} +0 -0
  135. /package/src/{session-approval-recorder.ts → session/session-approval-recorder.ts} +0 -0
  136. /package/src/{session-identity.ts → session/session-identity.ts} +0 -0
  137. /package/src/{tool-access-extractor-registry.ts → tool-input/tool-access-extractor-registry.ts} +0 -0
  138. /package/src/{tool-input-formatter-registry.ts → tool-input/tool-input-formatter-registry.ts} +0 -0
@@ -18,23 +18,20 @@
18
18
 
19
19
  import { readdirSync, readFileSync } from "node:fs";
20
20
  import { join } from "node:path";
21
+ import type { DebugReviewLogger } from "#src/logging/session-logger";
21
22
  import {
22
23
  ensureDirectoryExists,
23
24
  isErrnoCode,
24
25
  logPermissionForwardingError,
25
26
  safeDeleteFile,
26
27
  writeJsonFileAtomic,
27
- } from "#src/authority/forwarding-io";
28
- import type { PermissionForwardingTarget } from "#src/authority/permission-forwarding";
28
+ } from "./forwarding-io";
29
+ import type { PermissionForwardingTarget } from "./permission-forwarding";
29
30
  import {
30
31
  encodeSessionIdForPath,
31
32
  PERMISSION_FORWARDING_POLL_INTERVAL_MS,
32
- } from "#src/authority/permission-forwarding";
33
- import type {
34
- ServingAnnouncer,
35
- ServingLookup,
36
- } from "#src/authority/serving-registry";
37
- import type { DebugReviewLogger } from "#src/session-logger";
33
+ } from "./permission-forwarding";
34
+ import type { ServingAnnouncer, ServingLookup } from "./serving-registry";
38
35
 
39
36
  /**
40
37
  * How often a serving session rewrites its heartbeat — four poll ticks.
@@ -1,5 +1,5 @@
1
1
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import type { DebugReviewLogger } from "#src/session-logger";
2
+ import type { DebugReviewLogger } from "#src/logging/session-logger";
3
3
  import type { InboxProcessor } from "./forwarded-request-server";
4
4
  import { getSessionId } from "./forwarder-context";
5
5
  import { PERMISSION_FORWARDING_POLL_INTERVAL_MS } from "./permission-forwarding";
@@ -36,11 +36,11 @@ import type { PermissionsService } from "#src/service";
36
36
  import type {
37
37
  ResolvedToolAccessExtractor,
38
38
  ToolAccessExtractorLookup,
39
- } from "#src/tool-access-extractor-registry";
39
+ } from "#src/tool-input/tool-access-extractor-registry";
40
40
  import type {
41
41
  ToolInputFormatter,
42
42
  ToolInputFormatterLookup,
43
- } from "#src/tool-input-formatter-registry";
43
+ } from "#src/tool-input/tool-input-formatter-registry";
44
44
 
45
45
  /** This node's own session id, or `null` when the host exposes none. */
46
46
  export interface NodeIdentity {
@@ -1,25 +1,25 @@
1
1
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import { provenDirectionOf } from "#src/approval-grant";
3
- import type {
4
- PermissionPromptDecision,
5
- RequestPermissionOptions,
6
- } from "#src/authority/permission-dialog";
7
- import type {
8
- PermissionPromptUi,
9
- PromptPreferences,
10
- requestPermissionDecision,
11
- } from "#src/authority/permission-prompt-component";
12
2
  import {
13
3
  buildDirectionalSessionLabels,
14
4
  buildForwardedScopeLabels,
15
5
  describeGrantTarget,
16
- } from "#src/pattern-suggest";
6
+ } from "#src/presentation/pattern-suggest";
17
7
  import {
18
8
  emitUiPromptEvent,
19
9
  type PermissionEventBus,
20
- } from "#src/permission-events";
21
- import { buildUiPrompt } from "#src/permission-ui-prompt";
10
+ } from "#src/service/permission-events";
11
+ import { buildUiPrompt } from "#src/service/permission-ui-prompt";
12
+ import { provenDirectionOf } from "#src/session/approval-grant";
22
13
  import type { TerminalAuthorizer } from "./authorizer";
14
+ import type {
15
+ PermissionPromptDecision,
16
+ RequestPermissionOptions,
17
+ } from "./permission-dialog";
18
+ import type {
19
+ PermissionPromptUi,
20
+ PromptPreferences,
21
+ requestPermissionDecision,
22
+ } from "./permission-prompt-component";
23
23
  import type { PromptPermissionDetails } from "./permission-prompter";
24
24
 
25
25
  /** Dependencies required by {@link LocalUserAuthorizer}. */
@@ -1,5 +1,5 @@
1
- import type { SessionGrantWidth } from "#src/approval-grant";
2
- import type { DecisionSource } from "#src/authority/decision-source";
1
+ import type { SessionGrantWidth } from "#src/session/approval-grant";
2
+ import type { DecisionSource } from "./decision-source";
3
3
 
4
4
  export type PermissionDecisionState =
5
5
  | "approved"
@@ -1,8 +1,11 @@
1
1
  import { join } from "node:path";
2
- import type { ApprovalGrant, SessionGrantWidth } from "#src/approval-grant";
3
- import type { DecisionSource } from "#src/authority/decision-source";
4
- import type { PermissionUiPromptSource } from "#src/permission-events";
5
2
  import type { PromptPayload } from "#src/presentation/prompt-payload";
3
+ import type { PermissionUiPromptSource } from "#src/service/permission-events";
4
+ import type {
5
+ ApprovalGrant,
6
+ SessionGrantWidth,
7
+ } from "#src/session/approval-grant";
8
+ import type { DecisionSource } from "./decision-source";
6
9
  import type { PermissionDecisionState } from "./permission-dialog";
7
10
  import type { SubagentSessionRegistry } from "./subagent-registry";
8
11
 
@@ -4,17 +4,22 @@ import type {
4
4
  KeybindingsManager,
5
5
  } from "@earendil-works/pi-coding-agent";
6
6
  import { type Component, Input, matchesKey } from "@earendil-works/pi-tui";
7
- import { collapsePastedNewlines } from "#src/authority/bracketed-paste";
8
- import type {
9
- DecisionSource,
10
- UserDecisionSurface,
11
- } from "#src/authority/decision-source";
7
+ import {
8
+ completeViewBudget,
9
+ type DialogView,
10
+ type RenderBudget,
11
+ renderPromptDialog,
12
+ } from "#src/presentation/dialog-renderer";
13
+ import { fitLinesToWidth } from "#src/presentation/line-fitting";
14
+ import type { PromptPayload } from "#src/presentation/prompt-payload";
15
+ import { collapsePastedNewlines } from "./bracketed-paste";
16
+ import type { DecisionSource, UserDecisionSurface } from "./decision-source";
12
17
  import {
13
18
  type PermissionPromptDecision,
14
19
  type RequestPermissionOptions,
15
20
  requestPermissionDecisionFromUi,
16
21
  type UnattributedDecision,
17
- } from "#src/authority/permission-dialog";
22
+ } from "./permission-dialog";
18
23
  import {
19
24
  initialPromptState,
20
25
  type PromptEvent,
@@ -23,15 +28,7 @@ import {
23
28
  type PromptViewState,
24
29
  reducePrompt,
25
30
  visibleOptionKeys,
26
- } from "#src/authority/permission-prompt-decision";
27
- import {
28
- completeViewBudget,
29
- type DialogView,
30
- type RenderBudget,
31
- renderPromptDialog,
32
- } from "#src/presentation/dialog-renderer";
33
- import { fitLinesToWidth } from "#src/presentation/line-fitting";
34
- import type { PromptPayload } from "#src/presentation/prompt-payload";
31
+ } from "./permission-prompt-decision";
35
32
 
36
33
  /**
37
34
  * Inline `ctx.ui.custom` permission dialog for TUI sessions.
@@ -1,10 +1,10 @@
1
- import type { SessionGrantWidth } from "#src/approval-grant";
1
+ import type { SessionGrantWidth } from "#src/session/approval-grant";
2
2
  import {
3
3
  createDeniedPermissionDecision,
4
4
  normalizePermissionDenialReason,
5
5
  type RequestPermissionOptions,
6
6
  type UnattributedDecision,
7
- } from "#src/authority/permission-dialog";
7
+ } from "./permission-dialog";
8
8
 
9
9
  /**
10
10
  * Pure decision model for the inline keybind permission dialog.
@@ -1,14 +1,14 @@
1
- import type { SessionGrantWidth } from "#src/approval-grant";
2
- import type { DecisionSource } from "#src/authority/decision-source";
3
- import type { PermissionPromptDecision } from "#src/authority/permission-dialog";
4
- import type {
5
- ForwardedAccessFacts,
6
- ForwardedSessionApproval,
7
- } from "#src/authority/permission-forwarding";
1
+ import type { ReviewLogger } from "#src/logging/session-logger";
8
2
  import type { PromptPayload } from "#src/presentation/prompt-payload";
9
3
  import { renderReviewLogFacts } from "#src/presentation/review-log-renderer";
10
- import type { ReviewLogger } from "#src/session-logger";
4
+ import type { SessionGrantWidth } from "#src/session/approval-grant";
11
5
  import type { TerminalAuthorizer } from "./authorizer";
6
+ import type { DecisionSource } from "./decision-source";
7
+ import type { PermissionPromptDecision } from "./permission-dialog";
8
+ import type {
9
+ ForwardedAccessFacts,
10
+ ForwardedSessionApproval,
11
+ } from "./permission-forwarding";
12
12
 
13
13
  export type PermissionReviewSource = "tool_call" | "skill_input" | "skill_read";
14
14
 
@@ -1,7 +1,7 @@
1
- import { SUBAGENT_ENV_HINT_KEYS } from "#src/authority/permission-forwarding";
2
- import type { SubagentSessionRegistry } from "#src/authority/subagent-registry";
3
1
  import type { PathFlavor } from "#src/path/path-flavor";
4
- import { readSessionId } from "#src/session-identity";
2
+ import { readSessionId } from "#src/session/session-identity";
3
+ import { SUBAGENT_ENV_HINT_KEYS } from "./permission-forwarding";
4
+ import type { SubagentSessionRegistry } from "./subagent-registry";
5
5
 
6
6
  /**
7
7
  * Narrow context for subagent detection — the only session-manager readers
@@ -1,9 +1,9 @@
1
+ import type { PathFlavor } from "#src/path/path-flavor";
1
2
  import {
2
3
  isSubagentExecutionContext,
3
4
  type SubagentDetectionContext,
4
- } from "#src/authority/subagent-context";
5
- import type { SubagentSessionRegistry } from "#src/authority/subagent-registry";
6
- import type { PathFlavor } from "#src/path/path-flavor";
5
+ } from "./subagent-context";
6
+ import type { SubagentSessionRegistry } from "./subagent-registry";
7
7
 
8
8
  /**
9
9
  * Narrow seam for the ask-path consumers: "is the current session a subagent?"
@@ -1,6 +1,9 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { normalize } from "node:path";
3
3
  import type { ZodError } from "zod";
4
+ import { mergeFlatPermissions } from "#src/policy/permission-merge";
5
+ import type { FlatPermissionConfig, PatternValue } from "#src/types";
6
+ import { isDenyWithReason, isPermissionState } from "#src/types";
4
7
  import {
5
8
  getGlobalConfigPath,
6
9
  getLegacyExtensionConfigPath,
@@ -13,9 +16,6 @@ import {
13
16
  type UnifiedPermissionConfig,
14
17
  unifiedConfigSchema,
15
18
  } from "./config-schema";
16
- import { mergeFlatPermissions } from "./permission-merge";
17
- import type { FlatPermissionConfig, PatternValue } from "./types";
18
- import { isDenyWithReason, isPermissionState } from "./types";
19
19
 
20
20
  // The unified config shape is derived from the zod schema (config-schema.ts,
21
21
  // the single source of truth) and re-exported so existing importers keep their
@@ -4,13 +4,12 @@ import {
4
4
  getSettingsListTheme,
5
5
  } from "@earendil-works/pi-coding-agent";
6
6
  import { type SettingItem, SettingsList } from "@earendil-works/pi-tui";
7
-
7
+ import type { Ruleset } from "#src/policy/rule";
8
8
  import type { CommandConfigStore } from "./config-store";
9
9
  import {
10
10
  DEFAULT_EXTENSION_CONFIG,
11
11
  type PermissionSystemExtensionConfig,
12
12
  } from "./extension-config";
13
- import type { Ruleset } from "./rule";
14
13
 
15
14
  interface PermissionSystemConfigController {
16
15
  config: CommandConfigStore;
@@ -1,4 +1,4 @@
1
- import type { ResolvedPolicyPaths } from "./permission-manager";
1
+ import type { ResolvedPolicyPaths } from "#src/policy/permission-manager";
2
2
 
3
3
  export interface ResolvedConfigLogEntry {
4
4
  globalConfigPath: string;
@@ -10,7 +10,7 @@ import type {
10
10
  ExtensionCommandContext,
11
11
  ExtensionContext,
12
12
  } from "@earendil-works/pi-coding-agent";
13
-
13
+ import type { DebugReviewLogger } from "#src/logging/session-logger";
14
14
  import { loadAndMergeConfigs, loadUnifiedConfig } from "./config-loader";
15
15
  import {
16
16
  getGlobalConfigPath,
@@ -26,7 +26,6 @@ import {
26
26
  type PermissionSystemExtensionConfig,
27
27
  } from "./extension-config";
28
28
  import type { ResolvedPolicyPaths } from "./policy-loader";
29
- import type { DebugReviewLogger } from "./session-logger";
30
29
  import { syncPermissionSystemStatus } from "./status";
31
30
 
32
31
  /** Read-only view of the current config — for consumers that only read. */
@@ -1,14 +1,14 @@
1
1
  import { mkdirSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import {
5
+ OWNER_ONLY_DIRECTORY_MODE,
6
+ restrictExistingPathToOwner,
7
+ } from "#src/logging/log-file-permissions";
4
8
  import type {
5
9
  ShellToolsConfig,
6
10
  UnifiedPermissionConfig,
7
11
  } from "./config-loader";
8
- import {
9
- OWNER_ONLY_DIRECTORY_MODE,
10
- restrictExistingPathToOwner,
11
- } from "./log-file-permissions";
12
12
 
13
13
  export const EXTENSION_ID = "pi-permission-system";
14
14
 
@@ -1,6 +1,6 @@
1
1
  import { join } from "node:path";
2
+ import { discoverGlobalNodeModulesRoot } from "#src/path/node-modules-discovery";
2
3
  import { getGlobalLogsDir } from "./config-paths";
3
- import { discoverGlobalNodeModulesRoot } from "./node-modules-discovery";
4
4
 
5
5
  /**
6
6
  * Immutable path constants derived from `agentDir` at construction time.
@@ -1,14 +1,14 @@
1
1
  import { existsSync, readFileSync, statSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { getAgentDir } from "@earendil-works/pi-coding-agent";
4
+ import type { ScopeConfig } from "#src/types";
5
+ import { toRecord } from "#src/value-guards";
4
6
  import {
5
7
  loadUnifiedConfig,
6
8
  normalizeFlatPermissionValue,
7
9
  stripJsonComments,
8
10
  } from "./config-loader";
9
11
  import { getGlobalConfigPath } from "./config-paths";
10
- import type { ScopeConfig } from "./types";
11
- import { toRecord } from "./value-guards";
12
12
  import { extractFrontmatter, parseSimpleYamlMap } from "./yaml-frontmatter";
13
13
 
14
14
  // ---------------------------------------------------------------------------
@@ -1,7 +1,7 @@
1
1
  import { dirname } from "node:path";
2
2
 
3
- import type { PathNormalizer } from "./path-normalizer";
4
- import type { PermissionCheckResult, PermissionState } from "./types";
3
+ import type { PathNormalizer } from "#src/path/path-normalizer";
4
+ import type { PermissionCheckResult, PermissionState } from "#src/types";
5
5
 
6
6
  /**
7
7
  * Narrow interface for the raw (no-session-rules) permission checker used by
@@ -1,4 +1,4 @@
1
- import { getNonEmptyString, toRecord } from "./value-guards";
1
+ import { getNonEmptyString, toRecord } from "#src/value-guards";
2
2
 
3
3
  /** Narrow interface for the Pi tool API subset used by handler classes. */
4
4
  export interface ToolRegistry {
@@ -2,14 +2,17 @@ import type {
2
2
  BeforeAgentStartEventResult,
3
3
  ExtensionContext,
4
4
  } from "@earendil-works/pi-coding-agent";
5
- import type { TurnPreparation } from "#src/handlers/session-turn-prep";
6
- import type { PermissionResolver } from "#src/permission-resolver";
7
- import type { PermissionSession } from "#src/permission-session";
8
- import type { DebugLogger } from "#src/session-logger";
9
- import { resolveSkillPromptEntries } from "#src/skill-prompt-sanitizer";
10
- import { sanitizeAvailableToolsSection } from "#src/system-prompt-sanitizer";
11
- import { getToolNameFromValue, type ToolRegistry } from "#src/tool-registry";
12
- import type { ToolSurfaceObservation } from "#src/tool-surface-baseline";
5
+ import { resolveSkillPromptEntries } from "#src/exposure/skill-prompt-sanitizer";
6
+ import { sanitizeAvailableToolsSection } from "#src/exposure/system-prompt-sanitizer";
7
+ import {
8
+ getToolNameFromValue,
9
+ type ToolRegistry,
10
+ } from "#src/exposure/tool-registry";
11
+ import type { ToolSurfaceObservation } from "#src/exposure/tool-surface-baseline";
12
+ import type { DebugLogger } from "#src/logging/session-logger";
13
+ import type { PermissionResolver } from "#src/policy/permission-resolver";
14
+ import type { PermissionSession } from "#src/session/permission-session";
15
+ import type { TurnPreparation } from "./session-turn-prep";
13
16
 
14
17
  /** Minimal subset of BeforeAgentStartEvent used by this handler. */
15
18
  interface BeforeAgentStartPayload {
@@ -2,8 +2,8 @@ import type {
2
2
  BashCommand,
3
3
  WrapperKind,
4
4
  } from "#src/access-intent/bash/command-enumeration";
5
- import type { ScopedPermissionResolver } from "#src/permission-resolver";
6
- import { pickMostRestrictive } from "#src/restrictiveness";
5
+ import type { ScopedPermissionResolver } from "#src/policy/permission-resolver";
6
+ import { pickMostRestrictive } from "#src/policy/restrictiveness";
7
7
  import type { PermissionCheckResult } from "#src/types";
8
8
 
9
9
  /**
@@ -1,8 +1,8 @@
1
1
  import type { BashProgram } from "#src/access-intent/bash/program";
2
- import type { PathNormalizer } from "#src/path-normalizer";
3
- import type { ScopedPermissionResolver } from "#src/permission-resolver";
2
+ import type { PathNormalizer } from "#src/path/path-normalizer";
3
+ import type { ScopedPermissionResolver } from "#src/policy/permission-resolver";
4
4
  import { buildBashExternalDirectoryAskPayload } from "#src/presentation/path-ask-payload";
5
- import { SessionApproval } from "#src/session-approval";
5
+ import { SessionApproval } from "#src/session/session-approval";
6
6
  import type { GateResult } from "./descriptor";
7
7
  import { selectUncoveredExternalPaths } from "./external-directory-policy";
8
8
  import { accessFactsFromPath } from "./helpers";
@@ -1,5 +1,5 @@
1
1
  import { BashProgram } from "#src/access-intent/bash/program";
2
- import type { PathNormalizer } from "#src/path-normalizer";
2
+ import type { PathNormalizer } from "#src/path/path-normalizer";
3
3
 
4
4
  /**
5
5
  * Extract paths from a bash command that resolve outside CWD.
@@ -2,11 +2,11 @@ import type { AccessPath } from "#src/access-intent/access-path";
2
2
  import type { BashProgram } from "#src/access-intent/bash/program";
3
3
  import type { TokenEffect } from "#src/access-intent/effect";
4
4
  import { capabilitySurfaceForEffect } from "#src/access-intent/path-surfaces";
5
- import type { PathNormalizer } from "#src/path-normalizer";
6
- import type { ScopedPermissionResolver } from "#src/permission-resolver";
5
+ import type { PathNormalizer } from "#src/path/path-normalizer";
6
+ import type { ScopedPermissionResolver } from "#src/policy/permission-resolver";
7
+ import { pickMostRestrictive } from "#src/policy/restrictiveness";
7
8
  import { buildPathAskPayload } from "#src/presentation/path-ask-payload";
8
- import { pickMostRestrictive } from "#src/restrictiveness";
9
- import { SessionApproval } from "#src/session-approval";
9
+ import { SessionApproval } from "#src/session/session-approval";
10
10
  import type { PermissionCheckResult } from "#src/types";
11
11
  import type { GateResult } from "./descriptor";
12
12
  import { accessFactsFromPath } from "./helpers";
@@ -1,8 +1,8 @@
1
1
  import type { DecisionSource } from "#src/authority/decision-source";
2
2
  import type { PromptPermissionDetails } from "#src/authority/permission-prompter";
3
- import type { PermissionDecisionEvent } from "#src/permission-events";
4
3
  import type { PromptPayload } from "#src/presentation/prompt-payload";
5
- import type { SessionApproval } from "#src/session-approval";
4
+ import type { PermissionDecisionEvent } from "#src/service/permission-events";
5
+ import type { SessionApproval } from "#src/session/session-approval";
6
6
  import type { PermissionCheckResult, PermissionState } from "#src/types";
7
7
 
8
8
  // ── Descriptor types ───────────────────────────────────────────────────────
@@ -2,8 +2,8 @@ import type { AccessPath } from "#src/access-intent/access-path";
2
2
  import type { BashExternalPath } from "#src/access-intent/bash/bash-path-resolver";
3
3
  import type { TokenEffect } from "#src/access-intent/effect";
4
4
  import { capabilitySurfaceForEffect } from "#src/access-intent/path-surfaces";
5
- import type { ScopedPermissionResolver } from "#src/permission-resolver";
6
- import { pickMostRestrictive } from "#src/restrictiveness";
5
+ import type { ScopedPermissionResolver } from "#src/policy/permission-resolver";
6
+ import { pickMostRestrictive } from "#src/policy/restrictiveness";
7
7
  import type { PermissionCheckResult } from "#src/types";
8
8
 
9
9
  /** An external path whose resolved `external_directory` state is not "allow". */
@@ -1,10 +1,10 @@
1
1
  import { capabilitySurfaceForTool } from "#src/access-intent/path-surfaces";
2
2
  import { getToolInputPath } from "#src/access-intent/tool-input-path";
3
- import type { PathNormalizer } from "#src/path-normalizer";
4
- import type { ScopedPermissionResolver } from "#src/permission-resolver";
3
+ import type { PathNormalizer } from "#src/path/path-normalizer";
4
+ import type { ScopedPermissionResolver } from "#src/policy/permission-resolver";
5
5
  import { buildExternalDirectoryAskPayload } from "#src/presentation/path-ask-payload";
6
- import { SessionApproval } from "#src/session-approval";
7
- import type { ToolAccessExtractorLookup } from "#src/tool-access-extractor-registry";
6
+ import { SessionApproval } from "#src/session/session-approval";
7
+ import type { ToolAccessExtractorLookup } from "#src/tool-input/tool-access-extractor-registry";
8
8
  import type { GateResult } from "./descriptor";
9
9
  import { resolveExternalDirectoryPolicy } from "./external-directory-policy";
10
10
  import {
@@ -3,7 +3,7 @@ import type { ToolPathSource } from "#src/access-intent/tool-input-path";
3
3
  import { classifyToolKind } from "#src/access-intent/tool-kind";
4
4
  import type { ForwardedAccessFacts } from "#src/authority/permission-forwarding";
5
5
  import type { PromptPermissionDetails } from "#src/authority/permission-prompter";
6
- import type { PermissionDecisionResolution } from "#src/permission-events";
6
+ import type { PermissionDecisionResolution } from "#src/service/permission-events";
7
7
  import type { PermissionCheckResult } from "#src/types";
8
8
  import type { DecisionEventFacts } from "./descriptor";
9
9
  import type { ToolCallContext } from "./types";
@@ -1,10 +1,10 @@
1
1
  import { capabilitySurfaceForTool } from "#src/access-intent/path-surfaces";
2
2
  import { getToolInputPath } from "#src/access-intent/tool-input-path";
3
- import type { PathNormalizer } from "#src/path-normalizer";
4
- import type { ScopedPermissionResolver } from "#src/permission-resolver";
3
+ import type { PathNormalizer } from "#src/path/path-normalizer";
4
+ import type { ScopedPermissionResolver } from "#src/policy/permission-resolver";
5
5
  import { buildPathAskPayload } from "#src/presentation/path-ask-payload";
6
- import { SessionApproval } from "#src/session-approval";
7
- import type { ToolAccessExtractorLookup } from "#src/tool-access-extractor-registry";
6
+ import { SessionApproval } from "#src/session/session-approval";
7
+ import type { ToolAccessExtractorLookup } from "#src/tool-input/tool-access-extractor-registry";
8
8
  import type { GateDescriptor, GateResult } from "./descriptor";
9
9
  import {
10
10
  accessFactsFromPath,
@@ -2,16 +2,16 @@ import type { AskEscalator } from "#src/authority/authorizer-selection";
2
2
  import { resolutionFor } from "#src/authority/decision-resolution";
3
3
  import type { DecisionSource } from "#src/authority/decision-source";
4
4
  import type { PermissionPromptDecision } from "#src/authority/permission-dialog";
5
- import type { DecisionReporter } from "#src/decision-reporter";
6
- import { applyPermissionGate } from "#src/permission-gate";
5
+ import type { DecisionReporter } from "#src/logging/decision-reporter";
7
6
  import { createPermissionRequestId } from "#src/permission-request-id";
8
- import type { ScopedPermissionResolver } from "#src/permission-resolver";
7
+ import { applyPermissionGate } from "#src/policy/permission-gate";
8
+ import type { ScopedPermissionResolver } from "#src/policy/permission-resolver";
9
9
  import {
10
10
  renderPolicyDenial,
11
11
  renderRefusal,
12
12
  } from "#src/presentation/agent-renderer";
13
13
  import { renderReviewLogFacts } from "#src/presentation/review-log-renderer";
14
- import type { SessionApprovalRecorder } from "#src/session-approval-recorder";
14
+ import type { SessionApprovalRecorder } from "#src/session/session-approval-recorder";
15
15
  import type { PermissionCheckResult } from "#src/types";
16
16
  import type {
17
17
  DecisionEventFacts,
@@ -1,7 +1,7 @@
1
- import type { PathNormalizer } from "#src/path-normalizer";
1
+ import type { SkillPromptEntry } from "#src/exposure/skill-prompt-sanitizer";
2
+ import { findSkillPathMatch } from "#src/exposure/skill-prompt-sanitizer";
3
+ import type { PathNormalizer } from "#src/path/path-normalizer";
2
4
  import { buildSkillPathAskPayload } from "#src/presentation/skill-ask-payload";
3
- import type { SkillPromptEntry } from "#src/skill-prompt-sanitizer";
4
- import { findSkillPathMatch } from "#src/skill-prompt-sanitizer";
5
5
  import { toRecord } from "#src/value-guards";
6
6
  import type { GateDescriptor } from "./descriptor";
7
7
  import { accessFactsFromValue } from "./helpers";
@@ -4,16 +4,16 @@ import {
4
4
  resolveShellInvocation,
5
5
  type ShellInvocation,
6
6
  } from "#src/access-intent/tool-kind";
7
- import type { ShellToolsConfig } from "#src/config-schema";
8
- import type { PathNormalizer } from "#src/path-normalizer";
9
- import type { ScopedPermissionResolver } from "#src/permission-resolver";
10
- import type { SkillPromptEntry } from "#src/skill-prompt-sanitizer";
11
- import type { ToolAccessExtractorLookup } from "#src/tool-access-extractor-registry";
12
- import type { ToolInputFormatterLookup } from "#src/tool-input-formatter-registry";
7
+ import type { ShellToolsConfig } from "#src/config/config-schema";
8
+ import type { SkillPromptEntry } from "#src/exposure/skill-prompt-sanitizer";
9
+ import type { PathNormalizer } from "#src/path/path-normalizer";
10
+ import type { ScopedPermissionResolver } from "#src/policy/permission-resolver";
11
+ import type { ToolAccessExtractorLookup } from "#src/tool-input/tool-access-extractor-registry";
12
+ import type { ToolInputFormatterLookup } from "#src/tool-input/tool-input-formatter-registry";
13
13
  import {
14
14
  ToolPreviewFormatter,
15
15
  type ToolPreviewFormatterOptions,
16
- } from "#src/tool-preview-formatter";
16
+ } from "#src/tool-input/tool-preview-formatter";
17
17
  import type { PermissionCheckResult } from "#src/types";
18
18
  import { resolveBashCommandCheck } from "./bash-command";
19
19
  import { describeBashExternalDirectoryGate } from "./bash-external-directory";
@@ -8,10 +8,10 @@ import {
8
8
  import {
9
9
  suggestPathSessionPattern,
10
10
  suggestSessionPattern,
11
- } from "#src/pattern-suggest";
11
+ } from "#src/presentation/pattern-suggest";
12
12
  import { buildToolAskPayload } from "#src/presentation/tool-ask-payload";
13
- import { SessionApproval } from "#src/session-approval";
14
- import type { ToolPreviewFormatter } from "#src/tool-preview-formatter";
13
+ import { SessionApproval } from "#src/session/session-approval";
14
+ import type { ToolPreviewFormatter } from "#src/tool-input/tool-preview-formatter";
15
15
  import type { PermissionCheckResult } from "#src/types";
16
16
  import type { GateDescriptor } from "./descriptor";
17
17
  import {
@@ -1,11 +1,10 @@
1
1
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
-
3
- import type { DecisionSummaryWriter } from "#src/decision-audit";
4
- import type { PermissionResolver } from "#src/permission-resolver";
5
- import type { PermissionSession } from "#src/permission-session";
6
- import type { ServiceLifecycle } from "#src/service-lifecycle";
7
- import type { SessionLogger } from "#src/session-logger";
8
- import { PERMISSION_SYSTEM_STATUS_KEY } from "#src/status";
2
+ import { PERMISSION_SYSTEM_STATUS_KEY } from "#src/config/status";
3
+ import type { DecisionSummaryWriter } from "#src/logging/decision-audit";
4
+ import type { SessionLogger } from "#src/logging/session-logger";
5
+ import type { PermissionResolver } from "#src/policy/permission-resolver";
6
+ import type { ServiceLifecycle } from "#src/service/service-lifecycle";
7
+ import type { PermissionSession } from "#src/session/permission-session";
9
8
 
10
9
  /** Minimal subset of SessionStartEvent used by this handler. */
11
10
  interface SessionStartPayload {