@commonlyai/cli 0.1.95 → 0.1.97

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commonlyai/cli",
3
- "version": "0.1.95",
3
+ "version": "0.1.97",
4
4
  "license": "Apache-2.0",
5
5
  "description": "The Commonly CLI — connect agents, manage pods, iterate fast",
6
6
  "type": "module",
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * OpenCode adapter — wraps `opencode run --format json` as a Commonly seat.
3
3
  *
4
- * Smoke-tested version is recorded in TESTED_OPENCODE_VERSION below.
4
+ * Smoke-tested versions are recorded in TESTED_OPENCODE_VERSIONS below.
5
5
  * OpenCode stores sessions under XDG_DATA_HOME. Trusted seats use the
6
6
  * operator's data home directly; public seats get per-identity state without
7
7
  * operator auth.json and a child environment limited to safe launch/locale
@@ -58,7 +58,7 @@ import { resolvePublicSandboxMode } from '../sandbox/mode.js';
58
58
  const DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;
59
59
  const TERMINATION_GRACE_MS = 5000;
60
60
  // Bump only with a passing real sandbox-exec smoke against the new version.
61
- const TESTED_OPENCODE_VERSION = '1.18.35';
61
+ const TESTED_OPENCODE_VERSIONS = Object.freeze(['1.18.35', '1.19.0']);
62
62
  const ALLOW_UNTESTED_OPENCODE_VERSION_ENV = 'COMMONLY_OPENCODE_ALLOW_UNTESTED_VERSION';
63
63
  const VERSION_CHECK_TIMEOUT_MS = 5000;
64
64
  const OPENCODE_CONFIG_GITIGNORE = [
@@ -751,12 +751,17 @@ const compareOpenCodeVersions = (left, right) => {
751
751
  };
752
752
 
753
753
  const describeOpenCodeVersionMismatch = (installedVersion) => {
754
- if (!installedVersion) return 'installed OpenCode version is unknown';
755
- const relation = compareOpenCodeVersions(installedVersion, TESTED_OPENCODE_VERSION);
756
- if (relation === 0) {
757
- return `installed OpenCode ${installedVersion} differs from smoke-tested ${TESTED_OPENCODE_VERSION}`;
754
+ const tested = TESTED_OPENCODE_VERSIONS.join(', ');
755
+ if (!installedVersion) return `installed OpenCode version is unknown; smoke-tested versions: ${tested}`;
756
+ const oldest = TESTED_OPENCODE_VERSIONS[0];
757
+ const newest = TESTED_OPENCODE_VERSIONS[TESTED_OPENCODE_VERSIONS.length - 1];
758
+ if (compareOpenCodeVersions(installedVersion, newest) > 0) {
759
+ return `installed OpenCode ${installedVersion} is newer than smoke-tested versions ${tested}`;
758
760
  }
759
- return `installed OpenCode ${installedVersion} is ${relation > 0 ? 'newer' : 'older'} than smoke-tested ${TESTED_OPENCODE_VERSION}`;
761
+ if (compareOpenCodeVersions(installedVersion, oldest) < 0) {
762
+ return `installed OpenCode ${installedVersion} is older than smoke-tested versions ${tested}`;
763
+ }
764
+ return `installed OpenCode ${installedVersion} differs from smoke-tested versions ${tested}`;
760
765
  };
761
766
 
762
767
  export default {
@@ -814,7 +819,7 @@ export default {
814
819
  : childSourceEnv;
815
820
  const binary = ctx._binaryPath || spawnBinaryPath(runtimeEnv);
816
821
  const installedVersion = readOpenCodeVersion(binary, runtimeEnv);
817
- if (installedVersion !== TESTED_OPENCODE_VERSION) {
822
+ if (!TESTED_OPENCODE_VERSIONS.includes(installedVersion)) {
818
823
  const mismatch = describeOpenCodeVersionMismatch(installedVersion);
819
824
  const allowOverride = process.env[ALLOW_UNTESTED_OPENCODE_VERSION_ENV] === '1';
820
825
  if (isPublic && !allowOverride) {
@@ -993,7 +998,7 @@ export default {
993
998
  export {
994
999
  ALLOW_UNTESTED_OPENCODE_VERSION_ENV,
995
1000
  DISABLED_ENV,
996
- TESTED_OPENCODE_VERSION,
1001
+ TESTED_OPENCODE_VERSIONS,
997
1002
  buildArgs,
998
1003
  buildMcpConfig,
999
1004
  buildProviderConfig,
@@ -215,7 +215,16 @@ export const forwardHookEvent = async ({
215
215
  const body = await response.json().catch(() => ({}));
216
216
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
217
217
  if (preTool && body.permissionDecision === 'deny') {
218
- stdout(JSON.stringify({ permissionDecision: 'deny', ...(body.reason ? { reason: body.reason } : {}) }));
218
+ // Claude Code reads a PreToolUse decision only from `hookSpecificOutput`. The top-level
219
+ // `{permissionDecision}` this printed before was ignored and the tool ran (measured on
220
+ // Claude Code 2.1.296, 2026-10-14, issue #2145).
221
+ stdout(JSON.stringify({
222
+ hookSpecificOutput: {
223
+ hookEventName: 'PreToolUse',
224
+ permissionDecision: 'deny',
225
+ ...(body.reason ? { permissionDecisionReason: body.reason } : {}),
226
+ },
227
+ }));
219
228
  }
220
229
  return body;
221
230
  } catch (error) {