@kodizm/acp 0.6.7 → 0.6.9

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.
Files changed (2) hide show
  1. package/dist/index.js +126 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5706,6 +5706,60 @@ function mapResult(sessionId, message) {
5706
5706
  return events;
5707
5707
  }
5708
5708
 
5709
+ // src/backends/claude/features.ts
5710
+ function translateFeaturesToClaude(features, permissionMode) {
5711
+ const out = { disallowedTools: [], env: {} };
5712
+ if (features === undefined) {
5713
+ return out;
5714
+ }
5715
+ for (const [family, envName] of Object.entries(FAMILY_ENV)) {
5716
+ if (features[family] === false && envName !== undefined) {
5717
+ out.env[envName] = "1";
5718
+ }
5719
+ }
5720
+ if (features.simple === true) {
5721
+ out.tools = [...SIMPLE_MODE_TOOLS];
5722
+ out.settingSources = [];
5723
+ out.strictMcpConfig = true;
5724
+ return out;
5725
+ }
5726
+ if (features.tools !== undefined) {
5727
+ out.tools = [...features.tools];
5728
+ }
5729
+ for (const [family, tools] of Object.entries(FAMILY_TOOLS)) {
5730
+ if (features[family] !== false) {
5731
+ continue;
5732
+ }
5733
+ for (const tool of tools) {
5734
+ if (tool === "ExitPlanMode" && permissionMode === "plan") {
5735
+ continue;
5736
+ }
5737
+ out.disallowedTools.push(tool);
5738
+ }
5739
+ }
5740
+ return out;
5741
+ }
5742
+ var FAMILY_TOOLS, FAMILY_ENV, SIMPLE_MODE_TOOLS;
5743
+ var init_features = __esm(() => {
5744
+ FAMILY_TOOLS = {
5745
+ todos: ["TodoWrite", "TaskCreate", "TaskGet", "TaskUpdate", "TaskList"],
5746
+ subagents: ["Agent", "Task", "SendMessage", "ListAgents"],
5747
+ scheduling: ["Monitor", "CronCreate", "CronDelete", "CronList", "ScheduleWakeup", "RemoteTrigger"],
5748
+ backgroundTasks: ["TaskStop"],
5749
+ planMode: ["EnterPlanMode", "ExitPlanMode"],
5750
+ worktree: ["EnterWorktree", "ExitWorktree"],
5751
+ notebook: ["NotebookEdit"],
5752
+ clientTools: ["DesignSync", "PushNotification", "ShareOnboardingGuide", "ReportFindings"]
5753
+ };
5754
+ FAMILY_ENV = {
5755
+ scheduling: "CLAUDE_CODE_DISABLE_CRON",
5756
+ backgroundTasks: "CLAUDE_CODE_DISABLE_BACKGROUND_TASKS",
5757
+ autoMemory: "CLAUDE_CODE_DISABLE_AUTO_MEMORY",
5758
+ bundledSkills: "CLAUDE_CODE_DISABLE_BUNDLED_SKILLS"
5759
+ };
5760
+ SIMPLE_MODE_TOOLS = ["WebFetch", "WebSearch"];
5761
+ });
5762
+
5709
5763
  // src/backends/claude/mcp-bridge.ts
5710
5764
  function translateMcpServers(servers) {
5711
5765
  const out = {};
@@ -6030,24 +6084,32 @@ class ClaudeDriver {
6030
6084
  this.sessions.set(sessionId, {
6031
6085
  sessionId,
6032
6086
  options,
6087
+ ...this.sessionTimings(params)
6088
+ });
6089
+ return { sessionId };
6090
+ }
6091
+ sessionTimings(params) {
6092
+ return {
6033
6093
  ...params.permissionTimeoutMs === undefined ? {} : { permissionTimeoutMs: params.permissionTimeoutMs },
6034
6094
  ...params.permissionDeferTimeoutMs === undefined ? {} : { permissionDeferTimeoutMs: params.permissionDeferTimeoutMs },
6035
6095
  ...params.heartbeatIntervalMs === undefined ? {} : { heartbeatIntervalMs: params.heartbeatIntervalMs },
6036
6096
  ...params.inactivityThresholdMs === undefined ? {} : { inactivityThresholdMs: params.inactivityThresholdMs }
6037
- });
6038
- return { sessionId };
6097
+ };
6039
6098
  }
