Commit graph halkyon/apps/learn/halkyon_learn_flutter/test/feature/studyset/data
Author SHA1 Message Date
54e212a51c
feat(learn): Learn's agent, an MCP server suggesting in shared studysets
Some checks failed
CI / check (push) Failing after 1m56s
Halkyon's ADR 0044, step 6c (D7, D49 to D52). apps/learn/halkyon_learn_agent
is one executable, `halkyon-agent --instance URL sign-in | sync | mcp`:

- sign-in keeps the token read from stdin, signs in with it, makes the
  agent's key pair on its first sign-in, keeps it before setting the
  public halves on the register (agents.setKeys), and syncs;
- it opens its data as the app's _openPersonData does, on
  halkyon_learn_core and halkyon_content: its own SQLite database, the
  sync's space router, its keys and those of the spaces shared with it,
  and the repositories of studysets, cards, notes, paths, files and
  feedback;
- mcp serves ten tools over stdio (dart_mcp): list, read and search the
  studysets shared with it, suggest a change or a new card or note,
  report, list a studyset's suggestions and reply. Each syncs first and
  a suggestion again at once; a refusal is the tool's error;
- its files live in $XDG_CONFIG_HOME/halkyon-agent/<host>, 0700 and
  0600, refused when others may read them (D50);
- tool/install.sh builds it with `dart build cli` (libsodium and SQLite
  bundled) and copies it to its user on the host, the build before kept
  (D52).

The synced gateways of learning paths and files, and the fakes of the
core's gateways, move into halkyon_learn_core (its testing.dart), which
the app's tests and the agent's share.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-11 22:08:31 +01:00
d09625d43e
refactor(content,core,app,editor,learn): Learn's content in pure Dart, for its agent
ADR 0044's D49 (amended in building it): what reads and seals Learn's
content moves out of the Flutter packages, so Learn's agent, which runs
without Flutter, shares it rather than repeating the privacy rules.

packages/halkyon_content (new, pure Dart) takes from halkyon_app the
envelope and its cipher, SealedFile, UnlockedAccountKeys, shared
spaces' gateway with SharedKeys and KeyPins, FileCache and
FileServerGateway, with their fakes and tests; halkyon_app exports it,
so no app changes. Its rich_text.dart takes RichContent from
halkyon_editor, which exports it. newAccountKeys makes an agent's key
pair. halkyon_core takes DelayedDeletions and gains SyncRequests, what a
synced gateway asks of the sync, which SyncService implements.

