@stzhu/skills 0.1.0 → 0.1.2

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.
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { n as app, t as buildContext } from "./context-SQBI_fVn.mjs";
2
+ import { n as app, t as buildContext } from "./context-BQaSQqU1.mjs";
3
3
  import { proposeCompletions } from "@stricli/core";
4
-
5
4
  //#region src/bin/bash-complete.ts
6
5
  const inputs = process.argv.slice(3);
7
6
  if (process.env["COMP_LINE"]?.endsWith(" ")) inputs.push("");
@@ -9,6 +8,5 @@ await proposeCompletions(app, inputs, buildContext(process));
9
8
  try {
10
9
  for (const { completion } of await proposeCompletions(app, inputs, buildContext(process))) process.stdout.write(`${completion}\n`);
11
10
  } catch {}
12
-
13
11
  //#endregion
14
- export { };
12
+ export {};
package/dist/cli.mjs CHANGED
@@ -1,9 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { n as app, t as buildContext } from "./context-SQBI_fVn.mjs";
2
+ import { n as app, t as buildContext } from "./context-BQaSQqU1.mjs";
3
3
  import { run } from "@stricli/core";
4
-
5
4
  //#region src/bin/cli.ts
6
5
  await run(app, process.argv.slice(2), buildContext(process));
7
-
8
6
  //#endregion
9
- export { };
7
+ export {};
@@ -4,64 +4,52 @@ import fs from "node:fs";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { findWorkspacesRoot } from "find-workspaces";
7
-
8
7
  //#region package.json
9
- var version = "0.1.0";
8
+ var version = "0.1.2";
10
9
  var description = "Skills CLI";
11
- var bin = {
12
- "__stz-skills_bash_complete": "dist/bash-complete.mjs",
13
- "stz-skills": "dist/cli.mjs"
14
- };
15
-
16
- //#endregion
17
- //#region src/commands/agent-logbook/commands.ts
18
- const statsCommand = buildCommand({
19
- loader: async () => {
20
- const { stats } = await import("./stats-RlcmzM9e.mjs");
21
- return stats;
22
- },
23
- parameters: {
24
- flags: { agent: {
25
- kind: "enum",
26
- brief: "The agent to get stats for",
27
- values: ["claudecode", "geminicli"]
28
- } },
29
- positional: {
30
- kind: "tuple",
31
- parameters: [{
32
- parse: String,
33
- brief: "The session ID to get stats for"
34
- }]
35
- }
36
- },
37
- docs: { brief: "Agent logbook stats command" }
38
- });
39
- const validateCommand = buildCommand({
40
- loader: async () => {
41
- const { validate } = await import("./validate-D3AdsB3Q.mjs");
42
- return validate;
43
- },
44
- parameters: { positional: {
45
- kind: "tuple",
46
- parameters: [{
47
- parse: String,
48
- brief: "The target file or directory to validate frontmatter for",
49
- optional: true
50
- }]
51
- } },
52
- docs: { brief: "Agent logbook validate command" }
53
- });
10
+ var bin = { "stz-skills": "dist/cli.mjs" };
54
11
  const agentLogbookRoutes = buildRouteMap({
55
12
  routes: {
56
- stats: statsCommand,
57
- validate: validateCommand
13
+ stats: buildCommand({
14
+ loader: async () => {
15
+ const { stats } = await import("./stats-Bq8rF7sI.mjs");
16
+ return stats;
17
+ },
18
+ parameters: {
19
+ flags: { agent: {
20
+ kind: "enum",
21
+ brief: "The agent to get stats for",
22
+ values: ["claudecode", "geminicli"]
23
+ } },
24
+ positional: {
25
+ kind: "tuple",
26
+ parameters: [{
27
+ parse: String,
28
+ brief: "The session ID to get stats for"
29
+ }]
30
+ }
31
+ },
32
+ docs: { brief: "Agent logbook stats command" }
33
+ }),
34
+ validate: buildCommand({
35
+ loader: async () => {
36
+ const { validate } = await import("./validate-CMKdK9Xg.mjs");
37
+ return validate;
38
+ },
39
+ parameters: { positional: {
40
+ kind: "tuple",
41
+ parameters: [{
42
+ parse: String,
43
+ brief: "The target file or directory to validate frontmatter for",
44
+ optional: true
45
+ }]
46
+ } },
47
+ docs: { brief: "Agent logbook validate command" }
48
+ })
58
49
  },
59
50
  docs: { brief: "Agent logbook commands" }
60
51
  });
61
-
62
- //#endregion
63
- //#region src/app.ts
64
- const routes = buildRouteMap({
52
+ const app = buildApplication(buildRouteMap({
65
53
  routes: {
66
54
  "agent-logbook": agentLogbookRoutes,
67
55
  install: buildInstallCommand("stz-skills", { bash: "__stz-skills_bash_complete" }),
@@ -74,8 +62,7 @@ const routes = buildRouteMap({
74
62
  uninstall: true
75
63
  }
76
64
  }
77
- });
78
- const app = buildApplication(routes, {
65
+ }), {
79
66
  name: (() => {
80
67
  const name = Object.keys(bin).find((key) => !key.startsWith("__"));
81
68
  if (!name) throw new Error("Name not found");
@@ -83,7 +70,6 @@ const app = buildApplication(routes, {
83
70
  })(),
84
71
  versionInfo: { currentVersion: version }
85
72
  });
86
-
87
73
  //#endregion
88
74
  //#region src/context.ts
89
75
  function buildContext(process) {
@@ -97,6 +83,5 @@ function buildContext(process) {
97
83
  workspacesRoot: workspacesRoot.location
98
84
  };
99
85
  }
100
-
101
86
  //#endregion
102
- export { app as n, buildContext as t };
87
+ export { app as n, buildContext as t };
@@ -2,7 +2,6 @@ import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import readline from "node:readline";
5
-
6
5
  //#region src/util/defineCommandFunction.ts
7
6
  /**
8
7
  * Identity wrapper for strongly typed command implementations.
@@ -13,7 +12,6 @@ import readline from "node:readline";
13
12
  function defineCommandFunction(impl) {
14
13
  return impl;
15
14
  }
16
-
17
15
  //#endregion
18
16
  //#region src/commands/agent-logbook/stats/formatSessionStatsOutput.ts
19
17
  /**
@@ -60,7 +58,6 @@ function formatSessionStatsOutput(agentName, sessionId, result) {
60
58
  lines.push("");
61
59
  return lines.join("\n");
62
60
  }
63
-
64
61
  //#endregion
65
62
  //#region src/commands/agent-logbook/stats/defineSessionStatsPlugin.ts
66
63
  /**
@@ -72,7 +69,6 @@ function formatSessionStatsOutput(agentName, sessionId, result) {
72
69
  function defineSessionStatsPlugin(plugin) {
73
70
  return plugin;
74
71
  }
75
-
76
72
  //#endregion
77
73
  //#region src/commands/agent-logbook/stats/plugins/claudecode.ts
78
74
  /** Base directory where Claude Code stores project and session metadata. */
@@ -216,7 +212,6 @@ const claudecodePlugin = defineSessionStatsPlugin({
216
212
  };
217
213
  }
218
214
  });
219
-
220
215
  //#endregion
221
216
  //#region src/commands/agent-logbook/stats/plugins/geminicli.ts
222
217
  /** Base directory where Gemini CLI stores its temporary session data. */
@@ -229,88 +224,82 @@ async function readJsonFile(filePath) {
229
224
  const content = await fs.promises.readFile(filePath, "utf8");
230
225
  return JSON.parse(content);
231
226
  }
232
- /**
233
- * The GeminiCLI-specific stats plugin.
234
- * Handles parsing GeminiCLI session JSON files found in ~/.gemini/tmp.
235
- */
236
- const geminicliPlugin = defineSessionStatsPlugin({
237
- name: "geminicli",
238
- async findSession(sessionId) {
239
- const matchingFiles = [];
240
- try {
241
- const projectDirs = await fs.promises.readdir(GEMINICLI_TMP_DIR);
242
- const dirResults = await Promise.all(projectDirs.map(async (projectDir) => {
243
- const chatsDir = path.join(GEMINICLI_TMP_DIR, projectDir, "chats");
244
- try {
245
- const jsonFiles = (await fs.promises.readdir(chatsDir)).filter((f) => f.endsWith(".json")).map((f) => path.join(chatsDir, f));
246
- return (await Promise.all(jsonFiles.map(async (filePath) => {
247
- return (await readJsonFile(filePath)).sessionId === sessionId ? filePath : null;
248
- }))).filter((f) => f !== null);
249
- } catch {
250
- return [];
251
- }
252
- }));
253
- matchingFiles.push(...dirResults.flat());
254
- } catch (error) {
255
- console.error("Error searching gemini tmp directory:", error.message);
256
- }
257
- return matchingFiles.length > 0 ? matchingFiles : null;
258
- },
259
- async aggregateStats(sessionFiles) {
260
- const stats = {
261
- input: 0,
262
- output: 0,
263
- cached: 0,
264
- thoughts: 0,
265
- tool: 0,
266
- total: 0,
267
- models: /* @__PURE__ */ new Set()
268
- };
269
- const results = await Promise.all(sessionFiles.map(async (filePath) => {
270
- try {
271
- return await readJsonFile(filePath);
272
- } catch (error) {
273
- console.error(`Error processing file ${filePath}:`, error.message);
274
- return null;
275
- }
276
- }));
277
- for (const data of results) {
278
- if (!data?.messages || !Array.isArray(data.messages)) continue;
279
- for (const msg of data.messages) if (msg.type === "gemini" && msg.tokens) {
280
- stats.input += msg.tokens.input || 0;
281
- stats.output += msg.tokens.output || 0;
282
- stats.cached += msg.tokens.cached || 0;
283
- stats.thoughts += msg.tokens.thoughts || 0;
284
- stats.tool += msg.tokens.tool || 0;
285
- stats.total += msg.tokens.total || 0;
286
- if (msg.model) stats.models.add(msg.model);
287
- }
288
- }
289
- return {
290
- models: Array.from(stats.models),
291
- meta: [["Files Found", sessionFiles.length]],
292
- sections: [{
293
- label: "TOKEN USAGE",
294
- entries: [
295
- ["Input Tokens", stats.input - stats.cached],
296
- ["Output Tokens", stats.output],
297
- ["Cached Tokens", stats.cached],
298
- ["Thoughts Tokens", stats.thoughts],
299
- ["Tool Tokens", stats.tool]
300
- ]
301
- }],
302
- summary: null,
303
- grandTotal: stats.total
304
- };
305
- }
306
- });
307
-
308
227
  //#endregion
309
228
  //#region src/commands/agent-logbook/stats/index.ts
310
229
  /** Mapping of agent names to their respective stats plugins. */
311
230
  const plugins = {
312
231
  claudecode: claudecodePlugin,
313
- geminicli: geminicliPlugin
232
+ geminicli: defineSessionStatsPlugin({
233
+ name: "geminicli",
234
+ async findSession(sessionId) {
235
+ const matchingFiles = [];
236
+ try {
237
+ const projectDirs = await fs.promises.readdir(GEMINICLI_TMP_DIR);
238
+ const dirResults = await Promise.all(projectDirs.map(async (projectDir) => {
239
+ const chatsDir = path.join(GEMINICLI_TMP_DIR, projectDir, "chats");
240
+ try {
241
+ const jsonFiles = (await fs.promises.readdir(chatsDir)).filter((f) => f.endsWith(".json")).map((f) => path.join(chatsDir, f));
242
+ return (await Promise.all(jsonFiles.map(async (filePath) => {
243
+ return (await readJsonFile(filePath)).sessionId === sessionId ? filePath : null;
244
+ }))).filter((f) => f !== null);
245
+ } catch {
246
+ return [];
247
+ }
248
+ }));
249
+ matchingFiles.push(...dirResults.flat());
250
+ } catch (error) {
251
+ console.error("Error searching gemini tmp directory:", error.message);
252
+ }
253
+ return matchingFiles.length > 0 ? matchingFiles : null;
254
+ },
255
+ async aggregateStats(sessionFiles) {
256
+ const stats = {
257
+ input: 0,
258
+ output: 0,
259
+ cached: 0,
260
+ thoughts: 0,
261
+ tool: 0,
262
+ total: 0,
263
+ models: /* @__PURE__ */ new Set()
264
+ };
265
+ const results = await Promise.all(sessionFiles.map(async (filePath) => {
266
+ try {
267
+ return await readJsonFile(filePath);
268
+ } catch (error) {
269
+ console.error(`Error processing file ${filePath}:`, error.message);
270
+ return null;
271
+ }
272
+ }));
273
+ for (const data of results) {
274
+ if (!data?.messages || !Array.isArray(data.messages)) continue;
275
+ for (const msg of data.messages) if (msg.type === "gemini" && msg.tokens) {
276
+ stats.input += msg.tokens.input || 0;
277
+ stats.output += msg.tokens.output || 0;
278
+ stats.cached += msg.tokens.cached || 0;
279
+ stats.thoughts += msg.tokens.thoughts || 0;
280
+ stats.tool += msg.tokens.tool || 0;
281
+ stats.total += msg.tokens.total || 0;
282
+ if (msg.model) stats.models.add(msg.model);
283
+ }
284
+ }
285
+ return {
286
+ models: Array.from(stats.models),
287
+ meta: [["Files Found", sessionFiles.length]],
288
+ sections: [{
289
+ label: "TOKEN USAGE",
290
+ entries: [
291
+ ["Input Tokens", stats.input - stats.cached],
292
+ ["Output Tokens", stats.output],
293
+ ["Cached Tokens", stats.cached],
294
+ ["Thoughts Tokens", stats.thoughts],
295
+ ["Tool Tokens", stats.tool]
296
+ ]
297
+ }],
298
+ summary: null,
299
+ grandTotal: stats.total
300
+ };
301
+ }
302
+ })
314
303
  };
315
304
  /**
316
305
  * The 'stats' command implementation.
@@ -336,6 +325,5 @@ const stats = defineCommandFunction(async function stats({ agent }, sessionId) {
336
325
  const result = await plugin.aggregateStats(sessionData);
337
326
  console.log(formatSessionStatsOutput(plugin.name, sessionId, result));
338
327
  });
339
-
340
328
  //#endregion
341
- export { stats };
329
+ export { stats };
@@ -4,7 +4,6 @@ import matter from "gray-matter";
4
4
  import { Compile } from "typebox/compile";
5
5
  import yaml from "yaml";
6
6
  import { Type } from "typebox";
7
-
8
7
  //#region src/commands/agent-logbook/validate/frontmatterSchema.ts
9
8
  const IsoDate = Type.Codec(Type.String({ format: "date-time" })).Decode((value) => new Date(value)).Encode((value) => value.toISOString());
10
9
  /**
@@ -37,7 +36,6 @@ const FrontmatterSchema = Type.Object({
37
36
  relatedPlan: Type.Optional(Type.String()),
38
37
  migrated: Type.Optional(Type.Boolean())
39
38
  }, { additionalProperties: false });
40
-
41
39
  //#endregion
42
40
  //#region src/commands/agent-logbook/validate/index.ts
43
41
  /**
@@ -99,6 +97,5 @@ async function validate(_flags, targetPath = ".agent-logbook") {
99
97
  if (failed > 0) return process.exit(1);
100
98
  console.log("All files validated successfully");
101
99
  }
102
-
103
100
  //#endregion
104
- export { validate };
101
+ export { validate };
package/package.json CHANGED
@@ -1,18 +1,14 @@
1
1
  {
2
2
  "name": "@stzhu/skills",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Skills CLI",
5
5
  "keywords": [
6
6
  "skills"
7
7
  ],
8
8
  "license": "MIT",
9
9
  "author": "Steve Zhu <4130171+stevezhu@users.noreply.github.com>",
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/stevezhu/eslint-config.git"
13
- },
10
+ "repository": "github:stevezhu/skills",
14
11
  "bin": {
15
- "__stz-skills_bash_complete": "dist/bash-complete.mjs",
16
12
  "stz-skills": "dist/cli.mjs"
17
13
  },
18
14
  "files": [
@@ -27,16 +23,16 @@
27
23
  "@stricli/core": "^1.2.6",
28
24
  "find-workspaces": "^0.3.1",
29
25
  "gray-matter": "^4.0.3",
30
- "typebox": "^1.1.5",
26
+ "typebox": "^1.1.6",
31
27
  "yaml": "^2.8.2"
32
28
  },
33
29
  "devDependencies": {
34
- "@stzhu/tsconfig": "^0.1.1",
35
- "@types/node": "^25.3.3",
36
- "oxfmt": "^0.36.0",
37
- "oxlint": "^1.51.0",
30
+ "@stzhu/tsconfig": "^0.3.0",
31
+ "@types/node": "^25.4.0",
32
+ "oxfmt": "^0.37.0",
33
+ "oxlint": "^1.52.0",
38
34
  "oxlint-tsgolint": "^0.16.0",
39
- "tsdown": "^0.20.3",
35
+ "tsdown": "^0.21.1",
40
36
  "tsx": "^4.21.0",
41
37
  "typescript": "^5.9.3",
42
38
  "vitest": "^4.0.18"
@@ -45,14 +41,11 @@
45
41
  "node": ">=25"
46
42
  },
47
43
  "scripts": {
48
- "ai:claude": "claude",
49
- "ai:gemini": "SEATBELT_PROFILE=custom gemini",
50
44
  "build": "tsdown",
51
45
  "format": "oxfmt",
52
46
  "format:check": "oxfmt --check",
53
47
  "lint": "pnpm run format:check && oxlint --type-aware",
54
48
  "lint:fix": "oxlint --type-aware --fix",
55
- "postinstall": "([ ! -d \"src\" ] || pnpm run build) && node dist/cli.mjs install",
56
49
  "pretest": "tsc --noEmit",
57
50
  "test": "vitest"
58
51
  }