thoth-plugin 1.2.0 → 1.2.2

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 (69) hide show
  1. package/README.md +16 -0
  2. package/defaults/AGENTS.md +53 -0
  3. package/{dist/defaults/skill → defaults/skill/_legacy}/gardener/SKILL.md +243 -17
  4. package/defaults/skill/_legacy/onboarding/SKILL.md +207 -0
  5. package/defaults/skill/evening-close/SKILL.md +97 -0
  6. package/defaults/skill/mail-triage/SKILL.md +26 -0
  7. package/defaults/skill/morning-boot/SKILL.md +45 -0
  8. package/defaults/skill/slack-pulse/SKILL.md +26 -0
  9. package/defaults/skill/thought-router/SKILL.md +89 -0
  10. package/dist/cli.d.ts +0 -8
  11. package/dist/cli.js +70 -436
  12. package/dist/config/index.d.ts +1 -1
  13. package/dist/config/schema.d.ts +17 -0
  14. package/dist/defaults/skill/_legacy/cal-grid/SKILL.md +16 -0
  15. package/dist/defaults/skill/_legacy/capsule-init/SKILL.md +102 -0
  16. package/dist/defaults/skill/_legacy/cross-linker/SKILL.md +357 -0
  17. package/dist/defaults/skill/_legacy/email-draft/skill.md +134 -0
  18. package/dist/defaults/skill/_legacy/gardener/SKILL.md +509 -0
  19. package/dist/defaults/skill/_legacy/gardener/confidence-tiers.md +142 -0
  20. package/dist/defaults/skill/_legacy/gardener/repair-workflow.md +170 -0
  21. package/dist/defaults/skill/_legacy/google-chat-scan/SKILL.md +135 -0
  22. package/dist/defaults/skill/_legacy/handover/SKILL.md +18 -0
  23. package/dist/defaults/skill/_legacy/interview-prep/SKILL.md +23 -0
  24. package/dist/defaults/skill/_legacy/leadership-coach/SKILL.md +167 -0
  25. package/dist/defaults/skill/_legacy/link-retrofit/SKILL.md +345 -0
  26. package/dist/defaults/skill/_legacy/onboarding/SKILL.md +207 -0
  27. package/dist/defaults/skill/_legacy/post-meeting-drill/SKILL.md +485 -0
  28. package/dist/defaults/skill/_legacy/restore-environment/SKILL.md +30 -0
  29. package/dist/defaults/skill/_legacy/scorecard-synthesis/SKILL.md +26 -0
  30. package/dist/defaults/skill/_legacy/skill-generator/SKILL.md +362 -0
  31. package/dist/defaults/skill/_legacy/skill-generator/testing-protocol.md +158 -0
  32. package/dist/defaults/skill/_legacy/system-init/SKILL.md +103 -0
  33. package/dist/defaults/skill/evening-close/SKILL.md +6 -7
  34. package/dist/defaults/skill/mail-triage/SKILL.md +11 -8
  35. package/dist/defaults/skill/morning-boot/SKILL.md +26 -87
  36. package/dist/defaults/skill/slack-pulse/SKILL.md +11 -7
  37. package/dist/defaults/skill/thought-router/SKILL.md +10 -8
  38. package/dist/index.js +11316 -2308
  39. package/dist/schemas/skill.d.ts +96 -0
  40. package/dist/sdk/index.d.ts +4 -0
  41. package/dist/sdk/sentinel-service.d.ts +71 -0
  42. package/dist/sdk/skill-runner.d.ts +21 -0
  43. package/dist/sdk/thoth-client.d.ts +51 -0
  44. package/dist/sdk/workflows/calendar-watcher.d.ts +2 -0
  45. package/dist/sdk/workflows/inbox-watcher.d.ts +2 -0
  46. package/dist/sdk/workflows/index.d.ts +4 -0
  47. package/dist/sdk/workflows/system-watcher.d.ts +2 -0
  48. package/dist/sdk/workflows/task-watcher.d.ts +2 -0
  49. package/dist/services/index.d.ts +1 -0
  50. package/dist/services/skill-registry.d.ts +23 -0
  51. package/dist/tools/skill/tools.d.ts +2 -1
  52. package/package.json +8 -3
  53. /package/{dist/defaults/skill → defaults/skill/_legacy}/cal-grid/SKILL.md +0 -0
  54. /package/{dist/defaults/skill → defaults/skill/_legacy}/capsule-init/SKILL.md +0 -0
  55. /package/{dist/defaults/skill → defaults/skill/_legacy}/cross-linker/SKILL.md +0 -0
  56. /package/{dist/defaults/skill → defaults/skill/_legacy}/email-draft/skill.md +0 -0
  57. /package/{dist/defaults/skill → defaults/skill/_legacy}/gardener/confidence-tiers.md +0 -0
  58. /package/{dist/defaults/skill → defaults/skill/_legacy}/gardener/repair-workflow.md +0 -0
  59. /package/{dist/defaults/skill → defaults/skill/_legacy}/google-chat-scan/SKILL.md +0 -0
  60. /package/{dist/defaults/skill → defaults/skill/_legacy}/handover/SKILL.md +0 -0
  61. /package/{dist/defaults/skill → defaults/skill/_legacy}/interview-prep/SKILL.md +0 -0
  62. /package/{dist/defaults/skill → defaults/skill/_legacy}/leadership-coach/SKILL.md +0 -0
  63. /package/{dist/defaults/skill → defaults/skill/_legacy}/link-retrofit/SKILL.md +0 -0
  64. /package/{dist/defaults/skill → defaults/skill/_legacy}/post-meeting-drill/SKILL.md +0 -0
  65. /package/{dist/defaults/skill → defaults/skill/_legacy}/restore-environment/SKILL.md +0 -0
  66. /package/{dist/defaults/skill → defaults/skill/_legacy}/scorecard-synthesis/SKILL.md +0 -0
  67. /package/{dist/defaults/skill → defaults/skill/_legacy}/skill-generator/SKILL.md +0 -0
  68. /package/{dist/defaults/skill → defaults/skill/_legacy}/skill-generator/testing-protocol.md +0 -0
  69. /package/{dist/defaults/skill → defaults/skill/_legacy}/system-init/SKILL.md +0 -0
