@tyvm/knowhow 0.0.109 → 0.0.110

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 (94) hide show
  1. package/autodoc/README.md +324 -0
  2. package/autodoc/chat-guide.md +268 -365
  3. package/autodoc/cli-reference.md +399 -473
  4. package/autodoc/config-reference.md +431 -330
  5. package/autodoc/embeddings-guide.md +223 -322
  6. package/autodoc/generate-guide.md +261 -301
  7. package/autodoc/language-plugin-guide.md +221 -247
  8. package/autodoc/modules-guide.md +242 -215
  9. package/autodoc/plugins-guide.md +470 -469
  10. package/autodoc/quickstart-guide.md +67 -70
  11. package/autodoc/skills-guide.md +455 -339
  12. package/autodoc/worker-guide.md +301 -308
  13. package/package.json +1 -1
  14. package/scripts/build-for-node.sh +10 -24
  15. package/src/agents/tools/list.ts +2 -2
  16. package/src/ai.ts +81 -37
  17. package/src/chat/CliChatService.ts +1 -1
  18. package/src/chat/modules/AgentModule.ts +7 -2
  19. package/src/chat/modules/SessionsModule.ts +40 -1
  20. package/src/chat/modules/SystemModule.ts +2 -2
  21. package/src/clients/anthropic.ts +1 -1
  22. package/src/clients/index.ts +25 -6
  23. package/src/clients/openai.ts +8 -5
  24. package/src/clients/types.ts +29 -6
  25. package/src/clients/withRetry.ts +89 -0
  26. package/src/commands/agent.ts +30 -0
  27. package/src/commands/modules.ts +417 -47
  28. package/src/config.ts +1 -1
  29. package/src/fileSync.ts +20 -12
  30. package/src/hashes.ts +43 -22
  31. package/src/index.ts +4 -2
  32. package/src/processors/Base64ImageDetector.ts +73 -0
  33. package/src/services/MediaProcessorService.ts +79 -10
  34. package/src/services/modules/index.ts +47 -18
  35. package/tests/processors/Base64ImageDetector.test.ts +160 -0
  36. package/tests/unit/clients/AIClient.test.ts +446 -0
  37. package/tests/unit/clients/withRetry.test.ts +319 -0
  38. package/tests/unit/commands/github-credentials.test.ts +1 -2
  39. package/ts_build/package.json +1 -1
  40. package/ts_build/src/agents/tools/list.js +2 -2
  41. package/ts_build/src/agents/tools/list.js.map +1 -1
  42. package/ts_build/src/ai.d.ts +3 -3
  43. package/ts_build/src/ai.js +51 -23
  44. package/ts_build/src/ai.js.map +1 -1
  45. package/ts_build/src/chat/CliChatService.js +1 -1
  46. package/ts_build/src/chat/CliChatService.js.map +1 -1
  47. package/ts_build/src/chat/modules/AgentModule.js +5 -2
  48. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  49. package/ts_build/src/chat/modules/SessionsModule.js +30 -1
  50. package/ts_build/src/chat/modules/SessionsModule.js.map +1 -1
  51. package/ts_build/src/chat/modules/SystemModule.js +2 -2
  52. package/ts_build/src/chat/modules/SystemModule.js.map +1 -1
  53. package/ts_build/src/clients/anthropic.js +1 -1
  54. package/ts_build/src/clients/anthropic.js.map +1 -1
  55. package/ts_build/src/clients/index.js +7 -6
  56. package/ts_build/src/clients/index.js.map +1 -1
  57. package/ts_build/src/clients/openai.js +4 -4
  58. package/ts_build/src/clients/openai.js.map +1 -1
  59. package/ts_build/src/clients/types.d.ts +12 -6
  60. package/ts_build/src/clients/withRetry.d.ts +2 -0
  61. package/ts_build/src/clients/withRetry.js +60 -0
  62. package/ts_build/src/clients/withRetry.js.map +1 -0
  63. package/ts_build/src/commands/agent.js +25 -0
  64. package/ts_build/src/commands/agent.js.map +1 -1
  65. package/ts_build/src/commands/modules.js +359 -32
  66. package/ts_build/src/commands/modules.js.map +1 -1
  67. package/ts_build/src/config.js +1 -1
  68. package/ts_build/src/config.js.map +1 -1
  69. package/ts_build/src/fileSync.d.ts +2 -2
  70. package/ts_build/src/fileSync.js +13 -11
  71. package/ts_build/src/fileSync.js.map +1 -1
  72. package/ts_build/src/hashes.d.ts +2 -2
  73. package/ts_build/src/hashes.js +40 -16
  74. package/ts_build/src/hashes.js.map +1 -1
  75. package/ts_build/src/index.js +1 -1
  76. package/ts_build/src/index.js.map +1 -1
  77. package/ts_build/src/processors/Base64ImageDetector.d.ts +3 -0
  78. package/ts_build/src/processors/Base64ImageDetector.js +42 -0
  79. package/ts_build/src/processors/Base64ImageDetector.js.map +1 -1
  80. package/ts_build/src/services/MediaProcessorService.d.ts +5 -4
  81. package/ts_build/src/services/MediaProcessorService.js +53 -8
  82. package/ts_build/src/services/MediaProcessorService.js.map +1 -1
  83. package/ts_build/src/services/modules/index.js +35 -12
  84. package/ts_build/src/services/modules/index.js.map +1 -1
  85. package/ts_build/tests/processors/Base64ImageDetector.test.js +111 -0
  86. package/ts_build/tests/processors/Base64ImageDetector.test.js.map +1 -1
  87. package/ts_build/tests/unit/clients/AIClient.test.d.ts +1 -0
  88. package/ts_build/tests/unit/clients/AIClient.test.js +339 -0
  89. package/ts_build/tests/unit/clients/AIClient.test.js.map +1 -0
  90. package/ts_build/tests/unit/clients/withRetry.test.d.ts +1 -0
  91. package/ts_build/tests/unit/clients/withRetry.test.js +225 -0
  92. package/ts_build/tests/unit/clients/withRetry.test.js.map +1 -0
  93. package/ts_build/tests/unit/commands/github-credentials.test.js +1 -2
  94. package/ts_build/tests/unit/commands/github-credentials.test.js.map +1 -1