6040
6099
  async loadSession(params) {
6041
6100
  const existing = this.sessions.get(params.sessionId);
6042
6101
  const resumeKey = existing?.sdkSessionId ?? params.sessionId;
6043
6102
  const options = {
6044
6103
  ...this.buildBaseSdkOptions(params),
6104
+ ...params.systemPrompt === undefined ? {} : { systemPrompt: this.buildSystemPrompt(params.systemPrompt) },
6105
+ ...params.model === undefined ? {} : { model: params.model },
6045
6106
  resume: resumeKey
6046
6107
  };
6047
6108
  this.sessions.set(params.sessionId, {
6048
6109
  sessionId: params.sessionId,
6049
6110
  options,
6050
- sdkSessionId: existing?.sdkSessionId
6111
+ sdkSessionId: existing?.sdkSessionId,
6112
+ ...this.sessionTimings(params)
6051
6113
  });
6052
6114
  return { sessionId: params.sessionId };
6053
6115
  }
@@ -6369,10 +6431,15 @@ class ClaudeDriver {
6369
6431
  const additional = "additionalDirectories" in params && params.additionalDirectories !== undefined ? { additionalDirectories: [...params.additionalDirectories] } : {};
6370
6432
  const skills = "skills" in params && params.skills !== undefined && params.skills.length > 0 ? { skills: [...params.skills] } : {};
6371
6433
  const policyTranslation = "toolPolicy" in params && params.toolPolicy !== undefined ? translateToolPolicyToClaude(params.toolPolicy) : {};
6434
+ const permissionMode = policyTranslation.permissionMode ?? "bypassPermissions";
6435
+ const featureTranslation = translateFeaturesToClaude("features" in params ? params.features : undefined, permissionMode);
6436
+ const disallowedTools = [
6437
+ ...new Set([...policyTranslation.disallowedTools ?? [], ...featureTranslation.disallowedTools])
6438
+ ];
6372
6439
  const policyOptions = {
6373
6440
  ...policyTranslation.allowedTools !== undefined ? { allowedTools: policyTranslation.allowedTools } : {},
6374
- ...policyTranslation.disallowedTools !== undefined ? { disallowedTools: policyTranslation.disallowedTools } : {},
6375
- permissionMode: policyTranslation.permissionMode ?? "bypassPermissions",
6441
+ ...disallowedTools.length > 0 ? { disallowedTools } : {},
6442
+ permissionMode,
6376
6443
  ...policyTranslation.askRules !== undefined && policyTranslation.askRules.length > 0 ? {
6377
6444
  permissions: {
6378
6445
  rules: [
@@ -6386,21 +6453,22 @@ class ClaudeDriver {
6386
6453
  }
6387
6454
  } : {}
6388
6455
  };
6389
- const compactEnv = "autoCompact" in params && params.autoCompact === false ? {
6390
- env: {
6391
- ...process.env,
6392
- DISABLE_AUTO_COMPACT: "1"
6393
- }
6394
- } : {};
6395
- const settingSourcesOpt = "settingSources" in params && params.settingSources !== undefined ? { settingSources: [...params.settingSources] } : {};
6456
+ const extraEnv = {
6457
+ ...featureTranslation.env,
6458
+ ..."autoCompact" in params && params.autoCompact === false ? { DISABLE_AUTO_COMPACT: "1" } : {}
6459
+ };
6460
+ const envOpt = Object.keys(extraEnv).length > 0 ? { env: { ...process.env, ...extraEnv } } : {};
6461
+ const settingSourcesOpt = "settingSources" in params && params.settingSources !== undefined ? { settingSources: [...params.settingSources] } : featureTranslation.settingSources !== undefined ? { settingSources: featureTranslation.settingSources } : {};
6396
6462
  return {
6397
6463
  cwd: params.cwd,
6398
6464
  mcpServers: translateMcpServers(params.mcpServers),
6399
6465
  ...additional,
6400
6466
  ...skills,
6401
6467
  ...policyOptions,
6402
- ...compactEnv,
6403
- ...settingSourcesOpt
6468
+ ...envOpt,
6469
+ ...settingSourcesOpt,
6470
+ ...featureTranslation.tools !== undefined ? { tools: featureTranslation.tools } : {},
6471
+ ...featureTranslation.strictMcpConfig !== undefined ? { strictMcpConfig: featureTranslation.strictMcpConfig } : {}
6404
6472
  };
6405
6473
  }
6406
6474
  buildSystemPrompt(input) {
@@ -6442,6 +6510,7 @@ var init_driver = __esm(() => {
6442
6510
  init_ask_user_question();
6443
6511
  init_deferred_permission();
6444
6512
  init_error_classifier();
6513
+ init_features();
6445
6514
  init_permission_bridge();
6446
6515
  init_policy2();
6447
6516
  init_prompt_input();
@@ -51651,7 +51720,7 @@ class OpencodeDriver {
51651
51720
  }
51652
51721
  async newSession(params) {
51653
51722
  const sessionId = randomUUID4();
51654
- const env = this.buildAuthEnv(params);
51723
+ const env = this.buildSessionEnv(params);
51655
51724
  const bridge = this.bridgeFactory();
51656
51725
  const handle = await bridge.start({ env });
51657
51726
  const ruleset = buildOpencodeRuleset(params.toolPolicy);
@@ -51900,7 +51969,7 @@ class OpencodeDriver {
51900
51969
  throw new MethodNotSupportedError("session/load", this.supportedMethodNames());
51901
51970
  }
51902
51971
  const bridge = this.bridgeFactory();
51903
- const handle = await bridge.start({});
51972
+ const handle = await bridge.start({ env: this.buildSessionEnv(params) });
51904
51973
  const sessionApi = handle.sdk.session;
51905
51974
  if (typeof sessionApi.get === "function") {
51906
51975
  try {
@@ -51967,6 +52036,14 @@ class OpencodeDriver {
51967
52036
  return;
51968
52037
  })));
51969
52038
  }
52039
+ buildSessionEnv(params) {
52040
+ const sources = params.features?.simple === true ? [] : params.settingSources;
52041
+ const untrusted = sources !== undefined && !sources.includes("project");
52042
+ return {
52043
+ ...this.buildAuthEnv(params),
52044
+ ...untrusted ? { OPENCODE_DISABLE_PROJECT_CONFIG: "1" } : {}
52045
+ };
52046
+ }
51970
52047
  buildAuthEnv(params) {
51971
52048
  const meta = params._meta ?? {};
51972
52049
  if (meta.opencodeAuth === undefined) {
@@ -52057,7 +52134,7 @@ var init_driver2 = __esm(() => {
52057
52134
  // package.json
52058
52135
  var package_default = {
52059
52136
  name: "@kodizm/acp",
52060
- version: "0.6.7",
52137
+ version: "0.6.9",
52061
52138
  description: "Custom ACP server bridging Claude Code, codex, and opencode CLIs through a single Kodizm-flavored protocol surface.",
52062
52139
  type: "module",
52063
52140
  bin: {
@@ -52173,7 +52250,8 @@ var CANONICAL_FIELDS_BANNED_IN_META = [
52173
52250
  "debugCaptureRpc",
52174
52251
  "heartbeatIntervalMs",
52175
52252
  "inactivityThresholdMs",
52176
- "settingSources"
52253
+ "settingSources",
52254
+ "features"
52177
52255
  ];
52178
52256
  var SettingSourcesSchema = array(_enum(["user", "project", "local"]));
52179
52257
  var PermissionModeSchema = _enum(["default", "acceptEdits", "plan", "dontAsk", "bypassPermissions"]);
@@ -52183,6 +52261,20 @@ var ToolPolicySchema = object({
52183
52261
  ask: array(string2()).optional(),
52184
52262
  defaultMode: PermissionModeSchema.optional()
52185
52263
  });
52264
+ var FeaturesSchema = object({
52265
+ todos: boolean2().optional(),
52266
+ subagents: boolean2().optional(),
52267
+ backgroundTasks: boolean2().optional(),
52268
+ scheduling: boolean2().optional(),
52269
+ planMode: boolean2().optional(),
52270
+ worktree: boolean2().optional(),
52271
+ notebook: boolean2().optional(),
52272
+ clientTools: boolean2().optional(),
52273
+ autoMemory: boolean2().optional(),
52274
+ bundledSkills: boolean2().optional(),
52275
+ simple: boolean2().optional(),
52276
+ tools: array(string2().min(1)).optional()
52277
+ });
52186
52278
  function metaCarriesNoCanonicalFields(data) {
52187
52279
  if (data._meta === undefined) {
52188
52280
  return true;
@@ -52200,9 +52292,7 @@ var InitializeRequestSchema = object({
52200
52292
  clientCapabilities: record(string2(), unknown()).optional(),
52201
52293
  _meta: MetaSchema.optional()
52202
52294
  });
52203
- var NewSessionRequestSchema = object({
52204
- cwd: AbsolutePathSchema,
52205
- mcpServers: array(McpServerSchema),
52295
+ var SessionOptionFields = {
52206
52296
  additionalDirectories: array(AbsolutePathSchema).optional(),
52207
52297
  systemPrompt: SystemPromptSchema.optional(),
52208
52298
  model: string2().optional(),
@@ -52217,11 +52307,21 @@ var NewSessionRequestSchema = object({
52217
52307
  heartbeatIntervalMs: number2().int().positive().optional(),
52218
52308
  inactivityThresholdMs: number2().int().positive().optional(),
52219
52309
  settingSources: SettingSourcesSchema.optional(),
52310
+ features: FeaturesSchema.optional(),
52220
52311
  _meta: MetaSchema.optional()
52221
- }).refine(metaCarriesNoCanonicalFields, { message: META_SMUGGLE_MESSAGE, path: ["_meta"] }).refine((data) => !(data.permissionTimeoutMs !== undefined && data.permissionDeferTimeoutMs !== undefined), {
52312
+ };
52313
+ var TIMEOUT_EXCLUSION = {
52222
52314
  message: "permissionTimeoutMs and permissionDeferTimeoutMs are mutually exclusive (pick hard-deny on timeout OR soft-defer on timeout)",
52223
52315
  path: ["permissionDeferTimeoutMs"]
52224
- });
52316
+ };
52317
+ function timeoutsAreExclusive(data) {
52318
+ return !(data.permissionTimeoutMs !== undefined && data.permissionDeferTimeoutMs !== undefined);
52319
+ }
52320
+ var NewSessionRequestSchema = object({
52321
+ cwd: AbsolutePathSchema,
52322
+ mcpServers: array(McpServerSchema),
52323
+ ...SessionOptionFields
52324
+ }).refine(metaCarriesNoCanonicalFields, { message: META_SMUGGLE_MESSAGE, path: ["_meta"] }).refine(timeoutsAreExclusive, TIMEOUT_EXCLUSION);
52225
52325
  var PromptRequestSchema = object({
52226
52326
  sessionId: string2().min(1),
52227
52327
  prompt: array(unknown()),
@@ -52235,9 +52335,8 @@ var LoadSessionRequestSchema = object({
52235
52335
  sessionId: string2().min(1),
52236
52336
  cwd: AbsolutePathSchema,
52237
52337
  mcpServers: array(McpServerSchema),
52238
- settingSources: SettingSourcesSchema.optional(),
52239
- _meta: MetaSchema.optional()
52240
- }).refine(metaCarriesNoCanonicalFields, { message: META_SMUGGLE_MESSAGE, path: ["_meta"] });
52338
+ ...SessionOptionFields
52339
+ }).refine(metaCarriesNoCanonicalFields, { message: META_SMUGGLE_MESSAGE, path: ["_meta"] }).refine(timeoutsAreExclusive, TIMEOUT_EXCLUSION);
52241
52340
  var CompactSessionRequestSchema = object({
52242
52341
  sessionId: string2().min(1)
52243
52342
  });
@@ -52249,6 +52348,7 @@ var ForkSessionRequestSchema = object({
52249
52348
  model: string2().optional(),
52250
52349
  additionalDirectories: array(AbsolutePathSchema).optional(),
52251
52350
  settingSources: SettingSourcesSchema.optional(),
52351
+ features: FeaturesSchema.optional(),
52252
52352
  _meta: MetaSchema.optional()
52253
52353
  }).refine(metaCarriesNoCanonicalFields, { message: META_SMUGGLE_MESSAGE, path: ["_meta"] });
52254
52354
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kodizm/acp",
3
- "version": "0.6.7",
3
+ "version": "0.6.9",
4
4
  "description": "Custom ACP server bridging Claude Code, codex, and opencode CLIs through a single Kodizm-flavored protocol surface.",
5
5
  "type": "module",
6
6
  "bin": {