@chamba/core 0.3.1 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -610,6 +610,11 @@ declare class ContextBuilder {
610
610
  private collectMarkdown;
611
611
  private tryRead;
612
612
  }
613
+ /**
614
+ * All markdown notes under a vault (the same set `chamba_load_context` searches),
615
+ * skipping `.obsidian`, `.trash`, etc. Useful to show what chamba actually sees.
616
+ */
617
+ declare function listVaultNotes(fs: FilesystemPort, root: string): Promise<string[]>;
613
618
 
614
619
  /**
615
620
  * Line-based diff (LCS) producing a readable unified-ish output:
@@ -627,6 +632,13 @@ interface VaultDetection {
627
632
  path?: string;
628
633
  noteCount?: number;
629
634
  }
635
+ /**
636
+ * The vault is the directory that *contains* `.obsidian` — never `.obsidian`
637
+ * itself. A common mistake is to point `CHAMBA_OBSIDIAN_VAULT_PATH` at the
638
+ * `.obsidian` folder; correct it to its parent so writes and note search land
639
+ * in the real vault.
640
+ */
641
+ declare function normalizeVaultPath(path: string): string;
630
642
  interface DetectOptions {
631
643
  /** Explicit vault path (e.g. from CHAMBA_OBSIDIAN_VAULT_PATH). Authoritative. */
632
644
  explicitPath?: string;
@@ -835,4 +847,4 @@ declare class MultiRepoWorktreeManager {
835
847
  private git;
836
848
  }
837
849
 
838
- export { AGENT_ROLES, type AgentConfig, type AgentRole, type BranchNameInput, type BuiltContext, type ChambaConfig, type CleanupMultiResult, type CleanupResult, type ClockPort, ConfigError, type ConfigFile, type ConfigSource, type ConfigSourceKind, type ContextBuildInput, ContextBuilder, type CreateMultiInput, type CreateWorktreeInput, DEFAULT_CONFIG, DEFAULT_WORKTREE_CONFIG, type DetectOptions, type DirEntry, EFFORT_LEVELS, type Effort, FakeProcess, FilesystemMemoryStore, type FilesystemPort, type GeneratePlanInput, GitDetector, type Issue, type IssueSeverity, type ListedWorktree, type LoadConfigOptions, type LoadConfigResult, MEMORY_DIR, MODEL_CATALOG, type Memory, MemoryFilesystem, type MemoryStore, type ModelInfo, type ModelProvider, MultiRepoWorktreeManager, type MultiRepoWorktreeResult, type NoteFields, ObsidianDetector, type ParseResult, type PartialWorktreeConfig, type PlanReview, type PlanWorktreesInput, type ProcessExecOptions, type ProcessHandler, type ProcessPort, type ProcessResult, type ProjectRef, REASONING_PRIORITIES, ROLE_DESCRIPTIONS, type ReasoningPriority, type RecordedCall, type RelevantNote, type RememberInput, type ResolvedConfig, type ReviewInput, Reviewer, type SubtaskSpec, VAULT_NOTES_DIR, type ValidatePlanInput, type ValidationResult, type VaultDetection, VaultWriter, WORKSPACE_DIR, WORKSPACE_FILE, WORKSPACE_RELATIVE_PATH, type WorkerKind, type Workspace, WorkspaceScanner, type WorktreeConfig, WorktreeError, type WorktreeHandle, type WorktreeLayout, WorktreeManager, type WorktreePlanItem, type WorktreeStatus, type WriteNoteInput, type WriteNoteResult, basename, buildBranchName, buildHint, buildTicketBranch, configFileSchema, copyEnvFiles, detectGitRepos, diffLines, dirname, editorWorkspaceContent, editorWorkspaceDir, extname, generatePlanTemplate, getModel, joinPath, loadConfig, modelsByProvider, parseChambaConfig, planWorktrees, renderNote, renderWorkspaceMarkdown, resolveEffort, resolveRole, resolveWorktreeConfig, safeTicket, slugify, slugifyForGit, suggestFilesLikelyTouched, suggestSubtasks, textsEqual, validatePlan, worktreeConfigSchema, worktreePathFor, worktreeRelativePath, writeEditorWorkspace };
850
+ export { AGENT_ROLES, type AgentConfig, type AgentRole, type BranchNameInput, type BuiltContext, type ChambaConfig, type CleanupMultiResult, type CleanupResult, type ClockPort, ConfigError, type ConfigFile, type ConfigSource, type ConfigSourceKind, type ContextBuildInput, ContextBuilder, type CreateMultiInput, type CreateWorktreeInput, DEFAULT_CONFIG, DEFAULT_WORKTREE_CONFIG, type DetectOptions, type DirEntry, EFFORT_LEVELS, type Effort, FakeProcess, FilesystemMemoryStore, type FilesystemPort, type GeneratePlanInput, GitDetector, type Issue, type IssueSeverity, type ListedWorktree, type LoadConfigOptions, type LoadConfigResult, MEMORY_DIR, MODEL_CATALOG, type Memory, MemoryFilesystem, type MemoryStore, type ModelInfo, type ModelProvider, MultiRepoWorktreeManager, type MultiRepoWorktreeResult, type NoteFields, ObsidianDetector, type ParseResult, type PartialWorktreeConfig, type PlanReview, type PlanWorktreesInput, type ProcessExecOptions, type ProcessHandler, type ProcessPort, type ProcessResult, type ProjectRef, REASONING_PRIORITIES, ROLE_DESCRIPTIONS, type ReasoningPriority, type RecordedCall, type RelevantNote, type RememberInput, type ResolvedConfig, type ReviewInput, Reviewer, type SubtaskSpec, VAULT_NOTES_DIR, type ValidatePlanInput, type ValidationResult, type VaultDetection, VaultWriter, WORKSPACE_DIR, WORKSPACE_FILE, WORKSPACE_RELATIVE_PATH, type WorkerKind, type Workspace, WorkspaceScanner, type WorktreeConfig, WorktreeError, type WorktreeHandle, type WorktreeLayout, WorktreeManager, type WorktreePlanItem, type WorktreeStatus, type WriteNoteInput, type WriteNoteResult, basename, buildBranchName, buildHint, buildTicketBranch, configFileSchema, copyEnvFiles, detectGitRepos, diffLines, dirname, editorWorkspaceContent, editorWorkspaceDir, extname, generatePlanTemplate, getModel, joinPath, listVaultNotes, loadConfig, modelsByProvider, normalizeVaultPath, parseChambaConfig, planWorktrees, renderNote, renderWorkspaceMarkdown, resolveEffort, resolveRole, resolveWorktreeConfig, safeTicket, slugify, slugifyForGit, suggestFilesLikelyTouched, suggestSubtasks, textsEqual, validatePlan, worktreeConfigSchema, worktreePathFor, worktreeRelativePath, writeEditorWorkspace };
package/dist/index.js CHANGED
@@ -1005,27 +1005,7 @@ var ContextBuilder = class {
1005
1005
  return scored.slice(0, MAX_NOTES);
1006
1006
  }
1007
1007
  async collectMarkdown(root) {
1008
- const out = [];
1009
- const visit = async (dir, depth) => {
1010
- if (depth > NOTE_SCAN_MAX_DEPTH) return;
1011
- let entries;
1012
- try {
1013
- entries = await this.fs.readDir(dir);
1014
- } catch {
1015
- return;
1016
- }
1017
- for (const entry of entries) {
1018
- const full = joinPath(dir, entry.name);
1019
- if (entry.isDirectory) {
1020
- if (SKIP_DIRS.has(entry.name)) continue;
1021
- await visit(full, depth + 1);
1022
- } else if (entry.name.toLowerCase().endsWith(".md")) {
1023
- out.push(full);
1024
- }
1025
- }
1026
- };
1027
- await visit(root, 0);
1028
- return out;
1008
+ return listVaultNotes(this.fs, root);
1029
1009
  }
1030
1010
  async tryRead(path) {
1031
1011
  try {
@@ -1035,6 +1015,29 @@ var ContextBuilder = class {
1035
1015
  }
1036
1016
  }
1037
1017
  };
1018
+ async function listVaultNotes(fs, root) {
1019
+ const out = [];
1020
+ const visit = async (dir, depth) => {
1021
+ if (depth > NOTE_SCAN_MAX_DEPTH) return;
1022
+ let entries;
1023
+ try {
1024
+ entries = await fs.readDir(dir);
1025
+ } catch {
1026
+ return;
1027
+ }
1028
+ for (const entry of entries) {
1029
+ const full = joinPath(dir, entry.name);
1030
+ if (entry.isDirectory) {
1031
+ if (SKIP_DIRS.has(entry.name)) continue;
1032
+ await visit(full, depth + 1);
1033
+ } else if (entry.name.toLowerCase().endsWith(".md")) {
1034
+ out.push(full);
1035
+ }
1036
+ }
1037
+ };
1038
+ await visit(root, 0);
1039
+ return out;
1040
+ }
1038
1041
  function extractKeywords(task) {
1039
1042
  const seen = /* @__PURE__ */ new Set();
1040
1043
  for (const raw of task.toLowerCase().split(/[^a-z0-9áéíóúñ]+/i)) {
@@ -1108,6 +1111,10 @@ function textsEqual(oldText, newText) {
1108
1111
  }
1109
1112
 
1110
1113
  // src/workspace/obsidian-detector.ts
1114
+ function normalizeVaultPath(path) {
1115
+ const trimmed = path.replace(/[/\\]+$/, "");
1116
+ return basename(trimmed) === ".obsidian" ? dirname(trimmed) : trimmed;
1117
+ }
1111
1118
  var COUNT_MAX_DEPTH = 8;
1112
1119
  var SKIP_DIRS2 = /* @__PURE__ */ new Set([".obsidian", ".trash", "node_modules", ".git"]);
1113
1120
  var ObsidianDetector = class {
@@ -1117,12 +1124,9 @@ var ObsidianDetector = class {
1117
1124
  fs;
1118
1125
  async detect(opts) {
1119
1126
  if (opts.explicitPath) {
1120
- if (await this.fs.exists(opts.explicitPath)) {
1121
- return {
1122
- found: true,
1123
- path: opts.explicitPath,
1124
- noteCount: await this.countNotes(opts.explicitPath)
1125
- };
1127
+ const vault = normalizeVaultPath(opts.explicitPath);
1128
+ if (await this.fs.exists(vault)) {
1129
+ return { found: true, path: vault, noteCount: await this.countNotes(vault) };
1126
1130
  }
1127
1131
  return { found: false };
1128
1132
  }
@@ -1809,8 +1813,10 @@ export {
1809
1813
  generatePlanTemplate,
1810
1814
  getModel,
1811
1815
  joinPath,
1816
+ listVaultNotes,
1812
1817
  loadConfig,
1813
1818
  modelsByProvider,
1819
+ normalizeVaultPath,
1814
1820
  parseChambaConfig,
1815
1821
  planWorktrees,
1816
1822
  renderNote,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chamba/core",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Core logic for chamba: workspace scanner, plan + heuristic reviewer, git worktrees, Obsidian, memory — no Node APIs, no LLM",
5
5
  "license": "MIT",
6
6
  "type": "module",