@@ -1,152 +1,131 @@
1
- # Language Plugin Guide (Knowhow CLI)
1
+ # Knowhow Language Plugin Guide
2
2
 
3
- The **Language Plugin** is one of the most powerful features of Knowhow. It lets you define custom **hotwords / terms** (like `frontend`, `backend`, `my PR`, `API`, `prod`) that automatically **inject context** into your chat sessions whenever you use those terms—pulling in **files, inline text, GitHub content, and URLs**.
3
+ ## 1) What the language plugin does
4
4
 
5
- ---
6
-
7
- ## 1) What the Language Plugin does
8
-
9
- When you send a message (or when certain file events occur), the Language Plugin:
5
+ The **Language Plugin** lets you define custom “hotwords” (called **terms**) in `.knowhow/language.json`. When you use one of those terms in a chat (or when specific file events happen), Knowhow automatically:
10
6
 
11
- 1. Loads your term configuration from **`.knowhow/language.json`**
12
- 2. Finds which configured **term keys/patterns** match your input
13
- 3. Expands each matching term into one or more **sources**:
14
- - file contents from disk
15
- - raw inline text
16
- - GitHub PR/issue/file content
17
- - content fetched from a URL
18
- 4. Injects the loaded context into the session so your agent can answer using your real project/docs.
7
+ 1. **Finds matching terms** inside your input (via glob/wildcard + substring matching).
8
+ 2. **Resolves the configured sources** for each matching term (files, raw text, GitHub content, URLs, etc.).
9
+ 3. **Injects the resolved context** into the workflow by emitting an internal agent message (`agent:msg`) containing the expanded sources.
19
10
 
20
- **In short:** typing a term like `API` can automatically attach your local API docs/specs—no copy/paste required.
11
+ In short: **typing words like “frontend”, “API”, “prod” can automatically pull in the right docs, specs, PR details, or environment noteswithout you manually copying/pasting them.**
21
12
 
22
13
  ---
23
14
 
24
15
  ## 2) Configuration file: `.knowhow/language.json`
25
16
 
26
- Create or edit this file in your project:
17
+ Knowhow reads **only** the local file:
27
18
 
28
- ```text
29
- ./.knowhow/language.json
30
- ```
19
+ - **Local:** `.knowhow/language.json`
20
+
21
+ If the file does not exist, the plugin behaves as if there are **no language terms**.
31
22
 
32
- ### Example structure
23
+ ### Structure (high level)
24
+
25
+ Your file is a JSON object where each **key** is a term (or multiple patterns in one key), and each value defines:
26
+
27
+ - `events` (optional): triggers for file events / agent events
28
+ - `sources`: what to load when the term matches
33
29
 
