reasonix 0.4.21 → 0.4.22

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.d.ts CHANGED
@@ -2308,8 +2308,85 @@ declare function isPlausibleKey(key: string): boolean;
2308
2308
  /** Mask a key for display: `sk-abcd...wxyz`. */
2309
2309
  declare function redactKey(key: string): string;
2310
2310
 
2311
- /** Reasonix — DeepSeek-native agent framework. Library entry point. */
2312
-
2313
- declare const VERSION = "0.4.20";
2311
+ /**
2312
+ * Version module.
2313
+ *
2314
+ * Two jobs:
2315
+ *
2316
+ * 1. Expose `VERSION` sourced from the real `package.json` so the
2317
+ * constant never drifts from what npm publishes. Works in dev
2318
+ * (`tsx src/...`) AND after `tsup` bundles to `dist/` — both
2319
+ * layouts sit two levels below the manifest, so a short
2320
+ * walk-up finds it.
2321
+ *
2322
+ * 2. Offer an opt-in `getLatestVersion()` that hits the npm
2323
+ * registry with a bounded timeout and a 24-hour on-disk
2324
+ * cache at `~/.reasonix/version-cache.json`. Returns `null`
2325
+ * on any failure — offline / restricted-network launches
2326
+ * should stay silent rather than nag the user.
2327
+ *
2328
+ * The CLI wires `getLatestVersion` asynchronously at App mount
2329
+ * (never in a hot path) and renders the outcome in the stats
2330
+ * panel when there's a newer published version.
2331
+ */
2332
+ /** TTL for the on-disk cache entry. 24h keeps noise low; users who
2333
+ * want a fresh check can run `reasonix update` which passes
2334
+ * `force: true`. */
2335
+ declare const LATEST_CACHE_TTL_MS: number;
2336
+ /** Network timeout. Short — we never block the UI waiting on this. */
2337
+ declare const LATEST_FETCH_TIMEOUT_MS = 2000;
2338
+ declare const VERSION: string;
2339
+ interface GetLatestVersionOptions {
2340
+ /** Ignore the cached entry and always fetch fresh. Used by `reasonix update`. */
2341
+ force?: boolean;
2342
+ /** Registry URL override (tests). */
2343
+ registryUrl?: string;
2344
+ /** Home-directory override (tests). */
2345
+ homeDir?: string;
2346
+ /** Fetch implementation override (tests). Defaults to `globalThis.fetch`. */
2347
+ fetchImpl?: typeof fetch;
2348
+ /** TTL override (tests). */
2349
+ ttlMs?: number;
2350
+ /** Network timeout override (tests). */
2351
+ timeoutMs?: number;
2352
+ }
2353
+ /**
2354
+ * Resolve the latest published `reasonix` version from the npm registry.
2355
+ *
2356
+ * Returns `null` on any network / parse failure. Callers treat `null`
2357
+ * as "don't know, don't nag the user." The cache entry is only
2358
+ * written on a successful fetch — a bad registry response won't
2359
+ * poison the cache.
2360
+ */
2361
+ declare function getLatestVersion(opts?: GetLatestVersionOptions): Promise<string | null>;
2362
+ /**
2363
+ * Semver compare. Returns a negative number when `a < b`, positive
2364
+ * when `a > b`, zero when equal.
2365
+ *
2366
+ * Minimal pre-release handling: when the CORE (`x.y.z`) parts match,
2367
+ * any version WITH a suffix (`-rc.1`, `-alpha.4`) compares LOWER
2368
+ * than the bare version. That matches npm's dist-tag semantics —
2369
+ * `reasonix@latest` resolves to a real release, not a pre-release.
2370
+ *
2371
+ * We're deliberately not pulling in `semver` (~50KB). The three
2372
+ * cases we care about are: current > latest (future build, no
2373
+ * prompt), current < latest (prompt), current === latest (no prompt).
2374
+ */
2375
+ declare function compareVersions(a: string, b: string): number;
2376
+ /**
2377
+ * Heuristic: did this process launch via `npx` / `pnpm dlx` instead
2378
+ * of a global install? The update command takes different advice in
2379
+ * each case — a global install can `npm i -g reasonix@latest`, while
2380
+ * npx just needs its cache to roll over on next launch.
2381
+ *
2382
+ * Signals checked, in order:
2383
+ * - `process.argv[1]` contains `_npx` (npm's ephemeral dir name)
2384
+ * - `process.argv[1]` contains `.pnpm` + `dlx`
2385
+ * - `npm_config_user_agent` contains `npx/`
2386
+ *
2387
+ * Any one hit → npx. False negatives are safe (worst case we suggest
2388
+ * `npm i -g` to an npx user, which is a valid way to upgrade too).
2389
+ */
2390
+ declare function isNpxInstall(): boolean;
2314
2391
 
