notebook

package
v0.0.0-...-3b57c73 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 22, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package notebook provides Go-native tooling for the Obsidian-style vault: incremental YAML state tracking, markdown task extraction, wiki analysis, and deterministic fan-out batch planning for the automated ingest/absorb pipelines. It is a port of the original Python scripts in tmp/Note/Scripts.

Index

Constants

View Source
const (
	FunctionScanIngestPending   = "notebook.scan_ingest_pending"
	FunctionRecordIngestSuccess = "notebook.record_ingest_success"
	FunctionScanAbsorbPending   = "notebook.scan_absorb_pending"
	FunctionRecordAbsorbSuccess = "notebook.record_absorb_success"
)

Names under which the notebook functions are registered in the workflow default FunctionRegistry, so `type: function` nodes can invoke them via e.g. `function: notebook.scan_ingest_pending`.

View Source
const DefaultJournalBatchSize = 7

DefaultJournalBatchSize is the number of journal notes aggregated per absorption group, mirroring the original Python pipeline.

View Source
const MaxFailCount = 3

MaxFailCount is the failure retry ceiling: files whose recorded fail_count reached this value are skipped by NeedsProcessing to prevent infinite retry storms.

Variables

View Source
var DefaultSkipDirs = []string{
	".git",
	".obsidian",
	".venv",
	".agents",
	"tmp",
	"99_Templates",
	"node_modules",
}

DefaultSkipDirs lists directories excluded from task scanning by default.

Functions

func CollectCandidates

func CollectCandidates(inputDir string, extensions []string) ([]string, error)

CollectCandidates recursively scans inputDir and returns the sorted list of files whose extension (case-insensitive) matches one of extensions. A missing inputDir yields an empty result.

func ComputeSHA1

func ComputeSHA1(path string) (string, error)

ComputeSHA1 returns the hexadecimal SHA-1 digest of the file's content.

func FindPending

func FindPending(candidates []string, state StateMap) ([]string, error)

FindPending filters candidates down to the files that need processing.

func FindTags

func FindTags(wikiDir, tagName string) ([]string, error)

FindTags returns the vault-relative paths of all notes carrying the tag, either in the frontmatter `tags` field (list or comma-separated string) or as an inline #tag in the body. Matching is case-insensitive.

func GetTodoTasks

func GetTodoTasks(noteDir string, skipDirs []string) (string, error)

GetTodoTasks scans all markdown files under noteDir (skipping any path containing a skipDirs component, or DefaultSkipDirs when none are given) and formats the open tasks as `- [rel_path:line] task_text` lines. It returns "No pending tasks found." when nothing is pending.

func ListAllTags

func ListAllTags(wikiDir string) (map[string]int, error)

ListAllTags counts, per unique tag, how many wiki notes carry it in their frontmatter or body. Tags repeated within a single note count once.

func NeedsProcessing

func NeedsProcessing(path string, state StateMap) (bool, error)

NeedsProcessing reports whether the file still requires processing: files unknown to the state or whose SHA-1 differs from the recorded one need processing, while files with FailCount >= MaxFailCount are skipped.

func ParseFrontmatter

func ParseFrontmatter(content string) (map[string]interface{}, string)

ParseFrontmatter extracts the YAML frontmatter and the markdown body from content. When the frontmatter is absent, malformed, or not a mapping, the full content is returned as the body with an empty metadata map.

func PlanGroups

func PlanGroups(pendingFiles []string, journalBatchSize int) [][]string

PlanGroups deterministically splits pending files into fan-out groups: journal notes (any path containing a Journal component) are sorted and batched journalBatchSize at a time (defaulting to DefaultJournalBatchSize when non-positive), while every other entity file forms a single-file group appended afterwards in input order.

func RecordAbsorbSuccess

func RecordAbsorbSuccess(ctx context.Context, nctx *workflow.NodeContext) (string, error)

RecordAbsorbSuccess implements `notebook.record_absorb_success`: it reads the fan-out results from `${tmp_dir}/absorb_results.jsonl` (a missing file is tolerated as an empty result set). For SUCCEEDED groups it records SHA-1 checkpoints of every contained Raw file into `.state/absorb_state.yaml`; for FAILED groups it increments each file's fail_count. It returns the number of successfully settled files.

Note on concurrency: state settlement relies on the workflow engine's single-instance execution constraint per workflow to avoid concurrent read-modify-write races on `.state/absorb_state.yaml`.

func RecordFailure

func RecordFailure(path string, state StateMap)

RecordFailure records a failed processing of path: the entry keeps only the path and status while incrementing FailCount. The SHA-1 is intentionally dropped so the file is retried on the next run until FailCount reaches MaxFailCount.

func RecordIngestSuccess

func RecordIngestSuccess(ctx context.Context, nctx *workflow.NodeContext) (string, error)

RecordIngestSuccess implements `notebook.record_ingest_success`: it reads the fan-out results from `${tmp_dir}/ingest_results.jsonl` (a missing file is tolerated as an empty result set), records SHA-1 checkpoints for SUCCEEDED items into `.state/ingest_state.yaml`, increments fail_count for FAILED ones, and returns a settlement summary.

