happy-coder 0.9.0-0 → 0.9.0-1

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.cjs CHANGED
@@ -1623,6 +1623,8 @@ class PermissionHandler {
1623
1623
  pendingRequests = /* @__PURE__ */ new Map();
1624
1624
  session;
1625
1625
  allowedTools = /* @__PURE__ */ new Set();
1626
+ allowedBashLiterals = /* @__PURE__ */ new Set();
1627
+ allowedBashPrefixes = /* @__PURE__ */ new Set();
1626
1628
  permissionMode = "default";
1627
1629
  constructor(session) {
1628
1630
  this.session = session;
@@ -1636,7 +1638,13 @@ class PermissionHandler {
1636
1638
  */
1637
1639
  handlePermissionResponse(response, pending) {
1638
1640
  if (response.allowTools && response.allowTools.length > 0) {
1639
- response.allowTools.forEach((tool) => this.allowedTools.add(tool));
1641
+ response.allowTools.forEach((tool) => {
1642
+ if (tool.startsWith("Bash(") || tool === "Bash") {
1643
+ this.parseBashPermission(tool);
1644
+ } else {
1645
+ this.allowedTools.add(tool);
1646
+ }
1647
+ });
1640
1648
  }
1641
1649
  if (response.mode) {
1642
1650
  this.permissionMode = response.mode;
@@ -1663,7 +1671,19 @@ class PermissionHandler {
1663
1671
  * Creates the canCallTool callback for the SDK
1664
1672
  */
1665
1673
  handleToolCall = async (toolName, input, mode, options) => {
1666
- if (this.allowedTools.has(toolName)) {
1674
+ if (toolName === "Bash") {
1675
+ const inputObj = input;
1676
+ if (inputObj?.command) {
1677
+ if (this.allowedBashLiterals.has(inputObj.command)) {
1678
+ return { behavior: "allow", updatedInput: input };
1679
+ }
1680
+ for (const prefix of this.allowedBashPrefixes) {
1681
+ if (inputObj.command.startsWith(prefix)) {
1682
+ return { behavior: "allow", updatedInput: input };
1683
+ }
1684
+ }
1685
+ }
1686
+ } else if (this.allowedTools.has(toolName)) {
1667
1687
  return { behavior: "allow", updatedInput: input };
1668
1688
  }
1669
1689
  const descriptor = getToolDescriptor(toolName);
@@ -1729,6 +1749,26 @@ class PermissionHandler {
1729
1749
  types$1.logger.debug(`Permission request sent for tool call ${id}: ${toolName}`);
1730
1750
  });
1731
1751
  }
1752
+ /**
1753
+ * Parses Bash permission strings into literal and prefix sets
1754
+ */
1755
+ parseBashPermission(permission) {
1756
+ if (permission === "Bash") {
1757
+ return;
1758
+ }
1759
+ const bashPattern = /^Bash\((.+?)\)$/;
1760
+ const match = permission.match(bashPattern);
1761
+ if (!match) {
1762
+ return;
1763
+ }
1764
+ const command = match[1];
1765
+ if (command.endsWith(":*")) {
1766
+ const prefix = command.slice(0, -2);
1767
+ this.allowedBashPrefixes.add(prefix);
1768
+ } else {
1769
+ this.allowedBashLiterals.add(command);
1770
+ }
1771
+ }
1732
1772
  /**
1733
1773
  * Resolves tool call ID based on tool name and input
1734
1774
  */
@@ -1797,6 +1837,9 @@ class PermissionHandler {
1797
1837
  reset() {
1798
1838
  this.toolCalls = [];
1799
1839
  this.responses.clear();
1840
+ this.allowedTools.clear();
1841
+ this.allowedBashLiterals.clear();
1842
+ this.allowedBashPrefixes.clear();
1800
1843
  for (const [, pending] of this.pendingRequests.entries()) {
1801
1844
  pending.reject(new Error("Session reset"));
1802
1845
  }
@@ -2534,7 +2577,7 @@ async function loop(opts) {
2534
2577
  }
2535
2578
 
2536
2579
  var name = "happy-coder";
2537
- var version = "0.9.0-0";
2580
+ var version = "0.9.0-1";
2538
2581
  var description = "Claude Code session sharing CLI";
2539
2582
  var author = "Kirill Dubovitskiy";
2540
2583
  var license = "MIT";
package/dist/index.mjs CHANGED
@@ -1602,6 +1602,8 @@ class PermissionHandler {
1602
1602
  pendingRequests = /* @__PURE__ */ new Map();
1603
1603
  session;
1604
1604
  allowedTools = /* @__PURE__ */ new Set();
1605
+ allowedBashLiterals = /* @__PURE__ */ new Set();
1606
+ allowedBashPrefixes = /* @__PURE__ */ new Set();
1605
1607
  permissionMode = "default";
1606
1608
  constructor(session) {
1607
1609
  this.session = session;
@@ -1615,7 +1617,13 @@ class PermissionHandler {
1615
1617
  */
1616
1618
  handlePermissionResponse(response, pending) {
1617
1619
  if (response.allowTools && response.allowTools.length > 0) {
1618
- response.allowTools.forEach((tool) => this.allowedTools.add(tool));
1620
+ response.allowTools.forEach((tool) => {
1621
+ if (tool.startsWith("Bash(") || tool === "Bash") {
1622
+ this.parseBashPermission(tool);
1623
+ } else {
1624
+ this.allowedTools.add(tool);
1625
+ }
1626
+ });
1619
1627
  }
1620
1628
  if (response.mode) {
1621
1629
  this.permissionMode = response.mode;
@@ -1642,7 +1650,19 @@ class PermissionHandler {
1642
1650
  * Creates the canCallTool callback for the SDK
1643
1651
  */
1644
1652
  handleToolCall = async (toolName, input, mode, options) => {
1645
- if (this.allowedTools.has(toolName)) {
1653
+ if (toolName === "Bash") {
1654
+ const inputObj = input;
1655
+ if (inputObj?.command) {
1656
+ if (this.allowedBashLiterals.has(inputObj.command)) {
1657
+ return { behavior: "allow", updatedInput: input };
1658
+ }
1659
+ for (const prefix of this.allowedBashPrefixes) {
1660
+ if (inputObj.command.startsWith(prefix)) {
1661
+ return { behavior: "allow", updatedInput: input };
1662
+ }
1663
+ }
1664
+ }
1665
+ } else if (this.allowedTools.has(toolName)) {
1646
1666
  return { behavior: "allow", updatedInput: input };
1647
1667
  }
1648
1668
  const descriptor = getToolDescriptor(toolName);
@@ -1708,6 +1728,26 @@ class PermissionHandler {
1708
1728
  logger.debug(`Permission request sent for tool call ${id}: ${toolName}`);
1709
1729
  });
1710
1730
  }
1731
+ /**
1732
+ * Parses Bash permission strings into literal and prefix sets
1733
+ */
1734
+ parseBashPermission(permission) {
1735
+ if (permission === "Bash") {
1736
+ return;
1737
+ }
1738
+ const bashPattern = /^Bash\((.+?)\)$/;
1739
+ const match = permission.match(bashPattern);
1740
+ if (!match) {
1741
+ return;
1742
+ }
1743
+ const command = match[1];
1744
+ if (command.endsWith(":*")) {
1745
+ const prefix = command.slice(0, -2);
1746
+ this.allowedBashPrefixes.add(prefix);
1747
+ } else {
1748
+ this.allowedBashLiterals.add(command);
1749
+ }
1750
+ }
1711
1751
  /**
1712
1752
  * Resolves tool call ID based on tool name and input
1713
1753
  */
@@ -1776,6 +1816,9 @@ class PermissionHandler {
1776
1816
  reset() {
1777
1817
  this.toolCalls = [];
1778
1818
  this.responses.clear();
1819
+ this.allowedTools.clear();
1820
+ this.allowedBashLiterals.clear();
1821
+ this.allowedBashPrefixes.clear();
1779
1822
  for (const [, pending] of this.pendingRequests.entries()) {
1780
1823
  pending.reject(new Error("Session reset"));
1781
1824
  }
@@ -2513,7 +2556,7 @@ async function loop(opts) {
2513
2556
  }
2514
2557
 
2515
2558
  var name = "happy-coder";
2516
- var version = "0.9.0-0";
2559
+ var version = "0.9.0-1";
2517
2560
  var description = "Claude Code session sharing CLI";
2518
2561
  var author = "Kirill Dubovitskiy";
2519
2562
  var license = "MIT";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "happy-coder",
3
- "version": "0.9.0-0",
3
+ "version": "0.9.0-1",
4
4
  "description": "Claude Code session sharing CLI",
5
5
  "author": "Kirill Dubovitskiy",
6
6
  "license": "MIT",