reasonix 0.5.6 → 0.5.7

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
@@ -1055,6 +1055,65 @@ declare function formatLoopError(err: Error): string;
1055
1055
  */
1056
1056
  /** Caps match tool-result dispatch truncation (0.5.2). */
1057
1057
  declare const DEFAULT_AT_MENTION_MAX_BYTES: number;
1058
+ /**
1059
+ * Default directory names skipped when listing files for the picker.
1060
+ * Matches what most repos gitignore AND keeps the picker off the
1061
+ * hottest bloat — `node_modules` alone can be 100k+ entries.
1062
+ */
1063
+ declare const DEFAULT_PICKER_IGNORE_DIRS: readonly string[];
1064
+ interface ListFilesOptions {
1065
+ /** Cap the walk once we've collected this many entries. Default 500. */
1066
+ maxResults?: number;
1067
+ /** Directory names to skip entirely. Defaults to {@link DEFAULT_PICKER_IGNORE_DIRS}. */
1068
+ ignoreDirs?: readonly string[];
1069
+ }
1070
+ /**
1071
+ * Walk `root` recursively and return relative file paths (forward-slash
1072
+ * separator, regardless of platform) for the `@` picker.
1073
+ *
1074
+ * Synchronous on purpose: this runs once at App mount (and on each turn
1075
+ * so newly-created files show up) and blocks the render thread for a
1076
+ * predictable ~10-50ms on a moderate repo. An async variant would need
1077
+ * to coordinate with the Ink render loop; sync fits the rest of the
1078
+ * TUI's single-turn-per-tick model cleanly.
1079
+ *
1080
+ * Skips:
1081
+ * - directories in `ignoreDirs` (default: DEFAULT_PICKER_IGNORE_DIRS)
1082
+ * - any directory whose name starts with `.` (covers `.git`,
1083
+ * `.vscode`, dotfile vendors). Dotfile REGULAR FILES (`.env`,
1084
+ * `.gitignore`, `.prettierrc`) are kept — users reference them.
1085
+ * - entries the walker can't read (permission errors, broken links).
1086
+ */
1087
+ declare function listFilesSync(root: string, opts?: ListFilesOptions): string[];
1088
+ /**
1089
+ * Prefix pattern used by the `@` picker to detect an IN-PROGRESS
1090
+ * mention at the END of the input buffer. Captures the partial path
1091
+ * (which may be empty — just `@`) so the picker can use it as a
1092
+ * substring filter.
1093
+ *
1094
+ * Distinct from {@link AT_MENTION_PATTERN} (which finds completed
1095
+ * mentions anywhere in the text for expansion-at-submit). This one
1096
+ * fires on the trailing token only, anchored at end-of-input.
1097
+ */
1098
+ declare const AT_PICKER_PREFIX: RegExp;
1099
+ /**
1100
+ * Return the picker state for a given input buffer: the partial query
1101
+ * (may be empty string — just `@`) and the buffer offset of the `@`
1102
+ * character. `null` when the buffer doesn't end in a mention-in-
1103
+ * progress.
1104
+ */
1105
+ declare function detectAtPicker(input: string): {
1106
+ query: string;
1107
+ atOffset: number;
1108
+ } | null;
1109
+ /**
1110
+ * Filter and rank candidate files against the picker's partial query.
1111
+ * Empty query → return the first `limit` candidates as-is (alpha).
1112
+ * Non-empty query → case-insensitive substring match, with a modest
1113
+ * boost for basename-starts-with matches so `src/l` still puts
1114
+ * `loop.ts`-shaped paths near the top.
1115
+ */
1116
+ declare function rankPickerCandidates(files: readonly string[], query: string, limit?: number): string[];
1058
1117
  /**
1059
1118
  * Matches `@` at a word boundary (start-of-string or preceded by
1060
1119
  * whitespace) followed by a path-like token. Deliberately rejects `@`
@@ -3048,4 +3107,4 @@ declare function aggregateUsage(records: UsageRecord[], opts?: AggregateOptions)
3048
3107
  /** File-size helper for the stats header — "1.2 MB" etc. Returns "" if missing. */
