@windyroad/voice-tone 0.5.14 → 0.6.0-preview.764
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.
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
# PreToolUse, nothing to read.)
|
|
25
25
|
#
|
|
26
26
|
# Gate behaviour:
|
|
27
|
-
# 1.
|
|
27
|
+
# 1. (removed P377/RFC-029) — BYPASS_RISK_GATE env override no longer exists; the gate is cleared only by delegating to the reviewer.
|
|
28
28
|
# 2. POLICY_FILE absent → advisory-only mode (permits with systemMessage).
|
|
29
29
|
# 3. Hybrid leak-pattern pre-filter (lib/leak-detect.sh) hard-fails on
|
|
30
30
|
# credentials, prod-URL prefixes, business-context-paired financial figures,
|
|
@@ -97,10 +97,11 @@ EXTERNAL_COMMS_POLICY_FILE="${EXTERNAL_COMMS_POLICY_FILE:-RISK-POLICY.md}"
|
|
|
97
97
|
EXTERNAL_COMMS_LEAK_PREFILTER="${EXTERNAL_COMMS_LEAK_PREFILTER:-yes}"
|
|
98
98
|
EXTERNAL_COMMS_SKIP_SURFACES="${EXTERNAL_COMMS_SKIP_SURFACES:-}"
|
|
99
99
|
|
|
100
|
-
#
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
# P377/RFC-029: the BYPASS_RISK_GATE=1 env override is REMOVED (never
|
|
101
|
+
# authorised). There is no env escape from the external-comms gate — clear it
|
|
102
|
+
# by delegating to the wr-risk-scorer:external-comms reviewer (the gate marks
|
|
103
|
+
# the draft reviewed on a PASS verdict). A genuine gate misfire is recovered
|
|
104
|
+
# per ADR-048 (documented recovery), not an env bypass.
|
|
104
105
|
|
|
105
106
|
INPUT=$(cat)
|
|
106
107
|
|
|
@@ -316,7 +317,7 @@ fi
|
|
|
316
317
|
# EXTERNAL_COMMS_LEAK_PREFILTER=yes (risk) or =no (voice-tone).
|
|
317
318
|
if [ "$EXTERNAL_COMMS_LEAK_PREFILTER" = "yes" ]; then
|
|
318
319
|
if ! leak_detect_scan "$DRAFT"; then
|
|
319
|
-
REASON=$(printf 'BLOCKED (external-comms gate / %s evaluator): %s on %s. Remove the leak before retrying.
|
|
320
|
+
REASON=$(printf 'BLOCKED (external-comms gate / %s evaluator): %s on %s. Remove the leak before retrying. There is no env override (P377/RFC-029 — BYPASS_RISK_GATE removed).' \
|
|
320
321
|
"$EXTERNAL_COMMS_EVALUATOR_ID" "$LEAK_DETECT_REASON" "$SURFACE")
|
|
321
322
|
deny_with_reason "$REASON"
|
|
322
323
|
exit 0
|
|
@@ -386,7 +387,7 @@ fi
|
|
|
386
387
|
# PostToolUse mark hook can derive the canonical marker key locally
|
|
387
388
|
# (sha256(DRAFT + '\n' + SURFACE)). Single fire per gate cycle.
|
|
388
389
|
VERDICT_PREFIX="${EXTERNAL_COMMS_VERDICT_PREFIX:-EXTERNAL_COMMS_${EXTERNAL_COMMS_EVALUATOR_ID^^}}"
|
|
389
|
-
REASON=$(printf 'BLOCKED (external-comms gate / %s evaluator): %s draft has not been reviewed by %s. Delegate to %s (subagent_type: '"'"'%s'"'"') with a prompt that starts with the line `SURFACE: %s` and wraps the draft body verbatim inside `<draft>...</draft>` markers (for the changeset-author surface the body is the changeset summary WITHOUT the leading `---` frontmatter block — the gate strips frontmatter before hashing the marker key). The PostToolUse hook derives the marker key from that structure and marks the draft reviewed when the subagent emits %s_VERDICT: PASS — single fire suffices. Use %s for an interactive walkthrough.
|
|
390
|
+
REASON=$(printf 'BLOCKED (external-comms gate / %s evaluator): %s draft has not been reviewed by %s. Delegate to %s (subagent_type: '"'"'%s'"'"') with a prompt that starts with the line `SURFACE: %s` and wraps the draft body verbatim inside `<draft>...</draft>` markers (for the changeset-author surface the body is the changeset summary WITHOUT the leading `---` frontmatter block — the gate strips frontmatter before hashing the marker key). The PostToolUse hook derives the marker key from that structure and marks the draft reviewed when the subagent emits %s_VERDICT: PASS — single fire suffices. Use %s for an interactive walkthrough. There is no env override (P377/RFC-029 — BYPASS_RISK_GATE removed).' \
|
|
390
391
|
"$EXTERNAL_COMMS_EVALUATOR_ID" "$SURFACE" "$EXTERNAL_COMMS_SUBAGENT_TYPE" "$EXTERNAL_COMMS_SUBAGENT_TYPE" "$EXTERNAL_COMMS_SUBAGENT_TYPE" "$SURFACE" "$VERDICT_PREFIX" "$EXTERNAL_COMMS_ASSESS_SKILL")
|
|
391
392
|
deny_with_reason "$REASON"
|
|
392
393
|
exit 0
|
package/lib/install-utils.mjs
CHANGED
|
@@ -7,10 +7,12 @@ import { execSync } from "node:child_process";
|
|
|
7
7
|
|
|
8
8
|
const MARKETPLACE_REPO = "windyroad/agent-plugins";
|
|
9
9
|
const MARKETPLACE_NAME = "windyroad";
|
|
10
|
+
const CODEX_MARKETPLACE_PATH = ".";
|
|
11
|
+
const CODEX_MARKETPLACE_NAME = "windyroad-local";
|
|
10
12
|
|
|
11
13
|
let _dryRun = false;
|
|
12
14
|
|
|
13
|
-
export { MARKETPLACE_REPO, MARKETPLACE_NAME };
|
|
15
|
+
export { MARKETPLACE_REPO, MARKETPLACE_NAME, CODEX_MARKETPLACE_PATH, CODEX_MARKETPLACE_NAME };
|
|
14
16
|
|
|
15
17
|
export function setDryRun(value) {
|
|
16
18
|
_dryRun = value;
|
|
@@ -35,16 +37,34 @@ export function run(cmd, label) {
|
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
function runtimesFor(runtime = "claude") {
|
|
41
|
+
if (runtime === "both") return ["claude", "codex"];
|
|
42
|
+
return [runtime];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function checkPrerequisites({ runtime = "claude" } = {}) {
|
|
39
46
|
if (_dryRun) return;
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
for (const currentRuntime of runtimesFor(runtime)) {
|
|
49
|
+
if (currentRuntime === "claude") {
|
|
50
|
+
try {
|
|
51
|
+
execSync("claude --version", { stdio: "pipe" });
|
|
52
|
+
} catch {
|
|
53
|
+
console.error(
|
|
54
|
+
"Error: 'claude' CLI not found. Install Claude Code first:\n https://docs.anthropic.com/en/docs/claude-code\n"
|
|
55
|
+
);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
} else if (currentRuntime === "codex") {
|
|
59
|
+
try {
|
|
60
|
+
execSync("codex --version", { stdio: "pipe" });
|
|
61
|
+
} catch {
|
|
62
|
+
console.error(
|
|
63
|
+
"Error: 'codex' CLI not found. Install Codex CLI first:\n https://developers.openai.com/codex\n"
|
|
64
|
+
);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
48
68
|
}
|
|
49
69
|
}
|
|
50
70
|
|
|
@@ -55,6 +75,13 @@ export function addMarketplace() {
|
|
|
55
75
|
);
|
|
56
76
|
}
|
|
57
77
|
|
|
78
|
+
export function addCodexMarketplace() {
|
|
79
|
+
return run(
|
|
80
|
+
`codex plugin marketplace add ${CODEX_MARKETPLACE_PATH}`,
|
|
81
|
+
`Codex marketplace: ${CODEX_MARKETPLACE_NAME}`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
58
85
|
export function installPlugin(pluginName, { scope = "project" } = {}) {
|
|
59
86
|
return run(
|
|
60
87
|
`claude plugin install ${pluginName}@${MARKETPLACE_NAME} --scope ${scope}`,
|
|
@@ -62,6 +89,13 @@ export function installPlugin(pluginName, { scope = "project" } = {}) {
|
|
|
62
89
|
);
|
|
63
90
|
}
|
|
64
91
|
|
|
92
|
+
export function installCodexPlugin(pluginName) {
|
|
93
|
+
return run(
|
|
94
|
+
`codex plugin add ${pluginName}@${CODEX_MARKETPLACE_NAME}`,
|
|
95
|
+
pluginName
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
65
99
|
export function updatePlugin(pluginName, { scope = "project" } = {}) {
|
|
66
100
|
return run(
|
|
67
101
|
`claude plugin update "${pluginName}@${MARKETPLACE_NAME}" --scope ${scope}`,
|
|
@@ -69,18 +103,36 @@ export function updatePlugin(pluginName, { scope = "project" } = {}) {
|
|
|
69
103
|
);
|
|
70
104
|
}
|
|
71
105
|
|
|
106
|
+
export function updateCodexMarketplace() {
|
|
107
|
+
return run(
|
|
108
|
+
`codex plugin marketplace add ${CODEX_MARKETPLACE_PATH}`,
|
|
109
|
+
`Codex marketplace: ${CODEX_MARKETPLACE_NAME}`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
72
113
|
export function uninstallPlugin(pluginName) {
|
|
73
114
|
return run(`claude plugin uninstall ${pluginName}`, `Removing ${pluginName}`);
|
|
74
115
|
}
|
|
75
116
|
|
|
117
|
+
export function uninstallCodexPlugin(pluginName) {
|
|
118
|
+
return run(`codex plugin remove ${pluginName}`, `Removing ${pluginName}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
76
121
|
/**
|
|
77
122
|
* Install a single package: marketplace add + plugin install.
|
|
78
123
|
*/
|
|
79
|
-
export function installPackage(pluginName, { deps = [], scope = "project" } = {}) {
|
|
124
|
+
export function installPackage(pluginName, { deps = [], scope = "project", runtime = "claude" } = {}) {
|
|
80
125
|
console.log(`\nInstalling @windyroad/${pluginName.replace("wr-", "")} (${scope} scope)...\n`);
|
|
81
126
|
|
|
82
|
-
|
|
83
|
-
|
|
127
|
+
if (runtime === "claude" || runtime === "both") {
|
|
128
|
+
addMarketplace();
|
|
129
|
+
installPlugin(pluginName, { scope });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (runtime === "codex" || runtime === "both") {
|
|
133
|
+
addCodexMarketplace();
|
|
134
|
+
installCodexPlugin(pluginName);
|
|
135
|
+
}
|
|
84
136
|
|
|
85
137
|
if (deps.length > 0) {
|
|
86
138
|
console.log(`\nNote: This plugin works best with:`);
|
|
@@ -90,34 +142,47 @@ export function installPackage(pluginName, { deps = [], scope = "project" } = {}
|
|
|
90
142
|
}
|
|
91
143
|
|
|
92
144
|
console.log(
|
|
93
|
-
`\nDone! Restart Claude Code to activate.\n`
|
|
145
|
+
`\nDone! Restart ${runtime === "codex" ? "Codex" : runtime === "both" ? "Claude Code and Codex" : "Claude Code"} to activate.\n`
|
|
94
146
|
);
|
|
95
147
|
}
|
|
96
148
|
|
|
97
149
|
/**
|
|
98
150
|
* Update a single package.
|
|
99
151
|
*/
|
|
100
|
-
export function updatePackage(pluginName, { scope = "project" } = {}) {
|
|
152
|
+
export function updatePackage(pluginName, { scope = "project", runtime = "claude" } = {}) {
|
|
101
153
|
console.log(`\nUpdating @windyroad/${pluginName.replace("wr-", "")}...\n`);
|
|
102
154
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
155
|
+
if (runtime === "claude" || runtime === "both") {
|
|
156
|
+
run(
|
|
157
|
+
`claude plugin marketplace update ${MARKETPLACE_NAME}`,
|
|
158
|
+
"Updating marketplace"
|
|
159
|
+
);
|
|
160
|
+
updatePlugin(pluginName, { scope });
|
|
161
|
+
}
|
|
108
162
|
|
|
109
|
-
|
|
163
|
+
if (runtime === "codex" || runtime === "both") {
|
|
164
|
+
updateCodexMarketplace();
|
|
165
|
+
installCodexPlugin(pluginName);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log(`\nDone! Restart ${runtime === "codex" ? "Codex" : runtime === "both" ? "Claude Code and Codex" : "Claude Code"} to apply updates.\n`);
|
|
110
169
|
}
|
|
111
170
|
|
|
112
171
|
/**
|
|
113
172
|
* Uninstall a single package.
|
|
114
173
|
*/
|
|
115
|
-
export function uninstallPackage(pluginName) {
|
|
174
|
+
export function uninstallPackage(pluginName, { runtime = "claude" } = {}) {
|
|
116
175
|
console.log(`\nUninstalling @windyroad/${pluginName.replace("wr-", "")}...\n`);
|
|
117
176
|
|
|
118
|
-
|
|
177
|
+
if (runtime === "claude" || runtime === "both") {
|
|
178
|
+
uninstallPlugin(pluginName);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (runtime === "codex" || runtime === "both") {
|
|
182
|
+
uninstallCodexPlugin(pluginName);
|
|
183
|
+
}
|
|
119
184
|
|
|
120
|
-
console.log(
|
|
185
|
+
console.log(`\nDone. Restart ${runtime === "codex" ? "Codex" : runtime === "both" ? "Claude Code and Codex" : "Claude Code"} to apply changes.\n`);
|
|
121
186
|
}
|
|
122
187
|
|
|
123
188
|
/**
|
|
@@ -131,6 +196,7 @@ export function parseStandardArgs(argv) {
|
|
|
131
196
|
update: args.includes("--update"),
|
|
132
197
|
dryRun: args.includes("--dry-run"),
|
|
133
198
|
scope: "project",
|
|
199
|
+
runtime: "claude",
|
|
134
200
|
};
|
|
135
201
|
const scopeIdx = args.indexOf("--scope");
|
|
136
202
|
if (scopeIdx !== -1 && args[scopeIdx + 1]) {
|
|
@@ -142,5 +208,15 @@ export function parseStandardArgs(argv) {
|
|
|
142
208
|
process.exit(1);
|
|
143
209
|
}
|
|
144
210
|
}
|
|
211
|
+
const runtimeIdx = args.indexOf("--runtime");
|
|
212
|
+
if (runtimeIdx !== -1 && args[runtimeIdx + 1]) {
|
|
213
|
+
const val = args[runtimeIdx + 1];
|
|
214
|
+
if (["claude", "codex", "both"].includes(val)) {
|
|
215
|
+
flags.runtime = val;
|
|
216
|
+
} else {
|
|
217
|
+
console.error("--runtime requires: claude, codex, or both");
|
|
218
|
+
process.exit(1);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
145
221
|
return flags;
|
|
146
222
|
}
|