config

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package config resolves where the library lives and how the tool behaves.

Override order, highest first: the --db flag, FILIATION_DB, the config file, then a per-user application data directory (ADR-006). One library per user, not one per directory — a database in the working directory produces a scattering of half-built graphs, and the whole product thesis is a library that accumulates over years.

Because the default location differs per OS, the CLI prints the path on first run. Without that, users cannot find their own data.

Configuration is resolved, never prompted for. config has to work from a test, an MCP server and a web handler, none of which have a terminal — so it reports (FirstRun, Warnings) and the front door does the asking. Save is how an answer given once survives to the next run.

A leaf package, with one exception: it imports internal/errs, so that a bad config file arrives at the CLI as errs.ErrInvalidConfig rather than as an opaque string. errs imports nothing itself, so this cannot create a cycle, and without the exception the sentinel package cannot do its job.

Index

Constants

View Source
const (
	// DefaultMaxNodes is the primary control on how large a graph may grow.
	// 500 is large enough to be a map of a literature and small enough to
	// finish in well under a minute, and it costs 5 credits of a 1,000/day
	// allowance (D11). Depth is only a secondary guard: at the measured 70-100
	// references per STEM paper, depth 2 alone is ~5,000 nodes, so this number
	// is what actually stops an expansion.
	DefaultMaxNodes = 500

	// DefaultMaxDepth stops a run that would otherwise wander a long way from
	// the seed before the node budget bites. It is rarely the binding limit.
	DefaultMaxDepth = 3

	// DefaultMaxRefsPerWork caps how many candidates one work may contribute to
	// the frontier. A review article citing 800 papers would otherwise consume
	// an entire budget by itself. It does not cap edges: every reference is
	// recorded, because they arrive free inside the response and throwing them
	// away would falsify the graph.
	DefaultMaxRefsPerWork = 100

	// FileName is the settings file: the global one in the per-user directory
	// (ADR-006), and each library folder's own (ADR-011).
	FileName = "filiation.toml"

	// DBName is the database of a v0.1 or v0.2 library, which is a file with
	// no folder around it.
	DBName = "library.db"

	// LibraryDBName is the database inside a library folder.
	LibraryDBName = "filiation.db"

	// DefaultLibraryName is the first library's name, and its folder's.
	DefaultLibraryName = "My Library"
)

Defaults. Every one of these is a number the user may override; none of them is a limit of the tool.

View Source
const EnvDB = "FILIATION_DB"

EnvDB overrides the library path from the environment. It sits between the --db flag and everything else.

Variables

This section is empty.

Functions

func CloudService added in v0.3.0

func CloudService(path string) string

CloudService names the sync service whose folder path is inside — OneDrive, iCloud Drive, Dropbox or Google Drive — or returns "" for an ordinary folder.

It matters for one reason. SQLite in WAL mode keeps a library in three files, and sync tools copy them separately, which corrupts the database. So when a library folder syncs, its database is kept in the per-user application directory instead, and the folder holds everything else (ADR-011). PDFs sync safely; the database does not.

Detection reads the path, and on Windows the variables OneDrive sets. It is a guard, not a guarantee: a sync tool configured somewhere unusual will not be seen, and fil says where the database is so a person can check.

func DefaultCacheDir

func DefaultCacheDir() (string, error)

DefaultCacheDir is where the HTTP response cache lives unless told otherwise.

It is deliberately not beside the library. The cache is regenerable and the library is not, so it goes where each OS expects disposable data — %LocalAppData% on Windows, ~/Library/Caches on macOS, $XDG_CACHE_HOME or ~/.cache on Linux — where cleanup tools and backup exclusions already treat it as such.

func DefaultCompiledDir added in v0.3.0

func DefaultCompiledDir() (string, error)

DefaultCompiledDir is where the PDF extractor keeps its compiled code, so it starts in a tenth of a second rather than three. Regenerable, like the HTTP cache, so it sits beside it.

func DefaultDir

func DefaultDir() (string, error)

DefaultDir is the per-user directory holding the global settings and, for a library in a cloud sync folder, its database.

os.UserConfigDir is stdlib and already correct on all three targets — %AppData% on Windows, ~/Library/Application Support on macOS, and $XDG_CONFIG_HOME or ~/.config on Linux — so the adrg/xdg dependency suggested by ADR-006 is not taken.

func DocumentsDir added in v0.3.0

func DocumentsDir() (string, error)

DocumentsDir is the user's Documents folder. Linux reads XDG_DOCUMENTS_DIR, which user-dirs sets, and falls back to ~/Documents; macOS has only the latter.

Types

type Config