34
30
  ```jsonc
35
31
  {
36
- "term-or-pattern-key": {
32
+ "term-or-patterns": {
33
+ "events": ["file:open", "file:save", "agent:message", "..."],
37
34
  "sources": [
38
- { "kind": "file", "data": ["glob-or-path-1", "glob-or-path-2"] },
39
- { "kind": "text", "data": "Inline raw text to inject" },
40
- { "kind": "github","data": ["github input payload(s)"] },
41
- { "kind": "url", "data": ["https://example.com/..."] }
42
- ],
43
- "events": ["file:open", "file:save"]
35
+ { "kind": "file", "data": ["path-or-glob", "..."] },
36
+ { "kind": "text", "data": "some inline text" },
37
+ { "kind": "github", "data": ["pr:123", "issue:456", "..."] },
38
+ { "kind": "url", "data": ["https://example.com/docs", "..."] }
39
+ ]
44
40
  }
45
41
  }
46
42
  ```
47
43
 
48
- ### Required fields
49
- - **`sources`**: an array of source entries, each with:
50
- - **`kind`**: one of `file`, `text`, `github`, `url`
51
- - **`data`**: varies by kind (see section 4)
44
+ ### Term key format (important)
45
+ A single JSON key can contain **multiple comma-separated patterns**. Those patterns are treated as alternatives that map to the same `sources`.
52
46
 
53
- ### Optional fields
54
- - **`events`**: an array of event names (commonly file events).
55
- When present, the term is considered for **event-driven triggers** based on the file operation type.
47
+ Example key with alternatives:
56
48
 
