@martinffx/atelier 3.5.0 → 3.6.0

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/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@
4
4
 
5
5
  - **breaking:** rename the `recon` agent to `sentinel`. Existing Atelier configuration is migrated automatically and legacy generated files are removed during the next command.
6
6
 
7
+ ## [3.6.0](https://github.com/martinffx/atelier/compare/v3.5.0...v3.6.0) (2026-10-25)
8
+
9
+
10
+ ### Features
11
+
12
+ * **claude:** disable conflicting Claude Code built-ins ([40e074d](https://github.com/martinffx/atelier/commit/40e074df4e55a300ea4521fb05fad9232525715d))
13
+
7
14
  ## [3.5.0](https://github.com/martinffx/atelier/compare/v3.4.0...v3.5.0) (2026-10-18)
8
15
 
9
16
 
package/README.md CHANGED
@@ -141,7 +141,7 @@ Run `atelier update --harness <claude|codex|opencode>` to choose models and thin
141
141
 
142
142
  Thinking is stored as `agents[].thinking`, `build_thinking`, and `plan_thinking` in `~/.atelier/config.json`. Values are model-specific: `default`, `off`, `on`, `low`, `medium`, `high`, `xhigh`, or `max`. The picker offers only verified capabilities. Custom models and catalog models whose controls have not been verified offer `default` only. Missing fields preserve legacy behavior; **Keep existing behavior** preserves that omission when editing. In particular, old Codex configurations retain medium agent/Build effort and high Plan effort. An explicit `default` omits Atelier's native effort override; other harness settings can still apply.
143
143
 
144
- - **Claude Code:** `opusplan` switches Opus/Sonnet by mode. Other session models share one thinking setting across modes. Atelier writes canonical `modelSettings.<model>.effortLevel` entries and subagent `effort`. Session `max` cannot be persisted, though supported subagents can use it. Use Claude Code **2.1.280 or later** for Opus 5.5 and the current aliases. Atelier also sets `disableClaudeAiConnectors: true`, `syncClaudeAiSkills: false` and `syncClaudeAiPlugins: false` in `~/.claude/settings.json`, so nothing from claude.ai is synced into Claude Code; `atelier remove` clears them unless you changed them. [Claude configuration](https://code.claude.com/docs/en/model-config)
144
+ - **Claude Code:** `opusplan` switches Opus/Sonnet by mode. Other session models share one thinking setting across modes. Atelier writes canonical `modelSettings.<model>.effortLevel` entries and subagent `effort`. Session `max` cannot be persisted, though supported subagents can use it. Use Claude Code **2.1.280 or later** for Opus 5.5 and the current aliases. Atelier also sets `disableClaudeAiConnectors: true`, `syncClaudeAiSkills: false` and `syncClaudeAiPlugins: false` in `~/.claude/settings.json`, so nothing from claude.ai is synced into Claude Code; `atelier remove` clears them unless you changed them. It also disables the Claude Code built-ins that clash with Atelier skills (`disableBundledSkills`, `enableArtifact: false`, `disableWorkflows`, deny rules for `Artifact`, `ArtifactComments`, `ArtifactData`, `Workflow` and `DesignSync`, and `skillOverrides` turning off the `/security-review` and `/ultrareview` commands). Interactive `init` also offers a checklist of optional built-ins to disable, none selected by default: `cron` (`/loop` and the Cron tools), `chrome` (the claude-in-chrome MCP server) and `remote-trigger` (`RemoteTrigger`). `atelier remove` and unticking an option undo these the same way. [Claude configuration](https://code.claude.com/docs/en/model-config)
145
145
  - **Codex:** Plan and Build share the selected session model, with separate reasoning settings. Oracle and Architect use independent Astra configurations. `off` maps to native `none`, available on Sol/Luna but not Astra. [Codex configuration](https://developers.openai.com/codex/config-reference/)
146
146
  - **OpenCode:** all five assignments are independent. Use **1.18.30 or later** for GPT-6 integration. Atelier sends explicit provider options rather than relying on automatically discovered reasoning variants: `reasoningEffort` for OpenAI-compatible routes, `effort` for Anthropic, and `reasoningConfig` for Bedrock. GLM 5.3 supports low/high/max; it does not support medium. Bedrock defaults use US inference profiles with `us-east-1`. [OpenCode agents](https://opencode.ai/docs/agents/)
147
147
  - **MiMo:** `on`/`off` maps to `thinking.type: enabled`/`disabled`. There are no graded effort tiers. OpenCode agent files omit the old fixed temperature override so provider defaults apply. [MiMo API](https://mimo.mi.com/docs/en-US/api/chat/openai-api)
package/dist/atelier.js CHANGED
@@ -32570,7 +32570,10 @@ var OpenCodeConfigSchema = objectType({
32570
32570
  plan_thinking: ThinkingSchema.optional(),
32571
32571
  agents: arrayType(ThinkingAgentSchema).min(1)
32572
32572
  }).superRefine((config, ctx) => checkThinking("opencode", config, ctx));
32573
- var ClaudeConfigSchema = SimpleConfigSchema.superRefine((config, ctx) => {
32573
+ var CLAUDE_OPTIONAL_BUILTINS = ["cron", "chrome", "remote-trigger"];
32574
+ var ClaudeConfigSchema = SimpleConfigSchema.extend({
32575
+ disabled_builtins: arrayType(enumType(CLAUDE_OPTIONAL_BUILTINS)).optional()
32576
+ }).superRefine((config, ctx) => {
32574
32577
  checkThinking("claude", config, ctx);
32575
32578
  if (config.default_model !== "opusplan" && config.plan_thinking !== undefined && config.plan_thinking !== config.build_thinking) {
32576
32579
  ctx.addIssue({ code: "custom", path: ["plan_thinking"], message: "Separate Claude Plan/Build thinking requires opusplan" });
@@ -32602,6 +32605,16 @@ var CLAUDE_AI_OPT_OUTS = {
32602
32605
  syncClaudeAiSkills: false,
32603
32606
  syncClaudeAiPlugins: false
32604
32607
  };
32608
+ var CONFLICTING_BUILTINS = {
32609
+ settings: { disableBundledSkills: true, enableArtifact: false, disableWorkflows: true },
32610
+ deny: ["Artifact", "ArtifactComments", "ArtifactData", "Workflow", "DesignSync"],
32611
+ skillOverrides: ["security-review", "ultrareview"]
32612
+ };
32613
+ var OPTIONAL_BUILTINS = {
32614
+ cron: { env: { CLAUDE_CODE_DISABLE_CRON: "1" } },
32615
+ chrome: { deniedMcpServers: ["claude-in-chrome"] },
32616
+ "remote-trigger": { deny: ["RemoteTrigger"] }
32617
+ };
32605
32618
  var claudeAdapter = {
32606
32619
  name: "claude",
32607
32620
  configSchema: ClaudeConfigSchema,
@@ -32631,7 +32644,15 @@ function modelsForProvider(_provider) {
32631
32644
  return [...ANTHROPIC_MODELS];
32632
32645
  }
32633
32646
  async function promptSection(prompt, section) {
32634
- return promptForSimpleModels(prompt, section, modelsForProvider());
32647
+ const claude = section;
32648
+ const result = await promptForSimpleModels(prompt, claude, modelsForProvider());
32649
+ const { disabled } = await prompt.prompt([{
32650
+ type: "checkbox",
32651
+ name: "disabled",
32652
+ message: "Disable optional Claude Code built-ins",
32653
+ choices: CLAUDE_OPTIONAL_BUILTINS.map((value) => ({ name: value, value, checked: claude.disabled_builtins?.includes(value) ?? false }))
32654
+ }]);
32655
+ return { ...result, disabled_builtins: disabled };
32635
32656
  }
32636
32657
  function installAgents(section, basePath) {
32637
32658
  const config = ClaudeConfigSchema.parse(section);
@@ -32671,6 +32692,13 @@ function mergeHarnessConfig(section, basePath) {
32671
32692
  model: config.default_model || DEFAULT_MODELS.default_model
32672
32693
  };
32673
32694
  applyModeThinking(settings, config);
32695
+ applyBuiltins(settings, CONFLICTING_BUILTINS);
32696
+ for (const name of CLAUDE_OPTIONAL_BUILTINS) {
32697
+ if (config.disabled_builtins?.includes(name))
32698
+ applyBuiltins(settings, OPTIONAL_BUILTINS[name]);
32699
+ else
32700
+ removeBuiltins(settings, OPTIONAL_BUILTINS[name]);
32701
+ }
32674
32702
  try {
32675
32703
  mkdirSync2(claudeDir, { recursive: true });
32676
32704
  writeFileSync3(settingsPath, JSON.stringify(settings, null, 2) + `
@@ -32729,6 +32757,9 @@ function removeAtelierSettings(claudeDir, config) {
32729
32757
  delete content[key];
32730
32758
  }
32731
32759
  applyModeThinking(content, config, true);
32760
+ removeBuiltins(content, CONFLICTING_BUILTINS);
32761
+ for (const patch of Object.values(OPTIONAL_BUILTINS))
32762
+ removeBuiltins(content, patch);
32732
32763
  writeOrDeleteSettings(settingsPath, content);
32733
32764
  }
32734
32765
  function applyModeThinking(settings, config, remove = false) {
@@ -32753,6 +32784,75 @@ function applyModeThinking(settings, config, remove = false) {
32753
32784
  else
32754
32785
  delete settings.modelSettings;
32755
32786
  }
32787
+ function applyBuiltins(settings, patch) {
32788
+ Object.assign(settings, patch.settings);
32789
+ if (patch.env)
32790
+ settings.env = { ...settings.env, ...patch.env };
32791
+ if (patch.deny) {
32792
+ const permissions = { ...settings.permissions };
32793
+ const deny = permissions.deny ?? [];
32794
+ permissions.deny = [...deny, ...patch.deny.filter((rule) => !deny.includes(rule))];
32795
+ settings.permissions = permissions;
32796
+ }
32797
+ if (patch.skillOverrides) {
32798
+ const overrides = { ...settings.skillOverrides };
32799
+ for (const name of patch.skillOverrides)
32800
+ overrides[name] = "off";
32801
+ settings.skillOverrides = overrides;
32802
+ }
32803
+ if (patch.deniedMcpServers) {
32804
+ const denied = settings.deniedMcpServers ?? [];
32805
+ const missing = patch.deniedMcpServers.filter((name) => !denied.some((entry) => entry.serverName === name));
32806
+ settings.deniedMcpServers = [...denied, ...missing.map((serverName) => ({ serverName }))];
32807
+ }
32808
+ }
32809
+ function removeBuiltins(settings, patch) {
32810
+ for (const [key, value] of Object.entries(patch.settings ?? {})) {
32811
+ if (settings[key] === value)
32812
+ delete settings[key];
32813
+ }
32814
+ if (patch.env) {
32815
+ const env = { ...settings.env };
32816
+ for (const [key, value] of Object.entries(patch.env)) {
32817
+ if (env[key] === value)
32818
+ delete env[key];
32819
+ }
32820
+ if (Object.keys(env).length)
32821
+ settings.env = env;
32822
+ else
32823
+ delete settings.env;
32824
+ }
32825
+ if (patch.deny && settings.permissions) {
32826
+ const permissions = { ...settings.permissions };
32827
+ const deny = (permissions.deny ?? []).filter((rule) => !patch.deny.includes(rule));
32828
+ if (deny.length)
32829
+ permissions.deny = deny;
32830
+ else
32831
+ delete permissions.deny;
32832
+ if (Object.keys(permissions).length)
32833
+ settings.permissions = permissions;
32834
+ else
32835
+ delete settings.permissions;
32836
+ }
32837
+ if (patch.skillOverrides && settings.skillOverrides) {
32838
+ const overrides = { ...settings.skillOverrides };
32839
+ for (const name of patch.skillOverrides) {
32840
+ if (overrides[name] === "off")
32841
+ delete overrides[name];
32842
+ }
32843
+ if (Object.keys(overrides).length)
32844
+ settings.skillOverrides = overrides;
32845
+ else
32846
+ delete settings.skillOverrides;
32847
+ }
32848
+ if (patch.deniedMcpServers && settings.deniedMcpServers) {
32849
+ const denied = settings.deniedMcpServers.filter((entry) => !patch.deniedMcpServers.includes(entry.serverName ?? ""));
32850
+ if (denied.length)
32851
+ settings.deniedMcpServers = denied;
32852
+ else
32853
+ delete settings.deniedMcpServers;
32854
+ }
32855
+ }
32756
32856
  function parseSettingsJson(settingsPath) {
32757
32857
  try {
32758
32858
  return JSON.parse(readFileSync4(settingsPath, "utf-8"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@martinffx/atelier",
3
- "version": "3.5.0",
3
+ "version": "3.6.0",
4
4
  "description": "Personal development toolkit - spec-driven development, code quality, deep thinking, and ecosystem patterns",
5
5
  "type": "module",
6
6
  "bin": {