@v1nvn/statusline 0.30.8 → 0.30.9

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.
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { basename, join } from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ //#region src/render/install-record.ts
6
+ var RECORD_FILE = join(".claude", "plugins", "installed_plugins.json");
7
+ var UNREADABLE = "installed_plugins.json unreadable";
8
+ var NONE_USABLE = "no statusline@agentic install with a render.mjs";
9
+ function isObject(value) {
10
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11
+ }
12
+ function ourEntries(home) {
13
+ let raw;
14
+ try {
15
+ raw = readFileSync(join(home, RECORD_FILE), "utf8");
16
+ } catch {
17
+ return null;
18
+ }
19
+ let parsed;
20
+ try {
21
+ parsed = JSON.parse(raw);
22
+ } catch {
23
+ return null;
24
+ }
25
+ const plugins = isObject(parsed) ? parsed.plugins : void 0;
26
+ const ours = isObject(plugins) ? plugins["statusline@agentic"] : null;
27
+ return Array.isArray(ours) ? ours : ours === void 0 ? [] : null;
28
+ }
29
+ function stamp(value) {
30
+ const ms = typeof value === "string" ? Date.parse(value) : NaN;
31
+ return Number.isNaN(ms) ? 0 : ms;
32
+ }
33
+ function isNewer(candidate, incumbent) {
34
+ const updated = stamp(candidate.lastUpdated) - stamp(incumbent.lastUpdated);
35
+ return updated > 0 || updated === 0 && stamp(candidate.installedAt) > stamp(incumbent.installedAt);
36
+ }
37
+ function usable(value) {
38
+ return isObject(value) && typeof value.installPath === "string" && existsSync(join(value.installPath, "render.mjs"));
39
+ }
40
+ function resolveInstall(home) {
41
+ const entries = ourEntries(home);
42
+ if (entries === null) return {
43
+ kind: "unresolved",
44
+ reason: UNREADABLE
45
+ };
46
+ const installed = entries.filter(usable);
47
+ if (installed.length === 0) return {
48
+ kind: "unresolved",
49
+ reason: NONE_USABLE
50
+ };
51
+ const best = installed.reduce((incumbent, candidate) => isNewer(candidate, incumbent) ? candidate : incumbent);
52
+ return {
53
+ installPath: best.installPath,
54
+ kind: "resolved",
55
+ version: typeof best.version === "string" ? best.version : basename(best.installPath)
56
+ };
57
+ }
58
+ //#endregion
59
+ //#region src/render/resolver.ts
60
+ try {
61
+ const record = resolveInstall(process.env.HOME ?? "");
62
+ if (record.kind === "unresolved") {
63
+ process.stderr.write(`${record.reason}\n`);
64
+ process.exit(1);
65
+ }
66
+ await import(pathToFileURL(join(record.installPath, "render.mjs")).href);
67
+ } catch (e) {
68
+ process.stderr.write(`${e.message}\n`);
69
+ process.exit(1);
70
+ }
71
+ //#endregion
72
+ export {};
73
+
74
+ //# sourceMappingURL=resolver.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.mjs","names":[],"sources":["../src/render/install-record.ts","../src/render/resolver.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { basename, join } from 'node:path';\n\nexport type InstallRecord =\n | {\n readonly installPath: string;\n readonly kind: 'resolved';\n readonly version: string;\n }\n | { readonly kind: 'unresolved'; readonly reason: string };\n\ninterface Entry {\n readonly installedAt?: unknown;\n readonly installPath: string;\n readonly lastUpdated?: unknown;\n readonly version?: unknown;\n}\n\nconst RECORD_FILE = join('.claude', 'plugins', 'installed_plugins.json');\nconst UNREADABLE = 'installed_plugins.json unreadable';\nconst NONE_USABLE = 'no statusline@agentic install with a render.mjs';\n\n// Stays node-built-ins-only: the render pass bundles this module into the\n// standalone resolver while the CLI imports it in-process.\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n// Claude Code's own install record (v2 shape): the plugin-update path\n// rewrites it, so the entries name the renderers updates have landed.\nfunction ourEntries(home: string): null | readonly unknown[] {\n let raw: string;\n try {\n raw = readFileSync(join(home, RECORD_FILE), 'utf8');\n } catch {\n return null;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n const plugins = isObject(parsed) ? parsed.plugins : undefined;\n const ours = isObject(plugins) ? plugins['statusline@agentic'] : null;\n return Array.isArray(ours) ? ours : ours === undefined ? [] : null;\n}\n\nfunction stamp(value: unknown): number {\n const ms = typeof value === 'string' ? Date.parse(value) : Number.NaN;\n return Number.isNaN(ms) ? 0 : ms;\n}\n\nfunction isNewer(candidate: Entry, incumbent: Entry): boolean {\n const updated = stamp(candidate.lastUpdated) - stamp(incumbent.lastUpdated);\n return (\n updated > 0 ||\n (updated === 0 &&\n stamp(candidate.installedAt) > stamp(incumbent.installedAt))\n );\n}\n\nfunction usable(value: unknown): value is Entry {\n return (\n isObject(value) &&\n typeof value.installPath === 'string' &&\n existsSync(join(value.installPath, 'render.mjs'))\n );\n}\n\nexport function resolveInstall(home: string): InstallRecord {\n const entries = ourEntries(home);\n if (entries === null) {\n return { kind: 'unresolved', reason: UNREADABLE };\n }\n const installed = entries.filter(usable);\n if (installed.length === 0) {\n return { kind: 'unresolved', reason: NONE_USABLE };\n }\n const best = installed.reduce((incumbent, candidate) =>\n isNewer(candidate, incumbent) ? candidate : incumbent,\n );\n return {\n installPath: best.installPath,\n kind: 'resolved',\n version:\n typeof best.version === 'string'\n ? best.version\n : basename(best.installPath),\n };\n}\n","import { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { resolveInstall } from './install-record.js';\n\n// The deployed data-dir entry the settings keys spawn. The renderer\n// self-invokes at module scope on argv and stdin, so an in-process dynamic\n// import with both intact is the whole wrapper; the exits land only on paths\n// that wrote nothing to stdout.\ntry {\n const record = resolveInstall(process.env.HOME ?? '');\n if (record.kind === 'unresolved') {\n process.stderr.write(`${record.reason}\\n`);\n // eslint-disable-next-line n/no-process-exit\n process.exit(1);\n }\n await import(pathToFileURL(join(record.installPath, 'render.mjs')).href);\n} catch (e) {\n process.stderr.write(`${(e as Error).message}\\n`);\n // eslint-disable-next-line n/no-process-exit\n process.exit(1);\n}\n"],"mappings":";;;;;AAkBA,IAAM,cAAc,KAAK,WAAW,WAAW,wBAAwB;AACvE,IAAM,aAAa;AACnB,IAAM,cAAc;AAIpB,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAIA,SAAS,WAAW,MAAyC;CAC3D,IAAI;CACJ,IAAI;EACF,MAAM,aAAa,KAAK,MAAM,WAAW,GAAG,MAAM;CACpD,QAAQ;EACN,OAAO;CACT;CACA,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,GAAG;CACzB,QAAQ;EACN,OAAO;CACT;CACA,MAAM,UAAU,SAAS,MAAM,IAAI,OAAO,UAAU,KAAA;CACpD,MAAM,OAAO,SAAS,OAAO,IAAI,QAAQ,wBAAwB;CACjE,OAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,SAAS,KAAA,IAAY,CAAC,IAAI;AAChE;AAEA,SAAS,MAAM,OAAwB;CACrC,MAAM,KAAK,OAAO,UAAU,WAAW,KAAK,MAAM,KAAK,IAAI;CAC3D,OAAO,OAAO,MAAM,EAAE,IAAI,IAAI;AAChC;AAEA,SAAS,QAAQ,WAAkB,WAA2B;CAC5D,MAAM,UAAU,MAAM,UAAU,WAAW,IAAI,MAAM,UAAU,WAAW;CAC1E,OACE,UAAU,KACT,YAAY,KACX,MAAM,UAAU,WAAW,IAAI,MAAM,UAAU,WAAW;AAEhE;AAEA,SAAS,OAAO,OAAgC;CAC9C,OACE,SAAS,KAAK,KACd,OAAO,MAAM,gBAAgB,YAC7B,WAAW,KAAK,MAAM,aAAa,YAAY,CAAC;AAEpD;AAEA,SAAgB,eAAe,MAA6B;CAC1D,MAAM,UAAU,WAAW,IAAI;CAC/B,IAAI,YAAY,MACd,OAAO;EAAE,MAAM;EAAc,QAAQ;CAAW;CAElD,MAAM,YAAY,QAAQ,OAAO,MAAM;CACvC,IAAI,UAAU,WAAW,GACvB,OAAO;EAAE,MAAM;EAAc,QAAQ;CAAY;CAEnD,MAAM,OAAO,UAAU,QAAQ,WAAW,cACxC,QAAQ,WAAW,SAAS,IAAI,YAAY,SAC9C;CACA,OAAO;EACL,aAAa,KAAK;EAClB,MAAM;EACN,SACE,OAAO,KAAK,YAAY,WACpB,KAAK,UACL,SAAS,KAAK,WAAW;CACjC;AACF;;;ACjFA,IAAI;CACF,MAAM,SAAS,eAAe,QAAQ,IAAI,QAAQ,EAAE;CACpD,IAAI,OAAO,SAAS,cAAc;EAChC,QAAQ,OAAO,MAAM,GAAG,OAAO,OAAO,GAAG;EAEzC,QAAQ,KAAK,CAAC;CAChB;CACA,MAAM,OAAO,cAAc,KAAK,OAAO,aAAa,YAAY,CAAC,CAAC,CAAC;AACrE,SAAS,GAAG;CACV,QAAQ,OAAO,MAAM,GAAI,EAAY,QAAQ,GAAG;CAEhD,QAAQ,KAAK,CAAC;AAChB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v1nvn/statusline",
3
- "version": "0.30.8",
3
+ "version": "0.30.9",
4
4
  "description": "Browse statusline variants and configure the live status line and agent panel — the statusline CLI behind the statusline plugin.",
5
5
  "type": "module",
6
6
  "bin": "dist/index.js",
@@ -35,7 +35,7 @@
35
35
  "node": ">=22"
36
36
  },
37
37
  "dependencies": {
38
- "@v1nvn/agentic-core": "^0.30.8",
38
+ "@v1nvn/agentic-core": "^0.30.9",
39
39
  "commander": "^15.0.0"
40
40
  },
41
41
  "devDependencies": {