@orchid-labs/pluxx 0.1.21 → 0.1.22
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/README.md +5 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/index.js +361 -108
- package/dist/cli/install.d.ts.map +1 -1
- package/dist/cli/primitive-summary.d.ts.map +1 -1
- package/dist/cli/publish.d.ts.map +1 -1
- package/dist/codex-hooks-feature.d.ts +1 -1
- package/dist/codex-hooks-feature.d.ts.map +1 -1
- package/dist/compatibility/core-four-primitives.d.ts +5 -0
- package/dist/compatibility/core-four-primitives.d.ts.map +1 -0
- package/dist/compatibility/matrix.d.ts +1 -0
- package/dist/compatibility/matrix.d.ts.map +1 -1
- package/dist/generators/opencode/index.d.ts.map +1 -1
- package/dist/hook-command-env.d.ts.map +1 -1
- package/dist/hook-events.d.ts +1 -0
- package/dist/hook-events.d.ts.map +1 -1
- package/dist/index.js +286 -45
- package/dist/readiness.d.ts.map +1 -1
- package/dist/user-config.d.ts +11 -0
- package/dist/user-config.d.ts.map +1 -1
- package/dist/validation/platform-rules.d.ts +1 -0
- package/dist/validation/platform-rules.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7841,6 +7841,20 @@ function definePlugin(config) {
|
|
|
7841
7841
|
return PluginConfigSchema.parse(config);
|
|
7842
7842
|
}
|
|
7843
7843
|
|
|
7844
|
+
// src/hook-events.ts
|
|
7845
|
+
var CODEX_SUPPORTED_HOOK_EVENTS = [
|
|
7846
|
+
"SessionStart",
|
|
7847
|
+
"SubagentStart",
|
|
7848
|
+
"PreToolUse",
|
|
7849
|
+
"PermissionRequest",
|
|
7850
|
+
"PostToolUse",
|
|
7851
|
+
"PreCompact",
|
|
7852
|
+
"PostCompact",
|
|
7853
|
+
"UserPromptSubmit",
|
|
7854
|
+
"SubagentStop",
|
|
7855
|
+
"Stop"
|
|
7856
|
+
];
|
|
7857
|
+
|
|
7844
7858
|
// src/runtime-readiness-registry.ts
|
|
7845
7859
|
function getEnabledRuntimeReadinessBindings(capability, plan) {
|
|
7846
7860
|
return capability.bindings.filter((binding) => {
|
|
@@ -7855,7 +7869,7 @@ function getEnabledRuntimeReadinessBindings(capability, plan) {
|
|
|
7855
7869
|
});
|
|
7856
7870
|
}
|
|
7857
7871
|
var NAMED_PROMPT_TARGET_NOTE = "Named `skills` / `commands` readiness targets currently translate through prompt-entry gating with best-effort matching because the core four do not share one exact per-skill or per-command runtime interception surface.";
|
|
7858
|
-
var CODEX_EXTERNAL_NOTE = "Codex readiness now bundles translated hooks in the plugin, and Pluxx still emits `.codex/readiness.generated.json` plus `.codex/hooks.generated.json` as debugging companions because
|
|
7872
|
+
var CODEX_EXTERNAL_NOTE = "Codex readiness now bundles translated hooks in the plugin, and Pluxx still emits `.codex/readiness.generated.json` plus `.codex/hooks.generated.json` as debugging companions because hook activation still depends on `[features].hooks = true`, enabled plugin state, review, trust, and runtime support. `codex_hooks` is deprecated and should not be treated as the current hook feature key.";
|
|
7859
7873
|
function getRuntimeReadinessNamedPromptTargetNote() {
|
|
7860
7874
|
return NAMED_PROMPT_TARGET_NOTE;
|
|
7861
7875
|
}
|
|
@@ -8103,7 +8117,7 @@ var PLATFORM_LIMIT_POLICIES = {
|
|
|
8103
8117
|
},
|
|
8104
8118
|
hooksFeatureFlag: {
|
|
8105
8119
|
kind: "hard",
|
|
8106
|
-
notes: "
|
|
8120
|
+
notes: "Codex hook support depends on the canonical hooks feature flag plus enabled-plugin, trust/review, and runtime support."
|
|
8107
8121
|
}
|
|
8108
8122
|
},
|
|
8109
8123
|
"cursor": {
|
|
@@ -8303,8 +8317,8 @@ var PLATFORM_VALIDATION_RULES = {
|
|
|
8303
8317
|
hooks: {
|
|
8304
8318
|
supported: true,
|
|
8305
8319
|
files: ["hooks/hooks.json", ".codex/hooks.json", "~/.codex/hooks.json"],
|
|
8306
|
-
eventNames: [
|
|
8307
|
-
notes: "Codex documents both project
|
|
8320
|
+
eventNames: [...CODEX_SUPPORTED_HOOK_EVENTS],
|
|
8321
|
+
notes: "Codex documents both project/user hook config and plugin-bundled hooks. Plugin-bundled hooks live at `hooks/hooks.json` in the plugin and require the canonical `[features].hooks = true` flag, enabled plugin state, user review, trust, and runtime support. `codex_hooks` is deprecated and should not be treated as the current hook feature key."
|
|
8308
8322
|
},
|
|
8309
8323
|
instructions: {
|
|
8310
8324
|
files: ["AGENTS.md", "AGENTS.override.md"],
|
|
@@ -8743,7 +8757,7 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
|
|
|
8743
8757
|
hooks: {
|
|
8744
8758
|
mode: "translate",
|
|
8745
8759
|
nativeSurfaces: ["hooks/hooks.json", ".codex/hooks.json", "~/.codex/hooks.json"],
|
|
8746
|
-
notes: "Hooks are native. Pluxx bundles translated Codex hooks in the plugin with the documented `[features].
|
|
8760
|
+
notes: "Hooks are native. Pluxx bundles translated Codex hooks in the plugin with the documented `[features].hooks = true` feature key, and still tracks broader project/user hook config paths where `codex_hooks` is deprecated. Plugin-bundled execution still also depends on enabled plugin state, review, trust, and runtime support."
|
|
8747
8761
|
},
|
|
8748
8762
|
permissions: {
|
|
8749
8763
|
mode: "translate",
|
|
@@ -9139,6 +9153,78 @@ function getPublishReloadInstruction(target) {
|
|
|
9139
9153
|
return PUBLISH_RELOAD_INSTRUCTIONS[target];
|
|
9140
9154
|
}
|
|
9141
9155
|
|
|
9156
|
+
// src/mcp-native-overrides.ts
|
|
9157
|
+
function asRecord(value) {
|
|
9158
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
9159
|
+
return value;
|
|
9160
|
+
}
|
|
9161
|
+
function firstString(...values) {
|
|
9162
|
+
for (const value of values) {
|
|
9163
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
9164
|
+
}
|
|
9165
|
+
return void 0;
|
|
9166
|
+
}
|
|
9167
|
+
function readStringRecord(value) {
|
|
9168
|
+
const record = asRecord(value);
|
|
9169
|
+
if (!record) return void 0;
|
|
9170
|
+
const stringRecord = Object.fromEntries(
|
|
9171
|
+
Object.entries(record).filter(([, entryValue]) => typeof entryValue === "string")
|
|
9172
|
+
);
|
|
9173
|
+
return Object.keys(stringRecord).length > 0 ? stringRecord : void 0;
|
|
9174
|
+
}
|
|
9175
|
+
function extractEnvVar(value) {
|
|
9176
|
+
const match = value.match(/\$\{(?:env:)?([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/);
|
|
9177
|
+
return match?.[1] ?? match?.[2];
|
|
9178
|
+
}
|
|
9179
|
+
function envVarToKey(envVar) {
|
|
9180
|
+
return envVar.toLowerCase().replace(/_/g, "-");
|
|
9181
|
+
}
|
|
9182
|
+
function collectNativeMcpAuthUserConfigEntries(config, platforms, existingFields) {
|
|
9183
|
+
const next = [];
|
|
9184
|
+
const seenKeys = new Set(existingFields.map((field) => field.key));
|
|
9185
|
+
const seenEnvVars = new Set(
|
|
9186
|
+
existingFields.map((field) => field.envVar ?? defaultUserConfigEnvVar(field.key))
|
|
9187
|
+
);
|
|
9188
|
+
const pushDerived = (envVar, platform, serverName) => {
|
|
9189
|
+
if (!envVar || seenEnvVars.has(envVar)) return;
|
|
9190
|
+
const key = envVarToKey(envVar);
|
|
9191
|
+
if (seenKeys.has(key)) return;
|
|
9192
|
+
seenEnvVars.add(envVar);
|
|
9193
|
+
seenKeys.add(key);
|
|
9194
|
+
next.push({
|
|
9195
|
+
key,
|
|
9196
|
+
title: envVar,
|
|
9197
|
+
description: `Derived from native ${platform} MCP auth for ${serverName}.`,
|
|
9198
|
+
type: "secret",
|
|
9199
|
+
required: true,
|
|
9200
|
+
envVar,
|
|
9201
|
+
targets: [platform]
|
|
9202
|
+
});
|
|
9203
|
+
};
|
|
9204
|
+
for (const platform of platforms) {
|
|
9205
|
+
const platformConfig = asRecord(config.platforms?.[platform]);
|
|
9206
|
+
const mcpServers = asRecord(platformConfig?.mcpServers);
|
|
9207
|
+
if (!mcpServers) continue;
|
|
9208
|
+
for (const [serverName, rawOverride] of Object.entries(mcpServers)) {
|
|
9209
|
+
const override = asRecord(rawOverride);
|
|
9210
|
+
if (!override) continue;
|
|
9211
|
+
const bearerTokenEnv = firstString(override.bearer_token_env_var, override.bearerTokenEnvVar);
|
|
9212
|
+
if (bearerTokenEnv) pushDerived(bearerTokenEnv, platform, serverName);
|
|
9213
|
+
for (const record of [
|
|
9214
|
+
readStringRecord(override.env_http_headers ?? override.envHttpHeaders),
|
|
9215
|
+
readStringRecord(override.headers),
|
|
9216
|
+
readStringRecord(override.http_headers ?? override.httpHeaders)
|
|
9217
|
+
]) {
|
|
9218
|
+
for (const value of Object.values(record ?? {})) {
|
|
9219
|
+
const envVar = extractEnvVar(value) ?? value;
|
|
9220
|
+
pushDerived(envVar, platform, serverName);
|
|
9221
|
+
}
|
|
9222
|
+
}
|
|
9223
|
+
}
|
|
9224
|
+
}
|
|
9225
|
+
return next;
|
|
9226
|
+
}
|
|
9227
|
+
|
|
9142
9228
|
// src/cli/publish.ts
|
|
9143
9229
|
var INSTALLER_TARGETS = ["claude-code", "cursor", "codex", "opencode"];
|
|
9144
9230
|
function runCommandDefault(command, args, options) {
|
|
@@ -9438,8 +9524,15 @@ echo
|
|
|
9438
9524
|
echo "Installed __DISPLAY_NAME__ across ${installerTargets.join(", ")}."
|
|
9439
9525
|
`.replaceAll("__REPO__", "REPO_PLACEHOLDER").replaceAll("__DISPLAY_NAME__", "DISPLAY_PLACEHOLDER");
|
|
9440
9526
|
}
|
|
9527
|
+
function collectInstallerUserConfigEntries(config, platforms) {
|
|
9528
|
+
const baseEntries = collectUserConfigEntries(config, platforms);
|
|
9529
|
+
return [
|
|
9530
|
+
...baseEntries,
|
|
9531
|
+
...collectNativeMcpAuthUserConfigEntries(config, platforms, baseEntries)
|
|
9532
|
+
];
|
|
9533
|
+
}
|
|
9441
9534
|
function renderInstallerUserConfigSnippet(config, platform, installDirVariable) {
|
|
9442
|
-
const entries =
|
|
9535
|
+
const entries = collectInstallerUserConfigEntries(config, [platform]).map((entry) => ({
|
|
9443
9536
|
key: entry.key,
|
|
9444
9537
|
title: entry.title,
|
|
9445
9538
|
type: entry.type ?? "string",
|
|
@@ -9447,6 +9540,7 @@ function renderInstallerUserConfigSnippet(config, platform, installDirVariable)
|
|
|
9447
9540
|
envVar: entry.envVar ?? defaultUserConfigEnvVar(entry.key)
|
|
9448
9541
|
}));
|
|
9449
9542
|
if (entries.length === 0) return "";
|
|
9543
|
+
const preserveSecretReferences = platform === "codex";
|
|
9450
9544
|
const promptLines = entries.map((entry) => {
|
|
9451
9545
|
const functionName = entry.type === "secret" ? "pluxx_prompt_secret_config" : "pluxx_prompt_text_config";
|
|
9452
9546
|
return `${functionName} ${JSON.stringify(entry.key)} ${JSON.stringify(entry.envVar)} ${JSON.stringify(entry.title)} ${entry.required ? "1" : "0"}`;
|
|
@@ -9457,6 +9551,8 @@ ${JSON.stringify(entries)}
|
|
|
9457
9551
|
PLUXX_USER_CONFIG_JSON
|
|
9458
9552
|
)"
|
|
9459
9553
|
PLUXX_REUSED_USER_CONFIG=0
|
|
9554
|
+
PLUXX_PRESERVE_SECRET_REFS="${preserveSecretReferences ? "1" : "0"}"
|
|
9555
|
+
export PLUXX_PRESERVE_SECRET_REFS
|
|
9460
9556
|
|
|
9461
9557
|
pluxx_is_placeholder_secret() {
|
|
9462
9558
|
case "$1" in
|
|
@@ -9483,12 +9579,14 @@ const fs = require('fs')
|
|
|
9483
9579
|
const filepath = process.env.PLUXX_SAVED_USER_CONFIG_PATH
|
|
9484
9580
|
const key = process.env.PLUXX_SAVED_CONFIG_KEY
|
|
9485
9581
|
const envVar = process.env.PLUXX_SAVED_CONFIG_ENV_VAR
|
|
9582
|
+
const preserveSecretRefs = process.env.PLUXX_PRESERVE_SECRET_REFS === '1'
|
|
9486
9583
|
|
|
9487
9584
|
try {
|
|
9488
9585
|
const payload = JSON.parse(fs.readFileSync(filepath, 'utf8'))
|
|
9489
9586
|
const candidates = [
|
|
9490
9587
|
payload && payload.env && envVar ? payload.env[envVar] : undefined,
|
|
9491
9588
|
payload && payload.values && key ? payload.values[key] : undefined,
|
|
9589
|
+
preserveSecretRefs && payload && payload.envRefs && envVar && payload.envRefs[envVar] === envVar ? envVar : undefined,
|
|
9492
9590
|
]
|
|
9493
9591
|
|
|
9494
9592
|
for (const candidate of candidates) {
|
|
@@ -9584,21 +9682,53 @@ const path = require('path')
|
|
|
9584
9682
|
|
|
9585
9683
|
const installDir = process.env.PLUXX_INSTALL_DIR
|
|
9586
9684
|
const spec = JSON.parse(process.env.PLUXX_USER_CONFIG_SPEC || '[]')
|
|
9685
|
+
const preserveSecretReferences = ${preserveSecretReferences ? "true" : "false"}
|
|
9587
9686
|
|
|
9588
9687
|
if (installDir && spec.length > 0) {
|
|
9589
9688
|
const env = {}
|
|
9590
9689
|
const values = {}
|
|
9690
|
+
const envRefs = {}
|
|
9691
|
+
const secretKeys = []
|
|
9692
|
+
const secretEnv = []
|
|
9693
|
+
let hasSecret = false
|
|
9694
|
+
const secretEnvVars = new Set(
|
|
9695
|
+
spec
|
|
9696
|
+
.filter((entry) => entry && entry.type === 'secret' && typeof entry.envVar === 'string' && entry.envVar !== '')
|
|
9697
|
+
.map((entry) => entry.envVar),
|
|
9698
|
+
)
|
|
9591
9699
|
|
|
9592
9700
|
for (const entry of spec) {
|
|
9701
|
+
if (entry.type === 'secret') {
|
|
9702
|
+
hasSecret = true
|
|
9703
|
+
if (preserveSecretReferences) {
|
|
9704
|
+
if (entry.key) secretKeys.push(entry.key)
|
|
9705
|
+
if (entry.envVar) secretEnv.push(entry.envVar)
|
|
9706
|
+
}
|
|
9707
|
+
}
|
|
9593
9708
|
const value = process.env[entry.envVar]
|
|
9594
9709
|
if (value === undefined || value === '') continue
|
|
9710
|
+
if (preserveSecretReferences && entry.type === 'secret') {
|
|
9711
|
+
envRefs[entry.envVar] = entry.envVar
|
|
9712
|
+
continue
|
|
9713
|
+
}
|
|
9595
9714
|
values[entry.key] = value
|
|
9596
9715
|
env[entry.envVar] = value
|
|
9597
9716
|
}
|
|
9598
9717
|
|
|
9599
9718
|
fs.writeFileSync(
|
|
9600
9719
|
path.join(installDir, '.pluxx-user.json'),
|
|
9601
|
-
JSON.stringify(
|
|
9720
|
+
JSON.stringify(
|
|
9721
|
+
{
|
|
9722
|
+
...(Object.keys(values).length > 0 ? { values } : {}),
|
|
9723
|
+
...(Object.keys(env).length > 0 ? { env } : {}),
|
|
9724
|
+
...(Object.keys(envRefs).length > 0 ? { envRefs } : {}),
|
|
9725
|
+
...(hasSecret ? { secretStorage: preserveSecretReferences ? 'env-ref' : 'materialized' } : {}),
|
|
9726
|
+
...(preserveSecretReferences && secretKeys.length > 0 ? { secretKeys: [...new Set(secretKeys)].sort() } : {}),
|
|
9727
|
+
...(preserveSecretReferences && secretEnv.length > 0 ? { secretEnv: [...new Set(secretEnv)].sort() } : {}),
|
|
9728
|
+
},
|
|
9729
|
+
null,
|
|
9730
|
+
2,
|
|
9731
|
+
) + '\\n',
|
|
9602
9732
|
)
|
|
9603
9733
|
|
|
9604
9734
|
const envScriptPath = path.join(installDir, 'scripts/check-env.sh')
|
|
@@ -9611,7 +9741,10 @@ if (installDir && spec.length > 0) {
|
|
|
9611
9741
|
|
|
9612
9742
|
const materialize = (value) =>
|
|
9613
9743
|
typeof value === 'string'
|
|
9614
|
-
? value.replace(
|
|
9744
|
+
? value.replace(
|
|
9745
|
+
/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g,
|
|
9746
|
+
(_match, name) => (preserveSecretReferences && secretEnvVars.has(name) ? '${" + name + "}' : (env[name] || '${" + name + "}')),
|
|
9747
|
+
)
|
|
9615
9748
|
: value
|
|
9616
9749
|
|
|
9617
9750
|
const materializeRecord = (record) => {
|
|
@@ -9635,7 +9768,7 @@ if (installDir && spec.length > 0) {
|
|
|
9635
9768
|
server.env = materializeRecord(server.env)
|
|
9636
9769
|
}
|
|
9637
9770
|
|
|
9638
|
-
if (server.bearer_token_env_var && env[server.bearer_token_env_var]) {
|
|
9771
|
+
if (!preserveSecretReferences && server.bearer_token_env_var && env[server.bearer_token_env_var]) {
|
|
9639
9772
|
server.http_headers = {
|
|
9640
9773
|
...(server.http_headers || {}),
|
|
9641
9774
|
Authorization: 'Bearer ' + env[server.bearer_token_env_var],
|
|
@@ -9643,7 +9776,7 @@ if (installDir && spec.length > 0) {
|
|
|
9643
9776
|
delete server.bearer_token_env_var
|
|
9644
9777
|
}
|
|
9645
9778
|
|
|
9646
|
-
if (server.env_http_headers && typeof server.env_http_headers === 'object') {
|
|
9779
|
+
if (!preserveSecretReferences && server.env_http_headers && typeof server.env_http_headers === 'object') {
|
|
9647
9780
|
server.http_headers = {
|
|
9648
9781
|
...(server.http_headers || {}),
|
|
9649
9782
|
}
|
|
@@ -9668,7 +9801,7 @@ NODE
|
|
|
9668
9801
|
`;
|
|
9669
9802
|
}
|
|
9670
9803
|
function hasInstallerUserConfig(config, platform) {
|
|
9671
|
-
return
|
|
9804
|
+
return collectInstallerUserConfigEntries(config, [platform]).length > 0;
|
|
9672
9805
|
}
|
|
9673
9806
|
function renderInstallerSavedUserConfigCaptureSnippet(config, platform, installDirVariable) {
|
|
9674
9807
|
if (!hasInstallerUserConfig(config, platform)) return "";
|
|
@@ -9834,13 +9967,13 @@ for (const line of lines) {
|
|
|
9834
9967
|
continue
|
|
9835
9968
|
}
|
|
9836
9969
|
if (tableName === '') {
|
|
9837
|
-
const dottedMatch = trimmed.match(/^features\\.
|
|
9970
|
+
const dottedMatch = trimmed.match(/^features\\.hooks\\s*=\\s*(.+)$/)
|
|
9838
9971
|
if (dottedMatch && isTomlTrue(dottedMatch[1])) process.exit(0)
|
|
9839
9972
|
const inlineMatch = trimmed.match(/^features\\s*=\\s*(.+)$/)
|
|
9840
|
-
if (inlineMatch && /\\
|
|
9973
|
+
if (inlineMatch && /\\bhooks\\s*=\\s*true\\b/i.test(inlineMatch[1])) process.exit(0)
|
|
9841
9974
|
}
|
|
9842
9975
|
if (tableName !== 'features') continue
|
|
9843
|
-
const match = trimmed.match(/^
|
|
9976
|
+
const match = trimmed.match(/^hooks\\s*=\\s*(.+)$/)
|
|
9844
9977
|
if (match && isTomlTrue(match[1])) process.exit(0)
|
|
9845
9978
|
}
|
|
9846
9979
|
process.exit(1)
|
|
@@ -9859,7 +9992,7 @@ NODE
|
|
|
9859
9992
|
*)
|
|
9860
9993
|
if [[ -r /dev/tty ]]; then
|
|
9861
9994
|
echo "This Codex plugin bundle includes startup hooks." >/dev/tty
|
|
9862
|
-
echo "Codex requires [features].
|
|
9995
|
+
echo "Codex requires [features].hooks = true before plugin-bundled hooks can run." >/dev/tty
|
|
9863
9996
|
read -r -p "Enable Codex plugin-bundled hooks in $CODEX_CONFIG_PATH now? [Y/n] " PLUXX_CODEX_HOOKS_REPLY </dev/tty
|
|
9864
9997
|
case "$PLUXX_CODEX_HOOKS_REPLY" in
|
|
9865
9998
|
n|N|no|NO)
|
|
@@ -9931,7 +10064,7 @@ for (let index = 0; index < lines.length; index += 1) {
|
|
|
9931
10064
|
if (/^features\\.[A-Za-z0-9_-]+\\s*=/.test(trimmed) && firstTopLevelFeaturesDotted < 0) {
|
|
9932
10065
|
firstTopLevelFeaturesDotted = index
|
|
9933
10066
|
}
|
|
9934
|
-
if (/^features\\.
|
|
10067
|
+
if (/^features\\.hooks\\s*=/.test(trimmed)) {
|
|
9935
10068
|
topLevelPluginHooksDotted = index
|
|
9936
10069
|
}
|
|
9937
10070
|
if (/^features\\s*=\\s*\\{/.test(trimmed)) {
|
|
@@ -9950,28 +10083,28 @@ if (start >= 0) {
|
|
|
9950
10083
|
|
|
9951
10084
|
let updated = false
|
|
9952
10085
|
for (let index = start + 1; index < end; index += 1) {
|
|
9953
|
-
if (/^
|
|
9954
|
-
lines[index] = '
|
|
10086
|
+
if (/^hooks\\s*=/.test(stripTomlComment(lines[index]).trim())) {
|
|
10087
|
+
lines[index] = 'hooks = true'
|
|
9955
10088
|
updated = true
|
|
9956
10089
|
}
|
|
9957
10090
|
}
|
|
9958
|
-
if (!updated) lines.splice(start + 1, 0, '
|
|
10091
|
+
if (!updated) lines.splice(start + 1, 0, 'hooks = true')
|
|
9959
10092
|
} else if (topLevelPluginHooksDotted >= 0) {
|
|
9960
|
-
lines[topLevelPluginHooksDotted] = 'features.
|
|
10093
|
+
lines[topLevelPluginHooksDotted] = 'features.hooks = true'
|
|
9961
10094
|
} else if (firstTopLevelFeaturesDotted >= 0) {
|
|
9962
|
-
lines.splice(firstTopLevelFeaturesDotted + 1, 0, 'features.
|
|
10095
|
+
lines.splice(firstTopLevelFeaturesDotted + 1, 0, 'features.hooks = true')
|
|
9963
10096
|
} else if (topLevelInlineFeatures >= 0 && lines[topLevelInlineFeatures].includes('}')) {
|
|
9964
|
-
if (/\\
|
|
10097
|
+
if (/\\bhooks\\s*=/.test(lines[topLevelInlineFeatures])) {
|
|
9965
10098
|
lines[topLevelInlineFeatures] = lines[topLevelInlineFeatures].replace(
|
|
9966
|
-
/\\
|
|
9967
|
-
'
|
|
10099
|
+
/\\bhooks\\s*=\\s*(true|false)\\b/i,
|
|
10100
|
+
'hooks = true',
|
|
9968
10101
|
)
|
|
9969
10102
|
} else {
|
|
9970
|
-
lines[topLevelInlineFeatures] = lines[topLevelInlineFeatures].replace(/}/, ',
|
|
10103
|
+
lines[topLevelInlineFeatures] = lines[topLevelInlineFeatures].replace(/}/, ', hooks = true }')
|
|
9971
10104
|
}
|
|
9972
10105
|
} else {
|
|
9973
10106
|
if (lines.length > 0 && lines[lines.length - 1] !== '') lines.push('')
|
|
9974
|
-
lines.push('[features]', '
|
|
10107
|
+
lines.push('[features]', 'hooks = true')
|
|
9975
10108
|
}
|
|
9976
10109
|
|
|
9977
10110
|
fs.mkdirSync(path.dirname(filepath), { recursive: true })
|
|
@@ -9982,7 +10115,7 @@ NODE
|
|
|
9982
10115
|
else
|
|
9983
10116
|
echo "Codex plugin-bundled hooks are not enabled. Startup hooks from this plugin will not run until you add this to $CODEX_CONFIG_PATH:" >&2
|
|
9984
10117
|
echo "[features]" >&2
|
|
9985
|
-
echo "
|
|
10118
|
+
echo "hooks = true" >&2
|
|
9986
10119
|
echo "Then restart or refresh Codex before relying on plugin startup hooks." >&2
|
|
9987
10120
|
echo "Set PLUXX_CODEX_ENABLE_PLUGIN_HOOKS=1 before running this installer to enable it noninteractively." >&2
|
|
9988
10121
|
fi
|
|
@@ -10621,7 +10754,7 @@ import { resolve as resolve5 } from "path";
|
|
|
10621
10754
|
import { spawn, spawnSync as spawnSync2 } from "child_process";
|
|
10622
10755
|
import { accessSync, constants, existsSync as existsSync4, lstatSync, readFileSync as readFileSync4, readdirSync as readdirSync2, realpathSync } from "fs";
|
|
10623
10756
|
import { homedir } from "os";
|
|
10624
|
-
import { basename as basename2, dirname as dirname2, resolve as resolve4 } from "path";
|
|
10757
|
+
import { basename as basename2, dirname as dirname2, relative as relative2, resolve as resolve4 } from "path";
|
|
10625
10758
|
|
|
10626
10759
|
// node_modules/jiti/lib/jiti.mjs
|
|
10627
10760
|
var import_jiti = __toESM(require_jiti(), 1);
|
|
@@ -11156,7 +11289,7 @@ var MUTATING_PREFIX_PATTERN = new RegExp(`^(${MUTATING_PREFIXES.join("|")})\\b`,
|
|
|
11156
11289
|
// src/codex-hooks-feature.ts
|
|
11157
11290
|
var RECOMMENDED_CODEX_HOOKS_FEATURE_FLAG = "hooks";
|
|
11158
11291
|
var ALTERNATE_CODEX_HOOKS_FEATURE_FLAG = "codex_hooks";
|
|
11159
|
-
var PLUGIN_BUNDLED_CODEX_HOOKS_FEATURE_FLAG = "
|
|
11292
|
+
var PLUGIN_BUNDLED_CODEX_HOOKS_FEATURE_FLAG = "hooks";
|
|
11160
11293
|
function getCodexHooksFeatureState(features) {
|
|
11161
11294
|
if (!features) {
|
|
11162
11295
|
return {
|
|
@@ -11334,12 +11467,119 @@ function splitTomlDottedPath(value) {
|
|
|
11334
11467
|
var MATERIALIZED_ENV_MARKER = "materialized required config";
|
|
11335
11468
|
var MIN_NODE_MAJOR = 18;
|
|
11336
11469
|
var STDIO_LAUNCH_SMOKE_TIMEOUT_MS = 1200;
|
|
11470
|
+
var MAX_SECRET_SCAN_FILE_BYTES = 512 * 1024;
|
|
11471
|
+
var LEGACY_SECRET_IDENTIFIER_PATTERN = /(^|[-_])(api[-_]?key|secret|token|password|credential)([-_]|$)/i;
|
|
11472
|
+
var TEST_SECRET_SENTINELS = [
|
|
11473
|
+
{ pattern: /\bshh-secret\b/i, label: "test secret sentinel" },
|
|
11474
|
+
{ pattern: /\bsecret-key\b/i, label: "test secret sentinel" },
|
|
11475
|
+
{ pattern: /\bliteral-secret-value-that-should-not-copy\b/i, label: "test secret sentinel" }
|
|
11476
|
+
];
|
|
11337
11477
|
function renderInstalledPluginRoot(value, rootDir) {
|
|
11338
11478
|
return value.replaceAll("${PLUGIN_ROOT}", rootDir).replaceAll("${CLAUDE_PLUGIN_ROOT}", rootDir).replaceAll("${CURSOR_PLUGIN_ROOT}", rootDir).replaceAll("${CODEX_PLUGIN_ROOT}", rootDir).replaceAll("${OPENCODE_PLUGIN_ROOT}", rootDir);
|
|
11339
11479
|
}
|
|
11340
11480
|
function addCheck(checks, check) {
|
|
11341
11481
|
checks.push(check);
|
|
11342
11482
|
}
|
|
11483
|
+
function looksLegacySecretIdentifier(value) {
|
|
11484
|
+
return LEGACY_SECRET_IDENTIFIER_PATTERN.test(
|
|
11485
|
+
value.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[._/\s]+/g, "-")
|
|
11486
|
+
);
|
|
11487
|
+
}
|
|
11488
|
+
function walkInstalledBundleFiles(rootDir, currentDir = rootDir) {
|
|
11489
|
+
const files = [];
|
|
11490
|
+
for (const entry of readdirSync2(currentDir, { withFileTypes: true })) {
|
|
11491
|
+
const absolutePath = resolve4(currentDir, entry.name);
|
|
11492
|
+
if (entry.isDirectory()) {
|
|
11493
|
+
files.push(...walkInstalledBundleFiles(rootDir, absolutePath));
|
|
11494
|
+
continue;
|
|
11495
|
+
}
|
|
11496
|
+
if (!entry.isFile()) continue;
|
|
11497
|
+
files.push(relative2(rootDir, absolutePath).replace(/\\/g, "/"));
|
|
11498
|
+
}
|
|
11499
|
+
return files.sort();
|
|
11500
|
+
}
|
|
11501
|
+
function readInstalledTextFile(rootDir, relativePath) {
|
|
11502
|
+
const absolutePath = resolve4(rootDir, relativePath);
|
|
11503
|
+
const content = readFileSync4(absolutePath);
|
|
11504
|
+
if (content.length > MAX_SECRET_SCAN_FILE_BYTES) return null;
|
|
11505
|
+
if (content.includes(0)) return null;
|
|
11506
|
+
return content.toString("utf-8");
|
|
11507
|
+
}
|
|
11508
|
+
function collectInstalledPlaintextSecretCandidates(rootDir) {
|
|
11509
|
+
const userConfigPath = resolve4(rootDir, ".pluxx-user.json");
|
|
11510
|
+
if (!existsSync4(userConfigPath)) return [];
|
|
11511
|
+
try {
|
|
11512
|
+
const payload = JSON.parse(readFileSync4(userConfigPath, "utf-8"));
|
|
11513
|
+
if (payload.secretStorage === "materialized") return [];
|
|
11514
|
+
const secretKeys = new Set(Array.isArray(payload.secretKeys) ? payload.secretKeys.filter((value) => typeof value === "string") : []);
|
|
11515
|
+
const secretEnv = new Set(Array.isArray(payload.secretEnv) ? payload.secretEnv.filter((value) => typeof value === "string") : []);
|
|
11516
|
+
const hasSecretMetadata = secretKeys.size > 0 || secretEnv.size > 0;
|
|
11517
|
+
const candidateLabels = /* @__PURE__ */ new Map();
|
|
11518
|
+
const recordCandidate = (rawValue, label) => {
|
|
11519
|
+
if (typeof rawValue !== "string") return;
|
|
11520
|
+
const value = rawValue.trim();
|
|
11521
|
+
if (!value) return;
|
|
11522
|
+
if (extractEnvReference(value)) return;
|
|
11523
|
+
if (isPlaceholderSecretValue(value)) return;
|
|
11524
|
+
const labels = candidateLabels.get(value) ?? /* @__PURE__ */ new Set();
|
|
11525
|
+
labels.add(label);
|
|
11526
|
+
candidateLabels.set(value, labels);
|
|
11527
|
+
};
|
|
11528
|
+
for (const [key, value] of Object.entries(payload.values ?? {})) {
|
|
11529
|
+
if (hasSecretMetadata ? !secretKeys.has(key) : !looksLegacySecretIdentifier(key)) continue;
|
|
11530
|
+
recordCandidate(value, `userConfig "${key}"`);
|
|
11531
|
+
}
|
|
11532
|
+
for (const [key, value] of Object.entries(payload.env ?? {})) {
|
|
11533
|
+
if (hasSecretMetadata ? !secretEnv.has(key) : !looksLegacySecretIdentifier(key)) continue;
|
|
11534
|
+
recordCandidate(value, `env "${key}"`);
|
|
11535
|
+
}
|
|
11536
|
+
return [...candidateLabels.entries()].map(([value, labels]) => ({
|
|
11537
|
+
value,
|
|
11538
|
+
labels: [...labels].sort()
|
|
11539
|
+
}));
|
|
11540
|
+
} catch {
|
|
11541
|
+
return [];
|
|
11542
|
+
}
|
|
11543
|
+
}
|
|
11544
|
+
function checkInstalledPlaintextSecrets(checks, rootDir) {
|
|
11545
|
+
const literalCandidates = collectInstalledPlaintextSecretCandidates(rootDir);
|
|
11546
|
+
const findings = /* @__PURE__ */ new Map();
|
|
11547
|
+
for (const relativePath of walkInstalledBundleFiles(rootDir)) {
|
|
11548
|
+
const content = readInstalledTextFile(rootDir, relativePath);
|
|
11549
|
+
if (!content) continue;
|
|
11550
|
+
const labels = /* @__PURE__ */ new Set();
|
|
11551
|
+
for (const candidate of literalCandidates) {
|
|
11552
|
+
if (!content.includes(candidate.value)) continue;
|
|
11553
|
+
for (const label of candidate.labels) labels.add(label);
|
|
11554
|
+
}
|
|
11555
|
+
for (const sentinel of TEST_SECRET_SENTINELS) {
|
|
11556
|
+
if (sentinel.pattern.test(content)) {
|
|
11557
|
+
labels.add(sentinel.label);
|
|
11558
|
+
}
|
|
11559
|
+
}
|
|
11560
|
+
if (labels.size > 0) {
|
|
11561
|
+
findings.set(relativePath, labels);
|
|
11562
|
+
}
|
|
11563
|
+
}
|
|
11564
|
+
if (findings.size === 0) {
|
|
11565
|
+
addCheck(checks, {
|
|
11566
|
+
level: "success",
|
|
11567
|
+
code: "consumer-plaintext-secret-absent",
|
|
11568
|
+
title: "Installed bundle does not expose known plaintext secret material",
|
|
11569
|
+
detail: "No known prompted secret values or maintained test-secret sentinels were detected in scanned installed text files.",
|
|
11570
|
+
fix: "No action needed."
|
|
11571
|
+
});
|
|
11572
|
+
return;
|
|
11573
|
+
}
|
|
11574
|
+
const detail = [...findings.entries()].map(([path, labels]) => `${path} (${[...labels].sort().join(", ")})`).join("; ");
|
|
11575
|
+
addCheck(checks, {
|
|
11576
|
+
level: "error",
|
|
11577
|
+
code: "consumer-plaintext-secret-leak",
|
|
11578
|
+
title: "Installed bundle contains plaintext secret material",
|
|
11579
|
+
detail: `Detected plaintext secret material in installed files: ${detail}.`,
|
|
11580
|
+
fix: "Rotate the affected credential, remove the leaking install, reinstall after the Pluxx secret-reference fix, and rerun pluxx doctor --consumer."
|
|
11581
|
+
});
|
|
11582
|
+
}
|
|
11343
11583
|
function summarizeChecks(checks) {
|
|
11344
11584
|
const visibleChecks = checks.filter((check) => !check.code.startsWith("primitive-"));
|
|
11345
11585
|
const errors = visibleChecks.filter((check) => check.level === "error").length;
|
|
@@ -11474,7 +11714,7 @@ function readCodexHooksFeatureFlag(filePath) {
|
|
|
11474
11714
|
inFeaturesTable = sectionMatch[1].trim() === "features";
|
|
11475
11715
|
continue;
|
|
11476
11716
|
}
|
|
11477
|
-
const dottedFeatureMatch = line.match(/^features\.(
|
|
11717
|
+
const dottedFeatureMatch = line.match(/^features\.(hooks|codex_hooks)\s*=\s*(.+)$/);
|
|
11478
11718
|
if (dottedFeatureMatch) {
|
|
11479
11719
|
assignFeatureFlag(dottedFeatureMatch[1], dottedFeatureMatch[2]);
|
|
11480
11720
|
continue;
|
|
@@ -11491,7 +11731,7 @@ function readCodexHooksFeatureFlag(filePath) {
|
|
|
11491
11731
|
continue;
|
|
11492
11732
|
}
|
|
11493
11733
|
if (!inFeaturesTable) continue;
|
|
11494
|
-
const featureMatch = line.match(/^(
|
|
11734
|
+
const featureMatch = line.match(/^(hooks|codex_hooks)\s*=\s*(.+)$/);
|
|
11495
11735
|
if (!featureMatch) continue;
|
|
11496
11736
|
assignFeatureFlag(featureMatch[1], featureMatch[2]);
|
|
11497
11737
|
}
|
|
@@ -12110,20 +12350,20 @@ function checkInstalledCodexHooksFeatureFlag(checks, rootDir, layout, options) {
|
|
|
12110
12350
|
const enabledProbes = probes.filter((probe) => probe.enabled);
|
|
12111
12351
|
const checkedPaths = probes.map((probe) => `${probe.scope} ${probe.exists ? "config" : "path"}: ${probe.path}${probe.exists ? "" : " (missing)"}`).join("; ");
|
|
12112
12352
|
const describeEnabledFlags = (probe) => {
|
|
12113
|
-
const enabledFlags =
|
|
12114
|
-
if (probe.pluginBundledEnabled) enabledFlags.
|
|
12115
|
-
if (probe.recommendedEnabled) enabledFlags.
|
|
12116
|
-
if (probe.alternateEnabled) enabledFlags.
|
|
12117
|
-
return enabledFlags.join(" + ");
|
|
12353
|
+
const enabledFlags = /* @__PURE__ */ new Set();
|
|
12354
|
+
if (probe.pluginBundledEnabled) enabledFlags.add(PLUGIN_BUNDLED_CODEX_HOOKS_FEATURE_FLAG);
|
|
12355
|
+
if (probe.recommendedEnabled) enabledFlags.add(RECOMMENDED_CODEX_HOOKS_FEATURE_FLAG);
|
|
12356
|
+
if (probe.alternateEnabled) enabledFlags.add(ALTERNATE_CODEX_HOOKS_FEATURE_FLAG);
|
|
12357
|
+
return [...enabledFlags].join(" + ");
|
|
12118
12358
|
};
|
|
12119
12359
|
const generalOnlyProbes = probes.filter((probe) => !probe.pluginBundledEnabled && (probe.recommendedEnabled || probe.alternateEnabled));
|
|
12120
12360
|
if (generalOnlyProbes.length > 0) {
|
|
12121
12361
|
addCheck(checks, {
|
|
12122
12362
|
level: "warning",
|
|
12123
12363
|
code: "consumer-codex-plugin-hooks-feature-flag-general-only",
|
|
12124
|
-
title: "Codex config enables only
|
|
12125
|
-
detail: `This installed Codex bundle declares plugin-bundled hooks at ${hooksReference}, but ${generalOnlyProbes.map((probe) => `${probe.scope} config ${probe.path}`).join(" and ")} enables only
|
|
12126
|
-
fix: `Enable \`${
|
|
12364
|
+
title: "Codex config enables only deprecated hook flags",
|
|
12365
|
+
detail: `This installed Codex bundle declares plugin-bundled hooks at ${hooksReference}, but ${generalOnlyProbes.map((probe) => `${probe.scope} config ${probe.path}`).join(" and ")} enables only deprecated hook flags (${generalOnlyProbes.map((probe) => describeEnabledFlags(probe)).join(" and ")}). Current Codex docs use \`${RECOMMENDED_CODEX_HOOKS_FEATURE_FLAG}\` as the canonical feature key.`,
|
|
12366
|
+
fix: `Enable \`${RECOMMENDED_CODEX_HOOKS_FEATURE_FLAG} = true\` under \`[features]\` in the active Codex config, reload Codex, and rerun pluxx verify-install.`,
|
|
12127
12367
|
path: generalOnlyProbes[0].path
|
|
12128
12368
|
});
|
|
12129
12369
|
}
|
|
@@ -12133,8 +12373,8 @@ function checkInstalledCodexHooksFeatureFlag(checks, rootDir, layout, options) {
|
|
|
12133
12373
|
level: "warning",
|
|
12134
12374
|
code: "consumer-codex-hooks-feature-flag-legacy-only",
|
|
12135
12375
|
title: "Codex config still uses the deprecated general hook compatibility flag",
|
|
12136
|
-
detail: `This installed Codex bundle declares plugin-bundled hooks at ${hooksReference}, and the checked Codex config enables only the deprecated
|
|
12137
|
-
fix: `
|
|
12376
|
+
detail: `This installed Codex bundle declares plugin-bundled hooks at ${hooksReference}, and the checked Codex config enables only the deprecated hook flag \`${ALTERNATE_CODEX_HOOKS_FEATURE_FLAG} = true\` in ${legacyOnlyProbes.map((probe) => `${probe.scope} config ${probe.path}`).join(" and ")}. Current Codex docs use \`${RECOMMENDED_CODEX_HOOKS_FEATURE_FLAG}\` as the canonical feature key.`,
|
|
12377
|
+
fix: `Use \`${RECOMMENDED_CODEX_HOOKS_FEATURE_FLAG} = true\` under \`[features]\`, reload Codex, and rerun pluxx verify-install after updating the active config.`,
|
|
12138
12378
|
path: legacyOnlyProbes[0].path
|
|
12139
12379
|
});
|
|
12140
12380
|
}
|
|
@@ -12142,8 +12382,8 @@ function checkInstalledCodexHooksFeatureFlag(checks, rootDir, layout, options) {
|
|
|
12142
12382
|
addCheck(checks, {
|
|
12143
12383
|
level: "success",
|
|
12144
12384
|
code: "consumer-codex-hooks-feature-flag-enabled",
|
|
12145
|
-
title: "Codex
|
|
12146
|
-
detail: `This installed Codex bundle declares plugin-bundled hooks at ${hooksReference}, and the
|
|
12385
|
+
title: "Codex hook feature flag found for this install",
|
|
12386
|
+
detail: `This installed Codex bundle declares plugin-bundled hooks at ${hooksReference}, and the canonical hook feature key was found in ${enabledProbes.map((probe) => `${probe.scope} config ${probe.path} (${describeEnabledFlags(probe)})`).join(" and ")}. Treat that as a prerequisite, not proof of live hook execution.`,
|
|
12147
12387
|
fix: "No action needed.",
|
|
12148
12388
|
path: enabledProbes[0].path
|
|
12149
12389
|
});
|
|
@@ -12154,8 +12394,8 @@ function checkInstalledCodexHooksFeatureFlag(checks, rootDir, layout, options) {
|
|
|
12154
12394
|
level: "warning",
|
|
12155
12395
|
code: "consumer-codex-hooks-feature-flag-missing",
|
|
12156
12396
|
title: "Codex plugin-bundled hook activation is missing its known feature-gate prerequisite",
|
|
12157
|
-
detail: `This installed Codex bundle declares plugin-bundled hooks at ${hooksReference}, but \`${
|
|
12158
|
-
fix: `Enable \`${
|
|
12397
|
+
detail: `This installed Codex bundle declares plugin-bundled hooks at ${hooksReference}, but \`${RECOMMENDED_CODEX_HOOKS_FEATURE_FLAG} = true\` was not found in the checked Codex config layers. \`${ALTERNATE_CODEX_HOOKS_FEATURE_FLAG}\` is deprecated and should not be treated as the current hook feature key. Checked ${checkedPaths}.${parseErrors.length > 0 ? ` Unparseable config: ${parseErrors.join("; ")}.` : ""}`,
|
|
12398
|
+
fix: `Enable \`${RECOMMENDED_CODEX_HOOKS_FEATURE_FLAG} = true\` under \`[features]\` in the relevant project or user Codex config, reload Codex, and rerun pluxx verify-install.`,
|
|
12159
12399
|
path: probes.find((probe) => probe.exists)?.path ?? hooksReference
|
|
12160
12400
|
});
|
|
12161
12401
|
}
|
|
@@ -12689,6 +12929,7 @@ async function doctorConsumer(rootDir = process.cwd(), options = {}) {
|
|
|
12689
12929
|
checkInstalledCodexPermissionCompanion(checks, rootDir, layout, options);
|
|
12690
12930
|
checkInstalledPermissionHook(checks, rootDir, layout);
|
|
12691
12931
|
checkInstalledUserConfig(checks, rootDir);
|
|
12932
|
+
checkInstalledPlaintextSecrets(checks, rootDir);
|
|
12692
12933
|
checkInstalledEnvValidation(checks, rootDir);
|
|
12693
12934
|
checkInstalledRuntimeScriptRoles(checks, rootDir);
|
|
12694
12935
|
await checkInstalledMcpConfig(checks, rootDir, layout);
|
package/dist/readiness.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEhD,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,OAAO,CAAA;IACrB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,YAAY,EAAE,OAAO,CAAA;IACrB,eAAe,EAAE,OAAO,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,gBAAgB,GAAG,SAAS,GAAG,oBAAoB,CAsBrG;AAED,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEhD,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,OAAO,CAAA;IACrB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,YAAY,EAAE,OAAO,CAAA;IACrB,eAAe,EAAE,OAAO,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,gBAAgB,GAAG,SAAS,GAAG,oBAAoB,CAsBrG;AAED,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,CAiSjF"}
|
package/dist/user-config.d.ts
CHANGED
|
@@ -4,6 +4,14 @@ export interface ResolvedUserConfigEntry {
|
|
|
4
4
|
value: string | number | boolean;
|
|
5
5
|
envVar?: string;
|
|
6
6
|
}
|
|
7
|
+
export interface InstalledUserConfigPayload {
|
|
8
|
+
values?: Record<string, string | number | boolean>;
|
|
9
|
+
env?: Record<string, string>;
|
|
10
|
+
envRefs?: Record<string, string>;
|
|
11
|
+
secretStorage?: 'env-ref' | 'materialized';
|
|
12
|
+
secretKeys?: string[];
|
|
13
|
+
secretEnv?: string[];
|
|
14
|
+
}
|
|
7
15
|
interface DerivedUserConfigEntry extends UserConfigEntry {
|
|
8
16
|
source: 'explicit' | 'mcp-auth' | 'mcp-env';
|
|
9
17
|
}
|
|
@@ -16,5 +24,8 @@ export declare function collectUserConfigEntries(config: PluginConfig, platforms
|
|
|
16
24
|
export declare function resolveUserConfigEntriesForTarget(entries: ResolvedUserConfigEntry[], target: TargetPlatform): ResolvedUserConfigEntry[];
|
|
17
25
|
export declare function buildUserConfigEnvMap(entries: ResolvedUserConfigEntry[]): Record<string, string>;
|
|
18
26
|
export declare function buildUserConfigValueMap(entries: ResolvedUserConfigEntry[]): Record<string, string | number | boolean>;
|
|
27
|
+
export declare function buildInstalledUserConfigPayload(entries: ResolvedUserConfigEntry[], options?: {
|
|
28
|
+
preserveSecretReferences?: boolean;
|
|
29
|
+
}): InstalledUserConfigPayload;
|
|
19
30
|
export {};
|
|
20
31
|
//# sourceMappingURL=user-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-config.d.ts","sourceRoot":"","sources":["../src/user-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAExF,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,eAAe,CAAA;IACtB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,UAAU,sBAAuB,SAAQ,eAAe;IACtD,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAA;CAC5C;AAcD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM3D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAIjF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKhE;AA2CD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,YAAY,EACpB,SAAS,GAAE,cAAc,EAAmB,GAC3C,sBAAsB,EAAE,CAyD1B;AAED,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,uBAAuB,EAAE,EAClC,MAAM,EAAE,cAAc,GACrB,uBAAuB,EAAE,CAE3B;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOhG;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,uBAAuB,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAMrH"}
|
|
1
|
+
{"version":3,"file":"user-config.d.ts","sourceRoot":"","sources":["../src/user-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAExF,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,eAAe,CAAA;IACtB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAA;IAClD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,aAAa,CAAC,EAAE,SAAS,GAAG,cAAc,CAAA;IAC1C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAED,UAAU,sBAAuB,SAAQ,eAAe;IACtD,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAA;CAC5C;AAcD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM3D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAIjF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKhE;AA2CD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,YAAY,EACpB,SAAS,GAAE,cAAc,EAAmB,GAC3C,sBAAsB,EAAE,CAyD1B;AAED,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,uBAAuB,EAAE,EAClC,MAAM,EAAE,cAAc,GACrB,uBAAuB,EAAE,CAE3B;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOhG;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,uBAAuB,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAMrH;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,uBAAuB,EAAE,EAClC,OAAO,GAAE;IAAE,wBAAwB,CAAC,EAAE,OAAO,CAAA;CAAO,GACnD,0BAA0B,CAqC5B"}
|
|
@@ -77,6 +77,7 @@ export interface PlatformRules {
|
|
|
77
77
|
}
|
|
78
78
|
export type PrimitiveTranslationMode = 'preserve' | 'translate' | 'degrade' | 'drop';
|
|
79
79
|
export type CoreFourPlatform = Extract<TargetPlatform, 'claude-code' | 'cursor' | 'codex' | 'opencode'>;
|
|
80
|
+
export declare const CORE_FOUR_PLATFORMS: readonly ["claude-code", "cursor", "codex", "opencode"];
|
|
80
81
|
export interface PlatformPrimitiveCapability {
|
|
81
82
|
mode: PrimitiveTranslationMode;
|
|
82
83
|
nativeSurfaces: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-rules.d.ts","sourceRoot":"","sources":["../../src/validation/platform-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"platform-rules.d.ts","sourceRoot":"","sources":["../../src/validation/platform-rules.ts"],"names":[],"mappings":"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"}
|