detached fa7d8d8

refactor: split source into packages/{provider,core,tui,agent}

Single Go module, four top-level packages under packages/. Import
paths become github.com/patriceckhart/zot/packages/<name>; downstream
consumers can depend on individual packages without pulling the rest.

Layout:
  packages/provider/     LLM clients + catalog
  packages/provider/auth/ credential store + OAuth + login server
  packages/core/         agent loop, sessions, cost
  packages/tui/          terminal toolkit + chat view
  packages/agent/        CLI wiring, system prompt
    extensions/ extproto/ modes/ tools/ skills/ swarm/
    sdk/  (was pkg/zotcore, package renamed zotcore -> sdk)
    ext/  (was pkg/zotext, package renamed zotext -> ext)

internal/ and pkg/ removed. The internal/assets logo moved into
packages/provider/auth/assets.

Public Go SDK identifiers renamed:
  pkg/zotcore (package zotcore) -> packages/agent/sdk (package sdk)
  pkg/zotext  (package zotext)  -> packages/agent/ext (package ext)

This breaks Go-based extensions and embedders; the JSON wire protocol
for extensions and RPC is unchanged, so non-Go extensions, already-
built extension binaries, and zot rpc consumers are unaffected.

Docs, examples, and the built-in write-zot-extension skill updated
for the new paths and identifiers. Shadow-bug fixes in code samples
(ext := ext.New -> e := ext.New).
commit
fa7d8d8be57408de792532ec21b56ec4e6477042
author
patriceckhart · · 2026-05-27 07:07 UTC
parent
fb3e1af
signature
unsigned
200 files · +272 -266
M README.md +22 -18
@@ -1,6 +1,6 @@
11 <div align="center">
22 <a href="https://www.zot.sh">
3- <img src="internal/assets/zot-logo.png" alt="zot coding agent harness" width="130" height="130" />
3+ <img src="packages/provider/auth/assets/zot-logo.png" alt="zot coding agent harness" width="130" height="130" />
44 </a>
55 </div>
66 <p align="center">
@@ -175,7 +175,7 @@ When the sandbox is on (see `/jail`), all four tools refuse paths outside the se
175175
176176 Two ways to drive zot from another program:
177177
178-- **Go in-process**: import `github.com/patriceckhart/zot/pkg/zotcore`. One `Runtime` per project; `Prompt(ctx, text, images)` returns a channel of `Event`. Small example in `examples/sdk/`.
178+- **Go in-process**: import `github.com/patriceckhart/zot/packages/agent/sdk`. One `Runtime` per project; `Prompt(ctx, text, images)` returns a channel of `Event`. Small example in `examples/sdk/`.
179179 - **Any language, out-of-process**: spawn `zot rpc` as a subprocess and exchange newline-delimited JSON over its stdin/stdout. Wire format and event schema in [docs/rpc.md](docs/rpc.md). Reference clients live under `examples/rpc/`.
180180
181181 Both interfaces share the same event schema, so transcripts captured by one can be replayed through the other.
@@ -197,7 +197,7 @@ Type `/` in the TUI to open the autocomplete popup. Available commands:
197197 | `/swarm` | Spawn, monitor, and chat with background subagents. Each runs in parallel with your main session and shares its working directory. |
198198 | `/skills` | List discovered skills (SKILL.md files) and preview their bodies. |
199199 | `/compact` | Summarize the transcript into one message to free up context. |
200-| `/study` | Run the canned prompt "Read and understand everything in the current directory." so the agent has full project context before you start asking targeted questions. Pass a path — typed, drag-dropped, or selected via `@` — to target a specific file or directory instead: `/study [dir:internal/]`, `/study cmd/zot/main.go`. |
200+| `/study` | Run the canned prompt "Read and understand everything in the current directory." so the agent has full project context before you start asking targeted questions. Pass a path — typed, drag-dropped, or selected via `@` — to target a specific file or directory instead: `/study [dir:packages/]`, `/study cmd/zot/main.go`. |
201201 | `/jail` | Confine tools to the current directory. |
202202 | `/unjail` | Allow tools to touch paths outside again. |
203203 | `/reload-ext` | Hot-reload all extensions (re-read manifests, respawn subprocesses, rebuild tool registry). |
@@ -600,7 +600,7 @@ For development, point `zot --ext <path>` at a working directory and skip the in
600600
601601 ### Reference
602602
603-`examples/extensions/` ships reference implementations in Go, TypeScript, Node, and shell. See [docs/extensions.md](docs/extensions.md) for the full protocol, the SDK API (`pkg/zotext`), and the phase roadmap.
603+`examples/extensions/` ships reference implementations in Go, TypeScript, Node, and shell. See [docs/extensions.md](docs/extensions.md) for the full protocol, the SDK API (`packages/agent/ext`), and the phase roadmap.
604604
605605 ## Skills
606606
@@ -671,24 +671,28 @@ make fmt # gofmt -w .
671671 make release # cross-compile linux/darwin/windows on amd64 and arm64
672672 ```
673673
674-Source layout:
674+Source layout (single Go module, four packages under `packages/`):
675675
676676 ```
677-cmd/zot/ main()
678-internal/agent/ cli wiring, arg parsing, system prompt, config
679-internal/agent/extensions/ extension subprocess manager
680-internal/agent/modes/ interactive tui, print, json, dialogs
681-internal/agent/tools/ read, write, edit, bash, sandbox
682-internal/auth/ credential store, api-key probe, oauth, login server
683-internal/core/ agent loop, sessions, cost tracking
684-internal/extproto/ extension wire-format types
685-internal/provider/ anthropic + openai-compatible streaming clients, model catalog
686-internal/skills/ skill discovery, frontmatter parser, skill tool
687-internal/tui/ terminal raw-mode, input parser, editor, renderer, markdown, view
688-pkg/zotcore/ public Go SDK for embedding zot in-process
689-pkg/zotext/ public Go SDK for writing extensions
677+cmd/zot/ main()
678+packages/provider/ LLM client surface, model catalog, streaming clients
679+packages/provider/auth/ credential store, api-key probe, oauth, login server
680+packages/core/ agent loop, sessions, cost tracking, compaction
681+packages/tui/ terminal raw-mode, input parser, editor, renderer, markdown, view
682+packages/agent/ cli wiring, arg parsing, system prompt, config
683+packages/agent/extensions/ extension subprocess manager
684+packages/agent/extproto/ extension wire-format types
685+packages/agent/modes/ interactive tui, print, json, dialogs
686+packages/agent/tools/ read, write, edit, bash, sandbox
687+packages/agent/skills/ skill discovery, frontmatter parser, skill tool
688+packages/agent/swarm/ background subagent runtime
689+packages/agent/sdk/ public Go SDK for embedding zot in-process (package sdk)
690+packages/agent/ext/ public Go SDK for writing extensions (package ext)
690691 ```
691692
693+Downstream consumers can depend on individual packages:
694+`go get github.com/patriceckhart/zot/packages/core` pulls only `core` and its transitive deps (today: `provider`), no agent or TUI code.
695+
692696 ## License
693697
694698 MIT
@@ -1,6 +1,6 @@
1 <div align="center">1 <div align="center">
2 <a href="https://www.zot.sh">2 <a href="https://www.zot.sh">
3- <img src="internal/assets/zot-logo.png" alt="zot coding agent harness" width="130" height="130" />3+ <img src="packages/provider/auth/assets/zot-logo.png" alt="zot coding agent harness" width="130" height="130" />
4 </a>4 </a>
5 </div>5 </div>
6 <p align="center">6 <p align="center">
@@ -175,7 +175,7 @@ When the sandbox is on (see `/jail`), all four tools refuse paths outside the se
175 175
176 Two ways to drive zot from another program:176 Two ways to drive zot from another program:
177 177
178-- **Go in-process**: import `github.com/patriceckhart/zot/pkg/zotcore`. One `Runtime` per project; `Prompt(ctx, text, images)` returns a channel of `Event`. Small example in `examples/sdk/`.178+- **Go in-process**: import `github.com/patriceckhart/zot/packages/agent/sdk`. One `Runtime` per project; `Prompt(ctx, text, images)` returns a channel of `Event`. Small example in `examples/sdk/`.
179 - **Any language, out-of-process**: spawn `zot rpc` as a subprocess and exchange newline-delimited JSON over its stdin/stdout. Wire format and event schema in [docs/rpc.md](docs/rpc.md). Reference clients live under `examples/rpc/`.179 - **Any language, out-of-process**: spawn `zot rpc` as a subprocess and exchange newline-delimited JSON over its stdin/stdout. Wire format and event schema in [docs/rpc.md](docs/rpc.md). Reference clients live under `examples/rpc/`.
180 180
181 Both interfaces share the same event schema, so transcripts captured by one can be replayed through the other.181 Both interfaces share the same event schema, so transcripts captured by one can be replayed through the other.
@@ -197,7 +197,7 @@ Type `/` in the TUI to open the autocomplete popup. Available commands:
197 | `/swarm` | Spawn, monitor, and chat with background subagents. Each runs in parallel with your main session and shares its working directory. |197 | `/swarm` | Spawn, monitor, and chat with background subagents. Each runs in parallel with your main session and shares its working directory. |
198 | `/skills` | List discovered skills (SKILL.md files) and preview their bodies. |198 | `/skills` | List discovered skills (SKILL.md files) and preview their bodies. |
199 | `/compact` | Summarize the transcript into one message to free up context. |199 | `/compact` | Summarize the transcript into one message to free up context. |
200-| `/study` | Run the canned prompt "Read and understand everything in the current directory." so the agent has full project context before you start asking targeted questions. Pass a path — typed, drag-dropped, or selected via `@` — to target a specific file or directory instead: `/study [dir:internal/]`, `/study cmd/zot/main.go`. |200+| `/study` | Run the canned prompt "Read and understand everything in the current directory." so the agent has full project context before you start asking targeted questions. Pass a path — typed, drag-dropped, or selected via `@` — to target a specific file or directory instead: `/study [dir:packages/]`, `/study cmd/zot/main.go`. |
201 | `/jail` | Confine tools to the current directory. |201 | `/jail` | Confine tools to the current directory. |
202 | `/unjail` | Allow tools to touch paths outside again. |202 | `/unjail` | Allow tools to touch paths outside again. |
203 | `/reload-ext` | Hot-reload all extensions (re-read manifests, respawn subprocesses, rebuild tool registry). |203 | `/reload-ext` | Hot-reload all extensions (re-read manifests, respawn subprocesses, rebuild tool registry). |
@@ -600,7 +600,7 @@ For development, point `zot --ext <path>` at a working directory and skip the in
600 600
601 ### Reference601 ### Reference
602 602
603-`examples/extensions/` ships reference implementations in Go, TypeScript, Node, and shell. See [docs/extensions.md](docs/extensions.md) for the full protocol, the SDK API (`pkg/zotext`), and the phase roadmap.603+`examples/extensions/` ships reference implementations in Go, TypeScript, Node, and shell. See [docs/extensions.md](docs/extensions.md) for the full protocol, the SDK API (`packages/agent/ext`), and the phase roadmap.
604 604
605 ## Skills605 ## Skills
606 606
@@ -671,24 +671,28 @@ make fmt # gofmt -w .
671 make release # cross-compile linux/darwin/windows on amd64 and arm64671 make release # cross-compile linux/darwin/windows on amd64 and arm64
672 ```672 ```
673 673
674-Source layout:674+Source layout (single Go module, four packages under `packages/`):
675 675
676 ```676 ```
677-cmd/zot/ main()677+cmd/zot/ main()
678-internal/agent/ cli wiring, arg parsing, system prompt, config678+packages/provider/ LLM client surface, model catalog, streaming clients
679-internal/agent/extensions/ extension subprocess manager679+packages/provider/auth/ credential store, api-key probe, oauth, login server
680-internal/agent/modes/ interactive tui, print, json, dialogs680+packages/core/ agent loop, sessions, cost tracking, compaction
681-internal/agent/tools/ read, write, edit, bash, sandbox681+packages/tui/ terminal raw-mode, input parser, editor, renderer, markdown, view
682-internal/auth/ credential store, api-key probe, oauth, login server682+packages/agent/ cli wiring, arg parsing, system prompt, config
683-internal/core/ agent loop, sessions, cost tracking683+packages/agent/extensions/ extension subprocess manager
684-internal/extproto/ extension wire-format types684+packages/agent/extproto/ extension wire-format types
685-internal/provider/ anthropic + openai-compatible streaming clients, model catalog685+packages/agent/modes/ interactive tui, print, json, dialogs
686-internal/skills/ skill discovery, frontmatter parser, skill tool686+packages/agent/tools/ read, write, edit, bash, sandbox
687-internal/tui/ terminal raw-mode, input parser, editor, renderer, markdown, view687+packages/agent/skills/ skill discovery, frontmatter parser, skill tool
688-pkg/zotcore/ public Go SDK for embedding zot in-process688+packages/agent/swarm/ background subagent runtime
689-pkg/zotext/ public Go SDK for writing extensions689+packages/agent/sdk/ public Go SDK for embedding zot in-process (package sdk)
690+packages/agent/ext/ public Go SDK for writing extensions (package ext)
690 ```691 ```
691 692
693+Downstream consumers can depend on individual packages:
694+`go get github.com/patriceckhart/zot/packages/core` pulls only `core` and its transitive deps (today: `provider`), no agent or TUI code.
695+
692 ## License696 ## License
693 697
694 MIT698 MIT
M cmd/zot/main.go +1 -1
@@ -5,7 +5,7 @@ import (
55 "fmt"
66 "os"
77
8- "github.com/patriceckhart/zot/internal/agent"
8+ "github.com/patriceckhart/zot/packages/agent"
99 )
1010
1111 // Injected at build time via -ldflags "-X main.version=... -X main.commit=... -X main.date=...".
@@ -5,7 +5,7 @@ import (
5 "fmt"5 "fmt"
6 "os"6 "os"
7 7
8- "github.com/patriceckhart/zot/internal/agent"8+ "github.com/patriceckhart/zot/packages/agent"
9 )9 )
10 10
11 // Injected at build time via -ldflags "-X main.version=... -X main.commit=... -X main.date=...".11 // Injected at build time via -ldflags "-X main.version=... -X main.commit=... -X main.date=...".
M docs/extensions.md +19 -17
@@ -478,34 +478,34 @@ the extension dies with zot like any other subprocess.
478478 Writing the wire protocol by hand is fine for one-off scripts, but
479479 for anything bigger the SDKs handle the boilerplate.
480480
481-### Go — `pkg/zotext`
481+### Go — `packages/agent/ext`
482482
483483 ```go
484484 package main
485485
486486 import (
487487 "encoding/json"
488- "github.com/patriceckhart/zot/pkg/zotext"
488+ "github.com/patriceckhart/zot/packages/agent/ext"
489489 )
490490
491491 func main() {
492- ext := zotext.New("hello", "1.0.0")
492+ e := ext.New("hello", "1.0.0")
493493
494494 // Slash command
495- ext.Command("hello", "say hi", func(args string) zotext.Response {
496- return zotext.Prompt("Greet me in one short sentence.")
495+ e.Command("hello", "say hi", func(args string) ext.Response {
496+ return ext.Prompt("Greet me in one short sentence.")
497497 })
498498
499499 // LLM-callable tool
500- ext.Tool("weather", "Current weather for a city.",
500+ e.Tool("weather", "Current weather for a city.",
501501 json.RawMessage(`{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}`),
502- func(args json.RawMessage) zotext.ToolResult {
502+ func(args json.RawMessage) ext.ToolResult {
503503 var in struct{ City string `json:"city"` }
504504 json.Unmarshal(args, &in)
505- return zotext.TextResult(in.City + ": sunny")
505+ return ext.TextResult(in.City + ": sunny")
506506 })
507507
508- ext.Run()
508+ e.Run()
509509 }
510510 ```
511511
@@ -515,29 +515,31 @@ into `$ZOT_HOME/extensions/hello/`.
515515 The SDK has four interceptor hooks, all optional:
516516
517517 ```go
518+// e is the *ext.Extension returned by ext.New(...).
519+
518520 // Refuse calls or rewrite args before they run.
519-ext.InterceptToolCall(func(tool string, args json.RawMessage) (bool, string) {
521+e.InterceptToolCall(func(tool string, args json.RawMessage) (bool, string) {
520522 if tool == "bash" { /* inspect args, return false, reason */ }
521523 return true, ""
522524 })
523525
524526 // Richer variant: returns ToolCallDecision so you can also rewrite
525527 // args via ModifiedArgs.
526-ext.InterceptToolCallX(func(tool string, args json.RawMessage) zotext.ToolCallDecision {
527- return zotext.ToolCallDecision{
528+e.InterceptToolCallX(func(tool string, args json.RawMessage) ext.ToolCallDecision {
529+ return ext.ToolCallDecision{
528530 ModifiedArgs: json.RawMessage(`{"command":"echo GUARDED"}`),
529531 }
530532 })
531533
532534 // Block the next turn before the model is called.
533-ext.InterceptTurnStart(func(step int) zotext.TurnStartDecision {
534- if time.Now().Hour() < 9 { return zotext.TurnStartDecision{Block: true, Reason: "outside business hours"} }
535- return zotext.TurnStartDecision{}
535+e.InterceptTurnStart(func(step int) ext.TurnStartDecision {
536+ if time.Now().Hour() < 9 { return ext.TurnStartDecision{Block: true, Reason: "outside business hours"} }
537+ return ext.TurnStartDecision{}
536538 })
537539
538540 // Scrub or rewrite the assistant's final text before the user sees it.
539-ext.InterceptAssistantMessage(func(text string) zotext.AssistantMessageDecision {
540- return zotext.AssistantMessageDecision{
541+e.InterceptAssistantMessage(func(text string) ext.AssistantMessageDecision {
542+ return ext.AssistantMessageDecision{
541543 ReplaceText: strings.ReplaceAll(text, "SECRET", "[redacted]"),
542544 }
543545 })
@@ -478,34 +478,34 @@ the extension dies with zot like any other subprocess.
478 Writing the wire protocol by hand is fine for one-off scripts, but478 Writing the wire protocol by hand is fine for one-off scripts, but
479 for anything bigger the SDKs handle the boilerplate.479 for anything bigger the SDKs handle the boilerplate.
480 480
481-### Go — `pkg/zotext`481+### Go — `packages/agent/ext`
482 482
483 ```go483 ```go
484 package main484 package main
485 485
486 import (486 import (
487 "encoding/json"487 "encoding/json"
488- "github.com/patriceckhart/zot/pkg/zotext"488+ "github.com/patriceckhart/zot/packages/agent/ext"
489 )489 )
490 490
491 func main() {491 func main() {
492- ext := zotext.New("hello", "1.0.0")492+ e := ext.New("hello", "1.0.0")
493 493
494 // Slash command494 // Slash command
495- ext.Command("hello", "say hi", func(args string) zotext.Response {495+ e.Command("hello", "say hi", func(args string) ext.Response {
496- return zotext.Prompt("Greet me in one short sentence.")496+ return ext.Prompt("Greet me in one short sentence.")
497 })497 })
498 498
499 // LLM-callable tool499 // LLM-callable tool
500- ext.Tool("weather", "Current weather for a city.",500+ e.Tool("weather", "Current weather for a city.",
501 json.RawMessage(`{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}`),501 json.RawMessage(`{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}`),
502- func(args json.RawMessage) zotext.ToolResult {502+ func(args json.RawMessage) ext.ToolResult {
503 var in struct{ City string `json:"city"` }503 var in struct{ City string `json:"city"` }
504 json.Unmarshal(args, &in)504 json.Unmarshal(args, &in)
505- return zotext.TextResult(in.City + ": sunny")505+ return ext.TextResult(in.City + ": sunny")
506 })506 })
507 507
508- ext.Run()508+ e.Run()
509 }509 }
510 ```510 ```
511 511
@@ -515,29 +515,31 @@ into `$ZOT_HOME/extensions/hello/`.
515 The SDK has four interceptor hooks, all optional:515 The SDK has four interceptor hooks, all optional:
516 516
517 ```go517 ```go
518+// e is the *ext.Extension returned by ext.New(...).
519+
518 // Refuse calls or rewrite args before they run.520 // Refuse calls or rewrite args before they run.
519-ext.InterceptToolCall(func(tool string, args json.RawMessage) (bool, string) {521+e.InterceptToolCall(func(tool string, args json.RawMessage) (bool, string) {
520 if tool == "bash" { /* inspect args, return false, reason */ }522 if tool == "bash" { /* inspect args, return false, reason */ }
521 return true, ""523 return true, ""
522 })524 })
523 525
524 // Richer variant: returns ToolCallDecision so you can also rewrite526 // Richer variant: returns ToolCallDecision so you can also rewrite
525 // args via ModifiedArgs.527 // args via ModifiedArgs.
526-ext.InterceptToolCallX(func(tool string, args json.RawMessage) zotext.ToolCallDecision {528+e.InterceptToolCallX(func(tool string, args json.RawMessage) ext.ToolCallDecision {
527- return zotext.ToolCallDecision{529+ return ext.ToolCallDecision{
528 ModifiedArgs: json.RawMessage(`{"command":"echo GUARDED"}`),530 ModifiedArgs: json.RawMessage(`{"command":"echo GUARDED"}`),
529 }531 }
530 })532 })
531 533
532 // Block the next turn before the model is called.534 // Block the next turn before the model is called.
533-ext.InterceptTurnStart(func(step int) zotext.TurnStartDecision {535+e.InterceptTurnStart(func(step int) ext.TurnStartDecision {
534- if time.Now().Hour() < 9 { return zotext.TurnStartDecision{Block: true, Reason: "outside business hours"} }536+ if time.Now().Hour() < 9 { return ext.TurnStartDecision{Block: true, Reason: "outside business hours"} }
535- return zotext.TurnStartDecision{}537+ return ext.TurnStartDecision{}
536 })538 })
537 539
538 // Scrub or rewrite the assistant's final text before the user sees it.540 // Scrub or rewrite the assistant's final text before the user sees it.
539-ext.InterceptAssistantMessage(func(text string) zotext.AssistantMessageDecision {541+e.InterceptAssistantMessage(func(text string) ext.AssistantMessageDecision {
540- return zotext.AssistantMessageDecision{542+ return ext.AssistantMessageDecision{
541 ReplaceText: strings.ReplaceAll(text, "SECRET", "[redacted]"),543 ReplaceText: strings.ReplaceAll(text, "SECRET", "[redacted]"),
542 }544 }
543 })545 })
M docs/rpc.md +2 -2
@@ -2,7 +2,7 @@
22
33 `zot rpc` runs the agent runtime as a subprocess that speaks newline-delimited JSON on stdin and stdout. Use it from any language that can spawn a process and read/write its pipes — Go, TypeScript, Python, Rust, shell, anything.
44
5-For a Go program embedding the runtime in-process, use the `pkg/zotcore` SDK instead. The wire format below mirrors the SDK's types one-for-one so consumers can share parsing code.
5+For a Go program embedding the runtime in-process, use the `packages/agent/sdk` SDK instead. The wire format below mirrors the SDK's types one-for-one so consumers can share parsing code.
66
77 ## Quick start
88
@@ -223,7 +223,7 @@ See `examples/rpc/` for working implementations in:
223223 - `shell` — `bash` + `jq` one-liner
224224 - `python` — `subprocess.Popen` + `json.loads` per line
225225 - `node` — `child_process.spawn` + `readline`
226-- `go` — direct subprocess wrapper (the `pkg/zotcore` SDK is the in-process Go API)
226+- `go` — direct subprocess wrapper (the `packages/agent/sdk` SDK is the in-process Go API)
227227
228228 ## Versioning
229229
@@ -2,7 +2,7 @@
2 2
3 `zot rpc` runs the agent runtime as a subprocess that speaks newline-delimited JSON on stdin and stdout. Use it from any language that can spawn a process and read/write its pipes — Go, TypeScript, Python, Rust, shell, anything.3 `zot rpc` runs the agent runtime as a subprocess that speaks newline-delimited JSON on stdin and stdout. Use it from any language that can spawn a process and read/write its pipes — Go, TypeScript, Python, Rust, shell, anything.
4 4
5-For a Go program embedding the runtime in-process, use the `pkg/zotcore` SDK instead. The wire format below mirrors the SDK's types one-for-one so consumers can share parsing code.5+For a Go program embedding the runtime in-process, use the `packages/agent/sdk` SDK instead. The wire format below mirrors the SDK's types one-for-one so consumers can share parsing code.
6 6
7 ## Quick start7 ## Quick start
8 8
@@ -223,7 +223,7 @@ See `examples/rpc/` for working implementations in:
223 - `shell` — `bash` + `jq` one-liner223 - `shell` — `bash` + `jq` one-liner
224 - `python` — `subprocess.Popen` + `json.loads` per line224 - `python` — `subprocess.Popen` + `json.loads` per line
225 - `node` — `child_process.spawn` + `readline`225 - `node` — `child_process.spawn` + `readline`
226-- `go` — direct subprocess wrapper (the `pkg/zotcore` SDK is the in-process Go API)226+- `go` — direct subprocess wrapper (the `packages/agent/sdk` SDK is the in-process Go API)
227 227
228 ## Versioning228 ## Versioning
229 229
M examples/extensions/clock/README.md +1 -1
@@ -49,5 +49,5 @@ points at and reads/writes JSON lines on its stdio.
4949
5050 ## See also
5151
52-- `examples/extensions/hello` — Go version using the `pkg/zotext` SDK
52+- `examples/extensions/hello` — Go version using the `packages/agent/ext` SDK
5353 - `docs/extensions.md` — full protocol reference
@@ -49,5 +49,5 @@ points at and reads/writes JSON lines on its stdio.
49 49
50 ## See also50 ## See also
51 51
52-- `examples/extensions/hello` — Go version using the `pkg/zotext` SDK52+- `examples/extensions/hello` — Go version using the `packages/agent/ext` SDK
53 - `docs/extensions.md` — full protocol reference53 - `docs/extensions.md` — full protocol reference
M examples/extensions/guard/main.go +10 -10
@@ -29,7 +29,7 @@ import (
2929 "strings"
3030 "time"
3131
32- "github.com/patriceckhart/zot/pkg/zotext"
32+ "github.com/patriceckhart/zot/packages/agent/ext"
3333 )
3434
3535 var dangerPatterns = []*regexp.Regexp{
@@ -42,7 +42,7 @@ var dangerPatterns = []*regexp.Regexp{
4242 }
4343
4444 func main() {
45- ext := zotext.New("guard", "1.0.0")
45+ e := ext.New("guard", "1.0.0")
4646
4747 auditPath := filepath.Join(os.TempDir(), "zot-guard-audit.log")
4848 auditFile, _ := os.OpenFile(auditPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)
@@ -54,19 +54,19 @@ func main() {
5454 if auditFile != nil {
5555 auditFile.WriteString(line)
5656 }
57- ext.Logf("%s", strings.TrimRight(line, "\n"))
57+ e.Logf("%s", strings.TrimRight(line, "\n"))
5858 }
5959
6060 // Lifecycle observers.
61- ext.On("session_start", func(ev zotext.Event) { audit("[guard] session_start") })
62- ext.On("turn_start", func(ev zotext.Event) { audit("[guard] turn_start step=%d", ev.Step) })
63- ext.On("tool_call", func(ev zotext.Event) {
61+ e.On("session_start", func(ev ext.Event) { audit("[guard] session_start") })
62+ e.On("turn_start", func(ev ext.Event) { audit("[guard] turn_start step=%d", ev.Step) })
63+ e.On("tool_call", func(ev ext.Event) {
6464 audit("[guard] tool_call %s args=%s", ev.ToolName, string(ev.ToolArgs))
6565 })
66- ext.On("turn_end", func(ev zotext.Event) { audit("[guard] turn_end stop=%s err=%s", ev.Stop, ev.Error) })
66+ e.On("turn_end", func(ev ext.Event) { audit("[guard] turn_end stop=%s err=%s", ev.Stop, ev.Error) })
6767
6868 // Tool-call gate.
69- ext.InterceptToolCall(func(toolName string, args json.RawMessage) (bool, string) {
69+ e.InterceptToolCall(func(toolName string, args json.RawMessage) (bool, string) {
7070 if toolName != "bash" {
7171 return true, "" // only guard bash
7272 }
@@ -85,7 +85,7 @@ func main() {
8585 return true, ""
8686 })
8787
88- if err := ext.Run(); err != nil {
89- ext.Logf("fatal: %v", err)
88+ if err := e.Run(); err != nil {
89+ e.Logf("fatal: %v", err)
9090 }
9191 }
@@ -29,7 +29,7 @@ import (
29 "strings"29 "strings"
30 "time"30 "time"
31 31
32- "github.com/patriceckhart/zot/pkg/zotext"32+ "github.com/patriceckhart/zot/packages/agent/ext"
33 )33 )
34 34
35 var dangerPatterns = []*regexp.Regexp{35 var dangerPatterns = []*regexp.Regexp{
@@ -42,7 +42,7 @@ var dangerPatterns = []*regexp.Regexp{
42 }42 }
43 43
44 func main() {44 func main() {
45- ext := zotext.New("guard", "1.0.0")45+ e := ext.New("guard", "1.0.0")
46 46
47 auditPath := filepath.Join(os.TempDir(), "zot-guard-audit.log")47 auditPath := filepath.Join(os.TempDir(), "zot-guard-audit.log")
48 auditFile, _ := os.OpenFile(auditPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)48 auditFile, _ := os.OpenFile(auditPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)
@@ -54,19 +54,19 @@ func main() {
54 if auditFile != nil {54 if auditFile != nil {
55 auditFile.WriteString(line)55 auditFile.WriteString(line)
56 }56 }
57- ext.Logf("%s", strings.TrimRight(line, "\n"))57+ e.Logf("%s", strings.TrimRight(line, "\n"))
58 }58 }
59 59
60 // Lifecycle observers.60 // Lifecycle observers.
61- ext.On("session_start", func(ev zotext.Event) { audit("[guard] session_start") })61+ e.On("session_start", func(ev ext.Event) { audit("[guard] session_start") })
62- ext.On("turn_start", func(ev zotext.Event) { audit("[guard] turn_start step=%d", ev.Step) })62+ e.On("turn_start", func(ev ext.Event) { audit("[guard] turn_start step=%d", ev.Step) })
63- ext.On("tool_call", func(ev zotext.Event) {63+ e.On("tool_call", func(ev ext.Event) {
64 audit("[guard] tool_call %s args=%s", ev.ToolName, string(ev.ToolArgs))64 audit("[guard] tool_call %s args=%s", ev.ToolName, string(ev.ToolArgs))
65 })65 })
66- ext.On("turn_end", func(ev zotext.Event) { audit("[guard] turn_end stop=%s err=%s", ev.Stop, ev.Error) })66+ e.On("turn_end", func(ev ext.Event) { audit("[guard] turn_end stop=%s err=%s", ev.Stop, ev.Error) })
67 67
68 // Tool-call gate.68 // Tool-call gate.
69- ext.InterceptToolCall(func(toolName string, args json.RawMessage) (bool, string) {69+ e.InterceptToolCall(func(toolName string, args json.RawMessage) (bool, string) {
70 if toolName != "bash" {70 if toolName != "bash" {
71 return true, "" // only guard bash71 return true, "" // only guard bash
72 }72 }
@@ -85,7 +85,7 @@ func main() {
85 return true, ""85 return true, ""
86 })86 })
87 87
88- if err := ext.Run(); err != nil {88+ if err := e.Run(); err != nil {
89- ext.Logf("fatal: %v", err)89+ e.Logf("fatal: %v", err)
90 }90 }
91 }91 }
M examples/extensions/hello/README.md +2 -2
@@ -1,7 +1,7 @@
11 # hello — example zot extension (Go)
22
33 A minimal example showing how to register slash commands with the
4-`zotext` SDK.
4+`ext` SDK.
55
66 ## Build
77
@@ -31,5 +31,5 @@ In zot, type:
3131
3232 ## See also
3333
34-- `pkg/zotext` — Go SDK
34+- `packages/agent/ext` — Go SDK
3535 - `docs/extensions.md` — protocol reference for any-language extensions
@@ -1,7 +1,7 @@
1 # hello — example zot extension (Go)1 # hello — example zot extension (Go)
2 2
3 A minimal example showing how to register slash commands with the3 A minimal example showing how to register slash commands with the
4-`zotext` SDK.4+`ext` SDK.
5 5
6 ## Build6 ## Build
7 7
@@ -31,5 +31,5 @@ In zot, type:
31 31
32 ## See also32 ## See also
33 33
34-- `pkg/zotext` — Go SDK34+- `packages/agent/ext` — Go SDK
35 - `docs/extensions.md` — protocol reference for any-language extensions35 - `docs/extensions.md` — protocol reference for any-language extensions
M examples/extensions/hello/main.go +10 -10
@@ -13,29 +13,29 @@ package main
1313 import (
1414 "strings"
1515
16- "github.com/patriceckhart/zot/pkg/zotext"
16+ "github.com/patriceckhart/zot/packages/agent/ext"
1717 )
1818
1919 func main() {
20- ext := zotext.New("hello", "1.0.0")
20+ e := ext.New("hello", "1.0.0")
2121
2222 // /hello [name] — submits a friendly prompt to the agent.
23- ext.Command("hello", "say hello (optional name)", func(args string) zotext.Response {
23+ e.Command("hello", "say hello (optional name)", func(args string) ext.Response {
2424 who := strings.TrimSpace(args)
2525 if who == "" {
26- return zotext.Prompt("Greet me with a short, slightly absurd compliment.")
26+ return ext.Prompt("Greet me with a short, slightly absurd compliment.")
2727 }
28- return zotext.Prompt("Greet " + who + " with a short, slightly absurd compliment.")
28+ return ext.Prompt("Greet " + who + " with a short, slightly absurd compliment.")
2929 })
3030
3131 // /summon — pushes a notice into the chat without involving the
3232 // model. Useful for pretending we did something important.
33- ext.Command("summon", "show a tongue-in-cheek summon notice", func(args string) zotext.Response {
34- ext.Notify("info", "the daemon stirs in its cage.")
35- return zotext.Display("a wisp of incense curls past your terminal.")
33+ e.Command("summon", "show a tongue-in-cheek summon notice", func(args string) ext.Response {
34+ e.Notify("info", "the daemon stirs in its cage.")
35+ return ext.Display("a wisp of incense curls past your terminal.")
3636 })
3737
38- if err := ext.Run(); err != nil {
39- ext.Logf("fatal: %v", err)
38+ if err := e.Run(); err != nil {
39+ e.Logf("fatal: %v", err)
4040 }
4141 }
@@ -13,29 +13,29 @@ package main
13 import (13 import (
14 "strings"14 "strings"
15 15
16- "github.com/patriceckhart/zot/pkg/zotext"16+ "github.com/patriceckhart/zot/packages/agent/ext"
17 )17 )
18 18
19 func main() {19 func main() {
20- ext := zotext.New("hello", "1.0.0")20+ e := ext.New("hello", "1.0.0")
21 21
22 // /hello [name] — submits a friendly prompt to the agent.22 // /hello [name] — submits a friendly prompt to the agent.
23- ext.Command("hello", "say hello (optional name)", func(args string) zotext.Response {23+ e.Command("hello", "say hello (optional name)", func(args string) ext.Response {
24 who := strings.TrimSpace(args)24 who := strings.TrimSpace(args)
25 if who == "" {25 if who == "" {
26- return zotext.Prompt("Greet me with a short, slightly absurd compliment.")26+ return ext.Prompt("Greet me with a short, slightly absurd compliment.")
27 }27 }
28- return zotext.Prompt("Greet " + who + " with a short, slightly absurd compliment.")28+ return ext.Prompt("Greet " + who + " with a short, slightly absurd compliment.")
29 })29 })
30 30
31 // /summon — pushes a notice into the chat without involving the31 // /summon — pushes a notice into the chat without involving the
32 // model. Useful for pretending we did something important.32 // model. Useful for pretending we did something important.
33- ext.Command("summon", "show a tongue-in-cheek summon notice", func(args string) zotext.Response {33+ e.Command("summon", "show a tongue-in-cheek summon notice", func(args string) ext.Response {
34- ext.Notify("info", "the daemon stirs in its cage.")34+ e.Notify("info", "the daemon stirs in its cage.")
35- return zotext.Display("a wisp of incense curls past your terminal.")35+ return ext.Display("a wisp of incense curls past your terminal.")
36 })36 })
37 37
38- if err := ext.Run(); err != nil {38+ if err := e.Run(); err != nil {
39- ext.Logf("fatal: %v", err)39+ e.Logf("fatal: %v", err)
40 }40 }
41 }41 }
M examples/extensions/todo/main.go +30 -30
@@ -8,7 +8,7 @@ import (
88 "strings"
99 "sync"
1010
11- "github.com/patriceckhart/zot/pkg/zotext"
11+ "github.com/patriceckhart/zot/packages/agent/ext"
1212 )
1313
1414 type todoItem struct {
@@ -28,7 +28,7 @@ type toolArgs struct {
2828 }
2929
3030 type app struct {
31- ext *zotext.Extension
31+ e *ext.Extension
3232 mu sync.Mutex
3333 path string
3434 st store
@@ -39,15 +39,15 @@ type app struct {
3939 const panelID = "todos-main"
4040
4141 func main() {
42- ext := zotext.New("todo-panel", "0.3.0")
43- a := &app{ext: ext}
44- ext.Command("todo", "open a persistent todo panel", func(args string) zotext.Response {
42+ e := ext.New("todo-panel", "0.3.0")
43+ a := &app{e: e}
44+ e.Command("todo", "open a persistent todo panel", func(args string) ext.Response {
4545 if err := a.ensureLoaded(); err != nil {
46- return zotext.Errorf("load todos: %v", err)
46+ return ext.Errorf("load todos: %v", err)
4747 }
4848 a.mu.Lock()
4949 defer a.mu.Unlock()
50- return zotext.OpenPanel(panelID, a.title(), a.renderLines(), a.footer())
50+ return ext.OpenPanel(panelID, a.title(), a.renderLines(), a.footer())
5151 })
5252 schema, _ := json.Marshal(map[string]any{
5353 "type": "object",
@@ -58,9 +58,9 @@ func main() {
5858 },
5959 "required": []string{"action"},
6060 })
61- ext.Tool("todo_manage", "List, add, complete, edit, or remove todos by title.", schema, a.handleTool)
62- ext.OnPanelKey(panelID, a.handleKey, nil)
63- if err := ext.Run(); err != nil {
61+ e.Tool("todo_manage", "List, add, complete, edit, or remove todos by title.", schema, a.handleTool)
62+ e.OnPanelKey(panelID, a.handleKey, nil)
63+ if err := e.Run(); err != nil {
6464 fmt.Fprintln(os.Stderr, err)
6565 os.Exit(1)
6666 }
@@ -72,9 +72,9 @@ func (a *app) ensureLoaded() error {
7272 if a.path != "" {
7373 return nil
7474 }
75- dir := a.ext.Host().DataDir
75+ dir := a.e.Host().DataDir
7676 if dir == "" {
77- dir = a.ext.Host().ExtensionDir
77+ dir = a.e.Host().ExtensionDir
7878 }
7979 if dir == "" {
8080 return fmt.Errorf("host did not provide extension_dir/data_dir")
@@ -178,12 +178,12 @@ func (a *app) footer() string {
178178 }
179179
180180 func (a *app) rerenderLocked() {
181- a.ext.RenderPanel(panelID, a.title(), a.renderLines(), a.footer())
181+ a.e.RenderPanel(panelID, a.title(), a.renderLines(), a.footer())
182182 }
183183
184184 func (a *app) handleKey(key, text string) {
185185 if err := a.ensureLoaded(); err != nil {
186- a.ext.Notify("error", fmt.Sprintf("todo: %v", err))
186+ a.e.Notify("error", fmt.Sprintf("todo: %v", err))
187187 return
188188 }
189189 a.mu.Lock()
@@ -220,7 +220,7 @@ func (a *app) handleKey(key, text string) {
220220 }
221221 a.clampLocked()
222222 if err := a.saveLocked(); err != nil {
223- a.ext.Notify("error", fmt.Sprintf("save todos: %v", err))
223+ a.e.Notify("error", fmt.Sprintf("save todos: %v", err))
224224 }
225225 a.rerenderLocked()
226226 }
@@ -253,25 +253,25 @@ func (a *app) handleEditModeLocked(key, text string) {
253253 }
254254 }
255255 if err := a.saveLocked(); err != nil {
256- a.ext.Notify("error", fmt.Sprintf("save todos: %v", err))
256+ a.e.Notify("error", fmt.Sprintf("save todos: %v", err))
257257 }
258258 a.rerenderLocked()
259259 }
260260
261-func (a *app) handleTool(args json.RawMessage) zotext.ToolResult {
261+func (a *app) handleTool(args json.RawMessage) ext.ToolResult {
262262 if err := a.ensureLoaded(); err != nil {
263- return zotext.TextErrorResult("load todos: " + err.Error())
263+ return ext.TextErrorResult("load todos: " + err.Error())
264264 }
265265 var in toolArgs
266266 if err := json.Unmarshal(args, &in); err != nil {
267- return zotext.TextErrorResult("invalid args: " + err.Error())
267+ return ext.TextErrorResult("invalid args: " + err.Error())
268268 }
269269 a.mu.Lock()
270270 defer a.mu.Unlock()
271271 switch in.Action {
272272 case "list":
273273 if len(a.st.Items) == 0 {
274- return zotext.TextResult("No todos.")
274+ return ext.TextResult("No todos.")
275275 }
276276 var lines []string
277277 for _, it := range a.st.Items {
@@ -281,48 +281,48 @@ func (a *app) handleTool(args json.RawMessage) zotext.ToolResult {
281281 }
282282 lines = append(lines, mark+" "+it.Text)
283283 }
284- return zotext.TextResult(strings.Join(lines, "\n"))
284+ return ext.TextResult(strings.Join(lines, "\n"))
285285 case "add":
286286 if strings.TrimSpace(in.Title) == "" {
287- return zotext.TextErrorResult("title is required for add")
287+ return ext.TextErrorResult("title is required for add")
288288 }
289289 a.st.Items = append(a.st.Items, todoItem{Text: strings.TrimSpace(in.Title)})
290290 a.st.Cursor = len(a.st.Items) - 1
291291 case "complete":
292292 idx := a.findByTitleLocked(in.Title)
293293 if idx < 0 {
294- return zotext.TextErrorResult("todo not found: " + in.Title)
294+ return ext.TextErrorResult("todo not found: " + in.Title)
295295 }
296296 a.st.Items[idx].Done = true
297297 a.st.Cursor = idx
298298 case "edit":
299299 idx := a.findByTitleLocked(in.Title)
300300 if idx < 0 {
301- return zotext.TextErrorResult("todo not found: " + in.Title)
301+ return ext.TextErrorResult("todo not found: " + in.Title)
302302 }
303303 if strings.TrimSpace(in.NewTitle) == "" {
304- return zotext.TextErrorResult("new_title is required for edit")
304+ return ext.TextErrorResult("new_title is required for edit")
305305 }
306306 a.st.Items[idx].Text = strings.TrimSpace(in.NewTitle)
307307 a.st.Cursor = idx
308308 case "remove":
309309 idx := a.findByTitleLocked(in.Title)
310310 if idx < 0 {
311- return zotext.TextErrorResult("todo not found: " + in.Title)
311+ return ext.TextErrorResult("todo not found: " + in.Title)
312312 }
313313 a.st.Items = append(a.st.Items[:idx], a.st.Items[idx+1:]...)
314314 case "":
315- return zotext.TextErrorResult("action is required")
315+ return ext.TextErrorResult("action is required")
316316 default:
317- return zotext.TextErrorResult("unsupported action: " + in.Action)
317+ return ext.TextErrorResult("unsupported action: " + in.Action)
318318 }
319319 if err := a.saveLocked(); err != nil {
320- return zotext.TextErrorResult("save todos: " + err.Error())
320+ return ext.TextErrorResult("save todos: " + err.Error())
321321 }
322322 if a.mode == "" {
323323 a.rerenderLocked()
324324 }
325- return zotext.TextResult("ok")
325+ return ext.TextResult("ok")
326326 }
327327
328328 func (a *app) findByTitleLocked(title string) int {
@@ -8,7 +8,7 @@ import (
8 "strings"8 "strings"
9 "sync"9 "sync"
10 10
11- "github.com/patriceckhart/zot/pkg/zotext"11+ "github.com/patriceckhart/zot/packages/agent/ext"
12 )12 )
13 13
14 type todoItem struct {14 type todoItem struct {
@@ -28,7 +28,7 @@ type toolArgs struct {
28 }28 }
29 29
30 type app struct {30 type app struct {
31- ext *zotext.Extension31+ e *ext.Extension
32 mu sync.Mutex32 mu sync.Mutex
33 path string33 path string
34 st store34 st store
@@ -39,15 +39,15 @@ type app struct {
39 const panelID = "todos-main"39 const panelID = "todos-main"
40 40
41 func main() {41 func main() {
42- ext := zotext.New("todo-panel", "0.3.0")42+ e := ext.New("todo-panel", "0.3.0")
43- a := &app{ext: ext}43+ a := &app{e: e}
44- ext.Command("todo", "open a persistent todo panel", func(args string) zotext.Response {44+ e.Command("todo", "open a persistent todo panel", func(args string) ext.Response {
45 if err := a.ensureLoaded(); err != nil {45 if err := a.ensureLoaded(); err != nil {
46- return zotext.Errorf("load todos: %v", err)46+ return ext.Errorf("load todos: %v", err)
47 }47 }
48 a.mu.Lock()48 a.mu.Lock()
49 defer a.mu.Unlock()49 defer a.mu.Unlock()
50- return zotext.OpenPanel(panelID, a.title(), a.renderLines(), a.footer())50+ return ext.OpenPanel(panelID, a.title(), a.renderLines(), a.footer())
51 })51 })
52 schema, _ := json.Marshal(map[string]any{52 schema, _ := json.Marshal(map[string]any{
53 "type": "object",53 "type": "object",
@@ -58,9 +58,9 @@ func main() {
58 },58 },
59 "required": []string{"action"},59 "required": []string{"action"},
60 })60 })
61- ext.Tool("todo_manage", "List, add, complete, edit, or remove todos by title.", schema, a.handleTool)61+ e.Tool("todo_manage", "List, add, complete, edit, or remove todos by title.", schema, a.handleTool)
62- ext.OnPanelKey(panelID, a.handleKey, nil)62+ e.OnPanelKey(panelID, a.handleKey, nil)
63- if err := ext.Run(); err != nil {63+ if err := e.Run(); err != nil {
64 fmt.Fprintln(os.Stderr, err)64 fmt.Fprintln(os.Stderr, err)
65 os.Exit(1)65 os.Exit(1)
66 }66 }
@@ -72,9 +72,9 @@ func (a *app) ensureLoaded() error {
72 if a.path != "" {72 if a.path != "" {
73 return nil73 return nil
74 }74 }
75- dir := a.ext.Host().DataDir75+ dir := a.e.Host().DataDir
76 if dir == "" {76 if dir == "" {
77- dir = a.ext.Host().ExtensionDir77+ dir = a.e.Host().ExtensionDir
78 }78 }
79 if dir == "" {79 if dir == "" {
80 return fmt.Errorf("host did not provide extension_dir/data_dir")80 return fmt.Errorf("host did not provide extension_dir/data_dir")
@@ -178,12 +178,12 @@ func (a *app) footer() string {
178 }178 }
179 179
180 func (a *app) rerenderLocked() {180 func (a *app) rerenderLocked() {
181- a.ext.RenderPanel(panelID, a.title(), a.renderLines(), a.footer())181+ a.e.RenderPanel(panelID, a.title(), a.renderLines(), a.footer())
182 }182 }
183 183
184 func (a *app) handleKey(key, text string) {184 func (a *app) handleKey(key, text string) {
185 if err := a.ensureLoaded(); err != nil {185 if err := a.ensureLoaded(); err != nil {
186- a.ext.Notify("error", fmt.Sprintf("todo: %v", err))186+ a.e.Notify("error", fmt.Sprintf("todo: %v", err))
187 return187 return
188 }188 }
189 a.mu.Lock()189 a.mu.Lock()
@@ -220,7 +220,7 @@ func (a *app) handleKey(key, text string) {
220 }220 }
221 a.clampLocked()221 a.clampLocked()
222 if err := a.saveLocked(); err != nil {222 if err := a.saveLocked(); err != nil {
223- a.ext.Notify("error", fmt.Sprintf("save todos: %v", err))223+ a.e.Notify("error", fmt.Sprintf("save todos: %v", err))
224 }224 }
225 a.rerenderLocked()225 a.rerenderLocked()
226 }226 }
@@ -253,25 +253,25 @@ func (a *app) handleEditModeLocked(key, text string) {
253 }253 }
254 }254 }
255 if err := a.saveLocked(); err != nil {255 if err := a.saveLocked(); err != nil {
256- a.ext.Notify("error", fmt.Sprintf("save todos: %v", err))256+ a.e.Notify("error", fmt.Sprintf("save todos: %v", err))
257 }257 }
258 a.rerenderLocked()258 a.rerenderLocked()
259 }259 }
260 260
261-func (a *app) handleTool(args json.RawMessage) zotext.ToolResult {261+func (a *app) handleTool(args json.RawMessage) ext.ToolResult {
262 if err := a.ensureLoaded(); err != nil {262 if err := a.ensureLoaded(); err != nil {
263- return zotext.TextErrorResult("load todos: " + err.Error())263+ return ext.TextErrorResult("load todos: " + err.Error())
264 }264 }
265 var in toolArgs265 var in toolArgs
266 if err := json.Unmarshal(args, &in); err != nil {266 if err := json.Unmarshal(args, &in); err != nil {
267- return zotext.TextErrorResult("invalid args: " + err.Error())267+ return ext.TextErrorResult("invalid args: " + err.Error())
268 }268 }
269 a.mu.Lock()269 a.mu.Lock()
270 defer a.mu.Unlock()270 defer a.mu.Unlock()
271 switch in.Action {271 switch in.Action {
272 case "list":272 case "list":
273 if len(a.st.Items) == 0 {273 if len(a.st.Items) == 0 {
274- return zotext.TextResult("No todos.")274+ return ext.TextResult("No todos.")
275 }275 }
276 var lines []string276 var lines []string
277 for _, it := range a.st.Items {277 for _, it := range a.st.Items {
@@ -281,48 +281,48 @@ func (a *app) handleTool(args json.RawMessage) zotext.ToolResult {
281 }281 }
282 lines = append(lines, mark+" "+it.Text)282 lines = append(lines, mark+" "+it.Text)
283 }283 }
284- return zotext.TextResult(strings.Join(lines, "\n"))284+ return ext.TextResult(strings.Join(lines, "\n"))
285 case "add":285 case "add":
286 if strings.TrimSpace(in.Title) == "" {286 if strings.TrimSpace(in.Title) == "" {
287- return zotext.TextErrorResult("title is required for add")287+ return ext.TextErrorResult("title is required for add")
288 }288 }
289 a.st.Items = append(a.st.Items, todoItem{Text: strings.TrimSpace(in.Title)})289 a.st.Items = append(a.st.Items, todoItem{Text: strings.TrimSpace(in.Title)})
290 a.st.Cursor = len(a.st.Items) - 1290 a.st.Cursor = len(a.st.Items) - 1
291 case "complete":291 case "complete":
292 idx := a.findByTitleLocked(in.Title)292 idx := a.findByTitleLocked(in.Title)
293 if idx < 0 {293 if idx < 0 {
294- return zotext.TextErrorResult("todo not found: " + in.Title)294+ return ext.TextErrorResult("todo not found: " + in.Title)
295 }295 }
296 a.st.Items[idx].Done = true296 a.st.Items[idx].Done = true
297 a.st.Cursor = idx297 a.st.Cursor = idx
298 case "edit":298 case "edit":
299 idx := a.findByTitleLocked(in.Title)299 idx := a.findByTitleLocked(in.Title)
300 if idx < 0 {300 if idx < 0 {
301- return zotext.TextErrorResult("todo not found: " + in.Title)301+ return ext.TextErrorResult("todo not found: " + in.Title)
302 }302 }
303 if strings.TrimSpace(in.NewTitle) == "" {303 if strings.TrimSpace(in.NewTitle) == "" {
304- return zotext.TextErrorResult("new_title is required for edit")304+ return ext.TextErrorResult("new_title is required for edit")
305 }305 }
306 a.st.Items[idx].Text = strings.TrimSpace(in.NewTitle)306 a.st.Items[idx].Text = strings.TrimSpace(in.NewTitle)
307 a.st.Cursor = idx307 a.st.Cursor = idx
308 case "remove":308 case "remove":
309 idx := a.findByTitleLocked(in.Title)309 idx := a.findByTitleLocked(in.Title)
310 if idx < 0 {310 if idx < 0 {
311- return zotext.TextErrorResult("todo not found: " + in.Title)311+ return ext.TextErrorResult("todo not found: " + in.Title)
312 }312 }
313 a.st.Items = append(a.st.Items[:idx], a.st.Items[idx+1:]...)313 a.st.Items = append(a.st.Items[:idx], a.st.Items[idx+1:]...)
314 case "":314 case "":
315- return zotext.TextErrorResult("action is required")315+ return ext.TextErrorResult("action is required")
316 default:316 default:
317- return zotext.TextErrorResult("unsupported action: " + in.Action)317+ return ext.TextErrorResult("unsupported action: " + in.Action)
318 }318 }
319 if err := a.saveLocked(); err != nil {319 if err := a.saveLocked(); err != nil {
320- return zotext.TextErrorResult("save todos: " + err.Error())320+ return ext.TextErrorResult("save todos: " + err.Error())
321 }321 }
322 if a.mode == "" {322 if a.mode == "" {
323 a.rerenderLocked()323 a.rerenderLocked()
324 }324 }
325- return zotext.TextResult("ok")325+ return ext.TextResult("ok")
326 }326 }
327 327
328 func (a *app) findByTitleLocked(title string) int {328 func (a *app) findByTitleLocked(title string) int {
M examples/extensions/weather/main.go +8 -8
@@ -21,7 +21,7 @@ import (
2121 "fmt"
2222 "strings"
2323
24- "github.com/patriceckhart/zot/pkg/zotext"
24+ "github.com/patriceckhart/zot/packages/agent/ext"
2525 )
2626
2727 const weatherSchema = `{
@@ -36,27 +36,27 @@ const weatherSchema = `{
3636 }`
3737
3838 func main() {
39- ext := zotext.New("weather", "1.0.0")
39+ e := ext.New("weather", "1.0.0")
4040
41- ext.Tool("weather", "Get the current weather for a city.", json.RawMessage(weatherSchema), func(args json.RawMessage) zotext.ToolResult {
41+ e.Tool("weather", "Get the current weather for a city.", json.RawMessage(weatherSchema), func(args json.RawMessage) ext.ToolResult {
4242 var in struct {
4343 City string `json:"city"`
4444 }
4545 if err := json.Unmarshal(args, &in); err != nil {
46- return zotext.TextErrorResult("invalid args: " + err.Error())
46+ return ext.TextErrorResult("invalid args: " + err.Error())
4747 }
4848 city := strings.TrimSpace(in.City)
4949 if city == "" {
50- return zotext.TextErrorResult("city is required")
50+ return ext.TextErrorResult("city is required")
5151 }
5252 // Stable fake "weather": derive temperature + condition from a
5353 // hash of the city name so the same city always reports the
5454 // same thing. No API calls, no timezone math, no surprises.
55- return zotext.TextResult(fakeWeather(city))
55+ return ext.TextResult(fakeWeather(city))
5656 })
5757
58- if err := ext.Run(); err != nil {
59- ext.Logf("fatal: %v", err)
58+ if err := e.Run(); err != nil {
59+ e.Logf("fatal: %v", err)
6060 }
6161 }
6262
@@ -21,7 +21,7 @@ import (
21 "fmt"21 "fmt"
22 "strings"22 "strings"
23 23
24- "github.com/patriceckhart/zot/pkg/zotext"24+ "github.com/patriceckhart/zot/packages/agent/ext"
25 )25 )
26 26
27 const weatherSchema = `{27 const weatherSchema = `{
@@ -36,27 +36,27 @@ const weatherSchema = `{
36 }`36 }`
37 37
38 func main() {38 func main() {
39- ext := zotext.New("weather", "1.0.0")39+ e := ext.New("weather", "1.0.0")
40 40
41- ext.Tool("weather", "Get the current weather for a city.", json.RawMessage(weatherSchema), func(args json.RawMessage) zotext.ToolResult {41+ e.Tool("weather", "Get the current weather for a city.", json.RawMessage(weatherSchema), func(args json.RawMessage) ext.ToolResult {
42 var in struct {42 var in struct {
43 City string `json:"city"`43 City string `json:"city"`
44 }44 }
45 if err := json.Unmarshal(args, &in); err != nil {45 if err := json.Unmarshal(args, &in); err != nil {
46- return zotext.TextErrorResult("invalid args: " + err.Error())46+ return ext.TextErrorResult("invalid args: " + err.Error())
47 }47 }
48 city := strings.TrimSpace(in.City)48 city := strings.TrimSpace(in.City)
49 if city == "" {49 if city == "" {
50- return zotext.TextErrorResult("city is required")50+ return ext.TextErrorResult("city is required")
51 }51 }
52 // Stable fake "weather": derive temperature + condition from a52 // Stable fake "weather": derive temperature + condition from a
53 // hash of the city name so the same city always reports the53 // hash of the city name so the same city always reports the
54 // same thing. No API calls, no timezone math, no surprises.54 // same thing. No API calls, no timezone math, no surprises.
55- return zotext.TextResult(fakeWeather(city))55+ return ext.TextResult(fakeWeather(city))
56 })56 })
57 57
58- if err := ext.Run(); err != nil {58+ if err := e.Run(); err != nil {
59- ext.Logf("fatal: %v", err)59+ e.Logf("fatal: %v", err)
60 }60 }
61 }61 }
62 62
M examples/rpc/go/main.go +1 -1
@@ -1,6 +1,6 @@
11 // Tiny Go program that drives `zot rpc` as a subprocess.
22 //
3-// For an in-process Go embedding, use github.com/patriceckhart/zot/pkg/zotcore
3+// For an in-process Go embedding, use github.com/patriceckhart/zot/packages/agent/sdk
44 // instead — this example exists to show what consumers in OTHER
55 // languages have to do.
66 package main
@@ -1,6 +1,6 @@
1 // Tiny Go program that drives `zot rpc` as a subprocess.1 // Tiny Go program that drives `zot rpc` as a subprocess.
2 //2 //
3-// For an in-process Go embedding, use github.com/patriceckhart/zot/pkg/zotcore3+// For an in-process Go embedding, use github.com/patriceckhart/zot/packages/agent/sdk
4 // instead — this example exists to show what consumers in OTHER4 // instead — this example exists to show what consumers in OTHER
5 // languages have to do.5 // languages have to do.
6 package main6 package main
M examples/sdk/main.go +3 -3
@@ -1,4 +1,4 @@
1-// In-process Go embedding of the zot agent runtime via the zotcore SDK.
1+// In-process Go embedding of the zot agent runtime via the sdk package.
22 // Compare to examples/rpc/go which spawns `zot rpc` as a subprocess.
33 package main
44
@@ -8,7 +8,7 @@ import (
88 "os"
99 "strings"
1010
11- "github.com/patriceckhart/zot/pkg/zotcore"
11+ "github.com/patriceckhart/zot/packages/agent/sdk"
1212 )
1313
1414 func main() {
@@ -18,7 +18,7 @@ func main() {
1818 }
1919 prompt := strings.Join(os.Args[1:], " ")
2020
21- rt, err := zotcore.New(zotcore.Config{})
21+ rt, err := sdk.New(sdk.Config{})
2222 if err != nil {
2323 fmt.Fprintln(os.Stderr, err)
2424 os.Exit(1)
@@ -1,4 +1,4 @@
1-// In-process Go embedding of the zot agent runtime via the zotcore SDK.1+// In-process Go embedding of the zot agent runtime via the sdk package.
2 // Compare to examples/rpc/go which spawns `zot rpc` as a subprocess.2 // Compare to examples/rpc/go which spawns `zot rpc` as a subprocess.
3 package main3 package main
4 4
@@ -8,7 +8,7 @@ import (
8 "os"8 "os"
9 "strings"9 "strings"
10 10
11- "github.com/patriceckhart/zot/pkg/zotcore"11+ "github.com/patriceckhart/zot/packages/agent/sdk"
12 )12 )
13 13
14 func main() {14 func main() {
@@ -18,7 +18,7 @@ func main() {
18 }18 }
19 prompt := strings.Join(os.Args[1:], " ")19 prompt := strings.Join(os.Args[1:], " ")
20 20
21- rt, err := zotcore.New(zotcore.Config{})21+ rt, err := sdk.New(sdk.Config{})
22 if err != nil {22 if err != nil {
23 fmt.Fprintln(os.Stderr, err)23 fmt.Fprintln(os.Stderr, err)
24 os.Exit(1)24 os.Exit(1)
R internal/agent/args.go → packages/agent/args.go +2 -2 renamed, 99% similar
@@ -5,7 +5,7 @@ import (
55 "os"
66 "strings"
77
8- "github.com/patriceckhart/zot/internal/tui"
8+ "github.com/patriceckhart/zot/packages/tui"
99 "golang.org/x/term"
1010 )
1111
@@ -22,7 +22,7 @@ const (
2222 // the path provided by --swarm-agent, reads supervisor messages
2323 // off it ("user ...", "cancel", "shutdown"), runs each user turn
2424 // against a persistent session, and streams JSONL events on
25- // stdout. See internal/swarm/inbox.go for the wire protocol.
25+ // stdout. See packages/agent/swarm/inbox.go for the wire protocol.
2626 ModeSwarmAgent Mode = "swarm-agent"
2727 )
2828
@@ -5,7 +5,7 @@ import (
5 "os"5 "os"
6 "strings"6 "strings"
7 7
8- "github.com/patriceckhart/zot/internal/tui"8+ "github.com/patriceckhart/zot/packages/tui"
9 "golang.org/x/term"9 "golang.org/x/term"
10 )10 )
11 11
@@ -22,7 +22,7 @@ const (
22 // the path provided by --swarm-agent, reads supervisor messages22 // the path provided by --swarm-agent, reads supervisor messages
23 // off it ("user ...", "cancel", "shutdown"), runs each user turn23 // off it ("user ...", "cancel", "shutdown"), runs each user turn
24 // against a persistent session, and streams JSONL events on24 // against a persistent session, and streams JSONL events on
25- // stdout. See internal/swarm/inbox.go for the wire protocol.25+ // stdout. See packages/agent/swarm/inbox.go for the wire protocol.
26 ModeSwarmAgent Mode = "swarm-agent"26 ModeSwarmAgent Mode = "swarm-agent"
27 )27 )
28 28
R internal/agent/botcmd.go → packages/agent/botcmd.go +2 -2 renamed, 99% similar
@@ -15,8 +15,8 @@ import (
1515 "syscall"
1616 "time"
1717
18- "github.com/patriceckhart/zot/internal/agent/modes/telegram"
19- "github.com/patriceckhart/zot/internal/core"
18+ "github.com/patriceckhart/zot/packages/agent/modes/telegram"
19+ "github.com/patriceckhart/zot/packages/core"
2020 )
2121
2222 // detachChild configures cmd to run in its own process group so tty
@@ -15,8 +15,8 @@ import (
15 "syscall"15 "syscall"
16 "time"16 "time"
17 17
18- "github.com/patriceckhart/zot/internal/agent/modes/telegram"18+ "github.com/patriceckhart/zot/packages/agent/modes/telegram"
19- "github.com/patriceckhart/zot/internal/core"19+ "github.com/patriceckhart/zot/packages/core"
20 )20 )
21 21
22 // detachChild configures cmd to run in its own process group so tty22 // detachChild configures cmd to run in its own process group so tty
R internal/agent/botcmd_unix.go → packages/agent/botcmd_unix.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/botcmd_windows.go → packages/agent/botcmd_windows.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/build.go → packages/agent/build.go +5 -5 renamed, 98% similar
@@ -9,10 +9,10 @@ import (
99 "strings"
1010
1111 zotdocs "github.com/patriceckhart/zot"
12- "github.com/patriceckhart/zot/internal/agent/tools"
13- "github.com/patriceckhart/zot/internal/core"
14- "github.com/patriceckhart/zot/internal/provider"
15- "github.com/patriceckhart/zot/internal/skills"
12+ "github.com/patriceckhart/zot/packages/agent/skills"
13+ "github.com/patriceckhart/zot/packages/agent/tools"
14+ "github.com/patriceckhart/zot/packages/core"
15+ "github.com/patriceckhart/zot/packages/provider"
1616 )
1717
1818 // Resolved is the effective configuration after merging CLI, config, defaults.
@@ -88,7 +88,7 @@ func (r *Resolved) MergeExtensionTools(mgr ExtensionToolSource) {
8888
8989 // ExtensionToolSource is the slice of the extension manager that
9090 // MergeExtensionTools needs. Lives here as an interface so the
91-// build package doesn't import internal/agent/extensions (which
91+// build package doesn't import packages/agent/extensions (which
9292 // imports core, which imports... avoid the cycle).
9393 type ExtensionToolSource interface {
9494 Tools() []ExtensionToolInfo
@@ -9,10 +9,10 @@ import (
9 "strings"9 "strings"
10 10
11 zotdocs "github.com/patriceckhart/zot"11 zotdocs "github.com/patriceckhart/zot"
12- "github.com/patriceckhart/zot/internal/agent/tools"12+ "github.com/patriceckhart/zot/packages/agent/skills"
13- "github.com/patriceckhart/zot/internal/core"13+ "github.com/patriceckhart/zot/packages/agent/tools"
14- "github.com/patriceckhart/zot/internal/provider"14+ "github.com/patriceckhart/zot/packages/core"
15- "github.com/patriceckhart/zot/internal/skills"15+ "github.com/patriceckhart/zot/packages/provider"
16 )16 )
17 17
18 // Resolved is the effective configuration after merging CLI, config, defaults.18 // Resolved is the effective configuration after merging CLI, config, defaults.
@@ -88,7 +88,7 @@ func (r *Resolved) MergeExtensionTools(mgr ExtensionToolSource) {
88 88
89 // ExtensionToolSource is the slice of the extension manager that89 // ExtensionToolSource is the slice of the extension manager that
90 // MergeExtensionTools needs. Lives here as an interface so the90 // MergeExtensionTools needs. Lives here as an interface so the
91-// build package doesn't import internal/agent/extensions (which91+// build package doesn't import packages/agent/extensions (which
92 // imports core, which imports... avoid the cycle).92 // imports core, which imports... avoid the cycle).
93 type ExtensionToolSource interface {93 type ExtensionToolSource interface {
94 Tools() []ExtensionToolInfo94 Tools() []ExtensionToolInfo
R internal/agent/build_test.go → packages/agent/build_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/changelog.go → packages/agent/changelog.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/cli.go → packages/agent/cli.go +10 -10 renamed, 98% similar
@@ -15,16 +15,16 @@ import (
1515 "syscall"
1616 "time"
1717
18- "github.com/patriceckhart/zot/internal/agent/extensions"
19- "github.com/patriceckhart/zot/internal/agent/modes"
20- "github.com/patriceckhart/zot/internal/agent/tools"
21- "github.com/patriceckhart/zot/internal/auth"
22- "github.com/patriceckhart/zot/internal/core"
23- "github.com/patriceckhart/zot/internal/extproto"
24- "github.com/patriceckhart/zot/internal/provider"
25- "github.com/patriceckhart/zot/internal/skills"
26- "github.com/patriceckhart/zot/internal/swarm"
27- "github.com/patriceckhart/zot/internal/tui"
18+ "github.com/patriceckhart/zot/packages/agent/extensions"
19+ "github.com/patriceckhart/zot/packages/agent/extproto"
20+ "github.com/patriceckhart/zot/packages/agent/modes"
21+ "github.com/patriceckhart/zot/packages/agent/skills"
22+ "github.com/patriceckhart/zot/packages/agent/swarm"
23+ "github.com/patriceckhart/zot/packages/agent/tools"
24+ "github.com/patriceckhart/zot/packages/core"
25+ "github.com/patriceckhart/zot/packages/provider"
26+ "github.com/patriceckhart/zot/packages/provider/auth"
27+ "github.com/patriceckhart/zot/packages/tui"
2828 )
2929
3030 // interactiveExtHooks is a tiny adapter that lets the extension
@@ -15,16 +15,16 @@ import (
15 "syscall"15 "syscall"
16 "time"16 "time"
17 17
18- "github.com/patriceckhart/zot/internal/agent/extensions"18+ "github.com/patriceckhart/zot/packages/agent/extensions"
19- "github.com/patriceckhart/zot/internal/agent/modes"19+ "github.com/patriceckhart/zot/packages/agent/extproto"
20- "github.com/patriceckhart/zot/internal/agent/tools"20+ "github.com/patriceckhart/zot/packages/agent/modes"
21- "github.com/patriceckhart/zot/internal/auth"21+ "github.com/patriceckhart/zot/packages/agent/skills"
22- "github.com/patriceckhart/zot/internal/core"22+ "github.com/patriceckhart/zot/packages/agent/swarm"
23- "github.com/patriceckhart/zot/internal/extproto"23+ "github.com/patriceckhart/zot/packages/agent/tools"
24- "github.com/patriceckhart/zot/internal/provider"24+ "github.com/patriceckhart/zot/packages/core"
25- "github.com/patriceckhart/zot/internal/skills"25+ "github.com/patriceckhart/zot/packages/provider"
26- "github.com/patriceckhart/zot/internal/swarm"26+ "github.com/patriceckhart/zot/packages/provider/auth"
27- "github.com/patriceckhart/zot/internal/tui"27+ "github.com/patriceckhart/zot/packages/tui"
28 )28 )
29 29
30 // interactiveExtHooks is a tiny adapter that lets the extension30 // interactiveExtHooks is a tiny adapter that lets the extension
R internal/agent/config.go → packages/agent/config.go +1 -1 renamed, 99% similar
@@ -11,7 +11,7 @@ import (
1111 "runtime"
1212 "time"
1313
14- "github.com/patriceckhart/zot/internal/auth"
14+ "github.com/patriceckhart/zot/packages/provider/auth"
1515 )
1616
1717 // Config is the persisted user configuration.
@@ -11,7 +11,7 @@ import (
11 "runtime"11 "runtime"
12 "time"12 "time"
13 13
14- "github.com/patriceckhart/zot/internal/auth"14+ "github.com/patriceckhart/zot/packages/provider/auth"
15 )15 )
16 16
17 // Config is the persisted user configuration.17 // Config is the persisted user configuration.
R pkg/zotext/zotext.go → packages/agent/ext/ext.go +7 -7 renamed, 98% similar
@@ -1,4 +1,4 @@
1-// Package zotext is the Go SDK for writing zot extensions.
1+// Package ext is the Go SDK for writing zot extensions.
22 //
33 // An extension is a subprocess that talks to zot over its stdin/stdout
44 // in newline-delimited JSON. This package wraps the wire format so
@@ -9,12 +9,12 @@
99 //
1010 // package main
1111 //
12-// import "github.com/patriceckhart/zot/pkg/zotext"
12+// import "github.com/patriceckhart/zot/packages/agent/ext"
1313 //
1414 // func main() {
15-// ext := zotext.New("hello", "1.0.0")
16-// ext.Command("hello", "say hi", func(args string) zotext.Response {
17-// return zotext.Prompt("Greet me in three different languages.")
15+// ext := ext.New("hello", "1.0.0")
16+// ext.Command("hello", "say hi", func(args string) ext.Response {
17+// return ext.Prompt("Greet me in three different languages.")
1818 // })
1919 // ext.Run()
2020 // }
@@ -24,7 +24,7 @@
2424 //
2525 // The same wire format also has reference clients in TypeScript and
2626 // Python under examples/extensions/. Use whichever language fits.
27-package zotext
27+package ext
2828
2929 import (
3030 "bufio"
@@ -35,7 +35,7 @@ import (
3535 "os"
3636 "sync"
3737
38- "github.com/patriceckhart/zot/internal/extproto"
38+ "github.com/patriceckhart/zot/packages/agent/extproto"
3939 )
4040
4141 func base64Encode(b []byte) string { return base64.StdEncoding.EncodeToString(b) }
@@ -1,4 +1,4 @@
1-// Package zotext is the Go SDK for writing zot extensions.1+// Package ext is the Go SDK for writing zot extensions.
2 //2 //
3 // An extension is a subprocess that talks to zot over its stdin/stdout3 // An extension is a subprocess that talks to zot over its stdin/stdout
4 // in newline-delimited JSON. This package wraps the wire format so4 // in newline-delimited JSON. This package wraps the wire format so
@@ -9,12 +9,12 @@
9 //9 //
10 // package main10 // package main
11 //11 //
12-// import "github.com/patriceckhart/zot/pkg/zotext"12+// import "github.com/patriceckhart/zot/packages/agent/ext"
13 //13 //
14 // func main() {14 // func main() {
15-// ext := zotext.New("hello", "1.0.0")15+// ext := ext.New("hello", "1.0.0")
16-// ext.Command("hello", "say hi", func(args string) zotext.Response {16+// ext.Command("hello", "say hi", func(args string) ext.Response {
17-// return zotext.Prompt("Greet me in three different languages.")17+// return ext.Prompt("Greet me in three different languages.")
18 // })18 // })
19 // ext.Run()19 // ext.Run()
20 // }20 // }
@@ -24,7 +24,7 @@
24 //24 //
25 // The same wire format also has reference clients in TypeScript and25 // The same wire format also has reference clients in TypeScript and
26 // Python under examples/extensions/. Use whichever language fits.26 // Python under examples/extensions/. Use whichever language fits.
27-package zotext27+package ext
28 28
29 import (29 import (
30 "bufio"30 "bufio"
@@ -35,7 +35,7 @@ import (
35 "os"35 "os"
36 "sync"36 "sync"
37 37
38- "github.com/patriceckhart/zot/internal/extproto"38+ "github.com/patriceckhart/zot/packages/agent/extproto"
39 )39 )
40 40
41 func base64Encode(b []byte) string { return base64.StdEncoding.EncodeToString(b) }41 func base64Encode(b []byte) string { return base64.StdEncoding.EncodeToString(b) }
R internal/agent/extcmd.go → packages/agent/extcmd.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/extensions/base64.go → packages/agent/extensions/base64.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/extensions/events.go → packages/agent/extensions/events.go +1 -1 renamed, 99% similar
@@ -6,7 +6,7 @@ import (
66 "fmt"
77 "time"
88
9- "github.com/patriceckhart/zot/internal/extproto"
9+ "github.com/patriceckhart/zot/packages/agent/extproto"
1010 )
1111
1212 // EmitEvent fires a one-way lifecycle event to every extension that
@@ -6,7 +6,7 @@ import (
6 "fmt"6 "fmt"
7 "time"7 "time"
8 8
9- "github.com/patriceckhart/zot/internal/extproto"9+ "github.com/patriceckhart/zot/packages/agent/extproto"
10 )10 )
11 11
12 // EmitEvent fires a one-way lifecycle event to every extension that12 // EmitEvent fires a one-way lifecycle event to every extension that
R internal/agent/extensions/intercept_test.go → packages/agent/extensions/intercept_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/extensions/manager.go → packages/agent/extensions/manager.go +2 -2 renamed, 99% similar
@@ -9,7 +9,7 @@
99 // extension does not affect the others or the host.
1010 //
1111 // See docs/extensions.md for the user-facing reference and
12-// internal/extproto for the wire format.
12+// packages/agent/extproto for the wire format.
1313 package extensions
1414
1515 import (
@@ -27,7 +27,7 @@ import (
2727 "syscall"
2828 "time"
2929
30- "github.com/patriceckhart/zot/internal/extproto"
30+ "github.com/patriceckhart/zot/packages/agent/extproto"
3131 )
3232
3333 // Manifest is the extension.json file shipped alongside an
@@ -9,7 +9,7 @@
9 // extension does not affect the others or the host.9 // extension does not affect the others or the host.
10 //10 //
11 // See docs/extensions.md for the user-facing reference and11 // See docs/extensions.md for the user-facing reference and
12-// internal/extproto for the wire format.12+// packages/agent/extproto for the wire format.
13 package extensions13 package extensions
14 14
15 import (15 import (
@@ -27,7 +27,7 @@ import (
27 "syscall"27 "syscall"
28 "time"28 "time"
29 29
30- "github.com/patriceckhart/zot/internal/extproto"30+ "github.com/patriceckhart/zot/packages/agent/extproto"
31 )31 )
32 32
33 // Manifest is the extension.json file shipped alongside an33 // Manifest is the extension.json file shipped alongside an
R internal/agent/extensions/manager_test.go → packages/agent/extensions/manager_test.go +1 -1 renamed, 98% similar
@@ -5,7 +5,7 @@ import (
55 "encoding/json"
66 "os"
77
8- "github.com/patriceckhart/zot/internal/extproto"
8+ "github.com/patriceckhart/zot/packages/agent/extproto"
99 "path/filepath"
1010 "runtime"
1111 "sync"
@@ -5,7 +5,7 @@ import (
5 "encoding/json"5 "encoding/json"
6 "os"6 "os"
7 7
8- "github.com/patriceckhart/zot/internal/extproto"8+ "github.com/patriceckhart/zot/packages/agent/extproto"
9 "path/filepath"9 "path/filepath"
10 "runtime"10 "runtime"
11 "sync"11 "sync"
R internal/agent/extensions/tool.go → packages/agent/extensions/tool.go +2 -2 renamed, 97% similar
@@ -6,8 +6,8 @@ import (
66 "fmt"
77 "time"
88
9- "github.com/patriceckhart/zot/internal/core"
10- "github.com/patriceckhart/zot/internal/provider"
9+ "github.com/patriceckhart/zot/packages/core"
10+ "github.com/patriceckhart/zot/packages/provider"
1111 )
1212
1313 // extensionTool wraps a single extension-registered tool as a
@@ -6,8 +6,8 @@ import (
6 "fmt"6 "fmt"
7 "time"7 "time"
8 8
9- "github.com/patriceckhart/zot/internal/core"9+ "github.com/patriceckhart/zot/packages/core"
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/provider"
11 )11 )
12 12
13 // extensionTool wraps a single extension-registered tool as a13 // extensionTool wraps a single extension-registered tool as a
R internal/agent/extensions/tool_test.go → packages/agent/extensions/tool_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/extproto/extproto.go → packages/agent/extproto/extproto.go +1 -1 renamed, 98% similar
@@ -1,6 +1,6 @@
11 // Package extproto defines the JSON-over-stdin/stdout wire format
22 // spoken between zot and its extension subprocesses. Both the host
3-// (internal/agent/extensions) and the SDK (pkg/zotext) marshal/
3+// (packages/agent/extensions) and the SDK (packages/agent/ext) marshal/
44 // unmarshal the same types, so changes here ripple through both.
55 //
66 // All frames are one JSON object terminated by a single LF. Object
@@ -1,6 +1,6 @@
1 // Package extproto defines the JSON-over-stdin/stdout wire format1 // Package extproto defines the JSON-over-stdin/stdout wire format
2 // spoken between zot and its extension subprocesses. Both the host2 // spoken between zot and its extension subprocesses. Both the host
3-// (internal/agent/extensions) and the SDK (pkg/zotext) marshal/3+// (packages/agent/extensions) and the SDK (packages/agent/ext) marshal/
4 // unmarshal the same types, so changes here ripple through both.4 // unmarshal the same types, so changes here ripple through both.
5 //5 //
6 // All frames are one JSON object terminated by a single LF. Object6 // All frames are one JSON object terminated by a single LF. Object
R internal/agent/modelsync.go → packages/agent/modelsync.go +1 -1 renamed, 99% similar
@@ -7,7 +7,7 @@ import (
77 "path/filepath"
88 "time"
99
10- "github.com/patriceckhart/zot/internal/provider"
10+ "github.com/patriceckhart/zot/packages/provider"
1111 )
1212
1313 // ModelCachePath returns the on-disk location of the merged model cache.
@@ -7,7 +7,7 @@ import (
7 "path/filepath"7 "path/filepath"
8 "time"8 "time"
9 9
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/provider"
11 )11 )
12 12
13 // ModelCachePath returns the on-disk location of the merged model cache.13 // ModelCachePath returns the on-disk location of the merged model cache.
R internal/agent/modelsync_test.go → packages/agent/modelsync_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/btw_dialog.go → packages/agent/modes/btw_dialog.go +3 -3 renamed, 98% similar
@@ -7,9 +7,9 @@ import (
77 "sync"
88 "time"
99
10- "github.com/patriceckhart/zot/internal/core"
11- "github.com/patriceckhart/zot/internal/provider"
12- "github.com/patriceckhart/zot/internal/tui"
10+ "github.com/patriceckhart/zot/packages/core"
11+ "github.com/patriceckhart/zot/packages/provider"
12+ "github.com/patriceckhart/zot/packages/tui"
1313 )
1414
1515 // btwTurn is one user/assistant pair within a side chat. Kept
@@ -7,9 +7,9 @@ import (
7 "sync"7 "sync"
8 "time"8 "time"
9 9
10- "github.com/patriceckhart/zot/internal/core"10+ "github.com/patriceckhart/zot/packages/core"
11- "github.com/patriceckhart/zot/internal/provider"11+ "github.com/patriceckhart/zot/packages/provider"
12- "github.com/patriceckhart/zot/internal/tui"12+ "github.com/patriceckhart/zot/packages/tui"
13 )13 )
14 14
15 // btwTurn is one user/assistant pair within a side chat. Kept15 // btwTurn is one user/assistant pair within a side chat. Kept
R internal/agent/modes/changelog_dialog.go → packages/agent/modes/changelog_dialog.go +1 -1 renamed, 98% similar
@@ -4,7 +4,7 @@ import (
44 "fmt"
55 "strings"
66
7- "github.com/patriceckhart/zot/internal/tui"
7+ "github.com/patriceckhart/zot/packages/tui"
88 )
99
1010 // changelogDialog is the one-shot release-notes overlay shown the
@@ -4,7 +4,7 @@ import (
4 "fmt"4 "fmt"
5 "strings"5 "strings"
6 6
7- "github.com/patriceckhart/zot/internal/tui"7+ "github.com/patriceckhart/zot/packages/tui"
8 )8 )
9 9
10 // changelogDialog is the one-shot release-notes overlay shown the10 // changelogDialog is the one-shot release-notes overlay shown the
R internal/agent/modes/confirm_dialog.go → packages/agent/modes/confirm_dialog.go +2 -2 renamed, 98% similar
@@ -6,8 +6,8 @@ import (
66 "sync"
77 "time"
88
9- "github.com/patriceckhart/zot/internal/core"
10- "github.com/patriceckhart/zot/internal/tui"
9+ "github.com/patriceckhart/zot/packages/core"
10+ "github.com/patriceckhart/zot/packages/tui"
1111 )
1212
1313 // confirmRequest is one pending confirmation. The agent goroutine
@@ -6,8 +6,8 @@ import (
6 "sync"6 "sync"
7 "time"7 "time"
8 8
9- "github.com/patriceckhart/zot/internal/core"9+ "github.com/patriceckhart/zot/packages/core"
10- "github.com/patriceckhart/zot/internal/tui"10+ "github.com/patriceckhart/zot/packages/tui"
11 )11 )
12 12
13 // confirmRequest is one pending confirmation. The agent goroutine13 // confirmRequest is one pending confirmation. The agent goroutine
R internal/agent/modes/dialog_frame.go → packages/agent/modes/dialog_frame.go +1 -1 renamed, 98% similar
@@ -5,7 +5,7 @@ import (
55
66 "github.com/mattn/go-runewidth"
77
8- "github.com/patriceckhart/zot/internal/tui"
8+ "github.com/patriceckhart/zot/packages/tui"
99 )
1010
1111 // frameHeader returns a full-width rule with a small title at the left.
@@ -5,7 +5,7 @@ import (
5 5
6 "github.com/mattn/go-runewidth"6 "github.com/mattn/go-runewidth"
7 7
8- "github.com/patriceckhart/zot/internal/tui"8+ "github.com/patriceckhart/zot/packages/tui"
9 )9 )
10 10
11 // frameHeader returns a full-width rule with a small title at the left.11 // frameHeader returns a full-width rule with a small title at the left.
R internal/agent/modes/ext_panel_dialog.go → packages/agent/modes/ext_panel_dialog.go +1 -1 renamed, 98% similar
@@ -6,7 +6,7 @@ import (
66
77 "github.com/mattn/go-runewidth"
88
9- "github.com/patriceckhart/zot/internal/tui"
9+ "github.com/patriceckhart/zot/packages/tui"
1010 )
1111
1212 type extPanelDialog struct {
@@ -6,7 +6,7 @@ import (
6 6
7 "github.com/mattn/go-runewidth"7 "github.com/mattn/go-runewidth"
8 8
9- "github.com/patriceckhart/zot/internal/tui"9+ "github.com/patriceckhart/zot/packages/tui"
10 )10 )
11 11
12 type extPanelDialog struct {12 type extPanelDialog struct {
R internal/agent/modes/file_suggest.go → packages/agent/modes/file_suggest.go +1 -1 renamed, 99% similar
@@ -8,7 +8,7 @@ import (
88 "strings"
99 "time"
1010
11- "github.com/patriceckhart/zot/internal/tui"
11+ "github.com/patriceckhart/zot/packages/tui"
1212 )
1313
1414 // fileSuggester provides an @-triggered file/directory picker popup.
@@ -8,7 +8,7 @@ import (
8 "strings"8 "strings"
9 "time"9 "time"
10 10
11- "github.com/patriceckhart/zot/internal/tui"11+ "github.com/patriceckhart/zot/packages/tui"
12 )12 )
13 13
14 // fileSuggester provides an @-triggered file/directory picker popup.14 // fileSuggester provides an @-triggered file/directory picker popup.
R internal/agent/modes/file_suggest_test.go → packages/agent/modes/file_suggest_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/help.go → packages/agent/modes/help.go +1 -1 renamed, 98% similar
@@ -5,7 +5,7 @@ import (
55 "strings"
66
77 "github.com/mattn/go-runewidth"
8- "github.com/patriceckhart/zot/internal/tui"
8+ "github.com/patriceckhart/zot/packages/tui"
99 )
1010
1111 // helpKeyRows is the list of keybindings shown by /help.
@@ -5,7 +5,7 @@ import (
5 "strings"5 "strings"
6 6
7 "github.com/mattn/go-runewidth"7 "github.com/mattn/go-runewidth"
8- "github.com/patriceckhart/zot/internal/tui"8+ "github.com/patriceckhart/zot/packages/tui"
9 )9 )
10 10
11 // helpKeyRows is the list of keybindings shown by /help.11 // helpKeyRows is the list of keybindings shown by /help.
R internal/agent/modes/image_scroll_test.go → packages/agent/modes/image_scroll_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/interactive.go → packages/agent/modes/interactive.go +10 -10 renamed, 99% similar
@@ -9,16 +9,16 @@ import (
99 "sync"
1010 "time"
1111
12- "github.com/patriceckhart/zot/internal/agent/extensions"
13- "github.com/patriceckhart/zot/internal/agent/modes/telegram"
14- "github.com/patriceckhart/zot/internal/agent/tools"
15- "github.com/patriceckhart/zot/internal/auth"
16- "github.com/patriceckhart/zot/internal/core"
17- "github.com/patriceckhart/zot/internal/extproto"
18- "github.com/patriceckhart/zot/internal/provider"
19- "github.com/patriceckhart/zot/internal/skills"
20- "github.com/patriceckhart/zot/internal/swarm"
21- "github.com/patriceckhart/zot/internal/tui"
12+ "github.com/patriceckhart/zot/packages/agent/extensions"
13+ "github.com/patriceckhart/zot/packages/agent/extproto"
14+ "github.com/patriceckhart/zot/packages/agent/modes/telegram"
15+ "github.com/patriceckhart/zot/packages/agent/skills"
16+ "github.com/patriceckhart/zot/packages/agent/swarm"
17+ "github.com/patriceckhart/zot/packages/agent/tools"
18+ "github.com/patriceckhart/zot/packages/core"
19+ "github.com/patriceckhart/zot/packages/provider"
20+ "github.com/patriceckhart/zot/packages/provider/auth"
21+ "github.com/patriceckhart/zot/packages/tui"
2222 )
2323
2424 // InteractiveConfig configures the interactive loop.
@@ -9,16 +9,16 @@ import (
9 "sync"9 "sync"
10 "time"10 "time"
11 11
12- "github.com/patriceckhart/zot/internal/agent/extensions"12+ "github.com/patriceckhart/zot/packages/agent/extensions"
13- "github.com/patriceckhart/zot/internal/agent/modes/telegram"13+ "github.com/patriceckhart/zot/packages/agent/extproto"
14- "github.com/patriceckhart/zot/internal/agent/tools"14+ "github.com/patriceckhart/zot/packages/agent/modes/telegram"
15- "github.com/patriceckhart/zot/internal/auth"15+ "github.com/patriceckhart/zot/packages/agent/skills"
16- "github.com/patriceckhart/zot/internal/core"16+ "github.com/patriceckhart/zot/packages/agent/swarm"
17- "github.com/patriceckhart/zot/internal/extproto"17+ "github.com/patriceckhart/zot/packages/agent/tools"
18- "github.com/patriceckhart/zot/internal/provider"18+ "github.com/patriceckhart/zot/packages/core"
19- "github.com/patriceckhart/zot/internal/skills"19+ "github.com/patriceckhart/zot/packages/provider"
20- "github.com/patriceckhart/zot/internal/swarm"20+ "github.com/patriceckhart/zot/packages/provider/auth"
21- "github.com/patriceckhart/zot/internal/tui"21+ "github.com/patriceckhart/zot/packages/tui"
22 )22 )
23 23
24 // InteractiveConfig configures the interactive loop.24 // InteractiveConfig configures the interactive loop.
R internal/agent/modes/json.go → packages/agent/modes/json.go +2 -2 renamed, 97% similar
@@ -6,8 +6,8 @@ import (
66 "fmt"
77 "io"
88
9- "github.com/patriceckhart/zot/internal/core"
10- "github.com/patriceckhart/zot/internal/provider"
9+ "github.com/patriceckhart/zot/packages/core"
10+ "github.com/patriceckhart/zot/packages/provider"
1111 )
1212
1313 // RunJSON runs the agent to completion, writing one JSON object per
@@ -6,8 +6,8 @@ import (
6 "fmt"6 "fmt"
7 "io"7 "io"
8 8
9- "github.com/patriceckhart/zot/internal/core"9+ "github.com/patriceckhart/zot/packages/core"
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/provider"
11 )11 )
12 12
13 // RunJSON runs the agent to completion, writing one JSON object per13 // RunJSON runs the agent to completion, writing one JSON object per
R internal/agent/modes/jump_dialog.go → packages/agent/modes/jump_dialog.go +2 -2 renamed, 98% similar
@@ -4,8 +4,8 @@ import (
44 "fmt"
55 "strings"
66
7- "github.com/patriceckhart/zot/internal/provider"
8- "github.com/patriceckhart/zot/internal/tui"
7+ "github.com/patriceckhart/zot/packages/provider"
8+ "github.com/patriceckhart/zot/packages/tui"
99 )
1010
1111 // jumpTarget describes one "turn" in the current session — a user
@@ -4,8 +4,8 @@ import (
4 "fmt"4 "fmt"
5 "strings"5 "strings"
6 6
7- "github.com/patriceckhart/zot/internal/provider"7+ "github.com/patriceckhart/zot/packages/provider"
8- "github.com/patriceckhart/zot/internal/tui"8+ "github.com/patriceckhart/zot/packages/tui"
9 )9 )
10 10
11 // jumpTarget describes one "turn" in the current session — a user11 // jumpTarget describes one "turn" in the current session — a user
R internal/agent/modes/keychord_hint.go → packages/agent/modes/keychord_hint.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/keychord_hint_test.go → packages/agent/modes/keychord_hint_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/login_dialog.go → packages/agent/modes/login_dialog.go +3 -3 renamed, 99% similar
@@ -4,9 +4,9 @@ import (
44 "fmt"
55 "path/filepath"
66
7- "github.com/patriceckhart/zot/internal/auth"
8- "github.com/patriceckhart/zot/internal/provider"
9- "github.com/patriceckhart/zot/internal/tui"
7+ "github.com/patriceckhart/zot/packages/provider"
8+ "github.com/patriceckhart/zot/packages/provider/auth"
9+ "github.com/patriceckhart/zot/packages/tui"
1010 )
1111
1212 // loginStep is the current node in the login dialog state machine.
@@ -4,9 +4,9 @@ import (
4 "fmt"4 "fmt"
5 "path/filepath"5 "path/filepath"
6 6
7- "github.com/patriceckhart/zot/internal/auth"7+ "github.com/patriceckhart/zot/packages/provider"
8- "github.com/patriceckhart/zot/internal/provider"8+ "github.com/patriceckhart/zot/packages/provider/auth"
9- "github.com/patriceckhart/zot/internal/tui"9+ "github.com/patriceckhart/zot/packages/tui"
10 )10 )
11 11
12 // loginStep is the current node in the login dialog state machine.12 // loginStep is the current node in the login dialog state machine.
R internal/agent/modes/logout_dialog.go → packages/agent/modes/logout_dialog.go +1 -1 renamed, 98% similar
@@ -1,7 +1,7 @@
11 package modes
22
33 import (
4- "github.com/patriceckhart/zot/internal/tui"
4+ "github.com/patriceckhart/zot/packages/tui"
55 )
66
77 // logoutDialog is the picker shown when the user runs `/logout`
@@ -1,7 +1,7 @@
1 package modes1 package modes
2 2
3 import (3 import (
4- "github.com/patriceckhart/zot/internal/tui"4+ "github.com/patriceckhart/zot/packages/tui"
5 )5 )
6 6
7 // logoutDialog is the picker shown when the user runs `/logout`7 // logoutDialog is the picker shown when the user runs `/logout`
R internal/agent/modes/model_dialog.go → packages/agent/modes/model_dialog.go +2 -2 renamed, 98% similar
@@ -6,8 +6,8 @@ import (
66 "strings"
77
88 "github.com/mattn/go-runewidth"
9- "github.com/patriceckhart/zot/internal/provider"
10- "github.com/patriceckhart/zot/internal/tui"
9+ "github.com/patriceckhart/zot/packages/provider"
10+ "github.com/patriceckhart/zot/packages/tui"
1111 )
1212
1313 // modelDialog is an inline picker for choosing the active model.
@@ -6,8 +6,8 @@ import (
6 "strings"6 "strings"
7 7
8 "github.com/mattn/go-runewidth"8 "github.com/mattn/go-runewidth"
9- "github.com/patriceckhart/zot/internal/provider"9+ "github.com/patriceckhart/zot/packages/provider"
10- "github.com/patriceckhart/zot/internal/tui"10+ "github.com/patriceckhart/zot/packages/tui"
11 )11 )
12 12
13 // modelDialog is an inline picker for choosing the active model.13 // modelDialog is an inline picker for choosing the active model.
R internal/agent/modes/print.go → packages/agent/modes/print.go +2 -2 renamed, 93% similar
@@ -7,8 +7,8 @@ import (
77 "io"
88 "strings"
99
10- "github.com/patriceckhart/zot/internal/core"
11- "github.com/patriceckhart/zot/internal/provider"
10+ "github.com/patriceckhart/zot/packages/core"
11+ "github.com/patriceckhart/zot/packages/provider"
1212 )
1313
1414 // RunPrint runs the agent to completion and writes only the final
@@ -7,8 +7,8 @@ import (
7 "io"7 "io"
8 "strings"8 "strings"
9 9
10- "github.com/patriceckhart/zot/internal/core"10+ "github.com/patriceckhart/zot/packages/core"
11- "github.com/patriceckhart/zot/internal/provider"11+ "github.com/patriceckhart/zot/packages/provider"
12 )12 )
13 13
14 // RunPrint runs the agent to completion and writes only the final14 // RunPrint runs the agent to completion and writes only the final
R internal/agent/modes/rescue_dialog.go → packages/agent/modes/rescue_dialog.go +2 -2 renamed, 98% similar
@@ -4,8 +4,8 @@ import (
44 "fmt"
55 "strings"
66
7- "github.com/patriceckhart/zot/internal/provider"
8- "github.com/patriceckhart/zot/internal/tui"
7+ "github.com/patriceckhart/zot/packages/provider"
8+ "github.com/patriceckhart/zot/packages/tui"
99 )
1010
1111 // rescueDialog offers a quick model swap when the active turn fails
@@ -4,8 +4,8 @@ import (
4 "fmt"4 "fmt"
5 "strings"5 "strings"
6 6
7- "github.com/patriceckhart/zot/internal/provider"7+ "github.com/patriceckhart/zot/packages/provider"
8- "github.com/patriceckhart/zot/internal/tui"8+ "github.com/patriceckhart/zot/packages/tui"
9 )9 )
10 10
11 // rescueDialog offers a quick model swap when the active turn fails11 // rescueDialog offers a quick model swap when the active turn fails
R internal/agent/modes/session_dialog.go → packages/agent/modes/session_dialog.go +2 -2 renamed, 98% similar
@@ -5,8 +5,8 @@ import (
55 "strings"
66 "time"
77
8- "github.com/patriceckhart/zot/internal/core"
9- "github.com/patriceckhart/zot/internal/tui"
8+ "github.com/patriceckhart/zot/packages/core"
9+ "github.com/patriceckhart/zot/packages/tui"
1010 )
1111
1212 // sessionDialog is the inline picker shown when the user runs /sessions.
@@ -5,8 +5,8 @@ import (
5 "strings"5 "strings"
6 "time"6 "time"
7 7
8- "github.com/patriceckhart/zot/internal/core"8+ "github.com/patriceckhart/zot/packages/core"
9- "github.com/patriceckhart/zot/internal/tui"9+ "github.com/patriceckhart/zot/packages/tui"
10 )10 )
11 11
12 // sessionDialog is the inline picker shown when the user runs /sessions.12 // sessionDialog is the inline picker shown when the user runs /sessions.
R internal/agent/modes/session_ops_dialog.go → packages/agent/modes/session_ops_dialog.go +1 -1 renamed, 98% similar
@@ -1,7 +1,7 @@
11 package modes
22
33 import (
4- "github.com/patriceckhart/zot/internal/tui"
4+ "github.com/patriceckhart/zot/packages/tui"
55 )
66
77 // sessionOpsDialog is the picker shown when the user runs `/session`
@@ -1,7 +1,7 @@
1 package modes1 package modes
2 2
3 import (3 import (
4- "github.com/patriceckhart/zot/internal/tui"4+ "github.com/patriceckhart/zot/packages/tui"
5 )5 )
6 6
7 // sessionOpsDialog is the picker shown when the user runs `/session`7 // sessionOpsDialog is the picker shown when the user runs `/session`
R internal/agent/modes/session_tree_dialog.go → packages/agent/modes/session_tree_dialog.go +2 -2 renamed, 98% similar
@@ -4,8 +4,8 @@ import (
44 "fmt"
55 "strings"
66
7- "github.com/patriceckhart/zot/internal/core"
8- "github.com/patriceckhart/zot/internal/tui"
7+ "github.com/patriceckhart/zot/packages/core"
8+ "github.com/patriceckhart/zot/packages/tui"
99 )
1010
1111 // sessionTreeDialog renders the branch topology for the current
@@ -4,8 +4,8 @@ import (
4 "fmt"4 "fmt"
5 "strings"5 "strings"
6 6
7- "github.com/patriceckhart/zot/internal/core"7+ "github.com/patriceckhart/zot/packages/core"
8- "github.com/patriceckhart/zot/internal/tui"8+ "github.com/patriceckhart/zot/packages/tui"
9 )9 )
10 10
11 // sessionTreeDialog renders the branch topology for the current11 // sessionTreeDialog renders the branch topology for the current
R internal/agent/modes/settings_dialog.go → packages/agent/modes/settings_dialog.go +1 -1 renamed, 99% similar
@@ -1,7 +1,7 @@
11 package modes
22
33 import (
4- "github.com/patriceckhart/zot/internal/tui"
4+ "github.com/patriceckhart/zot/packages/tui"
55 )
66
77 type settingsDialog struct {
@@ -1,7 +1,7 @@
1 package modes1 package modes
2 2
3 import (3 import (
4- "github.com/patriceckhart/zot/internal/tui"4+ "github.com/patriceckhart/zot/packages/tui"
5 )5 )
6 6
7 type settingsDialog struct {7 type settingsDialog struct {
R internal/agent/modes/skills_dialog.go → packages/agent/modes/skills_dialog.go +2 -2 renamed, 98% similar
@@ -4,8 +4,8 @@ import (
44 "fmt"
55 "strings"
66
7- "github.com/patriceckhart/zot/internal/skills"
8- "github.com/patriceckhart/zot/internal/tui"
7+ "github.com/patriceckhart/zot/packages/agent/skills"
8+ "github.com/patriceckhart/zot/packages/tui"
99 )
1010
1111 // skillsDialog lists every discovered skill and lets the user view
@@ -4,8 +4,8 @@ import (
4 "fmt"4 "fmt"
5 "strings"5 "strings"
6 6
7- "github.com/patriceckhart/zot/internal/skills"7+ "github.com/patriceckhart/zot/packages/agent/skills"
8- "github.com/patriceckhart/zot/internal/tui"8+ "github.com/patriceckhart/zot/packages/tui"
9 )9 )
10 10
11 // skillsDialog lists every discovered skill and lets the user view11 // skillsDialog lists every discovered skill and lets the user view
R internal/agent/modes/slash_suggest.go → packages/agent/modes/slash_suggest.go +1 -1 renamed, 99% similar
@@ -6,7 +6,7 @@ import (
66
77 "github.com/mattn/go-runewidth"
88
9- "github.com/patriceckhart/zot/internal/tui"
9+ "github.com/patriceckhart/zot/packages/tui"
1010 )
1111
1212 // slashCommand is one entry in the autocomplete popup. Header rows
@@ -6,7 +6,7 @@ import (
6 6
7 "github.com/mattn/go-runewidth"7 "github.com/mattn/go-runewidth"
8 8
9- "github.com/patriceckhart/zot/internal/tui"9+ "github.com/patriceckhart/zot/packages/tui"
10 )10 )
11 11
12 // slashCommand is one entry in the autocomplete popup. Header rows12 // slashCommand is one entry in the autocomplete popup. Header rows
R internal/agent/modes/slash_suggest_test.go → packages/agent/modes/slash_suggest_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/spinner.go → packages/agent/modes/spinner.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/study_test.go → packages/agent/modes/study_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/swarm_dialog.go → packages/agent/modes/swarm_dialog.go +2 -2 renamed, 99% similar
@@ -6,8 +6,8 @@ import (
66 "strings"
77 "time"
88
9- "github.com/patriceckhart/zot/internal/swarm"
10- "github.com/patriceckhart/zot/internal/tui"
9+ "github.com/patriceckhart/zot/packages/agent/swarm"
10+ "github.com/patriceckhart/zot/packages/tui"
1111 )
1212
1313 // swarmDialog is the dashboard shown by /swarm (no argument) and
@@ -6,8 +6,8 @@ import (
6 "strings"6 "strings"
7 "time"7 "time"
8 8
9- "github.com/patriceckhart/zot/internal/swarm"9+ "github.com/patriceckhart/zot/packages/agent/swarm"
10- "github.com/patriceckhart/zot/internal/tui"10+ "github.com/patriceckhart/zot/packages/tui"
11 )11 )
12 12
13 // swarmDialog is the dashboard shown by /swarm (no argument) and13 // swarmDialog is the dashboard shown by /swarm (no argument) and
R internal/agent/modes/swarm_dialog_test.go → packages/agent/modes/swarm_dialog_test.go +3 -3 renamed, 99% similar
@@ -9,9 +9,9 @@ import (
99 "testing"
1010 "time"
1111
12- "github.com/patriceckhart/zot/internal/provider"
13- "github.com/patriceckhart/zot/internal/swarm"
14- "github.com/patriceckhart/zot/internal/tui"
12+ "github.com/patriceckhart/zot/packages/agent/swarm"
13+ "github.com/patriceckhart/zot/packages/provider"
14+ "github.com/patriceckhart/zot/packages/tui"
1515 )
1616
1717 // staticSnapshots returns a deterministic snapshot slice for the
@@ -9,9 +9,9 @@ import (
9 "testing"9 "testing"
10 "time"10 "time"
11 11
12- "github.com/patriceckhart/zot/internal/provider"12+ "github.com/patriceckhart/zot/packages/agent/swarm"
13- "github.com/patriceckhart/zot/internal/swarm"13+ "github.com/patriceckhart/zot/packages/provider"
14- "github.com/patriceckhart/zot/internal/tui"14+ "github.com/patriceckhart/zot/packages/tui"
15 )15 )
16 16
17 // staticSnapshots returns a deterministic snapshot slice for the17 // staticSnapshots returns a deterministic snapshot slice for the
R internal/agent/modes/swarm_slash.go → packages/agent/modes/swarm_slash.go +1 -1 renamed, 99% similar
@@ -5,7 +5,7 @@ import (
55 "fmt"
66 "strings"
77
8- "github.com/patriceckhart/zot/internal/swarm"
8+ "github.com/patriceckhart/zot/packages/agent/swarm"
99 )
1010
1111 // runSwarm dispatches /swarm subcommands. Layout:
@@ -5,7 +5,7 @@ import (
5 "fmt"5 "fmt"
6 "strings"6 "strings"
7 7
8- "github.com/patriceckhart/zot/internal/swarm"8+ "github.com/patriceckhart/zot/packages/agent/swarm"
9 )9 )
10 10
11 // runSwarm dispatches /swarm subcommands. Layout:11 // runSwarm dispatches /swarm subcommands. Layout:
R internal/agent/modes/swarm_slash_test.go → packages/agent/modes/swarm_slash_test.go +1 -1 renamed, 99% similar
@@ -5,7 +5,7 @@ import (
55 "testing"
66 "time"
77
8- "github.com/patriceckhart/zot/internal/swarm"
8+ "github.com/patriceckhart/zot/packages/agent/swarm"
99 )
1010
1111 // newInteractiveForSwarmTest builds the minimal Interactive scaffolding
@@ -5,7 +5,7 @@ import (
5 "testing"5 "testing"
6 "time"6 "time"
7 7
8- "github.com/patriceckhart/zot/internal/swarm"8+ "github.com/patriceckhart/zot/packages/agent/swarm"
9 )9 )
10 10
11 // newInteractiveForSwarmTest builds the minimal Interactive scaffolding11 // newInteractiveForSwarmTest builds the minimal Interactive scaffolding
R internal/agent/modes/telegram/api.go → packages/agent/modes/telegram/api.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/telegram/bot.go → packages/agent/modes/telegram/bot.go +2 -2 renamed, 99% similar
@@ -7,8 +7,8 @@ import (
77 "sync"
88 "time"
99
10- "github.com/patriceckhart/zot/internal/core"
11- "github.com/patriceckhart/zot/internal/provider"
10+ "github.com/patriceckhart/zot/packages/core"
11+ "github.com/patriceckhart/zot/packages/provider"
1212 )
1313
1414 // Bot owns the Telegram polling loop and dispatches inbound DMs to
@@ -7,8 +7,8 @@ import (
7 "sync"7 "sync"
8 "time"8 "time"
9 9
10- "github.com/patriceckhart/zot/internal/core"10+ "github.com/patriceckhart/zot/packages/core"
11- "github.com/patriceckhart/zot/internal/provider"11+ "github.com/patriceckhart/zot/packages/provider"
12 )12 )
13 13
14 // Bot owns the Telegram polling loop and dispatches inbound DMs to14 // Bot owns the Telegram polling loop and dispatches inbound DMs to
R internal/agent/modes/telegram/bridge.go → packages/agent/modes/telegram/bridge.go +1 -1 renamed, 99% similar
@@ -7,7 +7,7 @@ import (
77 "sync"
88 "time"
99
10- "github.com/patriceckhart/zot/internal/provider"
10+ "github.com/patriceckhart/zot/packages/provider"
1111 )
1212
1313 // Host is the small interface the Bridge calls back into the TUI
@@ -7,7 +7,7 @@ import (
7 "sync"7 "sync"
8 "time"8 "time"
9 9
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/provider"
11 )11 )
12 12
13 // Host is the small interface the Bridge calls back into the TUI13 // Host is the small interface the Bridge calls back into the TUI
R internal/agent/modes/telegram/commands.go → packages/agent/modes/telegram/commands.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/telegram/commands_test.go → packages/agent/modes/telegram/commands_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/telegram/config.go → packages/agent/modes/telegram/config.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/telegram/daemon.go → packages/agent/modes/telegram/daemon.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/telegram/fs.go → packages/agent/modes/telegram/fs.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/telegram/io.go → packages/agent/modes/telegram/io.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/modes/telegram/status.go → packages/agent/modes/telegram/status.go +1 -1 renamed, 98% similar
@@ -5,7 +5,7 @@ import (
55 "os"
66 "strings"
77
8- "github.com/patriceckhart/zot/internal/provider"
8+ "github.com/patriceckhart/zot/packages/provider"
99 )
1010
1111 // StatusSnapshot is the small cross-host state bundle rendered for
@@ -5,7 +5,7 @@ import (
5 "os"5 "os"
6 "strings"6 "strings"
7 7
8- "github.com/patriceckhart/zot/internal/provider"8+ "github.com/patriceckhart/zot/packages/provider"
9 )9 )
10 10
11 // StatusSnapshot is the small cross-host state bundle rendered for11 // StatusSnapshot is the small cross-host state bundle rendered for
R internal/agent/modes/telegram/status_test.go → packages/agent/modes/telegram/status_test.go +1 -1 renamed, 93% similar
@@ -4,7 +4,7 @@ import (
44 "strings"
55 "testing"
66
7- "github.com/patriceckhart/zot/internal/provider"
7+ "github.com/patriceckhart/zot/packages/provider"
88 )
99
1010 func TestFormatStatusIncludesModelUsageContextAndCWD(t *testing.T) {
@@ -4,7 +4,7 @@ import (
4 "strings"4 "strings"
5 "testing"5 "testing"
6 6
7- "github.com/patriceckhart/zot/internal/provider"7+ "github.com/patriceckhart/zot/packages/provider"
8 )8 )
9 9
10 func TestFormatStatusIncludesModelUsageContextAndCWD(t *testing.T) {10 func TestFormatStatusIncludesModelUsageContextAndCWD(t *testing.T) {
R internal/agent/modes/telegram_dialog.go → packages/agent/modes/telegram_dialog.go +1 -1 renamed, 98% similar
@@ -1,7 +1,7 @@
11 package modes
22
33 import (
4- "github.com/patriceckhart/zot/internal/tui"
4+ "github.com/patriceckhart/zot/packages/tui"
55 )
66
77 // telegramDialog is the picker shown when the user runs `/telegram`
@@ -1,7 +1,7 @@
1 package modes1 package modes
2 2
3 import (3 import (
4- "github.com/patriceckhart/zot/internal/tui"4+ "github.com/patriceckhart/zot/packages/tui"
5 )5 )
6 6
7 // telegramDialog is the picker shown when the user runs `/telegram`7 // telegramDialog is the picker shown when the user runs `/telegram`
R internal/agent/modes/update_banner.go → packages/agent/modes/update_banner.go +1 -1 renamed, 96% similar
@@ -3,7 +3,7 @@ package modes
33 import (
44 "fmt"
55
6- "github.com/patriceckhart/zot/internal/tui"
6+ "github.com/patriceckhart/zot/packages/tui"
77 )
88
99 // UpdateInfo mirrors agent.UpdateInfo without the import cycle. The
@@ -3,7 +3,7 @@ package modes
3 import (3 import (
4 "fmt"4 "fmt"
5 5
6- "github.com/patriceckhart/zot/internal/tui"6+ "github.com/patriceckhart/zot/packages/tui"
7 )7 )
8 8
9 // UpdateInfo mirrors agent.UpdateInfo without the import cycle. The9 // UpdateInfo mirrors agent.UpdateInfo without the import cycle. The
R internal/agent/modes/welcome.go → packages/agent/modes/welcome.go +1 -1 renamed, 94% similar
@@ -1,6 +1,6 @@
11 package modes
22
3-import "github.com/patriceckhart/zot/internal/tui"
3+import "github.com/patriceckhart/zot/packages/tui"
44
55 // welcomeBanner returns the intro text shown at the top of an empty chat.
66 // It uses the `zot` label color (same as the assistant) for consistency.
@@ -1,6 +1,6 @@
1 package modes1 package modes
2 2
3-import "github.com/patriceckhart/zot/internal/tui"3+import "github.com/patriceckhart/zot/packages/tui"
4 4
5 // welcomeBanner returns the intro text shown at the top of an empty chat.5 // welcomeBanner returns the intro text shown at the top of an empty chat.
6 // It uses the `zot` label color (same as the assistant) for consistency.6 // It uses the `zot` label color (same as the assistant) for consistency.
R internal/agent/rpc.go → packages/agent/rpc.go +5 -5 renamed, 97% similar
@@ -12,11 +12,11 @@ import (
1212 "sync"
1313 "time"
1414
15- "github.com/patriceckhart/zot/internal/agent/extensions"
16- "github.com/patriceckhart/zot/internal/agent/modes"
17- "github.com/patriceckhart/zot/internal/core"
18- "github.com/patriceckhart/zot/internal/extproto"
19- "github.com/patriceckhart/zot/internal/provider"
15+ "github.com/patriceckhart/zot/packages/agent/extensions"
16+ "github.com/patriceckhart/zot/packages/agent/extproto"
17+ "github.com/patriceckhart/zot/packages/agent/modes"
18+ "github.com/patriceckhart/zot/packages/core"
19+ "github.com/patriceckhart/zot/packages/provider"
2020 )
2121
2222 // runRPCMode implements the JSON-over-stdin/stdout RPC protocol.
@@ -12,11 +12,11 @@ import (
12 "sync"12 "sync"
13 "time"13 "time"
14 14
15- "github.com/patriceckhart/zot/internal/agent/extensions"15+ "github.com/patriceckhart/zot/packages/agent/extensions"
16- "github.com/patriceckhart/zot/internal/agent/modes"16+ "github.com/patriceckhart/zot/packages/agent/extproto"
17- "github.com/patriceckhart/zot/internal/core"17+ "github.com/patriceckhart/zot/packages/agent/modes"
18- "github.com/patriceckhart/zot/internal/extproto"18+ "github.com/patriceckhart/zot/packages/core"
19- "github.com/patriceckhart/zot/internal/provider"19+ "github.com/patriceckhart/zot/packages/provider"
20 )20 )
21 21
22 // runRPCMode implements the JSON-over-stdin/stdout RPC protocol.22 // runRPCMode implements the JSON-over-stdin/stdout RPC protocol.
R pkg/zotcore/zotcore.go → packages/agent/sdk/sdk.go +11 -11 renamed, 93% similar
@@ -1,11 +1,11 @@
1-// Package zotcore is the public Go SDK for embedding the zot agent
1+// Package sdk is the public Go SDK for embedding the zot agent
22 // runtime in third-party programs. It is the only stable, importable
33 // surface the project exposes; everything under internal/ is subject
44 // to change without notice.
55 //
66 // Lifecycle:
77 //
8-// rt, err := zotcore.New(zotcore.Config{Provider: "anthropic", Model: "claude-sonnet-4-5"})
8+// rt, err := sdk.New(sdk.Config{Provider: "anthropic", Model: "claude-sonnet-4-5"})
99 // if err != nil { ... }
1010 // defer rt.Close()
1111 //
@@ -21,7 +21,7 @@
2121 //
2222 // For a non-Go consumer, run `zot rpc` and speak the same JSON
2323 // schema over stdin/stdout. See docs/rpc.md.
24-package zotcore
24+package sdk
2525
2626 import (
2727 "context"
@@ -29,9 +29,9 @@ import (
2929 "fmt"
3030 "sync"
3131
32- "github.com/patriceckhart/zot/internal/agent"
33- "github.com/patriceckhart/zot/internal/core"
34- "github.com/patriceckhart/zot/internal/provider"
32+ "github.com/patriceckhart/zot/packages/agent"
33+ "github.com/patriceckhart/zot/packages/core"
34+ "github.com/patriceckhart/zot/packages/provider"
3535 )
3636
3737 // Config configures a Runtime. All fields are optional; sensible
@@ -209,7 +209,7 @@ func (r *Runtime) Prompt(ctx context.Context, text string, images []Image) (<-ch
209209 }
210210 if r.agent == nil {
211211 r.mu.Unlock()
212- return nil, fmt.Errorf("zotcore: no agent (login first via /login or set credentials)")
212+ return nil, fmt.Errorf("sdk: no agent (login first via /login or set credentials)")
213213 }
214214 subCtx, cancel := context.WithCancel(ctx)
215215 r.activeCancel = cancel
@@ -253,7 +253,7 @@ func (r *Runtime) Cancel() {
253253 // user message, freeing up context. Blocks until done.
254254 func (r *Runtime) Compact(ctx context.Context, customInstructions string) (CompactResult, error) {
255255 if r.agent == nil {
256- return CompactResult{}, fmt.Errorf("zotcore: no agent")
256+ return CompactResult{}, fmt.Errorf("sdk: no agent")
257257 }
258258 r.mu.Lock()
259259 if r.activeCancel != nil {
@@ -282,7 +282,7 @@ func (r *Runtime) SetModel(model string) error {
282282 r.mu.Lock()
283283 defer r.mu.Unlock()
284284 if r.agent == nil {
285- return fmt.Errorf("zotcore: no agent")
285+ return fmt.Errorf("sdk: no agent")
286286 }
287287 if _, err := provider.FindModel(r.provider, model); err != nil {
288288 return err
@@ -344,7 +344,7 @@ func (r *Runtime) ListModels() []ModelInfo {
344344
345345 // ErrBusy is returned when a Prompt or Compact is started while
346346 // another is in flight on the same Runtime.
347-var ErrBusy = errors.New("zotcore: runtime is busy")
347+var ErrBusy = errors.New("sdk: runtime is busy")
348348
349349 // ErrClosed is returned by methods on a Runtime after Close.
350-var ErrClosed = errors.New("zotcore: runtime is closed")
350+var ErrClosed = errors.New("sdk: runtime is closed")
@@ -1,11 +1,11 @@
1-// Package zotcore is the public Go SDK for embedding the zot agent1+// Package sdk is the public Go SDK for embedding the zot agent
2 // runtime in third-party programs. It is the only stable, importable2 // runtime in third-party programs. It is the only stable, importable
3 // surface the project exposes; everything under internal/ is subject3 // surface the project exposes; everything under internal/ is subject
4 // to change without notice.4 // to change without notice.
5 //5 //
6 // Lifecycle:6 // Lifecycle:
7 //7 //
8-// rt, err := zotcore.New(zotcore.Config{Provider: "anthropic", Model: "claude-sonnet-4-5"})8+// rt, err := sdk.New(sdk.Config{Provider: "anthropic", Model: "claude-sonnet-4-5"})
9 // if err != nil { ... }9 // if err != nil { ... }
10 // defer rt.Close()10 // defer rt.Close()
11 //11 //
@@ -21,7 +21,7 @@
21 //21 //
22 // For a non-Go consumer, run `zot rpc` and speak the same JSON22 // For a non-Go consumer, run `zot rpc` and speak the same JSON
23 // schema over stdin/stdout. See docs/rpc.md.23 // schema over stdin/stdout. See docs/rpc.md.
24-package zotcore24+package sdk
25 25
26 import (26 import (
27 "context"27 "context"
@@ -29,9 +29,9 @@ import (
29 "fmt"29 "fmt"
30 "sync"30 "sync"
31 31
32- "github.com/patriceckhart/zot/internal/agent"32+ "github.com/patriceckhart/zot/packages/agent"
33- "github.com/patriceckhart/zot/internal/core"33+ "github.com/patriceckhart/zot/packages/core"
34- "github.com/patriceckhart/zot/internal/provider"34+ "github.com/patriceckhart/zot/packages/provider"
35 )35 )
36 36
37 // Config configures a Runtime. All fields are optional; sensible37 // Config configures a Runtime. All fields are optional; sensible
@@ -209,7 +209,7 @@ func (r *Runtime) Prompt(ctx context.Context, text string, images []Image) (<-ch
209 }209 }
210 if r.agent == nil {210 if r.agent == nil {
211 r.mu.Unlock()211 r.mu.Unlock()
212- return nil, fmt.Errorf("zotcore: no agent (login first via /login or set credentials)")212+ return nil, fmt.Errorf("sdk: no agent (login first via /login or set credentials)")
213 }213 }
214 subCtx, cancel := context.WithCancel(ctx)214 subCtx, cancel := context.WithCancel(ctx)
215 r.activeCancel = cancel215 r.activeCancel = cancel
@@ -253,7 +253,7 @@ func (r *Runtime) Cancel() {
253 // user message, freeing up context. Blocks until done.253 // user message, freeing up context. Blocks until done.
254 func (r *Runtime) Compact(ctx context.Context, customInstructions string) (CompactResult, error) {254 func (r *Runtime) Compact(ctx context.Context, customInstructions string) (CompactResult, error) {
255 if r.agent == nil {255 if r.agent == nil {
256- return CompactResult{}, fmt.Errorf("zotcore: no agent")256+ return CompactResult{}, fmt.Errorf("sdk: no agent")
257 }257 }
258 r.mu.Lock()258 r.mu.Lock()
259 if r.activeCancel != nil {259 if r.activeCancel != nil {
@@ -282,7 +282,7 @@ func (r *Runtime) SetModel(model string) error {
282 r.mu.Lock()282 r.mu.Lock()
283 defer r.mu.Unlock()283 defer r.mu.Unlock()
284 if r.agent == nil {284 if r.agent == nil {
285- return fmt.Errorf("zotcore: no agent")285+ return fmt.Errorf("sdk: no agent")
286 }286 }
287 if _, err := provider.FindModel(r.provider, model); err != nil {287 if _, err := provider.FindModel(r.provider, model); err != nil {
288 return err288 return err
@@ -344,7 +344,7 @@ func (r *Runtime) ListModels() []ModelInfo {
344 344
345 // ErrBusy is returned when a Prompt or Compact is started while345 // ErrBusy is returned when a Prompt or Compact is started while
346 // another is in flight on the same Runtime.346 // another is in flight on the same Runtime.
347-var ErrBusy = errors.New("zotcore: runtime is busy")347+var ErrBusy = errors.New("sdk: runtime is busy")
348 348
349 // ErrClosed is returned by methods on a Runtime after Close.349 // ErrClosed is returned by methods on a Runtime after Close.
350-var ErrClosed = errors.New("zotcore: runtime is closed")350+var ErrClosed = errors.New("sdk: runtime is closed")
R pkg/zotcore/types.go → packages/agent/sdk/types.go +3 -3 renamed, 98% similar
@@ -1,10 +1,10 @@
1-package zotcore
1+package sdk
22
33 import (
44 "encoding/json"
55
6- "github.com/patriceckhart/zot/internal/core"
7- "github.com/patriceckhart/zot/internal/provider"
6+ "github.com/patriceckhart/zot/packages/core"
7+ "github.com/patriceckhart/zot/packages/provider"
88 )
99
1010 // Event is the unit emitted by Runtime.Prompt's channel. Type
@@ -1,10 +1,10 @@
1-package zotcore1+package sdk
2 2
3 import (3 import (
4 "encoding/json"4 "encoding/json"
5 5
6- "github.com/patriceckhart/zot/internal/core"6+ "github.com/patriceckhart/zot/packages/core"
7- "github.com/patriceckhart/zot/internal/provider"7+ "github.com/patriceckhart/zot/packages/provider"
8 )8 )
9 9
10 // Event is the unit emitted by Runtime.Prompt's channel. Type10 // Event is the unit emitted by Runtime.Prompt's channel. Type
R internal/agent/settings_store.go → packages/agent/settings_store.go +1 -1 renamed, 97% similar
@@ -1,6 +1,6 @@
11 package agent
22
3-import "github.com/patriceckhart/zot/internal/provider"
3+import "github.com/patriceckhart/zot/packages/provider"
44
55 type configSettingsStore struct{}
66
@@ -1,6 +1,6 @@
1 package agent1 package agent
2 2
3-import "github.com/patriceckhart/zot/internal/provider"3+import "github.com/patriceckhart/zot/packages/provider"
4 4
5 type configSettingsStore struct{}5 type configSettingsStore struct{}
6 6
R internal/skills/builtin.go → packages/agent/skills/builtin.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/skills/builtin/write-zot-extension/SKILL.md → packages/agent/skills/builtin/write-zot-extension/SKILL.md +13 -13 renamed, 94% similar
@@ -178,36 +178,36 @@ never stalls the agent.
178178
179179 ## Recommended layout per language
180180
181-### Go (use the built-in SDK at pkg/zotext)
181+### Go (use the built-in SDK at packages/agent/ext)
182182
183183 ```go
184184 package main
185185
186186 import (
187187 "encoding/json"
188- "github.com/patriceckhart/zot/pkg/zotext"
188+ "github.com/patriceckhart/zot/packages/agent/ext"
189189 )
190190
191191 func main() {
192- ext := zotext.New("weather", "1.0.0")
192+ e := ext.New("weather", "1.0.0")
193193
194- ext.Command("weather", "current weather for a city",
195- func(args string) zotext.Response {
196- return zotext.Prompt("Tell me the weather for " + args)
194+ e.Command("weather", "current weather for a city",
195+ func(args string) ext.Response {
196+ return ext.Prompt("Tell me the weather for " + args)
197197 })
198198
199- ext.Tool("weather", "Get current weather for a city.",
199+ e.Tool("weather", "Get current weather for a city.",
200200 json.RawMessage(`{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}`),
201- func(args json.RawMessage) zotext.ToolResult {
201+ func(args json.RawMessage) ext.ToolResult {
202202 var in struct{ City string `json:"city"` }
203203 if err := json.Unmarshal(args, &in); err != nil {
204- return zotext.TextErrorResult("invalid args")
204+ return ext.TextErrorResult("invalid args")
205205 }
206- return zotext.TextResult(in.City + ": sunny, 21°C (fake)")
206+ return ext.TextResult(in.City + ": sunny, 21°C (fake)")
207207 })
208208
209- if err := ext.Run(); err != nil {
210- ext.Logf("fatal: %v", err)
209+ if err := e.Run(); err != nil {
210+ e.Logf("fatal: %v", err)
211211 }
212212 }
213213 ```
@@ -338,7 +338,7 @@ logged to `ext-<name>.log`.
338338 - "I want a slash command that triggers a prompt" → `command` only
339339 - "I want the model to be able to do X" → `tool`
340340 - "I want to gate / log every bash command" → `event` + `intercept`
341-3. Pick a language. Default to **Go via pkg/zotext** for new
341+3. Pick a language. Default to **Go via packages/agent/ext** for new
342342 extensions if the user has Go installed; **TypeScript via tsx**
343343 if they prefer JS-flavored ergonomics; **Python** for one-off
344344 scripts.
@@ -178,36 +178,36 @@ never stalls the agent.
178 178
179 ## Recommended layout per language179 ## Recommended layout per language
180 180
181-### Go (use the built-in SDK at pkg/zotext)181+### Go (use the built-in SDK at packages/agent/ext)
182 182
183 ```go183 ```go
184 package main184 package main
185 185
186 import (186 import (
187 "encoding/json"187 "encoding/json"
188- "github.com/patriceckhart/zot/pkg/zotext"188+ "github.com/patriceckhart/zot/packages/agent/ext"
189 )189 )
190 190
191 func main() {191 func main() {
192- ext := zotext.New("weather", "1.0.0")192+ e := ext.New("weather", "1.0.0")
193 193
194- ext.Command("weather", "current weather for a city",194+ e.Command("weather", "current weather for a city",
195- func(args string) zotext.Response {195+ func(args string) ext.Response {
196- return zotext.Prompt("Tell me the weather for " + args)196+ return ext.Prompt("Tell me the weather for " + args)
197 })197 })
198 198
199- ext.Tool("weather", "Get current weather for a city.",199+ e.Tool("weather", "Get current weather for a city.",
200 json.RawMessage(`{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}`),200 json.RawMessage(`{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}`),
201- func(args json.RawMessage) zotext.ToolResult {201+ func(args json.RawMessage) ext.ToolResult {
202 var in struct{ City string `json:"city"` }202 var in struct{ City string `json:"city"` }
203 if err := json.Unmarshal(args, &in); err != nil {203 if err := json.Unmarshal(args, &in); err != nil {
204- return zotext.TextErrorResult("invalid args")204+ return ext.TextErrorResult("invalid args")
205 }205 }
206- return zotext.TextResult(in.City + ": sunny, 21°C (fake)")206+ return ext.TextResult(in.City + ": sunny, 21°C (fake)")
207 })207 })
208 208
209- if err := ext.Run(); err != nil {209+ if err := e.Run(); err != nil {
210- ext.Logf("fatal: %v", err)210+ e.Logf("fatal: %v", err)
211 }211 }
212 }212 }
213 ```213 ```
@@ -338,7 +338,7 @@ logged to `ext-<name>.log`.
338 - "I want a slash command that triggers a prompt" → `command` only338 - "I want a slash command that triggers a prompt" → `command` only
339 - "I want the model to be able to do X" → `tool`339 - "I want the model to be able to do X" → `tool`
340 - "I want to gate / log every bash command" → `event` + `intercept`340 - "I want to gate / log every bash command" → `event` + `intercept`
341-3. Pick a language. Default to **Go via pkg/zotext** for new341+3. Pick a language. Default to **Go via packages/agent/ext** for new
342 extensions if the user has Go installed; **TypeScript via tsx**342 extensions if the user has Go installed; **TypeScript via tsx**
343 if they prefer JS-flavored ergonomics; **Python** for one-off343 if they prefer JS-flavored ergonomics; **Python** for one-off
344 scripts.344 scripts.
R internal/skills/skills.go → packages/agent/skills/skills.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/skills/skills_test.go → packages/agent/skills/skills_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/skills/tool.go → packages/agent/skills/tool.go +2 -2 renamed, 96% similar
@@ -6,8 +6,8 @@ import (
66 "fmt"
77 "sync"
88
9- "github.com/patriceckhart/zot/internal/core"
10- "github.com/patriceckhart/zot/internal/provider"
9+ "github.com/patriceckhart/zot/packages/core"
10+ "github.com/patriceckhart/zot/packages/provider"
1111 )
1212
1313 // Tool implements core.Tool, exposing a `skill` tool the LLM can call
@@ -6,8 +6,8 @@ import (
6 "fmt"6 "fmt"
7 "sync"7 "sync"
8 8
9- "github.com/patriceckhart/zot/internal/core"9+ "github.com/patriceckhart/zot/packages/core"
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/provider"
11 )11 )
12 12
13 // Tool implements core.Tool, exposing a `skill` tool the LLM can call13 // Tool implements core.Tool, exposing a `skill` tool the LLM can call
R internal/swarm/agent.go → packages/agent/swarm/agent.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/event.go → packages/agent/swarm/event.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/event_test.go → packages/agent/swarm/event_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/inbox.go → packages/agent/swarm/inbox.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/inbox_test.go → packages/agent/swarm/inbox_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/persist.go → packages/agent/swarm/persist.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/persist_test.go → packages/agent/swarm/persist_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/runner.go → packages/agent/swarm/runner.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/runner_e2e_test.go → packages/agent/swarm/runner_e2e_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/runner_test.go → packages/agent/swarm/runner_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/socketpath.go → packages/agent/swarm/socketpath.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/swarm.go → packages/agent/swarm/swarm.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/swarm_test.go → packages/agent/swarm/swarm_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/swarm/testdata/cmd/stubchild/main.go → packages/agent/swarm/testdata/cmd/stubchild/main.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/swarm_agent.go → packages/agent/swarm_agent.go +6 -6 renamed, 95% similar
@@ -9,10 +9,10 @@ import (
99 "sync"
1010 "time"
1111
12- "github.com/patriceckhart/zot/internal/agent/modes"
13- "github.com/patriceckhart/zot/internal/core"
14- "github.com/patriceckhart/zot/internal/provider"
15- "github.com/patriceckhart/zot/internal/swarm"
12+ "github.com/patriceckhart/zot/packages/agent/modes"
13+ "github.com/patriceckhart/zot/packages/agent/swarm"
14+ "github.com/patriceckhart/zot/packages/core"
15+ "github.com/patriceckhart/zot/packages/provider"
1616 )
1717
1818 // runSwarmAgentMode is the daemon-mode entry point used by every
@@ -28,9 +28,9 @@ import (
2828 // process can /swarm open this agent and replay its full history
2929 // even after the parent that spawned us is long gone.
3030 //
31-// The runner in internal/swarm/runner.go is the only caller in
31+// The runner in packages/agent/swarm/runner.go is the only caller in
3232 // production; tests use the stubchild binary under
33-// internal/swarm/testdata/cmd/stubchild instead of the real model
33+// packages/agent/swarm/testdata/cmd/stubchild instead of the real model
3434 // loop.
3535 func runSwarmAgentMode(ctx context.Context, args Args, version string) error {
3636 if args.SwarmAgent == "" {
@@ -9,10 +9,10 @@ import (
9 "sync"9 "sync"
10 "time"10 "time"
11 11
12- "github.com/patriceckhart/zot/internal/agent/modes"12+ "github.com/patriceckhart/zot/packages/agent/modes"
13- "github.com/patriceckhart/zot/internal/core"13+ "github.com/patriceckhart/zot/packages/agent/swarm"
14- "github.com/patriceckhart/zot/internal/provider"14+ "github.com/patriceckhart/zot/packages/core"
15- "github.com/patriceckhart/zot/internal/swarm"15+ "github.com/patriceckhart/zot/packages/provider"
16 )16 )
17 17
18 // runSwarmAgentMode is the daemon-mode entry point used by every18 // runSwarmAgentMode is the daemon-mode entry point used by every
@@ -28,9 +28,9 @@ import (
28 // process can /swarm open this agent and replay its full history28 // process can /swarm open this agent and replay its full history
29 // even after the parent that spawned us is long gone.29 // even after the parent that spawned us is long gone.
30 //30 //
31-// The runner in internal/swarm/runner.go is the only caller in31+// The runner in packages/agent/swarm/runner.go is the only caller in
32 // production; tests use the stubchild binary under32 // production; tests use the stubchild binary under
33-// internal/swarm/testdata/cmd/stubchild instead of the real model33+// packages/agent/swarm/testdata/cmd/stubchild instead of the real model
34 // loop.34 // loop.
35 func runSwarmAgentMode(ctx context.Context, args Args, version string) error {35 func runSwarmAgentMode(ctx context.Context, args Args, version string) error {
36 if args.SwarmAgent == "" {36 if args.SwarmAgent == "" {
R internal/agent/swarm_agent_test.go → packages/agent/swarm_agent_test.go +1 -1 renamed, 98% similar
@@ -8,7 +8,7 @@ import (
88 "path/filepath"
99 "testing"
1010
11- "github.com/patriceckhart/zot/internal/swarm"
11+ "github.com/patriceckhart/zot/packages/agent/swarm"
1212 )
1313
1414 // TestSwarmEmitterMirrorDormantUntilStdoutBreaks regresses the
@@ -8,7 +8,7 @@ import (
8 "path/filepath"8 "path/filepath"
9 "testing"9 "testing"
10 10
11- "github.com/patriceckhart/zot/internal/swarm"11+ "github.com/patriceckhart/zot/packages/agent/swarm"
12 )12 )
13 13
14 // TestSwarmEmitterMirrorDormantUntilStdoutBreaks regresses the14 // TestSwarmEmitterMirrorDormantUntilStdoutBreaks regresses the
R internal/agent/systemprompt.go → packages/agent/systemprompt.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/tools/bash.go → packages/agent/tools/bash.go +2 -2 renamed, 98% similar
@@ -15,8 +15,8 @@ import (
1515 "strings"
1616 "time"
1717
18- "github.com/patriceckhart/zot/internal/core"
19- "github.com/patriceckhart/zot/internal/provider"
18+ "github.com/patriceckhart/zot/packages/core"
19+ "github.com/patriceckhart/zot/packages/provider"
2020 )
2121
2222 const (
@@ -15,8 +15,8 @@ import (
15 "strings"15 "strings"
16 "time"16 "time"
17 17
18- "github.com/patriceckhart/zot/internal/core"18+ "github.com/patriceckhart/zot/packages/core"
19- "github.com/patriceckhart/zot/internal/provider"19+ "github.com/patriceckhart/zot/packages/provider"
20 )20 )
21 21
22 const (22 const (
R internal/agent/tools/bash_unix.go → packages/agent/tools/bash_unix.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/tools/bash_windows.go → packages/agent/tools/bash_windows.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/tools/edit.go → packages/agent/tools/edit.go +2 -2 renamed, 98% similar
@@ -8,8 +8,8 @@ import (
88 "os"
99 "strings"
1010
11- "github.com/patriceckhart/zot/internal/core"
12- "github.com/patriceckhart/zot/internal/provider"
11+ "github.com/patriceckhart/zot/packages/core"
12+ "github.com/patriceckhart/zot/packages/provider"
1313 )
1414
1515 // EditTool applies one or more exact-match replacements to a file.
@@ -8,8 +8,8 @@ import (
8 "os"8 "os"
9 "strings"9 "strings"
10 10
11- "github.com/patriceckhart/zot/internal/core"11+ "github.com/patriceckhart/zot/packages/core"
12- "github.com/patriceckhart/zot/internal/provider"12+ "github.com/patriceckhart/zot/packages/provider"
13 )13 )
14 14
15 // EditTool applies one or more exact-match replacements to a file.15 // EditTool applies one or more exact-match replacements to a file.
R internal/agent/tools/read.go → packages/agent/tools/read.go +2 -2 renamed, 97% similar
@@ -10,8 +10,8 @@ import (
1010 "path/filepath"
1111 "strings"
1212
13- "github.com/patriceckhart/zot/internal/core"
14- "github.com/patriceckhart/zot/internal/provider"
13+ "github.com/patriceckhart/zot/packages/core"
14+ "github.com/patriceckhart/zot/packages/provider"
1515 )
1616
1717 const (
@@ -10,8 +10,8 @@ import (
10 "path/filepath"10 "path/filepath"
11 "strings"11 "strings"
12 12
13- "github.com/patriceckhart/zot/internal/core"13+ "github.com/patriceckhart/zot/packages/core"
14- "github.com/patriceckhart/zot/internal/provider"14+ "github.com/patriceckhart/zot/packages/provider"
15 )15 )
16 16
17 const (17 const (
R internal/agent/tools/sandbox.go → packages/agent/tools/sandbox.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/tools/sandbox_test.go → packages/agent/tools/sandbox_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/tools/swarm_spawn.go → packages/agent/tools/swarm_spawn.go +3 -3 renamed, 96% similar
@@ -6,9 +6,9 @@ import (
66 "fmt"
77 "strings"
88
9- "github.com/patriceckhart/zot/internal/core"
10- "github.com/patriceckhart/zot/internal/provider"
11- "github.com/patriceckhart/zot/internal/swarm"
9+ "github.com/patriceckhart/zot/packages/agent/swarm"
10+ "github.com/patriceckhart/zot/packages/core"
11+ "github.com/patriceckhart/zot/packages/provider"
1212 )
1313
1414 // SwarmSpawnTool lets the main agent fork a background sub-agent
@@ -6,9 +6,9 @@ import (
6 "fmt"6 "fmt"
7 "strings"7 "strings"
8 8
9- "github.com/patriceckhart/zot/internal/core"9+ "github.com/patriceckhart/zot/packages/agent/swarm"
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/core"
11- "github.com/patriceckhart/zot/internal/swarm"11+ "github.com/patriceckhart/zot/packages/provider"
12 )12 )
13 13
14 // SwarmSpawnTool lets the main agent fork a background sub-agent14 // SwarmSpawnTool lets the main agent fork a background sub-agent
R internal/agent/tools/telegram_send.go → packages/agent/tools/telegram_send.go +2 -2 renamed, 98% similar
@@ -6,8 +6,8 @@ import (
66 "fmt"
77 "os"
88
9- "github.com/patriceckhart/zot/internal/core"
10- "github.com/patriceckhart/zot/internal/provider"
9+ "github.com/patriceckhart/zot/packages/core"
10+ "github.com/patriceckhart/zot/packages/provider"
1111 )
1212
1313 // TelegramSender is the small affordance the telegram-send tools call
@@ -6,8 +6,8 @@ import (
6 "fmt"6 "fmt"
7 "os"7 "os"
8 8
9- "github.com/patriceckhart/zot/internal/core"9+ "github.com/patriceckhart/zot/packages/core"
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/provider"
11 )11 )
12 12
13 // TelegramSender is the small affordance the telegram-send tools call13 // TelegramSender is the small affordance the telegram-send tools call
R internal/agent/tools/tools_test.go → packages/agent/tools/tools_test.go +1 -1 renamed, 98% similar
@@ -9,7 +9,7 @@ import (
99 "strings"
1010 "testing"
1111
12- "github.com/patriceckhart/zot/internal/provider"
12+ "github.com/patriceckhart/zot/packages/provider"
1313 )
1414
1515 func mustJSON(t *testing.T, v any) json.RawMessage {
@@ -9,7 +9,7 @@ import (
9 "strings"9 "strings"
10 "testing"10 "testing"
11 11
12- "github.com/patriceckhart/zot/internal/provider"12+ "github.com/patriceckhart/zot/packages/provider"
13 )13 )
14 14
15 func mustJSON(t *testing.T, v any) json.RawMessage {15 func mustJSON(t *testing.T, v any) json.RawMessage {
R internal/agent/tools/write.go → packages/agent/tools/write.go +2 -2 renamed, 95% similar
@@ -8,8 +8,8 @@ import (
88 "path/filepath"
99 "strings"
1010
11- "github.com/patriceckhart/zot/internal/core"
12- "github.com/patriceckhart/zot/internal/provider"
11+ "github.com/patriceckhart/zot/packages/core"
12+ "github.com/patriceckhart/zot/packages/provider"
1313 )
1414
1515 // WriteTool writes content to a file, creating parent directories.
@@ -8,8 +8,8 @@ import (
8 "path/filepath"8 "path/filepath"
9 "strings"9 "strings"
10 10
11- "github.com/patriceckhart/zot/internal/core"11+ "github.com/patriceckhart/zot/packages/core"
12- "github.com/patriceckhart/zot/internal/provider"12+ "github.com/patriceckhart/zot/packages/provider"
13 )13 )
14 14
15 // WriteTool writes content to a file, creating parent directories.15 // WriteTool writes content to a file, creating parent directories.
R internal/agent/update.go → packages/agent/update.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/agent/updatecmd.go → packages/agent/updatecmd.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/core/agent.go → packages/core/agent.go +1 -1 renamed, 99% similar
@@ -9,7 +9,7 @@ import (
99 "sync"
1010 "time"
1111
12- "github.com/patriceckhart/zot/internal/provider"
12+ "github.com/patriceckhart/zot/packages/provider"
1313 )
1414
1515 // Agent is a stateful conversation bound to a provider client, a model,
@@ -9,7 +9,7 @@ import (
9 "sync"9 "sync"
10 "time"10 "time"
11 11
12- "github.com/patriceckhart/zot/internal/provider"12+ "github.com/patriceckhart/zot/packages/provider"
13 )13 )
14 14
15 // Agent is a stateful conversation bound to a provider client, a model,15 // Agent is a stateful conversation bound to a provider client, a model,
R internal/core/compact.go → packages/core/compact.go +1 -1 renamed, 99% similar
@@ -7,7 +7,7 @@ import (
77 "strings"
88 "time"
99
10- "github.com/patriceckhart/zot/internal/provider"
10+ "github.com/patriceckhart/zot/packages/provider"
1111 )
1212
1313 // Compact summarizes the agent's transcript via the LLM and replaces
@@ -7,7 +7,7 @@ import (
7 "strings"7 "strings"
8 "time"8 "time"
9 9
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/provider"
11 )11 )
12 12
13 // Compact summarizes the agent's transcript via the LLM and replaces13 // Compact summarizes the agent's transcript via the LLM and replaces
R internal/core/confirm.go → packages/core/confirm.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/core/confirm_test.go → packages/core/confirm_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/core/core_test.go → packages/core/core_test.go +1 -1 renamed, 98% similar
@@ -5,7 +5,7 @@ import (
55 "testing"
66 "time"
77
8- "github.com/patriceckhart/zot/internal/provider"
8+ "github.com/patriceckhart/zot/packages/provider"
99 )
1010
1111 func TestSessionRoundTrip(t *testing.T) {
@@ -5,7 +5,7 @@ import (
5 "testing"5 "testing"
6 "time"6 "time"
7 7
8- "github.com/patriceckhart/zot/internal/provider"8+ "github.com/patriceckhart/zot/packages/provider"
9 )9 )
10 10
11 func TestSessionRoundTrip(t *testing.T) {11 func TestSessionRoundTrip(t *testing.T) {
R internal/core/cost.go → packages/core/cost.go +1 -1 renamed, 92% similar
@@ -1,6 +1,6 @@
11 package core
22
3-import "github.com/patriceckhart/zot/internal/provider"
3+import "github.com/patriceckhart/zot/packages/provider"
44
55 // CostTracker accumulates usage across turns in a session.
66 //
@@ -1,6 +1,6 @@
1 package core1 package core
2 2
3-import "github.com/patriceckhart/zot/internal/provider"3+import "github.com/patriceckhart/zot/packages/provider"
4 4
5 // CostTracker accumulates usage across turns in a session.5 // CostTracker accumulates usage across turns in a session.
6 //6 //
R internal/core/events.go → packages/core/events.go +1 -1 renamed, 98% similar
@@ -3,7 +3,7 @@ package core
33 import (
44 "encoding/json"
55
6- "github.com/patriceckhart/zot/internal/provider"
6+ "github.com/patriceckhart/zot/packages/provider"
77 )
88
99 // AgentEvent is the superset of events emitted by an Agent run.
@@ -3,7 +3,7 @@ package core
3 import (3 import (
4 "encoding/json"4 "encoding/json"
5 5
6- "github.com/patriceckhart/zot/internal/provider"6+ "github.com/patriceckhart/zot/packages/provider"
7 )7 )
8 8
9 // AgentEvent is the superset of events emitted by an Agent run.9 // AgentEvent is the superset of events emitted by an Agent run.
R internal/core/intercept_test.go → packages/core/intercept_test.go +1 -1 renamed, 98% similar
@@ -5,7 +5,7 @@ import (
55 "encoding/json"
66 "testing"
77
8- "github.com/patriceckhart/zot/internal/provider"
8+ "github.com/patriceckhart/zot/packages/provider"
99 )
1010
1111 // recordingTool captures the args it was invoked with so the test
@@ -5,7 +5,7 @@ import (
5 "encoding/json"5 "encoding/json"
6 "testing"6 "testing"
7 7
8- "github.com/patriceckhart/zot/internal/provider"8+ "github.com/patriceckhart/zot/packages/provider"
9 )9 )
10 10
11 // recordingTool captures the args it was invoked with so the test11 // recordingTool captures the args it was invoked with so the test
R internal/core/queue_test.go → packages/core/queue_test.go +1 -1 renamed, 98% similar
@@ -7,7 +7,7 @@ import (
77 "sync/atomic"
88 "testing"
99
10- "github.com/patriceckhart/zot/internal/provider"
10+ "github.com/patriceckhart/zot/packages/provider"
1111 )
1212
1313 type queueFakeClient struct {
@@ -7,7 +7,7 @@ import (
7 "sync/atomic"7 "sync/atomic"
8 "testing"8 "testing"
9 9
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/provider"
11 )11 )
12 12
13 type queueFakeClient struct {13 type queueFakeClient struct {
R internal/core/session.go → packages/core/session.go +1 -1 renamed, 99% similar
@@ -15,7 +15,7 @@ import (
1515 "time"
1616
1717 "github.com/google/uuid"
18- "github.com/patriceckhart/zot/internal/provider"
18+ "github.com/patriceckhart/zot/packages/provider"
1919 )
2020
2121 // Session is a JSONL-backed conversation transcript tied to a cwd.
@@ -15,7 +15,7 @@ import (
15 "time"15 "time"
16 16
17 "github.com/google/uuid"17 "github.com/google/uuid"
18- "github.com/patriceckhart/zot/internal/provider"18+ "github.com/patriceckhart/zot/packages/provider"
19 )19 )
20 20
21 // Session is a JSONL-backed conversation transcript tied to a cwd.21 // Session is a JSONL-backed conversation transcript tied to a cwd.
R internal/core/session_portable.go → packages/core/session_portable.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/core/session_portable_test.go → packages/core/session_portable_test.go +1 -1 renamed, 99% similar
@@ -7,7 +7,7 @@ import (
77 "strings"
88 "testing"
99
10- "github.com/patriceckhart/zot/internal/provider"
10+ "github.com/patriceckhart/zot/packages/provider"
1111 )
1212
1313 // TestSessionExportImportRoundTrip writes a few messages to a live
@@ -7,7 +7,7 @@ import (
7 "strings"7 "strings"
8 "testing"8 "testing"
9 9
10- "github.com/patriceckhart/zot/internal/provider"10+ "github.com/patriceckhart/zot/packages/provider"
11 )11 )
12 12
13 // TestSessionExportImportRoundTrip writes a few messages to a live13 // TestSessionExportImportRoundTrip writes a few messages to a live
R internal/core/session_repair_test.go → packages/core/session_repair_test.go +1 -1 renamed, 98% similar
@@ -3,7 +3,7 @@ package core
33 import (
44 "testing"
55
6- "github.com/patriceckhart/zot/internal/provider"
6+ "github.com/patriceckhart/zot/packages/provider"
77 )
88
99 // TestRepairToolUseResultPairsAppendsStub covers the most common
@@ -3,7 +3,7 @@ package core
3 import (3 import (
4 "testing"4 "testing"
5 5
6- "github.com/patriceckhart/zot/internal/provider"6+ "github.com/patriceckhart/zot/packages/provider"
7 )7 )
8 8
9 // TestRepairToolUseResultPairsAppendsStub covers the most common9 // TestRepairToolUseResultPairsAppendsStub covers the most common
R internal/core/tool.go → packages/core/tool.go +1 -1 renamed, 97% similar
@@ -9,7 +9,7 @@ import (
99 "fmt"
1010 "sort"
1111
12- "github.com/patriceckhart/zot/internal/provider"
12+ "github.com/patriceckhart/zot/packages/provider"
1313 )
1414
1515 // Tool is a capability the agent can invoke.
@@ -9,7 +9,7 @@ import (
9 "fmt"9 "fmt"
10 "sort"10 "sort"
11 11
12- "github.com/patriceckhart/zot/internal/provider"12+ "github.com/patriceckhart/zot/packages/provider"
13 )13 )
14 14
15 // Tool is a capability the agent can invoke.15 // Tool is a capability the agent can invoke.
R internal/provider/amazon_bedrock.go → packages/provider/amazon_bedrock.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/amazon_bedrock_test.go → packages/provider/amazon_bedrock_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/anthropic.go → packages/provider/anthropic.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/anthropic_image.go → packages/provider/anthropic_image.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/anthropic_image_test.go → packages/provider/anthropic_image_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/assets/assets.go → packages/provider/auth/assets/assets.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/assets/zot-logo.png → packages/provider/auth/assets/zot-logo.png +0 -0 binary file: no text diff · renamed, 100% similar

binary file: no text diff · renamed, 100% similar

R internal/auth/auth_test.go → packages/provider/auth/auth_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/auth/callback.go → packages/provider/auth/callback.go +1 -1 renamed, 99% similar
@@ -9,7 +9,7 @@ import (
99 "sync"
1010 "time"
1111
12- "github.com/patriceckhart/zot/internal/assets"
12+ "github.com/patriceckhart/zot/packages/provider/auth/assets"
1313 )
1414
1515 // CallbackResult is what an OAuth callback server returns once the
@@ -9,7 +9,7 @@ import (
9 "sync"9 "sync"
10 "time"10 "time"
11 11
12- "github.com/patriceckhart/zot/internal/assets"12+ "github.com/patriceckhart/zot/packages/provider/auth/assets"
13 )13 )
14 14
15 // CallbackResult is what an OAuth callback server returns once the15 // CallbackResult is what an OAuth callback server returns once the
R internal/auth/github_copilot.go → packages/provider/auth/github_copilot.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/auth/kimi.go → packages/provider/auth/kimi.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/auth/manager.go → packages/provider/auth/manager.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/auth/oauth.go → packages/provider/auth/oauth.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/auth/probe.go → packages/provider/auth/probe.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/auth/server.go → packages/provider/auth/server.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/auth/store.go → packages/provider/auth/store.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/auth/store_additional_test.go → packages/provider/auth/store_additional_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/azure_openai.go → packages/provider/azure_openai.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/cache.go → packages/provider/cache.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/catalog_builtin.go → packages/provider/catalog_builtin.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/discover.go → packages/provider/discover.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/extra_models.go → packages/provider/extra_models.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/extra_providers.go → packages/provider/extra_providers.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/gemini.go → packages/provider/gemini.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/gemini_test.go → packages/provider/gemini_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/github_copilot.go → packages/provider/github_copilot.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/google_vertex.go → packages/provider/google_vertex.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/google_vertex_test.go → packages/provider/google_vertex_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/labels.go → packages/provider/labels.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/merge.go → packages/provider/merge.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/models.go → packages/provider/models.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/openai.go → packages/provider/openai.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/openai_codex.go → packages/provider/openai_codex.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/openai_responses.go → packages/provider/openai_responses.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/provider.go → packages/provider/provider.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/provider_test.go → packages/provider/provider_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/reasoning.go → packages/provider/reasoning.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/reasoning_test.go → packages/provider/reasoning_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/refreshing.go → packages/provider/refreshing.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/retry.go → packages/provider/retry.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/retry_test.go → packages/provider/retry_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/sse.go → packages/provider/sse.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/provider/usermodels.go → packages/provider/usermodels.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/crlf_test.go → packages/tui/crlf_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/detect_bg.go → packages/tui/detect_bg.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/editor.go → packages/tui/editor.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/editor_ansi_prompt_test.go → packages/tui/editor_ansi_prompt_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/editor_vertical_test.go → packages/tui/editor_vertical_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/highlight.go → packages/tui/highlight.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/image.go → packages/tui/image.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/image_test.go → packages/tui/image_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/input.go → packages/tui/input.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/input_test.go → packages/tui/input_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/markdown.go → packages/tui/markdown.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/markdown_test.go → packages/tui/markdown_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/partialjson.go → packages/tui/partialjson.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/partialjson_test.go → packages/tui/partialjson_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/paste_collapse_test.go → packages/tui/paste_collapse_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/quote_paste_test.go → packages/tui/quote_paste_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/render.go → packages/tui/render.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/render_test.go → packages/tui/render_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/resize_unix.go → packages/tui/resize_unix.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/resize_windows.go → packages/tui/resize_windows.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/statusbar_test.go → packages/tui/statusbar_test.go +1 -1 renamed, 99% similar
@@ -4,7 +4,7 @@ import (
44 "strings"
55 "testing"
66
7- "github.com/patriceckhart/zot/internal/provider"
7+ "github.com/patriceckhart/zot/packages/provider"
88 )
99
1010 // TestStatusBarAlwaysTwoLines verifies the status bar always emits
@@ -4,7 +4,7 @@ import (
4 "strings"4 "strings"
5 "testing"5 "testing"
6 6
7- "github.com/patriceckhart/zot/internal/provider"7+ "github.com/patriceckhart/zot/packages/provider"
8 )8 )
9 9
10 // TestStatusBarAlwaysTwoLines verifies the status bar always emits10 // TestStatusBarAlwaysTwoLines verifies the status bar always emits
R internal/tui/terminal.go → packages/tui/terminal.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/theme.go → packages/tui/theme.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/tui/view.go → packages/tui/view.go +1 -1 renamed, 99% similar
@@ -10,7 +10,7 @@ import (
1010 "unicode/utf8"
1111
1212 "github.com/mattn/go-runewidth"
13- "github.com/patriceckhart/zot/internal/provider"
13+ "github.com/patriceckhart/zot/packages/provider"
1414 )
1515
1616 // expandTabs replaces tab characters with 4 spaces so code from
@@ -10,7 +10,7 @@ import (
10 "unicode/utf8"10 "unicode/utf8"
11 11
12 "github.com/mattn/go-runewidth"12 "github.com/mattn/go-runewidth"
13- "github.com/patriceckhart/zot/internal/provider"13+ "github.com/patriceckhart/zot/packages/provider"
14 )14 )
15 15
16 // expandTabs replaces tab characters with 4 spaces so code from16 // expandTabs replaces tab characters with 4 spaces so code from
R internal/tui/wrap_test.go → packages/tui/wrap_test.go +0 -0 renamed, 100% similar

renamed, 100% similar

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close