2315
- export { AppendOnlyLog, type ApplyResult, type ApplyStatus, type BranchOptions, type BranchProgress, type BranchResult, type BranchSample, type BranchSelector, type BranchSummary, type BridgeOptions, type BridgeResult, CODE_SYSTEM_PROMPT, CacheFirstLoop, type CacheFirstLoopOptions, type CallToolResult, type ChatMessage, type ChatResponse, DEFAULT_MAX_RESULT_CHARS, DeepSeekClient, type DeepSeekClientOptions, type RenderOptions as DiffRenderOptions, type DiffReport, type DiffSide, type EditBlock, type EditSnapshot, type EventRole, type FilesystemToolsOptions, type FlattenDecision, type FlattenOptions, type GetPromptResult, type HarvestOptions, ImmutablePrefix, type ImmutablePrefixOptions, type InitializeResult, type InspectionReport, type JSONSchema, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcResponse, type ListPromptsResult, type ListResourcesResult, type ListToolsResult, type LoopEvent, MCP_PROTOCOL_VERSION, MEMORY_INDEX_FILE, MEMORY_INDEX_MAX_CHARS, McpClient, type McpClientOptions, type McpContentBlock, type McpProgressHandler, type McpProgressInfo, type McpPrompt, type McpPromptArgument, type McpPromptMessage, type McpPromptResourceBlock, type McpResource, type McpResourceContents, type McpResourceContentsBlob, type McpResourceContentsText, type McpSpec, type McpTool, type McpToolSchema, type McpTransport, type MemoryEntry, type MemoryScope, MemoryStore, type MemoryStoreOptions, type MemoryToolsOptions, type MemoryType, type WriteInput as MemoryWriteInput, NeedsConfirmationError, PROJECT_MEMORY_FILE, PROJECT_MEMORY_MAX_CHARS, type PageContent, PlanProposedError, type PlanToolOptions, type ProgressNotificationParams, type ProjectMemory, type ReadResourceResult, type ReadTranscriptResult, type ReasonixConfig, type ReconfigurableOptions, type RepairReport, type ReplayStats, type RetryInfo, type RetryOptions, type Role, type RunCommandResult, type ScavengeOptions, type ScavengeResult, type SearchResult, type SectionResult, type SessionInfo, SessionStats, type SessionSummary, type ShellToolsOptions, type SseMcpSpec, SseTransport, type SseTransportOptions, type StdioMcpSpec, StdioTransport, type StdioTransportOptions, StormBreaker, type StreamChunk, type ToolCall, type ToolCallContext, ToolCallRepair, type ToolCallRepairOptions, type ToolDefinition, type ToolFunctionSpec, ToolRegistry, type ToolSpec, type TranscriptMeta, type TranscriptRecord, type TruncationRepairResult, type TurnPair, type TurnStats, type TypedPlanState, USER_MEMORY_DIR, Usage, VERSION, VolatileScratch, type WebFetchOptions, type WebSearchOptions, type WebToolsOptions, aggregateBranchUsage, analyzeSchema, appendSessionMessage, applyEditBlock, applyEditBlocks, applyMemoryStack, applyProjectMemory, applyUserMemory, bridgeMcpTools, claudeEquivalentCost, codeSystemPrompt, computeReplayStats, costUsd, defaultConfigPath, defaultSelector, deleteSession, diffTranscripts, emptyPlanState, fetchWithRetry, flattenMcpResult, flattenSchema, formatCommandResult, formatLoopError, formatSearchResults, harvest, healLoadedMessages, htmlToText, inputCostUsd, inspectMcpServer, isAllowed, isJsonRpcError, isPlanStateEmpty, isPlausibleKey, listSessions, loadApiKey, loadDotenv, loadSessionMessages, memoryEnabled, nestArguments, openTranscriptFile, outputCostUsd, parseEditBlocks, parseMcpSpec, parseMojeekResults, parseTranscript, prepareSpawn, projectHash, quoteForCmdExe, readConfig, readProjectMemory, readTranscript, recordFromLoopEvent, redactKey, registerFilesystemTools, registerMemoryTools, registerPlanTool, registerShellTools, registerWebTools, renderMarkdown as renderDiffMarkdown, renderSummaryTable as renderDiffSummary, repairTruncatedJson, replayFromFile, resolveExecutable, restoreSnapshots, runBranches, runCommand, sanitizeMemoryName, sanitizeName as sanitizeSessionName, saveApiKey, scavengeToolCalls, sessionPath, sessionsDir, similarity, snapshotBeforeEdits, stripHallucinatedToolMarkup, tokenizeCommand, truncateForModel, webFetch, webSearch, writeConfig, writeMeta, writeRecord };
2392
+ export { AppendOnlyLog, type ApplyResult, type ApplyStatus, type BranchOptions, type BranchProgress, type BranchResult, type BranchSample, type BranchSelector, type BranchSummary, type BridgeOptions, type BridgeResult, CODE_SYSTEM_PROMPT, CacheFirstLoop, type CacheFirstLoopOptions, type CallToolResult, type ChatMessage, type ChatResponse, DEFAULT_MAX_RESULT_CHARS, DeepSeekClient, type DeepSeekClientOptions, type RenderOptions as DiffRenderOptions, type DiffReport, type DiffSide, type EditBlock, type EditSnapshot, type EventRole, type FilesystemToolsOptions, type FlattenDecision, type FlattenOptions, type GetLatestVersionOptions, type GetPromptResult, type HarvestOptions, ImmutablePrefix, type ImmutablePrefixOptions, type InitializeResult, type InspectionReport, type JSONSchema, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcResponse, LATEST_CACHE_TTL_MS, LATEST_FETCH_TIMEOUT_MS, type ListPromptsResult, type ListResourcesResult, type ListToolsResult, type LoopEvent, MCP_PROTOCOL_VERSION, MEMORY_INDEX_FILE, MEMORY_INDEX_MAX_CHARS, McpClient, type McpClientOptions, type McpContentBlock, type McpProgressHandler, type McpProgressInfo, type McpPrompt, type McpPromptArgument, type McpPromptMessage, type McpPromptResourceBlock, type McpResource, type McpResourceContents, type McpResourceContentsBlob, type McpResourceContentsText, type McpSpec, type McpTool, type McpToolSchema, type McpTransport, type MemoryEntry, type MemoryScope, MemoryStore, type MemoryStoreOptions, type MemoryToolsOptions, type MemoryType, type WriteInput as MemoryWriteInput, NeedsConfirmationError, PROJECT_MEMORY_FILE, PROJECT_MEMORY_MAX_CHARS, type PageContent, PlanProposedError, type PlanToolOptions, type ProgressNotificationParams, type ProjectMemory, type ReadResourceResult, type ReadTranscriptResult, type ReasonixConfig, type ReconfigurableOptions, type RepairReport, type ReplayStats, type RetryInfo, type RetryOptions, type Role, type RunCommandResult, type ScavengeOptions, type ScavengeResult, type SearchResult, type SectionResult, type SessionInfo, SessionStats, type SessionSummary, type ShellToolsOptions, type SseMcpSpec, SseTransport, type SseTransportOptions, type StdioMcpSpec, StdioTransport, type StdioTransportOptions, StormBreaker, type StreamChunk, type ToolCall, type ToolCallContext, ToolCallRepair, type ToolCallRepairOptions, type ToolDefinition, type ToolFunctionSpec, ToolRegistry, type ToolSpec, type TranscriptMeta, type TranscriptRecord, type TruncationRepairResult, type TurnPair, type TurnStats, type TypedPlanState, USER_MEMORY_DIR, Usage, VERSION, VolatileScratch, type WebFetchOptions, type WebSearchOptions, type WebToolsOptions, aggregateBranchUsage, analyzeSchema, appendSessionMessage, applyEditBlock, applyEditBlocks, applyMemoryStack, applyProjectMemory, applyUserMemory, bridgeMcpTools, claudeEquivalentCost, codeSystemPrompt, compareVersions, computeReplayStats, costUsd, defaultConfigPath, defaultSelector, deleteSession, diffTranscripts, emptyPlanState, fetchWithRetry, flattenMcpResult, flattenSchema, formatCommandResult, formatLoopError, formatSearchResults, getLatestVersion, harvest, healLoadedMessages, htmlToText, inputCostUsd, inspectMcpServer, isAllowed, isJsonRpcError, isNpxInstall, isPlanStateEmpty, isPlausibleKey, listSessions, loadApiKey, loadDotenv, loadSessionMessages, memoryEnabled, nestArguments, openTranscriptFile, outputCostUsd, parseEditBlocks, parseMcpSpec, parseMojeekResults, parseTranscript, prepareSpawn, projectHash, quoteForCmdExe, readConfig, readProjectMemory, readTranscript, recordFromLoopEvent, redactKey, registerFilesystemTools, registerMemoryTools, registerPlanTool, registerShellTools, registerWebTools, renderMarkdown as renderDiffMarkdown, renderSummaryTable as renderDiffSummary, repairTruncatedJson, replayFromFile, resolveExecutable, restoreSnapshots, runBranches, runCommand, sanitizeMemoryName, sanitizeName as sanitizeSessionName, saveApiKey, scavengeToolCalls, sessionPath, sessionsDir, similarity, snapshotBeforeEdits, stripHallucinatedToolMarkup, tokenizeCommand, truncateForModel, webFetch, webSearch, writeConfig, writeMeta, writeRecord };
package/dist/index.js CHANGED
@@ -4778,8 +4778,106 @@ function redactKey(key) {
4778
4778
  return `${key.slice(0, 6)}\u2026${key.slice(-4)}`;
4779
4779
  }
