@orchid-labs/pluxx 0.1.4 → 0.1.5

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/index.js CHANGED
@@ -7132,27 +7132,67 @@ function mergeAction(current, next) {
7132
7132
  return ACTION_PRIORITY[next] > ACTION_PRIORITY[current] ? next : current;
7133
7133
  }
7134
7134
  function permissionRulesNeedToolLevelDowngrade(permissions) {
7135
- return collectPermissionRules(permissions).some((rule) => rule.pattern !== "*");
7135
+ return collectPermissionRules(permissions).some((rule) => rule.kind === "MCP");
7136
7136
  }
7137
7137
  function buildOpenCodePermissionMap(permissions) {
7138
7138
  const rules = collectPermissionRules(permissions);
7139
7139
  const output = {};
7140
- const toolAliases = {
7141
- Bash: ["bash", "shell"],
7142
- Edit: ["edit", "write"],
7143
- Read: ["read"],
7144
- MCP: ["mcp"],
7145
- // OpenCode's native permission surface is tool-level and does not expose
7146
- // a dedicated skill permission key.
7147
- Skill: []
7148
- };
7149
7140
  for (const rule of rules) {
7150
- for (const tool of toolAliases[rule.kind]) {
7151
- output[tool] = mergeAction(output[tool], rule.action);
7141
+ if (rule.kind === "MCP") {
7142
+ const toolName = translateCanonicalMcpPermission(rule.pattern);
7143
+ if (!toolName) continue;
7144
+ output[toolName] = mergeScalarPermission(output[toolName], rule.action);
7145
+ continue;
7152
7146
  }
7147
+ const tool = toOpenCodePermissionTool(rule.kind);
7148
+ if (!tool) continue;
7149
+ output[tool] = mergePatternPermission(output[tool], rule.pattern, rule.action);
7153
7150
  }
7154
7151
  return output;
7155
7152
  }
7153
+ function toOpenCodePermissionTool(kind) {
7154
+ switch (kind) {
7155
+ case "Bash":
7156
+ return "bash";
7157
+ case "Edit":
7158
+ return "edit";
7159
+ case "Read":
7160
+ return "read";
7161
+ case "Skill":
7162
+ return "skill";
7163
+ case "MCP":
7164
+ return null;
7165
+ }
7166
+ }
7167
+ function mergeScalarPermission(current, next) {
7168
+ if (!current) return next;
7169
+ if (typeof current === "string") {
7170
+ return mergeAction(current, next);
7171
+ }
7172
+ const merged = { ...current };
7173
+ merged["*"] = mergeAction(merged["*"], next);
7174
+ return merged;
7175
+ }
7176
+ function mergePatternPermission(current, pattern, next) {
7177
+ if (pattern === "*") {
7178
+ return mergeScalarPermission(current, next);
7179
+ }
7180
+ const merged = typeof current === "string" ? { "*": current } : { ...current ?? {} };
7181
+ merged[pattern] = mergeAction(merged[pattern], next);
7182
+ return merged;
7183
+ }
7184
+ function translateCanonicalMcpPermission(pattern) {
7185
+ const trimmed = pattern.trim();
7186
+ if (!trimmed || trimmed === "*") return null;
7187
+ const dot = trimmed.indexOf(".");
7188
+ if (dot === -1) {
7189
+ return `${trimmed}_*`;
7190
+ }
7191
+ const server = trimmed.slice(0, dot).trim();
7192
+ const tool = trimmed.slice(dot + 1).trim();
7193
+ if (!server || !tool) return null;
7194
+ return `${server}_${tool.replace(/\./g, "_")}`;
7195
+ }
7156
7196
  function buildGeneratedPermissionHookScript(permissions) {
7157
7197
  const rules = collectPermissionRules(permissions);
7158
7198
  if (rules.length === 0) return null;
@@ -7290,6 +7330,7 @@ function claudeResponse(match) {
7290
7330
  if (!match) return {};
7291
7331
  return {
7292
7332
  hookSpecificOutput: {
7333
+ hookEventName: "PreToolUse",
7293
7334
  permissionDecision: match.action,
7294
7335
  permissionDecisionReason: "Pluxx permissions matched " + match.rule.raw,
7295
7336
  },
@@ -7748,10 +7789,22 @@ var PLATFORM_LIMIT_POLICIES = {
7748
7789
  },
7749
7790
  "codex": {
7750
7791
  ...NULL_LIMIT_POLICIES,
7751
- skillDescriptionMax: { kind: "hard" },
7752
- skillNameMustMatchDir: { kind: "hard" },
7753
- manifestPromptMax: { kind: "hard" },
7754
- manifestPromptCountMax: { kind: "hard" },
7792
+ skillDescriptionMax: {
7793
+ kind: "advisory",
7794
+ notes: "Pluxx keeps Codex descriptions concise at 1,024 characters as a conservative compatibility heuristic; the current docs do not state this as an official hard cap."
7795
+ },
7796
+ skillNameMustMatchDir: {
7797
+ kind: "advisory",
7798
+ notes: "Pluxx keeps Codex skill directory names aligned with skill names for portability and predictability, but the current docs do not state this as a formal hard requirement."
7799
+ },
7800
+ manifestPromptMax: {
7801
+ kind: "advisory",
7802
+ notes: "Pluxx keeps Codex default prompts short at 128 characters as a conservative listing heuristic; the current docs do not publish this as a hard limit."
7803
+ },
7804
+ manifestPromptCountMax: {
7805
+ kind: "advisory",
7806
+ notes: "Pluxx keeps Codex default prompt count to three as a conservative listing heuristic; the current docs do not publish this as a hard limit."
7807
+ },
7755
7808
  manifestPathPrefix: { kind: "hard" },
7756
7809
  instructionsMaxBytes: {
7757
7810
  kind: "hard",
@@ -7804,7 +7857,7 @@ var PLATFORM_LIMIT_POLICIES = {
7804
7857
  var PLATFORM_VALIDATION_RULES = {
7805
7858
  "claude-code": {
7806
7859
  platform: "claude-code",
7807
- summary: "Claude Code plugins use an optional manifest at .claude-plugin/plugin.json with auto-discovery for skills, commands, agents, hooks, MCP, and output styles.",
7860
+ summary: "Claude Code plugins use an optional manifest at .claude-plugin/plugin.json with auto-discovery for skills, commands, agents, hooks, MCP, marketplaces, and output styles.",
7808
7861
  limits: PLATFORM_LIMITS["claude-code"],
7809
7862
  limitPolicies: PLATFORM_LIMIT_POLICIES["claude-code"],
7810
7863
  skillDiscoveryDirs: [
@@ -7812,7 +7865,21 @@ var PLATFORM_VALIDATION_RULES = {
7812
7865
  ],
7813
7866
  frontmatter: {
7814
7867
  standard: [...STANDARD_SKILL_FRONTMATTER],
7815
- additional: []
7868
+ additional: [
7869
+ "when_to_use",
7870
+ "argument-hint",
7871
+ "arguments",
7872
+ "user-invocable",
7873
+ "allowed-tools",
7874
+ "model",
7875
+ "effort",
7876
+ "context",
7877
+ "agent",
7878
+ "hooks",
7879
+ "paths",
7880
+ "shell"
7881
+ ],
7882
+ notes: "Claude exposes the richest documented skill frontmatter of the core four."
7816
7883
  },
7817
7884
  manifest: {
7818
7885
  files: [".claude-plugin/plugin.json"],
@@ -7820,43 +7887,58 @@ var PLATFORM_VALIDATION_RULES = {
7820
7887
  notes: "The manifest is optional; if present, name is the only required field."
7821
7888
  },
7822
7889
  mcp: {
7823
- files: [".mcp.json"],
7890
+ files: [".mcp.json", ".claude-plugin/plugin.json"],
7824
7891
  rootKey: "mcpServers",
7825
7892
  transports: ["stdio", "http", "sse"],
7826
- auth: ["headers", "env interpolation"],
7827
- notes: "Claude Code supports either inline MCP config in plugin.json or a separate .mcp.json file."
7893
+ auth: ["headers", "env interpolation", "OAuth 2.0", "bearer tokens", "dynamic headers"],
7894
+ notes: "Claude Code supports either inline MCP config in plugin.json or a separate .mcp.json file, with marketplace and dependency-aware install flows."
7828
7895
  },
7829
7896
  hooks: {
7830
7897
  supported: true,
7831
- files: ["hooks/hooks.json"],
7832
- eventNames: [],
7833
- notes: "Hook configs can be stored in hooks/hooks.json or inlined in plugin.json."
7898
+ files: ["hooks/hooks.json", ".claude-plugin/plugin.json", "~/.claude/settings.json", ".claude/settings.json", ".claude/settings.local.json"],
7899
+ eventNames: ["SessionStart", "PreToolUse", "PostToolUse", "PermissionRequest", "TaskCreated", "TaskCompleted", "Stop", "Notification", "ConfigChange"],
7900
+ 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."
7834
7901
  },
7835
7902
  instructions: {
7836
7903
  files: ["CLAUDE.md"],
7837
- format: "markdown"
7904
+ format: "markdown",
7905
+ notes: "Claude keeps persistent instructions in CLAUDE.md and pushes longer procedures into skills."
7838
7906
  },
7839
7907
  sources: [
7840
- { label: "Claude Code headless docs", url: "https://code.claude.com/docs/en/headless" },
7908
+ { label: "Claude Code MCP docs", url: "https://code.claude.com/docs/en/mcp" },
7909
+ { label: "Claude Code plugin marketplaces docs", url: "https://code.claude.com/docs/en/plugin-marketplaces" },
7910
+ { label: "Claude Code plugin dependencies docs", url: "https://code.claude.com/docs/en/plugin-dependencies" },
7911
+ { label: "Claude Code features overview", url: "https://code.claude.com/docs/en/features-overview" },
7912
+ { label: "Claude Code best practices", url: "https://code.claude.com/docs/en/best-practices" },
7841
7913
  { label: "Claude Code CLI reference", url: "https://code.claude.com/docs/en/cli-reference" },
7842
7914
  { label: "Claude Code discover plugins docs", url: "https://code.claude.com/docs/en/discover-plugins" },
7915
+ { label: "Claude Code plugins docs", url: "https://code.claude.com/docs/en/plugins" },
7843
7916
  { label: "Claude Code plugins reference", url: "https://code.claude.com/docs/en/plugins-reference" },
7917
+ { label: "Claude Code hooks guide", url: "https://code.claude.com/docs/en/hooks-guide" },
7844
7918
  { label: "Claude Code hooks docs", url: "https://code.claude.com/docs/en/hooks" },
7845
- { label: "Claude Code skills docs", url: "https://code.claude.com/docs/en/skills" }
7919
+ { label: "Claude Code skills docs", url: "https://code.claude.com/docs/en/skills" },
7920
+ { label: "Claude Code sub-agents docs", url: "https://code.claude.com/docs/en/sub-agents" },
7921
+ { label: "Claude Code env vars docs", url: "https://code.claude.com/docs/en/env-vars" }
7846
7922
  ]
7847
7923
  },
7848
7924
  "cursor": {
7849
7925
  platform: "cursor",
7850
- summary: "Cursor plugins use .cursor-plugin/plugin.json plus auto-discovered rules, skills, agents, commands, hooks, and mcp.json at the plugin root; Cursor subagents are a related but separate surface under .cursor/agents and ~/.cursor/agents.",
7926
+ summary: "Cursor plugins use .cursor-plugin/plugin.json plus native rules, skills, hooks, MCP, marketplace metadata, and subagent surfaces, with additional project and user config outside the plugin bundle.",
7851
7927
  limits: PLATFORM_LIMITS["cursor"],
7852
7928
  limitPolicies: PLATFORM_LIMIT_POLICIES["cursor"],
7853
7929
  skillDiscoveryDirs: [
7854
7930
  { path: "skills/", level: "supported" },
7855
- { path: "SKILL.md", level: "fallback", notes: "Used when no skills directory or manifest skill path is present." }
7931
+ { path: ".cursor/skills/", level: "supported" },
7932
+ { path: "~/.cursor/skills/", level: "supported" },
7933
+ { path: ".agents/skills/", level: "supported" },
7934
+ { path: "~/.agents/skills/", level: "supported" },
7935
+ { path: ".claude/skills/", level: "supported", notes: "Compatibility directory" },
7936
+ { path: ".codex/skills/", level: "supported", notes: "Compatibility directory" }
7856
7937
  ],
7857
7938
  frontmatter: {
7858
7939
  standard: [...STANDARD_SKILL_FRONTMATTER],
7859
- additional: []
7940
+ additional: [],
7941
+ notes: "Cursor skills document the shared frontmatter set plus compatibility metadata and supporting-file patterns."
7860
7942
  },
7861
7943
  manifest: {
7862
7944
  files: [".cursor-plugin/plugin.json"],
@@ -7864,16 +7946,16 @@ var PLATFORM_VALIDATION_RULES = {
7864
7946
  notes: "Cursor documents plugin.json as the required plugin manifest."
7865
7947
  },
7866
7948
  mcp: {
7867
- files: ["mcp.json"],
7949
+ files: ["mcp.json", ".cursor/mcp.json", "~/.cursor/mcp.json"],
7868
7950
  rootKey: "mcpServers",
7869
- transports: ["stdio", "http", "sse"],
7870
- auth: ["headers", "env interpolation"]
7951
+ transports: ["stdio", "sse", "streamable-http"],
7952
+ auth: ["headers", "env interpolation", "OAuth", "static OAuth credentials"]
7871
7953
  },
7872
7954
  hooks: {
7873
7955
  supported: true,
7874
- files: ["hooks/hooks.json"],
7875
- eventNames: [],
7876
- notes: "Cursor plugin hooks live under hooks/hooks.json; project hooks also exist separately in .cursor/hooks.json."
7956
+ files: ["hooks/hooks.json", ".cursor/hooks.json", "~/.cursor/hooks.json"],
7957
+ eventNames: ["sessionStart", "preToolUse", "postToolUse", "subagentStart", "subagentStop", "beforeShellExecution", "afterShellExecution"],
7958
+ notes: "Cursor plugin hooks live under hooks/hooks.json; project and user hooks also exist separately and reload on save."
7877
7959
  },
7878
7960
  instructions: {
7879
7961
  files: ["rules/", "AGENTS.md"],
@@ -7881,25 +7963,32 @@ var PLATFORM_VALIDATION_RULES = {
7881
7963
  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)."
7882
7964
  },
7883
7965
  sources: [
7884
- { label: "Cursor plugins reference", url: "https://cursor.com/docs/reference/plugins" },
7885
7966
  { label: "Cursor plugins overview", url: "https://cursor.com/docs/plugins" },
7886
7967
  { label: "Cursor hooks docs", url: "https://cursor.com/docs/hooks" },
7887
7968
  { label: "Cursor skills docs", url: "https://cursor.com/docs/skills" },
7888
7969
  { label: "Cursor rules docs", url: "https://cursor.com/docs/rules" },
7889
7970
  { label: "Cursor MCP docs", url: "https://cursor.com/docs/mcp" },
7890
7971
  { label: "Cursor CLI headless docs", url: "https://cursor.com/docs/cli/headless" },
7972
+ { label: "Cursor CLI slash commands", url: "https://cursor.com/docs/cli/reference/slash-commands" },
7891
7973
  { label: "Cursor CLI parameters", url: "https://cursor.com/docs/cli/reference/parameters" },
7892
7974
  { label: "Cursor CLI authentication", url: "https://cursor.com/docs/cli/reference/authentication" },
7975
+ { label: "Cursor CLI permissions", url: "https://cursor.com/docs/cli/reference/permissions" },
7976
+ { label: "Cursor CLI configuration", url: "https://cursor.com/docs/cli/reference/configuration" },
7977
+ { label: "Cursor ACP docs", url: "https://cursor.com/docs/cli/acp" },
7893
7978
  { label: "Cursor subagents docs", url: "https://cursor.com/docs/subagents" }
7894
7979
  ]
7895
7980
  },
7896
7981
  "codex": {
7897
7982
  platform: "codex",
7898
- summary: "Codex plugins use .codex-plugin/plugin.json with skills, .mcp.json, optional app mappings, and AGENTS.md; current docs separate plugin packaging from hooks configuration and do not document plugin-provided slash commands.",
7983
+ summary: "Codex plugins use .codex-plugin/plugin.json with skills, optional .mcp.json and .app.json, marketplace catalogs, cache installs, AGENTS.md instructions, and separate hook configuration.",
7899
7984
  limits: PLATFORM_LIMITS["codex"],
7900
7985
  limitPolicies: PLATFORM_LIMIT_POLICIES["codex"],
7901
7986
  skillDiscoveryDirs: [
7902
- { path: "skills/", level: "supported" }
7987
+ { path: "skills/", level: "supported" },
7988
+ { path: "$CWD/.agents/skills/", level: "supported" },
7989
+ { path: "ancestor .agents/skills/", level: "supported", notes: "Walks upward until repo root" },
7990
+ { path: "$HOME/.agents/skills/", level: "supported" },
7991
+ { path: "/etc/codex/skills/", level: "supported" }
7903
7992
  ],
7904
7993
  frontmatter: {
7905
7994
  standard: [...STANDARD_SKILL_FRONTMATTER],
@@ -7911,68 +8000,95 @@ var PLATFORM_VALIDATION_RULES = {
7911
8000
  notes: "The build plugins guide documents plugin.json, skills/, .mcp.json, .app.json, and assets/ as the standard plugin structure."
7912
8001
  },
7913
8002
  mcp: {
7914
- files: [".mcp.json"],
8003
+ files: [".mcp.json", ".codex/config.toml"],
7915
8004
  rootKey: "mcpServers",
7916
- transports: ["stdio", "http", "sse"],
7917
- auth: ["bearer_token_env_var", "env_http_headers", "http_headers", "platform-managed auth"],
7918
- notes: "The current build guide documents mcpServers as a path to .mcp.json in the plugin bundle."
8005
+ transports: ["stdio", "streamable-http"],
8006
+ auth: ["bearer token", "OAuth", "header env vars"],
8007
+ notes: "The current build guide documents mcpServers as a path to .mcp.json in the plugin bundle, while active MCP state also lives in config.toml."
7919
8008
  },
7920
8009
  hooks: {
7921
8010
  supported: true,
7922
8011
  files: [".codex/hooks.json", "~/.codex/hooks.json"],
7923
- eventNames: [],
7924
- notes: "Codex documents hooks in project/user config, but the current plugin build guide does not document plugin-packaged hooks."
8012
+ eventNames: ["SessionStart", "PreToolUse", "PermissionRequest", "PostToolUse", "UserPromptSubmit", "Stop"],
8013
+ notes: "Codex documents hooks in project/user config, guarded by the codex_hooks feature flag; the current plugin build guide does not document plugin-packaged hooks."
7925
8014
  },
7926
8015
  instructions: {
7927
- files: ["AGENTS.md"],
7928
- format: "markdown"
8016
+ files: ["AGENTS.md", "AGENTS.override.md"],
8017
+ format: "markdown",
8018
+ notes: "Codex also supports model instruction overrides plus configurable fallback filenames for project docs."
7929
8019
  },
7930
8020
  sources: [
8021
+ { label: "Codex plugins docs", url: "https://developers.openai.com/codex/plugins" },
7931
8022
  { label: "Codex build plugins docs", url: "https://developers.openai.com/codex/plugins/build" },
8023
+ { label: "Codex CLI features docs", url: "https://developers.openai.com/codex/cli/features" },
8024
+ { label: "Codex CLI reference docs", url: "https://developers.openai.com/codex/cli/reference" },
8025
+ { label: "Codex slash commands docs", url: "https://developers.openai.com/codex/cli/slash-commands" },
8026
+ { label: "Codex advanced config docs", url: "https://developers.openai.com/codex/config-advanced" },
8027
+ { label: "Codex rules docs", url: "https://developers.openai.com/codex/rules" },
7932
8028
  { label: "Codex hooks docs", url: "https://developers.openai.com/codex/hooks" },
7933
8029
  { label: "Codex skills docs", url: "https://developers.openai.com/codex/skills" },
7934
8030
  { label: "Codex MCP docs", url: "https://developers.openai.com/codex/mcp" },
7935
- { label: "Codex AGENTS.md guide", url: "https://developers.openai.com/codex/guides/agents-md" }
8031
+ { label: "Codex AGENTS.md guide", url: "https://developers.openai.com/codex/guides/agents-md" },
8032
+ { label: "Codex subagents docs", url: "https://developers.openai.com/codex/subagents" },
8033
+ { label: "Codex subagents concept docs", url: "https://developers.openai.com/codex/concepts/subagents" },
8034
+ { label: "Codex noninteractive docs", url: "https://developers.openai.com/codex/noninteractive" },
8035
+ { label: "Codex SDK docs", url: "https://developers.openai.com/codex/sdk" },
8036
+ { label: "Codex agents SDK guide", url: "https://developers.openai.com/codex/guides/agents-sdk" }
7936
8037
  ]
7937
8038
  },
7938
8039
  "opencode": {
7939
8040
  platform: "opencode",
7940
- summary: "OpenCode plugins are code-first TypeScript or JavaScript modules that register skills, commands, MCP servers, and hook handlers programmatically.",
8041
+ 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 permission surfaces.",
7941
8042
  limits: PLATFORM_LIMITS["opencode"],
7942
8043
  limitPolicies: PLATFORM_LIMIT_POLICIES["opencode"],
7943
8044
  skillDiscoveryDirs: [
7944
- { path: "skills/", level: "supported" }
8045
+ { path: "skills/", level: "supported" },
8046
+ { path: ".opencode/skills/", level: "supported" },
8047
+ { path: "~/.config/opencode/skills/", level: "supported" },
8048
+ { path: ".claude/skills/", level: "supported", notes: "Compatibility directory" },
8049
+ { path: ".agents/skills/", level: "supported", notes: "Compatibility directory" }
7945
8050
  ],
7946
8051
  frontmatter: {
7947
8052
  standard: [...STANDARD_SKILL_FRONTMATTER],
7948
- additional: []
8053
+ additional: [],
8054
+ notes: "OpenCode supports Agent Skills semantics, but plugin runtime behavior is code-first rather than manifest-first."
7949
8055
  },
7950
8056
  manifest: {
7951
- files: ["package.json", "index.ts"],
7952
- required: true,
7953
- notes: "OpenCode plugins are loaded as local modules or npm packages rather than a JSON manifest-only bundle."
8057
+ files: ["opencode.json", ".opencode/plugins/", "~/.config/opencode/plugins/"],
8058
+ required: false,
8059
+ notes: "OpenCode plugins are loaded as local modules or npm packages through config rather than a dedicated manifest-only bundle."
7954
8060
  },
7955
8061
  mcp: {
7956
- files: ["index.ts"],
8062
+ files: ["opencode.json"],
8063
+ rootKey: "mcp",
7957
8064
  transports: ["local", "remote"],
7958
- auth: ["headers", "programmatic env interpolation", "OAuth"],
7959
- notes: 'OpenCode plugin code mutates Config["mcp"] programmatically; the underlying platform config supports local and remote servers.'
8065
+ auth: ["headers", "env interpolation", "OAuth"],
8066
+ notes: "OpenCode config owns MCP; plugins can also extend runtime behavior programmatically."
7960
8067
  },
7961
8068
  hooks: {
7962
8069
  supported: true,
7963
- files: ["index.ts"],
8070
+ files: ["plugin module (index.ts/index.js)"],
7964
8071
  eventNames: [],
7965
8072
  notes: "OpenCode hooks are plugin event handlers implemented in code, not a separate hooks.json file."
7966
8073
  },
7967
8074
  instructions: {
7968
- files: ["index.ts"],
7969
- format: "typescript",
7970
- notes: "Plugins inject instructions into the runtime system prompt from code."
8075
+ files: ["AGENTS.md", "CLAUDE.md", "opencode.json"],
8076
+ format: "markdown + json + code",
8077
+ notes: "OpenCode supports AGENTS.md, CLAUDE.md fallback, config instructions, and plugin runtime instruction injection."
7971
8078
  },
7972
8079
  sources: [
8080
+ { label: "OpenCode SDK docs", url: "https://opencode.ai/docs/sdk/" },
8081
+ { label: "OpenCode server docs", url: "https://opencode.ai/docs/server/" },
8082
+ { label: "OpenCode config docs", url: "https://opencode.ai/docs/config/" },
7973
8083
  { label: "OpenCode plugins docs", url: "https://opencode.ai/docs/plugins/" },
7974
8084
  { label: "OpenCode skills docs", url: "https://opencode.ai/docs/skills/" },
7975
- { label: "OpenCode MCP servers docs", url: "https://opencode.ai/docs/mcp-servers/" }
8085
+ { label: "OpenCode commands docs", url: "https://opencode.ai/docs/commands/" },
8086
+ { label: "OpenCode agents docs", url: "https://opencode.ai/docs/agents/" },
8087
+ { label: "OpenCode MCP servers docs", url: "https://opencode.ai/docs/mcp-servers/" },
8088
+ { label: "OpenCode custom tools docs", url: "https://opencode.ai/docs/custom-tools/" },
8089
+ { label: "OpenCode permissions docs", url: "https://opencode.ai/docs/permissions/" },
8090
+ { label: "OpenCode rules docs", url: "https://opencode.ai/docs/rules/" },
8091
+ { label: "OpenCode ACP docs", url: "https://opencode.ai/docs/acp/" }
7976
8092
  ]
7977
8093
  },
7978
8094
  "openhands": {
@@ -8236,7 +8352,8 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
8236
8352
  },
8237
8353
  commands: {
8238
8354
  mode: "preserve",
8239
- nativeSurfaces: ["commands/*.md"]
8355
+ nativeSurfaces: ["commands/*.md", "skills/<skill>/SKILL.md"],
8356
+ notes: "Claude still supports command files, but the product is increasingly converging command workflows into skills."
8240
8357
  },
8241
8358
  agents: {
8242
8359
  mode: "preserve",
@@ -8245,7 +8362,7 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
8245
8362
  },
8246
8363
  hooks: {
8247
8364
  mode: "preserve",
8248
- nativeSurfaces: ["hooks/hooks.json", ".claude-plugin/plugin.json"]
8365
+ nativeSurfaces: ["hooks/hooks.json", ".claude-plugin/plugin.json", "settings hooks", "skill/agent frontmatter hooks"]
8249
8366
  },
8250
8367
  permissions: {
8251
8368
  mode: "translate",
@@ -8258,8 +8375,8 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
8258
8375
  },
8259
8376
  distribution: {
8260
8377
  mode: "translate",
8261
- nativeSurfaces: [".claude-plugin/plugin.json", "install scopes", "user configuration"],
8262
- notes: "Distribution surfaces are native, but shared brand metadata is narrower than Codex."
8378
+ nativeSurfaces: [".claude-plugin/plugin.json", "marketplaces", "install scopes", "user configuration", "/reload-plugins"],
8379
+ notes: "Distribution surfaces are native, including plugin marketplaces and explicit reload behavior."
8263
8380
  }
8264
8381
  },
8265
8382
  sources: PLATFORM_VALIDATION_RULES["claude-code"].sources
@@ -8278,7 +8395,7 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
8278
8395
  },
8279
8396
  commands: {
8280
8397
  mode: "preserve",
8281
- nativeSurfaces: ["commands/*"]
8398
+ nativeSurfaces: ["commands/*", "slash commands"]
8282
8399
  },
8283
8400
  agents: {
8284
8401
  mode: "translate",
@@ -8296,11 +8413,11 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
8296
8413
  },
8297
8414
  runtime: {
8298
8415
  mode: "preserve",
8299
- nativeSurfaces: ["mcp.json", ".cursor-plugin/plugin.json", "scripts/", "assets/"]
8416
+ nativeSurfaces: ["mcp.json", ".cursor/mcp.json", "~/.cursor/mcp.json", ".cursor-plugin/plugin.json", "scripts/", "assets/"]
8300
8417
  },
8301
8418
  distribution: {
8302
8419
  mode: "preserve",
8303
- nativeSurfaces: [".cursor-plugin/plugin.json", ".cursor-plugin/marketplace.json", "local marketplace install path"]
8420
+ nativeSurfaces: [".cursor-plugin/plugin.json", ".cursor-plugin/marketplace.json", "local marketplace install path", "reload window / restart"]
8304
8421
  }
8305
8422
  },
8306
8423
  sources: PLATFORM_VALIDATION_RULES["cursor"].sources
@@ -8343,7 +8460,7 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
8343
8460
  },
8344
8461
  distribution: {
8345
8462
  mode: "preserve",
8346
- nativeSurfaces: [".codex-plugin/plugin.json", "~/.agents/plugins/marketplace.json", "$REPO_ROOT/.agents/plugins/marketplace.json"]
8463
+ nativeSurfaces: [".codex-plugin/plugin.json", "~/.agents/plugins/marketplace.json", "$REPO_ROOT/.agents/plugins/marketplace.json", "cache install path", "restart after update"]
8347
8464
  }
8348
8465
  },
8349
8466
  sources: PLATFORM_VALIDATION_RULES["codex"].sources
@@ -8353,7 +8470,7 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
8353
8470
  buckets: {
8354
8471
  instructions: {
8355
8472
  mode: "translate",
8356
- nativeSurfaces: ["config instructions", "plugin code"],
8473
+ nativeSurfaces: ["AGENTS.md", "CLAUDE.md", "config instructions", "plugin code"],
8357
8474
  notes: "OpenCode instructions are native, but the surface is config- and code-driven rather than manifest markdown only."
8358
8475
  },
8359
8476
  skills: {
@@ -8366,7 +8483,8 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
8366
8483
  },
8367
8484
  agents: {
8368
8485
  mode: "preserve",
8369
- nativeSurfaces: ["agents/*.md", "config agent definitions"]
8486
+ nativeSurfaces: ["agents/*.md", "config agent definitions"],
8487
+ notes: "OpenCode agents are first-class native surfaces. Prefer permission-first agent config for new builds; legacy tools remains compatibility input, not the preferred emitted shape."
8370
8488
  },
8371
8489
  hooks: {
8372
8490
  mode: "translate",
@@ -8375,15 +8493,16 @@ var CORE_FOUR_PRIMITIVE_CAPABILITIES = {
8375
8493
  },
8376
8494
  permissions: {
8377
8495
  mode: "preserve",
8378
- nativeSurfaces: ["config permission", "per-agent overrides"]
8496
+ nativeSurfaces: ["config permission", "per-agent overrides"],
8497
+ notes: "OpenCode permission is keyed by tool name and patterns, including native skill and task controls. Legacy tools booleans are deprecated in favor of permission."
8379
8498
  },
8380
8499
  runtime: {
8381
8500
  mode: "preserve",
8382
- nativeSurfaces: ["config mcp", "plugin JS/TS runtime", "scripts/", "assets/"]
8501
+ nativeSurfaces: ["opencode.json", "config mcp", "plugin JS/TS runtime", "scripts/", "assets/"]
8383
8502
  },
8384
8503
  distribution: {
8385
8504
  mode: "translate",
8386
- nativeSurfaces: ["local plugin dir", "npm package", "plugin JS/TS entrypoint"],
8505
+ nativeSurfaces: [".opencode/plugins/", "~/.config/opencode/plugins/", "opencode.json", "npm package", "plugin JS/TS entrypoint"],
8387
8506
  notes: "Distribution is native, but there is no single shared manifest analog to Claude, Cursor, or Codex."
8388
8507
  }
8389
8508
  },
@@ -8686,9 +8805,9 @@ function collectChecks(args) {
8686
8805
  const gitStatus = args.runCommand("git", ["status", "--porcelain"], { cwd: args.rootDir });
8687
8806
  checks.push({
8688
8807
  name: "git-clean",
8689
- ok: gitStatus.status === 0 && gitStatus.stdout.trim() === "",
8808
+ ok: args.allowDirty || gitStatus.status === 0 && gitStatus.stdout.trim() === "",
8690
8809
  code: "git-clean",
8691
- detail: gitStatus.status !== 0 ? gitStatus.stderr || gitStatus.stdout || "Unable to read git status" : gitStatus.stdout.trim() === "" ? "Working tree is clean." : "Working tree has uncommitted changes."
8810
+ detail: args.allowDirty ? "Working tree cleanliness check skipped via --allow-dirty." : gitStatus.status !== 0 ? gitStatus.stderr || gitStatus.stdout || "Unable to read git status" : gitStatus.stdout.trim() === "" ? "Working tree is clean." : "Working tree has uncommitted changes."
8692
8811
  });
8693
8812
  if (args.npmEnabled) {
8694
8813
  checks.push({
@@ -8740,6 +8859,7 @@ function planPublish(config, options = {}) {
8740
8859
  config,
8741
8860
  npmEnabled,
8742
8861
  githubReleaseEnabled,
8862
+ allowDirty: options.allowDirty ?? false,
8743
8863
  packageDir,
8744
8864
  packageName,
8745
8865
  githubRepo,
@@ -9003,7 +9123,7 @@ rm -rf "$INSTALL_DIR"
9003
9123
  cp -R "$BUNDLE_DIR" "$INSTALL_DIR"
9004
9124
 
9005
9125
  echo "Installed $PLUGIN_NAME to $INSTALL_DIR"
9006
- echo "If Cursor is already open, restart or reload it so the plugin is picked up."
9126
+ echo "If Cursor is already open, use Developer: Reload Window or restart Cursor so the plugin is picked up."
9007
9127
  `;
9008
9128
  }
9009
9129
  function renderInstallCodexScript(config) {
@@ -9117,7 +9237,7 @@ NODE
9117
9237
 
9118
9238
  echo "Installed $PLUGIN_NAME to $INSTALL_DIR"
9119
9239
  echo "Updated Codex marketplace catalog at $MARKETPLACE_PATH"
9120
- echo "If Codex is already open, restart it so the plugin is picked up."
9240
+ echo "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."
9121
9241
  `;
9122
9242
  }
9123
9243
  function renderInstallOpenCodeScript(config) {
@@ -9494,7 +9614,7 @@ function getInstallTargets(pluginName) {
9494
9614
  {
9495
9615
  platform: "opencode",
9496
9616
  pluginDir: resolve3(home, ".config/opencode/plugins", pluginName),
9497
- description: `~/.config/opencode/plugins/${pluginName}.ts`
9617
+ description: `~/.config/opencode/plugins/${pluginName}.ts + ~/.config/opencode/plugins/${pluginName}/`
9498
9618
  },
9499
9619
  {
9500
9620
  platform: "github-copilot",
@@ -8,7 +8,7 @@ export interface ParsedPermissionRule {
8
8
  pattern: string;
9
9
  }
10
10
  export interface OpenCodePermissionMap {
11
- [tool: string]: PermissionAction;
11
+ [tool: string]: PermissionAction | Record<string, PermissionAction>;
12
12
  }
13
13
  export declare function parsePermissionRule(raw: string): Omit<ParsedPermissionRule, 'action'> | null;
14
14
  export declare function collectPermissionRules(permissions: Partial<Record<PermissionAction, string[]>> | undefined): ParsedPermissionRule[];
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,mDAAoD,CAAA;AAE1F,MAAM,MAAM,kBAAkB,GAAG,OAAO,yBAAyB,CAAC,MAAM,CAAC,CAAA;AACzE,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAA;AAEvD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,gBAAgB,CAAA;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,kBAAkB,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAAA;CACjC;AAMD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,GAAG,IAAI,CAc5F;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GACnE,oBAAoB,EAAE,CAkBxB;AAaD,wBAAgB,qCAAqC,CACnD,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GACnE,OAAO,CAET;AAED,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GACnE,qBAAqB,CAqBvB;AAED,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GACnE,MAAM,GAAG,IAAI,CA6Jf"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,mDAAoD,CAAA;AAE1F,MAAM,MAAM,kBAAkB,GAAG,OAAO,yBAAyB,CAAC,MAAM,CAAC,CAAA;AACzE,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAA;AAEvD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,gBAAgB,CAAA;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,kBAAkB,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;CACpE;AAMD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,GAAG,IAAI,CAc5F;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GACnE,oBAAoB,EAAE,CAkBxB;AAaD,wBAAgB,qCAAqC,CACnD,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GACnE,OAAO,CAET;AAED,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GACnE,qBAAqB,CAkBvB;AAiED,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,GACnE,MAAM,GAAG,IAAI,CA8Jf"}