@chamba/core 0.5.1 → 0.6.0

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
@@ -396,30 +396,6 @@ declare function slugify(title: string): string;
396
396
  */
397
397
  declare function renderNote(fields: NoteFields): string;
398
398
 
399
- interface WriteNoteInput {
400
- vaultPath: string;
401
- title: string;
402
- content: string;
403
- /** Subfolder slug under `proyectos/`; defaults to the title slug. */
404
- projectSlug?: string;
405
- tags?: string[];
406
- }
407
- interface WriteNoteResult {
408
- notePath: string;
409
- }
410
- /** Subfolder inside the vault where chamba writes its summaries. */
411
- declare const VAULT_NOTES_DIR = "proyectos";
412
- /**
413
- * Write a structured summary note into an Obsidian vault at
414
- * `<vault>/proyectos/<date>-<slug>.md` with valid YAML frontmatter.
415
- */
416
- declare class VaultWriter {
417
- private readonly fs;
418
- private readonly clock;
419
- constructor(fs: FilesystemPort, clock: ClockPort);
420
- write(input: WriteNoteInput): Promise<WriteNoteResult>;
421
- }
422
-
423
399
  interface RuleConvention {
424
400
  editor: string;
425
401
  /** Path relative to a repo root. */
@@ -484,6 +460,59 @@ interface Workspace {
484
460
  */
485
461
  declare function renderWorkspaceMarkdown(ws: Workspace): string;
486
462
 
463
+ /** Seed note written at the vault root with the initial workspace context. */
464
+ declare const VAULT_OVERVIEW_FILE = "Workspace overview.md";
465
+ interface SeedVaultInput {
466
+ /** Vault root — the directory that will hold `.obsidian/`. */
467
+ vaultPath: string;
468
+ /** Scanned workspace, rendered into the overview note. */
469
+ workspace: Workspace;
470
+ }
471
+ interface SeedVaultResult {
472
+ vaultPath: string;
473
+ markerPath: string;
474
+ overviewPath: string;
475
+ createdMarker: boolean;
476
+ createdOverview: boolean;
477
+ }
478
+ /**
479
+ * Bootstrap an Obsidian vault: drop the `.obsidian/` marker that makes a folder a
480
+ * vault, and seed a "Workspace overview" note from the scan. Idempotent — it never
481
+ * recreates the marker or overwrites an existing overview (the user may edit it).
482
+ * NO LLM, no Node APIs (principle 6): all IO goes through `FilesystemPort`.
483
+ */
484
+ declare class VaultInitializer {
485
+ private readonly fs;
486
+ private readonly clock;
487
+ constructor(fs: FilesystemPort, clock: ClockPort);
488
+ seed({ vaultPath, workspace }: SeedVaultInput): Promise<SeedVaultResult>;
489
+ private renderOverview;
490
+ }
491
+
492
+ interface WriteNoteInput {
493
+ vaultPath: string;
494
+ title: string;
495
+ content: string;
496
+ /** Subfolder slug under `proyectos/`; defaults to the title slug. */
497
+ projectSlug?: string;
498
+ tags?: string[];
499
+ }
500
+ interface WriteNoteResult {
501
+ notePath: string;
502
+ }
503
+ /** Subfolder inside the vault where chamba writes its summaries. */
504
+ declare const VAULT_NOTES_DIR = "proyectos";
505
+ /**
506
+ * Write a structured summary note into an Obsidian vault at
507
+ * `<vault>/proyectos/<date>-<slug>.md` with valid YAML frontmatter.
508
+ */
509
+ declare class VaultWriter {
510
+ private readonly fs;
511
+ private readonly clock;
512
+ constructor(fs: FilesystemPort, clock: ClockPort);
513
+ write(input: WriteNoteInput): Promise<WriteNoteResult>;
514
+ }
515
+
487
516
  type IssueSeverity = 'error' | 'warning';
488
517
  interface Issue {
489
518
  code: string;
@@ -887,4 +916,4 @@ declare class MultiRepoWorktreeManager {
887
916
  private git;
888
917
  }
889
918
 
890
- 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, RULE_SOURCES, type ReasoningPriority, type RecordedCall, type RelevantNote, type RememberInput, type ResolvedConfig, type ReviewInput, Reviewer, type RuleConvention, type RuleExcerpt, type RuleSource, 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, detectRuleSources, diffLines, dirname, editorWorkspaceContent, editorWorkspaceDir, extname, generatePlanTemplate, getModel, joinPath, listVaultNotes, loadConfig, modelsByProvider, normalizeVaultPath, parseChambaConfig, planWorktrees, readRuleExcerpts, renderNote, renderWorkspaceMarkdown, resolveEffort, resolveRole, resolveWorktreeConfig, safeTicket, slugify, slugifyForGit, suggestFilesLikelyTouched, suggestSubtasks, textsEqual, validatePlan, worktreeConfigSchema, worktreePathFor, worktreeRelativePath, writeEditorWorkspace };
919
+ 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, RULE_SOURCES, type ReasoningPriority, type RecordedCall, type RelevantNote, type RememberInput, type ResolvedConfig, type ReviewInput, Reviewer, type RuleConvention, type RuleExcerpt, type RuleSource, type SeedVaultInput, type SeedVaultResult, type SubtaskSpec, VAULT_NOTES_DIR, VAULT_OVERVIEW_FILE, type ValidatePlanInput, type ValidationResult, type VaultDetection, VaultInitializer, 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, detectRuleSources, diffLines, dirname, editorWorkspaceContent, editorWorkspaceDir, extname, generatePlanTemplate, getModel, joinPath, listVaultNotes, loadConfig, modelsByProvider, normalizeVaultPath, parseChambaConfig, planWorktrees, readRuleExcerpts, renderNote, renderWorkspaceMarkdown, resolveEffort, resolveRole, resolveWorktreeConfig, safeTicket, slugify, slugifyForGit, suggestFilesLikelyTouched, suggestSubtasks, textsEqual, validatePlan, worktreeConfigSchema, worktreePathFor, worktreeRelativePath, writeEditorWorkspace };
package/dist/index.js CHANGED
@@ -600,6 +600,47 @@ function escapeYaml(value) {
600
600
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
601
601
  }
602
602
 
603
+ // src/obsidian/vault-init.ts
604
+ var VAULT_OVERVIEW_FILE = "Workspace overview.md";
605
+ var VaultInitializer = class {
606
+ constructor(fs, clock) {
607
+ this.fs = fs;
608
+ this.clock = clock;
609
+ }
610
+ fs;
611
+ clock;
612
+ async seed({ vaultPath, workspace }) {
613
+ const obsidianDir = joinPath(vaultPath, ".obsidian");
614
+ const markerPath = joinPath(obsidianDir, "app.json");
615
+ let createdMarker = false;
616
+ if (!await this.fs.exists(markerPath)) {
617
+ await this.fs.mkdir(obsidianDir);
618
+ await this.fs.writeFile(markerPath, "{}\n");
619
+ createdMarker = true;
620
+ }
621
+ const overviewPath = joinPath(vaultPath, VAULT_OVERVIEW_FILE);
622
+ let createdOverview = false;
623
+ if (!await this.fs.exists(overviewPath)) {
624
+ await this.fs.writeFile(overviewPath, this.renderOverview(workspace));
625
+ createdOverview = true;
626
+ }
627
+ return { vaultPath, markerPath, overviewPath, createdMarker, createdOverview };
628
+ }
629
+ renderOverview(workspace) {
630
+ const frontmatter = [
631
+ "---",
632
+ "title: Workspace overview",
633
+ `date: ${this.clock.today()}`,
634
+ "tags: [chamba, workspace, overview]",
635
+ "source: chamba",
636
+ "---",
637
+ ""
638
+ ].join("\n");
639
+ return `${frontmatter}${renderWorkspaceMarkdown(workspace)}
640
+ `;
641
+ }
642
+ };
643
+
603
644
  // src/obsidian/vault-writer.ts
604
645
  var VAULT_NOTES_DIR = "proyectos";
605
646
  var VaultWriter = class {
@@ -634,6 +675,7 @@ var TESTS_RE = /\b(tests?|vitest|jest|spec|unit test|integration test)\b/i;
634
675
  var PLACEHOLDER_RE = /\b(todo|tbd|fixme|placeholder)\b/i;
635
676
  var DELETION_RE = /\b(delete[ds]?|deleting|remove[ds]?|removing|removal|drop(?:ping|s|ped)?|eliminat\w*|deprecat\w*|elimina\w*|borra\w*|quita\w*)\b/i;
636
677
  var ORPHAN_CHECK_RE = /\b(orphan\w*|dead[-\s]?code|unused\s+(?:export|import|symbol|function|code|reference)|referential|callers?|knip|ts-prune|depcheck|type-?check|typecheck|tsc|build\s+(?:passes|green|clean))\b/i;
678
+ var RESOLVED_MARKER_RE = /\b(answers?|answered|resolved|resuelt\w*|respuesta|respondid\w*|decidid\w*|confirmed|confirmad\w*)\b|→|=>/i;
637
679
  var DEFAULT_MODULES = /* @__PURE__ */ new Set([
638
680
  "packages",
639
681
  "examples",
@@ -728,6 +770,24 @@ function validatePlan(input) {
728
770
  "After removing code, verify nothing was orphaned: run the build/typecheck and a dead-code check (e.g. knip / ts-prune), not just a grep."
729
771
  );
730
772
  }
773
+ const openQuestions = [
774
+ .../* @__PURE__ */ new Set([
775
+ ...listItems(getSection(sec, "open question")),
776
+ ...listItems(getSection(sec, "preguntas abiertas")),
777
+ ...listItems(getSection(sec, "clarification"))
778
+ ])
779
+ ];
780
+ const unresolved = openQuestions.filter((q) => isConcrete(q) && !RESOLVED_MARKER_RE.test(q));
781
+ if (unresolved.length > 0) {
782
+ issues.push({
783
+ code: "unresolved-open-questions",
784
+ severity: "warning",
785
+ message: `${unresolved.length} open question(s) in the plan are unresolved. Ask the human and fold the answers in before executing.`
786
+ });
787
+ suggestions.push(
788
+ 'Resolve the "Open questions" with the human (or mark each one answered) before creating worktrees.'
789
+ );
790
+ }
731
791
  return { issues, suggestions, riskFlags };
732
792
  }
733
793
  function sections(plan) {
@@ -1925,6 +1985,8 @@ export {
1925
1985
  RULE_SOURCES,
1926
1986
  Reviewer,
1927
1987
  VAULT_NOTES_DIR,
1988
+ VAULT_OVERVIEW_FILE,
1989
+ VaultInitializer,
1928
1990
  VaultWriter,
1929
1991
  WORKSPACE_DIR,
1930
1992
  WORKSPACE_FILE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chamba/core",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
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",