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 ¶
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.
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
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 ¶
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
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 ¶
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
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 ¶
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
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
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 ¶
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
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.
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.