@devness/useai-cli 0.5.43 → 0.5.45

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 +453 -148
  2. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -30,15 +30,116 @@ var SYSTEMD_SERVICE_PATH = join(homedir(), ".config", "systemd", "user", "useai-
30
30
  var WINDOWS_STARTUP_SCRIPT_PATH = join(process.env["APPDATA"] ?? join(homedir(), "AppData", "Roaming"), "Microsoft", "Windows", "Start Menu", "Programs", "Startup", "useai-daemon.vbs");
31
31
 
32
32
  // ../shared/dist/constants/version.js
33
- var VERSION = "0.5.43";
33
+ var VERSION = "0.5.45";
34
34
 
35
35
  // ../shared/dist/constants/defaults.js
36
36
  var DEFAULT_CONFIG = {
37
37
  milestone_tracking: true,
38
- auto_sync: true
38
+ auto_sync: true,
39
+ evaluation_framework: "raw"
39
40
  };
40
41
  var DEFAULT_SYNC_INTERVAL_HOURS = 24;
41
42
 
43
+ // ../shared/dist/constants/tools.js
44
+ var TOOL_COLORS = {
45
+ "claude-code": "#d4a04a",
46
+ "claude-desktop": "#d4a04a",
47
+ codex: "#10a37f",
48
+ openai: "#10a37f",
49
+ cursor: "#00b4d8",
50
+ copilot: "#6e40c9",
51
+ "github-copilot": "#6e40c9",
52
+ "copilot-cli": "#6e40c9",
53
+ windsurf: "#38bdf8",
54
+ trae: "#06b6d4",
55
+ vscode: "#007ACC",
56
+ "vscode-insiders": "#24bfa5",
57
+ aider: "#4ade80",
58
+ "kilo-code": "#14b8a6",
59
+ crush: "#ef4444",
60
+ continue: "#f97316",
61
+ cody: "#ff6b6b",
62
+ tabby: "#a78bfa",
63
+ roo: "#f472b6",
64
+ "roo-code": "#f472b6",
65
+ gemini: "#4285f4",
66
+ "gemini-cli": "#4285f4",
67
+ zed: "#084CCF",
68
+ cline: "#EAB308",
69
+ "amazon-q": "#01A88D",
70
+ "amazon-q-cli": "#01A88D",
71
+ "amazon-q-ide": "#01A88D",
72
+ goose: "#FF6F00",
73
+ jetbrains: "#6B57D2",
74
+ junie: "#7B68EE",
75
+ opencode: "#71717A",
76
+ antigravity: "#E91E63",
77
+ augment: "#e879f9",
78
+ amp: "#f87171",
79
+ mcp: "#91919a"
80
+ };
81
+ var svg = (body) => `data:image/svg+xml,${encodeURIComponent(`<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">${body}</svg>`)}`;
82
+ var TOOL_ICONS = {
83
+ /* ---- Anthropic ---- */
84
+ "claude-code": `data:image/svg+xml,${encodeURIComponent('<svg fill="currentColor" fill-rule="evenodd" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"></path></svg>')}`,
85
+ "claude-desktop": `data:image/svg+xml,${encodeURIComponent('<svg fill="currentColor" fill-rule="evenodd" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"></path></svg>')}`,
86
+ /* ---- OpenAI ---- */
87
+ codex: `data:image/svg+xml,${encodeURIComponent('<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855l-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023l-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135l-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08L8.704 5.46a.795.795 0 0 0-.393.681zm1.097-2.365l2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5z"/></svg>')}`,
88
+ openai: `data:image/svg+xml,${encodeURIComponent('<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073z"/></svg>')}`,
89
+ /* ---- Cursor (simple-icons) ---- */
90
+ cursor: svg('<path fill="currentColor" d="M11.503.131 1.891 5.678a.84.84 0 0 0-.42.726v11.188c0 .3.162.575.42.724l9.609 5.55a1 1 0 0 0 .998 0l9.61-5.55a.84.84 0 0 0 .42-.724V6.404a.84.84 0 0 0-.42-.726L12.497.131a1.01 1.01 0 0 0-.996 0M2.657 6.338h18.55c.263 0 .43.287.297.515L12.23 22.918c-.062.107-.229.064-.229-.06V12.335a.59.59 0 0 0-.295-.51l-9.11-5.257c-.109-.063-.064-.23.061-.23"/>'),
91
+ /* ---- GitHub Copilot (lobehub) ---- */
92
+ copilot: svg('<path fill="currentColor" d="M9 23l.073-.001a2.53 2.53 0 01-2.347-1.838l-.697-2.433a2.529 2.529 0 00-2.426-1.839h-.497l-.104-.002c-4.485 0-2.935-5.278-1.75-9.225l.162-.525C2.412 3.99 3.883 1 6.25 1h8.86c1.12 0 2.106.745 2.422 1.829l.715 2.453a2.53 2.53 0 002.247 1.823l.147.005.534.001c3.557.115 3.088 3.745 2.156 7.206l-.113.413c-.154.548-.315 1.089-.47 1.607l-.163.525C21.588 20.01 20.116 23 17.75 23h-8.75zm8.22-15.89l-3.856.001a2.526 2.526 0 00-2.35 1.615L9.21 15.04a2.529 2.529 0 01-2.43 1.847l3.853.002c1.056 0 1.992-.661 2.361-1.644l1.796-6.287a2.529 2.529 0 012.43-1.848z"/>'),
93
+ "github-copilot": svg('<path fill="currentColor" d="M23.922 16.997C23.061 18.492 18.063 22.02 12 22.02 5.937 22.02.939 18.492.078 16.997A.641.641 0 0 1 0 16.741v-2.869a.883.883 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.098 10.098 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952C7.255 2.937 9.248 1.98 11.978 1.98c2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.841.841 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256Zm-11.75-5.992h-.344a4.359 4.359 0 0 1-.355.508c-.77.947-1.918 1.492-3.508 1.492-1.725 0-2.989-.359-3.782-1.259a2.137 2.137 0 0 1-.085-.104L4 11.746v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.359 4.359 0 0 1-.355-.508Zm2.328 3.25c.549 0 1 .451 1 1v2c0 .549-.451 1-1 1-.549 0-1-.451-1-1v-2c0-.549.451-1 1-1Zm-5 0c.549 0 1 .451 1 1v2c0 .549-.451 1-1 1-.549 0-1-.451-1-1v-2c0-.549.451-1 1-1Zm3.313-6.185c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"/>'),
94
+ "copilot-cli": svg('<path fill="currentColor" d="M9 23l.073-.001a2.53 2.53 0 01-2.347-1.838l-.697-2.433a2.529 2.529 0 00-2.426-1.839h-.497l-.104-.002c-4.485 0-2.935-5.278-1.75-9.225l.162-.525C2.412 3.99 3.883 1 6.25 1h8.86c1.12 0 2.106.745 2.422 1.829l.715 2.453a2.53 2.53 0 002.247 1.823l.147.005.534.001c3.557.115 3.088 3.745 2.156 7.206l-.113.413c-.154.548-.315 1.089-.47 1.607l-.163.525C21.588 20.01 20.116 23 17.75 23h-8.75zm8.22-15.89l-3.856.001a2.526 2.526 0 00-2.35 1.615L9.21 15.04a2.529 2.529 0 01-2.43 1.847l3.853.002c1.056 0 1.992-.661 2.361-1.644l1.796-6.287a2.529 2.529 0 012.43-1.848z"/>'),
95
+ /* ---- Windsurf (lobehub) ---- */
96
+ windsurf: svg('<path fill="currentColor" d="M23.78 5.004h-.228a2.187 2.187 0 00-2.18 2.196v4.912c0 .98-.804 1.775-1.76 1.775a1.818 1.818 0 01-1.472-.773L13.168 5.95a2.197 2.197 0 00-1.81-.95c-1.134 0-2.154.972-2.154 2.173v4.94c0 .98-.797 1.775-1.76 1.775-.57 0-1.136-.289-1.472-.773L.408 5.098C.282 4.918 0 5.007 0 5.228v4.284c0 .216.066.426.188.604l5.475 7.889c.324.466.8.812 1.351.938 1.377.316 2.645-.754 2.645-2.117V11.89c0-.98.787-1.775 1.76-1.775h.002c.586 0 1.135.288 1.472.773l4.972 7.163a2.15 2.15 0 001.81.95c1.158 0 2.151-.973 2.151-2.173v-4.939c0-.98.787-1.775 1.76-1.775h.194c.122 0 .22-.1.22-.222V5.225a.221.221 0 00-.22-.222z"/>'),
97
+ trae: `data:image/svg+xml,${encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="28" height="21" fill="none" viewBox="0 0 28 21"><g clip-path="url(#logo_svg__a)"><path fill="#fff" d="M28.002 20.846H4v-3.998H0V.846h28.002zM4 16.848h20.002V4.845H4zm10.002-6.062-2.829 2.828-2.828-2.828 2.828-2.829zm8-.002-2.828 2.828-2.829-2.828 2.829-2.829z"></path></g><defs><clipPath id="logo_svg__a"><path fill="#fff" d="M0 .846h28.002v20H0z"></path></clipPath></defs></svg>')}`,
98
+ /* ---- Google Gemini ---- */
99
+ gemini: svg('<path fill="currentColor" d="M12 0C12 6.627 6.627 12 0 12c6.627 0 12 5.373 12 12 0-6.627 5.373-12 12-12-6.627 0-12-5.373-12-12Z"/>'),
100
+ "gemini-cli": svg('<path fill="currentColor" d="M12 0C12 6.627 6.627 12 0 12c6.627 0 12 5.373 12 12 0-6.627 5.373-12 12-12-6.627 0-12-5.373-12-12Z"/>'),
101
+ /* ---- VS Code (simple-icons) ---- */
102
+ vscode: svg('<path fill="currentColor" d="M23.15 2.587L18.21.21a1.49 1.49 0 0 0-1.705.29l-9.46 8.63-4.12-3.128a1 1 0 0 0-1.276.057L.327 7.261A1 1 0 0 0 .326 8.74L3.899 12 .326 15.26a1 1 0 0 0 .001 1.479L1.65 17.94a1 1 0 0 0 1.276.057l4.12-3.128 9.46 8.63a1.49 1.49 0 0 0 1.704.29l4.942-2.377A1.5 1.5 0 0 0 24 20.06V3.939a1.5 1.5 0 0 0-.85-1.352m-5.146 14.861L10.826 12l7.178-5.448z"/>'),
103
+ "vscode-insiders": svg('<path fill="currentColor" d="M23.15 2.587L18.21.21a1.49 1.49 0 0 0-1.705.29l-9.46 8.63-4.12-3.128a1 1 0 0 0-1.276.057L.327 7.261A1 1 0 0 0 .326 8.74L3.899 12 .326 15.26a1 1 0 0 0 .001 1.479L1.65 17.94a1 1 0 0 0 1.276.057l4.12-3.128 9.46 8.63a1.49 1.49 0 0 0 1.704.29l4.942-2.377A1.5 1.5 0 0 0 24 20.06V3.939a1.5 1.5 0 0 0-.85-1.352m-5.146 14.861L10.826 12l7.178-5.448z"/>'),
104
+ /* ---- Zed (simple-icons) ---- */
105
+ zed: svg('<path fill="currentColor" d="M2.25 1.5a.75.75 0 0 0-.75.75v16.5H0V2.25A2.25 2.25 0 0 1 2.25 0h20.095c1.002 0 1.504 1.212.795 1.92L10.764 14.298h3.486V12.75h1.5v1.922a1.125 1.125 0 0 1-1.125 1.125H9.264l-2.578 2.578h11.689V9h1.5v9.375a1.5 1.5 0 0 1-1.5 1.5H5.185L2.562 22.5H21.75a.75.75 0 0 0 .75-.75V5.25H24v16.5A2.25 2.25 0 0 1 21.75 24H1.655C.653 24 .151 22.788.86 22.08L13.19 9.75H9.75v1.5h-1.5V9.375A1.125 1.125 0 0 1 9.375 8.25h5.314l2.625-2.625H5.625V15h-1.5V5.625a1.5 1.5 0 0 1 1.5-1.5h13.19L21.438 1.5z"/>'),
106
+ /* ---- Cline (lobehub) ---- */
107
+ cline: svg('<path fill="currentColor" d="M17.035 3.991c2.75 0 4.98 2.24 4.98 5.003v1.667l1.45 2.896a1.01 1.01 0 01-.002.909l-1.448 2.864v1.668c0 2.762-2.23 5.002-4.98 5.002H7.074c-2.751 0-4.98-2.24-4.98-5.002V17.33l-1.48-2.855a1.01 1.01 0 01-.003-.927l1.482-2.887V8.994c0-2.763 2.23-5.003 4.98-5.003h9.962zM8.265 9.6a2.274 2.274 0 00-2.274 2.274v4.042a2.274 2.274 0 004.547 0v-4.042A2.274 2.274 0 008.265 9.6zm7.326 0a2.274 2.274 0 00-2.274 2.274v4.042a2.274 2.274 0 104.548 0v-4.042A2.274 2.274 0 0015.59 9.6z"/><path fill="currentColor" d="M12.054 5.558a2.779 2.779 0 100-5.558 2.779 2.779 0 000 5.558z"/>'),
108
+ /* ---- JetBrains (simple-icons) ---- */
109
+ jetbrains: svg('<path fill="currentColor" d="M2.345 23.997A2.347 2.347 0 0 1 0 21.652V10.988C0 9.665.535 8.37 1.473 7.433l5.965-5.961A5.01 5.01 0 0 1 10.989 0h10.666A2.347 2.347 0 0 1 24 2.345v10.664a5.056 5.056 0 0 1-1.473 3.554l-5.965 5.965A5.017 5.017 0 0 1 13.007 24v-.003H2.345Zm8.969-6.854H5.486v1.371h5.828v-1.371ZM3.963 6.514h13.523v13.519l4.257-4.257a3.936 3.936 0 0 0 1.146-2.767V2.345c0-.678-.552-1.234-1.234-1.234H10.989a3.897 3.897 0 0 0-2.767 1.145L3.963 6.514Zm-.192.192L2.256 8.22a3.944 3.944 0 0 0-1.145 2.768v10.664c0 .678.552 1.234 1.234 1.234h10.666a3.9 3.9 0 0 0 2.767-1.146l1.512-1.511H3.771V6.706Z"/>'),
110
+ junie: svg('<path fill="currentColor" d="M2.345 23.997A2.347 2.347 0 0 1 0 21.652V10.988C0 9.665.535 8.37 1.473 7.433l5.965-5.961A5.01 5.01 0 0 1 10.989 0h10.666A2.347 2.347 0 0 1 24 2.345v10.664a5.056 5.056 0 0 1-1.473 3.554l-5.965 5.965A5.017 5.017 0 0 1 13.007 24v-.003H2.345Zm8.969-6.854H5.486v1.371h5.828v-1.371ZM3.963 6.514h13.523v13.519l4.257-4.257a3.936 3.936 0 0 0 1.146-2.767V2.345c0-.678-.552-1.234-1.234-1.234H10.989a3.897 3.897 0 0 0-2.767 1.145L3.963 6.514Zm-.192.192L2.256 8.22a3.944 3.944 0 0 0-1.145 2.768v10.664c0 .678.552 1.234 1.234 1.234h10.666a3.9 3.9 0 0 0 2.767-1.146l1.512-1.511H3.771V6.706Z"/>'),
111
+ /* ---- Sourcegraph Cody (iconify) ---- */
112
+ cody: svg('<path fill="currentColor" d="M17.897 3.84a2.38 2.38 0 1 1 3.09 3.623l-3.525 3.006-2.59-.919-.967-.342-1.625-.576 1.312-1.12.78-.665 3.525-3.007zm-8.27 13.313l.78-.665 1.312-1.12-1.624-.575-.967-.344-2.59-.918-3.525 3.007a2.38 2.38 0 1 0 3.09 3.622l3.525-3.007zM8.724 7.37l2.592.92 2.09-1.784-.84-4.556a2.38 2.38 0 1 0-4.683.865l.841 4.555zm6.554 9.262l-2.592-.92-2.091 1.784.842 4.557a2.38 2.38 0 0 0 4.682-.866l-.841-4.555zm8.186-.564a2.38 2.38 0 0 0-1.449-3.04l-4.365-1.55-.967-.342-1.625-.576-.966-.343-2.59-.92-.967-.342-1.624-.576-.967-.343-4.366-1.55a2.38 2.38 0 1 0-1.591 4.488l4.366 1.55.966.342 1.625.576.965.343 2.591.92.967.342 1.624.577.966.342 4.367 1.55a2.38 2.38 0 0 0 3.04-1.447"/>'),
113
+ /* ---- Goose (lobehub) ---- */
114
+ goose: svg('<path fill="currentColor" d="M21.595 23.61c1.167-.254 2.405-.944 2.405-.944l-2.167-1.784a12.124 12.124 0 01-2.695-3.131 12.127 12.127 0 00-3.97-4.049l-.794-.462a1.115 1.115 0 01-.488-.815.844.844 0 01.154-.575c.413-.582 2.548-3.115 2.94-3.44.503-.416 1.065-.762 1.586-1.159.074-.056.148-.112.221-.17.003-.002.007-.004.009-.007.167-.131.325-.272.45-.438.453-.524.563-.988.59-1.193-.061-.197-.244-.639-.753-1.148.319.02.705.272 1.056.569.235-.376.481-.773.727-1.171.165-.266-.08-.465-.086-.471h-.001V3.22c-.007-.007-.206-.25-.471-.086-.567.35-1.134.702-1.639 1.021 0 0-.597-.012-1.305.599a2.464 2.464 0 00-.438.45l-.007.009c-.058.072-.114.147-.17.221-.397.521-.743 1.083-1.16 1.587-.323.391-2.857 2.526-3.44 2.94a.842.842 0 01-.574.153 1.115 1.115 0 01-.815-.488l-.462-.794a12.123 12.123 0 00-4.049-3.97 12.133 12.133 0 01-3.13-2.695L1.332 0S.643 1.238.39 2.405c.352.428 1.27 1.49 2.34 2.302C1.58 4.167.73 3.75.06 3.4c-.103.765-.063 1.92.043 2.816.726.317 1.961.806 3.219 1.066-1.006.236-2.11.278-2.961.262.15.554.358 1.119.64 1.688.119.263.25.52.39.77.452.125 2.222.383 3.164.171l-2.51.897a27.776 27.776 0 002.544 2.726c2.031-1.092 2.494-1.241 4.018-2.238-2.467 2.008-3.108 2.828-3.8 3.67l-.483.678c-.25.351-.469.725-.65 1.117-.61 1.31-1.47 4.1-1.47 4.1-.154.486.202.842.674.674 0 0 2.79-.861 4.1-1.47.392-.182.766-.4 1.118-.65l.677-.483c.227-.187.453-.37.701-.586 0 0 1.705 2.02 3.458 3.349l.896-2.511c-.211.942.046 2.712.17 3.163.252.142.509.272.772.392.569.28 1.134.49 1.688.64-.016-.853.026-1.956.261-2.962.26 1.258.75 2.493 1.067 3.219.895.106 2.051.146 2.816.043a73.87 73.87 0 01-1.308-2.67c.811 1.07 1.874 1.988 2.302 2.34h-.001z"/>'),
115
+ /* ---- Amazon Q ---- */
116
+ "amazon-q": svg('<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10c1.82 0 3.53-.48 5.01-1.32L19.59 23 21 21.59l-2.32-2.42A9.94 9.94 0 0022 12c0-5.52-4.48-10-10-10zm0 3c3.87 0 7 3.13 7 7s-3.13 7-7 7-7-3.13-7-7 3.13-7 7-7z"/>'),
117
+ "amazon-q-cli": svg('<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10c1.82 0 3.53-.48 5.01-1.32L19.59 23 21 21.59l-2.32-2.42A9.94 9.94 0 0022 12c0-5.52-4.48-10-10-10zm0 3c3.87 0 7 3.13 7 7s-3.13 7-7 7-7-3.13-7-7 3.13-7 7-7z"/>'),
118
+ "amazon-q-ide": svg('<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10c1.82 0 3.53-.48 5.01-1.32L19.59 23 21 21.59l-2.32-2.42A9.94 9.94 0 0022 12c0-5.52-4.48-10-10-10zm0 3c3.87 0 7 3.13 7 7s-3.13 7-7 7-7-3.13-7-7 3.13-7 7-7z"/>'),
119
+ /* ---- Aider (terminal prompt) ---- */
120
+ aider: svg('<path fill="currentColor" d="M2 4a2 2 0 012-2h16a2 2 0 012 2v16a2 2 0 01-2 2H4a2 2 0 01-2-2V4zm5.3 4.3a1 1 0 011.4 0l3 3a1 1 0 010 1.4l-3 3a1 1 0 01-1.4-1.4L9.6 12 7.3 9.7a1 1 0 010-1.4zM13 15a1 1 0 100 2h4a1 1 0 100-2h-4z"/>'),
121
+ /* ---- Continue (fast-forward) ---- */
122
+ continue: svg('<path fill="currentColor" d="M3 4l9 8-9 8V4zm10 0l9 8-9 8V4z"/>'),
123
+ /* ---- TabbyML (cat silhouette) ---- */
124
+ tabby: svg('<path fill="currentColor" d="M4 8l4-6h2L7 8h10l-3-6h2l4 6v10a4 4 0 01-4 4H8a4 4 0 01-4-4V8zm4 4a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm8 0a1.5 1.5 0 100 3 1.5 1.5 0 000-3z"/>'),
125
+ /* ---- Roo Code (rocket) ---- */
126
+ roo: svg('<path fill="currentColor" d="M12 2C8.13 2 5 5.13 5 9c0 2.38 1.19 4.47 3 5.74V17h2v5h4v-5h2v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.87-3.13-7-7-7zm-2 7.5a1 1 0 11-2 0 1 1 0 012 0zm6 0a1 1 0 11-2 0 1 1 0 012 0z"/>'),
127
+ "roo-code": svg('<path fill="currentColor" d="M12 2C8.13 2 5 5.13 5 9c0 2.38 1.19 4.47 3 5.74V17h2v5h4v-5h2v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.87-3.13-7-7-7zm-2 7.5a1 1 0 11-2 0 1 1 0 012 0zm6 0a1 1 0 11-2 0 1 1 0 012 0z"/>'),
128
+ /* ---- OpenCode ---- */
129
+ opencode: `data:image/svg+xml,${encodeURIComponent("<svg width='240' height='300' viewBox='0 0 240 300' fill='none' xmlns='http://www.w3.org/2000/svg'><g clip-path='url(#clip0_1401_86274)'><mask id='mask0_1401_86274' style='mask-type:luminance' maskUnits='userSpaceOnUse' x='0' y='0' width='240' height='300'><path d='M240 0H0V300H240V0Z' fill='white'/></mask><g mask='url(#mask0_1401_86274)'><path d='M180 240H60V120H180V240Z' fill='#CFCECD'/><path d='M180 60H60V240H180V60ZM240 300H0V0H240V300Z' fill='#211E1E'/></g></g><defs><clipPath id='clip0_1401_86274'><rect width='240' height='300' fill='white'/></clipPath></defs></svg>")}`,
130
+ "kilo-code": `data:image/svg+xml,${encodeURIComponent('<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M0,0v100h100V0H0ZM92.5925926,92.5925926H7.4074074V7.4074074h85.1851852v85.1851852ZM61.1111044,71.9096084h9.2592593v7.4074074h-11.6402116l-5.026455-5.026455v-11.6402116h7.4074074v9.2592593ZM77.7777711,71.9096084h-7.4074074v-9.2592593h-9.2592593v-7.4074074h11.6402116l5.026455,5.026455v11.6402116ZM46.2962963,61.1114207h-7.4074074v-7.4074074h7.4074074v7.4074074ZM22.2222222,53.7040133h7.4074074v16.6666667h16.6666667v7.4074074h-19.047619l-5.026455-5.026455v-19.047619ZM77.7777711,38.8888889v7.4074074h-24.0740741v-7.4074074h8.2781918v-9.2592593h-8.2781918v-7.4074074h10.6591442l5.026455,5.026455v11.6402116h8.3884749ZM29.6296296,30.5555556h9.2592593l7.4074074,7.4074074v8.3333333h-7.4074074v-8.3333333h-9.2592593v8.3333333h-7.4074074v-24.0740741h7.4074074v8.3333333ZM46.2962963,30.5555556h-7.4074074v-8.3333333h7.4074074v8.3333333Z"/></svg>')}`,
131
+ crush: svg('<path fill="currentColor" d="M12 1.6l8.1 4.7v9.4L12 20.4 3.9 15.7V6.3L12 1.6zm0 3.1l-5.4 3.1v6.3l5.4 3.1 5.4-3.1V7.8L12 4.7zm-2.1 4.1h4.2v6.4H9.9V8.8z"/>'),
132
+ /* ---- Antigravity ---- */
133
+ antigravity: svg('<path fill="currentColor" d="m19.94,20.59c1.09.82,2.73.27,1.23-1.23-4.5-4.36-3.55-16.36-9.14-16.36S7.39,15,2.89,19.36c-1.64,1.64.14,2.05,1.23,1.23,4.23-2.86,3.95-7.91,7.91-7.91s3.68,5.05,7.91,7.91Z"/>'),
134
+ /* ---- Augment (sparkle) ---- */
135
+ augment: svg('<path fill="currentColor" d="M12 0l2.5 9.5L24 12l-9.5 2.5L12 24l-2.5-9.5L0 12l9.5-2.5z"/>'),
136
+ /* ---- Amp (lightning bolt) ---- */
137
+ amp: svg('<path fill="currentColor" d="M13 2L4 14h7l-2 8 9-12h-7l2-8z"/>'),
138
+ /* ---- MCP Client (plug) ---- */
139
+ mcp: svg('<path fill="currentColor" d="M14 2a2 2 0 012 2v2h2a2 2 0 012 2v2h-4V8h-4v2H8v4h2v4H8v-2H6a2 2 0 01-2-2v-2H0v-2h4V8a2 2 0 012-2h2V4a2 2 0 012-2h4z"/>')
140
+ };
141
+ var KNOWN_CLIENTS = Object.keys(TOOL_COLORS);
142
+
42
143
  // src/commands/stats.ts
43
144
  import { Command } from "commander";
44
145
  import chalk2 from "chalk";
@@ -324,91 +425,6 @@ var milestonesCommand = new Command3("milestones").description("List local miles
324
425
  // src/commands/config.ts
325
426
  import { Command as Command4 } from "commander";
326
427
  import chalk5 from "chalk";
327
- var configCommand = new Command4("config").description("View or update settings").option("--sync", "Enable auto-sync").option("--no-sync", "Disable auto-sync").option("--milestones", "Enable milestone tracking").option("--no-milestones", "Disable milestone tracking").action(() => {
328
- let changed = false;
329
- if (process.argv.includes("--no-sync")) {
330
- updateConfig({ auto_sync: false });
331
- console.log(success("Auto-sync disabled."));
332
- changed = true;
333
- } else if (process.argv.includes("--sync")) {
334
- updateConfig({ auto_sync: true });
335
- console.log(success("Auto-sync enabled."));
336
- changed = true;
337
- }
338
- if (process.argv.includes("--no-milestones")) {
339
- updateConfig({ milestone_tracking: false });
340
- console.log(success("Milestone tracking disabled."));
341
- changed = true;
342
- } else if (process.argv.includes("--milestones")) {
343
- updateConfig({ milestone_tracking: true });
344
- console.log(success("Milestone tracking enabled."));
345
- changed = true;
346
- }
347
- const config = getConfig();
348
- if (!changed) {
349
- console.log(header("Current Settings"));
350
- console.log(
351
- table([
352
- ["Milestone tracking", config.milestone_tracking ? chalk5.green("on") : chalk5.red("off")],
353
- ["Auto sync", config.auto_sync ? chalk5.green("on") : chalk5.red("off")],
354
- ["Sync interval", `${config.sync_interval_hours}h`],
355
- ["Last sync", config.last_sync_at ?? chalk5.dim("never")],
356
- ["Logged in", config.auth ? chalk5.green(config.auth.user.email) : chalk5.dim("no")]
357
- ])
358
- );
359
- console.log("");
360
- }
361
- });
362
-
363
- // src/commands/export.ts
364
- import { Command as Command5 } from "commander";
365
- var exportCommand = new Command5("export").description("Export all local data as JSON to stdout").action(() => {
366
- const config = getConfig();
367
- const sessions = readJson(SESSIONS_FILE, []);
368
- const milestones = readJson(MILESTONES_FILE, []);
369
- const data = {
370
- exported_at: (/* @__PURE__ */ new Date()).toISOString(),
371
- config,
372
- sessions,
373
- milestones
374
- };
375
- process.stdout.write(JSON.stringify(data, null, 2) + "\n");
376
- });
377
-
378
- // src/commands/purge.ts
379
- import { Command as Command6 } from "commander";
380
- import { existsSync as existsSync3, rmSync } from "fs";
381
- import { createInterface } from "readline";
382
- function confirm(question) {
383
- const rl = createInterface({ input: process.stdin, output: process.stderr });
384
- return new Promise((resolve) => {
385
- rl.question(question, (answer) => {
386
- rl.close();
387
- resolve(answer.trim().toLowerCase() === "yes");
388
- });
389
- });
390
- }
391
- var purgeCommand = new Command6("purge").description("Delete ALL local useai data").option("-y, --yes", "Skip confirmation").action(async (opts) => {
392
- if (!existsSync3(USEAI_DIR)) {
393
- console.log(info("No useai data directory found. Nothing to purge."));
394
- return;
395
- }
396
- if (!opts.yes) {
397
- console.log(error(`This will permanently delete all data in ${USEAI_DIR}`));
398
- const confirmed = await confirm(' Type "yes" to confirm: ');
399
- if (!confirmed) {
400
- console.log(info("Purge cancelled."));
401
- return;
402
- }
403
- }
404
- rmSync(USEAI_DIR, { recursive: true, force: true });
405
- console.log(success("All local useai data has been deleted."));
406
- });
407
-
408
- // src/commands/setup.ts
409
- import { Command as Command7 } from "commander";
410
- import { checkbox } from "@inquirer/prompts";
411
- import chalk6 from "chalk";
412
428
 
413
429
  // ../shared/dist/crypto/keystore.js
414
430
  import { generateKeyPairSync, randomBytes, createCipheriv, createDecipheriv, createPrivateKey } from "crypto";
@@ -4575,7 +4591,7 @@ var publishPayloadSchema = external_exports.object({
4575
4591
 
4576
4592
  // ../shared/dist/daemon/resolve-npx.js
4577
4593
  import { execSync } from "child_process";
4578
- import { existsSync as existsSync4 } from "fs";
4594
+ import { existsSync as existsSync3 } from "fs";
4579
4595
  import { join as join2 } from "path";
4580
4596
  import { homedir as homedir2 } from "os";
4581
4597
  var isWindows = process.platform === "win32";
@@ -4606,7 +4622,7 @@ function resolveNpxPath() {
4606
4622
  }
4607
4623
  }
4608
4624
  for (const p of KNOWN_PATHS) {
4609
- if (existsSync4(p))
4625
+ if (existsSync3(p))
4610
4626
  return p;
4611
4627
  }
4612
4628
  throw new Error("Could not find npx. Ensure Node.js is installed and npx is in your PATH.");
@@ -4630,14 +4646,14 @@ function buildNodePath() {
4630
4646
  }
4631
4647
  } catch {
4632
4648
  }
4633
- return dirs.filter((d) => existsSync4(d)).join(":");
4649
+ return dirs.filter((d) => existsSync3(d)).join(":");
4634
4650
  }
4635
4651
 
4636
4652
  // ../shared/dist/daemon/ensure.js
4637
- import { existsSync as existsSync5, readFileSync as readFileSync2, unlinkSync } from "fs";
4653
+ import { existsSync as existsSync4, readFileSync as readFileSync2, unlinkSync } from "fs";
4638
4654
  import { execSync as execSync2, spawn } from "child_process";
4639
4655
  function readPidFile() {
4640
- if (!existsSync5(DAEMON_PID_FILE))
4656
+ if (!existsSync4(DAEMON_PID_FILE))
4641
4657
  return null;
4642
4658
  try {
4643
4659
  const raw = readFileSync2(DAEMON_PID_FILE, "utf-8").trim();
@@ -4706,7 +4722,7 @@ async function killDaemon() {
4706
4722
  if (pidData && isProcessRunning(pidData.pid)) {
4707
4723
  await killPid(pidData.pid);
4708
4724
  try {
4709
- if (existsSync5(DAEMON_PID_FILE))
4725
+ if (existsSync4(DAEMON_PID_FILE))
4710
4726
  unlinkSync(DAEMON_PID_FILE);
4711
4727
  } catch {
4712
4728
  }
@@ -4723,7 +4739,7 @@ async function killDaemon() {
4723
4739
  await Promise.all(pids.map((p) => killPid(p)));
4724
4740
  }
4725
4741
  try {
4726
- if (existsSync5(DAEMON_PID_FILE))
4742
+ if (existsSync4(DAEMON_PID_FILE))
4727
4743
  unlinkSync(DAEMON_PID_FILE);
4728
4744
  } catch {
4729
4745
  }
@@ -4772,7 +4788,7 @@ async function ensureDaemon(options) {
4772
4788
  }
4773
4789
 
4774
4790
  // ../shared/dist/daemon/autostart.js
4775
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2 } from "fs";
4791
+ import { existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2 } from "fs";
4776
4792
  import { execSync as execSync3 } from "child_process";
4777
4793
  import { dirname } from "path";
4778
4794
  function detectPlatform() {
@@ -4866,13 +4882,13 @@ function removeMacos() {
4866
4882
  } catch {
4867
4883
  }
4868
4884
  try {
4869
- if (existsSync6(LAUNCHD_PLIST_PATH))
4885
+ if (existsSync5(LAUNCHD_PLIST_PATH))
4870
4886
  unlinkSync2(LAUNCHD_PLIST_PATH);
4871
4887
  } catch {
4872
4888
  }
4873
4889
  }
4874
4890
  function isMacosInstalled() {
4875
- return existsSync6(LAUNCHD_PLIST_PATH);
4891
+ return existsSync5(LAUNCHD_PLIST_PATH);
4876
4892
  }
4877
4893
  function buildSystemdUnit(npxPath, nodePath) {
4878
4894
  return `[Unit]
@@ -4910,7 +4926,7 @@ function removeLinux() {
4910
4926
  } catch {
4911
4927
  }
4912
4928
  try {
4913
- if (existsSync6(SYSTEMD_SERVICE_PATH))
4929
+ if (existsSync5(SYSTEMD_SERVICE_PATH))
4914
4930
  unlinkSync2(SYSTEMD_SERVICE_PATH);
4915
4931
  } catch {
4916
4932
  }
@@ -4920,7 +4936,7 @@ function removeLinux() {
4920
4936
  }
4921
4937
  }
4922
4938
  function isLinuxInstalled() {
4923
- return existsSync6(SYSTEMD_SERVICE_PATH);
4939
+ return existsSync5(SYSTEMD_SERVICE_PATH);
4924
4940
  }
4925
4941
  function buildVbsScript(npxPath) {
4926
4942
  return `Set WshShell = CreateObject("WScript.Shell")
@@ -4934,13 +4950,13 @@ function installWindows() {
4934
4950
  }
4935
4951
  function removeWindows() {
4936
4952
  try {
4937
- if (existsSync6(WINDOWS_STARTUP_SCRIPT_PATH))
4953
+ if (existsSync5(WINDOWS_STARTUP_SCRIPT_PATH))
4938
4954
  unlinkSync2(WINDOWS_STARTUP_SCRIPT_PATH);
4939
4955
  } catch {
4940
4956
  }
4941
4957
  }
4942
4958
  function isWindowsInstalled() {
4943
- return existsSync6(WINDOWS_STARTUP_SCRIPT_PATH);
4959
+ return existsSync5(WINDOWS_STARTUP_SCRIPT_PATH);
4944
4960
  }
4945
4961
  function installAutostart() {
4946
4962
  const platform = detectPlatform();
@@ -4991,7 +5007,7 @@ function recoverAutostart() {
4991
5007
  const platform = detectPlatform();
4992
5008
  switch (platform) {
4993
5009
  case "macos": {
4994
- if (!existsSync6(LAUNCHD_PLIST_PATH)) {
5010
+ if (!existsSync5(LAUNCHD_PLIST_PATH)) {
4995
5011
  return { recovered: false, message: "Auto-start is not installed (plist missing)" };
4996
5012
  }
4997
5013
  const target = getLaunchdServiceTarget();
@@ -5009,7 +5025,7 @@ function recoverAutostart() {
5009
5025
  }
5010
5026
  }
5011
5027
  case "linux": {
5012
- if (!existsSync6(SYSTEMD_SERVICE_PATH)) {
5028
+ if (!existsSync5(SYSTEMD_SERVICE_PATH)) {
5013
5029
  return { recovered: false, message: "Auto-start is not installed (unit file missing)" };
5014
5030
  }
5015
5031
  try {
@@ -5044,7 +5060,7 @@ async function fetchLatestVersion(packageName = PACKAGE_NAME) {
5044
5060
  }
5045
5061
 
5046
5062
  // ../shared/dist/hooks/claude-code.js
5047
- import { existsSync as existsSync7, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, unlinkSync as unlinkSync3, chmodSync } from "fs";
5063
+ import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, unlinkSync as unlinkSync3, chmodSync } from "fs";
5048
5064
  import { join as join3 } from "path";
5049
5065
  import { homedir as homedir3 } from "os";
5050
5066
  var STOP_GUARD_PATH = join3(USEAI_HOOKS_DIR, "stop-guard.js");
@@ -5099,7 +5115,7 @@ process.stdin.on('end', () => {
5099
5115
  });
5100
5116
  `;
5101
5117
  function readSettings() {
5102
- if (!existsSync7(CLAUDE_SETTINGS_PATH))
5118
+ if (!existsSync6(CLAUDE_SETTINGS_PATH))
5103
5119
  return {};
5104
5120
  try {
5105
5121
  return JSON.parse(readFileSync3(CLAUDE_SETTINGS_PATH, "utf-8"));
@@ -5167,7 +5183,7 @@ function installClaudeCodeHooks() {
5167
5183
  return changed;
5168
5184
  }
5169
5185
  function removeClaudeCodeHooks() {
5170
- if (existsSync7(CLAUDE_SETTINGS_PATH)) {
5186
+ if (existsSync6(CLAUDE_SETTINGS_PATH)) {
5171
5187
  try {
5172
5188
  const settings = readSettings();
5173
5189
  const hooks = settings["hooks"];
@@ -5204,20 +5220,190 @@ function removeClaudeCodeHooks() {
5204
5220
  }
5205
5221
  }
5206
5222
  try {
5207
- if (existsSync7(STOP_GUARD_PATH))
5223
+ if (existsSync6(STOP_GUARD_PATH))
5208
5224
  unlinkSync3(STOP_GUARD_PATH);
5209
5225
  } catch {
5210
5226
  }
5211
5227
  try {
5212
- if (existsSync7(PROMPT_GUARD_PATH))
5228
+ if (existsSync6(PROMPT_GUARD_PATH))
5213
5229
  unlinkSync3(PROMPT_GUARD_PATH);
5214
5230
  } catch {
5215
5231
  }
5216
5232
  }
5217
5233
 
5234
+ // ../shared/dist/frameworks/raw.js
5235
+ var rubrics = [
5236
+ {
5237
+ dimension: "prompt_quality",
5238
+ label: "Prompt Quality",
5239
+ weight: 0.25,
5240
+ levels: {
5241
+ 1: "Vague or ambiguous",
5242
+ 2: "Some goal stated but unclear",
5243
+ 3: "Clear goal, some missing details",
5244
+ 4: "Clear goal with most constraints",
5245
+ 5: "Crystal clear with acceptance criteria"
5246
+ }
5247
+ },
5248
+ {
5249
+ dimension: "context_provided",
5250
+ label: "Context Provided",
5251
+ weight: 0.25,
5252
+ levels: {
5253
+ 1: "No context provided",
5254
+ 2: "Minimal context",
5255
+ 3: "Some files or errors provided",
5256
+ 4: "Good context with some gaps",
5257
+ 5: "Comprehensive context with constraints"
5258
+ }
5259
+ },
5260
+ {
5261
+ dimension: "independence_level",
5262
+ label: "Independence Level",
5263
+ weight: 0.25,
5264
+ levels: {
5265
+ 1: "Needed constant guidance",
5266
+ 2: "Frequent back-and-forth",
5267
+ 3: "Some back-and-forth on approach",
5268
+ 4: "Mostly self-directed",
5269
+ 5: "Gave clear spec, AI executed autonomously"
5270
+ }
5271
+ },
5272
+ {
5273
+ dimension: "scope_quality",
5274
+ label: "Scope Quality",
5275
+ weight: 0.25,
5276
+ levels: {
5277
+ 1: "Vague or impossibly broad",
5278
+ 2: "Poorly defined scope",
5279
+ 3: "Reasonable scope with some ambiguity",
5280
+ 4: "Well-scoped with minor gaps",
5281
+ 5: "Precise, achievable, well-decomposed"
5282
+ }
5283
+ }
5284
+ ];
5285
+ var rawFramework = {
5286
+ id: "raw",
5287
+ name: "Raw",
5288
+ description: "Equal-weight average across all scored dimensions. Minimal rubric guidance.",
5289
+ version: "1.0.0",
5290
+ rubrics,
5291
+ computeSessionScore(evaluation) {
5292
+ const { prompt_quality, context_provided, independence_level, scope_quality } = evaluation;
5293
+ return (prompt_quality + context_provided + independence_level + scope_quality) / 20 * 100;
5294
+ },
5295
+ getInstructionText() {
5296
+ return "- At the END of every response, call `useai_end` with languages used, files_touched_count, milestones (generic descriptions only \u2014 no project names, file paths, or company names), and an `evaluation` object honestly assessing: prompt_quality (1-5), context_provided (1-5), task_outcome, iteration_count, independence_level (1-5), scope_quality (1-5), tools_leveraged count.";
5297
+ }
5298
+ };
5299
+
5300
+ // ../shared/dist/frameworks/space.js
5301
+ var rubrics2 = [
5302
+ {
5303
+ dimension: "prompt_quality",
5304
+ label: "Prompt Quality",
5305
+ spaceMapping: "Communication",
5306
+ weight: 0.3,
5307
+ levels: {
5308
+ 1: "Vague, no goal stated, AI must guess intent entirely",
5309
+ 2: "Goal implied but ambiguous, missing key constraints",
5310
+ 3: "Clear goal, some constraints provided, missing edge cases",
5311
+ 4: "Clear goal with constraints, minor ambiguity remains",
5312
+ 5: "Crystal clear goal, all constraints stated, acceptance criteria defined"
5313
+ }
5314
+ },
5315
+ {
5316
+ dimension: "context_provided",
5317
+ label: "Context Provided",
5318
+ spaceMapping: "Communication",
5319
+ weight: 0.25,
5320
+ levels: {
5321
+ 1: "No context provided \u2014 no files, errors, or background",
5322
+ 2: "Minimal context \u2014 vague references without specifics",
5323
+ 3: "Some files or errors provided but incomplete picture",
5324
+ 4: "Good context with relevant files, errors, and background",
5325
+ 5: "Comprehensive context: files, errors, constraints, and expected behavior"
5326
+ }
5327
+ },
5328
+ {
5329
+ dimension: "independence_level",
5330
+ label: "Independence Level",
5331
+ spaceMapping: "Efficiency",
5332
+ weight: 0.25,
5333
+ levels: {
5334
+ 1: "Needed constant guidance, every step required approval",
5335
+ 2: "Frequent back-and-forth, many clarifying questions needed",
5336
+ 3: "Some back-and-forth on approach, core decisions made by user",
5337
+ 4: "Mostly self-directed, only major decisions needed input",
5338
+ 5: "Gave clear spec, AI executed autonomously with minimal interruption"
5339
+ }
5340
+ },
5341
+ {
5342
+ dimension: "scope_quality",
5343
+ label: "Scope Quality",
5344
+ spaceMapping: "Performance",
5345
+ weight: 0.2,
5346
+ levels: {
5347
+ 1: "Vague or impossibly broad \u2014 no clear deliverable",
5348
+ 2: "Poorly defined \u2014 scope creep likely, unclear boundaries",
5349
+ 3: "Reasonable scope with some ambiguity in deliverables",
5350
+ 4: "Well-scoped with clear deliverables, minor gaps",
5351
+ 5: "Precise, achievable, well-decomposed into actionable steps"
5352
+ }
5353
+ }
5354
+ ];
5355
+ var spaceFramework = {
5356
+ id: "space",
5357
+ name: "SPACE",
5358
+ description: "SPACE-mapped rubrics with explicit per-level criteria and weighted dimensions.",
5359
+ version: "1.0.0",
5360
+ rubrics: rubrics2,
5361
+ computeSessionScore(evaluation) {
5362
+ const { prompt_quality, context_provided, independence_level, scope_quality } = evaluation;
5363
+ return (prompt_quality / 5 * 0.3 + context_provided / 5 * 0.25 + independence_level / 5 * 0.25 + scope_quality / 5 * 0.2) * 100;
5364
+ },
5365
+ getInstructionText() {
5366
+ return [
5367
+ "- At the END of every response, call `useai_end` with languages used, files_touched_count, milestones (generic descriptions only \u2014 no project names, file paths, or company names), and an `evaluation` object.",
5368
+ "- **Evaluation rubric (SPACE framework):** Score each metric 1-5 using these criteria:",
5369
+ " - **prompt_quality** (Communication, weight 0.30): 1=vague/no goal, 3=clear goal but missing edge cases, 5=crystal clear with acceptance criteria",
5370
+ " - **context_provided** (Communication, weight 0.25): 1=no context, 3=some files/errors but incomplete, 5=comprehensive with constraints",
5371
+ " - **independence_level** (Efficiency, weight 0.25): 1=constant guidance needed, 3=some back-and-forth, 5=clear spec with autonomous execution",
5372
+ " - **scope_quality** (Performance, weight 0.20): 1=vague/impossibly broad, 3=reasonable with ambiguity, 5=precise and well-decomposed",
5373
+ "- Also include: task_outcome (completed/partial/abandoned/blocked), iteration_count, tools_leveraged count.",
5374
+ "- For any scored metric < 5 or non-completed outcome, you MUST provide a *_reason field with a concrete tip to improve."
5375
+ ].join("\n");
5376
+ }
5377
+ };
5378
+
5379
+ // ../shared/dist/frameworks/registry.js
5380
+ var frameworks = {
5381
+ raw: rawFramework,
5382
+ space: spaceFramework
5383
+ };
5384
+ function getFramework(id) {
5385
+ if (id && id in frameworks) {
5386
+ return frameworks[id];
5387
+ }
5388
+ return frameworks.raw;
5389
+ }
5390
+ function getFrameworkIds() {
5391
+ return Object.keys(frameworks);
5392
+ }
5393
+ function buildInstructionsText(frameworkId) {
5394
+ const framework = getFramework(frameworkId);
5395
+ return [
5396
+ "## UseAI Session Tracking",
5397
+ "- At the START of every response, call `useai_start` with the appropriate task_type. Also generate a short session `title` (generic, no project names) and `private_title` (detailed, can include specifics) from the user's prompt.",
5398
+ "- To group multiple prompts in the same conversation, pass the `conversation_id` from the previous `useai_start` response. Omit it for the first message or a new conversation.",
5399
+ "- For LONG sessions (15+ min), call `useai_heartbeat` periodically.",
5400
+ framework.getInstructionText()
5401
+ ].join("\n");
5402
+ }
5403
+
5218
5404
  // src/services/tools.ts
5219
5405
  import { execSync as execSync4 } from "child_process";
5220
- import { existsSync as existsSync8, readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, unlinkSync as unlinkSync4 } from "fs";
5406
+ import { existsSync as existsSync7, readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, unlinkSync as unlinkSync4 } from "fs";
5221
5407
  import { dirname as dirname2, join as join4 } from "path";
5222
5408
  import { homedir as homedir4 } from "os";
5223
5409
  import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
@@ -5260,7 +5446,7 @@ function hasBinary(name) {
5260
5446
  }
5261
5447
  }
5262
5448
  function readJsonFile(path) {
5263
- if (!existsSync8(path)) return {};
5449
+ if (!existsSync7(path)) return {};
5264
5450
  try {
5265
5451
  const raw = readFileSync4(path, "utf-8").trim();
5266
5452
  if (!raw) return {};
@@ -5352,7 +5538,7 @@ function removeZed(configPath) {
5352
5538
  }
5353
5539
  }
5354
5540
  function readTomlFile(path) {
5355
- if (!existsSync8(path)) return {};
5541
+ if (!existsSync7(path)) return {};
5356
5542
  try {
5357
5543
  const raw = readFileSync4(path, "utf-8").trim();
5358
5544
  if (!raw) return {};
@@ -5399,7 +5585,7 @@ function removeToml(configPath) {
5399
5585
  }
5400
5586
  }
5401
5587
  function readYamlFile(path) {
5402
- if (!existsSync8(path)) return {};
5588
+ if (!existsSync7(path)) return {};
5403
5589
  try {
5404
5590
  const raw = readFileSync4(path, "utf-8").trim();
5405
5591
  if (!raw) return {};
@@ -5491,46 +5677,47 @@ function installCrushHttp(configPath) {
5491
5677
  }
5492
5678
  var INSTRUCTIONS_START = "<!-- useai:start -->";
5493
5679
  var INSTRUCTIONS_END = "<!-- useai:end -->";
5494
- var USEAI_INSTRUCTIONS = [
5495
- "## UseAI Session Tracking",
5496
- "- At the START of every response, call `useai_session_start` with the appropriate task_type.",
5497
- "- For LONG sessions (15+ min), call `useai_heartbeat` periodically.",
5498
- "- At the END of every response, call `useai_session_end` with languages used, files_touched_count, and milestones (generic descriptions only \u2014 no project names, file paths, or company names)."
5499
- ].join("\n");
5500
- var USEAI_INSTRUCTIONS_BLOCK = `${INSTRUCTIONS_START}
5501
- ${USEAI_INSTRUCTIONS}
5680
+ function getUseaiInstructions(frameworkId) {
5681
+ return buildInstructionsText(frameworkId);
5682
+ }
5683
+ function getUseaiInstructionsBlock(frameworkId) {
5684
+ return `${INSTRUCTIONS_START}
5685
+ ${getUseaiInstructions(frameworkId)}
5502
5686
  ${INSTRUCTIONS_END}`;
5687
+ }
5503
5688
  function hasInstructionsBlock(filePath) {
5504
- if (!existsSync8(filePath)) return false;
5689
+ if (!existsSync7(filePath)) return false;
5505
5690
  try {
5506
5691
  return readFileSync4(filePath, "utf-8").includes(INSTRUCTIONS_START);
5507
5692
  } catch {
5508
5693
  return false;
5509
5694
  }
5510
5695
  }
5511
- function injectInstructions(config) {
5696
+ function injectInstructions(config, frameworkId) {
5512
5697
  mkdirSync4(dirname2(config.path), { recursive: true });
5698
+ const instructions = getUseaiInstructions(frameworkId);
5699
+ const block = getUseaiInstructionsBlock(frameworkId);
5513
5700
  if (config.method === "create") {
5514
- writeFileSync4(config.path, USEAI_INSTRUCTIONS + "\n");
5701
+ writeFileSync4(config.path, instructions + "\n");
5515
5702
  return;
5516
5703
  }
5517
5704
  let existing = "";
5518
- if (existsSync8(config.path)) {
5705
+ if (existsSync7(config.path)) {
5519
5706
  existing = readFileSync4(config.path, "utf-8");
5520
5707
  }
5521
5708
  if (hasInstructionsBlock(config.path)) {
5522
5709
  const pattern = new RegExp(
5523
5710
  `${INSTRUCTIONS_START}[\\s\\S]*?${INSTRUCTIONS_END}`
5524
5711
  );
5525
- writeFileSync4(config.path, existing.replace(pattern, USEAI_INSTRUCTIONS_BLOCK));
5712
+ writeFileSync4(config.path, existing.replace(pattern, block));
5526
5713
  return;
5527
5714
  }
5528
5715
  const separator = existing && !existing.endsWith("\n") ? "\n\n" : existing ? "\n" : "";
5529
- writeFileSync4(config.path, existing + separator + USEAI_INSTRUCTIONS_BLOCK + "\n");
5716
+ writeFileSync4(config.path, existing + separator + block + "\n");
5530
5717
  }
5531
5718
  function removeInstructions(config) {
5532
5719
  if (config.method === "create") {
5533
- if (existsSync8(config.path)) {
5720
+ if (existsSync7(config.path)) {
5534
5721
  try {
5535
5722
  unlinkSync4(config.path);
5536
5723
  } catch {
@@ -5538,7 +5725,7 @@ function removeInstructions(config) {
5538
5725
  }
5539
5726
  return;
5540
5727
  }
5541
- if (!existsSync8(config.path)) return;
5728
+ if (!existsSync7(config.path)) return;
5542
5729
  try {
5543
5730
  const content = readFileSync4(config.path, "utf-8");
5544
5731
  const escaped = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -5570,6 +5757,7 @@ function createTool(def) {
5570
5757
  name: def.name,
5571
5758
  configFormat: def.configFormat,
5572
5759
  supportsUrl: urlSupported,
5760
+ instructionPlacement: def.instructions,
5573
5761
  getConfigPath: () => def.configPath,
5574
5762
  detect: def.detect,
5575
5763
  isConfigured: () => handler.isConfigured(def.configPath),
@@ -5628,7 +5816,7 @@ var AI_TOOLS = [
5628
5816
  name: "Claude Code",
5629
5817
  configFormat: "standard",
5630
5818
  configPath: join4(home, ".claude.json"),
5631
- detect: () => hasBinary("claude") || existsSync8(join4(home, ".claude.json")),
5819
+ detect: () => hasBinary("claude") || existsSync7(join4(home, ".claude.json")),
5632
5820
  instructions: { method: "append", path: join4(home, ".claude", "CLAUDE.md") },
5633
5821
  supportsUrl: true
5634
5822
  }),
@@ -5637,7 +5825,7 @@ var AI_TOOLS = [
5637
5825
  name: "Claude Desktop",
5638
5826
  configFormat: "standard",
5639
5827
  configPath: join4(appSupport, "Claude", "claude_desktop_config.json"),
5640
- detect: () => existsSync8(join4(appSupport, "Claude")) || existsSync8("/Applications/Claude.app"),
5828
+ detect: () => existsSync7(join4(appSupport, "Claude")) || existsSync7("/Applications/Claude.app"),
5641
5829
  supportsUrl: true
5642
5830
  }),
5643
5831
  createTool({
@@ -5645,7 +5833,7 @@ var AI_TOOLS = [
5645
5833
  name: "Cursor",
5646
5834
  configFormat: "standard",
5647
5835
  configPath: join4(home, ".cursor", "mcp.json"),
5648
- detect: () => existsSync8(join4(home, ".cursor")),
5836
+ detect: () => existsSync7(join4(home, ".cursor")),
5649
5837
  manualHint: "Open Cursor Settings \u2192 Rules \u2192 User Rules and paste the instructions below.",
5650
5838
  supportsUrl: true
5651
5839
  }),
@@ -5654,7 +5842,7 @@ var AI_TOOLS = [
5654
5842
  name: "Windsurf",
5655
5843
  configFormat: "standard",
5656
5844
  configPath: join4(home, ".codeium", "windsurf", "mcp_config.json"),
5657
- detect: () => existsSync8(join4(home, ".codeium", "windsurf")),
5845
+ detect: () => existsSync7(join4(home, ".codeium", "windsurf")),
5658
5846
  instructions: { method: "append", path: join4(home, ".codeium", "windsurf", "memories", "global_rules.md") },
5659
5847
  supportsUrl: true
5660
5848
  }),
@@ -5663,7 +5851,7 @@ var AI_TOOLS = [
5663
5851
  name: "VS Code",
5664
5852
  configFormat: "vscode",
5665
5853
  configPath: join4(appSupport, "Code", "User", "mcp.json"),
5666
- detect: () => existsSync8(join4(appSupport, "Code")),
5854
+ detect: () => existsSync7(join4(appSupport, "Code")),
5667
5855
  instructions: { method: "create", path: join4(appSupport, "Code", "User", "prompts", "useai.instructions.md") },
5668
5856
  supportsUrl: true
5669
5857
  }),
@@ -5672,7 +5860,7 @@ var AI_TOOLS = [
5672
5860
  name: "VS Code Insiders",
5673
5861
  configFormat: "vscode",
5674
5862
  configPath: join4(appSupport, "Code - Insiders", "User", "mcp.json"),
5675
- detect: () => existsSync8(join4(appSupport, "Code - Insiders")),
5863
+ detect: () => existsSync7(join4(appSupport, "Code - Insiders")),
5676
5864
  instructions: { method: "create", path: join4(appSupport, "Code - Insiders", "User", "prompts", "useai.instructions.md") },
5677
5865
  supportsUrl: true
5678
5866
  }),
@@ -5690,7 +5878,7 @@ var AI_TOOLS = [
5690
5878
  name: "Antigravity",
5691
5879
  configFormat: "standard",
5692
5880
  configPath: join4(home, ".gemini", "antigravity", "mcp_config.json"),
5693
- detect: () => existsSync8(join4(home, ".gemini", "antigravity")),
5881
+ detect: () => existsSync7(join4(home, ".gemini", "antigravity")),
5694
5882
  instructions: { method: "append", path: join4(home, ".gemini", "GEMINI.md") },
5695
5883
  supportsUrl: true
5696
5884
  }),
@@ -5699,7 +5887,7 @@ var AI_TOOLS = [
5699
5887
  name: "Copilot CLI",
5700
5888
  configFormat: "standard",
5701
5889
  configPath: join4(home, ".copilot", "mcp-config.json"),
5702
- detect: () => hasBinary("copilot") || existsSync8(join4(home, ".copilot")),
5890
+ detect: () => hasBinary("copilot") || existsSync7(join4(home, ".copilot")),
5703
5891
  manualHint: "No global instructions file \u2014 add UseAI instructions to your project-level agent rules.",
5704
5892
  supportsUrl: true
5705
5893
  }),
@@ -5708,7 +5896,7 @@ var AI_TOOLS = [
5708
5896
  name: "Trae",
5709
5897
  configFormat: "standard",
5710
5898
  configPath: join4(appSupport, "Trae", "User", "mcp.json"),
5711
- detect: () => existsSync8(join4(appSupport, "Trae")),
5899
+ detect: () => existsSync7(join4(appSupport, "Trae")),
5712
5900
  manualHint: "Open Trae Settings \u2192 Rules and paste the instructions below.",
5713
5901
  supportsUrl: true
5714
5902
  }),
@@ -5717,7 +5905,7 @@ var AI_TOOLS = [
5717
5905
  name: "Zed",
5718
5906
  configFormat: "zed",
5719
5907
  configPath: join4(appSupport, "Zed", "settings.json"),
5720
- detect: () => existsSync8(join4(appSupport, "Zed")),
5908
+ detect: () => existsSync7(join4(appSupport, "Zed")),
5721
5909
  manualHint: "Open Rules Library (\u2318\u2325L) \u2192 click + \u2192 paste the instructions below."
5722
5910
  }),
5723
5911
  createTool({
@@ -5733,7 +5921,7 @@ var AI_TOOLS = [
5733
5921
  "settings",
5734
5922
  "cline_mcp_settings.json"
5735
5923
  ),
5736
- detect: () => existsSync8(
5924
+ detect: () => existsSync7(
5737
5925
  join4(appSupport, "Code", "User", "globalStorage", "saoudrizwan.claude-dev")
5738
5926
  ),
5739
5927
  instructions: { method: "create", path: join4(home, "Documents", "Cline", "Rules", "useai.md") },
@@ -5752,7 +5940,7 @@ var AI_TOOLS = [
5752
5940
  "settings",
5753
5941
  "cline_mcp_settings.json"
5754
5942
  ),
5755
- detect: () => existsSync8(
5943
+ detect: () => existsSync7(
5756
5944
  join4(appSupport, "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline")
5757
5945
  ),
5758
5946
  instructions: { method: "create", path: join4(home, ".roo", "rules", "useai.md") },
@@ -5771,7 +5959,7 @@ var AI_TOOLS = [
5771
5959
  "settings",
5772
5960
  "mcp_settings.json"
5773
5961
  ),
5774
- detect: () => existsSync8(
5962
+ detect: () => existsSync7(
5775
5963
  join4(appSupport, "Code", "User", "globalStorage", "kilocode.kilo-code")
5776
5964
  ),
5777
5965
  manualHint: "Add the instructions below to .kilocode/rules/useai.md in your project root.",
@@ -5782,7 +5970,7 @@ var AI_TOOLS = [
5782
5970
  name: "Amazon Q CLI",
5783
5971
  configFormat: "standard",
5784
5972
  configPath: join4(home, ".aws", "amazonq", "mcp.json"),
5785
- detect: () => hasBinary("q") || existsSync8(join4(home, ".aws", "amazonq")),
5973
+ detect: () => hasBinary("q") || existsSync7(join4(home, ".aws", "amazonq")),
5786
5974
  manualHint: "Create .amazonq/rules/useai.md in your project root with the instructions below."
5787
5975
  }),
5788
5976
  createTool({
@@ -5790,7 +5978,7 @@ var AI_TOOLS = [
5790
5978
  name: "Amazon Q IDE",
5791
5979
  configFormat: "standard",
5792
5980
  configPath: join4(home, ".aws", "amazonq", "default.json"),
5793
- detect: () => existsSync8(join4(home, ".amazonq")) || existsSync8(join4(home, ".aws", "amazonq")),
5981
+ detect: () => existsSync7(join4(home, ".amazonq")) || existsSync7(join4(home, ".aws", "amazonq")),
5794
5982
  manualHint: "Create .amazonq/rules/useai.md in your project root with the instructions below."
5795
5983
  }),
5796
5984
  createTool({
@@ -5798,7 +5986,7 @@ var AI_TOOLS = [
5798
5986
  name: "Codex",
5799
5987
  configFormat: "toml",
5800
5988
  configPath: join4(home, ".codex", "config.toml"),
5801
- detect: () => hasBinary("codex") || existsSync8(join4(home, ".codex")) || existsSync8("/Applications/Codex.app"),
5989
+ detect: () => hasBinary("codex") || existsSync7(join4(home, ".codex")) || existsSync7("/Applications/Codex.app"),
5802
5990
  instructions: { method: "append", path: join4(home, ".codex", "AGENTS.md") },
5803
5991
  supportsUrl: true
5804
5992
  }),
@@ -5807,7 +5995,7 @@ var AI_TOOLS = [
5807
5995
  name: "Goose",
5808
5996
  configFormat: "yaml",
5809
5997
  configPath: join4(home, ".config", "goose", "config.yaml"),
5810
- detect: () => existsSync8(join4(home, ".config", "goose")),
5998
+ detect: () => existsSync7(join4(home, ".config", "goose")),
5811
5999
  instructions: { method: "append", path: join4(home, ".config", "goose", ".goosehints") },
5812
6000
  supportsUrl: true
5813
6001
  }),
@@ -5816,7 +6004,7 @@ var AI_TOOLS = [
5816
6004
  name: "OpenCode",
5817
6005
  configFormat: "standard",
5818
6006
  configPath: join4(home, ".config", "opencode", "opencode.json"),
5819
- detect: () => hasBinary("opencode") || existsSync8(join4(home, ".config", "opencode")),
6007
+ detect: () => hasBinary("opencode") || existsSync7(join4(home, ".config", "opencode")),
5820
6008
  instructions: { method: "append", path: join4(home, ".config", "opencode", "AGENTS.md") },
5821
6009
  supportsUrl: true
5822
6010
  }),
@@ -5825,7 +6013,7 @@ var AI_TOOLS = [
5825
6013
  name: "Crush",
5826
6014
  configFormat: "crush",
5827
6015
  configPath: join4(home, ".config", "crush", "crush.json"),
5828
- detect: () => hasBinary("crush") || existsSync8(join4(home, ".config", "crush")),
6016
+ detect: () => hasBinary("crush") || existsSync7(join4(home, ".config", "crush")),
5829
6017
  manualHint: "No global instructions file \u2014 add UseAI instructions to your project-level .crush.json.",
5830
6018
  supportsUrl: true
5831
6019
  }),
@@ -5834,12 +6022,129 @@ var AI_TOOLS = [
5834
6022
  name: "Junie",
5835
6023
  configFormat: "standard",
5836
6024
  configPath: join4(home, ".junie", "mcp", "mcp.json"),
5837
- detect: () => existsSync8(join4(home, ".junie")),
6025
+ detect: () => existsSync7(join4(home, ".junie")),
5838
6026
  manualHint: "Add the instructions below to .junie/guidelines.md in your project root."
5839
6027
  })
5840
6028
  ];
6029
+ function reinjectInstructions(frameworkId) {
6030
+ const results = [];
6031
+ for (const tool of AI_TOOLS) {
6032
+ try {
6033
+ if (!tool.isConfigured()) continue;
6034
+ if (tool.instructionPlacement) {
6035
+ injectInstructions(tool.instructionPlacement, frameworkId);
6036
+ results.push({ tool: tool.name, ok: true });
6037
+ }
6038
+ } catch {
6039
+ results.push({ tool: tool.name, ok: false });
6040
+ }
6041
+ }
6042
+ return results;
6043
+ }
6044
+
6045
+ // src/commands/config.ts
6046
+ var configCommand = new Command4("config").description("View or update settings").option("--sync", "Enable auto-sync").option("--no-sync", "Disable auto-sync").option("--milestones", "Enable milestone tracking").option("--no-milestones", "Disable milestone tracking").option("--framework <name>", "Set evaluation framework (raw, space)").action((opts) => {
6047
+ let changed = false;
6048
+ if (process.argv.includes("--no-sync")) {
6049
+ updateConfig({ auto_sync: false });
6050
+ console.log(success("Auto-sync disabled."));
6051
+ changed = true;
6052
+ } else if (process.argv.includes("--sync")) {
6053
+ updateConfig({ auto_sync: true });
6054
+ console.log(success("Auto-sync enabled."));
6055
+ changed = true;
6056
+ }
6057
+ if (process.argv.includes("--no-milestones")) {
6058
+ updateConfig({ milestone_tracking: false });
6059
+ console.log(success("Milestone tracking disabled."));
6060
+ changed = true;
6061
+ } else if (process.argv.includes("--milestones")) {
6062
+ updateConfig({ milestone_tracking: true });
6063
+ console.log(success("Milestone tracking enabled."));
6064
+ changed = true;
6065
+ }
6066
+ if (opts.framework) {
6067
+ const validIds = getFrameworkIds();
6068
+ if (!validIds.includes(opts.framework)) {
6069
+ console.log(error(`Unknown framework: ${opts.framework}. Valid: ${validIds.join(", ")}`));
6070
+ } else {
6071
+ updateConfig({ evaluation_framework: opts.framework });
6072
+ console.log(success(`Evaluation framework set to ${chalk5.bold(opts.framework)}.`));
6073
+ const results = reinjectInstructions(opts.framework);
6074
+ if (results.length > 0) {
6075
+ for (const r of results) {
6076
+ console.log(r.ok ? info(` \u21BB ${r.tool} instructions updated`) : error(` \u2717 ${r.tool}`));
6077
+ }
6078
+ }
6079
+ changed = true;
6080
+ }
6081
+ }
6082
+ const config = getConfig();
6083
+ if (!changed) {
6084
+ console.log(header("Current Settings"));
6085
+ console.log(
6086
+ table([
6087
+ ["Milestone tracking", config.milestone_tracking ? chalk5.green("on") : chalk5.red("off")],
6088
+ ["Auto sync", config.auto_sync ? chalk5.green("on") : chalk5.red("off")],
6089
+ ["Eval framework", chalk5.cyan(config.evaluation_framework ?? "raw")],
6090
+ ["Sync interval", `${config.sync_interval_hours}h`],
6091
+ ["Last sync", config.last_sync_at ?? chalk5.dim("never")],
6092
+ ["Logged in", config.auth ? chalk5.green(config.auth.user.email) : chalk5.dim("no")]
6093
+ ])
6094
+ );
6095
+ console.log("");
6096
+ }
6097
+ });
6098
+
6099
+ // src/commands/export.ts
6100
+ import { Command as Command5 } from "commander";
6101
+ var exportCommand = new Command5("export").description("Export all local data as JSON to stdout").action(() => {
6102
+ const config = getConfig();
6103
+ const sessions = readJson(SESSIONS_FILE, []);
6104
+ const milestones = readJson(MILESTONES_FILE, []);
6105
+ const data = {
6106
+ exported_at: (/* @__PURE__ */ new Date()).toISOString(),
6107
+ config,
6108
+ sessions,
6109
+ milestones
6110
+ };
6111
+ process.stdout.write(JSON.stringify(data, null, 2) + "\n");
6112
+ });
6113
+
6114
+ // src/commands/purge.ts
6115
+ import { Command as Command6 } from "commander";
6116
+ import { existsSync as existsSync8, rmSync } from "fs";
6117
+ import { createInterface } from "readline";
6118
+ function confirm(question) {
6119
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
6120
+ return new Promise((resolve) => {
6121
+ rl.question(question, (answer) => {
6122
+ rl.close();
6123
+ resolve(answer.trim().toLowerCase() === "yes");
6124
+ });
6125
+ });
6126
+ }
6127
+ var purgeCommand = new Command6("purge").description("Delete ALL local useai data").option("-y, --yes", "Skip confirmation").action(async (opts) => {
6128
+ if (!existsSync8(USEAI_DIR)) {
6129
+ console.log(info("No useai data directory found. Nothing to purge."));
6130
+ return;
6131
+ }
6132
+ if (!opts.yes) {
6133
+ console.log(error(`This will permanently delete all data in ${USEAI_DIR}`));
6134
+ const confirmed = await confirm(' Type "yes" to confirm: ');
6135
+ if (!confirmed) {
6136
+ console.log(info("Purge cancelled."));
6137
+ return;
6138
+ }
6139
+ }
6140
+ rmSync(USEAI_DIR, { recursive: true, force: true });
6141
+ console.log(success("All local useai data has been deleted."));
6142
+ });
5841
6143
 
5842
6144
  // src/commands/setup.ts
6145
+ import { Command as Command7 } from "commander";
6146
+ import { checkbox } from "@inquirer/prompts";
6147
+ import chalk6 from "chalk";
5843
6148
  function shortenPath(p) {
5844
6149
  const home2 = process.env["HOME"] ?? "";
5845
6150
  return home2 && p.startsWith(home2) ? p.replace(home2, "~") : p;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devness/useai-cli",
3
- "version": "0.5.43",
3
+ "version": "0.5.45",
4
4
  "description": "CLI tool for useai.dev — stats, sync, publish your AI development workflow",
5
5
  "author": "nabeelkausari",
6
6
  "license": "MIT",
@@ -25,6 +25,7 @@
25
25
  "@types/node": "^22.13.4",
26
26
  "tsup": "^8.0.0",
27
27
  "typescript": "^5.7.3",
28
+ "vitest": "^4.0.18",
28
29
  "@useai/shared": "0.3.0"
29
30
  },
30
31
  "repository": {
@@ -39,7 +40,7 @@
39
40
  "build": "tsc -p tsconfig.build.json",
40
41
  "dev": "tsc --watch",
41
42
  "bundle": "tsup src/index.ts --format esm --target node18 --no-splitting",
42
- "typecheck": "tsc --noEmit",
43
+ "typecheck": "tsc --noEmit -p tsconfig.build.json",
43
44
  "clean": "rm -rf dist"
44
45
  }
45
46
  }