@pulso/companion 0.3.2 → 0.3.3

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 +191 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2885,6 +2885,184 @@ var reconnectTimer = null;
2885
2885
  var heartbeatTimer = null;
2886
2886
  var HEARTBEAT_INTERVAL = 3e4;
2887
2887
  var reconnectAttempts = 0;
2888
+ var CAPABILITY_PROBES = [
2889
+ {
2890
+ name: "calendar",
2891
+ test: async () => {
2892
+ try {
2893
+ await runAppleScript('tell application "Calendar" to name of calendars');
2894
+ return true;
2895
+ } catch {
2896
+ return false;
2897
+ }
2898
+ },
2899
+ tools: ["sys_calendar_list", "sys_calendar_create"]
2900
+ },
2901
+ {
2902
+ name: "contacts",
2903
+ test: async () => {
2904
+ try {
2905
+ await runAppleScript('tell application "Contacts" to count of people');
2906
+ return true;
2907
+ } catch {
2908
+ return false;
2909
+ }
2910
+ },
2911
+ tools: ["sys_contacts_search"]
2912
+ },
2913
+ {
2914
+ name: "reminders",
2915
+ test: async () => {
2916
+ try {
2917
+ await runAppleScript('tell application "Reminders" to name of lists');
2918
+ return true;
2919
+ } catch {
2920
+ return false;
2921
+ }
2922
+ },
2923
+ tools: ["sys_reminder_create", "sys_reminder_list"]
2924
+ },
2925
+ {
2926
+ name: "screenshot",
2927
+ test: async () => {
2928
+ try {
2929
+ await runShell("screencapture -x -D1 /tmp/pulso-probe-ss.png", 5e3);
2930
+ unlinkSync("/tmp/pulso-probe-ss.png");
2931
+ return true;
2932
+ } catch {
2933
+ return false;
2934
+ }
2935
+ },
2936
+ tools: ["sys_screenshot"]
2937
+ },
2938
+ {
2939
+ name: "chrome_js",
2940
+ test: async () => {
2941
+ try {
2942
+ await runShell("pgrep -x 'Google Chrome' >/dev/null 2>&1");
2943
+ return true;
2944
+ } catch {
2945
+ return false;
2946
+ }
2947
+ },
2948
+ tools: ["sys_browser_execute_js"]
2949
+ },
2950
+ {
2951
+ name: "safari_js",
2952
+ test: async () => {
2953
+ try {
2954
+ await runAppleScript('tell application "Safari" to name of front window');
2955
+ return true;
2956
+ } catch {
2957
+ return false;
2958
+ }
2959
+ },
2960
+ tools: ["sys_browser_execute_js"]
2961
+ },
2962
+ {
2963
+ name: "spotify",
2964
+ test: async () => {
2965
+ try {
2966
+ await runShell("pgrep -x Spotify >/dev/null 2>&1 || ls /Applications/Spotify.app >/dev/null 2>&1");
2967
+ return true;
2968
+ } catch {
2969
+ return false;
2970
+ }
2971
+ },
2972
+ tools: ["sys_spotify_play", "sys_spotify_pause", "sys_spotify_current", "sys_spotify_next", "sys_spotify_previous", "sys_spotify_search"]
2973
+ },
2974
+ {
2975
+ name: "tts",
2976
+ test: async () => {
2977
+ try {
2978
+ await runShell("which say >/dev/null 2>&1");
2979
+ return true;
2980
+ } catch {
2981
+ return false;
2982
+ }
2983
+ },
2984
+ tools: ["sys_tts"]
2985
+ },
2986
+ {
2987
+ name: "shortcuts",
2988
+ test: async () => {
2989
+ try {
2990
+ await runShell("which shortcuts >/dev/null 2>&1");
2991
+ return true;
2992
+ } catch {
2993
+ return false;
2994
+ }
2995
+ },
2996
+ tools: ["sys_shortcuts_run", "sys_shortcuts_list"]
2997
+ }
2998
+ ];
2999
+ var verifiedCapabilities = {
3000
+ available: [],
3001
+ unavailable: [],
3002
+ tools: []
3003
+ };
3004
+ async function probeCapabilities() {
3005
+ console.log("\u{1F50D} Probing system capabilities...");
3006
+ const available = [];
3007
+ const unavailable = [];
3008
+ const tools = /* @__PURE__ */ new Set();
3009
+ const alwaysAvailable = [
3010
+ "sys_open_app",
3011
+ "sys_open_url",
3012
+ "sys_clipboard_read",
3013
+ "sys_clipboard_write",
3014
+ "sys_notification",
3015
+ "sys_shell",
3016
+ "sys_file_read",
3017
+ "sys_file_write",
3018
+ "sys_file_list",
3019
+ "sys_file_search",
3020
+ "sys_volume",
3021
+ "sys_window_list",
3022
+ "sys_window_focus",
3023
+ "sys_system_info",
3024
+ "sys_wifi_info",
3025
+ "sys_disk_info",
3026
+ "sys_process_list",
3027
+ "sys_process_kill",
3028
+ "sys_dark_mode",
3029
+ "sys_spotlight_search",
3030
+ "sys_settings",
3031
+ "sys_screen_lock",
3032
+ "sys_trash",
3033
+ "sys_power",
3034
+ "sys_focus_mode",
3035
+ "sys_audio_devices",
3036
+ "sys_bluetooth",
3037
+ "sys_browser_open_tab",
3038
+ "sys_browser_close_tab",
3039
+ "sys_browser_tabs",
3040
+ "sys_browser_read_page",
3041
+ "sys_browser_navigate"
3042
+ ];
3043
+ for (const t of alwaysAvailable) tools.add(t);
3044
+ const results = await Promise.allSettled(
3045
+ CAPABILITY_PROBES.map(async (probe) => {
3046
+ const ok = await probe.test();
3047
+ return { name: probe.name, ok, tools: probe.tools };
3048
+ })
3049
+ );
3050
+ for (const r of results) {
3051
+ if (r.status === "fulfilled") {
3052
+ if (r.value.ok) {
3053
+ available.push(r.value.name);
3054
+ for (const t of r.value.tools) tools.add(t);
3055
+ } else {
3056
+ unavailable.push(r.value.name);
3057
+ }
3058
+ }
3059
+ }
3060
+ const cap = { available, unavailable, tools: Array.from(tools) };
3061
+ console.log(` \u2705 Available: ${available.join(", ") || "none"}`);
3062
+ if (unavailable.length) console.log(` \u26A0\uFE0F Unavailable: ${unavailable.join(", ")}`);
3063
+ console.log(` \u{1F4E6} ${cap.tools.length} tools verified`);
3064
+ return cap;
3065
+ }
2888
3066
  function connect() {
2889
3067
  console.log("\u{1F50C} Connecting to Pulso...");
2890
3068
  console.log(` ${WS_URL.replace(/token=.*/, "token=***")}`);
@@ -2917,7 +3095,19 @@ function connect() {
2917
3095
  ` Access: ${ACCESS_LEVEL === "full" ? "\u{1F513} Full (unrestricted)" : "\u{1F512} Sandboxed (safe dirs only)"}`
2918
3096
  );
2919
3097
  console.log(" Waiting for commands from Pulso agent...");
2920
- ws.send(JSON.stringify({ type: "extension_ready" }));
3098
+ probeCapabilities().then((cap) => {
3099
+ verifiedCapabilities = cap;
3100
+ ws.send(JSON.stringify({
3101
+ type: "extension_ready",
3102
+ platform: "macos",
3103
+ version: "0.3.2",
3104
+ accessLevel: ACCESS_LEVEL,
3105
+ capabilities: cap.available,
3106
+ unavailable: cap.unavailable,
3107
+ tools: cap.tools,
3108
+ totalTools: cap.tools.length
3109
+ }));
3110
+ });
2921
3111
  if (heartbeatTimer) clearInterval(heartbeatTimer);
2922
3112
  heartbeatTimer = setInterval(() => {
2923
3113
  if (ws && ws.readyState === WebSocket.OPEN) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pulso/companion",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "description": "Pulso Companion — gives your AI agent real control over your computer",
6
6
  "bin": {