@askexenow/exe-os 0.9.20 → 0.9.21

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/LICENSE CHANGED
@@ -1,21 +1,30 @@
1
- MIT License
1
+ Proprietary License
2
2
 
3
- Copyright (c) 2026 AskExe
3
+ Copyright (c) 2026 Ask Exe Now Pty Ltd. All rights reserved.
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
5
+ This software and associated documentation files (the "Software") are the
6
+ exclusive property of Ask Exe Now Pty Ltd ("AskExe"). The Software is
7
+ licensed, not sold.
11
8
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
9
+ RESTRICTIONS
10
+
11
+ You may not, without the prior written consent of AskExe:
12
+
13
+ 1. Copy, modify, merge, or create derivative works of the Software;
14
+ 2. Distribute, sublicense, sell, lease, or transfer the Software;
15
+ 3. Reverse engineer, decompile, or disassemble the Software;
16
+ 4. Remove or alter any proprietary notices or labels on the Software.
17
+
18
+ PERMITTED USE
19
+
20
+ Use of the Software is permitted only under a valid license agreement
21
+ with AskExe. See https://askexe.com/license for terms.
22
+
23
+ DISCLAIMER
14
24
 
15
25
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
26
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28
+ ASKEXE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/dist/bin/cli.js CHANGED
@@ -917,18 +917,21 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
917
917
  args: [path6.join(packageRoot, "dist", "mcp", "server.js")],
918
918
  env: {}
919
919
  };
920
- const currentMem = claudeJson.mcpServers[MCP_LEGACY_KEY];
921
- const memMatches = currentMem && JSON.stringify(currentMem) === JSON.stringify(newEntry);
922
- if (claudeJson.mcpServers[MCP_PRIMARY_KEY]) {
923
- delete claudeJson.mcpServers[MCP_PRIMARY_KEY];
920
+ if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
921
+ delete claudeJson.mcpServers[MCP_LEGACY_KEY];
922
+ process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
924
923
  }
925
- if (memMatches && !claudeJson.mcpServers[MCP_PRIMARY_KEY]) {
924
+ const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
925
+ const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
926
+ if (osMatches) {
926
927
  await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
928
+ await migratePermissionsToExeOs(path6.join(homeDir, ".claude", "settings.json"));
927
929
  return false;
928
930
  }
929
- claudeJson.mcpServers[MCP_LEGACY_KEY] = newEntry;
931
+ claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
930
932
  await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
931
933
  await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
934
+ await migratePermissionsToExeOs(path6.join(homeDir, ".claude", "settings.json"));
932
935
  return true;
933
936
  }
934
937
  async function cleanSettingsJsonMcp(settingsPath) {
@@ -952,6 +955,35 @@ async function cleanSettingsJsonMcp(settingsPath) {
952
955
  } catch {
953
956
  }
954
957
  }
958
+ async function migratePermissionsToExeOs(settingsPath) {
959
+ if (!existsSync7(settingsPath)) return;
960
+ try {
961
+ const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
962
+ const permissions = settings.permissions;
963
+ if (!permissions || !Array.isArray(permissions.allow)) return;
964
+ const allow = permissions.allow;
965
+ let migrated = 0;
966
+ for (let i = 0; i < allow.length; i++) {
967
+ if (allow[i].startsWith("mcp__exe-mem__")) {
968
+ const newName = allow[i].replace("mcp__exe-mem__", "mcp__exe-os__");
969
+ if (!allow.includes(newName)) {
970
+ allow[i] = newName;
971
+ } else {
972
+ allow[i] = "__REMOVE__";
973
+ }
974
+ migrated++;
975
+ }
976
+ }
977
+ if (migrated > 0) {
978
+ permissions.allow = allow.filter((e) => e !== "__REMOVE__");
979
+ permissions.allow = [...new Set(permissions.allow)];
980
+ await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
981
+ process.stderr.write(`exe-os: migrated ${migrated} permission(s) from exe-mem \u2192 exe-os
982
+ `);
983
+ }
984
+ } catch {
985
+ }
986
+ }
955
987
  async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
956
988
  const settingsPath = path6.join(homeDir, ".claude", "settings.json");
957
989
  const logsDir = path6.join(homeDir, ".exe-os", "logs");
@@ -1212,9 +1244,10 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1212
1244
  "deploy_client"
1213
1245
  ];
1214
1246
  const allowList = permissions.allow;
