cue-ai 0.6.0 → 0.7.0

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/package.json +1 -1
  2. package/src/index.ts +66 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cue-ai",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "cue — Agent Profile Manager for Claude Code & Codex. Pick a profile, launch with the right skills, MCPs, and plugins.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.ts CHANGED
@@ -132,9 +132,75 @@ function similarity(a: string, b: string): number {
132
132
  return (2 * matches) / (a.length - 1 + b.length - 1);
133
133
  }
134
134
 
135
+ // ---------------------------------------------------------------------------
136
+ // Auto-update check — runs at most once per 24h, non-blocking
137
+ // ---------------------------------------------------------------------------
138
+
139
+ async function checkForUpdate(currentVersion: string): Promise<void> {
140
+ const { existsSync, readFileSync: rf, writeFileSync: wf, mkdirSync } = await import("node:fs");
141
+ const { join } = await import("node:path");
142
+ const { homedir } = await import("node:os");
143
+
144
+ const configDir = join(process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config"), "cue");
145
+ const checkFile = join(configDir, ".last-update-check");
146
+
147
+ // Only check once per 24 hours
148
+ if (existsSync(checkFile)) {
149
+ const last = parseInt(rf(checkFile, "utf8").trim(), 10) || 0;
150
+ if (Date.now() - last < 86400000) return;
151
+ }
152
+
153
+ // Fetch latest version from npm
154
+ const res = await fetch("https://registry.npmjs.org/cue-ai/latest", { signal: AbortSignal.timeout(3000) });
155
+ if (!res.ok) return;
156
+ const data = await res.json() as { version?: string };
157
+ const latest = data.version;
158
+ if (!latest) return;
159
+
160
+ // Save check timestamp
161
+ mkdirSync(configDir, { recursive: true });
162
+ wf(checkFile, String(Date.now()));
163
+
164
+ // Compare versions
165
+ if (latest === currentVersion) return;
166
+ const [cMaj, cMin, cPatch] = currentVersion.split(".").map(Number);
167
+ const [lMaj, lMin, lPatch] = latest.split(".").map(Number);
168
+ if (lMaj! < cMaj! || (lMaj === cMaj && lMin! < cMin!) || (lMaj === cMaj && lMin === cMin && lPatch! <= cPatch!)) return;
169
+
170
+ // Prompt user
171
+ process.stderr.write(`\n ⬆️ Update available: ${currentVersion} → ${latest}\n`);
172
+ process.stderr.write(` Run: npm install -g cue-ai\n\n`);
173
+
174
+ // Auto-install prompt (only in interactive TTY)
175
+ if (process.stdin.isTTY && process.stdout.isTTY) {
176
+ const readline = await import("node:readline");
177
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
178
+ const answer = await new Promise<string>((resolve) => {
179
+ rl.question(" Install now? [Y/n] ", (a) => { rl.close(); resolve(a); });
180
+ // Auto-accept after 5 seconds
181
+ setTimeout(() => { rl.close(); resolve("y"); }, 5000);
182
+ });
183
+ if (!answer || answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
184
+ process.stderr.write(" 📦 Updating...\n");
185
+ const { spawnSync } = await import("node:child_process");
186
+ const result = spawnSync("npm", ["install", "-g", "cue-ai"], { encoding: "utf8", timeout: 60000, stdio: ["ignore", "pipe", "pipe"] });
187
+ if (result.status === 0) {
188
+ process.stderr.write(` ✅ Updated to ${latest}\n\n`);
189
+ } else {
190
+ process.stderr.write(` ⚠️ Update failed. Run manually: npm install -g cue-ai\n\n`);
191
+ }
192
+ }
193
+ }
194
+ }
195
+
196
+ // ---------------------------------------------------------------------------
197
+
135
198
  async function main(argv: string[]): Promise<number> {
136
199
  const args = argv.slice(2);
137
200
 
201
+ // Non-blocking update check (runs in background, shows prompt if outdated)
202
+ checkForUpdate(readVersion()).catch(() => {});
203
+
138
204
  if (args.length === 0) {
139
205
  // Show status dashboard by default (like `git status`)
140
206
  const statusCmd = COMMANDS["status"];