pokegent 2.0.1 → 2.0.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.
- package/README.md +109 -101
- package/dist/index.js +542 -467
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3398,10 +3398,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3398
3398
|
* @param {string} [path]
|
|
3399
3399
|
* @return {(string|null|Command)}
|
|
3400
3400
|
*/
|
|
3401
|
-
executableDir(
|
|
3402
|
-
if (
|
|
3401
|
+
executableDir(path7) {
|
|
3402
|
+
if (path7 === void 0)
|
|
3403
3403
|
return this._executableDir;
|
|
3404
|
-
this._executableDir =
|
|
3404
|
+
this._executableDir = path7;
|
|
3405
3405
|
return this;
|
|
3406
3406
|
}
|
|
3407
3407
|
/**
|
|
@@ -7721,12 +7721,12 @@ var PathBase = class {
|
|
|
7721
7721
|
/**
|
|
7722
7722
|
* Get the Path object referenced by the string path, resolved from this Path
|
|
7723
7723
|
*/
|
|
7724
|
-
resolve(
|
|
7725
|
-
if (!
|
|
7724
|
+
resolve(path7) {
|
|
7725
|
+
if (!path7) {
|
|
7726
7726
|
return this;
|
|
7727
7727
|
}
|
|
7728
|
-
const rootPath = this.getRootString(
|
|
7729
|
-
const dir =
|
|
7728
|
+
const rootPath = this.getRootString(path7);
|
|
7729
|
+
const dir = path7.substring(rootPath.length);
|
|
7730
7730
|
const dirParts = dir.split(this.splitSep);
|
|
7731
7731
|
const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
|
|
7732
7732
|
return result;
|
|
@@ -8478,8 +8478,8 @@ var PathWin32 = class _PathWin32 extends PathBase {
|
|
|
8478
8478
|
/**
|
|
8479
8479
|
* @internal
|
|
8480
8480
|
*/
|
|
8481
|
-
getRootString(
|
|
8482
|
-
return win32.parse(
|
|
8481
|
+
getRootString(path7) {
|
|
8482
|
+
return win32.parse(path7).root;
|
|
8483
8483
|
}
|
|
8484
8484
|
/**
|
|
8485
8485
|
* @internal
|
|
@@ -8525,8 +8525,8 @@ var PathPosix = class _PathPosix extends PathBase {
|
|
|
8525
8525
|
/**
|
|
8526
8526
|
* @internal
|
|
8527
8527
|
*/
|
|
8528
|
-
getRootString(
|
|
8529
|
-
return
|
|
8528
|
+
getRootString(path7) {
|
|
8529
|
+
return path7.startsWith("/") ? "/" : "";
|
|
8530
8530
|
}
|
|
8531
8531
|
/**
|
|
8532
8532
|
* @internal
|
|
@@ -8575,8 +8575,8 @@ var PathScurryBase = class {
|
|
|
8575
8575
|
*
|
|
8576
8576
|
* @internal
|
|
8577
8577
|
*/
|
|
8578
|
-
constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs:
|
|
8579
|
-
this.#fs = fsFromOption(
|
|
8578
|
+
constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs8 = defaultFS } = {}) {
|
|
8579
|
+
this.#fs = fsFromOption(fs8);
|
|
8580
8580
|
if (cwd instanceof URL || cwd.startsWith("file://")) {
|
|
8581
8581
|
cwd = fileURLToPath(cwd);
|
|
8582
8582
|
}
|
|
@@ -8615,11 +8615,11 @@ var PathScurryBase = class {
|
|
|
8615
8615
|
/**
|
|
8616
8616
|
* Get the depth of a provided path, string, or the cwd
|
|
8617
8617
|
*/
|
|
8618
|
-
depth(
|
|
8619
|
-
if (typeof
|
|
8620
|
-
|
|
8618
|
+
depth(path7 = this.cwd) {
|
|
8619
|
+
if (typeof path7 === "string") {
|
|
8620
|
+
path7 = this.cwd.resolve(path7);
|
|
8621
8621
|
}
|
|
8622
|
-
return
|
|
8622
|
+
return path7.depth();
|
|
8623
8623
|
}
|
|
8624
8624
|
/**
|
|
8625
8625
|
* Return the cache of child entries. Exposed so subclasses can create
|
|
@@ -9106,9 +9106,9 @@ var PathScurryBase = class {
|
|
|
9106
9106
|
process3();
|
|
9107
9107
|
return results;
|
|
9108
9108
|
}
|
|
9109
|
-
chdir(
|
|
9109
|
+
chdir(path7 = this.cwd) {
|
|
9110
9110
|
const oldCwd = this.cwd;
|
|
9111
|
-
this.cwd = typeof
|
|
9111
|
+
this.cwd = typeof path7 === "string" ? this.cwd.resolve(path7) : path7;
|
|
9112
9112
|
this.cwd[setAsCwd](oldCwd);
|
|
9113
9113
|
}
|
|
9114
9114
|
};
|
|
@@ -9134,8 +9134,8 @@ var PathScurryWin32 = class extends PathScurryBase {
|
|
|
9134
9134
|
/**
|
|
9135
9135
|
* @internal
|
|
9136
9136
|
*/
|
|
9137
|
-
newRoot(
|
|
9138
|
-
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
9137
|
+
newRoot(fs8) {
|
|
9138
|
+
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs8 });
|
|
9139
9139
|
}
|
|
9140
9140
|
/**
|
|
9141
9141
|
* Return true if the provided path string is an absolute path
|
|
@@ -9163,8 +9163,8 @@ var PathScurryPosix = class extends PathScurryBase {
|
|
|
9163
9163
|
/**
|
|
9164
9164
|
* @internal
|
|
9165
9165
|
*/
|
|
9166
|
-
newRoot(
|
|
9167
|
-
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
9166
|
+
newRoot(fs8) {
|
|
9167
|
+
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs8 });
|
|
9168
9168
|
}
|
|
9169
9169
|
/**
|
|
9170
9170
|
* Return true if the provided path string is an absolute path
|
|
@@ -9464,8 +9464,8 @@ var MatchRecord = class {
|
|
|
9464
9464
|
}
|
|
9465
9465
|
// match, absolute, ifdir
|
|
9466
9466
|
entries() {
|
|
9467
|
-
return [...this.store.entries()].map(([
|
|
9468
|
-
|
|
9467
|
+
return [...this.store.entries()].map(([path7, n]) => [
|
|
9468
|
+
path7,
|
|
9469
9469
|
!!(n & 2),
|
|
9470
9470
|
!!(n & 1)
|
|
9471
9471
|
]);
|
|
@@ -9670,9 +9670,9 @@ var GlobUtil = class {
|
|
|
9670
9670
|
signal;
|
|
9671
9671
|
maxDepth;
|
|
9672
9672
|
includeChildMatches;
|
|
9673
|
-
constructor(patterns,
|
|
9673
|
+
constructor(patterns, path7, opts) {
|
|
9674
9674
|
this.patterns = patterns;
|
|
9675
|
-
this.path =
|
|
9675
|
+
this.path = path7;
|
|
9676
9676
|
this.opts = opts;
|
|
9677
9677
|
this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
|
|
9678
9678
|
this.includeChildMatches = opts.includeChildMatches !== false;
|
|
@@ -9691,11 +9691,11 @@ var GlobUtil = class {
|
|
|
9691
9691
|
});
|
|
9692
9692
|
}
|
|
9693
9693
|
}
|
|
9694
|
-
#ignored(
|
|
9695
|
-
return this.seen.has(
|
|
9694
|
+
#ignored(path7) {
|
|
9695
|
+
return this.seen.has(path7) || !!this.#ignore?.ignored?.(path7);
|
|
9696
9696
|
}
|
|
9697
|
-
#childrenIgnored(
|
|
9698
|
-
return !!this.#ignore?.childrenIgnored?.(
|
|
9697
|
+
#childrenIgnored(path7) {
|
|
9698
|
+
return !!this.#ignore?.childrenIgnored?.(path7);
|
|
9699
9699
|
}
|
|
9700
9700
|
// backpressure mechanism
|
|
9701
9701
|
pause() {
|
|
@@ -9910,8 +9910,8 @@ var GlobUtil = class {
|
|
|
9910
9910
|
};
|
|
9911
9911
|
var GlobWalker = class extends GlobUtil {
|
|
9912
9912
|
matches = /* @__PURE__ */ new Set();
|
|
9913
|
-
constructor(patterns,
|
|
9914
|
-
super(patterns,
|
|
9913
|
+
constructor(patterns, path7, opts) {
|
|
9914
|
+
super(patterns, path7, opts);
|
|
9915
9915
|
}
|
|
9916
9916
|
matchEmit(e) {
|
|
9917
9917
|
this.matches.add(e);
|
|
@@ -9948,8 +9948,8 @@ var GlobWalker = class extends GlobUtil {
|
|
|
9948
9948
|
};
|
|
9949
9949
|
var GlobStream = class extends GlobUtil {
|
|
9950
9950
|
results;
|
|
9951
|
-
constructor(patterns,
|
|
9952
|
-
super(patterns,
|
|
9951
|
+
constructor(patterns, path7, opts) {
|
|
9952
|
+
super(patterns, path7, opts);
|
|
9953
9953
|
this.results = new Minipass({
|
|
9954
9954
|
signal: this.signal,
|
|
9955
9955
|
objectMode: true
|
|
@@ -10245,26 +10245,26 @@ glob.glob = glob;
|
|
|
10245
10245
|
// src/constants.ts
|
|
10246
10246
|
import os from "os";
|
|
10247
10247
|
var home = os.homedir();
|
|
10248
|
-
var APP_TITLE = "
|
|
10248
|
+
var APP_TITLE = "Agentic";
|
|
10249
10249
|
var VERSION = "2.0.0";
|
|
10250
10250
|
var REFRESH_INTERVAL = 2e3;
|
|
10251
10251
|
var CLI_SIGNATURES = {
|
|
10252
|
-
"
|
|
10253
|
-
"
|
|
10254
|
-
"
|
|
10255
|
-
"
|
|
10256
|
-
"
|
|
10257
|
-
"
|
|
10258
|
-
"
|
|
10259
|
-
"
|
|
10260
|
-
"
|
|
10261
|
-
"
|
|
10262
|
-
"
|
|
10263
|
-
"
|
|
10264
|
-
"
|
|
10265
|
-
"
|
|
10266
|
-
"
|
|
10267
|
-
"
|
|
10252
|
+
"claude-code": { process: ["claude", "claude-code"], config: ["~/.claude", "~/.claude.json", "~/.config/claude"], icon: "\u{1F52E}", pokemonId: 150, pokemonSlug: "mewtwo", pokemonName: "Mewtwo" },
|
|
10253
|
+
"codex": { process: ["codex", "openai-codex"], config: ["~/.codex", "~/.config/codex"], icon: "\u{1F343}", pokemonId: 3, pokemonSlug: "venusaur", pokemonName: "Venusaur" },
|
|
10254
|
+
"copilot": { process: ["copilot", "github-copilot"], config: ["~/.copilot", "~/.config/github-copilot"], icon: "\u{1F422}", pokemonId: 9, pokemonSlug: "blastoise", pokemonName: "Blastoise" },
|
|
10255
|
+
"gemini-cli": { process: ["gemini", "gemini-cli"], config: ["~/.gemini", "~/.config/gemini"], icon: "\u26A1", pokemonId: 25, pokemonSlug: "pikachu", pokemonName: "Pikachu" },
|
|
10256
|
+
"cursor": { process: ["cursor"], config: ["~/.cursor", "~/.cursor-server"], icon: "\u{1F98A}", pokemonId: 133, pokemonSlug: "eevee", pokemonName: "Eevee" },
|
|
10257
|
+
"amp": { process: ["amp", "amp-cli"], config: ["~/.amp", "~/.config/amp"], icon: "\u{1F525}", pokemonId: 6, pokemonSlug: "charizard", pokemonName: "Charizard" },
|
|
10258
|
+
"cline": { process: ["cline"], config: ["~/.cline", "~/.vscode/extensions/saoudrizwan.claude-dev-*"], icon: "\u{1F98E}", pokemonId: 4, pokemonSlug: "charmander", pokemonName: "Charmander" },
|
|
10259
|
+
"roo-code": { process: ["roo", "roo-code"], config: ["~/.roo", "~/.roo-code"], icon: "\u{1F47B}", pokemonId: 94, pokemonSlug: "gengar", pokemonName: "Gengar" },
|
|
10260
|
+
"kilo-code": { process: ["kilo", "kilo-code"], config: ["~/.kilo", "~/.kilo-code"], icon: "\u{1F43B}", pokemonId: 143, pokemonSlug: "snorlax", pokemonName: "Snorlax" },
|
|
10261
|
+
"kiro": { process: ["kiro"], config: ["~/.kiro", "~/.config/kiro"], icon: "\u{1F987}", pokemonId: 41, pokemonSlug: "zubat", pokemonName: "Zubat" },
|
|
10262
|
+
"crush": { process: ["crush"], config: ["~/.crush"], icon: "\u{1F388}", pokemonId: 39, pokemonSlug: "jigglypuff", pokemonName: "Jigglypuff" },
|
|
10263
|
+
"opencode": { process: ["opencode"], config: ["~/.opencode", "~/.config/opencode"], icon: "\u{1F36E}", pokemonId: 132, pokemonSlug: "ditto", pokemonName: "Ditto" },
|
|
10264
|
+
"factory": { process: ["factory", "factory-droid"], config: ["~/.factory-droid"], icon: "\u{1F4AA}", pokemonId: 68, pokemonSlug: "machamp", pokemonName: "Machamp" },
|
|
10265
|
+
"antigravity": { process: ["antigravity", "ag-cli"], config: ["~/.antigravity"], icon: "\u{1F409}", pokemonId: 384, pokemonSlug: "rayquaza", pokemonName: "Rayquaza" },
|
|
10266
|
+
"kimi": { process: ["kimi", "kimi-cli"], config: ["~/.kimi", "~/.config/kimi"], icon: "\u26F5", pokemonId: 131, pokemonSlug: "lapras", pokemonName: "Lapras" },
|
|
10267
|
+
"qwen": { process: ["qwen", "qwen-code"], config: ["~/.qwen", "~/.config/qwen"], icon: "\u{1F409}", pokemonId: 149, pokemonSlug: "dragonite", pokemonName: "Dragonite" }
|
|
10268
10268
|
};
|
|
10269
10269
|
var MCP_SCAN_PATHS = [
|
|
10270
10270
|
{ path: "~/.claude/mcpServers.json", source: "Claude" },
|
|
@@ -10350,7 +10350,7 @@ async function scanClis() {
|
|
|
10350
10350
|
}
|
|
10351
10351
|
}
|
|
10352
10352
|
}
|
|
10353
|
-
results.push({ name, icon: sig.icon, state, pid, cpuPct, memMb, uptimeS, pokemonId: sig.pokemonId });
|
|
10353
|
+
results.push({ name, icon: sig.icon, state, pid, cpuPct, memMb, uptimeS, pokemonId: sig.pokemonId, pokemonSlug: sig.pokemonSlug, pokemonName: sig.pokemonName });
|
|
10354
10354
|
}
|
|
10355
10355
|
return results;
|
|
10356
10356
|
}
|
|
@@ -10627,10 +10627,10 @@ async function walkForMtime(dir, callback) {
|
|
|
10627
10627
|
}
|
|
10628
10628
|
async function getEnvIntegrity() {
|
|
10629
10629
|
let score2 = 1;
|
|
10630
|
-
const { execSync
|
|
10630
|
+
const { execSync } = await import("child_process");
|
|
10631
10631
|
for (const cmd of ENV_CHECKS) {
|
|
10632
10632
|
try {
|
|
10633
|
-
|
|
10633
|
+
execSync(`which ${cmd}`, { stdio: "ignore" });
|
|
10634
10634
|
} catch {
|
|
10635
10635
|
score2 -= 0.15;
|
|
10636
10636
|
}
|
|
@@ -10698,20 +10698,20 @@ function getBadges(clis, mcp, models, burn) {
|
|
|
10698
10698
|
const running = clis.filter((c) => c.state === "RUNNING").length;
|
|
10699
10699
|
const providerCount = getProviderCount(models);
|
|
10700
10700
|
if (mcp.length >= 10)
|
|
10701
|
-
badges.push("\u{1F3C6}
|
|
10701
|
+
badges.push("\u{1F3C6} MCP Master");
|
|
10702
10702
|
if (running >= 3)
|
|
10703
|
-
badges.push("\u{1F984}
|
|
10703
|
+
badges.push("\u{1F984} Power Orchestrator");
|
|
10704
10704
|
if (providerCount >= 3)
|
|
10705
|
-
badges.push("\u{1F9EC} Hybrid
|
|
10705
|
+
badges.push("\u{1F9EC} Hybrid System");
|
|
10706
10706
|
if (burn.tokenVelocity >= 1e4)
|
|
10707
|
-
badges.push("\u{1F525}
|
|
10707
|
+
badges.push("\u{1F525} High Throughput");
|
|
10708
10708
|
if (burn.sessionCount >= 100)
|
|
10709
|
-
badges.push("\u{1F48E}
|
|
10709
|
+
badges.push("\u{1F48E} Session Veteran");
|
|
10710
10710
|
if (agentsPct(clis) > 50 && mcpPct(mcp) > 50 && modelsPct(models) > 50 && burnPct(burn) > 50) {
|
|
10711
|
-
badges.push("\u26A1
|
|
10711
|
+
badges.push("\u26A1 Peak Synergy");
|
|
10712
10712
|
}
|
|
10713
10713
|
if (models.length >= 5)
|
|
10714
|
-
badges.push("\u{1F310}
|
|
10714
|
+
badges.push("\u{1F310} Model Collector");
|
|
10715
10715
|
return badges;
|
|
10716
10716
|
}
|
|
10717
10717
|
function agentsPct(clis) {
|
|
@@ -10731,23 +10731,19 @@ function burnPct(burn) {
|
|
|
10731
10731
|
}
|
|
10732
10732
|
function rarityLabel(score2) {
|
|
10733
10733
|
if (score2 >= 900)
|
|
10734
|
-
return "\u{1F31F}
|
|
10734
|
+
return "\u{1F31F} ELITE ARCHITECT \u2014 Top 1%";
|
|
10735
10735
|
if (score2 >= 750)
|
|
10736
|
-
return "\u{1F48E}
|
|
10736
|
+
return "\u{1F48E} EXPERT SYSTEM \u2014 Top 5%";
|
|
10737
10737
|
if (score2 >= 600)
|
|
10738
|
-
return "\u{1F947}
|
|
10738
|
+
return "\u{1F947} ADVANCED SYSTEM \u2014 Top 15%";
|
|
10739
10739
|
if (score2 >= 400)
|
|
10740
|
-
return "\u{1F948}
|
|
10740
|
+
return "\u{1F948} SYSTEM ADMINISTRATOR \u2014 Top 35%";
|
|
10741
10741
|
if (score2 >= 200)
|
|
10742
|
-
return "\u{1F949}
|
|
10743
|
-
return "\u{1F331}
|
|
10742
|
+
return "\u{1F949} SYSTEM OPERATOR \u2014 Top 60%";
|
|
10743
|
+
return "\u{1F331} SYSTEM INITIALIZED \u2014 everyone starts here";
|
|
10744
10744
|
}
|
|
10745
10745
|
|
|
10746
10746
|
// src/card.ts
|
|
10747
|
-
function bar(pct, width = 20, filled = "\u2588", empty = "\u2591") {
|
|
10748
|
-
const filledN = Math.floor(pct / 100 * width);
|
|
10749
|
-
return filled.repeat(filledN) + empty.repeat(width - filledN);
|
|
10750
|
-
}
|
|
10751
10747
|
function fmtTokens(n) {
|
|
10752
10748
|
if (n >= 1e6)
|
|
10753
10749
|
return `${(n / 1e6).toFixed(1)}M`;
|
|
@@ -10755,500 +10751,540 @@ function fmtTokens(n) {
|
|
|
10755
10751
|
return `${(n / 1e3).toFixed(1)}K`;
|
|
10756
10752
|
return String(n);
|
|
10757
10753
|
}
|
|
10758
|
-
function renderTerminal(clis, mcp, models, burn, scoreResult) {
|
|
10759
|
-
const running = clis.filter((c) => c.state === "RUNNING");
|
|
10760
|
-
const idle = clis.filter((c) => c.state === "IDLE" || c.state === "DETECTED");
|
|
10761
|
-
const agentLines = [];
|
|
10762
|
-
for (const c of [...running, ...idle].slice(0, 6)) {
|
|
10763
|
-
if (c.state === "RUNNING") {
|
|
10764
|
-
agentLines.push(` ${c.icon} ${c.name.padEnd(18)} \u25CF ${c.cpuPct.toFixed(1).padStart(5)}% CPU`);
|
|
10765
|
-
} else {
|
|
10766
|
-
agentLines.push(` ${c.icon} ${c.name.padEnd(18)} \u25CB ${c.state.toLowerCase()}`);
|
|
10767
|
-
}
|
|
10768
|
-
}
|
|
10769
|
-
const remaining = clis.length - agentLines.length;
|
|
10770
|
-
if (remaining > 0)
|
|
10771
|
-
agentLines.push(` \u2026 +${remaining} more`);
|
|
10772
|
-
const modelLines = [];
|
|
10773
|
-
for (const m of models.slice(0, 5)) {
|
|
10774
|
-
const b = bar(m.percentage, 10);
|
|
10775
|
-
modelLines.push(` ${m.name.padEnd(18)} ${b} ${m.percentage.toFixed(1).padStart(5)}%`);
|
|
10776
|
-
}
|
|
10777
|
-
const mcpLines = [];
|
|
10778
|
-
const sortedMcp = [...mcp].sort((a, b) => b.toolCount - a.toolCount);
|
|
10779
|
-
for (const t of sortedMcp.slice(0, 5)) {
|
|
10780
|
-
const tc = t.toolCount ? `[${t.toolCount}]` : "";
|
|
10781
|
-
mcpLines.push(` \u25C6 ${t.name.padEnd(16)} ${tc}`);
|
|
10782
|
-
}
|
|
10783
|
-
const mcpRemaining = mcp.length - 5;
|
|
10784
|
-
if (mcpRemaining > 0)
|
|
10785
|
-
mcpLines.push(` \u2026 +${mcpRemaining} more`);
|
|
10786
|
-
const burnLines = [
|
|
10787
|
-
` PP Tokens ${fmtTokens(burn.totalTokens)}`,
|
|
10788
|
-
` Cost ($) $${burn.estimatedCostUsd.toFixed(2)}/mo`,
|
|
10789
|
-
` PP/min ${fmtTokens(burn.tokenVelocity)}/min`,
|
|
10790
|
-
` Battles ${burn.sessionCount}`,
|
|
10791
|
-
` HP (Intg) ${bar(burn.envIntegrity * 100, 10)} ${Math.round(burn.envIntegrity * 100)}%`
|
|
10792
|
-
];
|
|
10793
|
-
const badgeLines = scoreResult.badges.length > 0 ? scoreResult.badges.map((b) => ` ${b}`) : [" (none yet)"];
|
|
10794
|
-
const rarity = rarityLabel(scoreResult.total);
|
|
10795
|
-
const w = 58;
|
|
10796
|
-
const lines = [
|
|
10797
|
-
`\u250C${"\u2500".repeat(w)}\u2510`,
|
|
10798
|
-
`\u2502 \u25D3 Pok\xE9gent${" ".repeat(w - 20)}${String(scoreResult.total).padStart(4)} pts \u2502`,
|
|
10799
|
-
`\u2502${"\u2501".repeat(w)}\u2502`,
|
|
10800
|
-
`\u2502${" ".repeat(w)}\u2502`
|
|
10801
|
-
];
|
|
10802
|
-
const leftHeader = `\u{1F392} POK\xC9MON TEAM (${running.length} run)`.padEnd(28);
|
|
10803
|
-
const rightHeader = `\u{1F4CA} SPECIES MOVEPOOL`.padEnd(24);
|
|
10804
|
-
lines.push(`\u2502 ${leftHeader} ${rightHeader}\u2502`);
|
|
10805
|
-
const maxRows = Math.max(agentLines.length, modelLines.length, 1);
|
|
10806
|
-
for (let i = 0; i < maxRows; i++) {
|
|
10807
|
-
const left = (agentLines[i] ?? "").padEnd(28);
|
|
10808
|
-
const right = modelLines[i] ?? "";
|
|
10809
|
-
lines.push(`\u2502 ${left} ${right.padEnd(24)}\u2502`);
|
|
10810
|
-
}
|
|
10811
|
-
lines.push(`\u2502${" ".repeat(w)}\u2502`);
|
|
10812
|
-
const totalTools = mcp.reduce((sum, t) => sum + t.toolCount, 0);
|
|
10813
|
-
const leftHeader2 = `\u{1F392} TMs & HMs (${mcp.length})`.padEnd(26);
|
|
10814
|
-
const rightHeader2 = `\u{1F50B} PP BURN (${totalTools} moves)`.padEnd(24);
|
|
10815
|
-
lines.push(`\u2502 ${leftHeader2} ${rightHeader2}\u2502`);
|
|
10816
|
-
const maxRows2 = Math.max(mcpLines.length, burnLines.length, 1);
|
|
10817
|
-
for (let i = 0; i < maxRows2; i++) {
|
|
10818
|
-
const left = (mcpLines[i] ?? "").padEnd(26);
|
|
10819
|
-
const right = burnLines[i] ?? "";
|
|
10820
|
-
lines.push(`\u2502 ${left} ${right.padEnd(24)}\u2502`);
|
|
10821
|
-
}
|
|
10822
|
-
lines.push(`\u2502${" ".repeat(w)}\u2502`);
|
|
10823
|
-
const leftHeader3 = `\u{1F3C6} RARITY`.padEnd(26);
|
|
10824
|
-
const rightHeader3 = `\u{1F3C5} BADGES`.padEnd(24);
|
|
10825
|
-
lines.push(`\u2502 ${leftHeader3} ${rightHeader3}\u2502`);
|
|
10826
|
-
lines.push(`\u2502 ${rarity.padEnd(26)} ${badgeLines[0].padEnd(24)}\u2502`);
|
|
10827
|
-
for (const bl of badgeLines.slice(1)) {
|
|
10828
|
-
lines.push(`\u2502 ${" ".repeat(26)} ${bl.padEnd(24)}\u2502`);
|
|
10829
|
-
}
|
|
10830
|
-
lines.push(`\u2502${" ".repeat(w)}\u2502`);
|
|
10831
|
-
lines.push(`\u2502${"\u2501".repeat(w)}\u2502`);
|
|
10832
|
-
lines.push(`\u2502 pokegent \xB7 npx \xB7 privacy-first (zero network)${" ".repeat(10)}\u2502`);
|
|
10833
|
-
lines.push(`\u2514${"\u2500".repeat(w)}\u2518`);
|
|
10834
|
-
return lines.join("\n");
|
|
10835
|
-
}
|
|
10836
|
-
|
|
10837
|
-
// src/markdown.ts
|
|
10838
|
-
function renderMarkdown(clis, mcp, models, burn, scoreResult) {
|
|
10839
|
-
const running = clis.filter((c) => c.state === "RUNNING");
|
|
10840
|
-
const rarity = rarityLabel(scoreResult.total);
|
|
10841
|
-
const lines = [
|
|
10842
|
-
"```",
|
|
10843
|
-
"\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
|
|
10844
|
-
`\u2502 \u25D3 Pok\xE9gent ${String(scoreResult.total).padStart(4)} pts \u2502`,
|
|
10845
|
-
"\u2502\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2502",
|
|
10846
|
-
"\u2502 \u2502"
|
|
10847
|
-
];
|
|
10848
|
-
const leftHeader = `\u{1F392} POK\xC9MON TEAM (${running.length} run)`.padEnd(26);
|
|
10849
|
-
const rightHeader = `\u{1F4CA} SPECIES MOVEPOOL`.padEnd(23);
|
|
10850
|
-
lines.push(`\u2502 ${leftHeader} \u2502 ${rightHeader} \u2502`);
|
|
10851
|
-
const agentLines = [];
|
|
10852
|
-
for (const c of clis.slice(0, 6)) {
|
|
10853
|
-
if (c.state === "RUNNING") {
|
|
10854
|
-
agentLines.push(`${c.icon} ${c.name.padEnd(12)} \u25CF run`);
|
|
10855
|
-
} else if (c.state === "IDLE" || c.state === "DETECTED") {
|
|
10856
|
-
agentLines.push(`${c.icon} ${c.name.padEnd(12)} \u25CB ${c.state.toLowerCase().slice(0, 4)}`);
|
|
10857
|
-
} else {
|
|
10858
|
-
agentLines.push(`${c.icon} ${c.name.padEnd(12)} \u25CB abs`);
|
|
10859
|
-
}
|
|
10860
|
-
}
|
|
10861
|
-
const modelLines = [];
|
|
10862
|
-
for (const m of models.slice(0, 5)) {
|
|
10863
|
-
const b = bar(m.percentage, 5);
|
|
10864
|
-
modelLines.push(`${m.name.slice(0, 11).padEnd(11)} ${b} ${m.percentage.toFixed(0).padStart(3)}%`);
|
|
10865
|
-
}
|
|
10866
|
-
const maxRows = Math.max(agentLines.length, modelLines.length);
|
|
10867
|
-
for (let i = 0; i < maxRows; i++) {
|
|
10868
|
-
const leftPart = (agentLines[i] ?? "").padEnd(26);
|
|
10869
|
-
const rightPart = (modelLines[i] ?? "").padEnd(23);
|
|
10870
|
-
lines.push(`\u2502 ${leftPart} \u2502 ${rightPart} \u2502`);
|
|
10871
|
-
}
|
|
10872
|
-
lines.push("\u2502 \u2502");
|
|
10873
|
-
const totalTools = mcp.reduce((sum, t) => sum + t.toolCount, 0);
|
|
10874
|
-
const leftHeader2 = `\u{1F392} TMs & HMs (${mcp.length})`.padEnd(26);
|
|
10875
|
-
const rightHeader2 = `\u{1F50B} PP BURN (${totalTools} moves)`.padEnd(23);
|
|
10876
|
-
lines.push(`\u2502 ${leftHeader2} \u2502 ${rightHeader2} \u2502`);
|
|
10877
|
-
const mcpLines = [];
|
|
10878
|
-
const sortedMcp = [...mcp].sort((a, b) => b.toolCount - a.toolCount);
|
|
10879
|
-
for (const t of sortedMcp.slice(0, 5)) {
|
|
10880
|
-
const tc = t.toolCount ? `[${t.toolCount}]` : "";
|
|
10881
|
-
mcpLines.push(`\u25C6 ${t.name.slice(0, 15).padEnd(15)} ${tc}`);
|
|
10882
|
-
}
|
|
10883
|
-
const burnLines = [
|
|
10884
|
-
`PP Tokens ${fmtTokens(burn.totalTokens)}`,
|
|
10885
|
-
`Cost ($) $${burn.estimatedCostUsd.toFixed(2)}/mo`,
|
|
10886
|
-
`PP/min ${fmtTokens(burn.tokenVelocity)}/min`,
|
|
10887
|
-
`Battles ${burn.sessionCount}`
|
|
10888
|
-
];
|
|
10889
|
-
const maxRows2 = Math.max(mcpLines.length, burnLines.length);
|
|
10890
|
-
for (let i = 0; i < maxRows2; i++) {
|
|
10891
|
-
const leftPart = (mcpLines[i] ?? "").padEnd(26);
|
|
10892
|
-
const rightPart = (burnLines[i] ?? "").padEnd(23);
|
|
10893
|
-
lines.push(`\u2502 ${leftPart} \u2502 ${rightPart} \u2502`);
|
|
10894
|
-
}
|
|
10895
|
-
lines.push("\u2502 \u2502");
|
|
10896
|
-
if (scoreResult.badges.length > 0) {
|
|
10897
|
-
lines.push(`\u2502 \u{1F3C6} ${scoreResult.badges.slice(0, 3).join(", ").padEnd(53)} \u2502`);
|
|
10898
|
-
if (scoreResult.badges.length > 3) {
|
|
10899
|
-
lines.push(`\u2502 ${scoreResult.badges.slice(3).join(", ").padEnd(53)} \u2502`);
|
|
10900
|
-
}
|
|
10901
|
-
} else {
|
|
10902
|
-
lines.push(`\u2502 \u{1F3C6} (collect badges by training more Pok\xE9mon)${" ".repeat(13)} \u2502`);
|
|
10903
|
-
}
|
|
10904
|
-
lines.push("\u2502 \u2502");
|
|
10905
|
-
lines.push(`\u2502 ${rarity.padEnd(55)} \u2502`);
|
|
10906
|
-
lines.push("\u2502\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2502");
|
|
10907
|
-
lines.push("\u2502 " + "pokegent \xB7 npx pokegent \xB7 github.com/shafiqimtiaz".padEnd(55) + " \u2502");
|
|
10908
|
-
lines.push("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
|
|
10909
|
-
lines.push("```");
|
|
10910
|
-
return lines.join("\n");
|
|
10911
|
-
}
|
|
10912
10754
|
|
|
10913
10755
|
// src/html.ts
|
|
10914
10756
|
function renderHtml(clis, mcp, models, burn, scoreResult) {
|
|
10915
|
-
const
|
|
10916
|
-
const
|
|
10757
|
+
const clisDetected = clis.filter((c) => c.state !== "ABSENT");
|
|
10758
|
+
const running = clisDetected.filter((c) => c.state === "RUNNING");
|
|
10759
|
+
const idle = clisDetected.filter((c) => c.state === "IDLE" || c.state === "DETECTED");
|
|
10917
10760
|
const rarity = rarityLabel(scoreResult.total);
|
|
10918
|
-
const totalTools = mcp.reduce((sum, t) => sum + t.toolCount, 0);
|
|
10919
10761
|
const sortedMcp = [...mcp].sort((a, b) => b.toolCount - a.toolCount);
|
|
10920
10762
|
return `<!DOCTYPE html>
|
|
10921
10763
|
<html lang="en">
|
|
10922
10764
|
<head>
|
|
10923
10765
|
<meta charset="UTF-8">
|
|
10924
10766
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
10925
|
-
<title>
|
|
10926
|
-
<meta property="og:title" content="
|
|
10927
|
-
<meta property="og:description" content="${running.length} active
|
|
10767
|
+
<title>Agentic \u2014 ${scoreResult.total} PTS</title>
|
|
10768
|
+
<meta property="og:title" content="Agentic \u2014 ${scoreResult.total} PTS">
|
|
10769
|
+
<meta property="og:description" content="${running.length} active agents, ${mcp.length} MCP servers loaded. ${rarity}">
|
|
10928
10770
|
<meta property="og:type" content="website">
|
|
10929
10771
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10930
10772
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
10931
|
-
<link href="https://fonts.googleapis.com/css2?family=
|
|
10773
|
+
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
10932
10774
|
<style>
|
|
10775
|
+
:root {
|
|
10776
|
+
/* Retro \u2014 Color tokens */
|
|
10777
|
+
--black: #000000;
|
|
10778
|
+
--white: #ffffff;
|
|
10779
|
+
--gray-50: #f9fafb;
|
|
10780
|
+
--gray-200: #e2e8f0;
|
|
10781
|
+
--gray-400: #687282;
|
|
10782
|
+
--gray-500: #475565;
|
|
10783
|
+
--gray-900: #111827;
|
|
10784
|
+
--peach: #ffd1ba;
|
|
10785
|
+
--peach-300: #ffb38f;
|
|
10786
|
+
--peach-100: #fff0e8;
|
|
10787
|
+
|
|
10788
|
+
--color-text-primary: var(--gray-500);
|
|
10789
|
+
--color-text-tertiary: var(--gray-900);
|
|
10790
|
+
--color-text-inverse: var(--gray-400);
|
|
10791
|
+
--color-text-on-base: var(--white);
|
|
10792
|
+
|
|
10793
|
+
--color-surface-base: var(--black);
|
|
10794
|
+
--color-surface-muted: var(--white);
|
|
10795
|
+
--color-surface-raised: var(--gray-50);
|
|
10796
|
+
--color-surface-strong: var(--peach);
|
|
10797
|
+
|
|
10798
|
+
--color-border: var(--black);
|
|
10799
|
+
--color-border-subtle: rgba(0,0,0,0.12);
|
|
10800
|
+
--color-focus-ring: var(--gray-900);
|
|
10801
|
+
|
|
10802
|
+
/* Typography */
|
|
10803
|
+
--font-sans: 'Geist', system-ui, -apple-system, sans-serif;
|
|
10804
|
+
--font-mono: 'Geist Mono', ui-monospace, monospace;
|
|
10805
|
+
|
|
10806
|
+
--text-caption: 14px;
|
|
10807
|
+
--text-body-sm: 16px;
|
|
10808
|
+
--text-body-md: 18px;
|
|
10809
|
+
--text-subheading: 20px;
|
|
10810
|
+
--text-heading: 24px;
|
|
10811
|
+
|
|
10812
|
+
--lh-caption: 24px;
|
|
10813
|
+
--lh-body-sm: 24px;
|
|
10814
|
+
--lh-body-md: 24px;
|
|
10815
|
+
--lh-subheading: 24px;
|
|
10816
|
+
--lh-heading: 32px;
|
|
10817
|
+
|
|
10818
|
+
--weight-regular: 400;
|
|
10819
|
+
--weight-medium: 500;
|
|
10820
|
+
--weight-semibold: 600;
|
|
10821
|
+
--weight-bold: 700;
|
|
10822
|
+
|
|
10823
|
+
--tracking-tight: -0.02em;
|
|
10824
|
+
--tracking-normal: 0em;
|
|
10825
|
+
--tracking-wide: 0.04em;
|
|
10826
|
+
|
|
10827
|
+
/* Spacing */
|
|
10828
|
+
--space-1: 4px;
|
|
10829
|
+
--space-2: 8px;
|
|
10830
|
+
--space-3: 12px;
|
|
10831
|
+
--space-4: 16px;
|
|
10832
|
+
--space-5: 20px;
|
|
10833
|
+
--space-6: 24px;
|
|
10834
|
+
--space-7: 32px;
|
|
10835
|
+
--space-8: 40px;
|
|
10836
|
+
|
|
10837
|
+
/* Shape */
|
|
10838
|
+
--radius-xs: 4px;
|
|
10839
|
+
--radius-sm: 6px;
|
|
10840
|
+
--border-width: 2px;
|
|
10841
|
+
|
|
10842
|
+
/* Elevation */
|
|
10843
|
+
--shadow-1: -6px 6px 0 0 #000;
|
|
10844
|
+
}
|
|
10845
|
+
|
|
10933
10846
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
10847
|
+
|
|
10934
10848
|
body {
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10849
|
+
margin: 0;
|
|
10850
|
+
font: var(--weight-regular) var(--text-body-sm)/var(--lh-body-sm) var(--font-sans);
|
|
10851
|
+
color: var(--color-text-primary);
|
|
10852
|
+
background: var(--color-surface-muted);
|
|
10853
|
+
-webkit-font-smoothing: antialiased;
|
|
10854
|
+
text-rendering: optimizeLegibility;
|
|
10938
10855
|
min-height: 100vh;
|
|
10939
10856
|
display: flex;
|
|
10940
10857
|
align-items: center;
|
|
10941
10858
|
justify-content: center;
|
|
10942
|
-
padding:
|
|
10943
|
-
}
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
box-shadow: 4px 4px 0px #0F1012;
|
|
10948
|
-
border-radius: 0px;
|
|
10949
|
-
padding: 2rem;
|
|
10950
|
-
max-width: 800px;
|
|
10859
|
+
padding: var(--space-8) var(--space-4);
|
|
10860
|
+
}
|
|
10861
|
+
|
|
10862
|
+
.retro-card {
|
|
10863
|
+
max-width: 860px;
|
|
10951
10864
|
width: 100%;
|
|
10952
|
-
|
|
10865
|
+
background: var(--white);
|
|
10866
|
+
border: var(--border-width) solid var(--color-border);
|
|
10867
|
+
border-radius: var(--radius-sm);
|
|
10868
|
+
box-shadow: var(--shadow-1);
|
|
10869
|
+
padding: var(--space-6);
|
|
10870
|
+
display: flex;
|
|
10871
|
+
flex-direction: column;
|
|
10872
|
+
gap: var(--space-6);
|
|
10953
10873
|
}
|
|
10954
|
-
|
|
10874
|
+
|
|
10875
|
+
.card-header {
|
|
10955
10876
|
display: flex;
|
|
10956
10877
|
justify-content: space-between;
|
|
10957
10878
|
align-items: center;
|
|
10958
|
-
|
|
10959
|
-
padding-bottom:
|
|
10960
|
-
|
|
10879
|
+
border-bottom: var(--border-width) solid var(--color-border);
|
|
10880
|
+
padding-bottom: var(--space-4);
|
|
10881
|
+
}
|
|
10882
|
+
|
|
10883
|
+
.brand {
|
|
10884
|
+
display: flex;
|
|
10885
|
+
align-items: center;
|
|
10886
|
+
gap: var(--space-3);
|
|
10887
|
+
}
|
|
10888
|
+
|
|
10889
|
+
.logo-glyph {
|
|
10890
|
+
width: 32px;
|
|
10891
|
+
height: 32px;
|
|
10892
|
+
display: grid;
|
|
10893
|
+
place-items: center;
|
|
10894
|
+
background: var(--color-surface-strong);
|
|
10895
|
+
border: var(--border-width) solid var(--color-border);
|
|
10896
|
+
border-radius: var(--radius-sm);
|
|
10897
|
+
font: var(--weight-bold) 18px/1 var(--font-mono);
|
|
10898
|
+
color: var(--color-text-tertiary);
|
|
10899
|
+
}
|
|
10900
|
+
|
|
10901
|
+
.logo-word {
|
|
10902
|
+
font: var(--weight-bold) var(--text-heading)/1 var(--font-sans);
|
|
10903
|
+
letter-spacing: var(--tracking-tight);
|
|
10904
|
+
color: var(--color-text-tertiary);
|
|
10905
|
+
}
|
|
10906
|
+
|
|
10907
|
+
.score-badge {
|
|
10908
|
+
display: flex;
|
|
10909
|
+
align-items: center;
|
|
10910
|
+
border: var(--border-width) solid var(--color-border);
|
|
10911
|
+
border-radius: var(--radius-xs);
|
|
10912
|
+
overflow: hidden;
|
|
10961
10913
|
}
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10914
|
+
|
|
10915
|
+
.score-label {
|
|
10916
|
+
font: var(--weight-bold) 11px/1 var(--font-mono);
|
|
10917
|
+
color: var(--color-text-on-base);
|
|
10918
|
+
background: var(--color-surface-base);
|
|
10919
|
+
padding: 6px var(--space-3);
|
|
10965
10920
|
text-transform: uppercase;
|
|
10921
|
+
letter-spacing: var(--tracking-wide);
|
|
10922
|
+
}
|
|
10923
|
+
|
|
10924
|
+
.score-value {
|
|
10925
|
+
font: var(--weight-bold) var(--text-caption)/1 var(--font-mono);
|
|
10926
|
+
color: var(--color-text-tertiary);
|
|
10927
|
+
padding: 6px var(--space-3);
|
|
10928
|
+
background: var(--white);
|
|
10929
|
+
}
|
|
10930
|
+
|
|
10931
|
+
.rarity-banner {
|
|
10932
|
+
background: var(--color-surface-strong);
|
|
10933
|
+
border: var(--border-width) solid var(--color-border);
|
|
10934
|
+
border-radius: var(--radius-sm);
|
|
10935
|
+
padding: var(--space-3) var(--space-4);
|
|
10966
10936
|
display: flex;
|
|
10967
10937
|
align-items: center;
|
|
10968
|
-
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
color: #3B4CCA; /* GameFreak Blue */
|
|
10973
|
-
font-weight: bold;
|
|
10974
|
-
}
|
|
10975
|
-
.rarity {
|
|
10976
|
-
background: #FFDE00; /* Pikachu Yellow */
|
|
10977
|
-
border: 4px solid #0F1012;
|
|
10978
|
-
box-shadow: 4px 4px 0px #0F1012;
|
|
10979
|
-
padding: 0.75rem;
|
|
10980
|
-
text-align: center;
|
|
10981
|
-
margin-bottom: 2rem;
|
|
10982
|
-
font-size: 0.7rem;
|
|
10938
|
+
justify-content: center;
|
|
10939
|
+
gap: var(--space-2);
|
|
10940
|
+
font: var(--weight-bold) var(--text-body-sm)/1 var(--font-mono);
|
|
10941
|
+
color: var(--color-text-tertiary);
|
|
10983
10942
|
text-transform: uppercase;
|
|
10984
|
-
|
|
10943
|
+
letter-spacing: var(--tracking-wide);
|
|
10985
10944
|
}
|
|
10945
|
+
|
|
10946
|
+
.rarity-banner svg {
|
|
10947
|
+
width: 18px;
|
|
10948
|
+
height: 18px;
|
|
10949
|
+
}
|
|
10950
|
+
|
|
10986
10951
|
.grid {
|
|
10987
10952
|
display: grid;
|
|
10988
10953
|
grid-template-columns: 1fr 1fr;
|
|
10989
|
-
gap:
|
|
10990
|
-
margin-bottom: 1.5rem;
|
|
10954
|
+
gap: var(--space-6);
|
|
10991
10955
|
}
|
|
10956
|
+
|
|
10992
10957
|
@media (max-width: 768px) {
|
|
10993
10958
|
.grid {
|
|
10994
10959
|
grid-template-columns: 1fr;
|
|
10995
10960
|
}
|
|
10996
10961
|
}
|
|
10962
|
+
|
|
10997
10963
|
.section {
|
|
10998
|
-
background:
|
|
10999
|
-
border:
|
|
11000
|
-
|
|
11001
|
-
padding:
|
|
10964
|
+
background: var(--color-surface-raised);
|
|
10965
|
+
border: var(--border-width) solid var(--color-border);
|
|
10966
|
+
border-radius: var(--radius-sm);
|
|
10967
|
+
padding: var(--space-5);
|
|
10968
|
+
display: flex;
|
|
10969
|
+
flex-direction: column;
|
|
10970
|
+
gap: var(--space-4);
|
|
11002
10971
|
}
|
|
10972
|
+
|
|
11003
10973
|
.section h2 {
|
|
11004
|
-
font
|
|
11005
|
-
color:
|
|
11006
|
-
margin-bottom: 1.25rem;
|
|
10974
|
+
font: var(--weight-semibold) var(--text-caption)/1 var(--font-mono);
|
|
10975
|
+
color: var(--color-text-tertiary);
|
|
11007
10976
|
text-transform: uppercase;
|
|
11008
|
-
|
|
11009
|
-
|
|
11010
|
-
|
|
10977
|
+
letter-spacing: var(--tracking-wide);
|
|
10978
|
+
border-bottom: var(--border-width) solid var(--color-border);
|
|
10979
|
+
padding-bottom: var(--space-3);
|
|
10980
|
+
display: flex;
|
|
10981
|
+
align-items: center;
|
|
10982
|
+
gap: var(--space-2);
|
|
10983
|
+
}
|
|
10984
|
+
|
|
10985
|
+
.section h2 svg {
|
|
10986
|
+
width: 16px;
|
|
10987
|
+
height: 16px;
|
|
10988
|
+
color: var(--color-text-tertiary);
|
|
11011
10989
|
}
|
|
10990
|
+
|
|
11012
10991
|
.item {
|
|
11013
10992
|
display: flex;
|
|
11014
10993
|
align-items: center;
|
|
11015
|
-
gap:
|
|
11016
|
-
padding:
|
|
11017
|
-
|
|
11018
|
-
font-size: 0.95rem;
|
|
11019
|
-
font-weight: bold;
|
|
11020
|
-
text-transform: uppercase;
|
|
11021
|
-
border-bottom: 2px dashed #EEEEEE;
|
|
10994
|
+
gap: var(--space-3);
|
|
10995
|
+
padding: var(--space-2) 0;
|
|
10996
|
+
border-bottom: 1.5px dashed var(--color-border-subtle);
|
|
11022
10997
|
}
|
|
11023
|
-
|
|
11024
|
-
|
|
11025
|
-
|
|
11026
|
-
|
|
11027
|
-
|
|
11028
|
-
|
|
10998
|
+
|
|
10999
|
+
.item:last-of-type {
|
|
11000
|
+
border-bottom: none;
|
|
11001
|
+
}
|
|
11002
|
+
|
|
11003
|
+
.icon-container {
|
|
11004
|
+
width: 44px;
|
|
11005
|
+
height: 44px;
|
|
11006
|
+
background: var(--white);
|
|
11007
|
+
border: var(--border-width) solid var(--color-border);
|
|
11008
|
+
border-radius: var(--radius-xs);
|
|
11029
11009
|
display: flex;
|
|
11030
11010
|
align-items: center;
|
|
11031
11011
|
justify-content: center;
|
|
11032
11012
|
flex-shrink: 0;
|
|
11013
|
+
font-size: 1.4rem;
|
|
11033
11014
|
}
|
|
11034
|
-
|
|
11035
|
-
|
|
11036
|
-
|
|
11037
|
-
|
|
11015
|
+
|
|
11016
|
+
.item .name {
|
|
11017
|
+
flex: 1;
|
|
11018
|
+
font: var(--weight-semibold) var(--text-caption)/1.4 var(--font-mono);
|
|
11019
|
+
color: var(--color-text-tertiary);
|
|
11038
11020
|
}
|
|
11039
|
-
|
|
11040
|
-
|
|
11021
|
+
|
|
11022
|
+
.item .state {
|
|
11023
|
+
font: var(--weight-bold) 11px/1 var(--font-mono);
|
|
11024
|
+
padding: 4px var(--space-2);
|
|
11025
|
+
border: var(--border-width) solid var(--color-border);
|
|
11026
|
+
border-radius: var(--radius-xs);
|
|
11027
|
+
text-transform: uppercase;
|
|
11028
|
+
background: var(--white);
|
|
11041
11029
|
}
|
|
11042
|
-
|
|
11043
|
-
|
|
11030
|
+
|
|
11031
|
+
.item .state.running {
|
|
11032
|
+
background: var(--color-surface-strong);
|
|
11033
|
+
color: var(--color-text-tertiary);
|
|
11034
|
+
}
|
|
11035
|
+
|
|
11036
|
+
.item .state.idle {
|
|
11037
|
+
background: var(--peach-100);
|
|
11038
|
+
color: var(--color-text-tertiary);
|
|
11044
11039
|
}
|
|
11045
|
-
|
|
11046
|
-
|
|
11047
|
-
|
|
11040
|
+
|
|
11041
|
+
.item .state.detected {
|
|
11042
|
+
background: var(--white);
|
|
11043
|
+
color: var(--color-text-primary);
|
|
11044
|
+
}
|
|
11045
|
+
|
|
11046
|
+
.item .state.absent {
|
|
11047
|
+
background: var(--white);
|
|
11048
|
+
color: var(--color-text-inverse);
|
|
11049
|
+
border-color: var(--color-border-subtle);
|
|
11048
11050
|
}
|
|
11049
|
-
.item .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
11050
|
-
.item .state { font-size: 0.7rem; padding: 2px 6px; border: 2px solid #0F1012; background: #E2E8F0; }
|
|
11051
|
-
.item .state.running { background: #8B956D; color: #000000; } /* DMG Screen Green Style */
|
|
11052
|
-
.item .state.idle { background: #FFDE00; color: #000000; }
|
|
11053
|
-
.item .state.detected { background: #E2E8F0; color: #555555; }
|
|
11054
|
-
.item .state.absent { background: #FFFFFF; color: #CCCCCC; border-color: #E2E8F0; }
|
|
11055
11051
|
|
|
11056
|
-
|
|
11052
|
+
.more-trigger {
|
|
11053
|
+
cursor: pointer;
|
|
11054
|
+
transition: background 100ms ease;
|
|
11055
|
+
}
|
|
11056
|
+
|
|
11057
|
+
.more-trigger:hover {
|
|
11058
|
+
background: var(--peach-100);
|
|
11059
|
+
}
|
|
11060
|
+
|
|
11061
|
+
/* HP Progress Bar */
|
|
11057
11062
|
.hp-container {
|
|
11058
11063
|
display: flex;
|
|
11059
11064
|
align-items: center;
|
|
11060
|
-
gap:
|
|
11065
|
+
gap: var(--space-2);
|
|
11061
11066
|
width: 100%;
|
|
11062
11067
|
}
|
|
11068
|
+
|
|
11063
11069
|
.hp-label {
|
|
11064
|
-
font
|
|
11065
|
-
|
|
11066
|
-
|
|
11067
|
-
|
|
11070
|
+
font: var(--weight-bold) 11px/1 var(--font-sans);
|
|
11071
|
+
color: var(--color-text-tertiary);
|
|
11072
|
+
border: 1.5px solid var(--color-border);
|
|
11073
|
+
border-radius: var(--radius-xs);
|
|
11074
|
+
padding: 1px var(--space-1);
|
|
11075
|
+
background: var(--color-surface-strong);
|
|
11076
|
+
text-transform: uppercase;
|
|
11068
11077
|
}
|
|
11078
|
+
|
|
11069
11079
|
.bar-container {
|
|
11070
11080
|
flex: 1;
|
|
11071
11081
|
height: 12px;
|
|
11072
|
-
background:
|
|
11073
|
-
border:
|
|
11074
|
-
|
|
11082
|
+
background: var(--white);
|
|
11083
|
+
border: var(--border-width) solid var(--color-border);
|
|
11084
|
+
border-radius: var(--radius-xs);
|
|
11085
|
+
overflow: hidden;
|
|
11086
|
+
position: relative;
|
|
11075
11087
|
}
|
|
11088
|
+
|
|
11076
11089
|
.bar-fill {
|
|
11077
11090
|
height: 100%;
|
|
11078
|
-
background: #
|
|
11079
|
-
|
|
11091
|
+
background: #34d399;
|
|
11092
|
+
border-right: var(--border-width) solid var(--color-border);
|
|
11080
11093
|
}
|
|
11094
|
+
|
|
11081
11095
|
.bar-fill.warning {
|
|
11082
|
-
background: #
|
|
11096
|
+
background: #fbbf24;
|
|
11083
11097
|
}
|
|
11098
|
+
|
|
11084
11099
|
.bar-fill.critical {
|
|
11085
|
-
background: #
|
|
11100
|
+
background: #f87171;
|
|
11101
|
+
}
|
|
11102
|
+
|
|
11103
|
+
.hp-percent {
|
|
11104
|
+
font: var(--weight-bold) 12px/1 var(--font-mono);
|
|
11105
|
+
color: var(--color-text-tertiary);
|
|
11106
|
+
min-width: 32px;
|
|
11107
|
+
text-align: right;
|
|
11086
11108
|
}
|
|
11087
11109
|
|
|
11088
11110
|
.metric {
|
|
11089
11111
|
display: flex;
|
|
11090
11112
|
justify-content: space-between;
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
font
|
|
11113
|
+
align-items: center;
|
|
11114
|
+
padding: var(--space-2) 0;
|
|
11115
|
+
border-bottom: 1.5px dashed var(--color-border-subtle);
|
|
11116
|
+
font: var(--weight-semibold) var(--text-caption)/1.4 var(--font-mono);
|
|
11117
|
+
}
|
|
11118
|
+
|
|
11119
|
+
.metric .label {
|
|
11120
|
+
color: var(--color-text-primary);
|
|
11095
11121
|
text-transform: uppercase;
|
|
11096
|
-
border-bottom: 2px dashed #EEEEEE;
|
|
11097
11122
|
}
|
|
11098
|
-
|
|
11099
|
-
.metric .value {
|
|
11123
|
+
|
|
11124
|
+
.metric .value {
|
|
11125
|
+
color: var(--color-text-tertiary);
|
|
11126
|
+
}
|
|
11100
11127
|
|
|
11101
11128
|
.badges {
|
|
11102
11129
|
display: flex;
|
|
11103
11130
|
flex-wrap: wrap;
|
|
11104
|
-
gap:
|
|
11105
|
-
margin-top: 1.5rem;
|
|
11106
|
-
margin-bottom: 1.5rem;
|
|
11131
|
+
gap: var(--space-2);
|
|
11107
11132
|
}
|
|
11133
|
+
|
|
11108
11134
|
.badge {
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11135
|
+
font: var(--weight-semibold) 11px/1 var(--font-mono);
|
|
11136
|
+
color: var(--color-text-tertiary);
|
|
11137
|
+
background: var(--color-surface-strong);
|
|
11138
|
+
border: var(--border-width) solid var(--color-border);
|
|
11139
|
+
border-radius: var(--radius-xs);
|
|
11140
|
+
padding: var(--space-2) var(--space-3);
|
|
11114
11141
|
text-transform: uppercase;
|
|
11115
|
-
|
|
11116
|
-
font-family: "Press Start 2P", monospace;
|
|
11142
|
+
letter-spacing: var(--tracking-wide);
|
|
11117
11143
|
}
|
|
11118
11144
|
|
|
11119
|
-
/* Dialogue box */
|
|
11120
11145
|
.dialogue-box {
|
|
11121
|
-
background:
|
|
11122
|
-
|
|
11123
|
-
|
|
11124
|
-
|
|
11125
|
-
|
|
11126
|
-
font
|
|
11127
|
-
|
|
11128
|
-
line-height: 1.8;
|
|
11129
|
-
margin-top: 1rem;
|
|
11130
|
-
word-break: break-word;
|
|
11146
|
+
background: var(--color-surface-base);
|
|
11147
|
+
color: var(--color-text-on-base);
|
|
11148
|
+
border: var(--border-width) solid var(--color-border);
|
|
11149
|
+
border-radius: var(--radius-sm);
|
|
11150
|
+
padding: var(--space-4) var(--space-5);
|
|
11151
|
+
font: var(--weight-medium) var(--text-caption)/1.5 var(--font-mono);
|
|
11152
|
+
text-align: center;
|
|
11131
11153
|
}
|
|
11154
|
+
|
|
11132
11155
|
.dialogue-box a {
|
|
11133
|
-
color:
|
|
11134
|
-
text-decoration: none;
|
|
11135
|
-
}
|
|
11136
|
-
.dialogue-box a:hover {
|
|
11156
|
+
color: var(--color-surface-strong);
|
|
11137
11157
|
text-decoration: underline;
|
|
11158
|
+
font-weight: var(--weight-bold);
|
|
11138
11159
|
}
|
|
11139
11160
|
</style>
|
|
11140
11161
|
</head>
|
|
11141
11162
|
<body>
|
|
11142
|
-
<div class="
|
|
11143
|
-
<div class="header">
|
|
11144
|
-
<
|
|
11145
|
-
|
|
11163
|
+
<div class="retro-card">
|
|
11164
|
+
<div class="card-header">
|
|
11165
|
+
<div class="brand">
|
|
11166
|
+
<span class="logo-glyph">A</span>
|
|
11167
|
+
<span class="logo-word">Agentic</span>
|
|
11168
|
+
</div>
|
|
11169
|
+
<div class="score-badge">
|
|
11170
|
+
<span class="score-label">SCORE</span>
|
|
11171
|
+
<span class="score-value">${scoreResult.total} PTS</span>
|
|
11172
|
+
</div>
|
|
11173
|
+
</div>
|
|
11174
|
+
|
|
11175
|
+
<div class="rarity-banner">
|
|
11176
|
+
<i data-lucide="award"></i>
|
|
11177
|
+
<span>${rarity}</span>
|
|
11146
11178
|
</div>
|
|
11147
|
-
|
|
11179
|
+
|
|
11148
11180
|
<div class="grid">
|
|
11181
|
+
<!-- Section: Agents -->
|
|
11149
11182
|
<div class="section">
|
|
11150
|
-
<h2
|
|
11151
|
-
${[...running, ...idle].
|
|
11152
|
-
const
|
|
11153
|
-
const imgHtml = spriteUrl ? `<img class="pokemon-sprite ${c.state.toLowerCase()}" src="${spriteUrl}" alt="${c.name}" width="36" height="36" onload="this.nextElementSibling.style.display='none'" onerror="this.style.display='none'" />` : "";
|
|
11183
|
+
<h2><i data-lucide="terminal"></i> AGENTS (${running.length} active)</h2>
|
|
11184
|
+
${[...running, ...idle].map((c, idx) => {
|
|
11185
|
+
const isHidden = idx >= 6;
|
|
11154
11186
|
return `
|
|
11155
|
-
<div class="item">
|
|
11156
|
-
<div class="
|
|
11157
|
-
|
|
11158
|
-
<span class="icon fallback-icon">${c.icon}</span>
|
|
11187
|
+
<div class="item ${isHidden ? "hidden-agent" : ""}" ${isHidden ? 'style="display: none;"' : ""}>
|
|
11188
|
+
<div class="icon-container">
|
|
11189
|
+
<span class="icon">${c.icon}</span>
|
|
11159
11190
|
</div>
|
|
11160
11191
|
<span class="name">${c.name}</span>
|
|
11161
11192
|
<span class="state ${c.state.toLowerCase()}">${c.state === "RUNNING" ? `${c.cpuPct.toFixed(1)}% CPU` : c.state.toLowerCase()}</span>
|
|
11162
11193
|
</div>
|
|
11163
11194
|
`;
|
|
11164
11195
|
}).join("")}
|
|
11165
|
-
${
|
|
11196
|
+
${clisDetected.length > 6 ? `
|
|
11197
|
+
<div class="item more-trigger" onclick="document.querySelectorAll('.hidden-agent').forEach(el => el.style.display = 'flex'); this.style.display = 'none';">
|
|
11198
|
+
<span class="name" style="color: var(--color-text-inverse)">\u2026 +${clisDetected.length - 6} MORE</span>
|
|
11199
|
+
<span class="state" style="border-color: var(--color-border-subtle); color: var(--color-text-inverse)">Expand</span>
|
|
11200
|
+
</div>
|
|
11201
|
+
` : ""}
|
|
11166
11202
|
</div>
|
|
11203
|
+
|
|
11204
|
+
<!-- Section: Models -->
|
|
11167
11205
|
<div class="section">
|
|
11168
|
-
<h2
|
|
11206
|
+
<h2><i data-lucide="database"></i> AI MODELS</h2>
|
|
11169
11207
|
${models.slice(0, 5).map((m) => {
|
|
11170
11208
|
const barClass = m.percentage > 50 ? "" : m.percentage > 20 ? "warning" : "critical";
|
|
11171
11209
|
return `
|
|
11172
|
-
<div class="item" style="flex-direction:column; align-items:flex-start; gap:
|
|
11173
|
-
<span class="name" style="font-size:
|
|
11210
|
+
<div class="item" style="flex-direction:column; align-items:flex-start; gap: var(--space-2);">
|
|
11211
|
+
<span class="name" style="font-size: var(--text-caption);">${m.name}</span>
|
|
11174
11212
|
<div class="hp-container">
|
|
11175
|
-
<span class="hp-label">HP</span>
|
|
11213
|
+
<span class="hp-label" style="background: var(--color-surface-base); color: var(--white); border-color: var(--color-surface-base);">HP</span>
|
|
11176
11214
|
<div class="bar-container">
|
|
11177
11215
|
<div class="bar-fill ${barClass}" style="width:${m.percentage}%"></div>
|
|
11178
11216
|
</div>
|
|
11179
|
-
<span
|
|
11217
|
+
<span class="hp-percent">${m.percentage.toFixed(0)}%</span>
|
|
11180
11218
|
</div>
|
|
11181
11219
|
</div>
|
|
11182
11220
|
`;
|
|
11183
11221
|
}).join("")}
|
|
11184
11222
|
</div>
|
|
11223
|
+
|
|
11224
|
+
<!-- Section: MCP Servers -->
|
|
11185
11225
|
<div class="section">
|
|
11186
|
-
<h2
|
|
11187
|
-
${sortedMcp.
|
|
11188
|
-
|
|
11189
|
-
|
|
11190
|
-
<
|
|
11226
|
+
<h2><i data-lucide="cpu"></i> MCP SERVERS \xB7 Skills (${mcp.length})</h2>
|
|
11227
|
+
${sortedMcp.map((t, idx) => {
|
|
11228
|
+
const isHidden = idx >= 5;
|
|
11229
|
+
return `
|
|
11230
|
+
<div class="item ${isHidden ? "hidden-mcp" : ""}" ${isHidden ? 'style="display: none;"' : ""}>
|
|
11231
|
+
<span class="name" style="color: var(--color-text-tertiary)">\u25C6 ${t.name}</span>
|
|
11232
|
+
<span class="state" style="border-color: var(--color-border-subtle); color: var(--color-text-primary); font-size: 10px;">[${t.toolCount} SKILLS]</span>
|
|
11233
|
+
</div>
|
|
11234
|
+
`;
|
|
11235
|
+
}).join("")}
|
|
11236
|
+
${mcp.length > 5 ? `
|
|
11237
|
+
<div class="item more-trigger" onclick="document.querySelectorAll('.hidden-mcp').forEach(el => el.style.display = 'flex'); this.style.display = 'none';">
|
|
11238
|
+
<span class="name" style="color: var(--color-text-inverse)">\u2026 +${mcp.length - 5} MORE</span>
|
|
11239
|
+
<span class="state" style="border-color: var(--color-border-subtle); color: var(--color-text-inverse)">Expand</span>
|
|
11191
11240
|
</div>
|
|
11192
|
-
`
|
|
11193
|
-
${mcp.length > 5 ? `<div class="item" style="color:#555555; padding-left: 0.5rem; font-family:'Courier New', monospace;">\u2026 +${mcp.length - 5} MORE</div>` : ""}
|
|
11241
|
+
` : ""}
|
|
11194
11242
|
</div>
|
|
11243
|
+
|
|
11244
|
+
<!-- Section: Token Burn -->
|
|
11195
11245
|
<div class="section">
|
|
11196
|
-
<h2
|
|
11197
|
-
<div class="metric"><span class="label">
|
|
11246
|
+
<h2><i data-lucide="zap"></i> SYSTEM METRICS</h2>
|
|
11247
|
+
<div class="metric"><span class="label">Tokens</span><span class="value">${fmtTokens(burn.totalTokens)}</span></div>
|
|
11198
11248
|
<div class="metric"><span class="label">Cost ($)</span><span class="value">$${burn.estimatedCostUsd.toFixed(2)}/mo</span></div>
|
|
11199
|
-
<div class="metric"><span class="label">
|
|
11200
|
-
<div class="metric"><span class="label">
|
|
11249
|
+
<div class="metric"><span class="label">Token Rate</span><span class="value">${fmtTokens(burn.tokenVelocity)}/min</span></div>
|
|
11250
|
+
<div class="metric"><span class="label">Sessions</span><span class="value">${burn.sessionCount}</span></div>
|
|
11201
11251
|
|
|
11202
|
-
<div class="item" style="flex-direction:column; align-items:flex-start; gap:
|
|
11203
|
-
<span class="label" style="font-
|
|
11204
|
-
<div class="hp-container">
|
|
11205
|
-
<span class="hp-label">HP</span>
|
|
11252
|
+
<div class="item" style="flex-direction:column; align-items:flex-start; gap: var(--space-2); border-bottom: none; padding-bottom: 0;">
|
|
11253
|
+
<span class="label" style="font: var(--weight-bold) 11px/1 var(--font-mono); color: var(--color-text-inverse); text-transform: uppercase;">System Integrity</span>
|
|
11254
|
+
<div class="hp-container" style="margin-top: var(--space-1);">
|
|
11255
|
+
<span class="hp-label" style="background: var(--color-surface-base); color: var(--white); border-color: var(--color-surface-base);">HP</span>
|
|
11206
11256
|
<div class="bar-container">
|
|
11207
11257
|
<div class="bar-fill ${burn.envIntegrity >= 0.8 ? "" : burn.envIntegrity >= 0.5 ? "warning" : "critical"}" style="width:${burn.envIntegrity * 100}%"></div>
|
|
11208
11258
|
</div>
|
|
11209
|
-
<span
|
|
11259
|
+
<span class="hp-percent">${Math.round(burn.envIntegrity * 100)}%</span>
|
|
11210
11260
|
</div>
|
|
11211
11261
|
</div>
|
|
11212
11262
|
</div>
|
|
11213
11263
|
</div>
|
|
11264
|
+
|
|
11265
|
+
<!-- Badges -->
|
|
11214
11266
|
<div class="badges">
|
|
11215
11267
|
${scoreResult.badges.map((b) => `<span class="badge">${b}</span>`).join("")}
|
|
11216
11268
|
</div>
|
|
11269
|
+
|
|
11270
|
+
<!-- Dialogue Box / Footer -->
|
|
11217
11271
|
<div class="dialogue-box">
|
|
11218
|
-
GENERATED BY <a href="https://github.com/shafiqimtiaz/pokegent">
|
|
11272
|
+
GENERATED BY <a href="https://github.com/shafiqimtiaz/pokegent" target="_blank" rel="noopener noreferrer">AGENTIC</a>.<br>
|
|
11219
11273
|
NPX POKEGENT \xB7 PRIVACY-FIRST LOCAL SCAN.
|
|
11220
11274
|
</div>
|
|
11221
11275
|
</div>
|
|
11222
|
-
</body>
|
|
11223
|
-
</html>`;
|
|
11224
|
-
}
|
|
11225
11276
|
|
|
11226
|
-
|
|
11227
|
-
|
|
11228
|
-
|
|
11229
|
-
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
if (platform === "darwin") {
|
|
11233
|
-
execSync("pbcopy", { input: Buffer.from(text) });
|
|
11234
|
-
return true;
|
|
11235
|
-
} else if (platform === "linux") {
|
|
11236
|
-
for (const cmd of ["xsel --clipboard --input", "xclip -selection clipboard", "wl-copy"]) {
|
|
11237
|
-
try {
|
|
11238
|
-
execSync(cmd, { input: Buffer.from(text) });
|
|
11239
|
-
return true;
|
|
11240
|
-
} catch {
|
|
11241
|
-
}
|
|
11277
|
+
<!-- Lucide Icons CDN -->
|
|
11278
|
+
<script src="https://unpkg.com/lucide@0.460.0/dist/umd/lucide.min.js"></script>
|
|
11279
|
+
<script>
|
|
11280
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
11281
|
+
if (window.lucide) {
|
|
11282
|
+
lucide.createIcons({ attrs: { 'stroke-width': 2 } });
|
|
11242
11283
|
}
|
|
11243
|
-
|
|
11244
|
-
|
|
11245
|
-
|
|
11246
|
-
|
|
11247
|
-
}
|
|
11248
|
-
return false;
|
|
11249
|
-
} catch {
|
|
11250
|
-
return false;
|
|
11251
|
-
}
|
|
11284
|
+
});
|
|
11285
|
+
</script>
|
|
11286
|
+
</body>
|
|
11287
|
+
</html>`;
|
|
11252
11288
|
}
|
|
11253
11289
|
|
|
11254
11290
|
// src/demo.ts
|
|
@@ -11273,7 +11309,7 @@ function mockClis() {
|
|
|
11273
11309
|
];
|
|
11274
11310
|
return Object.entries(CLI_SIGNATURES).map(([name, sig], i) => {
|
|
11275
11311
|
const [state, pid, cpuPct, memMb, uptimeS] = states[i % states.length];
|
|
11276
|
-
return { name, icon: sig.icon, state, pid, cpuPct, memMb, uptimeS, pokemonId: sig.pokemonId };
|
|
11312
|
+
return { name, icon: sig.icon, state, pid, cpuPct, memMb, uptimeS, pokemonId: sig.pokemonId, pokemonSlug: sig.pokemonSlug, pokemonName: sig.pokemonName };
|
|
11277
11313
|
});
|
|
11278
11314
|
}
|
|
11279
11315
|
function mockMcp() {
|
|
@@ -11331,8 +11367,11 @@ function mockBurn2() {
|
|
|
11331
11367
|
}
|
|
11332
11368
|
|
|
11333
11369
|
// src/cli.tsx
|
|
11334
|
-
import { useState, useEffect, useCallback } from "react";
|
|
11370
|
+
import { useState, useEffect, useCallback, useRef } from "react";
|
|
11335
11371
|
import { Box, Text, useApp, useInput } from "ink";
|
|
11372
|
+
import fs6 from "fs";
|
|
11373
|
+
import path5 from "path";
|
|
11374
|
+
import os2 from "os";
|
|
11336
11375
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11337
11376
|
function Dashboard({ demo }) {
|
|
11338
11377
|
const { exit } = useApp();
|
|
@@ -11343,7 +11382,11 @@ function Dashboard({ demo }) {
|
|
|
11343
11382
|
const [scoreResult, setScoreResult] = useState(null);
|
|
11344
11383
|
const [scanTime, setScanTime] = useState(0);
|
|
11345
11384
|
const [lastMessage, setLastMessage] = useState("");
|
|
11385
|
+
const scanningRef = useRef(false);
|
|
11346
11386
|
const runScan = useCallback(async () => {
|
|
11387
|
+
if (scanningRef.current)
|
|
11388
|
+
return;
|
|
11389
|
+
scanningRef.current = true;
|
|
11347
11390
|
const t0 = Date.now();
|
|
11348
11391
|
try {
|
|
11349
11392
|
let c, m, mo, b;
|
|
@@ -11369,12 +11412,18 @@ function Dashboard({ demo }) {
|
|
|
11369
11412
|
setScanTime((Date.now() - t0) / 1e3);
|
|
11370
11413
|
} catch (err) {
|
|
11371
11414
|
setLastMessage(`Scan error: ${err}`);
|
|
11415
|
+
} finally {
|
|
11416
|
+
scanningRef.current = false;
|
|
11372
11417
|
}
|
|
11373
11418
|
}, [demo]);
|
|
11374
11419
|
useEffect(() => {
|
|
11375
|
-
|
|
11376
|
-
|
|
11377
|
-
|
|
11420
|
+
let timeoutId;
|
|
11421
|
+
async function tick() {
|
|
11422
|
+
await runScan();
|
|
11423
|
+
timeoutId = setTimeout(tick, REFRESH_INTERVAL);
|
|
11424
|
+
}
|
|
11425
|
+
tick();
|
|
11426
|
+
return () => clearTimeout(timeoutId);
|
|
11378
11427
|
}, [runScan]);
|
|
11379
11428
|
useInput((input, key) => {
|
|
11380
11429
|
if (input === "q")
|
|
@@ -11382,19 +11431,48 @@ function Dashboard({ demo }) {
|
|
|
11382
11431
|
if (input === "r")
|
|
11383
11432
|
runScan();
|
|
11384
11433
|
if (input === "s" && scoreResult && burn) {
|
|
11385
|
-
const md = renderMarkdown(clis, mcp, models, burn, scoreResult);
|
|
11386
|
-
const copied = copyToClipboard(md);
|
|
11387
|
-
setLastMessage(copied ? "\u2713 Card copied to clipboard!" : "Clipboard unavailable");
|
|
11388
|
-
setTimeout(() => setLastMessage(""), 3e3);
|
|
11389
|
-
}
|
|
11390
|
-
if (input === "h" && scoreResult && burn) {
|
|
11391
11434
|
const html = renderHtml(clis, mcp, models, burn, scoreResult);
|
|
11392
|
-
const
|
|
11393
|
-
|
|
11394
|
-
|
|
11435
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11436
|
+
const baseName = `pokegent-${ts}`;
|
|
11437
|
+
const desktopDir = path5.join(os2.homedir(), "Desktop");
|
|
11438
|
+
const htmlPath = path5.join(desktopDir, `${baseName}.html`);
|
|
11439
|
+
try {
|
|
11440
|
+
fs6.writeFileSync(htmlPath, html);
|
|
11441
|
+
setLastMessage(`\u2713 HTML saved \u2192 ~/Desktop/${baseName}.html`);
|
|
11442
|
+
} catch {
|
|
11443
|
+
setLastMessage("\u2717 Failed to write HTML to Desktop");
|
|
11444
|
+
}
|
|
11445
|
+
setTimeout(() => setLastMessage(""), 4e3);
|
|
11395
11446
|
}
|
|
11396
11447
|
});
|
|
11397
|
-
|
|
11448
|
+
if (clis.length === 0) {
|
|
11449
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
|
|
11450
|
+
/* @__PURE__ */ jsx(Box, { justifyContent: "space-between", marginBottom: 1, children: /* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
|
|
11451
|
+
APP_TITLE,
|
|
11452
|
+
" ",
|
|
11453
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
11454
|
+
"v",
|
|
11455
|
+
VERSION
|
|
11456
|
+
] })
|
|
11457
|
+
] }) }),
|
|
11458
|
+
/* @__PURE__ */ jsxs(Box, { marginTop: 2, marginBottom: 2, flexDirection: "column", gap: 1, children: [
|
|
11459
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "\u25D3 Scanning Pok\xE9mon coding ecosystem..." }),
|
|
11460
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "(First live scan takes a few seconds to recursively search local logs & history)" })
|
|
11461
|
+
] }),
|
|
11462
|
+
/* @__PURE__ */ jsxs(Box, { marginTop: 1, justifyContent: "space-between", children: [
|
|
11463
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
11464
|
+
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u25CF LIVE" }),
|
|
11465
|
+
" \u2502 Scan: ",
|
|
11466
|
+
scanTime.toFixed(1),
|
|
11467
|
+
"s \u2502 ",
|
|
11468
|
+
(/* @__PURE__ */ new Date()).toLocaleTimeString()
|
|
11469
|
+
] }),
|
|
11470
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "q quit" })
|
|
11471
|
+
] })
|
|
11472
|
+
] });
|
|
11473
|
+
}
|
|
11474
|
+
const clisDetected = clis.filter((c) => c.state !== "ABSENT");
|
|
11475
|
+
const running = clisDetected.filter((c) => c.state === "RUNNING");
|
|
11398
11476
|
const totalTools = mcp.reduce((sum, t) => sum + t.toolCount, 0);
|
|
11399
11477
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
|
|
11400
11478
|
/* @__PURE__ */ jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [
|
|
@@ -11415,11 +11493,11 @@ function Dashboard({ demo }) {
|
|
|
11415
11493
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "50%", children: [
|
|
11416
11494
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
11417
11495
|
/* @__PURE__ */ jsxs(Text, { bold: true, color: "blue", children: [
|
|
11418
|
-
"\u{1F392}
|
|
11496
|
+
"\u{1F392} AGENTS (",
|
|
11419
11497
|
running.length,
|
|
11420
|
-
"
|
|
11498
|
+
" active)"
|
|
11421
11499
|
] }),
|
|
11422
|
-
|
|
11500
|
+
clisDetected.slice(0, 8).map((c, i) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
11423
11501
|
c.icon,
|
|
11424
11502
|
" ",
|
|
11425
11503
|
c.name.padEnd(20),
|
|
@@ -11430,19 +11508,19 @@ function Dashboard({ demo }) {
|
|
|
11430
11508
|
"% CPU"
|
|
11431
11509
|
] }) : c.state === "IDLE" ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: "\u25CB idle" }) : c.state === "DETECTED" ? /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u25CB detected" }) : /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u25CB absent" })
|
|
11432
11510
|
] }) }, i)),
|
|
11433
|
-
|
|
11511
|
+
clisDetected.length > 8 && /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
11434
11512
|
" \u2026 +",
|
|
11435
|
-
|
|
11513
|
+
clisDetected.length - 8,
|
|
11436
11514
|
" more"
|
|
11437
11515
|
] })
|
|
11438
11516
|
] }),
|
|
11439
11517
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
11440
11518
|
/* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", children: [
|
|
11441
|
-
"\u{1F392}
|
|
11519
|
+
"\u{1F392} MCP SERVERS \xB7 Skills (",
|
|
11442
11520
|
mcp.length,
|
|
11443
|
-
"
|
|
11521
|
+
" servers, ",
|
|
11444
11522
|
totalTools,
|
|
11445
|
-
"
|
|
11523
|
+
" skills)"
|
|
11446
11524
|
] }),
|
|
11447
11525
|
[...mcp].sort((a, b) => b.toolCount - a.toolCount).slice(0, 6).map((t, i) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
11448
11526
|
"\u25C6 ",
|
|
@@ -11454,14 +11532,14 @@ function Dashboard({ demo }) {
|
|
|
11454
11532
|
] }),
|
|
11455
11533
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "50%", children: [
|
|
11456
11534
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
11457
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "magenta", children: "\u{1F4CA}
|
|
11535
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "magenta", children: "\u{1F4CA} MODELS \xB7 Active List" }),
|
|
11458
11536
|
models.slice(0, 6).map((m, i) => {
|
|
11459
11537
|
const filled = Math.floor(m.percentage / 100 * 10);
|
|
11460
|
-
const
|
|
11538
|
+
const bar = "\u2588".repeat(filled) + "\u2591".repeat(10 - filled);
|
|
11461
11539
|
return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
11462
11540
|
m.name.padEnd(18),
|
|
11463
11541
|
" ",
|
|
11464
|
-
|
|
11542
|
+
bar,
|
|
11465
11543
|
" ",
|
|
11466
11544
|
m.percentage.toFixed(1).padStart(5),
|
|
11467
11545
|
"%"
|
|
@@ -11469,9 +11547,9 @@ function Dashboard({ demo }) {
|
|
|
11469
11547
|
})
|
|
11470
11548
|
] }),
|
|
11471
11549
|
burn && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
11472
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "red", children: "\u{1F50B}
|
|
11550
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "red", children: "\u{1F50B} SYSTEM METRICS" }),
|
|
11473
11551
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
11474
|
-
"
|
|
11552
|
+
" Tokens ",
|
|
11475
11553
|
burn.totalTokens >= 1e6 ? `${(burn.totalTokens / 1e6).toFixed(1)}M` : `${(burn.totalTokens / 1e3).toFixed(1)}K`
|
|
11476
11554
|
] }),
|
|
11477
11555
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
@@ -11480,16 +11558,16 @@ function Dashboard({ demo }) {
|
|
|
11480
11558
|
"/mo"
|
|
11481
11559
|
] }),
|
|
11482
11560
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
11483
|
-
"
|
|
11561
|
+
" Token Rate ",
|
|
11484
11562
|
burn.tokenVelocity >= 1e3 ? `${(burn.tokenVelocity / 1e3).toFixed(1)}K` : burn.tokenVelocity,
|
|
11485
11563
|
"/min"
|
|
11486
11564
|
] }),
|
|
11487
11565
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
11488
|
-
"
|
|
11566
|
+
" Sessions ",
|
|
11489
11567
|
burn.sessionCount
|
|
11490
11568
|
] }),
|
|
11491
11569
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
11492
|
-
"
|
|
11570
|
+
" Integrity ",
|
|
11493
11571
|
burn.envIntegrity >= 0.8 ? "\u{1F7E2}" : burn.envIntegrity >= 0.5 ? "\u{1F7E1}" : "\u{1F534}",
|
|
11494
11572
|
" ",
|
|
11495
11573
|
Math.round(burn.envIntegrity * 100),
|
|
@@ -11513,18 +11591,20 @@ function Dashboard({ demo }) {
|
|
|
11513
11591
|
"s \u2502 ",
|
|
11514
11592
|
(/* @__PURE__ */ new Date()).toLocaleTimeString()
|
|
11515
11593
|
] }),
|
|
11516
|
-
/* @__PURE__ */ jsx(Text, { color: "gray", children: "q quit \u2502 r refresh \u2502 s share
|
|
11594
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "q quit \u2502 r refresh \u2502 s share" })
|
|
11517
11595
|
] }),
|
|
11518
11596
|
lastMessage && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "green", children: lastMessage }) })
|
|
11519
11597
|
] });
|
|
11520
11598
|
}
|
|
11521
11599
|
|
|
11522
11600
|
// src/index.ts
|
|
11523
|
-
import
|
|
11601
|
+
import fs7 from "fs/promises";
|
|
11602
|
+
import path6 from "path";
|
|
11603
|
+
import os3 from "os";
|
|
11524
11604
|
var program2 = new Command();
|
|
11525
11605
|
program2.name("pokegent").description("Terminal dashboard that shows your Pok\xE9mon AI coding ecosystem").version(VERSION);
|
|
11526
|
-
program2.option("--demo", "Run with mock data").option("--share", "Generate
|
|
11527
|
-
if (opts.share || opts.
|
|
11606
|
+
program2.option("--demo", "Run with mock data").option("--share", "Generate HTML card on ~/Desktop").option("--json", "Export raw data as JSON").action(async (opts) => {
|
|
11607
|
+
if (opts.share || opts.json) {
|
|
11528
11608
|
await runOneShot(opts);
|
|
11529
11609
|
} else {
|
|
11530
11610
|
const { waitUntilExit } = render(React2.createElement(Dashboard, { demo: opts.demo ?? false }));
|
|
@@ -11551,17 +11631,12 @@ async function runOneShot(opts) {
|
|
|
11551
11631
|
console.log(JSON.stringify({ clis, mcp, models, burn, score: scoreResult }, null, 2));
|
|
11552
11632
|
return;
|
|
11553
11633
|
}
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
|
|
11560
|
-
}
|
|
11561
|
-
const terminalCard = renderTerminal(clis, mcp, models, burn, scoreResult);
|
|
11562
|
-
console.log(terminalCard);
|
|
11563
|
-
const mdCard = renderMarkdown(clis, mcp, models, burn, scoreResult);
|
|
11564
|
-
const copied = copyToClipboard(mdCard);
|
|
11565
|
-
console.log(copied ? "\n\u2713 Markdown card copied to clipboard!" : "\n(clipboard unavailable \u2014 card printed above)");
|
|
11634
|
+
const html = renderHtml(clis, mcp, models, burn, scoreResult);
|
|
11635
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11636
|
+
const baseName = `pokegent-${ts}`;
|
|
11637
|
+
const desktopDir = path6.join(os3.homedir(), "Desktop");
|
|
11638
|
+
const htmlPath = path6.join(desktopDir, `${baseName}.html`);
|
|
11639
|
+
await fs7.writeFile(htmlPath, html);
|
|
11640
|
+
console.log(`\u2713 HTML saved \u2192 ${htmlPath}`);
|
|
11566
11641
|
}
|
|
11567
11642
|
program2.parse();
|