1215
- for (const tool of expandDualPrefixTools(toolNames)) {
1216
- if (!allowList.includes(tool)) {
1217
- allowList.push(tool);
1247
+ for (const name of toolNames) {
1248
+ const fullName = `mcp__${MCP_PRIMARY_KEY}__${name}`;
1249
+ if (!allowList.includes(fullName)) {
1250
+ allowList.push(fullName);
1218
1251
  }
1219
1252
  }
1220
1253
  await mkdir3(path6.dirname(settingsPath), { recursive: true });
@@ -1217,15 +1217,6 @@ var init_agent_symlinks = __esm({
1217
1217
  });
1218
1218
 
1219
1219
  // src/lib/mcp-prefix.ts
1220
- function expandDualPrefixTools(shortNames) {
1221
- const out = [];
1222
- for (const name of shortNames) {
1223
- for (const prefix of MCP_TOOL_PREFIXES) {
1224
- out.push(prefix + name);
1225
- }
1226
- }
1227
- return out;
1228
- }
1229
1220
  var MCP_PRIMARY_KEY, MCP_LEGACY_KEY, MCP_TOOL_PREFIXES;
1230
1221
  var init_mcp_prefix = __esm({
1231
1222
  "src/lib/mcp-prefix.ts"() {
@@ -1368,18 +1359,21 @@ async function registerMcpServer(packageRoot, homeDir = os7.homedir()) {
1368
1359
  args: [path11.join(packageRoot, "dist", "mcp", "server.js")],
1369
1360
  env: {}
1370
1361
  };
1371
- const currentMem = claudeJson.mcpServers[MCP_LEGACY_KEY];
1372
- const memMatches = currentMem && JSON.stringify(currentMem) === JSON.stringify(newEntry);
1373
- if (claudeJson.mcpServers[MCP_PRIMARY_KEY]) {
1374
- delete claudeJson.mcpServers[MCP_PRIMARY_KEY];
1362
+ if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
1363
+ delete claudeJson.mcpServers[MCP_LEGACY_KEY];
1364
+ process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
1375
1365
  }
1376
- if (memMatches && !claudeJson.mcpServers[MCP_PRIMARY_KEY]) {
1366
+ const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
1367
+ const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
1368
+ if (osMatches) {
1377
1369
  await cleanSettingsJsonMcp(path11.join(homeDir, ".claude", "settings.json"));
1370
+ await migratePermissionsToExeOs(path11.join(homeDir, ".claude", "settings.json"));
1378
1371
  return false;
1379
1372
  }
1380
- claudeJson.mcpServers[MCP_LEGACY_KEY] = newEntry;
1373
+ claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
1381
1374
  await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
1382
1375
  await cleanSettingsJsonMcp(path11.join(homeDir, ".claude", "settings.json"));
1376
+ await migratePermissionsToExeOs(path11.join(homeDir, ".claude", "settings.json"));
1383
1377
  return true;
1384
1378
  }
1385
1379
  async function cleanSettingsJsonMcp(settingsPath) {
@@ -1403,6 +1397,35 @@ async function cleanSettingsJsonMcp(settingsPath) {
1403
1397
  } catch {
1404
1398
  }
1405
1399
  }
1400
+ async function migratePermissionsToExeOs(settingsPath) {
1401
+ if (!existsSync11(settingsPath)) return;
1402
+ try {
1403
+ const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
1404
+ const permissions = settings.permissions;
1405
+ if (!permissions || !Array.isArray(permissions.allow)) return;
1406
+ const allow = permissions.allow;
1407
+ let migrated = 0;
1408
+ for (let i = 0; i < allow.length; i++) {
1409
+ if (allow[i].startsWith("mcp__exe-mem__")) {
1410
+ const newName = allow[i].replace("mcp__exe-mem__", "mcp__exe-os__");
1411
+ if (!allow.includes(newName)) {
1412
+ allow[i] = newName;
1413
+ } else {
1414
+ allow[i] = "__REMOVE__";
1415
+ }
1416
+ migrated++;
1417
+ }
1418
+ }
1419
+ if (migrated > 0) {
1420
+ permissions.allow = allow.filter((e) => e !== "__REMOVE__");
1421
+ permissions.allow = [...new Set(permissions.allow)];
1422
+ await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
1423
+ process.stderr.write(`exe-os: migrated ${migrated} permission(s) from exe-mem \u2192 exe-os
1424
+ `);
1425
+ }
1426
+ } catch {
1427
+ }
1428
+ }
1406
1429
  async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1407
1430
  const settingsPath = path11.join(homeDir, ".claude", "settings.json");
1408
1431
  const logsDir = path11.join(homeDir, ".exe-os", "logs");
@@ -1663,9 +1686,10 @@ async function mergeHooks(packageRoot, homeDir = os7.homedir()) {
1663
1686
  "deploy_client"
1664
1687
  ];
1665
1688
  const allowList = permissions.allow;
1666
- for (const tool of expandDualPrefixTools(toolNames)) {
1667
- if (!allowList.includes(tool)) {
1668
- allowList.push(tool);
1689
+ for (const name of toolNames) {
1690
+ const fullName = `mcp__${MCP_PRIMARY_KEY}__${name}`;
1691
+ if (!allowList.includes(fullName)) {
1692
+ allowList.push(fullName);
1669
1693
  }
1670
1694
  }
1671
1695
  await mkdir3(path11.dirname(settingsPath), { recursive: true });
@@ -573,15 +573,6 @@ var init_agent_symlinks = __esm({
573
573
  });
574
574
 
575
575
  // src/lib/mcp-prefix.ts
576
- function expandDualPrefixTools(shortNames) {
577
- const out = [];
578
- for (const name of shortNames) {
579
- for (const prefix of MCP_TOOL_PREFIXES) {
580
- out.push(prefix + name);
581
- }
582
- }
583
- return out;
584
- }
585
576
  var MCP_PRIMARY_KEY, MCP_LEGACY_KEY, MCP_TOOL_PREFIXES;
586
577
  var init_mcp_prefix = __esm({
587
578
  "src/lib/mcp-prefix.ts"() {
@@ -712,18 +703,21 @@ async function registerMcpServer(packageRoot, homeDir = os5.homedir()) {
712
703
  args: [path6.join(packageRoot, "dist", "mcp", "server.js")],
713
704
  env: {}
714
705
  };
715
- const currentMem = claudeJson.mcpServers[MCP_LEGACY_KEY];
716
- const memMatches = currentMem && JSON.stringify(currentMem) === JSON.stringify(newEntry);
717
- if (claudeJson.mcpServers[MCP_PRIMARY_KEY]) {
718
- delete claudeJson.mcpServers[MCP_PRIMARY_KEY];
706
+ if (claudeJson.mcpServers[MCP_LEGACY_KEY]) {
707
+ delete claudeJson.mcpServers[MCP_LEGACY_KEY];
708
+ process.stderr.write("exe-os: migrated MCP server key exe-mem \u2192 exe-os\n");
719
709
  }
720
- if (memMatches && !claudeJson.mcpServers[MCP_PRIMARY_KEY]) {
710
+ const currentOs = claudeJson.mcpServers[MCP_PRIMARY_KEY];
711
+ const osMatches = currentOs && JSON.stringify(currentOs) === JSON.stringify(newEntry);
712
+ if (osMatches) {
721
713
  await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
714
+ await migratePermissionsToExeOs(path6.join(homeDir, ".claude", "settings.json"));
722
715
  return false;
723
716
  }
724
- claudeJson.mcpServers[MCP_LEGACY_KEY] = newEntry;
717
+ claudeJson.mcpServers[MCP_PRIMARY_KEY] = newEntry;
725
718
  await writeFile3(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
726
719
  await cleanSettingsJsonMcp(path6.join(homeDir, ".claude", "settings.json"));
720
+ await migratePermissionsToExeOs(path6.join(homeDir, ".claude", "settings.json"));
727
721
  return true;
728
722
  }
729
723
  async function cleanSettingsJsonMcp(settingsPath) {
@@ -747,6 +741,35 @@ async function cleanSettingsJsonMcp(settingsPath) {
747
741
  } catch {
748
742
  }
749
743
  }
744
+ async function migratePermissionsToExeOs(settingsPath) {
745
+ if (!existsSync7(settingsPath)) return;
746
+ try {
747
+ const settings = JSON.parse(await readFile3(settingsPath, "utf-8"));
748
+ const permissions = settings.permissions;
749
+ if (!permissions || !Array.isArray(permissions.allow)) return;
750
+ const allow = permissions.allow;
751
+ let migrated = 0;
752
+ for (let i = 0; i < allow.length; i++) {
753
+ if (allow[i].startsWith("mcp__exe-mem__")) {
754
+ const newName = allow[i].replace("mcp__exe-mem__", "mcp__exe-os__");
755
+ if (!allow.includes(newName)) {
756
+ allow[i] = newName;
757
+ } else {
758
+ allow[i] = "__REMOVE__";
759
+ }
760
+ migrated++;
761
+ }
762
+ }
763
+ if (migrated > 0) {
764
+ permissions.allow = allow.filter((e) => e !== "__REMOVE__");
765
+ permissions.allow = [...new Set(permissions.allow)];
766
+ await writeFile3(settingsPath, JSON.stringify(settings, null, 2) + "\n");
767
+ process.stderr.write(`exe-os: migrated ${migrated} permission(s) from exe-mem \u2192 exe-os
768
+ `);
769
+ }
770
+ } catch {
771
+ }
772
+ }
750
773
  async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
751
774
  const settingsPath = path6.join(homeDir, ".claude", "settings.json");
752
775
  const logsDir = path6.join(homeDir, ".exe-os", "logs");
@@ -1007,9 +1030,10 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
1007
1030
  "deploy_client"
1008
1031
  ];
1009
1032
  const allowList = permissions.allow;
1010
- for (const tool of expandDualPrefixTools(toolNames)) {
1011
- if (!allowList.includes(tool)) {
1012
- allowList.push(tool);
1033
+ for (const name of toolNames) {
1034
+ const fullName = `mcp__${MCP_PRIMARY_KEY}__${name}`;
1035
+ if (!allowList.includes(fullName)) {
1036
+ allowList.push(fullName);
1013
1037
  }
1014
1038
  }
1015
1039
  await mkdir3(path6.dirname(settingsPath), { recursive: true });
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.20",
3
+ "version": "0.9.21",
4
4
  "description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
5
- "license": "CC-BY-NC-4.0",
5
+ "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
7
7
  "repository": {
8
8
  "type": "git",