thoth-plugin 1.2.1 → 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.
- package/README.md +16 -0
- package/defaults/AGENTS.md +53 -0
- package/defaults/skill/evening-close/SKILL.md +97 -0
- package/defaults/skill/mail-triage/SKILL.md +26 -0
- package/defaults/skill/morning-boot/SKILL.md +45 -0
- package/defaults/skill/slack-pulse/SKILL.md +26 -0
- package/defaults/skill/thought-router/SKILL.md +89 -0
- package/dist/cli.d.ts +0 -8
- package/dist/cli.js +70 -436
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema.d.ts +17 -0
- package/dist/defaults/skill/_legacy/cal-grid/SKILL.md +16 -0
- package/dist/defaults/skill/_legacy/capsule-init/SKILL.md +102 -0
- package/dist/defaults/skill/_legacy/cross-linker/SKILL.md +357 -0
- package/dist/defaults/skill/_legacy/email-draft/skill.md +134 -0
- package/dist/defaults/skill/_legacy/gardener/SKILL.md +509 -0
- package/dist/defaults/skill/_legacy/gardener/confidence-tiers.md +142 -0
- package/dist/defaults/skill/_legacy/gardener/repair-workflow.md +170 -0
- package/dist/defaults/skill/_legacy/google-chat-scan/SKILL.md +135 -0
- package/dist/defaults/skill/_legacy/handover/SKILL.md +18 -0
- package/dist/defaults/skill/_legacy/interview-prep/SKILL.md +23 -0
- package/dist/defaults/skill/_legacy/leadership-coach/SKILL.md +167 -0
- package/dist/defaults/skill/_legacy/link-retrofit/SKILL.md +345 -0
- package/dist/defaults/skill/_legacy/onboarding/SKILL.md +207 -0
- package/dist/defaults/skill/_legacy/post-meeting-drill/SKILL.md +485 -0
- package/dist/defaults/skill/_legacy/restore-environment/SKILL.md +30 -0
- package/dist/defaults/skill/_legacy/scorecard-synthesis/SKILL.md +26 -0
- package/dist/defaults/skill/_legacy/skill-generator/SKILL.md +362 -0
- package/dist/defaults/skill/_legacy/skill-generator/testing-protocol.md +158 -0
- package/dist/defaults/skill/_legacy/system-init/SKILL.md +103 -0
- package/dist/defaults/skill/evening-close/SKILL.md +6 -7
- package/dist/defaults/skill/mail-triage/SKILL.md +11 -8
- package/dist/defaults/skill/morning-boot/SKILL.md +26 -87
- package/dist/defaults/skill/slack-pulse/SKILL.md +11 -7
- package/dist/defaults/skill/thought-router/SKILL.md +10 -8
- package/dist/index.js +11316 -2308
- package/dist/schemas/skill.d.ts +96 -0
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/sentinel-service.d.ts +71 -0
- package/dist/sdk/skill-runner.d.ts +21 -0
- package/dist/sdk/thoth-client.d.ts +51 -0
- package/dist/sdk/workflows/calendar-watcher.d.ts +2 -0
- package/dist/sdk/workflows/inbox-watcher.d.ts +2 -0
- package/dist/sdk/workflows/index.d.ts +4 -0
- package/dist/sdk/workflows/system-watcher.d.ts +2 -0
- package/dist/sdk/workflows/task-watcher.d.ts +2 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/skill-registry.d.ts +23 -0
- package/dist/tools/skill/tools.d.ts +2 -1
- package/package.json +8 -3
- /package/{dist/defaults/skill → defaults/skill/_legacy}/cal-grid/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/capsule-init/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/cross-linker/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/email-draft/skill.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/gardener/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/gardener/confidence-tiers.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/gardener/repair-workflow.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/google-chat-scan/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/handover/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/interview-prep/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/leadership-coach/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/link-retrofit/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/onboarding/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/post-meeting-drill/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/restore-environment/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/scorecard-synthesis/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/skill-generator/SKILL.md +0 -0
- /package/{dist/defaults/skill → defaults/skill/_legacy}/skill-generator/testing-protocol.md +0 -0
- /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
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
12
|
+
Welcome to your personal Thoth knowledge base.
|
|
48
13
|
|
|
49
14
|
## Structure
|
|
50
15
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
##
|
|
21
|
+
## Operating Modes
|
|
77
22
|
|
|
78
|
-
|
|
23
|
+
Thoth adapts based on where you start the session:
|
|
79
24
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
36
|
+
1. Start OpenCode in the desired context:
|
|
37
|
+
\`cd ~/thoth && opencode\`
|
|
100
38
|
|
|
101
|
-
|
|
102
|
-
- Ask: "Explain how Thoth works"
|
|
103
|
-
- Ask: "What skills are available?"
|
|
39
|
+
2. Ask Thoth: "Help me onboard"
|
|
104
40
|
`;
|
|
105
|
-
function
|
|
106
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
"work
|
|
135
|
-
"work
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
75
|
+
console.warn("Warning: Could not find defaults directory. Skills will not be pre-populated.");
|
|
265
76
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
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
|
}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -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";
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -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.
|