apps/learn/halkyon_learn_core (new, pure Dart) takes Learn's privacy,
sync, payloads and the models, codecs, gateways and repositories of
studysets, cards, notes, tags and feedback, with what they reach of
files, learning paths, citations and study options; the app imports them
from there. A subject's icon, colour and name stay in the app
(SubjectLook); what only the app shows (progress, exam coverage, the
card browser, deletions' waits) stays too. Nothing changes for people
using the apps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-11 22:08:16 +01:00
9b344141ef
feat(learn): share a studyset with people from its Share sheet
Share opens one sheet (Halkyon's ADR 0044, D29): the people first, then
the community. A studyset of the person's own offers Share with people,
which says what it does, moves it into a space of its own with its
progress told and Abort, and opens it there (StudysetSharingCubit). A
shared one lists its members (SpaceMembersCubit): the Owner invites by
handle as Editor or Viewer, changes roles, hands on and removes, and
deletes it for everyone; anyone leaves, the Owner naming who takes it
on; each refusal is said. A member's row opens their safety code
(twelve groups of five digits) to mark compared, and changed keys are
flagged, trusted only after comparing (D32). The community row leads to
the privacy dialog or publishing as Share did, and is off for a shared
studyset (D27).

A studyset knows its space and whether the person only views it
(Studyset.sharedIn, viewOnly, from the sync engine's grants). Its mark
is Lucide's users icon, "Shared · private" (D31). A Viewer's studyset
screen, its options, its topics and the move sheet offer nothing that
writes, and say they can view and study it (D30); the engine refuses
their writes on the device in any case. A shared top isn't moved,
archived or deleted from its options, and nothing moves in or out of
its space.

Whats-New: Share a studyset with people: invite them by their handle as editors or viewers, and compare safety codes to know nobody stands between you.
Whats-New-De: Teile ein Lernset mit Personen: Lade sie über ihr Handle als Bearbeiter:innen oder Betrachter:innen ein und vergleicht Sicherheitscodes, damit niemand zwischen euch steht.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-11 15:53:09 +01:00
5dd7575dd6
refactor(app,learn): people's files on the device shared in halkyon_app
ADR 0043's recommendation, for Todo's attachments: what Learn had for its
files on the device moves into halkyon_app, unchanged but for its names,
and Learn uses it from there.

- FileCache, DirectoryFileCache (Learn's AssetFileCache): the files by
  their SHA-256 in a folder of the person's, and which wait to be
  uploaded.
- FileServerGateway, ServerpodFileServerGateway (Learn's
  AssetServerGateway): halkyon_base's files endpoint, taking the module's
  caller rather than Learn's client; FileLimitReached, FileRoom.
- Their fakes in halkyon_app's testing: MemoryFileCache,
  FakeFileServerGateway, sha256Of.
- SealedFile: the format every app seals a file in (HLKF, version 1),
  sealing with halkyon_app's ContentCipher; Learn's Privacy seals and
  opens its files with it, for the same context as before, so every file
  sealed so far opens as it did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-11 01:19:40 +01:00
9868dc27c6
feat(learn): a studyset's subject, picked from a fixed list (ADR 0041)
A top studyset is filed under one of 44 subjects in six groups (the
developer's decisions of 9 and 10 Nov 2026): languages as one, computing
in five, Other / not sure last. Each has a Lucide icon and a default
colour, which picking it gives the studyset, its own to change from then
on. The studyset's sheet picks it (pickSubject); a sub-studyset shows its
top studyset's (subjectOf) and offers none. The payload keeps it as
`subject` (schema 8), so archives and published studysets carry it; an
ID this version doesn't know is kept and reads as none.

Whats-New: A studyset can now be filed under a subject, which gives it that subject's colour.
Whats-New-De: Ein Lernset lässt sich jetzt einem Fach zuordnen, das ihm dessen Farbe gibt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-10 19:20:49 +01:00
920e1c6c13
perf(learn): Delete now leaves Recently deleted at once
Deleting a studyset for good blanks and deletes every card, note, path
and PDF of its subtree before the studyset's row goes, which took about
3 s while the studyset stayed in Recently deleted. Now the repository's
Recently deleted leaves it out at once (StudysetRepository.leaving and
stay, applied to the value last read without reading again), the
deletion runs in the background, still one at a time in
StudysetDeletions' queue, and where it fails the studyset shows there
again, read anew with what is left of it, and a snack bar says so.

Whats-New: Delete now in Recently deleted takes a studyset away at once.
Whats-New-De: „Jetzt löschen“ unter „Zuletzt gelöscht“ entfernt ein Lernset sofort.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-08 11:48:40 +01:00
648dfe4051
refactor(learn): the editor's general parts move to halkyon_editor (ADR 0033, D37)
Todo stores editor documents too, so the document, the editor, its view,
the format bar, links, the clipboard, scripts and EditorBlocks move, with
their strings and tests, to a shared package on the same appflowy_editor
fork. What is Learn's alone stays in Learn on top of it, and what the
editor took from it directly is inverted: EditorBlocks gains textMarks,
formatActions and onEditorClosed, RichContentEditor a wrapEditor, and an
InsertableBlock's name takes the BuildContext. Learn's screens use
LearnContentEditor and LearnContentView, which add Learn's blocks and the
grammar check. Learn behaves as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-07 21:49:48 +01:00
e368bba2dd
feat(privacy): a private studyset's files are sealed with its key (ADR 0019, D5)
- `AssetRepository` seals a file of a private studyset with its tree's key
  for its asset row before hashing it (`AssetSealing`, which `Privacy`
  does): the row's hash and size and the file uploaded are the sealed
  file's, the upload says it is encrypted, and the row's payload, sealed
  too, carries the file name and the hash of what was sealed (asset
  schema 2). A download is checked against the row's hash, opened for its
  row and checked against what was sealed. This device keeps the sealed
  file to upload and the opened one, by its own hash, for what reads files
  by path.
- The same file is a row per key: in a private and a readable studyset, or
  two private trees, it is two.
- Every place adding a file names its studyset: the editors' pictures and
  sounds (`StudysetFiles`, which every screen of a studyset and the PDF
  reader set), PDFs and screenshots, Anki imports, copies and their updates
  (a copy's top studyset is made first, so its files take its key), and
  accepted suggestions (by their item's tree).
- Making a tree private or not, or moving a topic into another tree, moves
  its files: each under another key is added anew under the tree's, the
  content names the new row (whole `asset:` values and a PDF's file, never
  text), and the old row is blanked and deleted once nothing else names it.
- Tests: a private studyset's file never uploads readable; a sealed file
  moved to another row, or under a key not open here, doesn't open; a
  changed file is refused by its hash; one row per key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-23 14:13:10 +02:00
649499be23
chore: Halkyon Learn moves into apps/learn
Its server, client, app and curator, and the tools that write its
assets (maps, Anki fixtures, icons), as they are; paths are fixed in
the commits that follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-22 18:11:02 +02:00