3049
3108
  declare function formatLogSize(path?: string): string;
3050
3109
 
3051
- export { AT_MENTION_PATTERN, type AggregateOptions, AppendOnlyLog, type AppendUsageInput, type ApplyResult, type ApplyStatus, type AtMentionExpansion, type AtMentionOptions, 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_AT_MENTION_MAX_BYTES, DEFAULT_MAX_RESULT_CHARS, DEFAULT_MAX_RESULT_TOKENS, 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, HOOK_EVENTS, HOOK_SETTINGS_DIRNAME, HOOK_SETTINGS_FILENAME, type HarvestOptions, type HookConfig, type HookEvent, type HookOutcome, type HookPayload, type HookReport, type HookScope, type HookSettings, type HookSpawnInput, type HookSpawnResult, type HookSpawner, 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 LoadHookSettingsOptions, 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 ResolvedHook, type RetryInfo, type RetryOptions, type Role, type RunCommandResult, type RunHooksOptions, 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 SubagentEvent, type SubagentSink, type SubagentToolOptions, 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, type UsageAggregate, type UsageBucket, type UsageRecord, VERSION, VolatileScratch, type WebFetchOptions, type WebSearchOptions, type WebToolsOptions, aggregateBranchUsage, aggregateUsage, analyzeSchema, appendSessionMessage, appendUsage, applyEditBlock, applyEditBlocks, applyMemoryStack, applyProjectMemory, applyUserMemory, bridgeMcpTools, bucketCacheHitRatio, bucketSavingsFraction, claudeEquivalentCost, codeSystemPrompt, compareVersions, computeReplayStats, costUsd, decideOutcome, defaultConfigPath, defaultSelector, defaultUsageLogPath, deleteSession, detectShellOperator, diffTranscripts, emptyPlanState, expandAtMentions, fetchWithRetry, fixToolCallPairing, flattenMcpResult, flattenSchema, forkRegistryExcluding, formatCommandResult, formatHookOutcomeMessage, formatLogSize, formatLoopError, formatSearchResults, getLatestVersion, globalSettingsPath, harvest, healLoadedMessages, healLoadedMessagesByTokens, htmlToText, injectPowerShellUtf8, inputCostUsd, inspectMcpServer, isAllowed, isJsonRpcError, isNpxInstall, isPlanStateEmpty, isPlausibleKey, listSessions, loadApiKey, loadDotenv, loadHooks, loadSessionMessages, matchesTool, memoryEnabled, nestArguments, openTranscriptFile, outputCostUsd, parseEditBlocks, parseMcpSpec, parseMojeekResults, parseTranscript, prepareSpawn, projectHash, projectSettingsPath, quoteForCmdExe, readConfig, readProjectMemory, readTranscript, readUsageLog, recordFromLoopEvent, redactKey, registerFilesystemTools, registerMemoryTools, registerPlanTool, registerShellTools, registerSubagentTool, registerWebTools, renderMarkdown as renderDiffMarkdown, renderSummaryTable as renderDiffSummary, repairTruncatedJson, replayFromFile, resolveExecutable, restoreSnapshots, runBranches, runCommand, runHooks, sanitizeMemoryName, sanitizeName as sanitizeSessionName, saveApiKey, scavengeToolCalls, sessionPath, sessionsDir, similarity, snapshotBeforeEdits, stripHallucinatedToolMarkup, tokenizeCommand, truncateForModel, truncateForModelByTokens, webFetch, webSearch, withUtf8Codepage, writeConfig, writeMeta, writeRecord };
3110
+ export { AT_MENTION_PATTERN, AT_PICKER_PREFIX, type AggregateOptions, AppendOnlyLog, type AppendUsageInput, type ApplyResult, type ApplyStatus, type AtMentionExpansion, type AtMentionOptions, 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_AT_MENTION_MAX_BYTES, DEFAULT_MAX_RESULT_CHARS, DEFAULT_MAX_RESULT_TOKENS, DEFAULT_PICKER_IGNORE_DIRS, 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, HOOK_EVENTS, HOOK_SETTINGS_DIRNAME, HOOK_SETTINGS_FILENAME, type HarvestOptions, type HookConfig, type HookEvent, type HookOutcome, type HookPayload, type HookReport, type HookScope, type HookSettings, type HookSpawnInput, type HookSpawnResult, type HookSpawner, ImmutablePrefix, type ImmutablePrefixOptions, type InitializeResult, type InspectionReport, type JSONSchema, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcResponse, LATEST_CACHE_TTL_MS, LATEST_FETCH_TIMEOUT_MS, type ListFilesOptions, type ListPromptsResult, type ListResourcesResult, type ListToolsResult, type LoadHookSettingsOptions, 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 ResolvedHook, type RetryInfo, type RetryOptions, type Role, type RunCommandResult, type RunHooksOptions, 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 SubagentEvent, type SubagentSink, type SubagentToolOptions, 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, type UsageAggregate, type UsageBucket, type UsageRecord, VERSION, VolatileScratch, type WebFetchOptions, type WebSearchOptions, type WebToolsOptions, aggregateBranchUsage, aggregateUsage, analyzeSchema, appendSessionMessage, appendUsage, applyEditBlock, applyEditBlocks, applyMemoryStack, applyProjectMemory, applyUserMemory, bridgeMcpTools, bucketCacheHitRatio, bucketSavingsFraction, claudeEquivalentCost, codeSystemPrompt, compareVersions, computeReplayStats, costUsd, decideOutcome, defaultConfigPath, defaultSelector, defaultUsageLogPath, deleteSession, detectAtPicker, detectShellOperator, diffTranscripts, emptyPlanState, expandAtMentions, fetchWithRetry, fixToolCallPairing, flattenMcpResult, flattenSchema, forkRegistryExcluding, formatCommandResult, formatHookOutcomeMessage, formatLogSize, formatLoopError, formatSearchResults, getLatestVersion, globalSettingsPath, harvest, healLoadedMessages, healLoadedMessagesByTokens, htmlToText, injectPowerShellUtf8, inputCostUsd, inspectMcpServer, isAllowed, isJsonRpcError, isNpxInstall, isPlanStateEmpty, isPlausibleKey, listFilesSync, listSessions, loadApiKey, loadDotenv, loadHooks, loadSessionMessages, matchesTool, memoryEnabled, nestArguments, openTranscriptFile, outputCostUsd, parseEditBlocks, parseMcpSpec, parseMojeekResults, parseTranscript, prepareSpawn, projectHash, projectSettingsPath, quoteForCmdExe, rankPickerCandidates, readConfig, readProjectMemory, readTranscript, readUsageLog, recordFromLoopEvent, redactKey, registerFilesystemTools, registerMemoryTools, registerPlanTool, registerShellTools, registerSubagentTool, registerWebTools, renderMarkdown as renderDiffMarkdown, renderSummaryTable as renderDiffSummary, repairTruncatedJson, replayFromFile, resolveExecutable, restoreSnapshots, runBranches, runCommand, runHooks, sanitizeMemoryName, sanitizeName as sanitizeSessionName, saveApiKey, scavengeToolCalls, sessionPath, sessionsDir, similarity, snapshotBeforeEdits, stripHallucinatedToolMarkup, tokenizeCommand, truncateForModel, truncateForModelByTokens, webFetch, webSearch, withUtf8Codepage, writeConfig, writeMeta, writeRecord };
package/dist/index.js CHANGED
@@ -2491,9 +2491,79 @@ function formatLoopError(err) {
2491
2491
  }
