@lannguyensi/harness 0.7.0 → 0.8.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 +229 -0
- package/README.md +56 -17
- package/dist/cli/apply/apply.d.ts +13 -0
- package/dist/cli/apply/apply.js +59 -3
- package/dist/cli/apply/apply.js.map +1 -1
- package/dist/cli/apply/generate-codex-config.d.ts +6 -0
- package/dist/cli/apply/generate-codex-config.js +149 -0
- package/dist/cli/apply/generate-codex-config.js.map +1 -0
- package/dist/cli/apply/generate-settings.d.ts +15 -1
- package/dist/cli/apply/generate-settings.js +16 -1
- package/dist/cli/apply/generate-settings.js.map +1 -1
- package/dist/cli/apply/index.d.ts +2 -1
- package/dist/cli/apply/index.js +2 -1
- package/dist/cli/apply/index.js.map +1 -1
- package/dist/cli/approve/understanding.d.ts +39 -0
- package/dist/cli/approve/understanding.js +122 -0
- package/dist/cli/approve/understanding.js.map +1 -0
- package/dist/cli/doctor/codex.d.ts +34 -0
- package/dist/cli/doctor/codex.js +331 -0
- package/dist/cli/doctor/codex.js.map +1 -0
- package/dist/cli/doctor/format.js +11 -0
- package/dist/cli/doctor/format.js.map +1 -1
- package/dist/cli/doctor/index.d.ts +13 -1
- package/dist/cli/doctor/index.js +19 -0
- package/dist/cli/doctor/index.js.map +1 -1
- package/dist/cli/doctor/types.d.ts +21 -1
- package/dist/cli/doctor/types.js +12 -1
- package/dist/cli/doctor/types.js.map +1 -1
- package/dist/cli/index.js +261 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/pack/add.d.ts +13 -0
- package/dist/cli/pack/add.js +71 -0
- package/dist/cli/pack/add.js.map +1 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +30 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.js +149 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -0
- package/dist/cli/pack/hook-codex-stop.d.ts +31 -0
- package/dist/cli/pack/hook-codex-stop.js +332 -0
- package/dist/cli/pack/hook-codex-stop.js.map +1 -0
- package/dist/cli/pack/hook-codex-user-prompt-submit.d.ts +18 -0
- package/dist/cli/pack/hook-codex-user-prompt-submit.js +92 -0
- package/dist/cli/pack/hook-codex-user-prompt-submit.js.map +1 -0
- package/dist/cli/pack/hook-pre-tool-use.d.ts +32 -0
- package/dist/cli/pack/hook-pre-tool-use.js +181 -0
- package/dist/cli/pack/hook-pre-tool-use.js.map +1 -0
- package/dist/cli/pack/index.d.ts +4 -0
- package/dist/cli/pack/index.js +5 -0
- package/dist/cli/pack/index.js.map +1 -0
- package/dist/cli/pack/list.d.ts +10 -0
- package/dist/cli/pack/list.js +43 -0
- package/dist/cli/pack/list.js.map +1 -0
- package/dist/cli/pack/mutate.d.ts +14 -0
- package/dist/cli/pack/mutate.js +76 -0
- package/dist/cli/pack/mutate.js.map +1 -0
- package/dist/cli/pack/remove.d.ts +15 -0
- package/dist/cli/pack/remove.js +153 -0
- package/dist/cli/pack/remove.js.map +1 -0
- package/dist/cli/policy/intercept.js +24 -0
- package/dist/cli/policy/intercept.js.map +1 -1
- package/dist/cli/validate/checks.js +32 -0
- package/dist/cli/validate/checks.js.map +1 -1
- package/dist/policy-packs/builtin/permission-profiles.d.ts +11 -0
- package/dist/policy-packs/builtin/permission-profiles.js +74 -0
- package/dist/policy-packs/builtin/permission-profiles.js.map +1 -0
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +56 -0
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +186 -0
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +1 -0
- package/dist/policy-packs/builtin/understanding-before-execution.d.ts +15 -0
- package/dist/policy-packs/builtin/understanding-before-execution.js +254 -0
- package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -0
- package/dist/policy-packs/expand.d.ts +4 -0
- package/dist/policy-packs/expand.js +90 -0
- package/dist/policy-packs/expand.js.map +1 -0
- package/dist/policy-packs/index.d.ts +5 -0
- package/dist/policy-packs/index.js +5 -0
- package/dist/policy-packs/index.js.map +1 -0
- package/dist/policy-packs/permission-translator.d.ts +9 -0
- package/dist/policy-packs/permission-translator.js +76 -0
- package/dist/policy-packs/permission-translator.js.map +1 -0
- package/dist/policy-packs/registry.d.ts +11 -0
- package/dist/policy-packs/registry.js +20 -0
- package/dist/policy-packs/registry.js.map +1 -0
- package/dist/policy-packs/runtime.d.ts +8 -0
- package/dist/policy-packs/runtime.js +30 -0
- package/dist/policy-packs/runtime.js.map +1 -0
- package/dist/policy-packs/source.d.ts +6 -0
- package/dist/policy-packs/source.js +10 -0
- package/dist/policy-packs/source.js.map +1 -0
- package/dist/policy-packs/types.d.ts +41 -0
- package/dist/policy-packs/types.js +11 -0
- package/dist/policy-packs/types.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/intercept.d.ts +20 -1
- package/dist/runtime/intercept.js +18 -6
- package/dist/runtime/intercept.js.map +1 -1
- package/dist/runtime/ledger-add.d.ts +16 -0
- package/dist/runtime/ledger-add.js +139 -0
- package/dist/runtime/ledger-add.js.map +1 -0
- package/dist/schema/index.d.ts +1485 -10
- package/dist/schema/index.js +6 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/permission-profiles.d.ts +2161 -0
- package/dist/schema/permission-profiles.js +60 -0
- package/dist/schema/permission-profiles.js.map +1 -0
- package/dist/schema/policy-packs.d.ts +52 -0
- package/dist/schema/policy-packs.js +35 -0
- package/dist/schema/policy-packs.js.map +1 -0
- package/dist/schema/tools.d.ts +8 -8
- package/package.json +1 -1
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
// Builtin Policy Pack: `understanding-before-execution`.
|
|
2
|
+
//
|
|
3
|
+
// Bundles three hook contributions for Claude Code (UserPromptSubmit,
|
|
4
|
+
// Stop, PreToolUse), plus a per-mode instructions.md that documents what
|
|
5
|
+
// the pack is doing for human auditors. The actual prompt that the agent
|
|
6
|
+
// sees at UserPromptSubmit time is owned by `@lannguyensi/understanding-gate`
|
|
7
|
+
// (specifically `src/prompts/{full,fast-confirm,grill-me}.ts`); harness's
|
|
8
|
+
// instructions.md is the operator-facing summary, not the agent-injected
|
|
9
|
+
// text. Drift on instructions.md is therefore meaningful (someone edited
|
|
10
|
+
// the audit copy), distinct from drift on the package's own templates
|
|
11
|
+
// (which the package's own drift detection would handle on a future
|
|
12
|
+
// `understanding-gate init` reinstall).
|
|
13
|
+
import { profileToSettingsPermissions } from "../permission-translator.js";
|
|
14
|
+
import { DEFAULT_RUNTIME } from "../runtime.js";
|
|
15
|
+
import { isKnownProfileName, resolveProfile, KNOWN_PROFILE_NAMES, } from "./permission-profiles.js";
|
|
16
|
+
export const PACK_NAME = "understanding-before-execution";
|
|
17
|
+
const MODES = ["fast_confirm", "grill_me", "strict"];
|
|
18
|
+
export const DEFAULT_MODE = "grill_me";
|
|
19
|
+
const HOOK_NAME_PREFIX = `policy-pack:${PACK_NAME}`;
|
|
20
|
+
// Per-runtime hook surface. Claude Code keys on tool name (Edit|Write|Bash);
|
|
21
|
+
// Codex's write surface is `apply_patch` + `Bash`/`shell` (the task's
|
|
22
|
+
// in-scope list). The hook contract Codex feeds to the adapter is the
|
|
23
|
+
// same generic envelope harness publishes: `{ session_id, tool_name,
|
|
24
|
+
// raw_input, event }` on stdin, `{ decision }` on stdout, exit 2 on
|
|
25
|
+
// block. See dogfood/phase6-6/README.md for the wire format.
|
|
26
|
+
const PRE_TOOL_USE_MATCH_CLAUDE = "Edit|Write|Bash";
|
|
27
|
+
const PRE_TOOL_USE_MATCH_CODEX = "apply_patch|Bash|shell";
|
|
28
|
+
// UserPromptSubmit + Stop hooks point at `@lannguyensi/understanding-gate`
|
|
29
|
+
// bare bin names (npm i -g). The harness validator's checkHooks skips
|
|
30
|
+
// PATH lookup for non-rooted commands by design, so missing-bin shows
|
|
31
|
+
// up at runtime, not at lint. `harness doctor` (Phase 6 #4 follow-up)
|
|
32
|
+
// will add the presence check.
|
|
33
|
+
const BIN_USER_PROMPT_SUBMIT_CLAUDE = "understanding-gate-claude-hook";
|
|
34
|
+
const BIN_STOP_CLAUDE = "understanding-gate-claude-stop";
|
|
35
|
+
// PreToolUse blocker is the harness CLI itself (Phase 6 #4): it consults
|
|
36
|
+
// BOTH the evidence-ledger tag (canonical for harnessed sessions) AND
|
|
37
|
+
// the persisted JSON report under `.understanding-gate/reports/`
|
|
38
|
+
// (fallback for sessions without grounding-mcp wired). The npm package's
|
|
39
|
+
// own bin remains available for solo users; the harness blocker is
|
|
40
|
+
// strictly more powerful.
|
|
41
|
+
const PRE_TOOL_USE_COMMAND_CLAUDE = "harness pack hook pre-tool-use";
|
|
42
|
+
// Codex variants. The package `@lannguyensi/understanding-gate` does
|
|
43
|
+
// not yet ship Codex bins, so harness owns the adapter:
|
|
44
|
+
//
|
|
45
|
+
// - UserPromptSubmit-equivalent injector (Phase 6 #6).
|
|
46
|
+
// - Stop-equivalent capture into `.understanding-gate/reports/`
|
|
47
|
+
// (Phase 6 #6 follow-up).
|
|
48
|
+
// - PreToolUse blocker on apply_patch/Bash/shell (Phase 6 #6).
|
|
49
|
+
//
|
|
50
|
+
// Cross-runtime sessions can still approve from a Claude Code report:
|
|
51
|
+
// the ledger tag is the canonical source for harnessed sessions,
|
|
52
|
+
// independent of which runtime captured the report. The persisted-
|
|
53
|
+
// report directory is shared between runtimes, so a Codex stop that
|
|
54
|
+
// writes a report is approvable via `harness approve understanding`
|
|
55
|
+
// regardless of which runtime invokes the next tool call.
|
|
56
|
+
const COMMAND_USER_PROMPT_SUBMIT_CODEX = "harness pack hook codex-user-prompt-submit";
|
|
57
|
+
const COMMAND_STOP_CODEX = "harness pack hook codex-stop";
|
|
58
|
+
const COMMAND_PRE_TOOL_USE_CODEX = "harness pack hook codex-pre-tool-use";
|
|
59
|
+
export function isMode(value) {
|
|
60
|
+
return typeof value === "string" && MODES.includes(value);
|
|
61
|
+
}
|
|
62
|
+
export function resolveMode(pack) {
|
|
63
|
+
const raw = pack.config["mode"];
|
|
64
|
+
if (raw === undefined)
|
|
65
|
+
return { mode: DEFAULT_MODE, warning: null };
|
|
66
|
+
if (isMode(raw))
|
|
67
|
+
return { mode: raw, warning: null };
|
|
68
|
+
const warning = `policy_packs[${pack.name}].config.mode: unrecognised value ${JSON.stringify(raw)}, falling back to "${DEFAULT_MODE}". Allowed: ${MODES.join(", ")}.`;
|
|
69
|
+
return { mode: DEFAULT_MODE, warning };
|
|
70
|
+
}
|
|
71
|
+
function buildHooks(runtime) {
|
|
72
|
+
// Per-mode hook commands are identical (the mode is passed via the
|
|
73
|
+
// package's UNDERSTANDING_GATE_MODE env var, set elsewhere — out of
|
|
74
|
+
// scope for Phase 6 #2). What changes per mode is the instructions.md
|
|
75
|
+
// content + the actual injected prompt (owned by the npm package).
|
|
76
|
+
if (runtime === "codex") {
|
|
77
|
+
return [
|
|
78
|
+
{
|
|
79
|
+
name: `${HOOK_NAME_PREFIX}:codex:user-prompt-submit`,
|
|
80
|
+
event: "UserPromptSubmit",
|
|
81
|
+
command: COMMAND_USER_PROMPT_SUBMIT_CODEX,
|
|
82
|
+
blocking: false,
|
|
83
|
+
budget_ms: 5000,
|
|
84
|
+
description: "Codex adapter: inject the Understanding-Gate instruction template before the agent acts. Phase 6 #6.",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: `${HOOK_NAME_PREFIX}:codex:stop`,
|
|
88
|
+
event: "Stop",
|
|
89
|
+
command: COMMAND_STOP_CODEX,
|
|
90
|
+
blocking: false,
|
|
91
|
+
budget_ms: 5000,
|
|
92
|
+
description: "Codex adapter: capture the agent's Understanding Report into .understanding-gate/reports/ as approvalStatus:pending. Phase 6 #6 follow-up.",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: `${HOOK_NAME_PREFIX}:codex:pre-tool-use`,
|
|
96
|
+
event: "PreToolUse",
|
|
97
|
+
match: PRE_TOOL_USE_MATCH_CODEX,
|
|
98
|
+
command: COMMAND_PRE_TOOL_USE_CODEX,
|
|
99
|
+
blocking: "hard",
|
|
100
|
+
budget_ms: 5000,
|
|
101
|
+
description: "Codex adapter: block apply_patch/Bash/shell until an approved Understanding Report exists for the session. Consults both the evidence-ledger tag and the persisted JSON report.",
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
return [
|
|
106
|
+
{
|
|
107
|
+
name: `${HOOK_NAME_PREFIX}:user-prompt-submit`,
|
|
108
|
+
event: "UserPromptSubmit",
|
|
109
|
+
command: BIN_USER_PROMPT_SUBMIT_CLAUDE,
|
|
110
|
+
blocking: false,
|
|
111
|
+
budget_ms: 5000,
|
|
112
|
+
description: "Inject the Understanding-Gate instruction template before the agent acts. Source: @lannguyensi/understanding-gate.",
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: `${HOOK_NAME_PREFIX}:stop`,
|
|
116
|
+
event: "Stop",
|
|
117
|
+
command: BIN_STOP_CLAUDE,
|
|
118
|
+
blocking: false,
|
|
119
|
+
budget_ms: 5000,
|
|
120
|
+
description: "Capture the agent's Understanding Report into .understanding-gate/reports/. Source: @lannguyensi/understanding-gate.",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: `${HOOK_NAME_PREFIX}:pre-tool-use`,
|
|
124
|
+
event: "PreToolUse",
|
|
125
|
+
match: PRE_TOOL_USE_MATCH_CLAUDE,
|
|
126
|
+
command: PRE_TOOL_USE_COMMAND_CLAUDE,
|
|
127
|
+
blocking: "hard",
|
|
128
|
+
budget_ms: 5000,
|
|
129
|
+
description: "Block Edit/Write/Bash until an approved Understanding Report exists for the session. Consults both the evidence-ledger tag (understanding-approved:${SESSION_ID}) and the persisted JSON report.",
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
function modeFriction(mode) {
|
|
134
|
+
switch (mode) {
|
|
135
|
+
case "fast_confirm":
|
|
136
|
+
return "low friction. The gate fires on prompts the classifier flags as execution-relevant. Brief Understanding Report; one-line approval.";
|
|
137
|
+
case "grill_me":
|
|
138
|
+
return "medium friction (default). The gate fires on any prompt the agent might respond to with a write. Full Understanding Report (assumptions, openQuestions, outOfScope, risks, verificationPlan). Push-back is encouraged.";
|
|
139
|
+
case "strict":
|
|
140
|
+
return "high friction. The gate fires on every prompt. Report MUST include verificationPlan and outOfScope; requiresHumanApproval is forced to true.";
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function buildInstructions(pack, mode, runtime) {
|
|
144
|
+
const description = pack.description?.trim() ?? "";
|
|
145
|
+
const isCodex = runtime === "codex";
|
|
146
|
+
const injectorCmd = isCodex ? COMMAND_USER_PROMPT_SUBMIT_CODEX : BIN_USER_PROMPT_SUBMIT_CLAUDE;
|
|
147
|
+
const stopCmd = isCodex ? COMMAND_STOP_CODEX : BIN_STOP_CLAUDE;
|
|
148
|
+
const blockerCmd = isCodex ? COMMAND_PRE_TOOL_USE_CODEX : PRE_TOOL_USE_COMMAND_CLAUDE;
|
|
149
|
+
const blockerMatch = isCodex ? PRE_TOOL_USE_MATCH_CODEX : PRE_TOOL_USE_MATCH_CLAUDE;
|
|
150
|
+
const settingsArtefact = isCodex
|
|
151
|
+
? "`harness.generated/codex/config.toml`"
|
|
152
|
+
: "harness-managed `settings.json`";
|
|
153
|
+
const stopBullet = `2. \`Stop\` capture (\`${stopCmd}\`): persists the emitted Understanding
|
|
154
|
+
Report under \`.understanding-gate/reports/\` for audit and downstream
|
|
155
|
+
approval consumption.
|
|
156
|
+
`;
|
|
157
|
+
const blockerOrdinal = "3";
|
|
158
|
+
return `# Policy Pack: ${PACK_NAME}
|
|
159
|
+
|
|
160
|
+
> Operator audit copy. The agent-facing prompt is injected at runtime by
|
|
161
|
+
> the \`${injectorCmd}\` UserPromptSubmit hook; that text lives
|
|
162
|
+
> in the \`@lannguyensi/understanding-gate\` package, not here. This file
|
|
163
|
+
> records WHAT the pack is doing and HOW it is configured so that
|
|
164
|
+
> \`harness diff --since-apply\` can flag operator-facing drift.
|
|
165
|
+
|
|
166
|
+
## Runtime
|
|
167
|
+
|
|
168
|
+
${runtime}
|
|
169
|
+
|
|
170
|
+
## Mode
|
|
171
|
+
|
|
172
|
+
${mode}
|
|
173
|
+
|
|
174
|
+
${modeFriction(mode)}
|
|
175
|
+
|
|
176
|
+
## Effect
|
|
177
|
+
|
|
178
|
+
While this pack is enabled, hooks are wired into the ${settingsArtefact}:
|
|
179
|
+
|
|
180
|
+
1. \`UserPromptSubmit\` injector (\`${injectorCmd}\`): inserts the
|
|
181
|
+
Understanding-Gate instruction template into the agent's first response.
|
|
182
|
+
${stopBullet}${blockerOrdinal}. \`PreToolUse\` blocker (\`${blockerCmd}\`, blocking: hard)
|
|
183
|
+
on \`${blockerMatch}\`: refuses the tool call until an approved
|
|
184
|
+
report exists for the session. Consults BOTH the evidence-ledger
|
|
185
|
+
tag (\`understanding-approved:\${SESSION_ID}\`, canonical for
|
|
186
|
+
harnessed sessions) AND the persisted JSON report under
|
|
187
|
+
\`.understanding-gate/reports/\` (fallback for sessions without
|
|
188
|
+
grounding-mcp wired). Either source approves.
|
|
189
|
+
|
|
190
|
+
## Approval
|
|
191
|
+
|
|
192
|
+
The standalone blocker shipped in \`@lannguyensi/understanding-gate@>=0.2.0\`
|
|
193
|
+
checks the persisted JSON report's \`approvalStatus\`. Phase 6 #4 will
|
|
194
|
+
add a harness-side blocker that ALSO consults the evidence-ledger tag
|
|
195
|
+
\`understanding-approved:\${SESSION_ID}\` (canonical for harnessed
|
|
196
|
+
sessions), and \`harness approve understanding\` will round-trip both.
|
|
197
|
+
Until then, approval flows through the package's own CLI.
|
|
198
|
+
|
|
199
|
+
## Pack metadata
|
|
200
|
+
${description ? `\n> ${description.replace(/\n/g, "\n> ")}\n` : ""}
|
|
201
|
+
- Source: \`builtin\`
|
|
202
|
+
- Pack: \`${PACK_NAME}\`
|
|
203
|
+
- Mode: \`${mode}\`
|
|
204
|
+
- Runtime: \`${runtime}\`
|
|
205
|
+
|
|
206
|
+
## See also
|
|
207
|
+
|
|
208
|
+
- \`docs/policy-packs/understanding-before-execution.md\` (full reference)
|
|
209
|
+
- \`docs/ROADMAP.md\` Phase 6 sub-task decomposition
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
function resolvePermissionProfile(pack) {
|
|
213
|
+
const raw = pack.config["permission_profile"];
|
|
214
|
+
if (raw === undefined)
|
|
215
|
+
return { permissions: null, warning: null };
|
|
216
|
+
if (typeof raw !== "string") {
|
|
217
|
+
return {
|
|
218
|
+
permissions: null,
|
|
219
|
+
warning: `policy_packs[${pack.name}].config.permission_profile: expected a string, got ${typeof raw}; skipping permission contribution.`,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
if (!isKnownProfileName(raw)) {
|
|
223
|
+
return {
|
|
224
|
+
permissions: null,
|
|
225
|
+
warning: `policy_packs[${pack.name}].config.permission_profile: unrecognised profile ${JSON.stringify(raw)}. Allowed: ${KNOWN_PROFILE_NAMES.join(", ")}. Skipping permission contribution.`,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
const profile = resolveProfile(raw);
|
|
229
|
+
if (!profile)
|
|
230
|
+
return { permissions: null, warning: null };
|
|
231
|
+
return { permissions: profileToSettingsPermissions(profile), warning: null };
|
|
232
|
+
}
|
|
233
|
+
export function resolve(pack, runtime = DEFAULT_RUNTIME) {
|
|
234
|
+
const { mode, warning } = resolveMode(pack);
|
|
235
|
+
const hooks = buildHooks(runtime);
|
|
236
|
+
const instructionsContent = buildInstructions(pack, mode, runtime);
|
|
237
|
+
const files = [
|
|
238
|
+
{
|
|
239
|
+
relativePath: `policy-packs/${PACK_NAME}/instructions.md`,
|
|
240
|
+
content: instructionsContent,
|
|
241
|
+
},
|
|
242
|
+
];
|
|
243
|
+
const warnings = [];
|
|
244
|
+
if (warning)
|
|
245
|
+
warnings.push(warning);
|
|
246
|
+
const profileResult = resolvePermissionProfile(pack);
|
|
247
|
+
if (profileResult.warning)
|
|
248
|
+
warnings.push(profileResult.warning);
|
|
249
|
+
const contribution = { hooks, files };
|
|
250
|
+
if (profileResult.permissions)
|
|
251
|
+
contribution.permissions = profileResult.permissions;
|
|
252
|
+
return { contribution, warnings };
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=understanding-before-execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"understanding-before-execution.js","sourceRoot":"","sources":["../../../src/policy-packs/builtin/understanding-before-execution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Apply-time expansion of `policy_packs[]` entries.
|
|
2
|
+
//
|
|
3
|
+
// Walks the manifest's enabled packs, parses each `source:` string,
|
|
4
|
+
// resolves builtin packs through the registry, and aggregates their
|
|
5
|
+
// contributions (hooks + files). Unrecognised sources or unknown builtin
|
|
6
|
+
// names produce non-fatal warnings here; `harness validate` is the
|
|
7
|
+
// place that turns the same conditions into hard errors so the user
|
|
8
|
+
// sees them at lint time, not silently at apply time.
|
|
9
|
+
//
|
|
10
|
+
// Hook-name collision handling: pack hooks are namespaced
|
|
11
|
+
// (`policy-pack:<name>:<role>`) by the builtin definitions, so a user
|
|
12
|
+
// hook with a colliding name is the user's mistake. We surface that as
|
|
13
|
+
// a warning here rather than blowing up; the schema's duplicate-name
|
|
14
|
+
// superRefine will reject it on the augmented manifest's downstream
|
|
15
|
+
// re-parse if a caller re-validates.
|
|
16
|
+
import { resolveBuiltin } from "./registry.js";
|
|
17
|
+
import { DEFAULT_RUNTIME } from "./runtime.js";
|
|
18
|
+
import { parsePackSource } from "./source.js";
|
|
19
|
+
export function expandPolicyPacks(manifest, runtime = DEFAULT_RUNTIME) {
|
|
20
|
+
const out = { hooks: [], files: [], warnings: [], skipped: [] };
|
|
21
|
+
if (manifest.policy_packs.length === 0)
|
|
22
|
+
return out;
|
|
23
|
+
const existingHookNames = new Set(manifest.hooks.map((h) => h.name));
|
|
24
|
+
const seenPackHookNames = new Set();
|
|
25
|
+
const allowSet = new Set();
|
|
26
|
+
const askSet = new Set();
|
|
27
|
+
const denySet = new Set();
|
|
28
|
+
let anyPermissions = false;
|
|
29
|
+
for (const pack of manifest.policy_packs) {
|
|
30
|
+
if (!pack.enabled) {
|
|
31
|
+
out.skipped.push(pack.name);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const sourceParsed = parsePackSource(pack.source);
|
|
35
|
+
if (sourceParsed.kind === "unknown") {
|
|
36
|
+
out.warnings.push(`policy_packs[${pack.name}]: source ${JSON.stringify(pack.source)} is not recognised in v1 (only "builtin" resolves); skipping.`);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const resolved = resolveBuiltin(pack, runtime);
|
|
40
|
+
if (!resolved) {
|
|
41
|
+
out.warnings.push(`policy_packs[${pack.name}]: not a known builtin pack; skipping. See docs/policy-packs/ for supported names.`);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
out.warnings.push(...resolved.warnings);
|
|
45
|
+
for (const hook of resolved.contribution.hooks) {
|
|
46
|
+
if (existingHookNames.has(hook.name)) {
|
|
47
|
+
out.warnings.push(`policy_packs[${pack.name}]: hook name "${hook.name}" collides with a manifest hooks[] entry; pack contribution dropped to avoid a duplicate-name failure.`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (seenPackHookNames.has(hook.name)) {
|
|
51
|
+
out.warnings.push(`policy_packs[${pack.name}]: hook name "${hook.name}" was already contributed by an earlier pack; second copy dropped.`);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
seenPackHookNames.add(hook.name);
|
|
55
|
+
out.hooks.push(hook);
|
|
56
|
+
}
|
|
57
|
+
out.files.push(...resolved.contribution.files);
|
|
58
|
+
if (resolved.contribution.permissions) {
|
|
59
|
+
anyPermissions = true;
|
|
60
|
+
for (const p of resolved.contribution.permissions.allow)
|
|
61
|
+
allowSet.add(p);
|
|
62
|
+
for (const p of resolved.contribution.permissions.ask)
|
|
63
|
+
askSet.add(p);
|
|
64
|
+
for (const p of resolved.contribution.permissions.deny)
|
|
65
|
+
denySet.add(p);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (anyPermissions) {
|
|
69
|
+
// Deny wins over ask wins over allow at merge time: a stricter
|
|
70
|
+
// intent from any pack should not be silently relaxed by a more
|
|
71
|
+
// permissive sibling. Concretely, a pattern present in deny is
|
|
72
|
+
// stripped from ask + allow; a pattern present in ask is stripped
|
|
73
|
+
// from allow.
|
|
74
|
+
for (const p of denySet) {
|
|
75
|
+
askSet.delete(p);
|
|
76
|
+
allowSet.delete(p);
|
|
77
|
+
}
|
|
78
|
+
for (const p of askSet) {
|
|
79
|
+
allowSet.delete(p);
|
|
80
|
+
}
|
|
81
|
+
const permissions = {
|
|
82
|
+
allow: [...allowSet].sort(),
|
|
83
|
+
ask: [...askSet].sort(),
|
|
84
|
+
deny: [...denySet].sort(),
|
|
85
|
+
};
|
|
86
|
+
out.permissions = permissions;
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=expand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expand.js","sourceRoot":"","sources":["../../src/policy-packs/expand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { expandPolicyPacks } from "./expand.js";
|
|
2
|
+
export { KNOWN_BUILTIN_PACKS, isBuiltinPackName, resolveBuiltin, type BuiltinPackName, type ResolveBuiltinResult, } from "./registry.js";
|
|
3
|
+
export { KNOWN_RUNTIMES, DEFAULT_RUNTIME, isRuntime, parseRuntime, type Runtime, } from "./runtime.js";
|
|
4
|
+
export { parsePackSource, type PackSourceKind, type PackSourceParseResult } from "./source.js";
|
|
5
|
+
export type { PackContribution, PackContributionFile, PackExpansionResult, } from "./types.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { expandPolicyPacks } from "./expand.js";
|
|
2
|
+
export { KNOWN_BUILTIN_PACKS, isBuiltinPackName, resolveBuiltin, } from "./registry.js";
|
|
3
|
+
export { KNOWN_RUNTIMES, DEFAULT_RUNTIME, isRuntime, parseRuntime, } from "./runtime.js";
|
|
4
|
+
export { parsePackSource } from "./source.js";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy-packs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,GAGf,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,cAAc,EACd,eAAe,EACf,SAAS,EACT,YAAY,GAEb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,eAAe,EAAmD,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PermissionActionKey, PermissionProfile } from "../schema/permission-profiles.js";
|
|
2
|
+
export interface SettingsPermissions {
|
|
3
|
+
allow: string[];
|
|
4
|
+
ask: string[];
|
|
5
|
+
deny: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function profileToSettingsPermissions(profile: PermissionProfile): SettingsPermissions;
|
|
8
|
+
/** Test seam — exposed for unit coverage of the action→pattern map. */
|
|
9
|
+
export declare function _internalPatternMap(): Record<PermissionActionKey, string[]>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Phase 6 #5 — translate abstract permission profile actions into
|
|
2
|
+
// Claude Code's settings.json permissions vocabulary.
|
|
3
|
+
//
|
|
4
|
+
// Mapping rules:
|
|
5
|
+
//
|
|
6
|
+
// Action key → tool patterns (matcher style)
|
|
7
|
+
// ---------- ----------------------------------------------- ----------------
|
|
8
|
+
// read ["Read", "Glob", "Grep"] bare tool names
|
|
9
|
+
// edit ["Edit", "Write", "MultiEdit"] bare tool names
|
|
10
|
+
// bash ["Bash"] bare tool name
|
|
11
|
+
// commit ["Bash(git commit*)"] Bash-prefix syntax
|
|
12
|
+
// push ["Bash(git push*)"] Bash-prefix syntax
|
|
13
|
+
// pr ["mcp__agent-tasks__pull_requests_create", MCP + bare gh
|
|
14
|
+
// "Bash(gh pr create*)"]
|
|
15
|
+
// deploy ["Bash(kubectl*)", "Bash(terraform destroy*)", Bash-prefix syntax
|
|
16
|
+
// "Bash(npm publish*)"]
|
|
17
|
+
//
|
|
18
|
+
// `allow` enum mapping:
|
|
19
|
+
//
|
|
20
|
+
// "true" / true → permissions.allow
|
|
21
|
+
// "false" / false → permissions.deny
|
|
22
|
+
// "ask" → permissions.ask
|
|
23
|
+
// "limited" → permissions.ask (v1 fallback — distinct
|
|
24
|
+
// semantics deferred to a
|
|
25
|
+
// Phase 6 #5 follow-up)
|
|
26
|
+
// "ask_or_deny" → permissions.ask (same fallback rationale)
|
|
27
|
+
const ACTION_TO_PATTERNS = {
|
|
28
|
+
read: ["Read", "Glob", "Grep"],
|
|
29
|
+
edit: ["Edit", "Write", "MultiEdit"],
|
|
30
|
+
bash: ["Bash"],
|
|
31
|
+
commit: ["Bash(git commit*)"],
|
|
32
|
+
push: ["Bash(git push*)"],
|
|
33
|
+
pr: ["mcp__agent-tasks__pull_requests_create", "Bash(gh pr create*)"],
|
|
34
|
+
deploy: ["Bash(kubectl*)", "Bash(terraform destroy*)", "Bash(npm publish*)"],
|
|
35
|
+
};
|
|
36
|
+
function bucketForAllow(value) {
|
|
37
|
+
switch (value) {
|
|
38
|
+
case "true":
|
|
39
|
+
return "allow";
|
|
40
|
+
case "false":
|
|
41
|
+
return "deny";
|
|
42
|
+
case "ask":
|
|
43
|
+
case "limited":
|
|
44
|
+
case "ask_or_deny":
|
|
45
|
+
return "ask";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function profileToSettingsPermissions(profile) {
|
|
49
|
+
const allow = new Set();
|
|
50
|
+
const ask = new Set();
|
|
51
|
+
const deny = new Set();
|
|
52
|
+
const buckets = {
|
|
53
|
+
allow,
|
|
54
|
+
ask,
|
|
55
|
+
deny,
|
|
56
|
+
};
|
|
57
|
+
for (const key of Object.keys(profile.actions)) {
|
|
58
|
+
const rule = profile.actions[key];
|
|
59
|
+
if (!rule)
|
|
60
|
+
continue;
|
|
61
|
+
const target = bucketForAllow(rule.allow);
|
|
62
|
+
for (const pattern of ACTION_TO_PATTERNS[key]) {
|
|
63
|
+
buckets[target].add(pattern);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
allow: [...allow].sort(),
|
|
68
|
+
ask: [...ask].sort(),
|
|
69
|
+
deny: [...deny].sort(),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Test seam — exposed for unit coverage of the action→pattern map. */
|
|
73
|
+
export function _internalPatternMap() {
|
|
74
|
+
return ACTION_TO_PATTERNS;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=permission-translator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-translator.js","sourceRoot":"","sources":["../../src/policy-packs/permission-translator.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,sDAAsD;AACtD,EAAE;AACF,iBAAiB;AACjB,EAAE;AACF,mFAAmF;AACnF,oFAAoF;AACpF,mFAAmF;AACnF,mFAAmF;AACnF,kFAAkF;AAClF,sFAAsF;AACtF,sFAAsF;AACtF,iFAAiF;AACjF,2CAA2C;AAC3C,sFAAsF;AACtF,0CAA0C;AAC1C,EAAE;AACF,wBAAwB;AACxB,EAAE;AACF,yCAAyC;AACzC,wCAAwC;AACxC,uCAAuC;AACvC,gEAAgE;AAChE,iEAAiE;AACjE,+DAA+D;AAC/D,kEAAkE;AAclE,MAAM,kBAAkB,GAA0C;IAChE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAC9B,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC;IACpC,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,mBAAmB,CAAC;IAC7B,IAAI,EAAE,CAAC,iBAAiB,CAAC;IACzB,EAAE,EAAE,CAAC,wCAAwC,EAAE,qBAAqB,CAAC;IACrE,MAAM,EAAE,CAAC,gBAAgB,EAAE,0BAA0B,EAAE,oBAAoB,CAAC;CAC7E,CAAC;AAEF,SAAS,cAAc,CAAC,KAAsB;IAC5C,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,MAAM;YACT,OAAO,OAAO,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,MAAM,CAAC;QAChB,KAAK,KAAK,CAAC;QACX,KAAK,SAAS,CAAC;QACf,KAAK,aAAa;YAChB,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,OAA0B;IAE1B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,MAAM,OAAO,GAAmD;QAC9D,KAAK;QACL,GAAG;QACH,IAAI;KACL,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAA0B,EAAE,CAAC;QACxE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,KAAK,MAAM,OAAO,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9C,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE;QACxB,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE;QACpB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE;KACvB,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,mBAAmB;IACjC,OAAO,kBAAkB,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PolicyPack } from "../schema/index.js";
|
|
2
|
+
import { type Runtime } from "./runtime.js";
|
|
3
|
+
import type { PackContribution } from "./types.js";
|
|
4
|
+
export declare const KNOWN_BUILTIN_PACKS: readonly ["understanding-before-execution"];
|
|
5
|
+
export type BuiltinPackName = (typeof KNOWN_BUILTIN_PACKS)[number];
|
|
6
|
+
export declare function isBuiltinPackName(name: string): name is BuiltinPackName;
|
|
7
|
+
export interface ResolveBuiltinResult {
|
|
8
|
+
contribution: PackContribution;
|
|
9
|
+
warnings: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function resolveBuiltin(pack: PolicyPack, runtime?: Runtime): ResolveBuiltinResult | null;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Registry of builtin policy-pack names.
|
|
2
|
+
//
|
|
3
|
+
// Phase 6 #2 ships exactly one builtin: `understanding-before-execution`.
|
|
4
|
+
// Future builtins are added here. Non-builtin sources (path/npm/git) are
|
|
5
|
+
// out of scope for v1; their resolution lands in a later sub-task.
|
|
6
|
+
import { PACK_NAME as UNDERSTANDING_BEFORE_EXECUTION, resolve as resolveUnderstandingBeforeExecution, } from "./builtin/understanding-before-execution.js";
|
|
7
|
+
import { DEFAULT_RUNTIME } from "./runtime.js";
|
|
8
|
+
export const KNOWN_BUILTIN_PACKS = [UNDERSTANDING_BEFORE_EXECUTION];
|
|
9
|
+
export function isBuiltinPackName(name) {
|
|
10
|
+
return KNOWN_BUILTIN_PACKS.includes(name);
|
|
11
|
+
}
|
|
12
|
+
export function resolveBuiltin(pack, runtime = DEFAULT_RUNTIME) {
|
|
13
|
+
if (!isBuiltinPackName(pack.name))
|
|
14
|
+
return null;
|
|
15
|
+
switch (pack.name) {
|
|
16
|
+
case UNDERSTANDING_BEFORE_EXECUTION:
|
|
17
|
+
return resolveUnderstandingBeforeExecution(pack, runtime);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/policy-packs/registry.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,mEAAmE;AAGnE,OAAO,EACL,SAAS,IAAI,8BAA8B,EAC3C,OAAO,IAAI,mCAAmC,GAC/C,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,eAAe,EAAgB,MAAM,cAAc,CAAC;AAG7D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,8BAA8B,CAAU,CAAC;AAG7E,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAQ,mBAAyC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAOD,MAAM,UAAU,cAAc,CAC5B,IAAgB,EAChB,UAAmB,eAAe;IAElC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,QAAQ,IAAI,CAAC,IAAuB,EAAE,CAAC;QACrC,KAAK,8BAA8B;YACjC,OAAO,mCAAmC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const KNOWN_RUNTIMES: readonly ["claude-code", "codex"];
|
|
2
|
+
export type Runtime = (typeof KNOWN_RUNTIMES)[number];
|
|
3
|
+
export declare const DEFAULT_RUNTIME: Runtime;
|
|
4
|
+
export declare function isRuntime(value: unknown): value is Runtime;
|
|
5
|
+
export declare function parseRuntime(raw: string | undefined): {
|
|
6
|
+
runtime: Runtime;
|
|
7
|
+
warning: string | null;
|
|
8
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Phase 6 #6 — runtime target identifier threaded through policy-pack
|
|
2
|
+
// expansion. Selects which adapter shape a pack emits.
|
|
3
|
+
//
|
|
4
|
+
// `claude-code` (default): hook commands point at the `@lannguyensi/understanding-gate`
|
|
5
|
+
// claude-code bins and the harness PreToolUse blocker. Output of
|
|
6
|
+
// `harness apply` is the Claude Code `settings.json` shape under
|
|
7
|
+
// `harness.generated/settings.json`.
|
|
8
|
+
//
|
|
9
|
+
// `codex`: hook commands point at the harness-shipped Codex adapter
|
|
10
|
+
// subcommands (`harness pack hook codex-*`). Output of `harness apply`
|
|
11
|
+
// is a Codex-flavoured config artefact under
|
|
12
|
+
// `harness.generated/codex/`. Phase 6 #6 ships block + allow for the
|
|
13
|
+
// understanding-before-execution pack; cross-pack and additional
|
|
14
|
+
// runtimes are out of v1 scope.
|
|
15
|
+
export const KNOWN_RUNTIMES = ["claude-code", "codex"];
|
|
16
|
+
export const DEFAULT_RUNTIME = "claude-code";
|
|
17
|
+
export function isRuntime(value) {
|
|
18
|
+
return typeof value === "string" && KNOWN_RUNTIMES.includes(value);
|
|
19
|
+
}
|
|
20
|
+
export function parseRuntime(raw) {
|
|
21
|
+
if (raw === undefined)
|
|
22
|
+
return { runtime: DEFAULT_RUNTIME, warning: null };
|
|
23
|
+
if (isRuntime(raw))
|
|
24
|
+
return { runtime: raw, warning: null };
|
|
25
|
+
return {
|
|
26
|
+
runtime: DEFAULT_RUNTIME,
|
|
27
|
+
warning: `unrecognised runtime ${JSON.stringify(raw)}, falling back to "${DEFAULT_RUNTIME}". Allowed: ${KNOWN_RUNTIMES.join(", ")}.`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/policy-packs/runtime.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,uDAAuD;AACvD,EAAE;AACF,wFAAwF;AACxF,iEAAiE;AACjE,iEAAiE;AACjE,qCAAqC;AACrC,EAAE;AACF,oEAAoE;AACpE,uEAAuE;AACvE,6CAA6C;AAC7C,qEAAqE;AACrE,iEAAiE;AACjE,gCAAgC;AAEhC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,aAAa,EAAE,OAAO,CAAU,CAAC;AAEhE,MAAM,CAAC,MAAM,eAAe,GAAY,aAAa,CAAC;AAEtD,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,cAAoC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAuB;IAIlD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC1E,IAAI,SAAS,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3D,OAAO;QACL,OAAO,EAAE,eAAe;QACxB,OAAO,EAAE,wBAAwB,IAAI,CAAC,SAAS,CAC7C,GAAG,CACJ,sBAAsB,eAAe,eAAe,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;KAClF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Pack `source:` strings parse here. v1 only resolves `builtin`; future
|
|
2
|
+
// values (`path:./foo`, `npm:@scope/pack@1.0.0`, `git:https://...`) are
|
|
3
|
+
// reserved for community-authored packs and surface as `kind: "unknown"`
|
|
4
|
+
// today, with the canonical-doc-pointer in the warning.
|
|
5
|
+
export function parsePackSource(source) {
|
|
6
|
+
if (source === "builtin")
|
|
7
|
+
return { kind: "builtin", raw: source };
|
|
8
|
+
return { kind: "unknown", raw: source };
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/policy-packs/source.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,wEAAwE;AACxE,yEAAyE;AACzE,wDAAwD;AASxD,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAClE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Hook } from "../schema/index.js";
|
|
2
|
+
export interface PackContributionFile {
|
|
3
|
+
/** Relative path under `harness.generated/`, including the policy-packs/ prefix. */
|
|
4
|
+
relativePath: string;
|
|
5
|
+
content: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Phase 6 #5 — permissions contributed by a pack's selected
|
|
9
|
+
* permission profile. Translated downstream into the Claude Code
|
|
10
|
+
* settings.json `permissions` block.
|
|
11
|
+
*/
|
|
12
|
+
export interface PackPermissionsContribution {
|
|
13
|
+
allow: string[];
|
|
14
|
+
ask: string[];
|
|
15
|
+
deny: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface PackContribution {
|
|
18
|
+
/** Hooks to merge into the manifest before settings.json generation. */
|
|
19
|
+
hooks: Hook[];
|
|
20
|
+
/** Files to write under `harness.generated/`. */
|
|
21
|
+
files: PackContributionFile[];
|
|
22
|
+
/** Optional permission contribution (Phase 6 #5). */
|
|
23
|
+
permissions?: PackPermissionsContribution;
|
|
24
|
+
}
|
|
25
|
+
export interface PackExpansionResult {
|
|
26
|
+
/** Combined hooks contributed by every enabled, resolvable pack. */
|
|
27
|
+
hooks: Hook[];
|
|
28
|
+
/** Combined files contributed by every enabled, resolvable pack. */
|
|
29
|
+
files: PackContributionFile[];
|
|
30
|
+
/**
|
|
31
|
+
* Combined permissions contributed by every enabled, resolvable
|
|
32
|
+
* pack (set-union per bucket; later contributions cannot relax a
|
|
33
|
+
* deny from an earlier pack). undefined when no pack contributed
|
|
34
|
+
* any permission entries.
|
|
35
|
+
*/
|
|
36
|
+
permissions?: PackPermissionsContribution;
|
|
37
|
+
/** Non-fatal expansion warnings (e.g. unknown source, unknown name on a non-strict path). */
|
|
38
|
+
warnings: string[];
|
|
39
|
+
/** Names of packs that were skipped because `enabled: false`. */
|
|
40
|
+
skipped: string[];
|
|
41
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Shared types for the policy-pack expansion pipeline.
|
|
2
|
+
//
|
|
3
|
+
// A pack contribution is the data a builtin pack produces at apply time:
|
|
4
|
+
// a list of hooks to merge into the in-memory manifest before settings
|
|
5
|
+
// generation, plus a list of files to write under
|
|
6
|
+
// `harness.generated/policy-packs/<name>/`.
|
|
7
|
+
//
|
|
8
|
+
// The `Hook` shape mirrors the manifest's hooks[] entry exactly (so the
|
|
9
|
+
// existing generate-settings projection picks them up unchanged).
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|