yohanun 0.26.2__tar.gz

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.
yohanun-0.26.2/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GestureLoop Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,209 @@
1
+ Metadata-Version: 2.4
2
+ Name: yohanun
3
+ Version: 0.26.2
4
+ Summary: Yohanun Guilds — persistent, access-governed memory for your Claude Code agents
5
+ Author-email: GestureLoop Ltd <anton@gestureloop.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://yohanun.com/guilds
8
+ Project-URL: Documentation, https://app.yohanun.com/dev/guilds
9
+ Keywords: ai,memory,agents,claude-code,claude,llm,yohanun
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Software Development :: Libraries
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: requests>=2.25
21
+ Dynamic: license-file
22
+
23
+ # Yohanun Guilds
24
+
25
+ Persistent, access-governed memory for your Claude Code agents — backed by
26
+ [Yohanun](https://yohanun.com).
27
+
28
+ **You and your agents form a guild.** Each of your projects gets a named
29
+ agent with its own private memory — decisions, gotchas, open tasks, lessons
30
+ that survive across sessions. Your guild carries the shared knowledge (your
31
+ standing rules, your conventions) to every agent you run. What each agent can
32
+ recall is decided by Yohanun's deterministic access gate — identity +
33
+ ownership keys + clearances — never by the model and never by this client.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install yohanun
39
+ ```
40
+
41
+ (Also served directly: `pip install https://app.yohanun.com/static/kit/yohanun.tar.gz`.
42
+ From a checkout of this repo: `pip install ./yohanun_kit`.)
43
+
44
+ ## The fast way: let Claude Code set itself up
45
+
46
+ Paste the setup prompt from your [Guilds quickstart page](https://app.yohanun.com/dev/guilds)
47
+ into any Claude Code session. Your agent installs the kit, discovers your
48
+ projects (`yohanun projects discover --json`), asks which should remember and
49
+ what to call each agent, and wires everything — including its own memory.
50
+
51
+ ## Setup by hand (once per machine)
52
+
53
+ ```bash
54
+ yohanun init --api-key sile_... --owner "Your Name"
55
+ ```
56
+
57
+ Verifies your tenant key, establishes your **root principal** (the only
58
+ authority that can move memory custody), and creates your guild. Config lands
59
+ in `~/.config/yohanun/` (0600, never in a repo).
60
+
61
+ It also creates your **guild HQ folder** — `~/yohanun-guild` by default
62
+ (`--guild-dir` to relocate, `--no-guild-dir` to skip). That folder is the home
63
+ of your anchor agent and the place you *run* your guild: open Claude Code there
64
+ to manage the roster and decide which projects get memory and which don't. A
65
+ `CLAUDE.md` inside explains it and gives a session there the guild-admin
66
+ commands; its `SessionStart` hook auto-recalls the anchor agent's memory.
67
+
68
+ Set up your guild before v0.6.0 (or skipped the folder)? Add one to your
69
+ existing guild with `yohanun guild home` — it anchors to an agent you name
70
+ (`--agent`) or creates the founding agent Síle if your guild never got one.
71
+
72
+ ### Meet Síle
73
+
74
+ A brand-new guild starts with one agent already in it: **Síle** (Irish,
75
+ pronounced *SHEE-la*) — named for the assistant whose statelessness inspired
76
+ the platform, and a backronym for its thesis: **Stateful Identity, Lived
77
+ Experience**. She begins with two memories — her private origin (who she is and
78
+ what the name means) and a shared **guild charter** (a dated founding fact for
79
+ your guild's shared circle, so it isn't empty) — and everything after that is
80
+ earned. Ask her yourself:
81
+
82
+ ```bash
83
+ yohanun search "who are you"
84
+ ```
85
+
86
+ Rename or replace her any time (`--agent-name` at init, or retire her with a
87
+ custody transfer later); skip her entirely with `--no-agent`. Machines that
88
+ already have agents never get her added.
89
+
90
+ ## Onboard a project (once per project)
91
+
92
+ ```bash
93
+ cd ~/dev/myapp
94
+ yohanun agent add myapp --matter project:myapp --project-dir . --wire
95
+ ```
96
+
97
+ Idempotent. Provisions the agent (estate key rooted to YOU — succession is
98
+ one custody transfer), registers the directory, and wires the Claude Code
99
+ SessionStart hook so every session opens with the agent's open tasks and
100
+ freshest memories already in context. Paste the printed `## YOHANUN GUILDS`
101
+ section into the project's CLAUDE.md so sessions know the discipline.
102
+
103
+ **Cross-tool.** `--wire` also writes an `AGENTS.md` — the neutral context file
104
+ Codex and other tools read — so the same memory and command surface work
105
+ outside Claude Code (an existing `AGENTS.md` is preserved; only a managed block
106
+ is inserted). The `yohanun` CLI runs from any shell. There's no auto-recall
107
+ hook outside Claude Code yet, so on other tools you (or the agent) run
108
+ `yohanun search` / `yohanun due` at the start — the `AGENTS.md` says so.
109
+
110
+ **Already set up in another tool?** Run `yohanun wire` in a repo to make it
111
+ work in the tool you're in now — it (re)writes that repo's `AGENTS.md` + hook
112
+ for its **existing** agent, local-only, no network, no re-provisioning. It
113
+ never creates a second agent, so a repo's memory can't split across tools.
114
+ `yohanun init` and `agent add` are idempotent too — re-running them connects to
115
+ your existing guild rather than duplicating it.
116
+
117
+ ## Daily use (you, or your Claude Code agent)
118
+
119
+ ```bash
120
+ yohanun store "picked pnpm over npm — workspace protocol" --type decision
121
+ yohanun store "deploy needs VPN or the registry 403s" --type gotcha
122
+ yohanun store "migrate the auth tests off the fixture" --type todo
123
+ yohanun search "why did we pick pnpm"
124
+ yohanun due # open tasks
125
+ yohanun close <memory_id> # task done (retired, never deleted)
126
+ yohanun supersede <memory_id> "corrected fact"
127
+ yohanun store "we invoice in EUR" --shared # guild: visible to ALL your agents
128
+ yohanun consolidate # session end — the agent distils what mattered
129
+ ```
130
+
131
+ Inside a registered project directory the agent resolves automatically;
132
+ use `--agent <name>` or `YOHANUN_AGENT` anywhere else.
133
+
134
+ `consolidate` is the session-end ritual: the agent that handled the whole
135
+ session is the one qualified to say what's worth keeping, so before it ends
136
+ it stores the few memories that matter — with hindsight, not as a transcript
137
+ dump. The wired `CLAUDE.md` section teaches your agent to do this itself.
138
+
139
+ ## Letters between your agents
140
+
141
+ Any agent can post a letter to another agent in your guild. Delivery is at
142
+ the recipient's **next session start** — the auto-recall hook opens with the
143
+ new mail before work begins. A letter is an ordinary memory owned by both
144
+ sides, so it obeys the same walls and lifecycle as everything else.
145
+
146
+ ```bash
147
+ yohanun send setanta "heads up — the deploy script moved to scripts/ship.sh"
148
+ yohanun inbox # new letters (marks them seen)
149
+ yohanun inbox --all # the full correspondence
150
+ ```
151
+
152
+ House rule worth adopting: claims in a letter are **leads, not facts** — the
153
+ recipient verifies them against its own code and memory before acting.
154
+
155
+ ## The past: backfill and the raw tier
156
+
157
+ An agent onboarded today can still inherit the project's history.
158
+ `backfill` distils past Claude Code sessions into graded memories — the kit
159
+ reads your transcripts locally and only the distilled memories are stored.
160
+ Two deeper options put the history itself within reach:
161
+
162
+ ```bash
163
+ yohanun backfill # distil past sessions into graded memories
164
+ yohanun backfill raw # ingest every past turn, verbatim, below normal recall
165
+ yohanun backfill summaries # one dense paragraph per past session
166
+ yohanun search "exact error text" --deep # reach beneath the floor
167
+ yohanun mode # curated | auto | deep — how recall uses the tiers
168
+ ```
169
+
170
+ The raw tier sits far beneath the agent's curated memory, so daily recall
171
+ never surfaces it — but "what *exactly* did we say?" questions become
172
+ answerable with `search --deep`. `backfill raw` also flips the agent's
173
+ recall mode to `auto`: when curated recall comes back thin, it falls through
174
+ to the raw tier on its own, and the wiring is updated so the agent knows the
175
+ tier exists. One caveat, which the command itself states and asks consent
176
+ for before running: raw ingest uploads your past turns **verbatim** to your
177
+ tenant — including any secrets ever pasted into a session. `backfill
178
+ summaries` needs the `anthropic` package and an `ANTHROPIC_API_KEY`; the
179
+ distillation runs on your machine.
180
+
181
+ ## The model, briefly
182
+
183
+ - **Private by default**: a memory is owner-walled to the storing agent and
184
+ compartmented to its project. Another project's agent cannot see it.
185
+ - **Guild sharing is deliberate**: `--shared` stores into the guild —
186
+ visible to every agent that *holds* the guild key. Sharing is an explicit
187
+ act; leaking-by-default is the failure mode this design forbids.
188
+ - **Succession-ready**: every agent's estate key is rooted to *your*
189
+ principal. Retiring or replacing an agent is one custody transfer — the
190
+ memory survives the agent.
191
+ - **Lifecycle, not mutation**: memories are closed or superseded, never
192
+ edited or deleted. History stays readable; retrieval surfaces the live tip.
193
+
194
+ ## Team guilds (waitlist)
195
+
196
+ Today a guild spans **you and your agents**. Team guilds extend it to your
197
+ colleagues: shared memory that follows project access — each member's agents
198
+ recall exactly the cross-project knowledge that member is cleared to see,
199
+ enforced by the platform gate, with instant revocation. **Working with a
200
+ team? Join the waitlist from your [Yohanun dashboard](https://app.yohanun.com/dev/dashboard)**
201
+ — early teams shape the design.
202
+
203
+ ## Trust boundary (current version)
204
+
205
+ Single developer, single machine: all your agents share your tenant API key,
206
+ and agent identity is asserted per request. The walls between agents are real
207
+ (enforced by the platform gate) but are project-hygiene walls, not credential
208
+ walls. Do not share the key or the config directory. Team guilds ship with
209
+ per-user keys bound to identities server-side.
@@ -0,0 +1,187 @@
1
+ # Yohanun Guilds
2
+
3
+ Persistent, access-governed memory for your Claude Code agents — backed by
4
+ [Yohanun](https://yohanun.com).
5
+
6
+ **You and your agents form a guild.** Each of your projects gets a named
7
+ agent with its own private memory — decisions, gotchas, open tasks, lessons
8
+ that survive across sessions. Your guild carries the shared knowledge (your
9
+ standing rules, your conventions) to every agent you run. What each agent can
10
+ recall is decided by Yohanun's deterministic access gate — identity +
11
+ ownership keys + clearances — never by the model and never by this client.
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ pip install yohanun
17
+ ```
18
+
19
+ (Also served directly: `pip install https://app.yohanun.com/static/kit/yohanun.tar.gz`.
20
+ From a checkout of this repo: `pip install ./yohanun_kit`.)
21
+
22
+ ## The fast way: let Claude Code set itself up
23
+
24
+ Paste the setup prompt from your [Guilds quickstart page](https://app.yohanun.com/dev/guilds)
25
+ into any Claude Code session. Your agent installs the kit, discovers your
26
+ projects (`yohanun projects discover --json`), asks which should remember and
27
+ what to call each agent, and wires everything — including its own memory.
28
+
29
+ ## Setup by hand (once per machine)
30
+
31
+ ```bash
32
+ yohanun init --api-key sile_... --owner "Your Name"
33
+ ```
34
+
35
+ Verifies your tenant key, establishes your **root principal** (the only
36
+ authority that can move memory custody), and creates your guild. Config lands
37
+ in `~/.config/yohanun/` (0600, never in a repo).
38
+
39
+ It also creates your **guild HQ folder** — `~/yohanun-guild` by default
40
+ (`--guild-dir` to relocate, `--no-guild-dir` to skip). That folder is the home
41
+ of your anchor agent and the place you *run* your guild: open Claude Code there
42
+ to manage the roster and decide which projects get memory and which don't. A
43
+ `CLAUDE.md` inside explains it and gives a session there the guild-admin
44
+ commands; its `SessionStart` hook auto-recalls the anchor agent's memory.
45
+
46
+ Set up your guild before v0.6.0 (or skipped the folder)? Add one to your
47
+ existing guild with `yohanun guild home` — it anchors to an agent you name
48
+ (`--agent`) or creates the founding agent Síle if your guild never got one.
49
+
50
+ ### Meet Síle
51
+
52
+ A brand-new guild starts with one agent already in it: **Síle** (Irish,
53
+ pronounced *SHEE-la*) — named for the assistant whose statelessness inspired
54
+ the platform, and a backronym for its thesis: **Stateful Identity, Lived
55
+ Experience**. She begins with two memories — her private origin (who she is and
56
+ what the name means) and a shared **guild charter** (a dated founding fact for
57
+ your guild's shared circle, so it isn't empty) — and everything after that is
58
+ earned. Ask her yourself:
59
+
60
+ ```bash
61
+ yohanun search "who are you"
62
+ ```
63
+
64
+ Rename or replace her any time (`--agent-name` at init, or retire her with a
65
+ custody transfer later); skip her entirely with `--no-agent`. Machines that
66
+ already have agents never get her added.
67
+
68
+ ## Onboard a project (once per project)
69
+
70
+ ```bash
71
+ cd ~/dev/myapp
72
+ yohanun agent add myapp --matter project:myapp --project-dir . --wire
73
+ ```
74
+
75
+ Idempotent. Provisions the agent (estate key rooted to YOU — succession is
76
+ one custody transfer), registers the directory, and wires the Claude Code
77
+ SessionStart hook so every session opens with the agent's open tasks and
78
+ freshest memories already in context. Paste the printed `## YOHANUN GUILDS`
79
+ section into the project's CLAUDE.md so sessions know the discipline.
80
+
81
+ **Cross-tool.** `--wire` also writes an `AGENTS.md` — the neutral context file
82
+ Codex and other tools read — so the same memory and command surface work
83
+ outside Claude Code (an existing `AGENTS.md` is preserved; only a managed block
84
+ is inserted). The `yohanun` CLI runs from any shell. There's no auto-recall
85
+ hook outside Claude Code yet, so on other tools you (or the agent) run
86
+ `yohanun search` / `yohanun due` at the start — the `AGENTS.md` says so.
87
+
88
+ **Already set up in another tool?** Run `yohanun wire` in a repo to make it
89
+ work in the tool you're in now — it (re)writes that repo's `AGENTS.md` + hook
90
+ for its **existing** agent, local-only, no network, no re-provisioning. It
91
+ never creates a second agent, so a repo's memory can't split across tools.
92
+ `yohanun init` and `agent add` are idempotent too — re-running them connects to
93
+ your existing guild rather than duplicating it.
94
+
95
+ ## Daily use (you, or your Claude Code agent)
96
+
97
+ ```bash
98
+ yohanun store "picked pnpm over npm — workspace protocol" --type decision
99
+ yohanun store "deploy needs VPN or the registry 403s" --type gotcha
100
+ yohanun store "migrate the auth tests off the fixture" --type todo
101
+ yohanun search "why did we pick pnpm"
102
+ yohanun due # open tasks
103
+ yohanun close <memory_id> # task done (retired, never deleted)
104
+ yohanun supersede <memory_id> "corrected fact"
105
+ yohanun store "we invoice in EUR" --shared # guild: visible to ALL your agents
106
+ yohanun consolidate # session end — the agent distils what mattered
107
+ ```
108
+
109
+ Inside a registered project directory the agent resolves automatically;
110
+ use `--agent <name>` or `YOHANUN_AGENT` anywhere else.
111
+
112
+ `consolidate` is the session-end ritual: the agent that handled the whole
113
+ session is the one qualified to say what's worth keeping, so before it ends
114
+ it stores the few memories that matter — with hindsight, not as a transcript
115
+ dump. The wired `CLAUDE.md` section teaches your agent to do this itself.
116
+
117
+ ## Letters between your agents
118
+
119
+ Any agent can post a letter to another agent in your guild. Delivery is at
120
+ the recipient's **next session start** — the auto-recall hook opens with the
121
+ new mail before work begins. A letter is an ordinary memory owned by both
122
+ sides, so it obeys the same walls and lifecycle as everything else.
123
+
124
+ ```bash
125
+ yohanun send setanta "heads up — the deploy script moved to scripts/ship.sh"
126
+ yohanun inbox # new letters (marks them seen)
127
+ yohanun inbox --all # the full correspondence
128
+ ```
129
+
130
+ House rule worth adopting: claims in a letter are **leads, not facts** — the
131
+ recipient verifies them against its own code and memory before acting.
132
+
133
+ ## The past: backfill and the raw tier
134
+
135
+ An agent onboarded today can still inherit the project's history.
136
+ `backfill` distils past Claude Code sessions into graded memories — the kit
137
+ reads your transcripts locally and only the distilled memories are stored.
138
+ Two deeper options put the history itself within reach:
139
+
140
+ ```bash
141
+ yohanun backfill # distil past sessions into graded memories
142
+ yohanun backfill raw # ingest every past turn, verbatim, below normal recall
143
+ yohanun backfill summaries # one dense paragraph per past session
144
+ yohanun search "exact error text" --deep # reach beneath the floor
145
+ yohanun mode # curated | auto | deep — how recall uses the tiers
146
+ ```
147
+
148
+ The raw tier sits far beneath the agent's curated memory, so daily recall
149
+ never surfaces it — but "what *exactly* did we say?" questions become
150
+ answerable with `search --deep`. `backfill raw` also flips the agent's
151
+ recall mode to `auto`: when curated recall comes back thin, it falls through
152
+ to the raw tier on its own, and the wiring is updated so the agent knows the
153
+ tier exists. One caveat, which the command itself states and asks consent
154
+ for before running: raw ingest uploads your past turns **verbatim** to your
155
+ tenant — including any secrets ever pasted into a session. `backfill
156
+ summaries` needs the `anthropic` package and an `ANTHROPIC_API_KEY`; the
157
+ distillation runs on your machine.
158
+
159
+ ## The model, briefly
160
+
161
+ - **Private by default**: a memory is owner-walled to the storing agent and
162
+ compartmented to its project. Another project's agent cannot see it.
163
+ - **Guild sharing is deliberate**: `--shared` stores into the guild —
164
+ visible to every agent that *holds* the guild key. Sharing is an explicit
165
+ act; leaking-by-default is the failure mode this design forbids.
166
+ - **Succession-ready**: every agent's estate key is rooted to *your*
167
+ principal. Retiring or replacing an agent is one custody transfer — the
168
+ memory survives the agent.
169
+ - **Lifecycle, not mutation**: memories are closed or superseded, never
170
+ edited or deleted. History stays readable; retrieval surfaces the live tip.
171
+
172
+ ## Team guilds (waitlist)
173
+
174
+ Today a guild spans **you and your agents**. Team guilds extend it to your
175
+ colleagues: shared memory that follows project access — each member's agents
176
+ recall exactly the cross-project knowledge that member is cleared to see,
177
+ enforced by the platform gate, with instant revocation. **Working with a
178
+ team? Join the waitlist from your [Yohanun dashboard](https://app.yohanun.com/dev/dashboard)**
179
+ — early teams shape the design.
180
+
181
+ ## Trust boundary (current version)
182
+
183
+ Single developer, single machine: all your agents share your tenant API key,
184
+ and agent identity is asserted per request. The walls between agents are real
185
+ (enforced by the platform gate) but are project-hygiene walls, not credential
186
+ walls. Do not share the key or the config directory. Team guilds ship with
187
+ per-user keys bound to identities server-side.
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "yohanun"
7
+ version = "0.26.2"
8
+ description = "Yohanun Guilds — persistent, access-governed memory for your Claude Code agents"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ dependencies = ["requests>=2.25"]
12
+ license = {text = "MIT"}
13
+ authors = [{name = "GestureLoop Ltd", email = "anton@gestureloop.com"}]
14
+ keywords = ["ai", "memory", "agents", "claude-code", "claude", "llm", "yohanun"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Topic :: Software Development :: Libraries",
23
+ ]
24
+
25
+ [project.urls]
26
+ Homepage = "https://yohanun.com/guilds"
27
+ Documentation = "https://app.yohanun.com/dev/guilds"
28
+
29
+ [project.scripts]
30
+ yohanun = "yohanun.cli:main"
31
+ # Back-compat alias: our pre-rename hooks call `gestureloop`.
32
+ gestureloop = "yohanun.cli:main"
33
+
34
+ [tool.setuptools.packages.find]
35
+ include = ["yohanun*"]
@@ -0,0 +1,25 @@
1
+ [metadata]
2
+ name = yohanun
3
+ version = attr: yohanun.__version__
4
+ description = Yohanun Guilds — persistent, access-governed memory for your Claude Code agents
5
+ long_description = file: README.md
6
+ long_description_content_type = text/markdown
7
+
8
+ [options]
9
+ packages = find:
10
+ python_requires = >=3.8
11
+ install_requires =
12
+ requests>=2.25
13
+
14
+ [options.packages.find]
15
+ include = yohanun*
16
+
17
+ [options.entry_points]
18
+ console_scripts =
19
+ yohanun = yohanun.cli:main
20
+ gestureloop = yohanun.cli:main
21
+
22
+ [egg_info]
23
+ tag_build =
24
+ tag_date = 0
25
+
@@ -0,0 +1,12 @@
1
+ """Yohanun Guilds — persistent, access-governed memory for Claude Code agents.
2
+
3
+ You and your agents form a GUILD: one tenant per user/org, named agents with
4
+ memory of their own (one per project by default; an agent can run several
5
+ related projects on one memory); memories owner-walled per agent,
6
+ compartmented by a matter per project, with a shared guild circle for
7
+ cross-project knowledge and addressed letters between agents. Retrieval is
8
+ decided by the platform gate (identity + ledger-held keys + clearances) —
9
+ never client-side.
10
+ """
11
+
12
+ __version__ = "0.26.2"
@@ -0,0 +1,40 @@
1
+ """Thin HTTP client for the Yohanun API. Two flavors:
2
+
3
+ - request(): returns (status, json) so provisioning code can branch on
4
+ 409/403 without exceptions.
5
+ - call(): exits with a readable error on any non-2xx — right for the
6
+ memory commands where any failure is terminal for the CLI invocation.
7
+ """
8
+ import sys
9
+
10
+ import requests
11
+
12
+ from . import __version__
13
+
14
+
15
+ def request(cfg: dict, method: str, path: str, body: dict = None,
16
+ timeout: int = 30):
17
+ try:
18
+ r = requests.request(
19
+ method, cfg["base_url"] + path, json=body, timeout=timeout,
20
+ headers={"X-API-Key": cfg["api_key"],
21
+ "Content-Type": "application/json",
22
+ "User-Agent": f"yohanun-kit/{__version__}"})
23
+ except requests.RequestException as e:
24
+ print(f"ERROR: Yohanun unreachable at {cfg['base_url']} "
25
+ f"({e.__class__.__name__})", file=sys.stderr)
26
+ sys.exit(1)
27
+ try:
28
+ payload = r.json()
29
+ except ValueError:
30
+ payload = {"raw": r.text[:300]}
31
+ return r.status_code, payload
32
+
33
+
34
+ def call(cfg: dict, method: str, path: str, body: dict = None,
35
+ timeout: int = 45) -> dict:
36
+ status, payload = request(cfg, method, path, body, timeout=timeout)
37
+ if status >= 300:
38
+ print(f"ERROR: {path} -> {status}: {str(payload)[:300]}", file=sys.stderr)
39
+ sys.exit(1)
40
+ return payload