pokegent 2.0.2 → 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/dist/index.js +502 -463
- 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);
|
|
11011
10983
|
}
|
|
10984
|
+
|
|
10985
|
+
.section h2 svg {
|
|
10986
|
+
width: 16px;
|
|
10987
|
+
height: 16px;
|
|
10988
|
+
color: var(--color-text-tertiary);
|
|
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;
|
|
11014
|
+
}
|
|
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);
|
|
11020
|
+
}
|
|
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);
|
|
11029
|
+
}
|
|
11030
|
+
|
|
11031
|
+
.item .state.running {
|
|
11032
|
+
background: var(--color-surface-strong);
|
|
11033
|
+
color: var(--color-text-tertiary);
|
|
11033
11034
|
}
|
|
11034
|
-
|
|
11035
|
-
|
|
11036
|
-
|
|
11037
|
-
|
|
11035
|
+
|
|
11036
|
+
.item .state.idle {
|
|
11037
|
+
background: var(--peach-100);
|
|
11038
|
+
color: var(--color-text-tertiary);
|
|
11038
11039
|
}
|
|
11039
|
-
|
|
11040
|
-
|
|
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);
|
|
11041
11050
|
}
|
|
11042
|
-
|
|
11043
|
-
|
|
11051
|
+
|
|
11052
|
+
.more-trigger {
|
|
11053
|
+
cursor: pointer;
|
|
11054
|
+
transition: background 100ms ease;
|
|
11044
11055
|
}
|
|
11045
|
-
|
|
11046
|
-
|
|
11047
|
-
|
|
11056
|
+
|
|
11057
|
+
.more-trigger:hover {
|
|
11058
|
+
background: var(--peach-100);
|
|
11048
11059
|
}
|
|
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
11060
|
|
|
11056
|
-
/* HP
|
|
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() {
|
|
@@ -11333,6 +11369,9 @@ function mockBurn2() {
|
|
|
11333
11369
|
// src/cli.tsx
|
|
11334
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();
|
|
@@ -11392,16 +11431,18 @@ function Dashboard({ demo }) {
|
|
|
11392
11431
|
if (input === "r")
|
|
11393
11432
|
runScan();
|
|
11394
11433
|
if (input === "s" && scoreResult && burn) {
|
|
11395
|
-
const md = renderMarkdown(clis, mcp, models, burn, scoreResult);
|
|
11396
|
-
const copied = copyToClipboard(md);
|
|
11397
|
-
setLastMessage(copied ? "\u2713 Card copied to clipboard!" : "Clipboard unavailable");
|
|
11398
|
-
setTimeout(() => setLastMessage(""), 3e3);
|
|
11399
|
-
}
|
|
11400
|
-
if (input === "h" && scoreResult && burn) {
|
|
11401
11434
|
const html = renderHtml(clis, mcp, models, burn, scoreResult);
|
|
11402
|
-
const
|
|
11403
|
-
|
|
11404
|
-
|
|
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);
|
|
11405
11446
|
}
|
|
11406
11447
|
});
|
|
11407
11448
|
if (clis.length === 0) {
|
|
@@ -11430,7 +11471,8 @@ function Dashboard({ demo }) {
|
|
|
11430
11471
|
] })
|
|
11431
11472
|
] });
|
|
11432
11473
|
}
|
|
11433
|
-
const
|
|
11474
|
+
const clisDetected = clis.filter((c) => c.state !== "ABSENT");
|
|
11475
|
+
const running = clisDetected.filter((c) => c.state === "RUNNING");
|
|
11434
11476
|
const totalTools = mcp.reduce((sum, t) => sum + t.toolCount, 0);
|
|
11435
11477
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
|
|
11436
11478
|
/* @__PURE__ */ jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [
|
|
@@ -11451,11 +11493,11 @@ function Dashboard({ demo }) {
|
|
|
11451
11493
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "50%", children: [
|
|
11452
11494
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
11453
11495
|
/* @__PURE__ */ jsxs(Text, { bold: true, color: "blue", children: [
|
|
11454
|
-
"\u{1F392}
|
|
11496
|
+
"\u{1F392} AGENTS (",
|
|
11455
11497
|
running.length,
|
|
11456
|
-
"
|
|
11498
|
+
" active)"
|
|
11457
11499
|
] }),
|
|
11458
|
-
|
|
11500
|
+
clisDetected.slice(0, 8).map((c, i) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
11459
11501
|
c.icon,
|
|
11460
11502
|
" ",
|
|
11461
11503
|
c.name.padEnd(20),
|
|
@@ -11466,19 +11508,19 @@ function Dashboard({ demo }) {
|
|
|
11466
11508
|
"% CPU"
|
|
11467
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" })
|
|
11468
11510
|
] }) }, i)),
|
|
11469
|
-
|
|
11511
|
+
clisDetected.length > 8 && /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
11470
11512
|
" \u2026 +",
|
|
11471
|
-
|
|
11513
|
+
clisDetected.length - 8,
|
|
11472
11514
|
" more"
|
|
11473
11515
|
] })
|
|
11474
11516
|
] }),
|
|
11475
11517
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
11476
11518
|
/* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", children: [
|
|
11477
|
-
"\u{1F392}
|
|
11519
|
+
"\u{1F392} MCP SERVERS \xB7 Skills (",
|
|
11478
11520
|
mcp.length,
|
|
11479
|
-
"
|
|
11521
|
+
" servers, ",
|
|
11480
11522
|
totalTools,
|
|
11481
|
-
"
|
|
11523
|
+
" skills)"
|
|
11482
11524
|
] }),
|
|
11483
11525
|
[...mcp].sort((a, b) => b.toolCount - a.toolCount).slice(0, 6).map((t, i) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
11484
11526
|
"\u25C6 ",
|
|
@@ -11490,14 +11532,14 @@ function Dashboard({ demo }) {
|
|
|
11490
11532
|
] }),
|
|
11491
11533
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "50%", children: [
|
|
11492
11534
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
11493
|
-
/* @__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" }),
|
|
11494
11536
|
models.slice(0, 6).map((m, i) => {
|
|
11495
11537
|
const filled = Math.floor(m.percentage / 100 * 10);
|
|
11496
|
-
const
|
|
11538
|
+
const bar = "\u2588".repeat(filled) + "\u2591".repeat(10 - filled);
|
|
11497
11539
|
return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
11498
11540
|
m.name.padEnd(18),
|
|
11499
11541
|
" ",
|
|
11500
|
-
|
|
11542
|
+
bar,
|
|
11501
11543
|
" ",
|
|
11502
11544
|
m.percentage.toFixed(1).padStart(5),
|
|
11503
11545
|
"%"
|
|
@@ -11505,9 +11547,9 @@ function Dashboard({ demo }) {
|
|
|
11505
11547
|
})
|
|
11506
11548
|
] }),
|
|
11507
11549
|
burn && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
11508
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "red", children: "\u{1F50B}
|
|
11550
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "red", children: "\u{1F50B} SYSTEM METRICS" }),
|
|
11509
11551
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
11510
|
-
"
|
|
11552
|
+
" Tokens ",
|
|
11511
11553
|
burn.totalTokens >= 1e6 ? `${(burn.totalTokens / 1e6).toFixed(1)}M` : `${(burn.totalTokens / 1e3).toFixed(1)}K`
|
|
11512
11554
|
] }),
|
|
11513
11555
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
@@ -11516,16 +11558,16 @@ function Dashboard({ demo }) {
|
|
|
11516
11558
|
"/mo"
|
|
11517
11559
|
] }),
|
|
11518
11560
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
11519
|
-
"
|
|
11561
|
+
" Token Rate ",
|
|
11520
11562
|
burn.tokenVelocity >= 1e3 ? `${(burn.tokenVelocity / 1e3).toFixed(1)}K` : burn.tokenVelocity,
|
|
11521
11563
|
"/min"
|
|
11522
11564
|
] }),
|
|
11523
11565
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
11524
|
-
"
|
|
11566
|
+
" Sessions ",
|
|
11525
11567
|
burn.sessionCount
|
|
11526
11568
|
] }),
|
|
11527
11569
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
11528
|
-
"
|
|
11570
|
+
" Integrity ",
|
|
11529
11571
|
burn.envIntegrity >= 0.8 ? "\u{1F7E2}" : burn.envIntegrity >= 0.5 ? "\u{1F7E1}" : "\u{1F534}",
|
|
11530
11572
|
" ",
|
|
11531
11573
|
Math.round(burn.envIntegrity * 100),
|
|
@@ -11549,18 +11591,20 @@ function Dashboard({ demo }) {
|
|
|
11549
11591
|
"s \u2502 ",
|
|
11550
11592
|
(/* @__PURE__ */ new Date()).toLocaleTimeString()
|
|
11551
11593
|
] }),
|
|
11552
|
-
/* @__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" })
|
|
11553
11595
|
] }),
|
|
11554
11596
|
lastMessage && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "green", children: lastMessage }) })
|
|
11555
11597
|
] });
|
|
11556
11598
|
}
|
|
11557
11599
|
|
|
11558
11600
|
// src/index.ts
|
|
11559
|
-
import
|
|
11601
|
+
import fs7 from "fs/promises";
|
|
11602
|
+
import path6 from "path";
|
|
11603
|
+
import os3 from "os";
|
|
11560
11604
|
var program2 = new Command();
|
|
11561
11605
|
program2.name("pokegent").description("Terminal dashboard that shows your Pok\xE9mon AI coding ecosystem").version(VERSION);
|
|
11562
|
-
program2.option("--demo", "Run with mock data").option("--share", "Generate
|
|
11563
|
-
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) {
|
|
11564
11608
|
await runOneShot(opts);
|
|
11565
11609
|
} else {
|
|
11566
11610
|
const { waitUntilExit } = render(React2.createElement(Dashboard, { demo: opts.demo ?? false }));
|
|
@@ -11587,17 +11631,12 @@ async function runOneShot(opts) {
|
|
|
11587
11631
|
console.log(JSON.stringify({ clis, mcp, models, burn, score: scoreResult }, null, 2));
|
|
11588
11632
|
return;
|
|
11589
11633
|
}
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
}
|
|
11597
|
-
const terminalCard = renderTerminal(clis, mcp, models, burn, scoreResult);
|
|
11598
|
-
console.log(terminalCard);
|
|
11599
|
-
const mdCard = renderMarkdown(clis, mcp, models, burn, scoreResult);
|
|
11600
|
-
const copied = copyToClipboard(mdCard);
|
|
11601
|
-
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}`);
|
|
11602
11641
|
}
|
|
11603
11642
|
program2.parse();
|