Class: Agent::Sessions::Adapters::Base
- Inherits:
-
Object
- Object
- Agent::Sessions::Adapters::Base
- Includes:
- Enumeration, HomeExpansion
- Defined in:
- lib/agent/sessions/adapters/base.rb
Overview
Base class for every agent adapter. Subclass this directly, never another adapter: the DSL keeps its configuration in singleton instance variables, which Ruby does not carry down a second level of inheritance, so a subclass of a subclass would silently declare nothing.
An instance memoizes what it resolves. Build a new instance per resolution rather than reusing one across changes to the env hash.
What lives here is Layer 1: where a store is, what it declares, and whether disk agrees. Turning that store into sessions is Layer 2 and lives in Enumeration, included below — the two halves met at 460 lines in one class and were split before Layer 3 readers could make it three.
Direct Known Subclasses
Amp, Claude, Codex, Copilot, Cursor, CursorIde, Gemini, Grok, Opencode, Pi, Qwen
Constant Summary collapse
- FIDELITIES =
%i[full messages metadata unsupported].freeze
Constants included from Enumeration
Class Attribute Summary collapse
-
.agent_name ⇒ Object
readonly
Returns the value of attribute agent_name.
-
.declared_warnings ⇒ Object
readonly
Returns the value of attribute declared_warnings.
-
.documented_value ⇒ Object
readonly
Returns the value of attribute documented_value.
-
.label_text ⇒ Object
readonly
Returns the value of attribute label_text.
-
.verified_on_date ⇒ Object
readonly
Returns the value of attribute verified_on_date.
Class Method Summary collapse
-
.fidelity_value ⇒ Object
:unsupported is the honest default for an adapter that has not declared what a reader could reconstruct from its format.
- .homedir_config ⇒ Object
-
.reader_class ⇒ Object
The Layer 3 reader for this agent, or nil while it has none.
- .store_configs ⇒ Object
Instance Method Summary collapse
- #base_dir ⇒ Object
-
#initialize(env: ENV) ⇒ Base
constructor
A new instance of Base.
- #locate ⇒ Object
- #retention ⇒ Object
- #retention_source ⇒ Object
-
#verify ⇒ Object
Checks every declared store against disk.
- #warnings ⇒ Object
Methods included from Enumeration
#bytes_for, #encode_project, #project_dir_name, #project_path_for, #project_paths, #session_id_from, #sessions, #sessions_for_project, #started_at_for, #updated_at_for
Constructor Details
#initialize(env: ENV) ⇒ Base
Returns a new instance of Base.
77 78 79 |
# File 'lib/agent/sessions/adapters/base.rb', line 77 def initialize(env: ENV) @env = env end |
Class Attribute Details
.agent_name ⇒ Object (readonly)
Returns the value of attribute agent_name.
25 26 27 |
# File 'lib/agent/sessions/adapters/base.rb', line 25 def agent_name @agent_name end |
.declared_warnings ⇒ Object (readonly)
Returns the value of attribute declared_warnings.
25 26 27 |
# File 'lib/agent/sessions/adapters/base.rb', line 25 def declared_warnings @declared_warnings end |
.documented_value ⇒ Object (readonly)
Returns the value of attribute documented_value.
25 26 27 |
# File 'lib/agent/sessions/adapters/base.rb', line 25 def documented_value @documented_value end |
.label_text ⇒ Object (readonly)
Returns the value of attribute label_text.
25 26 27 |
# File 'lib/agent/sessions/adapters/base.rb', line 25 def label_text @label_text end |
.verified_on_date ⇒ Object (readonly)
Returns the value of attribute verified_on_date.
25 26 27 |
# File 'lib/agent/sessions/adapters/base.rb', line 25 def verified_on_date @verified_on_date end |
Class Method Details
.fidelity_value ⇒ Object
:unsupported is the honest default for an adapter that has not declared what a reader could reconstruct from its format.
29 |
# File 'lib/agent/sessions/adapters/base.rb', line 29 def fidelity_value = @fidelity_value || :unsupported |
.homedir_config ⇒ Object
31 |
# File 'lib/agent/sessions/adapters/base.rb', line 31 def homedir_config = @homedir_config || raise(Error, "#{inspect} declares no homedir") |
.reader_class ⇒ Object
The Layer 3 reader for this agent, or nil while it has none. nil is what makes Agent::Sessions.read raise UnsupportedFormat instead of handing back a reader that quietly yields nothing.
40 |
# File 'lib/agent/sessions/adapters/base.rb', line 40 def reader_class = nil |
.store_configs ⇒ Object
33 34 35 |
# File 'lib/agent/sessions/adapters/base.rb', line 33 def store_configs @store_configs || raise(Error, "#{inspect} declares no store") end |
Instance Method Details
#base_dir ⇒ Object
133 134 135 136 137 138 139 |
# File 'lib/agent/sessions/adapters/base.rb', line 133 def base_dir @base_dir ||= begin config = self.class.homedir_config root = resolver.home(config[:name]).to_s config[:join] ? File.join(root, config[:join]) : root end end |
#locate ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/agent/sessions/adapters/base.rb', line 81 def locate Store.new( agent: self.class.agent_name, label: self.class.label_text, documented: self.class.documented_value, verified_on: self.class.verified_on_date, effective: layers.first, layers: layers, env_overrides: env_overrides, retention: retention, retention_source: retention_source, warnings: warnings ) end |
#retention ⇒ Object
141 |
# File 'lib/agent/sessions/adapters/base.rb', line 141 def retention = nil |
#retention_source ⇒ Object
142 |
# File 'lib/agent/sessions/adapters/base.rb', line 142 def retention_source = :none |
#verify ⇒ Object
Checks every declared store against disk. The design doc says each adapter declares its own checks, and each one does: its store_configs decide what is looked for and whether an absence is a failure or drift. Content-level checks (first record type, encoding round-trip) need file reads and wait for Layer 3. An adapter that needs its own can override this and call super.
The skip gate is the same signal Store#installed? uses: any declared store
exists. It is deliberately NOT base-dir existence — ~/.cursor is created by
the Cursor editor with no agent store in it (observed 2026-08-05), and the
old gate made doctor report FAIL while where said "(not installed)".
A missing store proves nothing on its own (never used? layout moved? the
gem cannot tell), so :fail is reserved for the one case with evidence:
some store exists, proving the agent records data here, while a required
one is absent — the layout-moved signature.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/agent/sessions/adapters/base.rb', line 110 def verify unless layers.any?(&:exists?) detail = if Dir.exist?(base_dir) "#{base_dir} exists but holds none of the declared stores" else "#{base_dir} does not exist" end return [check(:skip, "agent is installed", detail)] end self.class.store_configs.map do |config| location = resolve(config) claim = "store #{config[:kind]} exists" if location.exists? check(:pass, claim, detail_for(location)) elsif config[:optional] check(:drift, claim, "#{location.path} not found (optional; undocumented layouts drift)") else check(:fail, claim, "#{location.path} not found") end end end |
#warnings ⇒ Object
144 145 146 |
# File 'lib/agent/sessions/adapters/base.rb', line 144 def warnings (self.class.declared_warnings || []).dup end |