package/dist/cli.js CHANGED
@@ -2,462 +2,96 @@
2
2
  // @bun
3
3
 
4
4
  // src/cli.ts
5
- import {
6
- existsSync,
7
- mkdirSync,
8
- cpSync,
9
- writeFileSync,
10
- readFileSync,
11
- readdirSync
12
- } from "fs";
13
- import { join, dirname } from "path";
5
+ import { existsSync, mkdirSync, cpSync, writeFileSync } from "fs";
6
+ import { join, resolve } from "path";
14
7
  import { homedir } from "os";
15
- import { fileURLToPath } from "url";
16
- import { createInterface } from "readline";
17
- import { createHash } from "crypto";
18
- var __filename2 = fileURLToPath(import.meta.url);
19
- var __dirname2 = dirname(__filename2);
20
- var NPM_DEFAULTS_PATH = join(__dirname2, "defaults");
21
- function prompt(question) {
22
- const rl = createInterface({
23
- input: process.stdin,
24
- output: process.stdout
25
- });
26
- return new Promise((resolve) => {
27
- rl.question(question, (answer) => {
28
- rl.close();
29
- resolve(answer.trim().toLowerCase());
30
- });
31
- });
32
- }
33
- function hashFile(filePath) {
34
- if (!existsSync(filePath))
35
- return "";
36
- const content = readFileSync(filePath, "utf-8");
37
- return createHash("md5").update(content).digest("hex");
38
- }
39
- function countLines(filePath) {
40
- if (!existsSync(filePath))
41
- return 0;
42
- return readFileSync(filePath, "utf-8").split(`
43
- `).length;
44
- }
45
- var README_TEMPLATE = `# Thoth Knowledge Base
8
+ var __dirname = "/Users/davidhelmus/Repos/thoth/thoth-core/src";
9
+ var KNOWLEDGE_BASE_TEMPLATE = `
10
+ # Thoth Knowledge Base
46
11
 
