@orchid-labs/pluxx 0.1.13 → 0.1.15
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/agent-translation-registry.d.ts +6 -0
- package/dist/agent-translation-registry.d.ts.map +1 -0
- package/dist/agents.d.ts +22 -0
- package/dist/agents.d.ts.map +1 -1
- package/dist/cli/agent.d.ts.map +1 -1
- package/dist/cli/behavioral.d.ts +2 -0
- package/dist/cli/behavioral.d.ts.map +1 -1
- package/dist/cli/discover-installed-mcp.d.ts +2 -1
- package/dist/cli/discover-installed-mcp.d.ts.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/index.js +3592 -1385
- package/dist/cli/init-from-mcp.d.ts +2 -0
- package/dist/cli/init-from-mcp.d.ts.map +1 -1
- package/dist/cli/install.d.ts.map +1 -1
- package/dist/cli/lint.d.ts.map +1 -1
- package/dist/cli/migrate.d.ts.map +1 -1
- package/dist/cli/publish.d.ts.map +1 -1
- package/dist/cli/verify-install.d.ts.map +1 -1
- package/dist/command-translation-registry.d.ts +9 -0
- package/dist/command-translation-registry.d.ts.map +1 -0
- package/dist/commands.d.ts +31 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/compiler-intent.d.ts +8 -0
- package/dist/compiler-intent.d.ts.map +1 -1
- package/dist/distribution-lifecycle.d.ts +6 -0
- package/dist/distribution-lifecycle.d.ts.map +1 -0
- package/dist/generators/base.d.ts.map +1 -1
- package/dist/generators/claude-code/index.d.ts.map +1 -1
- package/dist/generators/codex/index.d.ts +1 -0
- package/dist/generators/codex/index.d.ts.map +1 -1
- package/dist/generators/cursor/index.d.ts.map +1 -1
- package/dist/generators/opencode/index.d.ts +1 -0
- package/dist/generators/opencode/index.d.ts.map +1 -1
- package/dist/generators/shared/claude-family.d.ts.map +1 -1
- package/dist/hook-command-env.d.ts +2 -0
- package/dist/hook-command-env.d.ts.map +1 -0
- package/dist/hook-translation-registry.d.ts +10 -0
- package/dist/hook-translation-registry.d.ts.map +1 -1
- package/dist/index.js +248 -31
- package/dist/instructions.d.ts +6 -0
- package/dist/instructions.d.ts.map +1 -0
- package/dist/mcp-native-overrides.d.ts +14 -0
- package/dist/mcp-native-overrides.d.ts.map +1 -0
- package/dist/schema.d.ts +10109 -1659
- package/dist/schema.d.ts.map +1 -1
- package/dist/skill-translation-registry.d.ts +8 -0
- package/dist/skill-translation-registry.d.ts.map +1 -0
- package/dist/skills.d.ts +36 -0
- package/dist/skills.d.ts.map +1 -1
- package/dist/validation/platform-rules.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7415,10 +7415,20 @@ var McpServerSchema = external_exports.preprocess(
|
|
|
7415
7415
|
external_exports.discriminatedUnion("transport", [McpServerHttpSchema, McpServerSseSchema, McpServerStdioSchema])
|
|
7416
7416
|
);
|
|
7417
7417
|
var HookEntrySchema = external_exports.object({
|
|
7418
|
-
type: external_exports.enum(["command", "prompt"]).default("command"),
|
|
7418
|
+
type: external_exports.enum(["command", "http", "mcp_tool", "prompt", "agent"]).default("command"),
|
|
7419
7419
|
command: external_exports.string().optional(),
|
|
7420
7420
|
prompt: external_exports.string().optional(),
|
|
7421
7421
|
model: external_exports.string().optional(),
|
|
7422
|
+
url: external_exports.string().url().optional(),
|
|
7423
|
+
headers: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
7424
|
+
allowedEnvVars: external_exports.array(external_exports.string()).optional(),
|
|
7425
|
+
server: external_exports.string().optional(),
|
|
7426
|
+
tool: external_exports.string().optional(),
|
|
7427
|
+
input: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
7428
|
+
if: external_exports.string().optional(),
|
|
7429
|
+
async: external_exports.boolean().optional(),
|
|
7430
|
+
asyncRewake: external_exports.boolean().optional(),
|
|
7431
|
+
shell: external_exports.enum(["bash"]).optional(),
|
|
7422
7432
|
timeout: external_exports.number().optional(),
|
|
7423
7433
|
matcher: external_exports.union([external_exports.string(), external_exports.record(external_exports.string(), external_exports.unknown())]).optional(),
|
|
7424
7434
|
failClosed: external_exports.boolean().optional(),
|
|
@@ -7431,11 +7441,34 @@ var HookEntrySchema = external_exports.object({
|
|
|
7431
7441
|
message: "Command hooks require a command."
|
|
7432
7442
|
});
|
|
7433
7443
|
}
|
|
7434
|
-
if (entry.type === "
|
|
7444
|
+
if (entry.type === "http" && !entry.url) {
|
|
7445
|
+
ctx.addIssue({
|
|
7446
|
+
code: external_exports.ZodIssueCode.custom,
|
|
7447
|
+
path: ["url"],
|
|
7448
|
+
message: "HTTP hooks require a url."
|
|
7449
|
+
});
|
|
7450
|
+
}
|
|
7451
|
+
if (entry.type === "mcp_tool") {
|
|
7452
|
+
if (!entry.server) {
|
|
7453
|
+
ctx.addIssue({
|
|
7454
|
+
code: external_exports.ZodIssueCode.custom,
|
|
7455
|
+
path: ["server"],
|
|
7456
|
+
message: "MCP tool hooks require a server."
|
|
7457
|
+
});
|
|
7458
|
+
}
|
|
7459
|
+
if (!entry.tool) {
|
|
7460
|
+
ctx.addIssue({
|
|
7461
|
+
code: external_exports.ZodIssueCode.custom,
|
|
7462
|
+
path: ["tool"],
|
|
7463
|
+
message: "MCP tool hooks require a tool."
|
|
7464
|
+
});
|
|
7465
|
+
}
|
|
7466
|
+
}
|
|
7467
|
+
if ((entry.type === "prompt" || entry.type === "agent") && !entry.prompt) {
|
|
7435
7468
|
ctx.addIssue({
|
|
7436
7469
|
code: external_exports.ZodIssueCode.custom,
|
|
7437
7470
|
path: ["prompt"],
|
|
7438
|
-
message: "Prompt hooks require a prompt
|
|
7471
|
+
message: `${entry.type === "agent" ? "Agent" : "Prompt"} hooks require a prompt.`
|
|
7439
7472
|
});
|
|
7440
7473
|
}
|
|
7441
7474
|
});
|
|
@@ -7822,7 +7855,7 @@ function getEnabledRuntimeReadinessBindings(capability, plan) {
|
|
|
7822
7855
|
});
|
|
7823
7856
|
}
|
|
7824
7857
|
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.";
|
|
7825
|
-
var CODEX_EXTERNAL_NOTE = "Codex readiness
|
|
7858
|
+
var CODEX_EXTERNAL_NOTE = "Codex readiness now bundles translated hooks in the plugin, but Pluxx still emits `.codex/readiness.generated.json` and `.codex/hooks.generated.json` companion guidance because some Codex runtimes still gate hook activation behind `codex_hooks`.";
|
|
7826
7859
|
function getRuntimeReadinessNamedPromptTargetNote() {
|
|
7827
7860
|
return NAMED_PROMPT_TARGET_NOTE;
|
|
7828
7861
|
}
|
|
@@ -7891,7 +7924,7 @@ function getRuntimeReadinessCapability(platform, pluginRootVar = "PLUGIN_ROOT")
|
|
|
7891
7924
|
bundleEnforced: false,
|
|
7892
7925
|
namedPromptTargetScope: "best-effort",
|
|
7893
7926
|
scriptPath: ".codex/pluxx-readiness.mjs",
|
|
7894
|
-
companionArtifacts: [".codex/readiness.generated.json", ".codex/hooks.generated.json"],
|
|
7927
|
+
companionArtifacts: [".codex/readiness.generated.json", "hooks/hooks.json", ".codex/hooks.generated.json"],
|
|
7895
7928
|
bindings: [
|
|
7896
7929
|
{
|
|
7897
7930
|
gate: "session-start",
|
|
@@ -8115,7 +8148,7 @@ var PLATFORM_LIMIT_POLICIES = {
|
|
|
8115
8148
|
var PLATFORM_VALIDATION_RULES = {
|
|
8116
8149
|
"claude-code": {
|
|
8117
8150
|
platform: "claude-code",
|
|
8118
|
-
summary: "Claude Code plugins use an optional manifest at .claude-plugin/plugin.json with auto-discovery for skills, commands, agents, hooks, MCP, marketplaces, and
|
|
8151
|
+
summary: "Claude Code plugins use an optional manifest at .claude-plugin/plugin.json with auto-discovery for skills, commands, agents, hooks, MCP, marketplaces, output styles, and adjacent plugin assets like LSP, monitors, and themes.",
|
|
8119
8152
|
limits: PLATFORM_LIMITS["claude-code"],
|
|
8120
8153
|
limitPolicies: PLATFORM_LIMIT_POLICIES["claude-code"],
|
|
8121
8154
|
skillDiscoveryDirs: [
|
|
@@ -8154,13 +8187,13 @@ var PLATFORM_VALIDATION_RULES = {
|
|
|
8154
8187
|
hooks: {
|
|
8155
8188
|
supported: true,
|
|
8156
8189
|
files: ["hooks/hooks.json", ".claude-plugin/plugin.json", "~/.claude/settings.json", ".claude/settings.json", ".claude/settings.local.json"],
|
|
8157
|
-
eventNames: ["SessionStart", "PreToolUse", "PostToolUse", "
|
|
8158
|
-
notes: "Hook configs can be stored in hooks/hooks.json, inlined in plugin.json, added in settings files, or scoped through skill and agent frontmatter."
|
|
8190
|
+
eventNames: ["SessionStart", "Setup", "UserPromptSubmit", "UserPromptExpansion", "PreToolUse", "PermissionRequest", "PermissionDenied", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "Notification", "SubagentStart", "SubagentStop", "TaskCreated", "TaskCompleted", "Stop", "StopFailure", "TeammateIdle", "InstructionsLoaded", "ConfigChange", "CwdChanged", "FileChanged", "WorktreeCreate", "WorktreeRemove", "PreCompact", "PostCompact", "Elicitation", "ElicitationResult", "SessionEnd"],
|
|
8191
|
+
notes: "Hook configs can be stored in hooks/hooks.json, inlined in plugin.json, added in settings files, or scoped through skill and agent frontmatter. Claude also documents a broader lifecycle event set than the older simplified Pluxx model."
|
|
8159
8192
|
},
|
|
8160
8193
|
instructions: {
|
|
8161
8194
|
files: ["CLAUDE.md"],
|
|
8162
8195
|
format: "markdown",
|
|
8163
|
-
notes: "Claude keeps persistent instructions in CLAUDE.md and pushes longer procedures into skills."
|
|
8196
|
+
notes: "Claude keeps persistent instructions in CLAUDE.md and pushes longer procedures into skills. Related enforcement and distribution config also depends on managed, user, project, and local settings scopes."
|
|
8164
8197
|
},
|
|
8165
8198
|
sources: [
|
|
8166
8199
|
{ label: "Claude Code MCP docs", url: "https://code.claude.com/docs/en/mcp" },
|
|
@@ -8174,6 +8207,9 @@ var PLATFORM_VALIDATION_RULES = {
|
|
|
8174
8207
|
{ label: "Claude Code plugins reference", url: "https://code.claude.com/docs/en/plugins-reference" },
|
|
8175
8208
|
{ label: "Claude Code hooks guide", url: "https://code.claude.com/docs/en/hooks-guide" },
|
|
8176
8209
|
{ label: "Claude Code hooks docs", url: "https://code.claude.com/docs/en/hooks" },
|
|
8210
|
+
{ label: "Claude Code settings docs", url: "https://code.claude.com/docs/en/settings" },
|
|
8211
|
+
{ label: "Claude Code permissions docs", url: "https://code.claude.com/docs/en/permissions" },
|
|
8212
|
+
{ label: "Claude Code memory docs", url: "https://code.claude.com/docs/en/memory" },
|
|
8177
8213
|
{ label: "Claude Code skills docs", url: "https://code.claude.com/docs/en/skills" },
|
|
8178
8214
|
{ label: "Claude Code sub-agents docs", url: "https://code.claude.com/docs/en/sub-agents" },
|
|
8179
8215
|
{ label: "Claude Code env vars docs", url: "https://code.claude.com/docs/en/env-vars" }
|
|
@@ -8212,13 +8248,13 @@ var PLATFORM_VALIDATION_RULES = {
|
|
|
8212
8248
|
hooks: {
|
|
8213
8249
|
supported: true,
|
|
8214
8250
|
files: ["hooks/hooks.json", ".cursor/hooks.json", "~/.cursor/hooks.json"],
|
|
8215
|
-
eventNames: ["sessionStart", "preToolUse", "postToolUse", "subagentStart", "subagentStop", "beforeShellExecution", "afterShellExecution"],
|
|
8216
|
-
notes: "Cursor plugin hooks live under hooks/hooks.json; project and user hooks also exist separately and reload on save."
|
|
8251
|
+
eventNames: ["sessionStart", "sessionEnd", "preToolUse", "postToolUse", "postToolUseFailure", "subagentStart", "subagentStop", "beforeShellExecution", "afterShellExecution", "beforeMCPExecution", "afterMCPExecution", "beforeReadFile", "afterFileEdit", "beforeSubmitPrompt", "preCompact", "stop", "afterAgentResponse", "afterAgentThought", "beforeTabFileRead", "afterTabFileEdit"],
|
|
8252
|
+
notes: "Cursor plugin hooks live under hooks/hooks.json; project and user hooks also exist separately and reload on save. The official event surface spans both Agent and Tab flows."
|
|
8217
8253
|
},
|
|
8218
8254
|
instructions: {
|
|
8219
8255
|
files: ["rules/", "AGENTS.md"],
|
|
8220
8256
|
format: "mdc + markdown",
|
|
8221
|
-
notes: "rules/ is the plugin-native instruction surface. AGENTS.md remains useful as shared repo guidance. Cursor subagents use markdown files under .cursor/agents or ~/.cursor/agents (with .claude/.codex compatibility paths)."
|
|
8257
|
+
notes: "rules/ is the plugin-native instruction surface. AGENTS.md remains useful as shared repo guidance. Cursor subagents use markdown files under .cursor/agents or ~/.cursor/agents (with .claude/.codex compatibility paths). Cursor rules do not apply to Tab."
|
|
8222
8258
|
},
|
|
8223
8259
|
sources: [
|
|
8224
8260
|
{ label: "Cursor plugins overview", url: "https://cursor.com/docs/plugins" },
|
|
@@ -8238,7 +8274,7 @@ var PLATFORM_VALIDATION_RULES = {
|
|
|
8238
8274
|
},
|
|
8239
8275
|
"codex": {
|
|
8240
8276
|
platform: "codex",
|
|
8241
|
-
summary: "Codex plugins use .codex-plugin/plugin.json with skills, optional .mcp.json and .app.json, marketplace catalogs, cache installs, AGENTS.md instructions, and
|
|
8277
|
+
summary: "Codex plugins use .codex-plugin/plugin.json with skills, optional .mcp.json and .app.json, marketplace catalogs, cache installs, AGENTS.md instructions, and native bundled hook support plus broader project or user hook config.",
|
|
8242
8278
|
limits: PLATFORM_LIMITS["codex"],
|
|
8243
8279
|
limitPolicies: PLATFORM_LIMIT_POLICIES["codex"],
|
|
8244
8280
|
skillDiscoveryDirs: [
|
|
@@ -8266,9 +8302,9 @@ var PLATFORM_VALIDATION_RULES = {
|
|
|
8266
8302
|
},
|
|
8267
8303
|
hooks: {
|
|
8268
8304
|
supported: true,
|
|
8269
|
-
files: [".codex/hooks.json", "~/.codex/hooks.json"],
|
|
8305
|
+
files: ["hooks/hooks.json", ".codex/hooks.json", "~/.codex/hooks.json"],
|
|
8270
8306
|
eventNames: ["SessionStart", "PreToolUse", "PermissionRequest", "PostToolUse", "UserPromptSubmit", "Stop"],
|
|
8271
|
-
notes: "Codex documents hooks in project
|
|
8307
|
+
notes: "Codex documents hooks in project and user config, and the hooks docs still mention the codex_hooks feature flag/runtime caveat. The official hooks docs also cover plugin-bundled hooks, which Pluxx now emits at hooks/hooks.json."
|
|
8272
8308
|
},
|
|
8273
8309
|
instructions: {
|
|
8274
8310
|
files: ["AGENTS.md", "AGENTS.override.md"],
|
|
@@ -8286,6 +8322,9 @@ var PLATFORM_VALIDATION_RULES = {
|
|
|
8286
8322
|
{ label: "Codex hooks docs", url: "https://developers.openai.com/codex/hooks" },
|
|
8287
8323
|
{ label: "Codex skills docs", url: "https://developers.openai.com/codex/skills" },
|
|
8288
8324
|
{ label: "Codex MCP docs", url: "https://developers.openai.com/codex/mcp" },
|
|
8325
|
+
{ label: "Codex basic config docs", url: "https://developers.openai.com/codex/config-basic" },
|
|
8326
|
+
{ label: "Codex agent approvals and security docs", url: "https://developers.openai.com/codex/agent-approvals-security" },
|
|
8327
|
+
{ label: "Codex app commands docs", url: "https://developers.openai.com/codex/app/commands" },
|
|
8289
8328
|
{ label: "Codex AGENTS.md guide", url: "https://developers.openai.com/codex/guides/agents-md" },
|
|
8290
8329
|
{ label: "Codex subagents docs", url: "https://developers.openai.com/codex/subagents" },
|
|
8291
8330
|
{ label: "Codex subagents concept docs", url: "https://developers.openai.com/codex/concepts/subagents" },
|
|
@@ -8296,7 +8335,7 @@ var PLATFORM_VALIDATION_RULES = {
|
|
|
8296
8335
|
},
|
|
8297
8336
|
"opencode": {
|
|
8298
8337
|
platform: "opencode",
|
|
8299
|
-
summary: "OpenCode plugins are code-first JS or TS modules loaded from local plugin dirs or npm references in config, with native skills, commands, agents, MCP, and
|
|
8338
|
+
summary: "OpenCode plugins are code-first JS or TS modules loaded from local plugin dirs or npm references in config, with native skills, commands, agents, MCP, permission, custom-tool, and plugin-event surfaces.",
|
|
8300
8339
|
limits: PLATFORM_LIMITS["opencode"],
|
|
8301
8340
|
limitPolicies: PLATFORM_LIMIT_POLICIES["opencode"],
|
|
8302
8341
|
skillDiscoveryDirs: [
|
|
@@ -8326,13 +8365,13 @@ var PLATFORM_VALIDATION_RULES = {
|
|
|
8326
8365
|
hooks: {
|
|
8327
8366
|
supported: true,
|
|
8328
8367
|
files: ["plugin module (index.ts/index.js)"],
|
|
8329
|
-
eventNames: [],
|
|
8330
|
-
notes: "OpenCode hooks are plugin event handlers implemented in code, not a separate hooks.json file."
|
|
8368
|
+
eventNames: ["command.executed", "file.edited", "file.watcher.updated", "installation.updated", "lsp.client.diagnostics", "lsp.updated", "message.part.removed", "message.part.updated", "message.removed", "message.updated", "permission.asked", "permission.replied", "server.connected", "session.created", "session.compacted", "session.deleted", "session.diff", "session.error", "session.idle", "session.status", "session.updated", "todo.updated", "shell.env", "tool.execute.before", "tool.execute.after", "tui.prompt.append", "tui.command.execute", "tui.toast.show", "experimental.session.compacting"],
|
|
8369
|
+
notes: "OpenCode hooks are plugin event handlers implemented in code, not a separate hooks.json file. The official surface is an event bus rather than a small lifecycle-hook JSON schema."
|
|
8331
8370
|
},
|
|
8332
8371
|
instructions: {
|
|
8333
8372
|
files: ["AGENTS.md", "CLAUDE.md", "opencode.json"],
|
|
8334
8373
|
format: "markdown + json + code",
|
|
8335
|
-
notes: "OpenCode supports AGENTS.md, CLAUDE.md fallback, config instructions, and plugin runtime instruction injection."
|
|
8374
|
+
notes: "OpenCode supports AGENTS.md, CLAUDE.md fallback, config instructions, and plugin runtime instruction injection. Config layering also includes remote config, managed config files, and macOS managed preferences."
|
|
8336
8375
|
},
|
|
8337
8376
|
sources: [
|
|
8338
8377
|
{ label: "OpenCode SDK docs", url: "https://opencode.ai/docs/sdk/" },
|
|
@@ -8693,8 +8732,8 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
|
|
|
8693
8732
|
},
|
|
8694
8733
|
commands: {
|
|
8695
8734
|
mode: "degrade",
|
|
8696
|
-
nativeSurfaces: ["skills/", "AGENTS.md"],
|
|
8697
|
-
notes: "Current Codex docs do not document plugin-packaged slash-command parity."
|
|
8735
|
+
nativeSurfaces: ["skills/", "AGENTS.md", ".codex/commands.generated.json"],
|
|
8736
|
+
notes: "Current Codex docs do not document plugin-packaged slash-command parity, so Pluxx keeps canonical command intent through routing guidance plus a generated companion mirror."
|
|
8698
8737
|
},
|
|
8699
8738
|
agents: {
|
|
8700
8739
|
mode: "translate",
|
|
@@ -8703,8 +8742,8 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
|
|
|
8703
8742
|
},
|
|
8704
8743
|
hooks: {
|
|
8705
8744
|
mode: "translate",
|
|
8706
|
-
nativeSurfaces: [".codex/hooks.json", "~/.codex/hooks.json"],
|
|
8707
|
-
notes: "Hooks are native
|
|
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 plus the codex_hooks feature-gate caveat."
|
|
8708
8747
|
},
|
|
8709
8748
|
permissions: {
|
|
8710
8749
|
mode: "translate",
|
|
@@ -8947,6 +8986,7 @@ var CompilerIntentSkillPolicySchema = external_exports.object({
|
|
|
8947
8986
|
skillDir: external_exports.string(),
|
|
8948
8987
|
title: external_exports.string(),
|
|
8949
8988
|
description: external_exports.string().optional(),
|
|
8989
|
+
sourceFrontmatter: external_exports.record(external_exports.unknown()).optional(),
|
|
8950
8990
|
source: external_exports.object({
|
|
8951
8991
|
kind: external_exports.literal("claude-allowed-tools"),
|
|
8952
8992
|
platform: external_exports.literal("claude-code").default("claude-code")
|
|
@@ -9082,6 +9122,23 @@ function collectUserConfigEntries(config, platforms = config.targets) {
|
|
|
9082
9122
|
]);
|
|
9083
9123
|
}
|
|
9084
9124
|
|
|
9125
|
+
// src/distribution-lifecycle.ts
|
|
9126
|
+
var VERIFY_STALE_ACTIONS = {
|
|
9127
|
+
codex: "in Codex, use Plugins > Refresh if available, or restart Codex so the plugin cache reloads"
|
|
9128
|
+
};
|
|
9129
|
+
var PUBLISH_RELOAD_INSTRUCTIONS = {
|
|
9130
|
+
"claude-code": "If Claude is already open, run /reload-plugins in the active session.",
|
|
9131
|
+
cursor: "If Cursor is already open, use Developer: Reload Window or restart Cursor so the plugin is picked up.",
|
|
9132
|
+
codex: "If Codex is already open, use Plugins > Refresh if that action is available in your current UI, or restart Codex so the plugin is picked up.",
|
|
9133
|
+
opencode: "If OpenCode is already open, restart or reload it so the plugin is picked up."
|
|
9134
|
+
};
|
|
9135
|
+
function getVerifyInstallStaleAction(target) {
|
|
9136
|
+
return VERIFY_STALE_ACTIONS[target];
|
|
9137
|
+
}
|
|
9138
|
+
function getPublishReloadInstruction(target) {
|
|
9139
|
+
return PUBLISH_RELOAD_INSTRUCTIONS[target];
|
|
9140
|
+
}
|
|
9141
|
+
|
|
9085
9142
|
// src/cli/publish.ts
|
|
9086
9143
|
var INSTALLER_TARGETS = ["claude-code", "cursor", "codex", "opencode"];
|
|
9087
9144
|
function runCommandDefault(command, args, options) {
|
|
@@ -9724,7 +9781,7 @@ claude plugin install "\${PLUGIN_NAME}@\${MARKETPLACE_NAME}" --scope user
|
|
|
9724
9781
|
|
|
9725
9782
|
echo
|
|
9726
9783
|
echo "Installed \${PLUGIN_NAME}@\${MARKETPLACE_NAME} into Claude Code user scope."
|
|
9727
|
-
echo "
|
|
9784
|
+
echo "${getPublishReloadInstruction("claude-code")}"
|
|
9728
9785
|
`;
|
|
9729
9786
|
}
|
|
9730
9787
|
function renderInstallCursorScript(config) {
|
|
@@ -9781,7 +9838,7 @@ ${renderInstallerMcpPathMaterializationSnippet("cursor", "$INSTALL_DIR")}
|
|
|
9781
9838
|
${renderInstallerRuntimeBootstrapSnippet("$INSTALL_DIR")}
|
|
9782
9839
|
|
|
9783
9840
|
echo "Installed $PLUGIN_NAME to $INSTALL_DIR"
|
|
9784
|
-
echo "
|
|
9841
|
+
echo "${getPublishReloadInstruction("cursor")}"
|
|
9785
9842
|
`;
|
|
9786
9843
|
}
|
|
9787
9844
|
function renderInstallCodexScript(config) {
|
|
@@ -9898,7 +9955,7 @@ NODE
|
|
|
9898
9955
|
|
|
9899
9956
|
echo "Installed $PLUGIN_NAME to $INSTALL_DIR"
|
|
9900
9957
|
echo "Updated Codex marketplace catalog at $MARKETPLACE_PATH"
|
|
9901
|
-
echo "
|
|
9958
|
+
echo "${getPublishReloadInstruction("codex")}"
|
|
9902
9959
|
`;
|
|
9903
9960
|
}
|
|
9904
9961
|
function renderInstallOpenCodeScript(config) {
|
|
@@ -10045,7 +10102,7 @@ fi
|
|
|
10045
10102
|
echo "Installed $PLUGIN_NAME plugin code to $INSTALL_DIR"
|
|
10046
10103
|
echo "Installed OpenCode wrapper at $ENTRY_PATH"
|
|
10047
10104
|
echo "Synced namespaced skills into $SKILLS_ROOT"
|
|
10048
|
-
echo "
|
|
10105
|
+
echo "${getPublishReloadInstruction("opencode")}"
|
|
10049
10106
|
`;
|
|
10050
10107
|
}
|
|
10051
10108
|
function replaceInstallerPlaceholders(script, config, context) {
|
|
@@ -10241,7 +10298,7 @@ import { existsSync as existsSync5, lstatSync as lstatSync2, readdirSync as read
|
|
|
10241
10298
|
import { resolve as resolve5 } from "path";
|
|
10242
10299
|
|
|
10243
10300
|
// src/cli/doctor.ts
|
|
10244
|
-
import { spawn } from "child_process";
|
|
10301
|
+
import { spawn, spawnSync as spawnSync2 } from "child_process";
|
|
10245
10302
|
import { accessSync, constants, existsSync as existsSync4, lstatSync, readFileSync as readFileSync4, readdirSync as readdirSync2 } from "fs";
|
|
10246
10303
|
import { basename, dirname as dirname2, resolve as resolve4 } from "path";
|
|
10247
10304
|
|
|
@@ -11131,6 +11188,166 @@ function checkInstalledBundleIntegrity(checks, rootDir, layout) {
|
|
|
11131
11188
|
path: layout.manifestPath
|
|
11132
11189
|
});
|
|
11133
11190
|
}
|
|
11191
|
+
function parseInstalledPermissionRules(scriptSource) {
|
|
11192
|
+
const match = scriptSource.match(/const RULES = (\[[\s\S]*?\]);\nconst ACTION_PRIORITY/);
|
|
11193
|
+
if (!match?.[1]) {
|
|
11194
|
+
throw new Error("Could not locate embedded RULES payload in hooks/pluxx-permissions.mjs.");
|
|
11195
|
+
}
|
|
11196
|
+
const parsed = JSON.parse(match[1]);
|
|
11197
|
+
if (!Array.isArray(parsed)) {
|
|
11198
|
+
throw new Error("Embedded RULES payload is not an array.");
|
|
11199
|
+
}
|
|
11200
|
+
return parsed;
|
|
11201
|
+
}
|
|
11202
|
+
function materializePermissionPattern(pattern) {
|
|
11203
|
+
return pattern.replace(/\*\*/g, "probe/path").replace(/\*/g, "probe");
|
|
11204
|
+
}
|
|
11205
|
+
function buildInstalledPermissionProbe(platform, rule) {
|
|
11206
|
+
const value = materializePermissionPattern(rule.pattern);
|
|
11207
|
+
if (rule.kind === "Bash") {
|
|
11208
|
+
return {
|
|
11209
|
+
action: rule.action,
|
|
11210
|
+
raw: rule.raw,
|
|
11211
|
+
mode: platform === "cursor" ? "cursor-shell" : "claude-pretool",
|
|
11212
|
+
event: platform === "cursor" ? { command: value } : { tool_name: "Bash", tool_input: { command: value } }
|
|
11213
|
+
};
|
|
11214
|
+
}
|
|
11215
|
+
if (rule.kind === "Read") {
|
|
11216
|
+
return {
|
|
11217
|
+
action: rule.action,
|
|
11218
|
+
raw: rule.raw,
|
|
11219
|
+
mode: platform === "cursor" ? "cursor-read" : "claude-pretool",
|
|
11220
|
+
event: platform === "cursor" ? { file_path: value } : { tool_name: "Read", tool_input: { file_path: value } }
|
|
11221
|
+
};
|
|
11222
|
+
}
|
|
11223
|
+
if (rule.kind === "Edit") {
|
|
11224
|
+
return {
|
|
11225
|
+
action: rule.action,
|
|
11226
|
+
raw: rule.raw,
|
|
11227
|
+
mode: platform === "cursor" ? "cursor" : "claude-pretool",
|
|
11228
|
+
event: { tool_name: "Edit", tool_input: { file_path: value } }
|
|
11229
|
+
};
|
|
11230
|
+
}
|
|
11231
|
+
if (rule.kind === "Skill") {
|
|
11232
|
+
return {
|
|
11233
|
+
action: rule.action,
|
|
11234
|
+
raw: rule.raw,
|
|
11235
|
+
mode: platform === "cursor" ? "cursor" : "claude-pretool",
|
|
11236
|
+
event: { tool_name: "Skill", tool_input: { name: value } }
|
|
11237
|
+
};
|
|
11238
|
+
}
|
|
11239
|
+
if (rule.kind === "MCP") {
|
|
11240
|
+
const canonical = value.includes(".") ? value : `${value}.probe`;
|
|
11241
|
+
const dotIndex = canonical.indexOf(".");
|
|
11242
|
+
const server = canonical.slice(0, dotIndex).trim();
|
|
11243
|
+
const tool = canonical.slice(dotIndex + 1).trim();
|
|
11244
|
+
if (!server || !tool) return null;
|
|
11245
|
+
return {
|
|
11246
|
+
action: rule.action,
|
|
11247
|
+
raw: rule.raw,
|
|
11248
|
+
mode: platform === "cursor" ? "cursor-mcp" : "claude-pretool",
|
|
11249
|
+
event: platform === "cursor" ? { tool_name: `mcp__${server}__${tool.replace(/\./g, "__")}` } : { tool_name: `mcp__${server}__${tool.replace(/\./g, "__")}` }
|
|
11250
|
+
};
|
|
11251
|
+
}
|
|
11252
|
+
return null;
|
|
11253
|
+
}
|
|
11254
|
+
function extractPermissionDecision(platform, payload) {
|
|
11255
|
+
if (platform === "claude-code") {
|
|
11256
|
+
const hookSpecificOutput = payload.hookSpecificOutput;
|
|
11257
|
+
if (!hookSpecificOutput || typeof hookSpecificOutput !== "object") return void 0;
|
|
11258
|
+
const decision2 = hookSpecificOutput.permissionDecision;
|
|
11259
|
+
return typeof decision2 === "string" ? decision2 : void 0;
|
|
11260
|
+
}
|
|
11261
|
+
const decision = payload.permission;
|
|
11262
|
+
return typeof decision === "string" ? decision : void 0;
|
|
11263
|
+
}
|
|
11264
|
+
function smokeCheckInstalledPermissionHook(rootDir, layout) {
|
|
11265
|
+
if (layout.platform !== "claude-code" && layout.platform !== "cursor") {
|
|
11266
|
+
return null;
|
|
11267
|
+
}
|
|
11268
|
+
const scriptPath = resolve4(rootDir, "hooks/pluxx-permissions.mjs");
|
|
11269
|
+
if (!existsSync4(scriptPath)) {
|
|
11270
|
+
return null;
|
|
11271
|
+
}
|
|
11272
|
+
const rules = parseInstalledPermissionRules(readFileSync4(scriptPath, "utf-8"));
|
|
11273
|
+
const selected = /* @__PURE__ */ new Map();
|
|
11274
|
+
for (const rule of rules) {
|
|
11275
|
+
if (selected.has(rule.action)) continue;
|
|
11276
|
+
const probe = buildInstalledPermissionProbe(layout.platform, rule);
|
|
11277
|
+
if (!probe) continue;
|
|
11278
|
+
selected.set(rule.action, probe);
|
|
11279
|
+
}
|
|
11280
|
+
if (selected.size === 0) {
|
|
11281
|
+
return {
|
|
11282
|
+
ok: false,
|
|
11283
|
+
detail: "Permission hook script is present, but no supported canonical probe cases could be derived from its embedded rules."
|
|
11284
|
+
};
|
|
11285
|
+
}
|
|
11286
|
+
const failures = [];
|
|
11287
|
+
const successes = [];
|
|
11288
|
+
for (const probe of selected.values()) {
|
|
11289
|
+
const result = spawnSync2("node", [scriptPath, probe.mode], {
|
|
11290
|
+
cwd: rootDir,
|
|
11291
|
+
input: JSON.stringify(probe.event),
|
|
11292
|
+
encoding: "utf-8",
|
|
11293
|
+
env: process.env
|
|
11294
|
+
});
|
|
11295
|
+
if (result.status !== 0) {
|
|
11296
|
+
failures.push(`${probe.raw} exited ${result.status ?? "null"}${result.stderr ? `: ${result.stderr.trim()}` : ""}`);
|
|
11297
|
+
continue;
|
|
11298
|
+
}
|
|
11299
|
+
let payload;
|
|
11300
|
+
try {
|
|
11301
|
+
payload = JSON.parse(result.stdout || "{}");
|
|
11302
|
+
} catch (error) {
|
|
11303
|
+
failures.push(`${probe.raw} returned non-JSON output: ${error instanceof Error ? error.message : String(error)}`);
|
|
11304
|
+
continue;
|
|
11305
|
+
}
|
|
11306
|
+
const decision = extractPermissionDecision(layout.platform, payload);
|
|
11307
|
+
if (decision !== probe.action) {
|
|
11308
|
+
failures.push(`${probe.raw} returned ${decision ?? "no decision"} instead of ${probe.action}`);
|
|
11309
|
+
continue;
|
|
11310
|
+
}
|
|
11311
|
+
successes.push(`${probe.raw} -> ${decision}`);
|
|
11312
|
+
}
|
|
11313
|
+
return failures.length > 0 ? { ok: false, detail: failures.join("; ") } : { ok: true, detail: `Validated ${successes.join(", ")}` };
|
|
11314
|
+
}
|
|
11315
|
+
function checkInstalledPermissionHook(checks, rootDir, layout) {
|
|
11316
|
+
const permissionScriptPath = "hooks/pluxx-permissions.mjs";
|
|
11317
|
+
let scriptResult;
|
|
11318
|
+
try {
|
|
11319
|
+
scriptResult = smokeCheckInstalledPermissionHook(rootDir, layout);
|
|
11320
|
+
} catch (error) {
|
|
11321
|
+
addCheck(checks, {
|
|
11322
|
+
level: "error",
|
|
11323
|
+
code: "consumer-permission-hook-invalid",
|
|
11324
|
+
title: "Installed bundled permission hook behavior is broken",
|
|
11325
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
11326
|
+
fix: "Rebuild or reinstall the plugin so the bundled permission hook script and hook wiring stay aligned with the declared permission rules.",
|
|
11327
|
+
path: permissionScriptPath
|
|
11328
|
+
});
|
|
11329
|
+
return;
|
|
11330
|
+
}
|
|
11331
|
+
if (!scriptResult) {
|
|
11332
|
+
addCheck(checks, {
|
|
11333
|
+
level: "info",
|
|
11334
|
+
code: "consumer-permission-hook-not-applicable",
|
|
11335
|
+
title: "No bundled permission hook smoke check for this install",
|
|
11336
|
+
detail: layout.platform === "claude-code" || layout.platform === "cursor" ? "This installed bundle does not include hooks/pluxx-permissions.mjs." : "This platform does not currently use a bundled pluxx-permissions.mjs hook script for permission enforcement.",
|
|
11337
|
+
fix: "No action needed unless you expected bundled permission-hook enforcement in this installed bundle.",
|
|
11338
|
+
path: permissionScriptPath
|
|
11339
|
+
});
|
|
11340
|
+
return;
|
|
11341
|
+
}
|
|
11342
|
+
addCheck(checks, {
|
|
11343
|
+
level: scriptResult.ok ? "success" : "error",
|
|
11344
|
+
code: scriptResult.ok ? "consumer-permission-hook-valid" : "consumer-permission-hook-invalid",
|
|
11345
|
+
title: scriptResult.ok ? "Installed bundled permission hook returns expected decisions" : "Installed bundled permission hook behavior is broken",
|
|
11346
|
+
detail: scriptResult.detail,
|
|
11347
|
+
fix: scriptResult.ok ? "No action needed." : "Rebuild or reinstall the plugin so the bundled permission hook script and hook wiring stay aligned with the declared permission rules.",
|
|
11348
|
+
path: permissionScriptPath
|
|
11349
|
+
});
|
|
11350
|
+
}
|
|
11134
11351
|
function findMissingInstalledStdioRuntimePaths(rootDir, stdioEntries) {
|
|
11135
11352
|
const missing = /* @__PURE__ */ new Set();
|
|
11136
11353
|
for (const server of stdioEntries) {
|
|
@@ -11398,6 +11615,7 @@ async function doctorConsumer(rootDir = process.cwd()) {
|
|
|
11398
11615
|
});
|
|
11399
11616
|
checkConsumerManifest(checks, rootDir, layout);
|
|
11400
11617
|
checkInstalledBundleIntegrity(checks, rootDir, layout);
|
|
11618
|
+
checkInstalledPermissionHook(checks, rootDir, layout);
|
|
11401
11619
|
checkInstalledUserConfig(checks, rootDir);
|
|
11402
11620
|
checkInstalledEnvValidation(checks, rootDir);
|
|
11403
11621
|
checkInstalledRuntimeScriptRoles(checks, rootDir);
|
|
@@ -11557,9 +11775,8 @@ function getVerifyInstallRecoveryActions(check) {
|
|
|
11557
11775
|
}
|
|
11558
11776
|
if (check.stale) {
|
|
11559
11777
|
actions.push(`rerun pluxx install --target ${check.platform} to replace the stale local install`);
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
}
|
|
11778
|
+
const staleAction = getVerifyInstallStaleAction(check.platform);
|
|
11779
|
+
if (staleAction) actions.push(staleAction);
|
|
11563
11780
|
}
|
|
11564
11781
|
if (check.errors > 0 && actions.length === 0) {
|
|
11565
11782
|
actions.push(`run pluxx doctor --consumer "${check.consumerPath}" for the detailed host-specific failure`);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PluginConfig } from './schema';
|
|
2
|
+
export declare function resolveInstructionsPath(rootDir: string, config: Pick<PluginConfig, 'instructions'>): string | null;
|
|
3
|
+
export declare function readInstructionsContent(rootDir: string, config: Pick<PluginConfig, 'instructions'>): Promise<string | null>;
|
|
4
|
+
export declare function readInstructionsContentSync(rootDir: string, config: Pick<PluginConfig, 'instructions'>): string | null;
|
|
5
|
+
export declare function renderTitledInstructionsDocument(config: Pick<PluginConfig, 'name' | 'description' | 'brand'>, content: string, titleSuffix?: string): string;
|
|
6
|
+
//# sourceMappingURL=instructions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAG5C,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,GACzC,MAAM,GAAG,IAAI,CAIf;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,GACzC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,GACzC,MAAM,GAAG,IAAI,CAIf;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,SAAW,GAAG,MAAM,CAQ9J"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PluginConfig, TargetPlatform, UserConfigEntry } from './schema';
|
|
2
|
+
type JsonRecord = Record<string, unknown>;
|
|
3
|
+
type NativeMcpServerOverrides = Record<string, Record<string, unknown>>;
|
|
4
|
+
type NativeMcpPlatformOverrides = Partial<Record<TargetPlatform, {
|
|
5
|
+
mcpServers: NativeMcpServerOverrides;
|
|
6
|
+
}>>;
|
|
7
|
+
export declare function extractNativeMcpAuthConfig(cfg: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
8
|
+
export declare function buildNativeMcpPlatformOverrides(platform: TargetPlatform, servers: Record<string, unknown>): NativeMcpPlatformOverrides | undefined;
|
|
9
|
+
export declare function getNativeMcpServerOverride(config: PluginConfig, platform: TargetPlatform, serverName: string): JsonRecord | undefined;
|
|
10
|
+
export declare function getNativeJsonHeadersOverride(config: PluginConfig, platform: TargetPlatform, serverName: string): Record<string, string> | undefined;
|
|
11
|
+
export declare function getNativeCodexMcpEntryOverride(config: PluginConfig, serverName: string): JsonRecord | undefined;
|
|
12
|
+
export declare function collectNativeMcpAuthUserConfigEntries(config: PluginConfig, platforms: TargetPlatform[], existingFields: UserConfigEntry[]): UserConfigEntry[];
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=mcp-native-overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-native-overrides.d.ts","sourceRoot":"","sources":["../src/mcp-native-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG7E,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AACzC,KAAK,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AACvE,KAAK,0BAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE;IAAE,UAAU,EAAE,wBAAwB,CAAA;CAAE,CAAC,CAAC,CAAA;AA6B3G,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAqB5G;AAED,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,0BAA0B,GAAG,SAAS,CAkBxC;AAWD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,MAAM,GACjB,UAAU,GAAG,SAAS,CAKxB;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAGpC;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,MAAM,GACjB,UAAU,GAAG,SAAS,CAkBxB;AAED,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,cAAc,EAAE,EAC3B,cAAc,EAAE,eAAe,EAAE,GAChC,eAAe,EAAE,CAoDnB"}
|