octto 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # octto
2
+
3
+ An interactive browser UI for AI brainstorming. Stop typing in terminals. Start clicking in browsers.
4
+
5
+ ## The Problem
6
+
7
+ AI brainstorming today happens in the terminal:
8
+ ```
9
+ Agent: What framework do you want?
10
+ You: *types* React
11
+ Agent: *thinks for 10 seconds*
12
+ Agent: What about styling?
13
+ You: *types* Tailwind
14
+ Agent: *thinks*
15
+ ...repeat for 10 minutes...
16
+ ```
17
+
18
+ Slow. Tedious. One question at a time.
19
+
20
+ ## The Solution
21
+
22
+ **A browser window with visual questions you can answer in seconds.**
23
+
24
+ When you describe your idea, octto opens an interactive UI:
25
+
26
+ - Click options instead of typing
27
+ - See all questions at once
28
+ - Answer in any order
29
+ - Watch follow-ups appear instantly
30
+ - Review the final plan visually
31
+
32
+ **10 minutes of terminal typing → 2 minutes of clicking.**
33
+
34
+ ## Quick Start
35
+
36
+ Add to `~/.config/opencode/opencode.json`:
37
+
38
+ ```json
39
+ { "plugin": ["/path/to/octto"] }
40
+ ```
41
+
42
+ Select the **octto** agent:
43
+
44
+ ```
45
+ I want to add a caching layer to the API
46
+ ```
47
+
48
+ A browser window opens. Click your answers. Done.
49
+
50
+ ## The Interactive UI
51
+
52
+ ### Rich Question Types
53
+
54
+ No more typing everything. Pick from 14 visual input types:
55
+
56
+ | Type | What You See |
57
+ |------|--------------|
58
+ | `pick_one` | Radio buttons |
59
+ | `pick_many` | Checkboxes |
60
+ | `confirm` | Yes/No buttons |
61
+ | `slider` | Draggable range |
62
+ | `rank` | Drag to reorder |
63
+ | `rate` | Star rating |
64
+ | `thumbs` | Thumbs up/down |
65
+ | `show_options` | Cards with pros/cons |
66
+ | `show_diff` | Side-by-side code diff |
67
+ | `ask_code` | Syntax-highlighted editor |
68
+ | `ask_text` | Text input (when needed) |
69
+ | `ask_image` | Image upload |
70
+ | `ask_file` | File upload |
71
+ | `emoji_react` | Emoji picker |
72
+
73
+ ### Live Updates
74
+
75
+ - Questions appear as you answer previous ones
76
+ - Progress indicator shows remaining questions
77
+ - Completed answers visible for context
78
+ - Final plan rendered as reviewable sections
79
+
80
+ ### Parallel Branches
81
+
82
+ Your request is split into 2-4 exploration branches. All initial questions appear at once:
83
+
84
+ ```
85
+ ┌─ Branch 1: [question card]
86
+ Request ─┼─ Branch 2: [question card]
87
+ └─ Branch 3: [question card]
88
+
89
+ Answer any, in any order
90
+ ```
91
+
92
+ Each branch goes as deep as needed. Some finish in 2 questions, others take 4.
93
+
94
+ ## How It Works Behind the Scenes
95
+
96
+ ### 3 Agents
97
+
98
+ | Agent | Job |
99
+ |-------|-----|
100
+ | **bootstrapper** | Splits your request into branches |
101
+ | **probe** | Decides if a branch needs more questions |
102
+ | **octto** | Orchestrates the session |
103
+
104
+ ### The Flow
105
+
106
+ 1. Bootstrapper creates 2-4 branches from your request
107
+ 2. Each branch gets an initial question → all shown in browser
108
+ 3. You answer (click, not type)
109
+ 4. Probe agent evaluates: more questions or done?
110
+ 5. Repeat until all branches complete
111
+ 6. Final plan shown for approval
112
+ 7. Design saved to `docs/plans/`
113
+
114
+ ## Configuration
115
+
116
+ Optional `~/.config/opencode/octto.json`:
117
+
118
+ ```json
119
+ {
120
+ "agents": {
121
+ "probe": { "model": "anthropic/claude-sonnet-4" }
122
+ }
123
+ }
124
+ ```
125
+
126
+ ## Development
127
+
128
+ ```bash
129
+ bun install
130
+ bun run build
131
+ bun test
132
+ ```
133
+
134
+ ## License
135
+
136
+ MIT
@@ -0,0 +1,2 @@
1
+ import type { AgentConfig } from "@opencode-ai/sdk";
2
+ export declare const agent: AgentConfig;
@@ -0,0 +1,11 @@
1
+ import type { AgentConfig } from "@opencode-ai/sdk";
2
+ import { agent as bootstrapper } from "./bootstrapper";
3
+ import { agent as octto } from "./octto";
4
+ import { agent as probe } from "./probe";
5
+ export declare enum AGENTS {
6
+ octto = "octto",
7
+ bootstrapper = "bootstrapper",
8
+ probe = "probe"
9
+ }
10
+ export declare const agents: Record<AGENTS, AgentConfig>;
11
+ export { octto, bootstrapper, probe };
@@ -0,0 +1,2 @@
1
+ import type { AgentConfig } from "@opencode-ai/sdk";
2
+ export declare const agent: AgentConfig;
@@ -0,0 +1,2 @@
1
+ import type { AgentConfig } from "@opencode-ai/sdk";
2
+ export declare const agent: AgentConfig;
@@ -0,0 +1,3 @@
1
+ export { loadCustomConfig } from "./loader";
2
+ export type { AgentOverride, OcttoConfig } from "./schema";
3
+ export { AgentOverrideSchema, OcttoConfigSchema } from "./schema";
@@ -0,0 +1,8 @@
1
+ import type { AgentConfig } from "@opencode-ai/sdk";
2
+ import type { AGENTS } from "@/agents";
3
+ export type { AgentOverride, OcttoConfig } from "./schema";
4
+ /**
5
+ * Load user configuration and merge with plugin agents.
6
+ * Returns merged agent configs with user overrides applied.
7
+ */
8
+ export declare function loadCustomConfig(agents: Record<AGENTS, AgentConfig>, configDir?: string): Promise<Record<AGENTS, AgentConfig>>;
@@ -0,0 +1,82 @@
1
+ import * as v from "valibot";
2
+ import { AGENTS } from "@/agents";
3
+ export declare const AgentOverrideSchema: Omit<v.ObjectSchema<{
4
+ readonly model: v.StringSchema<undefined>;
5
+ readonly temperature: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 2, undefined>]>;
6
+ readonly maxSteps: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
7
+ }, undefined>, "~types" | "~run" | "~standard" | "entries"> & {
8
+ readonly entries: {
9
+ readonly model: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
10
+ readonly temperature: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 2, undefined>]>, undefined>;
11
+ readonly maxSteps: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
12
+ };
13
+ readonly "~standard": v.StandardProps<{
14
+ model?: string | undefined;
15
+ temperature?: number | undefined;
16
+ maxSteps?: number | undefined;
17
+ }, {
18
+ model?: string | undefined;
19
+ temperature?: number | undefined;
20
+ maxSteps?: number | undefined;
21
+ }>;
22
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
23
+ model?: string | undefined;
24
+ temperature?: number | undefined;
25
+ maxSteps?: number | undefined;
26
+ }, v.ObjectIssue | v.StringIssue | v.NumberIssue | v.MinValueIssue<number, 0> | v.MaxValueIssue<number, 2> | v.IntegerIssue<number> | v.MinValueIssue<number, 1>>;
27
+ readonly "~types"?: {
28
+ readonly input: {
29
+ model?: string | undefined;
30
+ temperature?: number | undefined;
31
+ maxSteps?: number | undefined;
32
+ };
33
+ readonly output: {
34
+ model?: string | undefined;
35
+ temperature?: number | undefined;
36
+ maxSteps?: number | undefined;
37
+ };
38
+ readonly issue: v.ObjectIssue | v.StringIssue | v.NumberIssue | v.MinValueIssue<number, 0> | v.MaxValueIssue<number, 2> | v.IntegerIssue<number> | v.MinValueIssue<number, 1>;
39
+ } | undefined;
40
+ };
41
+ export declare const OcttoConfigSchema: v.ObjectSchema<{
42
+ readonly agents: v.OptionalSchema<v.RecordSchema<v.EnumSchema<typeof AGENTS, undefined>, Omit<v.ObjectSchema<{
43
+ readonly model: v.StringSchema<undefined>;
44
+ readonly temperature: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 2, undefined>]>;
45
+ readonly maxSteps: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
46
+ }, undefined>, "~types" | "~run" | "~standard" | "entries"> & {
47
+ readonly entries: {
48
+ readonly model: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
49
+ readonly temperature: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 2, undefined>]>, undefined>;
50
+ readonly maxSteps: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
51
+ };
52
+ readonly "~standard": v.StandardProps<{
53
+ model?: string | undefined;
54
+ temperature?: number | undefined;
55
+ maxSteps?: number | undefined;
56
+ }, {
57
+ model?: string | undefined;
58
+ temperature?: number | undefined;
59
+ maxSteps?: number | undefined;
60
+ }>;
61
+ readonly "~run": (dataset: v.UnknownDataset, config: v.Config<v.BaseIssue<unknown>>) => v.OutputDataset<{
62
+ model?: string | undefined;
63
+ temperature?: number | undefined;
64
+ maxSteps?: number | undefined;
65
+ }, v.ObjectIssue | v.StringIssue | v.NumberIssue | v.MinValueIssue<number, 0> | v.MaxValueIssue<number, 2> | v.IntegerIssue<number> | v.MinValueIssue<number, 1>>;
66
+ readonly "~types"?: {
67
+ readonly input: {
68
+ model?: string | undefined;
69
+ temperature?: number | undefined;
70
+ maxSteps?: number | undefined;
71
+ };
72
+ readonly output: {
73
+ model?: string | undefined;
74
+ temperature?: number | undefined;
75
+ maxSteps?: number | undefined;
76
+ };
77
+ readonly issue: v.ObjectIssue | v.StringIssue | v.NumberIssue | v.MinValueIssue<number, 0> | v.MaxValueIssue<number, 2> | v.IntegerIssue<number> | v.MinValueIssue<number, 1>;
78
+ } | undefined;
79
+ }, undefined>, undefined>;
80
+ }, undefined>;
81
+ export type AgentOverride = v.InferOutput<typeof AgentOverrideSchema>;
82
+ export type OcttoConfig = v.InferOutput<typeof OcttoConfigSchema>;
@@ -0,0 +1,4 @@
1
+ /** Default timeout for waiting for user answers (5 minutes) */
2
+ export declare const DEFAULT_ANSWER_TIMEOUT_MS = 300000;
3
+ /** Default maximum number of follow-up questions per branch */
4
+ export declare const DEFAULT_MAX_QUESTIONS = 15;
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ declare const Octto: Plugin;
3
+ export default Octto;
4
+ export type * from "./types";