@orchid-labs/pluxx 0.1.17 → 0.1.19
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/dist/cli/index.js +243 -1
- package/dist/cli/publish.d.ts.map +1 -1
- package/dist/index.js +243 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -12081,7 +12081,7 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
|
|
|
12081
12081
|
hooks: {
|
|
12082
12082
|
mode: "translate",
|
|
12083
12083
|
nativeSurfaces: ["hooks/hooks.json", ".codex/hooks.json", "~/.codex/hooks.json"],
|
|
12084
|
-
notes: "Hooks are native. Pluxx bundles translated Codex hooks in the plugin and still tracks the project/user config paths
|
|
12084
|
+
notes: "Hooks are native. Pluxx bundles translated Codex hooks in the plugin with the documented `[features].plugin_hooks = true` plugin gate, and still tracks the broader project/user hook config paths where `[features].hooks` is the general flag and `codex_hooks` is deprecated."
|
|
12085
12085
|
},
|
|
12086
12086
|
permissions: {
|
|
12087
12087
|
mode: "translate",
|
|
@@ -24681,6 +24681,247 @@ if [[ -f "${installDirVariable}/scripts/bootstrap-runtime.sh" ]]; then
|
|
|
24681
24681
|
fi
|
|
24682
24682
|
`;
|
|
24683
24683
|
}
|
|
24684
|
+
function renderInstallerCodexPluginHooksSnippet(installDirVariable) {
|
|
24685
|
+
return `
|
|
24686
|
+
export PLUXX_INSTALL_DIR="${installDirVariable}"
|
|
24687
|
+
|
|
24688
|
+
set +e
|
|
24689
|
+
node <<'NODE'
|
|
24690
|
+
const fs = require('fs')
|
|
24691
|
+
const path = require('path')
|
|
24692
|
+
|
|
24693
|
+
const installDir = process.env.PLUXX_INSTALL_DIR
|
|
24694
|
+
if (!installDir) process.exit(0)
|
|
24695
|
+
|
|
24696
|
+
const manifestPath = path.join(installDir, '.codex-plugin/plugin.json')
|
|
24697
|
+
const standardHooksPath = path.join(installDir, 'hooks/hooks.json')
|
|
24698
|
+
let hasPluginHooks = fs.existsSync(standardHooksPath)
|
|
24699
|
+
|
|
24700
|
+
if (fs.existsSync(manifestPath)) {
|
|
24701
|
+
try {
|
|
24702
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'))
|
|
24703
|
+
const manifestHooks = manifest.hooks
|
|
24704
|
+
hasPluginHooks ||= typeof manifestHooks === 'string' && manifestHooks.trim().length > 0
|
|
24705
|
+
hasPluginHooks ||= Array.isArray(manifestHooks) && manifestHooks.length > 0
|
|
24706
|
+
hasPluginHooks ||= manifestHooks && typeof manifestHooks === 'object' && Object.keys(manifestHooks).length > 0
|
|
24707
|
+
hasPluginHooks ||= manifestHooks === true
|
|
24708
|
+
} catch {}
|
|
24709
|
+
}
|
|
24710
|
+
|
|
24711
|
+
process.exit(hasPluginHooks ? 0 : 2)
|
|
24712
|
+
NODE
|
|
24713
|
+
PLUXX_CODEX_BUNDLE_HAS_HOOKS="$?"
|
|
24714
|
+
set -e
|
|
24715
|
+
|
|
24716
|
+
if [[ "$PLUXX_CODEX_BUNDLE_HAS_HOOKS" == "0" ]]; then
|
|
24717
|
+
CODEX_HOME_DIR="\${CODEX_HOME:-$HOME/.codex}"
|
|
24718
|
+
CODEX_CONFIG_PATH="\${PLUXX_CODEX_CONFIG_PATH:-$CODEX_HOME_DIR/config.toml}"
|
|
24719
|
+
PLUXX_CODEX_HOOKS_MODE="\${PLUXX_CODEX_ENABLE_PLUGIN_HOOKS:-prompt}"
|
|
24720
|
+
|
|
24721
|
+
export CODEX_CONFIG_PATH
|
|
24722
|
+
if node <<'NODE'
|
|
24723
|
+
const fs = require('fs')
|
|
24724
|
+
const filepath = process.env.CODEX_CONFIG_PATH
|
|
24725
|
+
|
|
24726
|
+
function stripTomlComment(line) {
|
|
24727
|
+
let quote = null
|
|
24728
|
+
let escaped = false
|
|
24729
|
+
for (let index = 0; index < line.length; index += 1) {
|
|
24730
|
+
const char = line[index]
|
|
24731
|
+
if (escaped) {
|
|
24732
|
+
escaped = false
|
|
24733
|
+
continue
|
|
24734
|
+
}
|
|
24735
|
+
if (quote && char === '\\\\') {
|
|
24736
|
+
escaped = true
|
|
24737
|
+
continue
|
|
24738
|
+
}
|
|
24739
|
+
if (char === '"' || char === "'") {
|
|
24740
|
+
quote = quote === char ? null : quote || char
|
|
24741
|
+
continue
|
|
24742
|
+
}
|
|
24743
|
+
if (!quote && char === '#') return line.slice(0, index)
|
|
24744
|
+
}
|
|
24745
|
+
return line
|
|
24746
|
+
}
|
|
24747
|
+
|
|
24748
|
+
function isTomlTrue(rawValue) {
|
|
24749
|
+
return /^true\\b/i.test(rawValue.trim())
|
|
24750
|
+
}
|
|
24751
|
+
|
|
24752
|
+
let text = ''
|
|
24753
|
+
try {
|
|
24754
|
+
text = fs.readFileSync(filepath, 'utf8')
|
|
24755
|
+
} catch {
|
|
24756
|
+
process.exit(1)
|
|
24757
|
+
}
|
|
24758
|
+
const lines = text.split(/\\r?\\n/)
|
|
24759
|
+
let tableName = ''
|
|
24760
|
+
for (const line of lines) {
|
|
24761
|
+
const trimmed = stripTomlComment(line).trim()
|
|
24762
|
+
if (!trimmed) continue
|
|
24763
|
+
const tableMatch = trimmed.match(/^\\[([^\\]]+)\\]$/)
|
|
24764
|
+
if (tableMatch) {
|
|
24765
|
+
tableName = tableMatch[1].trim()
|
|
24766
|
+
continue
|
|
24767
|
+
}
|
|
24768
|
+
if (tableName === '') {
|
|
24769
|
+
const dottedMatch = trimmed.match(/^features\\.plugin_hooks\\s*=\\s*(.+)$/)
|
|
24770
|
+
if (dottedMatch && isTomlTrue(dottedMatch[1])) process.exit(0)
|
|
24771
|
+
const inlineMatch = trimmed.match(/^features\\s*=\\s*(.+)$/)
|
|
24772
|
+
if (inlineMatch && /\\bplugin_hooks\\s*=\\s*true\\b/i.test(inlineMatch[1])) process.exit(0)
|
|
24773
|
+
}
|
|
24774
|
+
if (tableName !== 'features') continue
|
|
24775
|
+
const match = trimmed.match(/^plugin_hooks\\s*=\\s*(.+)$/)
|
|
24776
|
+
if (match && isTomlTrue(match[1])) process.exit(0)
|
|
24777
|
+
}
|
|
24778
|
+
process.exit(1)
|
|
24779
|
+
NODE
|
|
24780
|
+
then
|
|
24781
|
+
echo "Codex plugin-bundled hooks already enabled in $CODEX_CONFIG_PATH."
|
|
24782
|
+
else
|
|
24783
|
+
PLUXX_ENABLE_CODEX_HOOKS="0"
|
|
24784
|
+
case "$PLUXX_CODEX_HOOKS_MODE" in
|
|
24785
|
+
1|true|TRUE|yes|YES|always|ALWAYS)
|
|
24786
|
+
PLUXX_ENABLE_CODEX_HOOKS="1"
|
|
24787
|
+
;;
|
|
24788
|
+
0|false|FALSE|no|NO|never|NEVER|skip|SKIP)
|
|
24789
|
+
PLUXX_ENABLE_CODEX_HOOKS="0"
|
|
24790
|
+
;;
|
|
24791
|
+
*)
|
|
24792
|
+
if [[ -r /dev/tty ]]; then
|
|
24793
|
+
echo "This Codex plugin bundle includes startup hooks." >/dev/tty
|
|
24794
|
+
echo "Codex requires [features].plugin_hooks = true before plugin-bundled hooks can run." >/dev/tty
|
|
24795
|
+
read -r -p "Enable Codex plugin-bundled hooks in $CODEX_CONFIG_PATH now? [Y/n] " PLUXX_CODEX_HOOKS_REPLY </dev/tty
|
|
24796
|
+
case "$PLUXX_CODEX_HOOKS_REPLY" in
|
|
24797
|
+
n|N|no|NO)
|
|
24798
|
+
PLUXX_ENABLE_CODEX_HOOKS="0"
|
|
24799
|
+
;;
|
|
24800
|
+
*)
|
|
24801
|
+
PLUXX_ENABLE_CODEX_HOOKS="1"
|
|
24802
|
+
;;
|
|
24803
|
+
esac
|
|
24804
|
+
fi
|
|
24805
|
+
;;
|
|
24806
|
+
esac
|
|
24807
|
+
|
|
24808
|
+
if [[ "$PLUXX_ENABLE_CODEX_HOOKS" == "1" ]]; then
|
|
24809
|
+
mkdir -p "$(dirname "$CODEX_CONFIG_PATH")"
|
|
24810
|
+
node <<'NODE'
|
|
24811
|
+
const fs = require('fs')
|
|
24812
|
+
const path = require('path')
|
|
24813
|
+
|
|
24814
|
+
const filepath = process.env.CODEX_CONFIG_PATH
|
|
24815
|
+
|
|
24816
|
+
function stripTomlComment(line) {
|
|
24817
|
+
let quote = null
|
|
24818
|
+
let escaped = false
|
|
24819
|
+
for (let index = 0; index < line.length; index += 1) {
|
|
24820
|
+
const char = line[index]
|
|
24821
|
+
if (escaped) {
|
|
24822
|
+
escaped = false
|
|
24823
|
+
continue
|
|
24824
|
+
}
|
|
24825
|
+
if (quote && char === '\\\\') {
|
|
24826
|
+
escaped = true
|
|
24827
|
+
continue
|
|
24828
|
+
}
|
|
24829
|
+
if (char === '"' || char === "'") {
|
|
24830
|
+
quote = quote === char ? null : quote || char
|
|
24831
|
+
continue
|
|
24832
|
+
}
|
|
24833
|
+
if (!quote && char === '#') return line.slice(0, index)
|
|
24834
|
+
}
|
|
24835
|
+
return line
|
|
24836
|
+
}
|
|
24837
|
+
|
|
24838
|
+
let text = ''
|
|
24839
|
+
try {
|
|
24840
|
+
text = fs.readFileSync(filepath, 'utf8')
|
|
24841
|
+
} catch {}
|
|
24842
|
+
|
|
24843
|
+
const lines = text.split(/\\r?\\n/)
|
|
24844
|
+
if (lines.length === 1 && lines[0] === '') lines.pop()
|
|
24845
|
+
|
|
24846
|
+
let start = -1
|
|
24847
|
+
let end = lines.length
|
|
24848
|
+
let firstTopLevelFeaturesDotted = -1
|
|
24849
|
+
let topLevelPluginHooksDotted = -1
|
|
24850
|
+
let topLevelInlineFeatures = -1
|
|
24851
|
+
let tableName = ''
|
|
24852
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
24853
|
+
const trimmed = stripTomlComment(lines[index]).trim()
|
|
24854
|
+
const tableMatch = trimmed.match(/^\\[([^\\]]+)\\]$/)
|
|
24855
|
+
if (tableMatch) tableName = tableMatch[1].trim()
|
|
24856
|
+
|
|
24857
|
+
if (trimmed === '[features]') {
|
|
24858
|
+
start = index
|
|
24859
|
+
break
|
|
24860
|
+
}
|
|
24861
|
+
|
|
24862
|
+
if (tableName === '') {
|
|
24863
|
+
if (/^features\\.[A-Za-z0-9_-]+\\s*=/.test(trimmed) && firstTopLevelFeaturesDotted < 0) {
|
|
24864
|
+
firstTopLevelFeaturesDotted = index
|
|
24865
|
+
}
|
|
24866
|
+
if (/^features\\.plugin_hooks\\s*=/.test(trimmed)) {
|
|
24867
|
+
topLevelPluginHooksDotted = index
|
|
24868
|
+
}
|
|
24869
|
+
if (/^features\\s*=\\s*\\{/.test(trimmed)) {
|
|
24870
|
+
topLevelInlineFeatures = index
|
|
24871
|
+
}
|
|
24872
|
+
}
|
|
24873
|
+
}
|
|
24874
|
+
|
|
24875
|
+
if (start >= 0) {
|
|
24876
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
24877
|
+
if (/^\\s*\\[[^\\]]+\\]/.test(stripTomlComment(lines[index]))) {
|
|
24878
|
+
end = index
|
|
24879
|
+
break
|
|
24880
|
+
}
|
|
24881
|
+
}
|
|
24882
|
+
|
|
24883
|
+
let updated = false
|
|
24884
|
+
for (let index = start + 1; index < end; index += 1) {
|
|
24885
|
+
if (/^plugin_hooks\\s*=/.test(stripTomlComment(lines[index]).trim())) {
|
|
24886
|
+
lines[index] = 'plugin_hooks = true'
|
|
24887
|
+
updated = true
|
|
24888
|
+
}
|
|
24889
|
+
}
|
|
24890
|
+
if (!updated) lines.splice(start + 1, 0, 'plugin_hooks = true')
|
|
24891
|
+
} else if (topLevelPluginHooksDotted >= 0) {
|
|
24892
|
+
lines[topLevelPluginHooksDotted] = 'features.plugin_hooks = true'
|
|
24893
|
+
} else if (firstTopLevelFeaturesDotted >= 0) {
|
|
24894
|
+
lines.splice(firstTopLevelFeaturesDotted + 1, 0, 'features.plugin_hooks = true')
|
|
24895
|
+
} else if (topLevelInlineFeatures >= 0 && lines[topLevelInlineFeatures].includes('}')) {
|
|
24896
|
+
if (/\\bplugin_hooks\\s*=/.test(lines[topLevelInlineFeatures])) {
|
|
24897
|
+
lines[topLevelInlineFeatures] = lines[topLevelInlineFeatures].replace(
|
|
24898
|
+
/\\bplugin_hooks\\s*=\\s*(true|false)\\b/i,
|
|
24899
|
+
'plugin_hooks = true',
|
|
24900
|
+
)
|
|
24901
|
+
} else {
|
|
24902
|
+
lines[topLevelInlineFeatures] = lines[topLevelInlineFeatures].replace(/}/, ', plugin_hooks = true }')
|
|
24903
|
+
}
|
|
24904
|
+
} else {
|
|
24905
|
+
if (lines.length > 0 && lines[lines.length - 1] !== '') lines.push('')
|
|
24906
|
+
lines.push('[features]', 'plugin_hooks = true')
|
|
24907
|
+
}
|
|
24908
|
+
|
|
24909
|
+
fs.mkdirSync(path.dirname(filepath), { recursive: true })
|
|
24910
|
+
fs.writeFileSync(filepath, lines.join('\\n') + '\\n')
|
|
24911
|
+
NODE
|
|
24912
|
+
echo "Enabled Codex plugin-bundled hooks in $CODEX_CONFIG_PATH."
|
|
24913
|
+
echo "Restart or refresh Codex before relying on plugin startup hooks."
|
|
24914
|
+
else
|
|
24915
|
+
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
|
|
24916
|
+
echo "[features]" >&2
|
|
24917
|
+
echo "plugin_hooks = true" >&2
|
|
24918
|
+
echo "Then restart or refresh Codex before relying on plugin startup hooks." >&2
|
|
24919
|
+
echo "Set PLUXX_CODEX_ENABLE_PLUGIN_HOOKS=1 before running this installer to enable it noninteractively." >&2
|
|
24920
|
+
fi
|
|
24921
|
+
fi
|
|
24922
|
+
fi
|
|
24923
|
+
`;
|
|
24924
|
+
}
|
|
24684
24925
|
function renderInstallClaudeCodeScript(config) {
|
|
24685
24926
|
return `#!/usr/bin/env bash
|
|
24686
24927
|
set -euo pipefail
|
|
@@ -24902,6 +25143,7 @@ cp -R "$BUNDLE_DIR" "$INSTALL_DIR"
|
|
|
24902
25143
|
${renderInstallerUserConfigSnippet(config, "codex", "$INSTALL_DIR")}
|
|
24903
25144
|
${renderInstallerMcpPathMaterializationSnippet("codex", "$INSTALL_DIR")}
|
|
24904
25145
|
${renderInstallerRuntimeBootstrapSnippet("$INSTALL_DIR")}
|
|
25146
|
+
${renderInstallerCodexPluginHooksSnippet("$INSTALL_DIR")}
|
|
24905
25147
|
|
|
24906
25148
|
mkdir -p "$(dirname "$MARKETPLACE_PATH")"
|
|
24907
25149
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/cli/publish.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAI7D,KAAK,cAAc,GAAG,KAAK,GAAG,gBAAgB,CAAA;AAC9C,KAAK,gBAAgB,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,CAAA;AACzE,KAAK,qBAAqB,GAAG,WAAW,GAAG,QAAQ,CAAA;AAEnD,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,KAAK,aAAa,GAAG,CACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KACvB,aAAa,CAAA;AAElB,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,CAAC,EAAE,cAAc,EAAE,CAAA;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,aAAa,CAAA;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,gBAAgB,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,OAAO,CAAC,EAAE,qBAAqB,CAAA;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,OAAO,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,CAAA;IAClB,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE;QACR,GAAG,EAAE;YACH,OAAO,EAAE,OAAO,CAAA;YAChB,QAAQ,EAAE,OAAO,CAAA;YACjB,WAAW,CAAC,EAAE,MAAM,CAAA;YACpB,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,YAAY,EAAE,OAAO,CAAA;SACtB,CAAA;QACD,aAAa,EAAE;YACb,OAAO,EAAE,OAAO,CAAA;YAChB,QAAQ,EAAE,OAAO,CAAA;YACjB,IAAI,CAAC,EAAE,MAAM,CAAA;YACb,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,kBAAkB,EAAE,OAAO,CAAA;YAC3B,MAAM,EAAE,gBAAgB,EAAE,CAAA;SAC3B,CAAA;KACF,CAAA;IACD,MAAM,EAAE,YAAY,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,EAAE,EAAE,OAAO,CAAA;IACX,SAAS,CAAC,EAAE;QACV,GAAG,CAAC,EAAE;YAAE,EAAE,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;QACtC,aAAa,CAAC,EAAE;YAAE,EAAE,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KACjD,CAAA;CACF;AAwPD,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAmD/F;
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/cli/publish.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAI7D,KAAK,cAAc,GAAG,KAAK,GAAG,gBAAgB,CAAA;AAC9C,KAAK,gBAAgB,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,CAAA;AACzE,KAAK,qBAAqB,GAAG,WAAW,GAAG,QAAQ,CAAA;AAEnD,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,KAAK,aAAa,GAAG,CACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KACvB,aAAa,CAAA;AAElB,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,CAAC,EAAE,cAAc,EAAE,CAAA;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,aAAa,CAAA;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,gBAAgB,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,OAAO,CAAC,EAAE,qBAAqB,CAAA;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,OAAO,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,CAAA;IAClB,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE;QACR,GAAG,EAAE;YACH,OAAO,EAAE,OAAO,CAAA;YAChB,QAAQ,EAAE,OAAO,CAAA;YACjB,WAAW,CAAC,EAAE,MAAM,CAAA;YACpB,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,YAAY,EAAE,OAAO,CAAA;SACtB,CAAA;QACD,aAAa,EAAE;YACb,OAAO,EAAE,OAAO,CAAA;YAChB,QAAQ,EAAE,OAAO,CAAA;YACjB,IAAI,CAAC,EAAE,MAAM,CAAA;YACb,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,kBAAkB,EAAE,OAAO,CAAA;YAC3B,MAAM,EAAE,gBAAgB,EAAE,CAAA;SAC3B,CAAA;KACF,CAAA;IACD,MAAM,EAAE,YAAY,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,EAAE,EAAE,OAAO,CAAA;IACX,SAAS,CAAC,EAAE;QACV,GAAG,CAAC,EAAE;YAAE,EAAE,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;QACtC,aAAa,CAAC,EAAE;YAAE,EAAE,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KACjD,CAAA;CACF;AAwPD,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAmD/F;AA6nCD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,CAoC7D;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,kBAAuB,GAAG,gBAAgB,CA8EnG"}
|
package/dist/index.js
CHANGED
|
@@ -8743,7 +8743,7 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
|
|
|
8743
8743
|
hooks: {
|
|
8744
8744
|
mode: "translate",
|
|
8745
8745
|
nativeSurfaces: ["hooks/hooks.json", ".codex/hooks.json", "~/.codex/hooks.json"],
|
|
8746
|
-
notes: "Hooks are native. Pluxx bundles translated Codex hooks in the plugin and still tracks the project/user config paths
|
|
8746
|
+
notes: "Hooks are native. Pluxx bundles translated Codex hooks in the plugin with the documented `[features].plugin_hooks = true` plugin gate, and still tracks the broader project/user hook config paths where `[features].hooks` is the general flag and `codex_hooks` is deprecated."
|
|
8747
8747
|
},
|
|
8748
8748
|
permissions: {
|
|
8749
8749
|
mode: "translate",
|
|
@@ -9675,6 +9675,247 @@ if [[ -f "${installDirVariable}/scripts/bootstrap-runtime.sh" ]]; then
|
|
|
9675
9675
|
fi
|
|
9676
9676
|
`;
|
|
9677
9677
|
}
|
|
9678
|
+
function renderInstallerCodexPluginHooksSnippet(installDirVariable) {
|
|
9679
|
+
return `
|
|
9680
|
+
export PLUXX_INSTALL_DIR="${installDirVariable}"
|
|
9681
|
+
|
|
9682
|
+
set +e
|
|
9683
|
+
node <<'NODE'
|
|
9684
|
+
const fs = require('fs')
|
|
9685
|
+
const path = require('path')
|
|
9686
|
+
|
|
9687
|
+
const installDir = process.env.PLUXX_INSTALL_DIR
|
|
9688
|
+
if (!installDir) process.exit(0)
|
|
9689
|
+
|
|
9690
|
+
const manifestPath = path.join(installDir, '.codex-plugin/plugin.json')
|
|
9691
|
+
const standardHooksPath = path.join(installDir, 'hooks/hooks.json')
|
|
9692
|
+
let hasPluginHooks = fs.existsSync(standardHooksPath)
|
|
9693
|
+
|
|
9694
|
+
if (fs.existsSync(manifestPath)) {
|
|
9695
|
+
try {
|
|
9696
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'))
|
|
9697
|
+
const manifestHooks = manifest.hooks
|
|
9698
|
+
hasPluginHooks ||= typeof manifestHooks === 'string' && manifestHooks.trim().length > 0
|
|
9699
|
+
hasPluginHooks ||= Array.isArray(manifestHooks) && manifestHooks.length > 0
|
|
9700
|
+
hasPluginHooks ||= manifestHooks && typeof manifestHooks === 'object' && Object.keys(manifestHooks).length > 0
|
|
9701
|
+
hasPluginHooks ||= manifestHooks === true
|
|
9702
|
+
} catch {}
|
|
9703
|
+
}
|
|
9704
|
+
|
|
9705
|
+
process.exit(hasPluginHooks ? 0 : 2)
|
|
9706
|
+
NODE
|
|
9707
|
+
PLUXX_CODEX_BUNDLE_HAS_HOOKS="$?"
|
|
9708
|
+
set -e
|
|
9709
|
+
|
|
9710
|
+
if [[ "$PLUXX_CODEX_BUNDLE_HAS_HOOKS" == "0" ]]; then
|
|
9711
|
+
CODEX_HOME_DIR="\${CODEX_HOME:-$HOME/.codex}"
|
|
9712
|
+
CODEX_CONFIG_PATH="\${PLUXX_CODEX_CONFIG_PATH:-$CODEX_HOME_DIR/config.toml}"
|
|
9713
|
+
PLUXX_CODEX_HOOKS_MODE="\${PLUXX_CODEX_ENABLE_PLUGIN_HOOKS:-prompt}"
|
|
9714
|
+
|
|
9715
|
+
export CODEX_CONFIG_PATH
|
|
9716
|
+
if node <<'NODE'
|
|
9717
|
+
const fs = require('fs')
|
|
9718
|
+
const filepath = process.env.CODEX_CONFIG_PATH
|
|
9719
|
+
|
|
9720
|
+
function stripTomlComment(line) {
|
|
9721
|
+
let quote = null
|
|
9722
|
+
let escaped = false
|
|
9723
|
+
for (let index = 0; index < line.length; index += 1) {
|
|
9724
|
+
const char = line[index]
|
|
9725
|
+
if (escaped) {
|
|
9726
|
+
escaped = false
|
|
9727
|
+
continue
|
|
9728
|
+
}
|
|
9729
|
+
if (quote && char === '\\\\') {
|
|
9730
|
+
escaped = true
|
|
9731
|
+
continue
|
|
9732
|
+
}
|
|
9733
|
+
if (char === '"' || char === "'") {
|
|
9734
|
+
quote = quote === char ? null : quote || char
|
|
9735
|
+
continue
|
|
9736
|
+
}
|
|
9737
|
+
if (!quote && char === '#') return line.slice(0, index)
|
|
9738
|
+
}
|
|
9739
|
+
return line
|
|
9740
|
+
}
|
|
9741
|
+
|
|
9742
|
+
function isTomlTrue(rawValue) {
|
|
9743
|
+
return /^true\\b/i.test(rawValue.trim())
|
|
9744
|
+
}
|
|
9745
|
+
|
|
9746
|
+
let text = ''
|
|
9747
|
+
try {
|
|
9748
|
+
text = fs.readFileSync(filepath, 'utf8')
|
|
9749
|
+
} catch {
|
|
9750
|
+
process.exit(1)
|
|
9751
|
+
}
|
|
9752
|
+
const lines = text.split(/\\r?\\n/)
|
|
9753
|
+
let tableName = ''
|
|
9754
|
+
for (const line of lines) {
|
|
9755
|
+
const trimmed = stripTomlComment(line).trim()
|
|
9756
|
+
if (!trimmed) continue
|
|
9757
|
+
const tableMatch = trimmed.match(/^\\[([^\\]]+)\\]$/)
|
|
9758
|
+
if (tableMatch) {
|
|
9759
|
+
tableName = tableMatch[1].trim()
|
|
9760
|
+
continue
|
|
9761
|
+
}
|
|
9762
|
+
if (tableName === '') {
|
|
9763
|
+
const dottedMatch = trimmed.match(/^features\\.plugin_hooks\\s*=\\s*(.+)$/)
|
|
9764
|
+
if (dottedMatch && isTomlTrue(dottedMatch[1])) process.exit(0)
|
|
9765
|
+
const inlineMatch = trimmed.match(/^features\\s*=\\s*(.+)$/)
|
|
9766
|
+
if (inlineMatch && /\\bplugin_hooks\\s*=\\s*true\\b/i.test(inlineMatch[1])) process.exit(0)
|
|
9767
|
+
}
|
|
9768
|
+
if (tableName !== 'features') continue
|
|
9769
|
+
const match = trimmed.match(/^plugin_hooks\\s*=\\s*(.+)$/)
|
|
9770
|
+
if (match && isTomlTrue(match[1])) process.exit(0)
|
|
9771
|
+
}
|
|
9772
|
+
process.exit(1)
|
|
9773
|
+
NODE
|
|
9774
|
+
then
|
|
9775
|
+
echo "Codex plugin-bundled hooks already enabled in $CODEX_CONFIG_PATH."
|
|
9776
|
+
else
|
|
9777
|
+
PLUXX_ENABLE_CODEX_HOOKS="0"
|
|
9778
|
+
case "$PLUXX_CODEX_HOOKS_MODE" in
|
|
9779
|
+
1|true|TRUE|yes|YES|always|ALWAYS)
|
|
9780
|
+
PLUXX_ENABLE_CODEX_HOOKS="1"
|
|
9781
|
+
;;
|
|
9782
|
+
0|false|FALSE|no|NO|never|NEVER|skip|SKIP)
|
|
9783
|
+
PLUXX_ENABLE_CODEX_HOOKS="0"
|
|
9784
|
+
;;
|
|
9785
|
+
*)
|
|
9786
|
+
if [[ -r /dev/tty ]]; then
|
|
9787
|
+
echo "This Codex plugin bundle includes startup hooks." >/dev/tty
|
|
9788
|
+
echo "Codex requires [features].plugin_hooks = true before plugin-bundled hooks can run." >/dev/tty
|
|
9789
|
+
read -r -p "Enable Codex plugin-bundled hooks in $CODEX_CONFIG_PATH now? [Y/n] " PLUXX_CODEX_HOOKS_REPLY </dev/tty
|
|
9790
|
+
case "$PLUXX_CODEX_HOOKS_REPLY" in
|
|
9791
|
+
n|N|no|NO)
|
|
9792
|
+
PLUXX_ENABLE_CODEX_HOOKS="0"
|
|
9793
|
+
;;
|
|
9794
|
+
*)
|
|
9795
|
+
PLUXX_ENABLE_CODEX_HOOKS="1"
|
|
9796
|
+
;;
|
|
9797
|
+
esac
|
|
9798
|
+
fi
|
|
9799
|
+
;;
|
|
9800
|
+
esac
|
|
9801
|
+
|
|
9802
|
+
if [[ "$PLUXX_ENABLE_CODEX_HOOKS" == "1" ]]; then
|
|
9803
|
+
mkdir -p "$(dirname "$CODEX_CONFIG_PATH")"
|
|
9804
|
+
node <<'NODE'
|
|
9805
|
+
const fs = require('fs')
|
|
9806
|
+
const path = require('path')
|
|
9807
|
+
|
|
9808
|
+
const filepath = process.env.CODEX_CONFIG_PATH
|
|
9809
|
+
|
|
9810
|
+
function stripTomlComment(line) {
|
|
9811
|
+
let quote = null
|
|
9812
|
+
let escaped = false
|
|
9813
|
+
for (let index = 0; index < line.length; index += 1) {
|
|
9814
|
+
const char = line[index]
|
|
9815
|
+
if (escaped) {
|
|
9816
|
+
escaped = false
|
|
9817
|
+
continue
|
|
9818
|
+
}
|
|
9819
|
+
if (quote && char === '\\\\') {
|
|
9820
|
+
escaped = true
|
|
9821
|
+
continue
|
|
9822
|
+
}
|
|
9823
|
+
if (char === '"' || char === "'") {
|
|
9824
|
+
quote = quote === char ? null : quote || char
|
|
9825
|
+
continue
|
|
9826
|
+
}
|
|
9827
|
+
if (!quote && char === '#') return line.slice(0, index)
|
|
9828
|
+
}
|
|
9829
|
+
return line
|
|
9830
|
+
}
|
|
9831
|
+
|
|
9832
|
+
let text = ''
|
|
9833
|
+
try {
|
|
9834
|
+
text = fs.readFileSync(filepath, 'utf8')
|
|
9835
|
+
} catch {}
|
|
9836
|
+
|
|
9837
|
+
const lines = text.split(/\\r?\\n/)
|
|
9838
|
+
if (lines.length === 1 && lines[0] === '') lines.pop()
|
|
9839
|
+
|
|
9840
|
+
let start = -1
|
|
9841
|
+
let end = lines.length
|
|
9842
|
+
let firstTopLevelFeaturesDotted = -1
|
|
9843
|
+
let topLevelPluginHooksDotted = -1
|
|
9844
|
+
let topLevelInlineFeatures = -1
|
|
9845
|
+
let tableName = ''
|
|
9846
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
9847
|
+
const trimmed = stripTomlComment(lines[index]).trim()
|
|
9848
|
+
const tableMatch = trimmed.match(/^\\[([^\\]]+)\\]$/)
|
|
9849
|
+
if (tableMatch) tableName = tableMatch[1].trim()
|
|
9850
|
+
|
|
9851
|
+
if (trimmed === '[features]') {
|
|
9852
|
+
start = index
|
|
9853
|
+
break
|
|
9854
|
+
}
|
|
9855
|
+
|
|
9856
|
+
if (tableName === '') {
|
|
9857
|
+
if (/^features\\.[A-Za-z0-9_-]+\\s*=/.test(trimmed) && firstTopLevelFeaturesDotted < 0) {
|
|
9858
|
+
firstTopLevelFeaturesDotted = index
|
|
9859
|
+
}
|
|
9860
|
+
if (/^features\\.plugin_hooks\\s*=/.test(trimmed)) {
|
|
9861
|
+
topLevelPluginHooksDotted = index
|
|
9862
|
+
}
|
|
9863
|
+
if (/^features\\s*=\\s*\\{/.test(trimmed)) {
|
|
9864
|
+
topLevelInlineFeatures = index
|
|
9865
|
+
}
|
|
9866
|
+
}
|
|
9867
|
+
}
|
|
9868
|
+
|
|
9869
|
+
if (start >= 0) {
|
|
9870
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
9871
|
+
if (/^\\s*\\[[^\\]]+\\]/.test(stripTomlComment(lines[index]))) {
|
|
9872
|
+
end = index
|
|
9873
|
+
break
|
|
9874
|
+
}
|
|
9875
|
+
}
|
|
9876
|
+
|
|
9877
|
+
let updated = false
|
|
9878
|
+
for (let index = start + 1; index < end; index += 1) {
|
|
9879
|
+
if (/^plugin_hooks\\s*=/.test(stripTomlComment(lines[index]).trim())) {
|
|
9880
|
+
lines[index] = 'plugin_hooks = true'
|
|
9881
|
+
updated = true
|
|
9882
|
+
}
|
|
9883
|
+
}
|
|
9884
|
+
if (!updated) lines.splice(start + 1, 0, 'plugin_hooks = true')
|
|
9885
|
+
} else if (topLevelPluginHooksDotted >= 0) {
|
|
9886
|
+
lines[topLevelPluginHooksDotted] = 'features.plugin_hooks = true'
|
|
9887
|
+
} else if (firstTopLevelFeaturesDotted >= 0) {
|
|
9888
|
+
lines.splice(firstTopLevelFeaturesDotted + 1, 0, 'features.plugin_hooks = true')
|
|
9889
|
+
} else if (topLevelInlineFeatures >= 0 && lines[topLevelInlineFeatures].includes('}')) {
|
|
9890
|
+
if (/\\bplugin_hooks\\s*=/.test(lines[topLevelInlineFeatures])) {
|
|
9891
|
+
lines[topLevelInlineFeatures] = lines[topLevelInlineFeatures].replace(
|
|
9892
|
+
/\\bplugin_hooks\\s*=\\s*(true|false)\\b/i,
|
|
9893
|
+
'plugin_hooks = true',
|
|
9894
|
+
)
|
|
9895
|
+
} else {
|
|
9896
|
+
lines[topLevelInlineFeatures] = lines[topLevelInlineFeatures].replace(/}/, ', plugin_hooks = true }')
|
|
9897
|
+
}
|
|
9898
|
+
} else {
|
|
9899
|
+
if (lines.length > 0 && lines[lines.length - 1] !== '') lines.push('')
|
|
9900
|
+
lines.push('[features]', 'plugin_hooks = true')
|
|
9901
|
+
}
|
|
9902
|
+
|
|
9903
|
+
fs.mkdirSync(path.dirname(filepath), { recursive: true })
|
|
9904
|
+
fs.writeFileSync(filepath, lines.join('\\n') + '\\n')
|
|
9905
|
+
NODE
|
|
9906
|
+
echo "Enabled Codex plugin-bundled hooks in $CODEX_CONFIG_PATH."
|
|
9907
|
+
echo "Restart or refresh Codex before relying on plugin startup hooks."
|
|
9908
|
+
else
|
|
9909
|
+
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
|
|
9910
|
+
echo "[features]" >&2
|
|
9911
|
+
echo "plugin_hooks = true" >&2
|
|
9912
|
+
echo "Then restart or refresh Codex before relying on plugin startup hooks." >&2
|
|
9913
|
+
echo "Set PLUXX_CODEX_ENABLE_PLUGIN_HOOKS=1 before running this installer to enable it noninteractively." >&2
|
|
9914
|
+
fi
|
|
9915
|
+
fi
|
|
9916
|
+
fi
|
|
9917
|
+
`;
|
|
9918
|
+
}
|
|
9678
9919
|
function renderInstallClaudeCodeScript(config) {
|
|
9679
9920
|
return `#!/usr/bin/env bash
|
|
9680
9921
|
set -euo pipefail
|
|
@@ -9896,6 +10137,7 @@ cp -R "$BUNDLE_DIR" "$INSTALL_DIR"
|
|
|
9896
10137
|
${renderInstallerUserConfigSnippet(config, "codex", "$INSTALL_DIR")}
|
|
9897
10138
|
${renderInstallerMcpPathMaterializationSnippet("codex", "$INSTALL_DIR")}
|
|
9898
10139
|
${renderInstallerRuntimeBootstrapSnippet("$INSTALL_DIR")}
|
|
10140
|
+
${renderInstallerCodexPluginHooksSnippet("$INSTALL_DIR")}
|
|
9899
10141
|
|
|
9900
10142
|
mkdir -p "$(dirname "$MARKETPLACE_PATH")"
|
|
9901
10143
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchid-labs/pluxx",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "Build AI agent plugins once. Prime-time on Claude Code, Cursor, Codex, and OpenCode, with beta generators for additional hosts.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|