Note on concurrency: state settlement relies on the workflow engine's single-instance execution constraint per workflow to avoid concurrent read-modify-write races on `.state/ingest_state.yaml`.

func RecordSuccess

func RecordSuccess(path string, state StateMap, status string, extra map[string]interface{}) error

RecordSuccess records a successful processing of path under its base name: it stores the computed SHA-1, status, today's date, resets FailCount and merges extra fields into the inline extras.

func SaveState

func SaveState(state StateMap, stateFile string) error

SaveState atomically writes the state map to stateFile as YAML, creating parent directories as needed.

func ScanAbsorbPending

func ScanAbsorbPending(ctx context.Context, nctx *workflow.NodeContext) (string, error)

ScanAbsorbPending implements `notebook.scan_absorb_pending`: under the `.state/absorb.lock` guard it scans `01_Raw/` markdown notes, filters them against `.state/absorb_state.yaml` (skipping entries at the failure ceiling), plans deterministic absorption groups via PlanGroups, and atomically writes the groups (one JSON array per line) to `${tmp_dir}/absorb_items.jsonl` for fan-out consumption. It returns a grouping summary.

func ScanIngestPending

func ScanIngestPending(ctx context.Context, nctx *workflow.NodeContext) (string, error)

ScanIngestPending implements `notebook.scan_ingest_pending`: under the `.state/ingest.lock` guard it recursively scans `Data/` for supported file types, filters them against `.state/ingest_state.yaml` (skipping entries at the failure ceiling), and atomically writes the pending vault-relative paths (one per line) to `${tmp_dir}/ingest_items.jsonl` for fan-out consumption. It returns a one-line scan summary.

func WriteFanoutItemsFile

func WriteFanoutItemsFile(groups [][]string, outputPath string) error

WriteFanoutItemsFile atomically writes groups as a JSON Lines file: one JSON array of file paths per line, ready for fan-out consumption.

Types

type BacklinkResult

type BacklinkResult struct {
	Path string
	Line int
	Text string
}

BacklinkResult is a single wikilink reference pointing at a target note.

func FindBacklinks(wikiDir, targetNote string) ([]BacklinkResult, error)

FindBacklinks returns every wiki note line referencing [[targetNote]], [[targetNote|alias]] or [[targetNote#anchor]] (case-insensitive). Paths are reported relative to the vault root (the parent of wikiDir).

type FileLock

type FileLock struct {
	// contains filtered or unexported fields
}

FileLock is a process-aware PID file lock preventing concurrent double runs. Locks held by dead processes are detected and taken over; malformed lock files are treated as stale.

func NewFileLock

func NewFileLock(lockFile string) *FileLock

NewFileLock creates a FileLock guarding the given lock file path.

func (*FileLock) Acquire

func (l *FileLock) Acquire() bool

Acquire attempts to take the lock, returning false when a live process currently holds it. It uses O_CREATE|O_EXCL to ensure atomic, race-free acquisition.

func (*FileLock) Acquired

func (l *FileLock) Acquired() bool

Acquired reports whether this lock instance currently holds the lock.

func (*FileLock) Release

func (l *FileLock) Release()

Release removes the lock file if this instance holds the lock. Removal is best effort: failures are ignored.

type SearchResult

type SearchResult struct {
	Path string
	Line int
	Text string
}

SearchResult is a single content line matching a keyword search.

func SearchKeywords

func SearchKeywords(wikiDir string, terms []string) ([]SearchResult, error)

SearchKeywords performs a case-insensitive, line-level content search for any of the terms, returning every matching line with its note path.

type StateItem

type StateItem struct {
	Path      string                 `yaml:"path"`
	SHA1      string                 `yaml:"sha1,omitempty"`
	Status    string                 `yaml:"status"`
	Date      string                 `yaml:"date,omitempty"`
	FailCount int                    `yaml:"fail_count,omitempty"`
	Extra     map[string]interface{} `yaml:",inline"`
}

StateItem is the tracked processing state of a single vault file.

type StateMap

type StateMap map[string]StateItem

StateMap is keyed by file base name (filepath.Base), fully compatible with the YAML state files produced by the original Python scripts.

func LoadState

func LoadState(stateFile string) (StateMap, error)

LoadState reads and parses a YAML state file. A missing file yields an empty (non-nil) map. Known fields are decoded into StateItem; any other fields land in Extra, keeping full compatibility with the YAML state files produced by the original Python scripts.

type TaskItem

type TaskItem struct {
	RelPath string
	Line    int
	Text    string
}

TaskItem is a single open markdown todo item with its vault-relative location.

func ParseTasksFromFile

func ParseTasksFromFile(filePath, baseDir string) ([]TaskItem, error)

ParseTasksFromFile scans a markdown file line by line and returns every open task item (lines starting with "- [ ]") together with its 1-based line number and slash-separated path relative to baseDir.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL