@statechange/council 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.
Files changed (89) hide show
  1. package/README.md +207 -0
  2. package/council/creative/ABOUT.md +23 -0
  3. package/council/critic/ABOUT.md +23 -0
  4. package/council/strategist/ABOUT.md +21 -0
  5. package/dist/backends/anthropic.d.ts +2 -0
  6. package/dist/backends/anthropic.js +57 -0
  7. package/dist/backends/anthropic.js.map +1 -0
  8. package/dist/backends/google.d.ts +2 -0
  9. package/dist/backends/google.js +68 -0
  10. package/dist/backends/google.js.map +1 -0
  11. package/dist/backends/index.d.ts +3 -0
  12. package/dist/backends/index.js +47 -0
  13. package/dist/backends/index.js.map +1 -0
  14. package/dist/backends/ollama.d.ts +2 -0
  15. package/dist/backends/ollama.js +68 -0
  16. package/dist/backends/ollama.js.map +1 -0
  17. package/dist/backends/openai.d.ts +2 -0
  18. package/dist/backends/openai.js +62 -0
  19. package/dist/backends/openai.js.map +1 -0
  20. package/dist/backends/types.d.ts +1 -0
  21. package/dist/backends/types.js +2 -0
  22. package/dist/backends/types.js.map +1 -0
  23. package/dist/cli.d.ts +2 -0
  24. package/dist/cli.js +152 -0
  25. package/dist/cli.js.map +1 -0
  26. package/dist/commands/config.d.ts +7 -0
  27. package/dist/commands/config.js +118 -0
  28. package/dist/commands/config.js.map +1 -0
  29. package/dist/commands/counsellor.d.ts +7 -0
  30. package/dist/commands/counsellor.js +98 -0
  31. package/dist/commands/counsellor.js.map +1 -0
  32. package/dist/commands/discuss.d.ts +12 -0
  33. package/dist/commands/discuss.js +154 -0
  34. package/dist/commands/discuss.js.map +1 -0
  35. package/dist/commands/history.d.ts +5 -0
  36. package/dist/commands/history.js +46 -0
  37. package/dist/commands/history.js.map +1 -0
  38. package/dist/commands/list.d.ts +5 -0
  39. package/dist/commands/list.js +40 -0
  40. package/dist/commands/list.js.map +1 -0
  41. package/dist/core/conversation-engine.d.ts +13 -0
  42. package/dist/core/conversation-engine.js +226 -0
  43. package/dist/core/conversation-engine.js.map +1 -0
  44. package/dist/core/counsellor-loader.d.ts +4 -0
  45. package/dist/core/counsellor-loader.js +97 -0
  46. package/dist/core/counsellor-loader.js.map +1 -0
  47. package/dist/core/counsellor-registry.d.ts +12 -0
  48. package/dist/core/counsellor-registry.js +131 -0
  49. package/dist/core/counsellor-registry.js.map +1 -0
  50. package/dist/core/excalidraw-cheatsheet.d.ts +5 -0
  51. package/dist/core/excalidraw-cheatsheet.js +65 -0
  52. package/dist/core/excalidraw-cheatsheet.js.map +1 -0
  53. package/dist/core/history.d.ts +16 -0
  54. package/dist/core/history.js +74 -0
  55. package/dist/core/history.js.map +1 -0
  56. package/dist/core/infographic.d.ts +4 -0
  57. package/dist/core/infographic.js +81 -0
  58. package/dist/core/infographic.js.map +1 -0
  59. package/dist/core/key-scanner.d.ts +8 -0
  60. package/dist/core/key-scanner.js +79 -0
  61. package/dist/core/key-scanner.js.map +1 -0
  62. package/dist/core/logger.d.ts +5 -0
  63. package/dist/core/logger.js +38 -0
  64. package/dist/core/logger.js.map +1 -0
  65. package/dist/core/output-formatter.d.ts +2 -0
  66. package/dist/core/output-formatter.js +47 -0
  67. package/dist/core/output-formatter.js.map +1 -0
  68. package/dist/core/secretary.d.ts +23 -0
  69. package/dist/core/secretary.js +171 -0
  70. package/dist/core/secretary.js.map +1 -0
  71. package/dist/core/skill-loader.d.ts +2 -0
  72. package/dist/core/skill-loader.js +32 -0
  73. package/dist/core/skill-loader.js.map +1 -0
  74. package/dist/electron/ipc-handlers.d.ts +3 -0
  75. package/dist/electron/ipc-handlers.js +477 -0
  76. package/dist/electron/ipc-handlers.js.map +1 -0
  77. package/dist/electron/main.d.ts +1 -0
  78. package/dist/electron/main.js +85 -0
  79. package/dist/electron/main.js.map +1 -0
  80. package/dist/electron/preload.d.ts +1 -0
  81. package/dist/electron/preload.js +38 -0
  82. package/dist/electron/preload.js.map +1 -0
  83. package/dist/types.d.ts +184 -0
  84. package/dist/types.js +12 -0
  85. package/dist/types.js.map +1 -0
  86. package/dist-electron/main.js +1635 -0
  87. package/package.json +87 -0
  88. package/skills/council-manage/SKILL.md +214 -0
  89. package/skills/council-setup-keys/SKILL.md +127 -0