2492
2492
 
2493
2493
  // src/at-mentions.ts
2494
- import { existsSync as existsSync4, readFileSync as readFileSync4, statSync as statSync2 } from "fs";
2495
- import { isAbsolute, relative, resolve } from "path";
2494
+ import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
2495
+ import { isAbsolute, join as join4, relative, resolve } from "path";
2496
2496
  var DEFAULT_AT_MENTION_MAX_BYTES = 64 * 1024;
2497
+ var DEFAULT_PICKER_IGNORE_DIRS = [
2498
+ "node_modules",
2499
+ ".git",
2500
+ "dist",
2501
+ "build",
2502
+ ".next",
2503
+ "out",
2504
+ "coverage",
2505
+ ".cache",
2506
+ ".vscode",
2507
+ ".idea",
2508
+ "target",
2509
+ ".venv",
2510
+ "venv",
2511
+ "__pycache__"
2512
+ ];
2513
+ function listFilesSync(root, opts = {}) {
2514
+ const maxResults = Math.max(1, opts.maxResults ?? 500);
2515
+ const ignore = new Set(opts.ignoreDirs ?? DEFAULT_PICKER_IGNORE_DIRS);
2516
+ const rootAbs = resolve(root);
2517
+ const out = [];
2518
+ const walk2 = (dirAbs, dirRel) => {
2519
+ if (out.length >= maxResults) return;
2520
+ let entries;
2521
+ try {
2522
+ entries = readdirSync2(dirAbs, { withFileTypes: true });
2523
+ } catch {
2524
+ return;
2525
+ }
2526
+ entries.sort((a, b) => a.name.localeCompare(b.name));
2527
+ for (const ent of entries) {
2528
+ if (out.length >= maxResults) return;
2529
+ const relPath = dirRel ? `${dirRel}/${ent.name}` : ent.name;
2530
+ if (ent.isDirectory()) {
2531
+ if (ent.name.startsWith(".") || ignore.has(ent.name)) continue;
2532
+ walk2(join4(dirAbs, ent.name), relPath);
2533
+ } else if (ent.isFile()) {
2534
+ out.push(relPath);
2535
+ }
2536
+ }
2537
+ };
2538
+ walk2(rootAbs, "");
2539
+ return out;
2540
+ }
2541
+ var AT_PICKER_PREFIX = /(?:^|\s)@([a-zA-Z0-9_./\\-]*)$/;
2542
+ function detectAtPicker(input) {
2543
+ const m = AT_PICKER_PREFIX.exec(input);
2544
+ if (!m) return null;
2545
+ const query = m[1] ?? "";
2546
+ const atOffset = input.length - query.length - 1;
2547
+ return { query, atOffset };
2548
+ }
2549
+ function rankPickerCandidates(files, query, limit = 40) {
2550
+ if (!query) return files.slice(0, limit);
2551
+ const needle = query.toLowerCase();
2552
+ const scored = [];
2553
+ for (const f of files) {
2554
+ const lower = f.toLowerCase();
2555
+ const hit = lower.indexOf(needle);
2556
+ if (hit < 0) continue;
2557
+ const slash = lower.lastIndexOf("/");
2558
+ const base = slash >= 0 ? lower.slice(slash + 1) : lower;
2559
+ let score = 2;
2560
+ if (base.startsWith(needle)) score = 0;
2561
+ else if (lower.startsWith(needle)) score = 1;
2562
+ scored.push({ path: f, score: score * 1e4 + hit });
2563
+ }
2564
+ scored.sort((a, b) => a.score - b.score);
2565
+ return scored.slice(0, limit).map((s) => s.path);
2566
+ }
2497
2567
  var AT_MENTION_PATTERN = /(?<=^|\s)@([a-zA-Z0-9_./\\-]+)/g;
