olakai-cli 0.7.0 → 0.9.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.
- package/dist/{chunk-GXKHWBGO.js → chunk-B44Y3ZQP.js} +71 -4
- package/dist/{chunk-GXKHWBGO.js.map → chunk-B44Y3ZQP.js.map} +1 -1
- package/dist/{chunk-75YQWZ4Q.js → chunk-E33XD5CO.js} +1385 -19
- package/dist/chunk-E33XD5CO.js.map +1 -0
- package/dist/{doctor-27VDFNP7.js → doctor-TIVMQBE3.js} +3 -3
- package/dist/index.js +223 -3
- package/dist/index.js.map +1 -1
- package/dist/{repair-WSBWAW2B.js → repair-JYRH2ES4.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-75YQWZ4Q.js.map +0 -1
- /package/dist/{doctor-27VDFNP7.js.map → doctor-TIVMQBE3.js.map} +0 -0
- /package/dist/{repair-WSBWAW2B.js.map → repair-JYRH2ES4.js.map} +0 -0
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
runDoctor,
|
|
10
10
|
runFixes,
|
|
11
11
|
targetKey
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-B44Y3ZQP.js";
|
|
13
|
+
import "./chunk-E33XD5CO.js";
|
|
14
14
|
import "./chunk-KNGRF4XU.js";
|
|
15
15
|
import "./chunk-KY6OHQZW.js";
|
|
16
16
|
import "./chunk-AVB4N2UN.js";
|
|
@@ -26,4 +26,4 @@ export {
|
|
|
26
26
|
runFixes,
|
|
27
27
|
targetKey
|
|
28
28
|
};
|
|
29
|
-
//# sourceMappingURL=doctor-
|
|
29
|
+
//# sourceMappingURL=doctor-TIVMQBE3.js.map
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
reconcileCurrentWorkspace,
|
|
15
15
|
removeEntry,
|
|
16
16
|
runMonitorInstall
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-E33XD5CO.js";
|
|
18
18
|
import {
|
|
19
19
|
createAgent,
|
|
20
20
|
createCustomDataConfig,
|
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
getBaseUrl,
|
|
59
59
|
getEnvironment,
|
|
60
60
|
getValidEnvironments,
|
|
61
|
+
getValidToken,
|
|
61
62
|
isTokenValid,
|
|
62
63
|
isValidEnvironment,
|
|
63
64
|
loadToken,
|
|
@@ -459,6 +460,38 @@ function describeDetection(plugin, projectRoot) {
|
|
|
459
460
|
case "cursor": {
|
|
460
461
|
return "Cursor installed for this user";
|
|
461
462
|
}
|
|
463
|
+
case "gemini-cli": {
|
|
464
|
+
try {
|
|
465
|
+
const homeSettings = path.join(
|
|
466
|
+
process.env.HOME ?? "",
|
|
467
|
+
".gemini",
|
|
468
|
+
"settings.json"
|
|
469
|
+
);
|
|
470
|
+
if (process.env.HOME && fs.existsSync(homeSettings)) {
|
|
471
|
+
return "found ~/.gemini/settings.json";
|
|
472
|
+
}
|
|
473
|
+
const homeDir = path.join(process.env.HOME ?? "", ".gemini");
|
|
474
|
+
if (process.env.HOME && fs.existsSync(homeDir)) {
|
|
475
|
+
return "found ~/.gemini/";
|
|
476
|
+
}
|
|
477
|
+
} catch {
|
|
478
|
+
}
|
|
479
|
+
return "Gemini CLI on PATH";
|
|
480
|
+
}
|
|
481
|
+
case "antigravity": {
|
|
482
|
+
try {
|
|
483
|
+
const cliDir = path.join(
|
|
484
|
+
process.env.HOME ?? "",
|
|
485
|
+
".gemini",
|
|
486
|
+
"antigravity-cli"
|
|
487
|
+
);
|
|
488
|
+
if (process.env.HOME && fs.existsSync(cliDir)) {
|
|
489
|
+
return "found ~/.gemini/antigravity-cli/";
|
|
490
|
+
}
|
|
491
|
+
} catch {
|
|
492
|
+
}
|
|
493
|
+
return "Antigravity (agy) on PATH";
|
|
494
|
+
}
|
|
462
495
|
default: {
|
|
463
496
|
const _exhaustive = plugin.id;
|
|
464
497
|
void _exhaustive;
|
|
@@ -2458,7 +2491,7 @@ async function listCommand6(options) {
|
|
|
2458
2491
|
console.log(formatRegistryTable(registry));
|
|
2459
2492
|
}
|
|
2460
2493
|
async function doctorCommand(options) {
|
|
2461
|
-
const { runDoctor, printDoctorResult, exitCodeForStatus } = await import("./doctor-
|
|
2494
|
+
const { runDoctor, printDoctorResult, exitCodeForStatus } = await import("./doctor-TIVMQBE3.js");
|
|
2462
2495
|
let tool;
|
|
2463
2496
|
if (!options.all) {
|
|
2464
2497
|
tool = await resolveToolFromOptions(options.tool, "status");
|
|
@@ -2476,7 +2509,7 @@ async function doctorCommand(options) {
|
|
|
2476
2509
|
}
|
|
2477
2510
|
async function repairCommand(options) {
|
|
2478
2511
|
const tool = await resolveToolFromOptions(options.tool, "init");
|
|
2479
|
-
const { runRepair, formatRepairResult, exitCodeForRepair } = await import("./repair-
|
|
2512
|
+
const { runRepair, formatRepairResult, exitCodeForRepair } = await import("./repair-JYRH2ES4.js");
|
|
2480
2513
|
const result = await runRepair({
|
|
2481
2514
|
tool,
|
|
2482
2515
|
interactive: isInteractive()
|
|
@@ -2805,6 +2838,190 @@ function registerProfilesCommand(program2) {
|
|
|
2805
2838
|
});
|
|
2806
2839
|
}
|
|
2807
2840
|
|
|
2841
|
+
// src/commands/status.ts
|
|
2842
|
+
import * as fs3 from "fs";
|
|
2843
|
+
function formatDollars(cents) {
|
|
2844
|
+
return `$${(cents / 100).toFixed(2)}`;
|
|
2845
|
+
}
|
|
2846
|
+
function formatRelativeTime(isoString) {
|
|
2847
|
+
const then = new Date(isoString).getTime();
|
|
2848
|
+
const now = Date.now();
|
|
2849
|
+
const diffMs = now - then;
|
|
2850
|
+
if (diffMs < 0) return "just now";
|
|
2851
|
+
const diffSec = Math.floor(diffMs / 1e3);
|
|
2852
|
+
if (diffSec < 60) return "just now";
|
|
2853
|
+
const diffMin = Math.floor(diffSec / 60);
|
|
2854
|
+
if (diffMin < 60) return `${diffMin} minute${diffMin === 1 ? "" : "s"} ago`;
|
|
2855
|
+
const diffHr = Math.floor(diffMin / 60);
|
|
2856
|
+
if (diffHr < 24) return `${diffHr} hour${diffHr === 1 ? "" : "s"} ago`;
|
|
2857
|
+
const diffDay = Math.floor(diffHr / 24);
|
|
2858
|
+
return `${diffDay} day${diffDay === 1 ? "" : "s"} ago`;
|
|
2859
|
+
}
|
|
2860
|
+
function progressBar(pct) {
|
|
2861
|
+
const filled = Math.min(10, Math.max(0, Math.round(pct / 10)));
|
|
2862
|
+
return "\u2588".repeat(filled) + "\u2591".repeat(10 - filled);
|
|
2863
|
+
}
|
|
2864
|
+
function toolLabel(tool) {
|
|
2865
|
+
return tool.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
2866
|
+
}
|
|
2867
|
+
function pad(s, width) {
|
|
2868
|
+
return s.length >= width ? s : s + " ".repeat(width - s.length);
|
|
2869
|
+
}
|
|
2870
|
+
function collectLocalState() {
|
|
2871
|
+
const registry = readRegistry();
|
|
2872
|
+
return registry.workspaces.map((entry) => ({
|
|
2873
|
+
tool: entry.tool,
|
|
2874
|
+
agentId: entry.agentId,
|
|
2875
|
+
workspacePath: entry.path,
|
|
2876
|
+
configured: fs3.existsSync(entry.configPath)
|
|
2877
|
+
}));
|
|
2878
|
+
}
|
|
2879
|
+
async function fetchBackendStatus() {
|
|
2880
|
+
const token = getValidToken();
|
|
2881
|
+
if (!token) {
|
|
2882
|
+
return { data: null, error: "not logged in" };
|
|
2883
|
+
}
|
|
2884
|
+
const controller = new AbortController();
|
|
2885
|
+
const timeout = setTimeout(() => controller.abort(), 8e3);
|
|
2886
|
+
try {
|
|
2887
|
+
const response = await fetch(`${getBaseUrl()}/api/coding-iq/me/status`, {
|
|
2888
|
+
headers: {
|
|
2889
|
+
Authorization: `Bearer ${token}`
|
|
2890
|
+
},
|
|
2891
|
+
signal: controller.signal
|
|
2892
|
+
});
|
|
2893
|
+
if (response.status === 401) {
|
|
2894
|
+
return { data: null, error: "session expired" };
|
|
2895
|
+
}
|
|
2896
|
+
if (!response.ok) {
|
|
2897
|
+
return { data: null, error: "unreachable" };
|
|
2898
|
+
}
|
|
2899
|
+
const data = await response.json();
|
|
2900
|
+
return { data, error: null };
|
|
2901
|
+
} catch {
|
|
2902
|
+
return { data: null, error: "unreachable" };
|
|
2903
|
+
} finally {
|
|
2904
|
+
clearTimeout(timeout);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
var SECTION_WIDTH = 52;
|
|
2908
|
+
function sectionHeader(title) {
|
|
2909
|
+
const line = `\u2500\u2500 ${title} `;
|
|
2910
|
+
return line + "\u2500".repeat(Math.max(0, SECTION_WIDTH - line.length));
|
|
2911
|
+
}
|
|
2912
|
+
function renderHuman(workspaces, backend, backendError) {
|
|
2913
|
+
console.log(sectionHeader("MONITORING"));
|
|
2914
|
+
if (workspaces.length === 0) {
|
|
2915
|
+
console.log(
|
|
2916
|
+
" No workspaces configured. Run `olakai monitor init` in a project directory."
|
|
2917
|
+
);
|
|
2918
|
+
} else {
|
|
2919
|
+
for (const ws of workspaces) {
|
|
2920
|
+
const status = ws.configured ? "\u2713 configured" : "\u2717 config missing";
|
|
2921
|
+
console.log(
|
|
2922
|
+
` ${pad(toolLabel(ws.tool), 14)} ${pad(status, 16)} ${ws.workspacePath}`
|
|
2923
|
+
);
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
if (backend?.monitoring.lastActivityAt) {
|
|
2927
|
+
console.log(
|
|
2928
|
+
` Last activity: ${formatRelativeTime(backend.monitoring.lastActivityAt)}`
|
|
2929
|
+
);
|
|
2930
|
+
}
|
|
2931
|
+
console.log();
|
|
2932
|
+
if (!backend) {
|
|
2933
|
+
if (backendError === "not logged in") {
|
|
2934
|
+
console.log(
|
|
2935
|
+
"Run `olakai login` to see personal spend and budget."
|
|
2936
|
+
);
|
|
2937
|
+
} else if (backendError === "session expired") {
|
|
2938
|
+
console.log(
|
|
2939
|
+
"Session expired. Run `olakai login` to refresh your credentials."
|
|
2940
|
+
);
|
|
2941
|
+
} else if (backendError === "unreachable") {
|
|
2942
|
+
console.log("Could not reach Olakai backend.");
|
|
2943
|
+
}
|
|
2944
|
+
return;
|
|
2945
|
+
}
|
|
2946
|
+
const now = /* @__PURE__ */ new Date();
|
|
2947
|
+
const monthName = now.toLocaleString("default", { month: "long" });
|
|
2948
|
+
console.log(sectionHeader(`PERSONAL USAGE (${monthName} MTD)`));
|
|
2949
|
+
if (!backend.identity.found) {
|
|
2950
|
+
console.log(
|
|
2951
|
+
" Not yet recognized in Olakai Coding IQ \u2014 spend data will appear after your first session is processed."
|
|
2952
|
+
);
|
|
2953
|
+
} else {
|
|
2954
|
+
console.log(
|
|
2955
|
+
` Sessions: ${backend.monitoring.recentSessionCount}`
|
|
2956
|
+
);
|
|
2957
|
+
console.log(` Est. cost: ${formatDollars(backend.spend.mtdCents)}`);
|
|
2958
|
+
if (backend.spend.providers.length > 1) {
|
|
2959
|
+
for (const p of backend.spend.providers) {
|
|
2960
|
+
console.log(
|
|
2961
|
+
` ${pad(p.provider, 10)} ${formatDollars(p.mtdCents)}`
|
|
2962
|
+
);
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
console.log();
|
|
2967
|
+
if (backend.budget.found && backend.budget.monthlyLimitCents !== null) {
|
|
2968
|
+
console.log(sectionHeader("BUDGET"));
|
|
2969
|
+
const limitStr = formatDollars(backend.budget.monthlyLimitCents);
|
|
2970
|
+
console.log(` Limit: ${limitStr}/month`);
|
|
2971
|
+
if (backend.budget.usagePct !== null) {
|
|
2972
|
+
const pct = backend.budget.usagePct;
|
|
2973
|
+
const bar = progressBar(pct);
|
|
2974
|
+
const spentStr = formatDollars(backend.spend.mtdCents);
|
|
2975
|
+
console.log(
|
|
2976
|
+
` Used: ${pct.toFixed(1)}% ${bar} (${spentStr} of ${limitStr})`
|
|
2977
|
+
);
|
|
2978
|
+
}
|
|
2979
|
+
if (backend.spend.forecastMonthEndCents !== null && backend.budget.forecastPct !== null) {
|
|
2980
|
+
const confidence = backend.spend.forecastConfidence === "insufficient_data" ? "insufficient data" : backend.spend.forecastConfidence;
|
|
2981
|
+
console.log(
|
|
2982
|
+
` Forecast: ~${formatDollars(backend.spend.forecastMonthEndCents)} by month-end (${confidence} confidence)`
|
|
2983
|
+
);
|
|
2984
|
+
}
|
|
2985
|
+
if (backend.budget.status) {
|
|
2986
|
+
const statusLabel = backend.budget.status === "ok" ? "\u2713 On track" : backend.budget.status === "warning" ? "\u26A0 Approaching limit" : "\u2717 Limit exceeded";
|
|
2987
|
+
console.log(` Status: ${statusLabel}`);
|
|
2988
|
+
}
|
|
2989
|
+
console.log();
|
|
2990
|
+
}
|
|
2991
|
+
if (backend.identity.found) {
|
|
2992
|
+
console.log(sectionHeader("IDENTITY"));
|
|
2993
|
+
const identityLine = backend.identity.displayName ? `${backend.identity.displayName} (${backend.identity.identityCount} ${backend.identity.identityCount === 1 ? "identity" : "identities"})` : `${backend.identity.identityCount} ${backend.identity.identityCount === 1 ? "identity" : "identities"} recognized`;
|
|
2994
|
+
console.log(` Recognized: ${identityLine}`);
|
|
2995
|
+
if (backend.identity.projectNames.length > 0) {
|
|
2996
|
+
console.log(` Projects: ${backend.identity.projectNames.join(", ")}`);
|
|
2997
|
+
}
|
|
2998
|
+
console.log();
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
async function statusCommand2(options) {
|
|
3002
|
+
const workspaces = collectLocalState();
|
|
3003
|
+
let backend = null;
|
|
3004
|
+
let backendError = null;
|
|
3005
|
+
if (!options.workspaceOnly) {
|
|
3006
|
+
const result = await fetchBackendStatus();
|
|
3007
|
+
if (result.error) {
|
|
3008
|
+
backendError = result.error;
|
|
3009
|
+
} else {
|
|
3010
|
+
backend = result.data;
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
if (options.json) {
|
|
3014
|
+
const output = {
|
|
3015
|
+
localMonitor: { workspaces },
|
|
3016
|
+
backend,
|
|
3017
|
+
backendError
|
|
3018
|
+
};
|
|
3019
|
+
console.log(JSON.stringify(output, null, 2));
|
|
3020
|
+
return;
|
|
3021
|
+
}
|
|
3022
|
+
renderHuman(workspaces, backend, backendError);
|
|
3023
|
+
}
|
|
3024
|
+
|
|
2808
3025
|
// src/index.ts
|
|
2809
3026
|
var require2 = createRequire(import.meta.url);
|
|
2810
3027
|
var packageJson = require2("../package.json");
|
|
@@ -2855,6 +3072,9 @@ registerKpisCommand(program);
|
|
|
2855
3072
|
registerCustomDataCommand(program);
|
|
2856
3073
|
registerActivityCommand(program);
|
|
2857
3074
|
registerMonitorCommand(program);
|
|
3075
|
+
program.command("status").description("Show your Olakai monitoring state and personal Coding IQ status").option("--json", "Output as JSON (for machine consumption)").option("--workspace-only", "Show local monitor state only (no backend call)").action(
|
|
3076
|
+
(opts) => statusCommand2(opts)
|
|
3077
|
+
);
|
|
2858
3078
|
registerProfilesCommand(program);
|
|
2859
3079
|
program.parse();
|
|
2860
3080
|
//# sourceMappingURL=index.js.map
|