4780
4780
 
4781
- // src/index.ts
4782
- var VERSION = "0.4.20";
4781
+ // src/version.ts
4782
+ import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
4783
+ import { homedir as homedir5 } from "os";
4784
+ import { dirname as dirname5, join as join8 } from "path";
4785
+ import { fileURLToPath } from "url";
4786
+ var REGISTRY_URL = "https://registry.npmjs.org/reasonix/latest";
4787
+ var LATEST_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
4788
+ var LATEST_FETCH_TIMEOUT_MS = 2e3;
4789
+ function readPackageVersion() {
4790
+ try {
4791
+ let dir = dirname5(fileURLToPath(import.meta.url));
4792
+ for (let i = 0; i < 6; i++) {
4793
+ const p = join8(dir, "package.json");
4794
+ if (existsSync8(p)) {
4795
+ const pkg = JSON.parse(readFileSync10(p, "utf8"));
4796
+ if (pkg?.name === "reasonix" && typeof pkg.version === "string") {
4797
+ return pkg.version;
4798
+ }
4799
+ }
4800
+ const parent = dirname5(dir);
4801
+ if (parent === dir) break;
4802
+ dir = parent;
4803
+ }
4804
+ } catch {
4805
+ }
4806
+ return "0.0.0-dev";
4807
+ }
4808
+ var VERSION = readPackageVersion();
4809
+ function cachePath(homeDirOverride) {
4810
+ return join8(homeDirOverride ?? homedir5(), ".reasonix", "version-cache.json");
4811
+ }
4812
+ function readCache(homeDirOverride) {
4813
+ try {
4814
+ const raw = readFileSync10(cachePath(homeDirOverride), "utf8");
4815
+ const parsed = JSON.parse(raw);
4816
+ if (parsed && typeof parsed.version === "string" && typeof parsed.checkedAt === "number") {
4817
+ return parsed;
4818
+ }
4819
+ } catch {
4820
+ }
4821
+ return null;
4822
+ }
4823
+ function writeCache(entry, homeDirOverride) {
4824
+ try {
4825
+ const p = cachePath(homeDirOverride);
4826
+ mkdirSync5(dirname5(p), { recursive: true });
4827
+ writeFileSync5(p, JSON.stringify(entry), "utf8");
4828
+ } catch {
4829
+ }
4830
+ }
4831
+ async function getLatestVersion(opts = {}) {
4832
+ const ttl = opts.ttlMs ?? LATEST_CACHE_TTL_MS;
4833
+ if (!opts.force) {
4834
+ const cached = readCache(opts.homeDir);
4835
+ if (cached && Date.now() - cached.checkedAt < ttl) return cached.version;
4836
+ }
4837
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
4838
+ if (!fetchImpl) return null;
4839
+ const url = opts.registryUrl ?? REGISTRY_URL;
4840
+ const timeout = opts.timeoutMs ?? LATEST_FETCH_TIMEOUT_MS;
4841
+ const controller = new AbortController();
4842
+ const timer = setTimeout(() => controller.abort(), timeout);
4843
+ try {
4844
+ const res = await fetchImpl(url, {
4845
+ signal: controller.signal,
4846
+ headers: { accept: "application/json" }
4847
+ });
4848
+ if (!res.ok) return null;
4849
+ const body = await res.json();
4850
+ if (typeof body.version !== "string") return null;
4851
+ writeCache({ version: body.version, checkedAt: Date.now() }, opts.homeDir);
4852
+ return body.version;
4853
+ } catch {
4854
+ return null;
4855
+ } finally {
4856
+ clearTimeout(timer);
4857
+ }
4858
+ }
4859
+ function compareVersions(a, b) {
4860
+ const [aCore = "0", aPre = ""] = a.split("-", 2);
4861
+ const [bCore = "0", bPre = ""] = b.split("-", 2);
4862
+ const aParts = aCore.split(".").map((p) => Number.parseInt(p, 10) || 0);
4863
+ const bParts = bCore.split(".").map((p) => Number.parseInt(p, 10) || 0);
4864
+ for (let i = 0; i < 3; i++) {
4865
+ const diff = (aParts[i] ?? 0) - (bParts[i] ?? 0);
4866
+ if (diff !== 0) return diff;
4867
+ }
4868
+ if (!aPre && !bPre) return 0;
4869
+ if (!aPre) return 1;
4870
+ if (!bPre) return -1;
4871
+ return aPre < bPre ? -1 : aPre > bPre ? 1 : 0;
4872
+ }
4873
+ function isNpxInstall() {
4874
+ const bin = process.argv[1] ?? "";
4875
+ if (/[/\\]_npx[/\\]/.test(bin)) return true;
4876
+ if (/[/\\]\.pnpm[/\\]/.test(bin) && /dlx/i.test(bin)) return true;
4877
+ const ua = process.env.npm_config_user_agent ?? "";
4878
+ if (ua.includes("npx/")) return true;
4879
+ return false;
4880
+ }
4783
4881
  export {
4784
4882
  AppendOnlyLog,
4785
4883
  CODE_SYSTEM_PROMPT,
@@ -4787,6 +4885,8 @@ export {
4787
4885
  DEFAULT_MAX_RESULT_CHARS,
4788
4886
  DeepSeekClient,
4789
4887
  ImmutablePrefix,
4888
+ LATEST_CACHE_TTL_MS,
4889
+ LATEST_FETCH_TIMEOUT_MS,
4790
4890
  MCP_PROTOCOL_VERSION,
4791
4891
  MEMORY_INDEX_FILE,
4792
4892
  MEMORY_INDEX_MAX_CHARS,
@@ -4817,6 +4917,7 @@ export {
4817
4917
  bridgeMcpTools,
4818
4918
  claudeEquivalentCost,
4819
4919
  codeSystemPrompt,
4920
+ compareVersions,
4820
4921
  computeReplayStats,
4821
4922
  costUsd,
4822
4923
  defaultConfigPath,
@@ -4830,6 +4931,7 @@ export {
4830
4931
  formatCommandResult,
4831
4932
  formatLoopError,
4832
4933
  formatSearchResults,
4934
+ getLatestVersion,
4833
4935
  harvest,
4834
4936
  healLoadedMessages,
4835
4937
  htmlToText,
@@ -4837,6 +4939,7 @@ export {
4837
4939
  inspectMcpServer,
4838
4940
  isAllowed,
4839
4941
  isJsonRpcError,
4942
+ isNpxInstall,
4840
4943
  isPlanStateEmpty,
4841
4944
  isPlausibleKey,
4842
4945
  listSessions,