package/package.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "@statechange/council",
3
+ "version": "0.1.0",
4
+ "description": "CLI + GUI for orchestrating round-robin AI counsellor discussions with structured debate and freeform modes",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "main": "dist-electron/main.js",
8
+ "bin": {
9
+ "council": "./dist/cli.js"
10
+ },
11
+ "files": [
12
+ "dist/",
13
+ "council/creative/",
14
+ "council/critic/",
15
+ "council/strategist/",
16
+ "skills/",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/statechangelabs/council.git"
23
+ },
24
+ "keywords": [
25
+ "ai",
26
+ "council",
27
+ "debate",
28
+ "llm",
29
+ "multi-agent",
30
+ "anthropic",
31
+ "openai",
32
+ "google",
33
+ "ollama",
34
+ "claude-code",
35
+ "skills"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsc",
39
+ "dev": "tsx src/cli.tsx",
40
+ "start": "node dist/cli.js",
41
+ "dev:gui": "vite",
42
+ "build:gui": "vite build",
43
+ "package": "electron-builder",
44
+ "prepublishOnly": "tsc"
45
+ },
46
+ "dependencies": {
47
+ "@anthropic-ai/sdk": "^0.39.0",
48
+ "@excalidraw/excalidraw": "^0.18.0",
49
+ "@google/genai": "^1.43.0",
50
+ "@google/generative-ai": "^0.21.0",
51
+ "@lobehub/icons": "^4.6.0",
52
+ "autoprefixer": "^10.4.24",
53
+ "class-variance-authority": "^0.7.1",
54
+ "clsx": "^2.1.1",
55
+ "dotenv": "^16.4.0",
56
+ "glob": "^11.0.0",
57
+ "gray-matter": "^4.0.3",
58
+ "ink": "^5.0.1",
59
+ "ink-spinner": "^5.0.0",
60
+ "lucide-react": "^0.575.0",
61
+ "meow": "^13.2.0",
62
+ "ollama": "^0.5.0",
63
+ "openai": "^4.80.0",
64
+ "postcss": "^8.5.6",
65
+ "react": "^18.3.1",
66
+ "react-dom": "18",
67
+ "react-markdown": "^10.1.0",
68
+ "tailwind-merge": "^3.5.0",
69
+ "tailwindcss": "3",
70
+ "tailwindcss-animate": "^1.0.7",
71
+ "zod": "^3.24.1"
72
+ },
73
+ "devDependencies": {
74
+ "@types/node": "^22.10.2",
75
+ "@types/react": "^18.3.18",
76
+ "@types/react-dom": "18",
77
+ "@vitejs/plugin-react": "^5.1.4",
78
+ "concurrently": "^9.2.1",
79
+ "electron": "^40.6.0",
80
+ "electron-builder": "^26.8.1",
81
+ "tsx": "^4.21.0",
82
+ "typescript": "^5.7.2",
83
+ "vite": "^7.3.1",
84
+ "vite-plugin-electron": "^0.29.0",
85
+ "vite-plugin-electron-renderer": "^0.14.6"
86
+ }
87
+ }
@@ -0,0 +1,214 @@
1
+ ---
2
+ name: council-manage
3
+ description: Manage AI Council counsellors and discussions from the command line. Create, list, edit, and configure counsellors. Run discussions with topic selection and counsellor filtering. Use when the user wants to work with AI Council via CLI or needs help managing their council setup.
4
+ license: MIT
5
+ metadata:
6
+ author: ai-council
7
+ version: "1.0"
8
+ ---
9
+
10
+ # Council Manage
11
+
12
+ Manage AI Council counsellors and run discussions from the command line.
13
+
14
+ ## Installation
15
+
16
+ If `council` is not already installed, install it globally from NPM:
17
+
18
+ ```bash
19
+ npm install -g @statechange/council
20
+ ```
21
+
22
+ Or run commands directly with `npx @statechange/council`.
23
+
24
+ ## When to Use
25
+
26
+ - The user wants to create, edit, or delete a counsellor
27
+ - The user wants to list their counsellors and check their status
28
+ - The user wants to run a discussion from the CLI
29
+ - The user asks about council configuration or troubleshooting
30
+
31
+ ## Counsellor Structure
32
+
33
+ Each counsellor lives in a directory under the council path (default `./council/`), with an `ABOUT.md` file containing YAML frontmatter and a system prompt:
34
+
35
+ ```
36
+ council/
37
+ my-counsellor/
38
+ ABOUT.md
39
+ ```
40
+
41
+ ### ABOUT.md Format
42
+
43
+ ```markdown
44
+ ---
45
+ name: "Display Name"
46
+ description: "One-line description of this counsellor's perspective"
47
+ interests: ["topic1", "topic2", "topic3"]
48
+ backend: "anthropic" # anthropic | openai | google | ollama
49
+ model: "claude-sonnet-4-5-20250929" # optional, uses backend default if omitted
50
+ temperature: 0.7 # 0.0 - 2.0, optional
51
+ ---
52
+
53
+ You are [name], a [description of role and personality].
54
+
55
+ [Detailed system prompt instructions...]
56
+ ```
57
+
58
+ ### Available Backends and Default Models
59
+
60
+ | Backend | Default Model | Requires API Key |
61
+ |---------|--------------|-----------------|
62
+ | anthropic | claude-sonnet-4-5-20250929 | Yes (ANTHROPIC_API_KEY) |
63
+ | openai | gpt-4o | Yes (OPENAI_API_KEY) |
64
+ | google | gemini-2.0-flash | Yes (GOOGLE_API_KEY) |
65
+ | ollama | llama3.2 | No (local) |
66
+
67
+ ## CLI Commands
68
+
69
+ ### List counsellors
70
+
71
+ ```bash
72
+ council list
73
+ council list --council ./path/to/council/
74
+ ```
75
+
76
+ ### Run a discussion
77
+
78
+ ```bash
79
+ # Inline topic
80
+ council discuss "Should we adopt microservices?"
81
+
82
+ # Topic from file
83
+ council discuss ./topics/architecture.md
84
+
85
+ # With options
86
+ council discuss "Topic" --rounds 3 --format md --output ./results
87
+
88
+ # Specific counsellors only
89
+ council discuss "Topic" --counsellors ./council/strategist ./council/critic
90
+ ```
91
+
92
+ ### Manage counsellor registry
93
+
94
+ ```bash
95
+ # Register a counsellor from a local directory
96
+ council counsellor add ./path/to/counsellor
97
+
98
+ # Register counsellor(s) from a git repository
99
+ council counsellor add https://github.com/user/some-counsellor.git
100
+
101
+ # List all registered counsellors
102
+ council counsellor list
103
+
104
+ # Unregister a counsellor (--yes auto-deletes cloned files for git sources)
105
+ council counsellor remove my-counsellor
106
+ council counsellor remove my-counsellor --yes
107
+ ```
108
+
109
+ Registered counsellors are stored in `~/.ai-council/config.json` under the `counsellors` key. Git-cloned counsellors are placed at `~/.ai-council/counsellors/<name>/`.
110
+
111
+ URL detection: paths starting with `http://`, `https://`, or ending with `.git` are treated as git URLs; everything else is a local path.
112
+
113
+ Multi-counsellor repos: if the cloned root has no `ABOUT.md`, child directories are scanned for counsellors.
114
+
115
+ ### Check configuration
116
+
117
+ ```bash
118
+ council config show # Show backend status
119
+ council config scan # Find API keys
120
+ council config import # Import found keys
121
+ ```
122
+
123
+ ## Creating a New Counsellor
124
+
125
+ To create a new counsellor:
126
+
127
+ 1. Create a directory: `mkdir council/new-counsellor`
128
+ 2. Create `council/new-counsellor/ABOUT.md` with the frontmatter and system prompt
129
+ 3. Verify with `council list`
130
+
131
+ ### Building a Counsellor from Source Material
132
+
133
+ When creating a counsellor based on a real person, historical figure, or body of work, the ABOUT.md should have three distinct layers:
134
+
135
+ **Layer 1: Frontmatter** — identity and metadata:
136
+ ```yaml
137
+ ---
138
+ name: "Display Name"
139
+ description: "One-line summary of their perspective and what they bring to the council"
140
+ interests: ["core-topic-1", "core-topic-2", "core-topic-3"]
141
+ backend: "anthropic"
142
+ temperature: 0.7
143
+ avatar: "avatar.jpg" # local file preferred; DiceBear URL as fallback for generic personas
144
+ ---
145
+ ```
146
+
147
+ **Layer 2: System prompt** — the "who you are" section written directly after the frontmatter. This should:
148
+ - Establish the persona: "You are [Name], [role]. You sit on a council of experts and bring [perspective]."
149
+ - Define their **intellectual framework** as a structured list of 3-6 core principles or methods of analysis, each with a brief explanation
150
+ - Provide **behavioral instructions** for how they should engage in discussion (what to emphasize, what to question, how to relate to other perspectives)
151
+ - Set a **personality/style note** (e.g. rhetorically forceful, measured and empirical, provocative but grounded)
152
+ - End with: "Keep your responses focused and substantive. Aim for 2-4 paragraphs per turn."
153
+
154
+ **Layer 3: Reference material** — the bulk source text appended below. Separated by a markdown horizontal rule and a heading like `## Reference Material: [Title]`. Include a one-line instruction telling the counsellor to draw on this material. Then the full text.
155
+
156
+ #### Build Process for Source-Material Counsellors
157
+
158
+ Because pasting large reference texts directly into an LLM output can trigger content filtering, use a **concatenation approach**:
159
+
160
+ 1. **Download the source material** to a temp file:
161
+ ```bash
162
+ curl -o /tmp/source.txt "https://example.com/source-text"
163
+ ```
164
+
165
+ 2. **Write only the header** (frontmatter + system prompt + reference intro) to a temp file using the Write tool or a heredoc. This is the part you author — keep it under ~2KB.
166
+
167
+ 3. **Extract the relevant portion** of the source (e.g. strip Project Gutenberg headers/footers):
168
+ ```bash
169
+ sed -n '/START_MARKER/,/END_MARKER/p' /tmp/source.txt | sed '1d;$d' > /tmp/source-body.txt
170
+ ```
171
+
172
+ 4. **Concatenate** header + body into the final ABOUT.md:
173
+ ```bash
174
+ cat /tmp/header.md /tmp/source-body.txt > council/new-counsellor/ABOUT.md
175
+ ```
176
+
177
+ This keeps the authored content (which goes through the LLM) small, and the bulk reference text is handled entirely through file operations.
178
+
179
+ #### Tips
180
+
181
+ - **Interests**: Pick 5-8 terms that reflect the counsellor's core domains. These appear as tags in the UI and help users understand what the counsellor brings.
182
+ - **Avatar**: Prefer a real image of the person or what they're most associated with. For historical figures, authors, philosophers etc., download a public-domain portrait from Wikimedia Commons into the counsellor directory as `avatar.jpg` (use the Wikipedia API to find a thumbnail URL, then `curl -o council/<name>/avatar.jpg <url>`). Set `avatar: "avatar.jpg"` in frontmatter — relative paths are resolved automatically. Only fall back to DiceBear (`https://api.dicebear.com/9.x/personas/svg?seed=SlugHere&backgroundColor=hexWithoutHash`) for fictional or generic personas where no real image applies.
183
+ - **Temperature**: 0.7 is a good default. Go higher (0.8-0.9) for creative/provocative thinkers, lower (0.5-0.6) for analytical/precise ones.
184
+ - **Source material size**: The full Communist Manifesto (~77KB) works fine. Larger texts will too but may increase token costs per discussion turn. Consider excerpting if a source exceeds ~200KB.
185
+ - **Multiple sources**: You can append several reference texts with separate `## Reference Material:` headings.
186
+ - **Public domain sources**: Project Gutenberg (gutenberg.org) is a good source. Always strip the PG header/footer boilerplate.
187
+
188
+ ## Troubleshooting
189
+
190
+ ### Counsellor shows as red / has issues
191
+
192
+ Usually means the backend API key is missing. Fix with:
193
+ ```bash
194
+ council config show # Check which keys are missing
195
+ council config scan # Look for keys
196
+ council config import # Import found keys
197
+ ```
198
+
199
+ ### Discussion fails with backend errors
200
+
201
+ 1. Check the backend is configured: `council config show`
202
+ 2. For ollama: ensure `ollama serve` is running
203
+ 3. For cloud backends: verify the API key is valid and has credits
204
+
205
+ ## GUI Alternative
206
+
207
+ All of the above can also be done in the Electron GUI (requires cloning the repo):
208
+ ```bash
209
+ git clone https://github.com/statechangelabs/council.git && cd council
210
+ bun install && bun run dev:gui
211
+ ```
212
+ - **Settings page**: Configure API keys, test connections, see available models
213
+ - **Counsellors page**: Browse, create, edit, delete counsellors with a form editor
214
+ - **Discussion page**: Start discussions with counsellor selection and real-time streaming
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: council-setup-keys
3
+ description: Find AI API keys scattered across env files, shell profiles, and project directories, then consolidate them into the AI Council config at ~/.ai-council/config.json. Use when setting up AI Council, when counsellors show missing API key errors, or when the user asks to configure backends.
4
+ license: MIT
5
+ metadata:
6
+ author: ai-council
7
+ version: "1.0"
8
+ ---
9
+
10
+ # Council Setup Keys
11
+
12
+ Find and consolidate AI API keys into the AI Council configuration.
13
+
14
+ ## Installation
15
+
16
+ If `council` is not already installed, install it globally from NPM:
17
+
18
+ ```bash
19
+ npm install -g @statechange/council
20
+ ```
21
+
22
+ Or run commands directly with `npx @statechange/council`.
23
+
24
+ ## When to Use
25
+
26
+ - The user asks to set up or configure AI Council
27
+ - Counsellors are showing red / missing API key warnings
28
+ - The user wants to find their API keys from other projects
29
+ - The user says something like "find my keys", "setup my backends", or "configure API keys"
30
+
31
+ ## Steps
32
+
33
+ ### 1. Check current configuration status
34
+
35
+ Run the config show command to see what's already configured:
36
+
37
+ ```bash
38
+ council config show
39
+ ```
40
+
41
+ This shows each backend (anthropic, openai, google, ollama) and whether it has a key from the config file or environment.
42
+
43
+ ### 2. Scan standard locations
44
+
45
+ Run the built-in scanner to check env files and shell profiles:
46
+
47
+ ```bash
48
+ council config scan
49
+ ```
50
+
51
+ This searches:
52
+ - `.env`, `.env.local`, `.env.development`, `.env.production` in the current directory
53
+ - `~/.env`, `~/.bashrc`, `~/.bash_profile`, `~/.zshrc`, `~/.zshenv`, `~/.zprofile`, `~/.profile`
54
+ - `~/.config/fish/config.fish`
55
+ - Current process environment variables
56
+
57
+ ### 3. Search additional project directories
58
+
59
+ The built-in scanner covers standard locations, but keys are often in project `.env` files. Search common project directories for any the scanner missed:
60
+
61
+ ```bash
62
+ # Search for API key assignments in .env files across common directories
63
+ grep -r "ANTHROPIC_API_KEY\|OPENAI_API_KEY\|GOOGLE_API_KEY\|GEMINI_API_KEY" \
64
+ ~/Documents/ ~/Projects/ ~/Code/ ~/Developer/ ~/repos/ ~/src/ \
65
+ --include=".env*" -l 2>/dev/null
66
+ ```
67
+
68
+ If additional files are found, pass them to the scanner:
69
+
70
+ ```bash
71
+ council config scan /path/to/found/.env /other/path/.env
72
+ ```
73
+
74
+ ### 4. Import discovered keys
75
+
76
+ Once you've confirmed which keys are available, import them:
77
+
78
+ ```bash
79
+ council config import
80
+ ```
81
+
82
+ Or with additional paths:
83
+
84
+ ```bash
85
+ council config import /path/to/extra/.env
86
+ ```
87
+
88
+ This writes keys to `~/.ai-council/config.json`, skipping any backend that already has a key configured.
89
+
90
+ ### 5. Verify the result
91
+
92
+ Run show again to confirm all backends are configured:
93
+
94
+ ```bash
95
+ council config show
96
+ ```
97
+
98
+ ### 6. Report to the user
99
+
100
+ Tell the user:
101
+ - Which backends are now configured
102
+ - Which backends are still missing keys (and what env var or key they need)
103
+ - That they can also configure keys in the Electron GUI under Settings
104
+ - For ollama: no key needed, just ensure ollama is running locally
105
+
106
+ ## Key Environment Variables
107
+
108
+ | Backend | Env Variable | Key Prefix |
109
+ |---------|-------------|------------|
110
+ | Anthropic | `ANTHROPIC_API_KEY` | `sk-ant-` |
111
+ | OpenAI | `OPENAI_API_KEY` | `sk-` |
112
+ | Google | `GOOGLE_API_KEY` or `GEMINI_API_KEY` | `AI` |
113
+ | Ollama | (none needed) | — |
114
+
115
+ ## Config File Location
116
+
117
+ `~/.ai-council/config.json`
118
+
119
+ ```json
120
+ {
121
+ "backends": {
122
+ "anthropic": { "apiKey": "sk-ant-..." },
123
+ "openai": { "apiKey": "sk-..." },
124
+ "google": { "apiKey": "AI..." }
125
+ }
126
+ }
127
+ ```