47
- Welcome to your personal Thoth knowledge base - your AI chief of staff for life orchestration.
12
+ Welcome to your personal Thoth knowledge base.
48
13
 
49
14
  ## Structure
50
15
 
51
- | Hemisphere | Purpose |
52
- |------------|---------|
53
- | \`work/\` | Professional life - projects, colleagues, career |
54
- | \`life/\` | Personal life - health, relationships, home, finance |
55
- | \`coding/\` | Technical projects and development |
56
- | \`kernel/\` | System configuration and preferences |
57
-
58
- ## Getting Started
59
-
60
- 1. Start OpenCode in this directory:
61
- \`\`\`bash
62
- cd ${process.argv[3] || "~/thoth"}
63
- opencode
64
- \`\`\`
65
-
66
- 2. Ask Thoth to help you onboard:
67
- \`\`\`
68
- Help me set up my knowledge base
69
- \`\`\`
70
-
71
- 3. Or run the onboarding skill:
72
- \`\`\`
73
- /system-init
74
- \`\`\`
16
+ - **work/** - Professional life (projects, people, logs)
17
+ - **life/** - Personal life (health, finance, home)
18
+ - **coding/** - Technical projects and inventory
19
+ - **kernel/** - System configuration and agents
75
20
 
76
- ## Available Skills
21
+ ## Operating Modes
77
22
 
78
- Run these skills to automate common workflows:
23
+ Thoth adapts based on where you start the session:
79
24
 
80
- | Skill | Description |
81
- |-------|-------------|
82
- | \`/morning-boot\` | Start your day with inbox triage and calendar review |
83
- | \`/evening-close\` | End-of-day summary and overflow extraction |
84
- | \`/mail-triage\` | Process Gmail inbox systematically |
85
- | \`/slack-pulse\` | Scan Slack for mentions and important messages |
86
- | \`/thought-router\` | Quick capture and route thoughts |
87
- | \`/post-meeting-drill\` | Process meeting notes into action items |
25
+ - **Root Mode**: \`cd ~/thoth\`
26
+ - Generic orchestrator, routing, system maintenance.
27
+ - **Work Mode**: \`cd ~/thoth/work\`
28
+ - Professional Chief of Staff. P0 focus. Deep work context.
29
+ - **Life Mode**: \`cd ~/thoth/life\`
30
+ - Personal consultant. Health, finance, relationships.
31
+ - **Code Mode**: \`cd ~/thoth/coding\`
32
+ - Technical architect. Codebase analysis.
88
33
 
89
- ## Configuration
90
-
91
- Configure Thoth in \`.opencode/thoth-plugin.json\`:
92
-
93
- \`\`\`json
94
- {
95
- "knowledge_base": "${process.argv[3] || "~/thoth"}"
96
- }
97
- \`\`\`
34
+ ## Getting Started
98
35
 
99
- ## Learn More
36
+ 1. Start OpenCode in the desired context:
37
+ \`cd ~/thoth && opencode\`
100
38
 
101
- - Ask: "What can you help me with?"
102
- - Ask: "Explain how Thoth works"
103
- - Ask: "What skills are available?"
39
+ 2. Ask Thoth: "Help me onboard"
104
40
  `;