2498
2568
  function expandAtMentions(text, rootDir, opts = {}) {
2499
2569
  const maxBytes = opts.maxBytes ?? DEFAULT_AT_MENTION_MAX_BYTES;
@@ -2579,11 +2649,11 @@ var defaultFs = {
2579
2649
 
2580
2650
  // src/project-memory.ts
2581
2651
  import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
2582
- import { join as join4 } from "path";
2652
+ import { join as join5 } from "path";
2583
2653
  var PROJECT_MEMORY_FILE = "REASONIX.md";
2584
2654
  var PROJECT_MEMORY_MAX_CHARS = 8e3;
2585
2655
  function readProjectMemory(rootDir) {
2586
- const path = join4(rootDir, PROJECT_MEMORY_FILE);
2656
+ const path = join5(rootDir, PROJECT_MEMORY_FILE);
2587
2657
  if (!existsSync5(path)) return null;
2588
2658
  let raw;
2589
2659
  try {
@@ -2626,17 +2696,17 @@ import {
2626
2696
  existsSync as existsSync7,
2627
2697
  mkdirSync as mkdirSync2,
2628
2698
  readFileSync as readFileSync7,
2629
- readdirSync as readdirSync3,
2699
+ readdirSync as readdirSync4,
2630
2700
  unlinkSync as unlinkSync2,
2631
2701
  writeFileSync as writeFileSync2
2632
2702
  } from "fs";
2633
2703
  import { homedir as homedir4 } from "os";
2634
- import { join as join6, resolve as resolve3 } from "path";
2704
+ import { join as join7, resolve as resolve3 } from "path";
2635
2705
 
2636
2706
  // src/skills.ts
2637
- import { existsSync as existsSync6, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
2707
+ import { existsSync as existsSync6, readFileSync as readFileSync6, readdirSync as readdirSync3, statSync as statSync3 } from "fs";
2638
2708
  import { homedir as homedir3 } from "os";
2639
- import { join as join5, resolve as resolve2 } from "path";
2709
+ import { join as join6, resolve as resolve2 } from "path";
2640
2710
  var SKILLS_DIRNAME = "skills";
2641
2711
  var SKILL_FILE = "SKILL.md";
2642
2712
  var SKILLS_INDEX_MAX_CHARS = 4e3;
@@ -2683,11 +2753,11 @@ var SkillStore = class {
2683
2753
  const out = [];
2684
2754
  if (this.projectRoot) {
2685
2755
  out.push({
2686
- dir: join5(this.projectRoot, ".reasonix", SKILLS_DIRNAME),
2756
+ dir: join6(this.projectRoot, ".reasonix", SKILLS_DIRNAME),
2687
2757
  scope: "project"
2688
2758
  });
2689
2759
  }
2690
- out.push({ dir: join5(this.homeDir, ".reasonix", SKILLS_DIRNAME), scope: "global" });
2760
+ out.push({ dir: join6(this.homeDir, ".reasonix", SKILLS_DIRNAME), scope: "global" });
2691
2761
  return out;
2692
2762
  }
2693
2763
  /**
@@ -2701,7 +2771,7 @@ var SkillStore = class {
2701
2771
  if (!existsSync6(dir)) continue;
2702
2772
  let entries;
2703
2773
  try {
2704
- entries = readdirSync2(dir, { withFileTypes: true });
2774
+ entries = readdirSync3(dir, { withFileTypes: true });
2705
2775
  } catch {
2706
2776
  continue;
2707
2777
  }
@@ -2723,11 +2793,11 @@ var SkillStore = class {
2723
2793
  if (!isValidSkillName(name)) return null;
2724
2794
  for (const { dir, scope } of this.roots()) {
2725
2795
  if (!existsSync6(dir)) continue;
2726
- const dirCandidate = join5(dir, name, SKILL_FILE);
2796
+ const dirCandidate = join6(dir, name, SKILL_FILE);
2727
2797
  if (existsSync6(dirCandidate) && statSync3(dirCandidate).isFile()) {
2728
2798
  return this.parse(dirCandidate, name, scope);
2729
2799
  }
2730
- const flatCandidate = join5(dir, `${name}.md`);
2800
+ const flatCandidate = join6(dir, `${name}.md`);
2731
2801
  if (existsSync6(flatCandidate) && statSync3(flatCandidate).isFile()) {
2732
2802
  return this.parse(flatCandidate, name, scope);
2733
2803
  }
@@ -2742,14 +2812,14 @@ var SkillStore = class {
2742
2812
  readEntry(dir, scope, entry) {
2743
2813
  if (entry.isDirectory()) {
2744
2814
  if (!isValidSkillName(entry.name)) return null;
2745
- const file = join5(dir, entry.name, SKILL_FILE);
2815
+ const file = join6(dir, entry.name, SKILL_FILE);
2746
2816
  if (!existsSync6(file)) return null;
2747
2817
  return this.parse(file, entry.name, scope);
2748
2818
  }
2749
2819
  if (entry.isFile() && entry.name.endsWith(".md")) {
2750
2820
  const stem = entry.name.slice(0, -3);
2751
2821
  if (!isValidSkillName(stem)) return null;
2752
- return this.parse(join5(dir, entry.name), stem, scope);
2822
+ return this.parse(join6(dir, entry.name), stem, scope);
2753
2823
  }
2754
2824
  return null;
2755
2825
  }
@@ -2888,12 +2958,12 @@ function projectHash(rootDir) {
2888
2958
  }
2889
2959
  function scopeDir(opts) {
2890
2960
  if (opts.scope === "global") {
2891
- return join6(opts.homeDir, USER_MEMORY_DIR, "global");
2961
+ return join7(opts.homeDir, USER_MEMORY_DIR, "global");
2892
2962
  }
2893
2963
  if (!opts.projectRoot) {
2894
2964
  throw new Error("scope=project requires a projectRoot on MemoryStore");
2895
2965
  }
2896
- return join6(opts.homeDir, USER_MEMORY_DIR, projectHash(opts.projectRoot));
2966
+ return join7(opts.homeDir, USER_MEMORY_DIR, projectHash(opts.projectRoot));
2897
2967
  }
2898
2968
  function ensureDir(p) {
2899
2969
  if (!existsSync7(p)) mkdirSync2(p, { recursive: true });
@@ -2941,7 +3011,7 @@ var MemoryStore = class {
2941
3011
  homeDir;
2942
3012
  projectRoot;
2943
3013
  constructor(opts = {}) {
2944
- this.homeDir = opts.homeDir ?? join6(homedir4(), ".reasonix");
3014
+ this.homeDir = opts.homeDir ?? join7(homedir4(), ".reasonix");
2945
3015
  this.projectRoot = opts.projectRoot ? resolve3(opts.projectRoot) : void 0;
2946
3016
  }
2947
3017
  /** Directory this store writes `scope` files into, creating it if needed. */
@@ -2952,7 +3022,7 @@ var MemoryStore = class {
2952
3022
  }
2953
3023
  /** Absolute path to a memory file (no existence check). */
2954
3024
  pathFor(scope, name) {
2955
- return join6(this.dir(scope), `${sanitizeMemoryName(name)}.md`);
3025
+ return join7(this.dir(scope), `${sanitizeMemoryName(name)}.md`);
2956
3026
  }
2957
3027
  /** True iff this store is configured with a project scope available. */
2958
3028
  hasProjectScope() {
@@ -2964,7 +3034,7 @@ var MemoryStore = class {
2964
3034
  */
2965
3035
  loadIndex(scope) {
2966
3036
  if (scope === "project" && !this.projectRoot) return null;
2967
- const file = join6(
3037
+ const file = join7(
2968
3038
  scopeDir({ homeDir: this.homeDir, scope, projectRoot: this.projectRoot }),
2969
3039
  MEMORY_INDEX_FILE
2970
3040
  );
@@ -3013,7 +3083,7 @@ var MemoryStore = class {
3013
3083
  if (!existsSync7(dir)) continue;
3014
3084
  let entries;
3015
3085
  try {
3016
- entries = readdirSync3(dir);
3086
+ entries = readdirSync4(dir);
3017
3087
  } catch {
3018
3088
  continue;
3019
3089
  }
@@ -3051,7 +3121,7 @@ var MemoryStore = class {
3051
3121
  createdAt: todayIso()
3052
3122
  };
3053
3123
  const dir = this.dir(input.scope);
3054
- const file = join6(dir, `${name}.md`);
3124
+ const file = join7(dir, `${name}.md`);
3055
3125
  const content = `${formatFrontmatter(entry)}${body}
3056
3126
  `;
3057
3127
  writeFileSync2(file, content, "utf8");
@@ -3080,12 +3150,12 @@ var MemoryStore = class {
3080
3150
  if (!existsSync7(dir)) return;
3081
3151
  let files;
3082
3152
  try {
3083
- files = readdirSync3(dir);
3153
+ files = readdirSync4(dir);
3084
3154
  } catch {
3085
3155
  return;
3086
3156
  }
3087
3157
  const mdFiles = files.filter((f) => f !== MEMORY_INDEX_FILE && f.endsWith(".md")).sort((a, b) => a.localeCompare(b));
3088
- const indexPath = join6(dir, MEMORY_INDEX_FILE);
3158
+ const indexPath = join7(dir, MEMORY_INDEX_FILE);
3089
3159
  if (mdFiles.length === 0) {
3090
3160
  if (existsSync7(indexPath)) unlinkSync2(indexPath);
3091
3161
  return;
@@ -5832,7 +5902,7 @@ function sep() {
5832
5902
 
5833
5903
  // src/code/prompt.ts
5834
5904
  import { existsSync as existsSync10, readFileSync as readFileSync11 } from "fs";
5835
- import { join as join8 } from "path";
5905
+ import { join as join9 } from "path";
5836
5906
  var CODE_SYSTEM_PROMPT = `You are Reasonix Code, a coding assistant. You have filesystem tools (read_file, write_file, list_directory, search_files, etc.) rooted at the user's working directory.
5837
5907
 
5838
5908
  # Cite or shut up \u2014 non-negotiable
@@ -5953,7 +6023,7 @@ Two different rules depending on which tool:
5953
6023
  `;
5954
6024
  function codeSystemPrompt(rootDir) {
5955
6025
  const withMemory = applyMemoryStack(CODE_SYSTEM_PROMPT, rootDir);
5956
- const gitignorePath = join8(rootDir, ".gitignore");
6026
+ const gitignorePath = join9(rootDir, ".gitignore");
5957
6027
  if (!existsSync10(gitignorePath)) return withMemory;
5958
6028
  let content;
5959
6029
  try {
@@ -5979,9 +6049,9 @@ ${truncated}
5979
6049
  // src/config.ts
5980
6050
  import { chmodSync as chmodSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
5981
6051
  import { homedir as homedir5 } from "os";
5982
- import { dirname as dirname5, join as join9 } from "path";
6052
+ import { dirname as dirname5, join as join10 } from "path";
5983
6053
  function defaultConfigPath() {
5984
- return join9(homedir5(), ".reasonix", "config.json");
6054
+ return join10(homedir5(), ".reasonix", "config.json");
5985
6055
  }
5986
6056
  function readConfig(path = defaultConfigPath()) {
5987
6057
  try {
@@ -6022,7 +6092,7 @@ function redactKey(key) {
6022
6092
  // src/version.ts
6023
6093
  import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync5 } from "fs";
6024
6094
  import { homedir as homedir6 } from "os";
6025
- import { dirname as dirname6, join as join10 } from "path";
6095
+ import { dirname as dirname6, join as join11 } from "path";
6026
6096
  import { fileURLToPath as fileURLToPath2 } from "url";
6027
6097
  var REGISTRY_URL = "https://registry.npmjs.org/reasonix/latest";
6028
6098
  var LATEST_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
@@ -6031,7 +6101,7 @@ function readPackageVersion() {
6031
6101
  try {
6032
6102
  let dir = dirname6(fileURLToPath2(import.meta.url));
6033
6103
  for (let i = 0; i < 6; i++) {
6034
- const p = join10(dir, "package.json");
6104
+ const p = join11(dir, "package.json");
6035
6105
  if (existsSync11(p)) {
6036
6106
  const pkg = JSON.parse(readFileSync13(p, "utf8"));
6037
6107
  if (pkg?.name === "reasonix" && typeof pkg.version === "string") {
@@ -6048,7 +6118,7 @@ function readPackageVersion() {
6048
6118
  }
6049
6119
  var VERSION = readPackageVersion();
6050
6120
  function cachePath(homeDirOverride) {
6051
- return join10(homeDirOverride ?? homedir6(), ".reasonix", "version-cache.json");
6121
+ return join11(homeDirOverride ?? homedir6(), ".reasonix", "version-cache.json");
6052
6122
  }
6053
6123
  function readCache(homeDirOverride) {
6054
6124
  try {
@@ -6123,9 +6193,9 @@ function isNpxInstall() {
6123
6193
  // src/usage.ts
6124
6194
  import { appendFileSync as appendFileSync2, existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync14, statSync as statSync5 } from "fs";
6125
6195
  import { homedir as homedir7 } from "os";
6126
- import { dirname as dirname7, join as join11 } from "path";
6196
+ import { dirname as dirname7, join as join12 } from "path";
6127
6197
  function defaultUsageLogPath(homeDirOverride) {
6128
- return join11(homeDirOverride ?? homedir7(), ".reasonix", "usage.jsonl");
6198
+ return join12(homeDirOverride ?? homedir7(), ".reasonix", "usage.jsonl");
6129
6199
  }
6130
6200
  function appendUsage(input) {
6131
6201
  const record = {
@@ -6247,12 +6317,14 @@ function formatLogSize(path = defaultUsageLogPath()) {
6247
6317
  }
6248
6318
  export {
6249
6319
  AT_MENTION_PATTERN,
6320
+ AT_PICKER_PREFIX,
6250
6321
  AppendOnlyLog,
6251
6322
  CODE_SYSTEM_PROMPT,
6252
6323
  CacheFirstLoop,
6253
6324
  DEFAULT_AT_MENTION_MAX_BYTES,
6254
6325
  DEFAULT_MAX_RESULT_CHARS,
6255
6326
  DEFAULT_MAX_RESULT_TOKENS,
6327
+ DEFAULT_PICKER_IGNORE_DIRS,
6256
6328
  DeepSeekClient,
6257
6329
  HOOK_EVENTS,
6258
6330
  HOOK_SETTINGS_DIRNAME,
@@ -6302,6 +6374,7 @@ export {
6302
6374
  defaultSelector,
6303
6375
  defaultUsageLogPath,
6304
6376
  deleteSession,
6377
+ detectAtPicker,
6305
6378
  detectShellOperator,
6306
6379
  diffTranscripts,
6307
6380
  emptyPlanState,
@@ -6330,6 +6403,7 @@ export {
6330
6403
  isNpxInstall,
6331
6404
  isPlanStateEmpty,
6332
6405
  isPlausibleKey,
6406
+ listFilesSync,
6333
6407
  listSessions,
6334
6408
  loadApiKey,
6335
6409
  loadDotenv,
@@ -6348,6 +6422,7 @@ export {
6348
6422
  projectHash,
6349
6423
  projectSettingsPath,
6350
6424
  quoteForCmdExe,
6425
+ rankPickerCandidates,
6351
6426
  readConfig,
6352
6427
  readProjectMemory,
6353
6428
  readTranscript,