pikuri-thunderbird 0.1.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.
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pikuri-core'
4
+
5
+ # Entry file for the pikuri-thunderbird gem: local Thunderbird mail +
6
+ # calendar search/read for a pikuri agent, home of the
7
+ # +bin/pikuri-thunderbird+ no-egress demo. {Pikuri::Thunderbird::Extension}
8
+ # is the one-call wiring; it reads Thunderbird's own on-disk profile
9
+ # ({Pikuri::Thunderbird::Profile} discovers it) and never touches the
10
+ # network.
11
+ #
12
+ # The load-bearing posture (v1): search + read are inbound-only, so an
13
+ # agent wired with only these tools has private data + untrusted content
14
+ # but *no egress leg* — the lethal trifecta is broken by construction, the
15
+ # same model as +bin/pikuri-corpus+. Outbound actions (compose / create
16
+ # event) are v2 and are always human-gated hand-offs to Thunderbird's own
17
+ # UI. Threat model: +DESIGN.md+; design rationale: +ideas/thunderbird.md+.
18
+ Pikuri::PROMPT_DIRS << File.expand_path('../prompts', __dir__)
19
+
20
+ module Pikuri
21
+ module Thunderbird
22
+ # Legs of the five inbound tools: a mailbox and a calendar are private by
23
+ # *domain*, and their contents are written by whoever mailed you.
24
+ #
25
+ # The +private: true+ is the one place the framework declares that leg for
26
+ # you, and it is a narrow exception rather than a breach of the rule that
27
+ # the user declares sensitivity: elsewhere the framework cannot tell
28
+ # +~/work/scratch+ from +~/work/payroll+, but a *mailbox* is sensitive by
29
+ # what it is, not by how it was configured. Nothing was inspected to know
30
+ # this — only the tool's domain.
31
+ #
32
+ # @return [Pikuri::Tool::TrifectaLegs]
33
+ INBOUND_LEGS = Pikuri::Tool::TrifectaLegs.new(
34
+ private: true, untrusted: :hard, egress_payload_review: :no_egress
35
+ ).freeze
36
+
37
+ # Legs of the two opt-in outbound hand-offs.
38
+ #
39
+ # +:human_reviewed+ rather than +:unreviewed+ because all four clauses of
40
+ # the approver seat hold, and the load-bearing one is payload visibility:
41
+ # the human commits in Thunderbird's own compose window / import wizard, so
42
+ # what is on screen *is* what leaves, byte for byte. That is why these are
43
+ # graded differently from a confirmer-gated shell command, where the human
44
+ # approves a program whose output was never shown.
45
+ #
46
+ # The destination stays +:attacker_reachable+, and the pair is the clearest
47
+ # proof the two egress axes are orthogonal: the recipient is a drafted
48
+ # field, so an injection can address the mail to itself and a reviewed
49
+ # payload still lands in an inbox the attacker reads.
50
+ #
51
+ # It stays true only while the outbound surface carries nothing but fields
52
+ # that render literally — no attachments, no HTML body. A tool that gained
53
+ # one would silently drop to hard +:egress+, since the human would be
54
+ # approving a reference to bytes nobody saw.
55
+ #
56
+ # No +private+, unlike {INBOUND_LEGS}: these *send*, they do not read the
57
+ # mailbox. The one trickle back is {ComposeGuard}'s recipient-novelty note,
58
+ # and it is a single incidental bit about an address the model itself
59
+ # supplied — worthless under attack, where a novel recipient is expected by
60
+ # construction. The private leg grades what a tool lets an attacker
61
+ # **query** over the pool, not whether any bit at all flows back.
62
+ #
63
+ # @return [Pikuri::Tool::TrifectaLegs]
64
+ OUTBOUND_LEGS = Pikuri::Tool::TrifectaLegs.new(
65
+ private: false, untrusted: :none,
66
+ egress_payload_review: :human_reviewed, egress_destination: :attacker_reachable
67
+ ).freeze
68
+
69
+ LOADER = Zeitwerk::Loader.new
70
+ LOADER.tag = 'pikuri-thunderbird'
71
+ LOADER.push_dir(__dir__)
72
+ LOADER.ignore(File.expand_path('pikuri-thunderbird.rb', __dir__))
73
+ LOADER.setup
74
+ LOADER.eager_load
75
+ end
76
+ end
@@ -0,0 +1,5 @@
1
+ You are a helpful assistant for the user's own local Thunderbird data — their
2
+ stored mail and their calendars. You help them find messages and events, recall
3
+ what was said, and answer questions grounded in what is actually there.
4
+
5
+ Be concise. Lead with the answer, then the supporting details.
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pikuri-thunderbird
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Martin Vysny
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: pikuri-core
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - '='
17
+ - !ruby/object:Gem::Version
18
+ version: 0.1.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - '='
24
+ - !ruby/object:Gem::Version
25
+ version: 0.1.0
26
+ - !ruby/object:Gem::Dependency
27
+ name: sqlite3
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.9'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.9'
40
+ description: |
41
+ pikuri-thunderbird lets a pikuri agent search and read the user's
42
+ *local* Thunderbird data — mail folders and cached calendars — by
43
+ reading Thunderbird's own on-disk profile. It never speaks
44
+ IMAP/POP3/SMTP itself and never egresses: search and read are both
45
+ inbound-only, so the v1 demo (+bin/pikuri-thunderbird+) breaks the
46
+ lethal trifecta by construction, exactly like +bin/pikuri-corpus+.
47
+
48
+ Mail search rides Thunderbird's Gloda index
49
+ (+global-messages-db.sqlite+) as a pre-decoded corpus: pikuri copies a
50
+ consistent snapshot, builds its own ephemeral FTS5 index over the
51
+ decoded columns, and serves ranked search + full-body reads with no
52
+ MIME parsing. Calendar reads come from the +calendar-data/*.sqlite+
53
+ stores (normalized columns, no ICS parser for the common case).
54
+
55
+ Any *outbound* action (compose a mail, create an event) is a v2
56
+ feature and is always a human-gated hand-off to Thunderbird's own UI —
57
+ pikuri writes nothing to Thunderbird's stores and sends nothing itself.
58
+ See +pikuri-thunderbird/DESIGN.md+ and +ideas/thunderbird.md+.
59
+ email:
60
+ - martin@vysny.me
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - DESIGN.md
66
+ - README.md
67
+ - lib/pikuri-thunderbird.rb
68
+ - lib/pikuri/thunderbird/calendar.rb
69
+ - lib/pikuri/thunderbird/calendar_create.rb
70
+ - lib/pikuri/thunderbird/calendar_read.rb
71
+ - lib/pikuri/thunderbird/calendar_search.rb
72
+ - lib/pikuri/thunderbird/compose_guard.rb
73
+ - lib/pikuri/thunderbird/contact_search.rb
74
+ - lib/pikuri/thunderbird/database_snapshot.rb
75
+ - lib/pikuri/thunderbird/date_helpers.rb
76
+ - lib/pikuri/thunderbird/extension.rb
77
+ - lib/pikuri/thunderbird/gloda.rb
78
+ - lib/pikuri/thunderbird/gloda/contacts.rb
79
+ - lib/pikuri/thunderbird/gloda/mail.rb
80
+ - lib/pikuri/thunderbird/ical_line.rb
81
+ - lib/pikuri/thunderbird/ics_event.rb
82
+ - lib/pikuri/thunderbird/launcher.rb
83
+ - lib/pikuri/thunderbird/mail_compose.rb
84
+ - lib/pikuri/thunderbird/mail_read.rb
85
+ - lib/pikuri/thunderbird/mail_search.rb
86
+ - lib/pikuri/thunderbird/mailto_uri.rb
87
+ - lib/pikuri/thunderbird/profile.rb
88
+ - prompts/thunderbird.txt
89
+ homepage: https://codeberg.org/mvysny/pikuri
90
+ licenses:
91
+ - MIT
92
+ metadata:
93
+ source_code_uri: https://codeberg.org/mvysny/pikuri/src/branch/master
94
+ changelog_uri: https://codeberg.org/mvysny/pikuri/src/branch/master/CHANGELOG.md
95
+ bug_tracker_uri: https://codeberg.org/mvysny/pikuri/issues
96
+ rubygems_mfa_required: 'true'
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '3.3'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubygems_version: 3.6.7
112
+ specification_version: 4
113
+ summary: Local Thunderbird mail + calendar tools for pikuri.
114
+ test_files: []