105
- function copyDefaultSkills(targetSkillDir) {
106
- const sourceSkillDir = join(NPM_DEFAULTS_PATH, "skill");
107
- if (!existsSync(sourceSkillDir)) {
108
- console.log(" (No default skills found in package)");
109
- return;
110
- }
111
- const skills = readdirSync(sourceSkillDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
112
- for (const skill of skills) {
113
- const source = join(sourceSkillDir, skill);
114
- const target = join(targetSkillDir, skill);
115
- cpSync(source, target, { recursive: true });
116
- }
117
- console.log(` Copied ${skills.length} default skills`);
118
- }
119
- function init(targetPath) {
120
- const targetDir = targetPath || join(homedir(), "thoth");
41
+ function init() {
42
+ const targetDir = process.argv[3] || join(homedir(), "thoth");
121
43
  if (existsSync(targetDir)) {
122
- console.log(`
123
- Error: Directory already exists: ${targetDir}`);
124
- console.log("Use a different path or remove the existing directory.");
125
- console.log(`
126
- Example:`);
127
- console.log(` npx thoth-plugin init ~/my-thoth`);
44
+ console.log(`Directory already exists: ${targetDir}`);
45
+ console.log("Use a different path or remove existing directory.");
128
46
  process.exit(1);
129
47
  }
130
- console.log(`
131
- Creating Thoth knowledge base at: ${targetDir}
132
- `);
133
- const dirs = [
134
- "work/projects",
135
- "work/people",
136
- "work/inbox",
137
- "work/logs",
138
- "life/inbox",
139
- "life/health",
140
- "life/relationships",
141
- "life/finances",
142
- "coding/projects",
143
- "coding/references",
144
- "kernel/config",
145
- "kernel/templates",
146
- "kernel/memory",
147
- "kernel/Personas",
148
- ".opencode/skill"
149
- ];
150
- for (const dir of dirs) {
151
- mkdirSync(join(targetDir, dir), { recursive: true });
152
- }
153
- console.log(" Created directory structure");
154
- const defaultAgentsMd = join(NPM_DEFAULTS_PATH, "AGENTS.md");
155
- if (existsSync(defaultAgentsMd)) {
156
- cpSync(defaultAgentsMd, join(targetDir, "AGENTS.md"));
157
- console.log(" Copied root AGENTS.md");
158
- }
159
- copyDefaultSkills(join(targetDir, ".opencode", "skill"));
160
- writeFileSync(join(targetDir, "README.md"), README_TEMPLATE);
161
- console.log(" Created README.md");
162
- writeFileSync(join(targetDir, "kernel", "config", "preferences.md"), `---
163
- type: config
164
- hemisphere: kernel
165
- created: ${new Date().toISOString().split("T")[0]}
166
- updated: ${new Date().toISOString().split("T")[0]}
167
- ---
168
-
169
- # Preferences
170
-
171
- Your personal preferences for Thoth.
172
-
173
- ## Communication Style
174
-
175
- - Default: balanced (not too verbose, not too terse)
176
-
177
- ## Timezone
178
-
179
- - Default: auto-detect
180
-
181
- ## Work Hours
182
-
183
- - Default: 9:00 - 18:00
184
-
185
- ---
186
-
187
- *Edit this file to customize Thoth's behavior.*
188
- `);
189
- console.log(" Created kernel/config/preferences.md");
190
- const hemispheres = ["work", "life", "coding", "kernel"];
191
- for (const hemi of hemispheres) {
192
- writeFileSync(join(targetDir, hemi, "registry.md"), `---
193
- type: registry
194
- hemisphere: ${hemi}
195
- created: ${new Date().toISOString().split("T")[0]}
196
- updated: ${new Date().toISOString().split("T")[0]}
197
- ---
198
-
199
- # ${hemi.charAt(0).toUpperCase() + hemi.slice(1)} Registry
200
-
201
- Index of all knowledge in the ${hemi} hemisphere.
202
-
203
- ## Contents
204
-
205
- *This registry will be populated as you add knowledge.*
206
- `);
207
- }
208
- console.log(" Created hemisphere registries");
209
- console.log(`
210
- \u2713 Knowledge base created!
211
- `);
212
- console.log("Next steps:");
213
- console.log(` 1. cd ${targetDir}`);
214
- console.log(" 2. opencode");
215
- console.log(` 3. Ask: "Help me onboard"
216
- `);
217
- }
218
- function findKbPath(startPath) {
219
- const searchPaths = [
220
- startPath,
221
- process.cwd(),
222
- join(process.cwd(), ".."),
223
- join(homedir(), "thoth")
224
- ].filter(Boolean);
225
- for (const basePath of searchPaths) {
226
- const skillPath = join(basePath, ".opencode", "skill");
227
- if (existsSync(skillPath)) {
228
- return basePath;
48
+ console.log(`Creating Thoth knowledge base at: ${targetDir}`);
49
+ try {
50
+ mkdirSync(join(targetDir, "work", "projects"), { recursive: true });
51
+ mkdirSync(join(targetDir, "work", "people"), { recursive: true });
52
+ mkdirSync(join(targetDir, "work", "inbox"), { recursive: true });
53
+ mkdirSync(join(targetDir, "work", "logs"), { recursive: true });
54
+ mkdirSync(join(targetDir, "life", "inbox"), { recursive: true });
55
+ mkdirSync(join(targetDir, "life", "areas"), { recursive: true });
56
+ mkdirSync(join(targetDir, "coding", "projects"), { recursive: true });
57
+ mkdirSync(join(targetDir, "coding", "inbox"), { recursive: true });
58
+ mkdirSync(join(targetDir, "kernel", "config"), { recursive: true });
59
+ mkdirSync(join(targetDir, "kernel", "templates"), { recursive: true });
60
+ mkdirSync(join(targetDir, "kernel", "Agents"), { recursive: true });
61
+ let npmDefaultsPath = resolve(__dirname, "..", "defaults");
62
+ if (!existsSync(npmDefaultsPath)) {
63
+ npmDefaultsPath = resolve(__dirname, "..", "..", "defaults");
229
64
  }
230
- }
231
- return null;
232
- }
233
- function compareSkills(localSkillDir) {
234
- const packageSkillDir = join(NPM_DEFAULTS_PATH, "skill");
235
- const results = [];
236
- if (!existsSync(packageSkillDir)) {
237
- console.log("Error: No skills found in package");
238
- return results;
239
- }
240
- const packageSkills = existsSync(packageSkillDir) ? readdirSync(packageSkillDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name) : [];
241
- const localSkills = existsSync(localSkillDir) ? readdirSync(localSkillDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name) : [];
242
- const allSkills = [...new Set([...packageSkills, ...localSkills])].sort();
243
- for (const skill of allSkills) {
244
- const localPath = join(localSkillDir, skill);
245
- const packagePath = join(packageSkillDir, skill);
246
- const localExists = existsSync(localPath);
247
- const packageExists = existsSync(packagePath);
248
- const localFile = localExists ? existsSync(join(localPath, "SKILL.md")) ? join(localPath, "SKILL.md") : join(localPath, "skill.md") : "";
249
- const packageFile = packageExists ? existsSync(join(packagePath, "SKILL.md")) ? join(packagePath, "SKILL.md") : join(packagePath, "skill.md") : "";
250
- const localHash = localFile ? hashFile(localFile) : "";
251
- const packageHash = packageFile ? hashFile(packageFile) : "";
252
- const localLines = localFile ? countLines(localFile) : 0;
253
- const packageLines = packageFile ? countLines(packageFile) : 0;
254
- let status;
255
- if (!localExists && packageExists) {
256
- status = "package-only";
257
- } else if (localExists && !packageExists) {
258
- status = "local-only";
259
- } else if (localHash === packageHash) {
260
- status = "identical";
261
- } else if (localLines > packageLines) {
262
- status = "local-newer";
65
+ if (existsSync(npmDefaultsPath)) {
66
+ console.log("Copying default skills and agents...");
67
+ const skillDest = join(targetDir, ".opencode", "skill");
68
+ mkdirSync(skillDest, { recursive: true });
69
+ cpSync(join(npmDefaultsPath, "skill"), skillDest, { recursive: true });
70
+ const agentsSrc = join(npmDefaultsPath, "AGENTS.md");
71
+ if (existsSync(agentsSrc)) {
72
+ cpSync(agentsSrc, join(targetDir, "AGENTS.md"));
73
+ }
263
74
  } else {
264
- status = "package-newer";
75
+ console.warn("Warning: Could not find defaults directory. Skills will not be pre-populated.");
265
76
  }
266
- results.push({
267
- name: skill,
268
- status,
269
- localLines: localLines || undefined,
270
- packageLines: packageLines || undefined,
271
- localHash: localHash || undefined,
272
- packageHash: packageHash || undefined
273
- });
274
- }
275
- return results;
276
- }
277
- async function skillUpdate(kbPath) {
278
- const basePath = findKbPath(kbPath);
279
- if (!basePath) {
280
- console.log(`
281
- Error: Could not find Thoth knowledge base.`);
282
- console.log("Run this command from your knowledge base directory, or specify the path:");
283
- console.log(` npx thoth-plugin skill update ~/thoth
284
- `);
77
+ writeFileSync(join(targetDir, "README.md"), KNOWLEDGE_BASE_TEMPLATE.trim());
78
+ console.log("\u2713 Knowledge base created!");
79
+ console.log("");
80
+ console.log("Next steps:");
81
+ console.log(`1. cd ${targetDir}`);
82
+ console.log("2. Start OpenCode");
83
+ console.log("3. Ask Thoth: 'Help me onboard'");
84
+ } catch (err) {
85
+ console.error("Failed to initialize knowledge base:", err);
285
86
  process.exit(1);
286
87
  }
287
- const localSkillDir = join(basePath, ".opencode", "skill");
288
- const packageSkillDir = join(NPM_DEFAULTS_PATH, "skill");
289
- console.log(`
290
- Comparing skills in: ${localSkillDir}
291
- `);
292
- const comparisons = compareSkills(localSkillDir);
293
- const identical = comparisons.filter((c) => c.status === "identical");
294
- const packageNewer = comparisons.filter((c) => c.status === "package-newer");
295
- const localNewer = comparisons.filter((c) => c.status === "local-newer");
296
- const packageOnly = comparisons.filter((c) => c.status === "package-only");
297
- const localOnly = comparisons.filter((c) => c.status === "local-only");
298
- console.log("Skill Status Summary:");
299
- console.log("\u2500".repeat(60));
300
- if (identical.length > 0) {
301
- console.log(`
302
- \u2713 Up to date (${identical.length}):`);
303
- identical.forEach((s) => console.log(` ${s.name}`));
304
- }
305
- if (packageNewer.length > 0) {
306
- console.log(`
307
- \u2193 Updates available (${packageNewer.length}):`);
308
- packageNewer.forEach((s) => console.log(` ${s.name} (local: ${s.localLines} lines \u2192 package: ${s.packageLines} lines)`));
309
- }
310
- if (localNewer.length > 0) {
311
- console.log(`
312
- \u2191 Local is more advanced (${localNewer.length}):`);
313
- localNewer.forEach((s) => console.log(` ${s.name} (local: ${s.localLines} lines vs package: ${s.packageLines} lines)`));
314
- }
315
- if (packageOnly.length > 0) {
316
- console.log(`
317
- + New skills available (${packageOnly.length}):`);
318
- packageOnly.forEach((s) => console.log(` ${s.name}`));
319
- }
320
- if (localOnly.length > 0) {
321
- console.log(`
322
- \u25CB Local only (${localOnly.length}):`);
323
- localOnly.forEach((s) => console.log(` ${s.name}`));
324
- }
325
- console.log(`
326
- ` + "\u2500".repeat(60));
327
- const toUpdate = [...packageNewer, ...packageOnly];
328
- if (toUpdate.length === 0) {
329
- console.log(`
330
- \u2713 All skills are up to date!
331
- `);
332
- return;
333
- }
334
- console.log(`
335
- ${toUpdate.length} skill(s) can be updated.
336
- `);
337
- for (const skill of toUpdate) {
338
- const action = skill.status === "package-only" ? "install" : "update";
339
- const answer = await prompt(`${action === "install" ? "Install" : "Update"} ${skill.name}? [y/N/q] `);
340
- if (answer === "q") {
341
- console.log(`
342
- Aborted.
343
- `);
344
- return;
345
- }
346
- if (answer === "y" || answer === "yes") {
347
- const source = join(packageSkillDir, skill.name);
348
- const target = join(localSkillDir, skill.name);
349
- cpSync(source, target, { recursive: true });
350
- console.log(` \u2713 ${skill.name} ${action}d`);
351
- } else {
352
- console.log(` \u25CB ${skill.name} skipped`);
353
- }
354
- }
355
- if (localNewer.length > 0) {
356
- console.log(`
357
- ` + "\u2500".repeat(60));
358
- console.log(`
359
- You have skills that are more advanced than the package.`);
360
- console.log(`Consider contributing them back to Thoth!
361
- `);
362
- for (const skill of localNewer) {
363
- const answer = await prompt(`Would you like to contribute ${skill.name} back to Thoth? [y/N] `);
364
- if (answer === "y" || answer === "yes") {
365
- console.log(`
366
- To contribute ${skill.name}:`);
367
- console.log(` 1. Fork https://github.com/davidhelmus/thoth-core`);
368
- console.log(` 2. Copy your skill to defaults/skill/${skill.name}/`);
369
- console.log(` 3. Open a Pull Request
370
- `);
371
- }
372
- }
373
- }
374
- console.log(`
375
- \u2713 Done!
376
- `);
377
- }
378
- function skillList(kbPath) {
379
- const basePath = findKbPath(kbPath);
380
- if (!basePath) {
381
- console.log(`
382
- Showing skills from package only (no knowledge base found).
383
- `);
384
- }
385
- const packageSkillDir = join(NPM_DEFAULTS_PATH, "skill");
386
- const localSkillDir = basePath ? join(basePath, ".opencode", "skill") : null;
387
- const packageSkills = existsSync(packageSkillDir) ? readdirSync(packageSkillDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name) : [];
388
- const localSkills = localSkillDir && existsSync(localSkillDir) ? readdirSync(localSkillDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name) : [];
389
- const allSkills = [...new Set([...packageSkills, ...localSkills])].sort();
390
- console.log(`
391
- Available Skills:`);
392
- console.log("\u2500".repeat(40));
393
- for (const skill of allSkills) {
394
- const inPackage = packageSkills.includes(skill);
395
- const inLocal = localSkills.includes(skill);
396
- let status = "";
397
- if (inPackage && inLocal)
398
- status = "\u2713";
399
- else if (inLocal)
400
- status = "\u25CB (local only)";
401
- else
402
- status = "+ (available)";
403
- console.log(` ${status} ${skill}`);
404
- }
405
- console.log(`
406
- `);
407
- }
408
- function showHelp() {
409
- console.log(`
410
- Thoth - Life Orchestrator for OpenCode
411
-
412
- Usage:
413
- npx thoth-plugin <command> [options]
414
-
415
- Commands:
416
- init [path] Create a new knowledge base (default: ~/thoth)
417
- skill update [path] Update skills from the latest package
418
- skill list List available skills
419
-
420
- Examples:
421
- npx thoth-plugin init # Create at ~/thoth
422
- npx thoth-plugin init ~/my-thoth # Create at custom path
423
- npx thoth-plugin skill update # Update skills in current KB
424
- npx thoth-plugin skill list # List all available skills
425
-
426
- Learn more: https://github.com/davidhelmus/thoth-core
427
- `);
428
88
  }
429
89
  var command = process.argv[2];
430
- var subcommand = process.argv[3];
431
- switch (command) {
432
- case "init":
433
- init(process.argv[3]);
434
- break;
435
- case "skill":
436
- switch (subcommand) {
437
- case "update":
438
- skillUpdate(process.argv[4]);
439
- break;
440
- case "list":
441
- skillList(process.argv[4]);
442
- break;
443
- default:
444
- console.log(`
445
- Unknown skill command: ${subcommand}`);
446
- console.log(`Available: skill update, skill list
447
- `);
448
- process.exit(1);
449
- }
450
- break;
451
- case "help":
452
- case "--help":
453
- case "-h":
454
- showHelp();
455
- break;
456
- default:
457
- showHelp();
458
- if (command && command !== "help") {
459
- console.log(`Unknown command: ${command}
460
- `);
461
- process.exit(1);
462
- }
90
+ if (command === "init") {
91
+ init();
92
+ } else {
93
+ console.log("Thoth - Life Orchestrator for OpenCode");
94
+ console.log("");
95
+ console.log("Commands:");
96
+ console.log(" thoth init [path] Create knowledge base (default: ~/thoth)");
463
97
  }
@@ -1 +1 @@
1
- export { ThothPluginConfigSchema, type ThothPluginConfig, type AgentOverride, type HooksConfig, type SkillsConfig, type IntegrationsConfig, type HookName, type SkillName, type AgentName, } from "./schema";
1
+ export { ThothPluginConfigSchema, type ThothPluginConfig, type AgentOverride, type HooksConfig, type SkillsConfig, type SentinelConfig, type IntegrationsConfig, type HookName, type SkillName, type AgentName, } from "./schema";
@@ -32,9 +32,25 @@ declare const IntegrationsConfigSchema: z.ZodObject<{
32
32
  jira: z.ZodOptional<z.ZodBoolean>;
33
33
  drive_sync: z.ZodOptional<z.ZodBoolean>;
34
34
  }, z.core.$strict>;
35
+ declare const SentinelConfigSchema: z.ZodObject<{
36
+ enabled: z.ZodOptional<z.ZodBoolean>;
37
+ poll_interval_ms: z.ZodOptional<z.ZodNumber>;
38
+ quiet_hours: z.ZodOptional<z.ZodObject<{
39
+ start: z.ZodString;
40
+ end: z.ZodString;
41
+ }, z.core.$strip>>;
42
+ }, z.core.$strict>;
35
43
  export declare const ThothPluginConfigSchema: z.ZodObject<{
36
44
  enabled: z.ZodOptional<z.ZodBoolean>;
37
45
  knowledge_base: z.ZodOptional<z.ZodString>;
46
+ sentinel: z.ZodOptional<z.ZodObject<{
47
+ enabled: z.ZodOptional<z.ZodBoolean>;
48
+ poll_interval_ms: z.ZodOptional<z.ZodNumber>;
49
+ quiet_hours: z.ZodOptional<z.ZodObject<{
50
+ start: z.ZodString;
51
+ end: z.ZodString;
52
+ }, z.core.$strip>>;
53
+ }, z.core.$strict>>;
38
54
  agents: z.ZodOptional<z.ZodObject<{
39
55
  thoth: z.ZodOptional<z.ZodObject<{
40
56
  model: z.ZodOptional<z.ZodString>;
@@ -98,6 +114,7 @@ export type ThothPluginConfig = z.infer<typeof ThothPluginConfigSchema>;
98
114
  export type AgentOverride = z.infer<typeof AgentOverrideSchema>;
99
115
  export type HooksConfig = z.infer<typeof HooksConfigSchema>;
100
116
  export type SkillsConfig = z.infer<typeof SkillsConfigSchema>;
117
+ export type SentinelConfig = z.infer<typeof SentinelConfigSchema>;
101
118
  export type IntegrationsConfig = z.infer<typeof IntegrationsConfigSchema>;
102
119
  export type HookName = keyof NonNullable<ThothPluginConfig["hooks"]>;
103
120
  export type SkillName = keyof NonNullable<ThothPluginConfig["skills"]>;
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: cal-grid
3
+ description: Map Zeus's daily calendar grid using the Thoth standard protocol. Identifies deep work slots and critical preparation needs.
4
+ ---
5
+
6
+ # Calendar Grid Skill
7
+
8
+ You are the Daily Grid Architect for Zeus's Chief of Staff.
9
+
10
+ ## Protocol Execution
11
+
12
+ 1. **Read Master Instructions**: Load the full protocol from `kernel/Agents/cal-grid.md`.
13
+ 2. **Execute**: Follow the protocol exactly as defined in the master file.
14
+ 3. **Synthesize**: Provide the high-resolution grid and the required raw data block.
15
+
16
+ **MANDATORY**: Ensure the output includes the `## SCAN_DATA_START` and `## SCAN_DATA_END` markers as specified in the master instructions.