57
- ---
58
-
59
- ## 3) Term matching (comma-separated keys + glob/wildcard matching)
60
-
61
- ### Comma-separated keys = multiple match patterns
62
-
63
- A single top-level JSON key can represent multiple patterns:
64
-
65
- ```jsonc
49
+ ```json
66
50
  {
67
- "frontend, ui, web": {
68
- "sources": [ /* ... */ ]
51
+ "frontend,fe,ui": {
52
+ "sources": [
53
+ { "kind": "file", "data": [".knowhow/docs/frontend-architecture.md"] }
54
+ ]
69
55
  }
70
56
  }
71
57
  ```
72
58
 
73
- This means any of these can trigger the same term expansion:
74
- - `frontend`
75
- - `ui`
76
- - `web`
59
+ ---
77
60
 
78
- ### Matching behavior for generic prompt text
61
+ ## 3) Term matching (glob/wildcard + comma-separated keys)
79
62
 
80
- For normal chat input matching:
63
+ ### 3.1 User prompt matching (generic events)
64
+ When the plugin checks a message, it:
81
65
 
82
- - If a pattern contains `*`, Knowhow treats it as a **glob/wildcard pattern**
83
- - matching is performed with glob logic (e.g., via `minimatch`)
84
- - Otherwise, Knowhow performs **case-insensitive substring** matching:
85
- - `userPrompt.toLowerCase().includes(pattern.toLowerCase())`
66
+ - iterates over all term keys
67
+ - splits each key by commas: `term.split(",")`
68
+ - trims each pattern
69
+ - checks for match using:
70
+ - **glob/wildcard** matching when the pattern contains `*`
71
+ - otherwise **case-insensitive substring** match
86
72
 
87
- **Implication:**
88
- - Use `*` for families like `api*`, `payment*`, `spec-*`
89
- - Use plain words for hotphrases like `API`, `prod`, `staging`
73
+ **Rule from the code:**
74
+ - If pattern contains `*`: uses `minimatch(userPrompt, pattern)`
75
+ - Else: `userPrompt.toLowerCase().includes(pattern.toLowerCase())`
90
76
 
91
- ### Matching behavior for file open/save events
77
+ Examples:
78
+ - `"API"` matches when user prompt contains `"api"` anywhere.
79
+ - `"api*"` matches when user prompt matches the glob.
80
+ - `"prod,production"` matches either `prod` or `production`.
92
81
 
93
- For event-driven matching (file open/save), Knowhow checks patterns against the file:
82
+ ### 3.2 File operation matching (file events)
83
+ For `file:*` events, the plugin finds matching terms based on:
94
84
 
95
- - It only considers terms whose config includes the event type in **`events`**
96
- - For each pattern in the comma-separated key:
97
- - Match if `minimatch(filePath, pattern)` succeeds **(path glob match)**
98
- **OR**
99
- - Match if the file contents contain the pattern (case-insensitive substring match)
85
+ - **file path** pattern matching (glob via `minimatch(filePath, pattern)`)
86
+ - OR **file content** containing the pattern as a substring (case-insensitive)
100
87
 
101
- **Implication:**
102
- - You can target files by **path globs** (recommended)
103
- - Or by **content markers** when the path is unpredictable
88
+ So file triggers can be far more contextual, e.g.:
89
+ - Opening `apps/web/src/routes/login.tsx` can match terms like `apps/web/*` or keywords found in the file.
104
90
 
105
91
  ---
106
92
 
107
- ## 4) Source kinds supported
93
+ ## 4) Supported source kinds
108
94
 
109
- A matching term expands into one or more sources. Knowhow supports these kinds:
95
+ The Language Plugin loads **sources** for every matching term.
110
96
 
111
- ### `file` — load file contents (supports glob patterns)
97
+ ### 4.1 `file` — load file contents
98
+ - **Purpose:** read local file content and include it in the context.
99
+ - **Supports glob patterns** (configure `data` as globs like `specs/**/*.md`).
100
+ - Internally, it reads each resolved path as UTF-8 and includes `{ filePath, content }` for file expansions.
112
101
 
113
- Loads matching files from your repo/workspace.
114
-
115
- - `data` is treated as a list of glob/path strings
116
- - Each file is:
117
- - checked to exist
118
- - verified not to be a directory
119
- - read as UTF-8
120
-
121
- **Example:**
122
-
123
- ```jsonc
102
+ Example:
103
+ ```json
124
104
  {
125
- "API, apis": {
105
+ "API": {
126
106
  "sources": [
127
- { "kind": "file", "data": ["docs/api/**/*.md", "specs/openapi*.{json,yaml}"] }
107
+ { "kind": "file", "data": [".knowhow/docs/api/**/*.md"] }
128
108
  ]
129
109
  }
130
110
  }
131
111
  ```
132
112
 
133
- > Tip: keep paths tight to avoid injecting huge irrelevant bundles.
113
+ > Tip: Prefer smaller “topic” files (or glob only within a narrow folder) to keep prompts readable.
134
114
 
135
115
  ---
136
116
 
137
- ### `text` — inline raw text
117
+ ### 4.2 `text` — inline raw text
118
+ - **Purpose:** embed static text directly in the configuration.
119
+ - No file IO or fetching.
138
120
 
139
- Injects literal text directly.
140
-
141
- **Example:**
142
-
143
- ```jsonc
121
+ Example:
122
+ ```json
144
123
  {
145
- "review rubric": {
124
+ "triage": {
146
125
  "sources": [
147
126
  {
148
127
  "kind": "text",
149
- "data": "Review checklist:\n- correctness\n- edge cases\n- performance\n- tests\n- migration plan\n"
128
+ "data": "Triage checklist:\n1) Identify user impact\n2) Repro steps\n3) Logs/metrics\n4) Proposed fix area\n5) Risk assessment"
150
129
  }
151
130
  ]
152
131
  }
@@ -155,37 +134,39 @@ Injects literal text directly.
155
134
 
156
135
  ---
157
136
 
158
- ### `github` — loads GitHub PR/issue/file content
159
-
160
- This is resolved through the **GitHub plugin** mechanism. In the language config, you specify what you want loaded via `data`.
137
+ ### 4.3 `github` — load GitHub PR/issue/file content
138
+ - **Purpose:** fetch and include GitHub content.
139
+ - **Implemented via the `github` plugin.**
140
+ - The Language Plugin does not parse GitHub URLs itself; it **hands off the `data`** to the enabled plugin matching the `kind`.
161
141
 
162
- **Example (conceptual locator payloads):**
142
+ So `kind: "github"` means: *“call the `github` plugin with these selectors/identifiers.”*
163
143
 
164
- ```jsonc
144
+ Example:
145
+ ```json
165
146
  {
166
- "my PR, current PR": {
147
+ "my PR": {
167
148
  "sources": [
168
- { "kind": "github", "data": ["CURRENT_PR"] }
149
+ { "kind": "github", "data": ["pr:current", "repo:my-org/my-repo"] }
169
150
  ]
170
151
  }
171
152
  }
172
153
  ```
173
154
 
174
- > The exact `github` payload format depends on your GitHub plugin configuration, but the language plugin will delegate fetching/injection to that plugin.
155
+ > Use the selector format your `github` plugin expects (commonly things like `pr:<number>`, `issue:<number>`, repo selectors, or URL strings).
175
156
 
176
157
  ---
177
158
 
178
- ### `url` — fetches a web URL
179
-
180
- Resolved via the **URL plugin**. You provide the URL(s) in `data`.
159
+ ### 4.4 `url` — fetch web content
160
+ - **Purpose:** fetch a URL and include its contents.
161
+ - **Implemented via the `url` plugin.**
162
+ - Like `github`, the Language Plugin delegates to the enabled plugin where `kind === plugin key`.
181
163
 
182
- **Example:**
183
-
184
- ```jsonc
164
+ Example:
165
+ ```json
185
166
  {
186
- "k8s docs": {
167
+ "security model": {
187
168
  "sources": [
188
- { "kind": "url", "data": ["https://kubernetes.io/docs/home/"] }
169
+ { "kind": "url", "data": ["https://example.com/security/model"] }
189
170
  ]
190
171
  }
191
172
  }
@@ -193,251 +174,244 @@ Resolved via the **URL plugin**. You provide the URL(s) in `data`.
193
174
 
194
175
  ---
195
176
 
177
+ ### How other `kind` values work
178
+ The Language Plugin treats any `kind` that matches an **enabled plugin key** as a delegated call. In other words, besides `file` and `text`, your `kind` values typically should correspond to the plugin names you enabled in `.knowhow/knowhow.json` (the default enables `github` and `url`).
179
+
180
+ ---
181
+
196
182
  ## 5) Event-driven triggers (`events` field)
197
183
 
198
- If you want terms to expand based on file activity (open/save), include an **`events`** array on the term.
184
+ The Language Plugin can trigger context expansions not just from chat text, but also from **events**.
199
185
 
200
- Typical usage:
186
+ ### 5.1 What `events` does
187
+ In the Language Plugin constructor, it:
201
188
 
202
- ```jsonc
189
+ 1. loads `.knowhow/language.json`
190
+ 2. collects all unique event names from all terms’ `events`
191
+ 3. registers handlers:
192
+ - events starting with `"file"` → special file handler
193
+ - everything else → generic handler
194
+
195
+ ### 5.2 Common patterns
196
+ Even though event names are configured by your environment, the code clearly distinguishes:
197
+
198
+ - **File events:** anything like `file:*`
199
+ - matching uses file path + file content
200
+ - good for “while I edit this area, always bring these docs”
201
+
202
+ - **Non-file events:** anything else (e.g. agent messages)
203
+ - matching uses the event payload serialized as JSON (`JSON.stringify(eventData)`)
204
+
205
+ ### Example: trigger when saving frontend files
206
+ ```json
203
207
  {
204
- "OpenAPI, swagger": {
205
- "events": ["file:open", "file:save"],
208
+ "frontend": {
209
+ "events": ["file:save", "file:open"],
206
210
  "sources": [
207
- { "kind": "file", "data": ["specs/openapi*.yaml", "specs/openapi*.json"] }
211
+ { "kind": "file", "data": [".knowhow/docs/frontend-architecture.md"] }
208
212
  ]
209
213
  }
210
214
  }
211
215
  ```
212
216
 
213
- ### How it behaves
214
- - Knowhow collects all event types referenced in `events`
215
- - When those events occur, it:
216
- - filters terms to those that include the active event
217
- - runs matching against file path and (optionally) file contents
218
- - injects the configured sources
217
+ When you open/save frontend files, the term can auto-inject the architecture doc.
219
218
 
220
219
  ---
221
220
 
222
221
  ## 6) Practical examples (full config snippets)
223
222
 
224
- Below are copy/paste-friendly examples you can adapt.
225
-
226
- > Put these entries into `./.knowhow/language.json`.
223
+ Below are real-world, copy/paste-ready examples. You can combine multiple terms in the same `language.json`.
227
224
 
228
225
  ---
229
226
 
230
- ### Example A — Load frontend/backend architecture docs when you say “frontend” or “backend”
227
+ ### Example A — Load frontend/backend architecture docs for “frontend” / “backend”
231
228
 
232
- ```jsonc
229
+ ```json
233
230
  {
234
- "frontend, ui, web": {
231
+ "frontend": {
235
232
  "sources": [
236
- { "kind": "file", "data": ["docs/architecture/frontend/**/*.md", "docs/architecture/web-frontend.md"] },
237
233
  {
238
- "kind": "text",
239
- "data": "Frontend conventions:\n- Prefer feature-based folder structure\n- Keep API calls in data layer\n- Use typed DTOs\n"
234
+ "kind": "file",
235
+ "data": [".knowhow/docs/architecture/frontend-architecture.md"]
240
236
  }
241
237
  ]
242
238
  },
243
-
244
- "backend, api, service": {
239
+ "backend": {
245
240
  "sources": [
246
- { "kind": "file", "data": ["docs/architecture/backend/**/*.md", "docs/architecture/services/**/*.md"] },
247
241
  {
248
- "kind": "text",
249
- "data": "Backend conventions:\n- Validate at boundaries\n- Prefer idempotent endpoints when possible\n- Log correlation IDs\n"
242
+ "kind": "file",
243
+ "data": [".knowhow/docs/architecture/backend-architecture.md"]
250
244
  }
251
245
  ]
252
246
  }
253
247
  }
254
248
  ```
255
249
 
256
- **Workflow payoff**
257
- - Ask: “How does auth work in the frontend?”Knowhow injects frontend architecture docs automatically.
258
- - Ask: “Where should we implement input validation in backend?” Knowhow injects backend guidance.
250
+ **Workflow:**
251
+ - Say **“frontend”**the frontend architecture doc is injected
252
+ - Say **“backend”** the backend architecture doc is injected
259
253
 
260
254
  ---
261
255
 
262
256
  ### Example B — Load your current PR when you say “my PR”
263
257
 
264
- ```jsonc
258
+ ```json
265
259
  {
266
- "my PR, current PR, pr": {
260
+ "my PR": {
267
261
  "sources": [
268
- { "kind": "github", "data": ["CURRENT_PR"] },
269
262
  {
270
- "kind": "text",
271
- "data": "Review approach:\n- Summarize intent\n- Identify risks (correctness, security, perf)\n- Suggest tests and rollback strategy\n"
263
+ "kind": "github",
264
+ "data": ["pr:current"]
265
+ },
266
+ {
267
+ "kind": "file",
268
+ "data": [".knowhow/docs/pr-review-checklist.md"]
272
269
  }
273
270
  ]
274
271
  }
275
272
  }
276
273
  ```
277
274
 
278
- **Workflow payoff**
279
- - “Review my PR for concurrency issues and test coverage.”
280
- - “Summarize changes + highlight any breaking behavior.”
275
+ **Workflow:**
276
+ - You ask: Can you review my PR for risk and edge cases?”
277
+ - The plugin injects:
278
+ - your PR content (via `github` plugin)
279
+ - a review checklist (via `file` kind)
280
+
281
+ > If `pr:current` isn’t supported in your setup, replace it with whatever your `github` plugin accepts (e.g. `pr:123`, or `https://github.com/org/repo/pull/123`).
281
282
 
282
283
  ---
283
284
 
284
- ### Example C — Load a spec file when you mention a feature name (wildcards)
285
+ ### Example C — Load a spec file when you mention a feature name
285
286
 
286
- Assume specs are organized like:
287
+ Assume you keep specs under:
288
+ - `specs/features/<feature-name>/spec.md`
287
289
 
288
- ```text
289
- specs/features/<feature>.md
290
- specs/features/<feature>/openapi*.yaml
291
- ```
290
+ Use globs so the term can map to the right file(s):
292
291
 
293
- ```jsonc
292
+ ```json
294
293
  {
295
- "feature search, search feature": {
294
+ "payments, payment-processing": {
296
295
  "sources": [
297
- { "kind": "file", "data": ["specs/features/search.md", "specs/features/search/**/*.md"] }
296
+ {
297
+ "kind": "file",
298
+ "data": ["specs/features/payments/spec.md"]
299
+ }
298
300
  ]
299
301
  },
300
-
301
- "payments*, payment*": {
302
+ "search": {
302
303
  "sources": [
303
- { "kind": "file", "data": ["specs/features/payments*.md", "specs/features/payments/**/openapi*.{yaml,json}"] },
304
- { "kind": "text", "data": "Focus for payments:\n- retries & idempotency\n- refund/reconciliation flows\n- edge cases\n" }
304
+ {
305
+ "kind": "file",
306
+ "data": ["specs/features/search/**/*.md"]
307
+ }
305
308
  ]
306
309
  }
307
310
  }
308
311
  ```
309
312
 
310
- **How it works**
311
- - `payments*` includes `*`, so it matches using wildcard/glob logic.
312
- - `feature search` is a plain substring hotphrase.
313
-
314
- **Workflow payoff**
315
- - “Explain the payments retry strategy.” → injects payments specs automatically.
313
+ **Workflow:**
314
+ - “Explain the payments flow” loads payments spec(s)
315
+ - “What’s the intended behavior for search?” loads search spec(s)
316
316
 
317
317
  ---
318
318
 
319
- ### Example D — Load API docs when you say “API”
319
+ ### Example D — Load API docs when you say “API” (and optionally “endpoints”, “REST”, etc.)
320
320
 
321
- ```jsonc
321
+ ```json
322
322
  {
323
- "API, apis, api documentation": {
323
+ "API, api, rest*, endpoints*": {
324
324
  "sources": [
325
- { "kind": "file", "data": ["docs/api/**/*.md", "docs/api/**/*.mdx"] },
326
- { "kind": "file", "data": ["specs/openapi*.json", "specs/openapi*.yaml"] },
327
325
  {
328
- "kind": "text",
329
- "data": "API answering guidelines:\n- Prefer documented behavior\n- Include request/response schema notes\n- Call out auth and error codes\n- Mention rate limits and pagination\n"
326
+ "kind": "file",
327
+ "data": [".knowhow/docs/api/**/*.md"]
330
328
  }
331
329
  ]
332
330
  }
333
331
  }
334
332
  ```
335
333
 
336
- **Workflow payoff**
337
- - “What’s the contract for POST /sessions and what errors can it return?”
338
- - “How do I authenticate for the payments endpoints?”
334
+ **Matching behavior examples:**
335
+ - Saying API” or “api” triggers via substring match.
336
+ - Saying endpoints v2” can trigger via patterns like `endpoints*`.
339
337
 
340
338
  ---
341
339
 
342
340
  ### Example E — Load environment info when you say “prod” or “staging”
343
341
 
344
- ```jsonc
342
+ Keep environment runbooks locally:
343
+
344
+ ```json
345
345
  {
346
- "prod, production, live": {
346
+ "prod, production": {
347
+ "events": ["file:open", "file:save"],
347
348
  "sources": [
348
- { "kind": "file", "data": ["ops/runbooks/prod/**/*.md"] },
349
- { "kind": "file", "data": ["ops/env/prod.env.example", "ops/env/prod.*.example"] },
350
- { "kind": "url", "data": ["https://status.yourcompany.com/"] }
349
+ { "kind": "file", "data": [".knowhow/env/prod-runbook.md"] },
350
+ { "kind": "file", "data": [".knowhow/env/prod-env-variables.md"] }
351
351
  ]
352
352
  },
353
-
354
- "staging, stage, preprod": {
353
+ "staging, stage": {
355
354
  "sources": [
356
- { "kind": "file", "data": ["ops/runbooks/staging/**/*.md"] },
357
- { "kind": "file", "data": ["ops/env/staging.env.example"] }
355
+ { "kind": "file", "data": [".knowhow/env/staging-runbook.md"] }
358
356
  ]
359
357
  }
360
358
  }
361
359
  ```
362
360
 
363
- **Workflow payoff**
364
- - “How do we roll out this change to prod safely?”
365
- - “What’s the rollback procedure for staging failures?”
361
+ **Workflow:**
362
+ - Ask Is this safe to roll out to prod?” injects prod runbook + env vars.
363
+ - Say staging” while working on deployment-related files → brings staging context.
366
364
 
367
365
  ---
368
366
 
369
- ## 7) Dynamic language terms (runtime): `addLanguageTerm` tool
370
-
371
- Static `.knowhow/language.json` is great, but sometimes you want **temporary terms** created at runtime—for example:
372
- - “incident-123” should load the incident doc
373
- - “release candidate 1.2.3” should load the right notes
374
- - “my PR” should load the PR for the current branch/selection
375
-
376
- Knowhow provides an `addLanguageTerm` capability to add language terms during execution.
377
-
378
- ### Typical pattern (conceptual)
379
- 1. Call `addLanguageTerm` with:
380
- - the term key
381
- - its sources (kind/data)
382
- - optional `events`
383
- 2. The new term becomes matchable immediately
384
- 3. Next user message can trigger it
385
-
386
- **Example (conceptual)**
387
- ```ts
388
- addLanguageTerm({
389
- key: "incident-123",
390
- sources: [
391
- { kind: "file", data: ["ops/incidents/incident-123.md"] }
392
- ]
393
- });
394
- ```
367
+ ## 7) Dynamic language terms (runtime)
395
368
 
396
- **Workflow payoff**
397
- - During an incident response flow, you can dynamically register terms so the agent always references the correct incident/runbook material.
369
+ The guide mentions an `addLanguageTerm` tool. While it’s not shown in the provided plugin source, the intended workflow is:
398
370
 
399
- > Exact tool argument shapes vary by environment, but the core idea is: **runtime registration of term sources**.
371
+ - Add new terms **at runtime** (e.g. term = feature name, term = ticket title, term = customer name)
372
+ - Knowhow persists them into your local language config (commonly `.knowhow/language.json`)
373
+ - Subsequent messages immediately benefit from the new hotword mappings
374
+
375
+ **Common use cases:**
376
+ - Add “ACME widget” → map it to the widget spec file URL/path.
377
+ - Add “Jira ABC-123” → map it to an issue link or local sprint notes.
378
+ - Add “Release 2026-05” → map it to a release checklist.
379
+
380
+ Example conceptual usage (tool name/arguments may vary in your installation):
381
+ - Call `addLanguageTerm(term="my-customer", sources=[...])`
382
+ - Then say “my-customer” in chat to trigger expansions.
383
+
384
+ > If you tell me the exact `addLanguageTerm` tool signature available in your Knowhow version, I can provide a precise snippet.
400
385
 
401
386
  ---
402
387
 
403
388
  ## 8) Global vs local language config
404
389
 
405
- ### Local (project) config
406
- - Active config for term matching:
407
- - `./.knowhow/language.json`
390
+ ### What Knowhow loads for language terms
391
+ From the code:
392
+ - `getLanguageConfig()` reads **only**: `.knowhow/language.json`
408
393
 
409
- ### Global config
410
- - Your Knowhow installation may create a template at:
411
- - `~/.knowhow/language.json`
412
- - Whether it is merged automatically depends on your Knowhow version/config behavior.
394
+ So in practice:
413
395
 
414
- ### Recommended practice
415
- - Put **project/team-specific** rules in `./.knowhow/language.json`
416
- - architecture docs
417
- - feature specs
418
- - environment runbooks
419
- - repo-specific review rubrics
420
- - If you maintain global defaults, keep them **broad and non-conflicting**
421
- - e.g., standard “review rubric”, “testing strategy”, “security checklist”
396
+ - **Local language terms** in `.knowhow/language.json` are what the Language Plugin uses.
397
+ - The **global template** `~/.knowhow/language.json` may be created during `knowhow init`, but it is not directly read by the Language Plugin in the shown implementation.
422
398
 
423
- **Tip:** avoid overly broad patterns like `"api"` if other teams/tools use the same word differently—prefer `"API,"` or `"api docs"`.
399
+ ### Recommended workflow
400
+ - Use `knowhow init` to generate the local `.knowhow/language.json`
401
+ - Edit **local** terms per project
402
+ - Keep environment-specific terms (prod/staging, feature specs, architecture docs) in that local file
424
403
 
425
404
  ---
426
405
 
427
- ## Best practices (real-world)
406
+ ## Summary: why teams love this
428
407
 
429
- - **Target sources tightly**
430
- - A “frontend” term that injects *every* frontend file can overwhelm answers.
431
- - **Use globs intentionally**
432
- - Great: `payments*`, `openapi*`, `docs/api/**/*.md`
433
- - Risky: `*` or extremely short substrings that match too often
434
- - **Use `events` for file-driven workflows**
435
- - Example: expand API spec context only when editing OpenAPI files.
436
- - **Layer sources**
437
- - Combine `file` (authoritative docs) + `text` (answering rules)
438
- - **Prefer human hotphrases**
439
- - `my PR`, `release notes`, `prod rollback`, `incident <id>`
408
+ With a well-tuned `.knowhow/language.json`, developers can:
440
409
 
441
- ---
410
+ - Reduce “where is the doc?” interruptions
411
+ - Guarantee consistent architecture context (frontend/backend)
412
+ - Speed up PR review by pulling PR content + checklists automatically
413
+ - Tie feature names/ticket identifiers to specs
414
+ - Make environment questions (prod/staging) immediately grounded in runbooks
415
+ - Trigger expansions automatically while editing relevant files via `events`
442
416
 
443
- If you paste your current directory structure (or a redacted `.knowhow/language.json`), I can propose an optimized set of term keys + globs tailored to your repo and workflows.
417
+ If you share your current `language.json` (or your repo’s docs layout), I can propose an optimized set of terms and globs tailored to your workflow.