type Config struct {
	// DBPath is absolute. Everything downstream may open it without further
	// cleaning.
	DBPath string

	// Folder is the library folder (ADR-011), absolute: papers/, Inbox/ and
	// exports/ live in it. Empty for a library that is only a database — one
	// made by v0.1 or v0.2, or named with --db — until fil library move gives
	// it a folder.
	Folder string

	// Name is the library's name: what --library takes, and what the global
	// settings list it under. Empty for a library that is only a database.
	Name string

	// Cloud names the sync service the folder is in, or is empty. When it is
	// set, the database is kept outside the folder (CloudService).
	Cloud string

	// ContactEmail is sent to OpenAlex as mailto. It is optional: the spikes
	// measured byte-identical rate-limit headers with and without it (D11), so
	// requiring it would punish the user for a politeness that buys them
	// nothing. Absent, Warnings says so once and the tool runs.
	ContactEmail string

	MaxNodes       int
	MaxDepth       int
	MaxRefsPerWork int

	// FolderCollections makes each folder in papers/ a collection (ADR-012).
	// On by default; a library's own settings file can turn it off.
	FolderCollections bool

	// ConfigPath is the global settings file, whether or not it existed. The
	// CLI needs it to tell the user which file to edit.
	ConfigPath string

	// LibraryConfigPath is the library folder's own settings file, or empty
	// for a library with no folder.
	LibraryConfigPath string

	// FirstRun reports that no library has been chosen yet. The CLI uses it to
	// offer a location and to print where the library lives — without that,
	// users cannot find their own data, because the default differs on every
	// OS (ADR-006).
	FirstRun bool

	// Libraries are the library folders the global settings list.
	Libraries []Library
	// contains filtered or unexported fields
}

Config is the resolved configuration: what the tool will actually do, after the flags, the environment, the files and the defaults have been reconciled.

func Load

func Load(opts Options) (*Config, error)

Load resolves configuration.

Which library, highest priority first: the --db flag, FILIATION_DB, --library, the global settings (default_library, then a v0.2 db_path, then the first library listed), and on a first run a new folder proposed under Documents/Filiation.

Budgets, lowest priority first: the defaults, the global settings, then the library folder's own settings. Precedence is per field, not per source.

A missing settings file is the normal case on a first run and is not an error. A malformed one is: falling back to defaults would let a typo in max_nodes silently expand a graph nobody asked for.

func (*Config) DropDatabaseOnly added in v0.3.0

func (c *Config) DropDatabaseOnly()

DropDatabaseOnly forgets the v0.2 library named by db_path. fil library move uses it once the library has a folder; the old file stays on disk.

func (*Config) Forget added in v0.3.0

func (c *Config) Forget(folder string)

Forget removes the library at folder from the global list, for a library that is about to be listed again at a new folder. Nothing on disk changes.

func (*Config) IsRecordedDatabase added in v0.3.0

func (c *Config) IsRecordedDatabase(path string) bool

IsRecordedDatabase reports whether path is the v0.2 library db_path names.

func (*Config) MakeDefault added in v0.3.0

func (c *Config) MakeDefault()

MakeDefault makes this library the one fil opens when not told otherwise.

func (*Config) Save

func (c *Config) Save() error

Save writes the settings, creating directories as needed.

It is how a location chosen on first run survives to the second. Choosing is not this package's job: config never prompts, because it has to work where there is no terminal. The front door asks; this records the answer.

For a library folder it lists the library in the global settings — as the default, on a first run — and writes the folder's own settings file if there is none yet. For a library that is only a database it records db_path and the budgets in the global settings, as v0.2 did.

func (*Config) UseFolder added in v0.3.0

func (c *Config) UseFolder(dir string) error

UseFolder points this configuration at the library folder dir, which need not exist yet. The database goes in the folder, unless the folder is inside a cloud sync service: then it goes in the per-user directory, under a name that the folder's path makes unique.

func (*Config) Warnings

func (c *Config) Warnings() []string

Warnings is what the CLI should tell the user without refusing to run.

It returns strings rather than printing, because config must stay usable from a test, an MCP server and a web handler, none of which have a terminal to print to.

type Library added in v0.3.0

type Library struct {
	Name   string `toml:"name"`
	Folder string `toml:"folder"`
	// Database is where the database is kept when not in the folder — set for
	// a folder in a cloud sync service. Empty means Folder/filiation.db.
	Database string `toml:"database,omitempty"`
}

Library is one library folder the global settings list.

type Options

type Options struct {
	// DBFlag is the value of --db, empty when the flag was not passed. It wins
	// over every other source, and names a database with no folder.
	DBFlag string

	// LibraryFlag is the value of --library: a library's name, or its folder.
	LibraryFlag string

	// Dir is the directory holding the global settings file. Empty means the
	// per-user default from DefaultDir. Tests set it so they never read or
	// write the real one.
	Dir string

	// DocumentsDir replaces the user's Documents folder, under which the first
	// library is proposed. Tests set it so they never write to the real one.
	DocumentsDir string
}

Options are the inputs to Load that do not come from a settings file.

Jump to

Keyboard shortcuts

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