@use-aistack/cli 0.11.0 → 0.12.1

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 CHANGED
@@ -348,7 +348,7 @@ function apiEquivalentCost(modelKey, t, atMs) {
348
348
  }
349
349
 
350
350
  // src/version.ts
351
- var CLI_VERSION = true ? "0.11.0" : "0.0.0-dev";
351
+ var CLI_VERSION = true ? "0.12.1" : "0.0.0-dev";
352
352
 
353
353
  // src/api.ts
354
354
  var BASE_URL = process.env.AISTACK_URL || "https://aistack.to";
@@ -537,7 +537,7 @@ async function stackGet(token) {
537
537
  import * as p2 from "@clack/prompts";
538
538
 
539
539
  // src/classifier.ts
540
- import { basename, dirname } from "path";
540
+ import { basename, dirname } from "node:path";
541
541
 
542
542
  // src/stableKey.ts
543
543
  function computeStableKey(group, type, relPath) {
@@ -609,10 +609,10 @@ function classify(files) {
609
609
  }
610
610
 
611
611
  // src/config.ts
612
- import { randomBytes } from "crypto";
613
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
614
- import { homedir } from "os";
615
- import { dirname as dirname2, join } from "path";
612
+ import { randomBytes } from "node:crypto";
613
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
614
+ import { homedir } from "node:os";
615
+ import { dirname as dirname2, join } from "node:path";
616
616
  var CONFIG_DIR = join(homedir(), ".config", "aistack");
617
617
  var CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
618
618
  var DEFAULT_SERVER_URL = "https://aistack.to";
@@ -732,7 +732,7 @@ function saveExcludedPaths(directory, excluded, file = PROJECTS_FILE) {
732
732
  }
733
733
 
734
734
  // src/git.ts
735
- import { execFileSync } from "child_process";
735
+ import { execFileSync } from "node:child_process";
736
736
 
737
737
  // src/github-repo.ts
738
738
  function isGithubHost(host) {
@@ -816,9 +816,9 @@ function buildRepoLinkResource(canonical) {
816
816
  }
817
817
 
818
818
  // src/hooks.ts
819
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
820
- import { homedir as homedir2 } from "os";
821
- import { join as join2 } from "path";
819
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
820
+ import { homedir as homedir2 } from "node:os";
821
+ import { join as join2 } from "node:path";
822
822
  function readJson(path7) {
823
823
  try {
824
824
  if (!existsSync2(path7)) return null;
@@ -859,9 +859,9 @@ function detectHooks(cwd, home = homedir2()) {
859
859
  }
860
860
 
861
861
  // src/mcp.ts
862
- import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync3 } from "fs";
863
- import { homedir as homedir3, platform } from "os";
864
- import { join as join3 } from "path";
862
+ import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync3 } from "node:fs";
863
+ import { homedir as homedir3, platform } from "node:os";
864
+ import { join as join3 } from "node:path";
865
865
  import { parse as parseToml } from "smol-toml";
866
866
  import { parse as parseYaml } from "yaml";
867
867
  function commandName(cmd) {
@@ -1099,9 +1099,9 @@ function listYamlFiles(dir) {
1099
1099
  }
1100
1100
 
1101
1101
  // src/plugins.ts
1102
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
1103
- import { homedir as homedir4 } from "os";
1104
- import { join as join4 } from "path";
1102
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
1103
+ import { homedir as homedir4 } from "node:os";
1104
+ import { join as join4 } from "node:path";
1105
1105
  function marketplaceRepoUrl(mp) {
1106
1106
  const src = mp?.source;
1107
1107
  if (!src) return null;
@@ -1178,9 +1178,9 @@ function detectInstalledPlugins(pluginsDir = join4(homedir4(), ".claude", "plugi
1178
1178
  }
1179
1179
 
1180
1180
  // src/scanner.ts
1181
- import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync5, statSync } from "fs";
1182
- import { homedir as homedir5 } from "os";
1183
- import { join as join5, relative } from "path";
1181
+ import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync5, statSync } from "node:fs";
1182
+ import { homedir as homedir5 } from "node:os";
1183
+ import { join as join5, relative } from "node:path";
1184
1184
  import ignore from "ignore";
1185
1185
  var MAX_FILE_SIZE = 100 * 1024;
1186
1186
  var LOCAL_PATTERNS = [
@@ -1766,11 +1766,11 @@ function diffResources(current, existing) {
1766
1766
  }
1767
1767
 
1768
1768
  // src/commands/connect.ts
1769
- import { spawnSync } from "child_process";
1770
- import { cpSync, existsSync as existsSync6 } from "fs";
1771
- import { homedir as homedir10 } from "os";
1772
- import { dirname as dirname3, join as join6 } from "path";
1773
- import { fileURLToPath } from "url";
1769
+ import { spawnSync } from "node:child_process";
1770
+ import { cpSync, existsSync as existsSync6 } from "node:fs";
1771
+ import { homedir as homedir10 } from "node:os";
1772
+ import { dirname as dirname3, join as join6 } from "node:path";
1773
+ import { fileURLToPath } from "node:url";
1774
1774
  import * as p3 from "@clack/prompts";
1775
1775
 
1776
1776
  // src/harness/shared/aggregate.ts
@@ -2373,8 +2373,8 @@ function filterAtoms(atoms, sets) {
2373
2373
  }
2374
2374
 
2375
2375
  // src/harness/shared/recency.ts
2376
- import { readdir, stat } from "fs/promises";
2377
- import path from "path";
2376
+ import { readdir, stat } from "node:fs/promises";
2377
+ import path from "node:path";
2378
2378
  async function hasRecentFile(roots, matches, sinceMs, opts = {}) {
2379
2379
  const readDir = opts.readdirImpl ?? ((dir) => readdir(dir, { withFileTypes: true }));
2380
2380
  const statFile = opts.statImpl ?? stat;
@@ -4638,11 +4638,11 @@ function ingestUser(agg, rec) {
4638
4638
  }
4639
4639
 
4640
4640
  // src/harness/claude/scan.ts
4641
- import { createReadStream } from "fs";
4642
- import { readdir as readdir2, realpath, stat as stat2 } from "fs/promises";
4643
- import { homedir as homedir6 } from "os";
4644
- import path2 from "path";
4645
- import readline from "readline";
4641
+ import { createReadStream } from "node:fs";
4642
+ import { readdir as readdir2, realpath, stat as stat2 } from "node:fs/promises";
4643
+ import { homedir as homedir6 } from "node:os";
4644
+ import path2 from "node:path";
4645
+ import readline from "node:readline";
4646
4646
  function transcriptRoots() {
4647
4647
  const env = process.env.CLAUDE_CONFIG_DIR;
4648
4648
  if (env) {
@@ -4802,9 +4802,11 @@ function createFileState() {
4802
4802
  effort: null,
4803
4803
  responseIndex: 0,
4804
4804
  currentQuestionBack: false,
4805
- counted: false
4805
+ counted: false,
4806
+ metaTsMs: null
4806
4807
  };
4807
4808
  }
4809
+ var FORK_REPLAY_WINDOW_MS = 500;
4808
4810
  function ingestLine(agg, raw, state, sinceMs) {
4809
4811
  const rec = asObj(raw);
4810
4812
  if (!rec) return;
@@ -4822,6 +4824,7 @@ function ingestLine(agg, raw, state, sinceMs) {
4822
4824
  state.sessionId = asStr(payload.id) ?? asStr(payload.session_id) ?? state.sessionId;
4823
4825
  state.cliVersion = asStr(payload.cli_version) ?? state.cliVersion;
4824
4826
  state.cwd = asStr(payload.cwd) ?? state.cwd;
4827
+ state.metaTsMs = tsMs ?? state.metaTsMs;
4825
4828
  } else if (type === "turn_context" && payload) {
4826
4829
  const model = asName(payload.model);
4827
4830
  if (model) state.modelKey = normalizeModel(model);
@@ -4864,6 +4867,9 @@ function ingestEvent(agg, payload, state, tsMs) {
4864
4867
  };
4865
4868
  const total = countsTotal(counts);
4866
4869
  if (total === 0) return;
4870
+ if (tsMs !== null && state.metaTsMs !== null && tsMs - state.metaTsMs < FORK_REPLAY_WINDOW_MS)
4871
+ return;
4872
+ if (state.modelKey === null) return;
4867
4873
  if (tsMs === null) agg.untimestampedResponses++;
4868
4874
  agg.distinctResponses++;
4869
4875
  const modelKey = state.modelKey ?? "(unknown)";
@@ -4995,11 +5001,11 @@ function noteConfiguredMcpServers(agg, serverNames) {
4995
5001
  }
4996
5002
 
4997
5003
  // src/harness/codex/scan.ts
4998
- import { readFileSync as readFileSync6 } from "fs";
4999
- import { readdir as readdir3, realpath as realpath2, stat as stat3 } from "fs/promises";
5000
- import { homedir as homedir7 } from "os";
5001
- import path3 from "path";
5002
- import * as zlib from "zlib";
5004
+ import { readFileSync as readFileSync6 } from "node:fs";
5005
+ import { readdir as readdir3, realpath as realpath2, stat as stat3 } from "node:fs/promises";
5006
+ import { homedir as homedir7 } from "node:os";
5007
+ import path3 from "node:path";
5008
+ import * as zlib from "node:zlib";
5003
5009
  import { parse as parseToml2 } from "smol-toml";
5004
5010
  function codexHome() {
5005
5011
  return process.env.CODEX_HOME || path3.join(homedir7(), ".codex");
@@ -5144,6 +5150,7 @@ function ingestFile2(agg, file, opts) {
5144
5150
  function classifyRollout(records) {
5145
5151
  let originator = null;
5146
5152
  let sawTurnContext = false;
5153
+ let sawTokenCount = false;
5147
5154
  let genuine = records.length > 0;
5148
5155
  for (const [i, raw] of records.entries()) {
5149
5156
  const rec = asObj(raw);
@@ -5154,10 +5161,11 @@ function classifyRollout(records) {
5154
5161
  originator = asStr(payload.originator);
5155
5162
  } else if (type === "turn_context") {
5156
5163
  sawTurnContext = true;
5157
- } else if (type === "event_msg" && payload && asStr(payload.type) === "token_count" && !sawTurnContext) {
5158
- genuine = false;
5164
+ } else if (type === "event_msg" && payload && asStr(payload.type) === "token_count") {
5165
+ sawTokenCount = true;
5159
5166
  }
5160
5167
  }
5168
+ if (sawTokenCount && !sawTurnContext) genuine = false;
5161
5169
  if (genuine) return { genuine: true };
5162
5170
  return { genuine: false, originator: originator ?? "(none)" };
5163
5171
  }
@@ -5403,10 +5411,10 @@ function noteConfiguredMcpServers2(agg, state, serverNames) {
5403
5411
  }
5404
5412
 
5405
5413
  // src/harness/opencode/scan.ts
5406
- import { readFileSync as readFileSync7 } from "fs";
5407
- import { readdir as readdir4, stat as stat4 } from "fs/promises";
5408
- import { homedir as homedir8 } from "os";
5409
- import path4 from "path";
5414
+ import { readFileSync as readFileSync7 } from "node:fs";
5415
+ import { readdir as readdir4, stat as stat4 } from "node:fs/promises";
5416
+ import { homedir as homedir8 } from "node:os";
5417
+ import path4 from "node:path";
5410
5418
  var OPENCODE_MIGRATION_CEILING = 20260622202450;
5411
5419
  function opencodeDataDirs() {
5412
5420
  const xdg = process.env.XDG_DATA_HOME;
@@ -5428,7 +5436,7 @@ async function dbFilesIn(root) {
5428
5436
  }
5429
5437
  async function loadSqlite() {
5430
5438
  try {
5431
- const mod = await import("sqlite");
5439
+ const mod = await import("node:sqlite");
5432
5440
  if (typeof mod.DatabaseSync !== "function") return null;
5433
5441
  return (file) => new mod.DatabaseSync(file, { readOnly: true });
5434
5442
  } catch {
@@ -5927,11 +5935,11 @@ function readCounts2(usageRaw) {
5927
5935
  }
5928
5936
 
5929
5937
  // src/harness/pi/scan.ts
5930
- import { createReadStream as createReadStream2 } from "fs";
5931
- import { readdir as readdir5, realpath as realpath3, stat as stat5 } from "fs/promises";
5932
- import { homedir as homedir9 } from "os";
5933
- import path5 from "path";
5934
- import readline2 from "readline";
5938
+ import { createReadStream as createReadStream2 } from "node:fs";
5939
+ import { readdir as readdir5, realpath as realpath3, stat as stat5 } from "node:fs/promises";
5940
+ import { homedir as homedir9 } from "node:os";
5941
+ import path5 from "node:path";
5942
+ import readline2 from "node:readline";
5935
5943
  var MAX_SESSION_VERSION = 3;
5936
5944
  function piAgentDir() {
5937
5945
  return process.env.PI_CODING_AGENT_DIR || path5.join(homedir9(), ".pi", "agent");
@@ -6270,8 +6278,8 @@ async function offerConnectUpsell(deps = {}) {
6270
6278
  }
6271
6279
 
6272
6280
  // src/commands/create.ts
6273
- import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync2 } from "fs";
6274
- import { dirname as dirname4, join as join7 } from "path";
6281
+ import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync2 } from "node:fs";
6282
+ import { dirname as dirname4, join as join7 } from "node:path";
6275
6283
  import * as p4 from "@clack/prompts";
6276
6284
  async function createCommand() {
6277
6285
  intro2("create");
@@ -6372,7 +6380,7 @@ async function createCommand() {
6372
6380
  }
6373
6381
 
6374
6382
  // src/commands/login.ts
6375
- import { hostname } from "os";
6383
+ import { hostname } from "node:os";
6376
6384
  import * as p5 from "@clack/prompts";
6377
6385
  import open from "open";
6378
6386
  function proposedMachineName(read = hostname) {
@@ -6464,10 +6472,10 @@ async function loginCommand(options = {}) {
6464
6472
  import * as p7 from "@clack/prompts";
6465
6473
 
6466
6474
  // src/autosync/codexHook.ts
6467
- import { createHash } from "crypto";
6468
- import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync3 } from "fs";
6469
- import { homedir as homedir11 } from "os";
6470
- import { dirname as dirname5, join as join8 } from "path";
6475
+ import { createHash } from "node:crypto";
6476
+ import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync9, writeFileSync as writeFileSync3 } from "node:fs";
6477
+ import { homedir as homedir11 } from "node:os";
6478
+ import { dirname as dirname5, join as join8 } from "node:path";
6471
6479
  function codexHome2() {
6472
6480
  return process.env.CODEX_HOME || join8(homedir11(), ".codex");
6473
6481
  }
@@ -6565,9 +6573,9 @@ function codexHookTrusted(configFile = codexConfigFile()) {
6565
6573
  import * as p6 from "@clack/prompts";
6566
6574
 
6567
6575
  // src/autosync/hook.ts
6568
- import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "fs";
6569
- import { homedir as homedir12 } from "os";
6570
- import { dirname as dirname6, join as join9 } from "path";
6576
+ import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "node:fs";
6577
+ import { homedir as homedir12 } from "node:os";
6578
+ import { dirname as dirname6, join as join9 } from "node:path";
6571
6579
  var CLAUDE_SETTINGS_FILE = join9(homedir12(), ".claude", "settings.json");
6572
6580
  var AUTO_SYNC_HOOK_COMMAND = "npx -y @use-aistack/cli@latest sync --auto || npx -y --prefer-offline @use-aistack/cli sync --auto";
6573
6581
  function isOurs2(entry) {
@@ -6836,12 +6844,12 @@ import {
6836
6844
  mkdirSync as mkdirSync5,
6837
6845
  readFileSync as readFileSync11,
6838
6846
  writeFileSync as writeFileSync5
6839
- } from "fs";
6840
- import { homedir as homedir13 } from "os";
6841
- import { dirname as dirname7, join as join10 } from "path";
6847
+ } from "node:fs";
6848
+ import { homedir as homedir13 } from "node:os";
6849
+ import { dirname as dirname7, join as join10 } from "node:path";
6842
6850
 
6843
6851
  // src/sync/stage.ts
6844
- import { createHash as createHash2 } from "crypto";
6852
+ import { createHash as createHash2 } from "node:crypto";
6845
6853
 
6846
6854
  // src/usage/days.ts
6847
6855
  var round6 = (n) => Math.round(n * 1e6) / 1e6;
@@ -6990,8 +6998,8 @@ function selectDaysToPublish(input) {
6990
6998
  }
6991
6999
 
6992
7000
  // src/workflow/git.ts
6993
- import { execFile, execFileSync as execFileSync2 } from "child_process";
6994
- import path6 from "path";
7001
+ import { execFile, execFileSync as execFileSync2 } from "node:child_process";
7002
+ import path6 from "node:path";
6995
7003
  var TEST_FILE_RULE_VERSION = "test-files/v2";
6996
7004
  var FILE_TYPE_RULE_VERSION = "file-types/v2";
6997
7005
  var COMMIT_SET_RULE_VERSION = "commit-set/v1";
@@ -8268,6 +8276,33 @@ function styleSummaryLine(line) {
8268
8276
  return line;
8269
8277
  }
8270
8278
 
8279
+ // src/node-version.ts
8280
+ var MINIMUM_NODE_VERSION = "22.13.0";
8281
+ function versionParts(version) {
8282
+ const match = /^(?:v)?(\d+)\.(\d+)\.(\d+)/.exec(version);
8283
+ if (!match) return null;
8284
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
8285
+ }
8286
+ function atLeast(actual, floor) {
8287
+ const minimum = versionParts(floor);
8288
+ if (!minimum) return false;
8289
+ for (let i = 0; i < actual.length; i++) {
8290
+ if (actual[i] !== minimum[i])
8291
+ return actual[i] > minimum[i];
8292
+ }
8293
+ return true;
8294
+ }
8295
+ function supportsNodeVersion(version) {
8296
+ const actual = versionParts(version);
8297
+ if (!actual) return false;
8298
+ if (!atLeast(actual, MINIMUM_NODE_VERSION)) return false;
8299
+ if (actual[0] === 23) return atLeast(actual, "23.4.0");
8300
+ return true;
8301
+ }
8302
+ function unsupportedNodeMessage(version) {
8303
+ return `aistack requires Node.js ${MINIMUM_NODE_VERSION} or newer (23.x needs 23.4.0). You are running ${version}. Upgrade Node.js so sync can read OpenCode's SQLite usage database.`;
8304
+ }
8305
+
8271
8306
  // src/sync/server.ts
8272
8307
  var SERVER_NAME = "aistack";
8273
8308
  var SERVER_VERSION = "0.3.0";
@@ -8547,5 +8582,11 @@ program.command("sync").description("Scan, preview, and publish measured usage (
8547
8582
  "with --auto on: hours between auto-syncs (default 6)"
8548
8583
  ).action((options) => syncCommand(options));
8549
8584
  program.command("connect").description("Install the in-session sync surface (MCP server + Skill)").argument("<harness>", 'the harness to connect ("claude")').action(connectCommand);
8550
- program.parse();
8585
+ if (!supportsNodeVersion(process.versions.node)) {
8586
+ process.stderr.write(`${unsupportedNodeMessage(process.versions.node)}
8587
+ `);
8588
+ process.exitCode = 1;
8589
+ } else {
8590
+ program.parse();
8591
+ }
8551
8592
  //# sourceMappingURL=index.js.map