thoth-plugin 1.2.3 → 1.2.5

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 (102) hide show
  1. package/README.md +17 -1
  2. package/defaults/skill/cal-grid/SKILL.md +168 -0
  3. package/defaults/skill/cal-grid/cal-grid-template.md +106 -0
  4. package/defaults/skill/context-discovery/SKILL.md +253 -0
  5. package/defaults/skill/context-discovery/discovery.prose +143 -0
  6. package/defaults/skill/context-onboarding/SKILL.md +370 -0
  7. package/{dist/defaults/skill/_legacy/email-draft/skill.md → defaults/skill/email-draft/SKILL.md} +33 -30
  8. package/defaults/skill/evening-close/SKILL.md +93 -61
  9. package/defaults/skill/evening-close/evening-close-template.md +42 -0
  10. package/{dist/defaults/skill/_legacy → defaults/skill}/gardener/SKILL.md +3 -3
  11. package/{dist/defaults/skill/_legacy → defaults/skill}/google-chat-scan/SKILL.md +7 -0
  12. package/{dist/defaults/skill/_legacy → defaults/skill}/leadership-coach/SKILL.md +9 -8
  13. package/defaults/skill/mail-triage/SKILL.md +272 -15
  14. package/defaults/skill/mail-triage/mail-triage-template.md +90 -0
  15. package/defaults/skill/morning-boot/SKILL.md +214 -25
  16. package/defaults/skill/morning-boot/daily-log-template.md +98 -0
  17. package/defaults/skill/morning-boot/morning-boot.prose +98 -0
  18. package/defaults/skill/{_legacy/onboarding → onboarding}/SKILL.md +7 -6
  19. package/defaults/skill/open-prose/SKILL.md +373 -0
  20. package/defaults/skill/open-prose/antipatterns.md +852 -0
  21. package/defaults/skill/open-prose/docs.md +2676 -0
  22. package/defaults/skill/open-prose/patterns.md +610 -0
  23. package/defaults/skill/open-prose/prose.md +950 -0
  24. package/{dist/defaults/skill/_legacy → defaults/skill}/post-meeting-drill/SKILL.md +90 -95
  25. package/defaults/skill/post-meeting-drill/examples.md +130 -0
  26. package/defaults/skill/post-meeting-drill/post-meeting-drill-template.md +111 -0
  27. package/defaults/skill/skill-generator/SKILL.md +217 -0
  28. package/defaults/skill/skill-generator/skill-template.md +163 -0
  29. package/defaults/skill/slack-pulse/SKILL.md +211 -14
  30. package/defaults/skill/slack-pulse/slack-pulse-template.md +98 -0
  31. package/defaults/skill/slack-write/skill.md +184 -0
  32. package/defaults/skill/thought-router/SKILL.md +7 -8
  33. package/dist/cli.js +137 -3
  34. package/dist/config/schema.d.ts +0 -2
  35. package/dist/defaults/skill/cal-grid/SKILL.md +168 -0
  36. package/dist/defaults/skill/cal-grid/cal-grid-template.md +106 -0
  37. package/dist/defaults/skill/context-discovery/SKILL.md +253 -0
  38. package/dist/defaults/skill/context-discovery/discovery.prose +143 -0
  39. package/dist/defaults/skill/context-onboarding/SKILL.md +370 -0
  40. package/{defaults/skill/_legacy/email-draft/skill.md → dist/defaults/skill/email-draft/SKILL.md} +33 -30
  41. package/dist/defaults/skill/evening-close/SKILL.md +93 -61
  42. package/dist/defaults/skill/evening-close/evening-close-template.md +42 -0
  43. package/{defaults/skill/_legacy → dist/defaults/skill}/gardener/SKILL.md +3 -3
  44. package/{defaults/skill/_legacy → dist/defaults/skill}/google-chat-scan/SKILL.md +7 -0
  45. package/{defaults/skill/_legacy → dist/defaults/skill}/leadership-coach/SKILL.md +9 -8
  46. package/dist/defaults/skill/mail-triage/SKILL.md +272 -15
  47. package/dist/defaults/skill/mail-triage/mail-triage-template.md +90 -0
  48. package/dist/defaults/skill/morning-boot/SKILL.md +214 -25
  49. package/dist/defaults/skill/morning-boot/daily-log-template.md +98 -0
  50. package/dist/defaults/skill/morning-boot/morning-boot.prose +98 -0
  51. package/dist/defaults/skill/{_legacy/onboarding → onboarding}/SKILL.md +7 -6
  52. package/dist/defaults/skill/open-prose/SKILL.md +373 -0
  53. package/dist/defaults/skill/open-prose/antipatterns.md +852 -0
  54. package/dist/defaults/skill/open-prose/docs.md +2676 -0
  55. package/dist/defaults/skill/open-prose/patterns.md +610 -0
  56. package/dist/defaults/skill/open-prose/prose.md +950 -0
  57. package/{defaults/skill/_legacy → dist/defaults/skill}/post-meeting-drill/SKILL.md +90 -95
  58. package/dist/defaults/skill/post-meeting-drill/examples.md +130 -0
  59. package/dist/defaults/skill/post-meeting-drill/post-meeting-drill-template.md +111 -0
  60. package/dist/defaults/skill/skill-generator/SKILL.md +217 -0
  61. package/dist/defaults/skill/skill-generator/skill-template.md +163 -0
  62. package/dist/defaults/skill/slack-pulse/SKILL.md +211 -14
  63. package/dist/defaults/skill/slack-pulse/slack-pulse-template.md +98 -0
  64. package/dist/defaults/skill/slack-write/skill.md +184 -0
  65. package/dist/defaults/skill/thought-router/SKILL.md +7 -8
  66. package/dist/hooks/index.d.ts +0 -1
  67. package/dist/index.js +26 -189
  68. package/dist/sdk/index.d.ts +1 -1
  69. package/dist/sdk/sentinel-service.d.ts +0 -1
  70. package/dist/sdk/test-harness.d.ts +90 -0
  71. package/dist/sdk/thoth-client.d.ts +1 -0
  72. package/dist/shared/index.d.ts +0 -1
  73. package/dist/specialization/prompt-sections.d.ts +1 -1
  74. package/package.json +1 -1
  75. package/defaults/skill/_legacy/cal-grid/SKILL.md +0 -16
  76. package/defaults/skill/_legacy/skill-generator/SKILL.md +0 -362
  77. package/dist/defaults/skill/_legacy/cal-grid/SKILL.md +0 -16
  78. package/dist/defaults/skill/_legacy/skill-generator/SKILL.md +0 -362
  79. package/dist/hooks/temporal-awareness.d.ts +0 -31
  80. package/dist/hooks/temporal-awareness.test.d.ts +0 -1
  81. /package/defaults/skill/{_legacy/capsule-init → capsule-init}/SKILL.md +0 -0
  82. /package/defaults/skill/{_legacy/cross-linker → cross-linker}/SKILL.md +0 -0
  83. /package/defaults/skill/{_legacy/gardener → gardener}/confidence-tiers.md +0 -0
  84. /package/defaults/skill/{_legacy/gardener → gardener}/repair-workflow.md +0 -0
  85. /package/defaults/skill/{_legacy/handover → handover}/SKILL.md +0 -0
  86. /package/defaults/skill/{_legacy/interview-prep → interview-prep}/SKILL.md +0 -0
  87. /package/defaults/skill/{_legacy/link-retrofit → link-retrofit}/SKILL.md +0 -0
  88. /package/defaults/skill/{_legacy/restore-environment → restore-environment}/SKILL.md +0 -0
  89. /package/defaults/skill/{_legacy/scorecard-synthesis → scorecard-synthesis}/SKILL.md +0 -0
  90. /package/defaults/skill/{_legacy/skill-generator → skill-generator}/testing-protocol.md +0 -0
  91. /package/defaults/skill/{_legacy/system-init → system-init}/SKILL.md +0 -0
  92. /package/dist/defaults/skill/{_legacy/capsule-init → capsule-init}/SKILL.md +0 -0
  93. /package/dist/defaults/skill/{_legacy/cross-linker → cross-linker}/SKILL.md +0 -0
  94. /package/dist/defaults/skill/{_legacy/gardener → gardener}/confidence-tiers.md +0 -0
  95. /package/dist/defaults/skill/{_legacy/gardener → gardener}/repair-workflow.md +0 -0
  96. /package/dist/defaults/skill/{_legacy/handover → handover}/SKILL.md +0 -0
  97. /package/dist/defaults/skill/{_legacy/interview-prep → interview-prep}/SKILL.md +0 -0
  98. /package/dist/defaults/skill/{_legacy/link-retrofit → link-retrofit}/SKILL.md +0 -0
  99. /package/dist/defaults/skill/{_legacy/restore-environment → restore-environment}/SKILL.md +0 -0
  100. /package/dist/defaults/skill/{_legacy/scorecard-synthesis → scorecard-synthesis}/SKILL.md +0 -0
  101. /package/dist/defaults/skill/{_legacy/skill-generator → skill-generator}/testing-protocol.md +0 -0
  102. /package/dist/defaults/skill/{_legacy/system-init → system-init}/SKILL.md +0 -0
@@ -0,0 +1,184 @@
1
+ ---
2
+ name: slack-write
3
+ description: Use when writing Slack messages, team announcements, or channel posts. Ensures correct mrkdwn formatting instead of Markdown.
4
+ triggers:
5
+ created: 2026-01-07
6
+ updated: 2026-01-10
7
+ ---
8
+
9
+ <!--
10
+ ARCHITECTURE REFERENCE: docs/concepts/skill-architecture.md
11
+ -->
12
+
13
+ # Slack Write
14
+
15
+ **Core principle:** Slack uses `mrkdwn`, NOT Markdown. Different syntax for bold, links, and structure.
16
+
17
+ ---
18
+
19
+ ## When to Use
20
+
21
+ - Posting messages to Slack channels
22
+ - Team announcements or updates
23
+ - Any `slack_conversations_add_message` call
24
+
25
+ **Do NOT use when:**
26
+ - Reading/scanning Slack (use slack-pulse)
27
+ - Writing emails (use email-draft)
28
+ - Writing KB documentation (Markdown is fine)
29
+
30
+ ---
31
+
32
+ ## Quick Reference
33
+
34
+ | Format | mrkdwn Syntax | NOT This |
35
+ |--------|---------------|----------|
36
+ | **Bold** | `*text*` | `**text**` |
37
+ | *Italic* | `_text_` | `*text*` |
38
+ | ~~Strike~~ | `~text~` | `~~text~~` |
39
+ | `Code` | `` `code` `` | same |
40
+ | Link | `<https://url|text>` | `[text](url)` |
41
+ | User mention | `<@U123ABC>` | `@username` |
42
+ | Channel | `<#C123ABC>` | `#channel` |
43
+ | Emoji | `:emoji_name:` | same |
44
+ | Quote | `>text` | same |
45
+ | Line break | `\n` in string | same |
46
+
47
+ ---
48
+
49
+ ## Structure for Readability
50
+
51
+ Slack renders everything inline. Create visual breaks with:
52
+
53
+ ### Section Headers
54
+ Use emoji + bold:
55
+ ```
56
+ :rotating_light: *Important Update*
57
+ ```
58
+
59
+ ### Dividers
60
+ Use unicode box drawing (not `---`):
61
+ ```
62
+ ────────────────────────────
63
+ ```
64
+ Or emoji line:
65
+ ```
66
+ :small_blue_diamond::small_blue_diamond::small_blue_diamond:
67
+ ```
68
+
69
+ ### Bullets
70
+ No native list syntax. Use:
71
+ - `•` (unicode bullet)
72
+ - `◦` (hollow bullet)
73
+ - Emoji: `:white_check_mark:`, `:arrow_right:`
74
+
75
+ ### Numbered Lists
76
+ Manual numbering with line breaks:
77
+ ```
78
+ 1. First item\n2. Second item\n3. Third item
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Message Template
84
+
85
+ ```
86
+ :emoji: *Header Title*
87
+
88
+ Brief intro paragraph.
89
+
90
+ ────────────────────────────
91
+
92
+ :dart: *Section One*
93
+ • Point one
94
+ • Point two
95
+
96
+ :warning: *Section Two*
97
+ • Important note
98
+
99
+ ────────────────────────────
100
+
101
+ :link: Links: <https://example.com|Click here>
102
+
103
+ Questions? Reply in thread.
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Process
109
+
110
+ ### 1. Draft Content
111
+ Write the message content first, focusing on clarity.
112
+
113
+ ### 2. Convert to mrkdwn
114
+ - Replace `**bold**` → `*bold*`
115
+ - Replace `[text](url)` → `<url|text>`
116
+ - Add emoji section headers
117
+ - Add unicode dividers for visual breaks
118
+
119
+ ### 3. Present Final Payload for Approval
120
+ **CRITICAL:** Show Zeus the *exact* final string that will be sent.
121
+ - If formatting changes the wording, you MUST get re-approval.
122
+ - Use a code block to show the verbatim payload.
123
+
124
+ ### 4. Post only after "Yes" to the final payload
125
+ ```
126
+ slack_conversations_add_message(
127
+ channel_id="C123ABC",
128
+ content_type="text/markdown",
129
+ payload="*Approved Final Payload*"
130
+ )
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Common Mistakes
136
+
137
+ | Mistake | Prevention |
138
+ |---------|------------|
139
+ | `**bold**` | Use `*bold*` — single asterisks |
140
+ | `[text](url)` | Use `<url|text>` — angle brackets, pipe separator |
141
+ | `---` for divider | Use `────────────────────────────` (unicode) |
142
+ | Markdown tables | Not supported — use aligned text or bullet lists |
143
+ | `- item` for bullets | Use `•` or `◦` unicode bullets |
144
+ | Wall of text | Add emoji headers and dividers for scannability |
145
+ | Assuming Markdown works | mrkdwn is NOT Markdown — always convert |
146
+
147
+ ---
148
+
149
+ ## Red Flags - STOP
150
+
151
+ - About to use `**` for bold → STOP, use `*`
152
+ - About to use `[text](url)` → STOP, use `<url|text>`
153
+ - About to use `---` for divider → STOP, use unicode `────────`
154
+ - Message is a wall of text → STOP, add section breaks
155
+ - Not sure about syntax → Check Quick Reference table
156
+
157
+ ---
158
+
159
+ ## Verification Checklist
160
+
161
+ - [ ] No `**` double asterisks (use single `*`)
162
+ - [ ] Links use `<url|text>` format
163
+ - [ ] Dividers use unicode, not `---`
164
+ - [ ] Has visual structure (headers, breaks)
165
+ - [ ] Emoji used for scannability
166
+ - [ ] Presented to Zeus before posting
167
+
168
+ ---
169
+
170
+ ## Useful Emoji
171
+
172
+ | Purpose | Emoji |
173
+ |---------|-------|
174
+ | Alert/Important | `:rotating_light:` `:warning:` `:exclamation:` |
175
+ | Info/Update | `:information_source:` `:mega:` `:loudspeaker:` |
176
+ | Action/Task | `:dart:` `:arrow_right:` `:point_right:` |
177
+ | Success | `:white_check_mark:` `:tada:` `:sparkles:` |
178
+ | Link/Reference | `:link:` `:bookmark:` `:page_facing_up:` |
179
+ | Question | `:question:` `:thinking_face:` |
180
+ | Divider | `:small_blue_diamond:` `:heavy_minus_sign:` |
181
+
182
+ ---
183
+
184
+ *Slack Write Skill v1.0 | mrkdwn formatting for Slack messages*
@@ -1,17 +1,16 @@
1
1
  ---
2
2
  name: thought-router
3
- version: 1.0.0
4
- description: The thought(s) to capture
3
+ description: Route unstructured thoughts, brain dumps, and quick captures to their correct home in the knowledge base.
5
4
  triggers:
6
- inputs:
7
- - name: content
8
- type: markdown
9
- required: true
10
- output:
5
+ - "dump:
11
6
  created: 2026-01-09
12
- updated: 2026-01-09
7
+ updated: 2026-01-10
13
8
  ---
14
9
 
10
+ <!--
11
+ ARCHITECTURE REFERENCE: docs/concepts/skill-architecture.md
12
+ -->
13
+
15
14
  # Thought Router Skill
16
15
 
17
16
  You are the **Thought Router**. Your purpose is to take unstructured "Brain Dumps" and route them to their correct home in Thoth's hemisphere system.
@@ -1,7 +1,6 @@
1
1
  export { createPermissionEnforcerHook, type PermissionEnforcerHook, type PermissionEnforcerConfig, } from "./permission-enforcer";
2
2
  export { createTrustLevelTrackerHook, type TrustLevelTrackerHook, type TrustLevelTrackerConfig, type TrustLevel, type TrustState, } from "./trust-level-tracker";
3
3
  export { createContextApertureHook, type ContextApertureHook, type ContextApertureConfig, } from "./context-aperture";
4
- export { createTemporalAwarenessHook, type TemporalAwarenessHook, type TemporalAwarenessConfig, } from "./temporal-awareness";
5
4
  export { createFrontmatterEnforcerHook, type FrontmatterEnforcerHook, type FrontmatterEnforcerConfig, } from "./frontmatter-enforcer";
6
5
  export { createReadConfirmationHook, type ReadConfirmationHook, type ReadConfirmationConfig, } from "./read-confirmation";
7
6
  export { createWriteConfirmationHook, type WriteConfirmationHook, type WriteConfirmationConfig, } from "./write-confirmation";
package/dist/index.js CHANGED
@@ -7172,6 +7172,9 @@ Remember it. If action drifts from stated priority, surface it \u2014 once. "You
7172
7172
 
7173
7173
  ### When a Commitment is Made
7174
7174
  Track it. By Zeus or to Zeus \u2014 commitments get logged. Surface before they slip, not after.
7175
+
7176
+ ### When Improving Something That Works
7177
+ Verify the current state first. Understand why it works before changing how it works. Improvements that break existing functionality aren't improvements.
7175
7178
  </Behavioral_Guidance>`;
7176
7179
  var THOTH_KNOWLEDGE_MANAGEMENT = `<Knowledge_Management>
7177
7180
  ## Knowledge Management
@@ -7547,20 +7550,14 @@ A task is NOT complete without evidence:
7547
7550
  | Delegation | Agent result received and verified |
7548
7551
  </Execution>`;
7549
7552
  var THOTH_TEMPORAL_AWARENESS = `<Temporal_Awareness>
7550
- ## Temporal Awareness (Chronos Protocol)
7551
-
7552
- Operate with deep time awareness, respecting Zeus's biological and professional cycles.
7553
+ ## Time Awareness
7553
7554
 
7554
- ### Executive Calendar (Work)
7555
- - **Monday**: Launch Mode \u2014 Prioritize planning, alignment, P0 definition
7556
- - **Tue-Thu**: Execution Mode \u2014 Protect deep work blocks, minimize admin
7557
- - **Friday**: Closure Mode \u2014 Wrap up, delegation follow-ups, weekly review
7558
- - **Weekend**: Sanctuary \u2014 Block work unless Emergency P0
7555
+ The current date is provided in the environment context. Use it actively:
7556
+ - **Project context**: Know where we are in quarters, sprints, deadlines
7557
+ - **Commitment tracking**: "By Friday" means something different on Monday vs Thursday
7558
+ - **Recency**: Distinguish recent vs stale information when retrieving context
7559
7559
 
7560
- ### Biological Clock (Life)
7561
- - **Morning (08:00-11:00)**: High Cognitive \u2014 Protect from triage hell
7562
- - **Afternoon (14:00-17:00)**: Collaborative \u2014 Good for meetings and emails
7563
- - **Evening (19:00+)**: Restoration \u2014 Block work notifications, prompt journaling
7560
+ Time is not decorative metadata \u2014 it's essential context for prioritization.
7564
7561
  </Temporal_Awareness>`;
7565
7562
  var THOTH_PERMISSIONS = `<Permission_System>
7566
7563
  ## Permission System
@@ -7734,7 +7731,6 @@ function createThothAgent(specialization, cwd, knowledgeBasePath) {
7734
7731
  return {
7735
7732
  description: getAgentDescription(specialization),
7736
7733
  mode: "primary",
7737
- model: "google-vertex-anthropic/claude-opus-4-5@20251101",
7738
7734
  thinking: {
7739
7735
  type: "enabled",
7740
7736
  budgetTokens: 32000
@@ -7768,7 +7764,6 @@ function getAgentDescription(spec) {
7768
7764
  var thothAgent = {
7769
7765
  description: "Thoth - Root-level life orchestrator and trusted chief of staff. Manages all hemispheres (work, personal, coding, system). Routes intent to specialized agents, maintains knowledge base, enforces permissions, supports rhythmic workflows. Warm but professional advisor who knows everything about Zeus.",
7770
7766
  mode: "primary",
7771
- model: "google-vertex-anthropic/claude-opus-4-5@20251101",
7772
7767
  thinking: {
7773
7768
  type: "enabled",
7774
7769
  budgetTokens: 32000
@@ -8452,7 +8447,6 @@ Act accordingly.
8452
8447
  var codeMasterAgent = {
8453
8448
  description: "Code Master - Technical projects orchestrator with Sisyphus-level quality. Writes production-ready code, makes architectural decisions, debugs systematically, maintains technical documentation. Code indistinguishable from senior engineer.",
8454
8449
  mode: "subagent",
8455
- model: "google-vertex-anthropic/claude-opus-4-5@20251101",
8456
8450
  temperature: 0.1,
8457
8451
  prompt: CODE_MASTER_PROMPT
8458
8452
  };
@@ -9653,41 +9647,6 @@ function getWeekNumber(date) {
9653
9647
  const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
9654
9648
  return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
9655
9649
  }
9656
- function formatTemporalContext(ctx) {
9657
- return `<temporal_context>
9658
- Date: ${ctx.date} (${ctx.dayOfWeek})
9659
- Time: ${ctx.time}
9660
- Week: ${ctx.weekNumber} of 52
9661
- Quarter: Q${ctx.quarter}
9662
- Day Mode: ${formatDayMode(ctx.dayMode)}
9663
- Biological Mode: ${formatBiologicalMode(ctx.biologicalMode)}
9664
- ${ctx.isWeekend ? "\u26A0\uFE0F Weekend Sanctuary - Block work unless Emergency P0" : ""}
9665
- </temporal_context>`;
9666
- }
9667
- function formatDayMode(mode) {
9668
- switch (mode) {
9669
- case "launch":
9670
- return "Monday Launch Mode - Prioritize planning and alignment";
9671
- case "execution":
9672
- return "Execution Mode - Protect deep work blocks";
9673
- case "closure":
9674
- return "Friday Closure Mode - Wrap up and delegate";
9675
- case "weekend-sanctuary":
9676
- return "Weekend Sanctuary - Restoration priority";
9677
- }
9678
- }
9679
- function formatBiologicalMode(mode) {
9680
- switch (mode) {
9681
- case "high-cognitive":
9682
- return "High Cognitive (08:00-11:00) - Protect from triage";
9683
- case "collaborative":
9684
- return "Collaborative (14:00-17:00) - Good for meetings";
9685
- case "restoration":
9686
- return "Restoration (19:00+) - Block work notifications";
9687
- case "transition":
9688
- return "Transition - Flexible period";
9689
- }
9690
- }
9691
9650
 
9692
9651
  // src/hooks/permission-enforcer.ts
9693
9652
  import * as path2 from "path";
@@ -10247,95 +10206,6 @@ Consider focusing on specific entities rather than broad exploration.`;
10247
10206
  generateContextWarning
10248
10207
  };
10249
10208
  }
10250
- // src/hooks/temporal-awareness.ts
10251
- function createTemporalAwarenessHook(config = {}) {
10252
- const { enabled = true } = config;
10253
- if (!enabled) {
10254
- return null;
10255
- }
10256
- let injectedThisSession = false;
10257
- function shouldBlockWork() {
10258
- const temporal = getTemporalContext();
10259
- if (temporal.isWeekend) {
10260
- return {
10261
- blocked: true,
10262
- reason: "Weekend Sanctuary mode - work tasks blocked unless Emergency P0"
10263
- };
10264
- }
10265
- if (temporal.biologicalMode === "restoration") {
10266
- return {
10267
- blocked: true,
10268
- reason: "Restoration mode (evening/night) - work tasks blocked unless Emergency P0"
10269
- };
10270
- }
10271
- return { blocked: false };
10272
- }
10273
- function getWorkRecommendation() {
10274
- const temporal = getTemporalContext();
10275
- switch (temporal.biologicalMode) {
10276
- case "high-cognitive":
10277
- return "High cognitive period - ideal for deep work, complex problems, creative tasks. Protect from interruptions.";
10278
- case "collaborative":
10279
- return "Collaborative period - good for meetings, emails, discussions, reviews.";
10280
- case "restoration":
10281
- return "Restoration period - avoid work, focus on personal time and recovery.";
10282
- case "transition":
10283
- return "Transition period - flexible, good for admin tasks and planning.";
10284
- }
10285
- }
10286
- function getDayModeRecommendation() {
10287
- const temporal = getTemporalContext();
10288
- switch (temporal.dayMode) {
10289
- case "launch":
10290
- return "Monday Launch Mode - prioritize planning, alignment, and P0 definition.";
10291
- case "execution":
10292
- return "Execution Mode - protect deep work blocks, minimize administrative overhead.";
10293
- case "closure":
10294
- return "Friday Closure Mode - wrap up tasks, follow up on delegations, prepare weekly review.";
10295
- case "weekend-sanctuary":
10296
- return "Weekend Sanctuary - restoration priority, block work unless Emergency P0.";
10297
- }
10298
- }
10299
- return {
10300
- event: async (input) => {
10301
- if (input.event.type === "session.created" && !injectedThisSession) {
10302
- injectedThisSession = true;
10303
- const temporal = getTemporalContext();
10304
- const formatted = formatTemporalContext(temporal);
10305
- log("Temporal context for session:", formatted);
10306
- }
10307
- },
10308
- "tool.execute.before": async (input, output) => {
10309
- const workTools = [
10310
- "google-workspace_send_gmail_message",
10311
- "slack_conversations_add_message",
10312
- "jira_"
10313
- ];
10314
- const isWorkTool = workTools.some((t) => input.tool.startsWith(t) || input.tool === t);
10315
- if (!isWorkTool)
10316
- return;
10317
- const blockCheck = shouldBlockWork();
10318
- if (blockCheck.blocked) {
10319
- const args = output.args;
10320
- const argsString = JSON.stringify(args).toLowerCase();
10321
- const isEmergency = argsString.includes("p0") || argsString.includes("emergency") || argsString.includes("urgent") || argsString.includes("critical");
10322
- if (!isEmergency) {
10323
- output.abort = {
10324
- reason: `[Temporal Awareness] ${blockCheck.reason}
10325
-
10326
- To proceed, mark this as Emergency/P0 or wait until work hours.`
10327
- };
10328
- log(`Blocked work tool ${input.tool}: ${blockCheck.reason}`);
10329
- }
10330
- }
10331
- },
10332
- getTemporalContext,
10333
- formatTemporalContext,
10334
- shouldBlockWork,
10335
- getWorkRecommendation,
10336
- getDayModeRecommendation
10337
- };
10338
- }
10339
10209
  // src/hooks/frontmatter-enforcer.ts
10340
10210
  import * as path5 from "path";
10341
10211
  var FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
@@ -38231,7 +38101,11 @@ class SkillRegistry {
38231
38101
  try {
38232
38102
  const entries = readdirSync6(directory, { withFileTypes: true });
38233
38103
  for (const entry of entries) {
38234
- if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name.startsWith("_")) {
38104
+ if (entry.name.startsWith(".") || entry.name.startsWith("_")) {
38105
+ continue;
38106
+ }
38107
+ const isDir = entry.isDirectory() || entry.isSymbolicLink();
38108
+ if (!isDir) {
38235
38109
  continue;
38236
38110
  }
38237
38111
  const skillPath = join18(directory, entry.name);
@@ -38292,7 +38166,6 @@ var HooksConfigSchema = exports_external2.object({
38292
38166
  "permission-enforcer": exports_external2.boolean().optional(),
38293
38167
  "trust-level-tracker": exports_external2.boolean().optional(),
38294
38168
  "context-aperture": exports_external2.boolean().optional(),
38295
- "temporal-awareness": exports_external2.boolean().optional(),
38296
38169
  "knowledge-persistence": exports_external2.boolean().optional(),
38297
38170
  "directory-agents-injector": exports_external2.boolean().optional(),
38298
38171
  "frontmatter-enforcer": exports_external2.boolean().optional(),
@@ -39788,6 +39661,10 @@ async function createOpencode(options) {
39788
39661
  }
39789
39662
 
39790
39663
  // src/sdk/thoth-client.ts
39664
+ import { writeFile } from "fs/promises";
39665
+ import { dirname as dirname5 } from "path";
39666
+ import { mkdir } from "fs/promises";
39667
+
39791
39668
  class ThothClient {
39792
39669
  client = null;
39793
39670
  config;
@@ -39961,6 +39838,14 @@ class ThothClient {
39961
39838
  log(`Failed to show toast: ${err}`);
39962
39839
  }
39963
39840
  }
39841
+ async writeFile(path9, content) {
39842
+ try {
39843
+ await mkdir(dirname5(path9), { recursive: true });
39844
+ await writeFile(path9, content, "utf-8");
39845
+ } catch (err) {
39846
+ throw new Error(`Failed to write file ${path9}: ${err}`);
39847
+ }
39848
+ }
39964
39849
  extractResponseText(result) {
39965
39850
  try {
39966
39851
  const data = result?.data;
@@ -40256,50 +40141,6 @@ Describe common implementation patterns.`,
40256
40141
  }
40257
40142
  };
40258
40143
  }
40259
- function createMorningBootWorkflow() {
40260
- return {
40261
- name: "morning-boot",
40262
- description: "Daily morning briefing and task prioritization",
40263
- triggers: [
40264
- {
40265
- type: "schedule",
40266
- time: "08:00",
40267
- days: ["mon", "tue", "wed", "thu", "fri"]
40268
- }
40269
- ],
40270
- quietHours: { start: "22:00", end: "07:00" },
40271
- execute: async (context) => {
40272
- const { client: client3, temporal } = context;
40273
- const [email5, calendar, tasks] = await client3.runParallel([
40274
- {
40275
- prompt: `Scan emails from the last 12 hours. Categorize by urgency (P0/P1/P2). Today is ${temporal.dayOfWeek}, ${temporal.date}.`,
40276
- options: { title: "Email Scan" }
40277
- },
40278
- {
40279
- prompt: `Analyze today's calendar. Identify prep needed for meetings. Today is ${temporal.dayOfWeek}, ${temporal.date}.`,
40280
- options: { title: "Calendar Scan" }
40281
- },
40282
- {
40283
- prompt: `Check for overdue or at-risk tasks. Today is ${temporal.dayOfWeek}, ${temporal.date}.`,
40284
- options: { title: "Task Scan" }
40285
- }
40286
- ]);
40287
- const synthesis = await client3.runSession(`Create a morning briefing from these scans:
40288
-
40289
- EMAIL: ${email5.response}
40290
-
40291
- CALENDAR: ${calendar.response}
40292
-
40293
- TASKS: ${tasks.response}
40294
-
40295
- Provide:
40296
- 1. Top 3 priorities for today
40297
- 2. Any urgent items needing immediate attention
40298
- 3. Suggested focus blocks`, { title: "Morning Synthesis" });
40299
- return synthesis.response;
40300
- }
40301
- };
40302
- }
40303
40144
  // src/sdk/workflows/calendar-watcher.ts
40304
40145
  function createCalendarWatcherWorkflow() {
40305
40146
  return {
@@ -40533,7 +40374,6 @@ var ThothPlugin = async (ctx) => {
40533
40374
  quietHours: sentinelConfig?.quiet_hours,
40534
40375
  enabled: sentinelConfig?.enabled
40535
40376
  });
40536
- sentinelService.registerWorkflow(createMorningBootWorkflow());
40537
40377
  sentinelService.registerWorkflow(createDeepResearchWorkflow());
40538
40378
  sentinelService.registerWorkflow(createInboxWatcherWorkflow());
40539
40379
  sentinelService.registerWorkflow(createCalendarWatcherWorkflow());
@@ -40551,7 +40391,6 @@ var ThothPlugin = async (ctx) => {
40551
40391
  const permissionEnforcer = hooksConfig["permission-enforcer"] !== false ? createPermissionEnforcerHook({ knowledgeBasePath }) : null;
40552
40392
  const trustLevelTracker = hooksConfig["trust-level-tracker"] !== false ? createTrustLevelTrackerHook({ knowledgeBasePath }) : null;
40553
40393
  const contextAperture = hooksConfig["context-aperture"] !== false ? createContextApertureHook({ knowledgeBasePath }) : null;
40554
- const temporalAwareness = hooksConfig["temporal-awareness"] !== false ? createTemporalAwarenessHook() : null;
40555
40394
  const frontmatterEnforcer = hooksConfig["frontmatter-enforcer"] !== false ? createFrontmatterEnforcerHook({ knowledgeBasePath }) : null;
40556
40395
  const readConfirmation = hooksConfig["read-confirmation"] !== false ? createReadConfirmationHook({ knowledgeBasePath }) : null;
40557
40396
  const writeConfirmation = hooksConfig["write-confirmation"] !== false ? createWriteConfirmationHook({ knowledgeBasePath }) : null;
@@ -40641,7 +40480,6 @@ var ThothPlugin = async (ctx) => {
40641
40480
  }
40642
40481
  await trustLevelTracker?.event(input);
40643
40482
  await contextAperture?.event(input);
40644
- await temporalAwareness?.event(input);
40645
40483
  await directoryAgentsInjector?.event(input);
40646
40484
  await todoContinuationEnforcer?.handler(input);
40647
40485
  await backgroundNotificationHook.event(input);
@@ -40660,7 +40498,6 @@ var ThothPlugin = async (ctx) => {
40660
40498
  },
40661
40499
  "tool.execute.before": async (input, output) => {
40662
40500
  await permissionEnforcer?.["tool.execute.before"]?.(input, output);
40663
- await temporalAwareness?.["tool.execute.before"]?.(input, output);
40664
40501
  await contextAperture?.["tool.execute.before"]?.(input, output);
40665
40502
  await trustLevelTracker?.["tool.execute.before"]?.(input, output);
40666
40503
  await frontmatterEnforcer?.["tool.execute.before"]?.(input, output);
@@ -1,4 +1,4 @@
1
1
  export { ThothClient, createThothClient, type ThothClientConfig, type SessionOptions, type SessionResult, type PipelineUnit, type PipelineOutput, } from "./thoth-client";
2
- export { SentinelService, createMorningBootWorkflow, createDeepResearchWorkflow, type SentinelConfig, type WorkflowDefinition, type WorkflowContext, type Trigger, type ScheduleTrigger, type FileChangeTrigger, type ManualTrigger, type TriggerType, } from "./sentinel-service";
2
+ export { SentinelService, createDeepResearchWorkflow, type SentinelConfig, type WorkflowDefinition, type WorkflowContext, type Trigger, type ScheduleTrigger, type FileChangeTrigger, type ManualTrigger, type TriggerType, } from "./sentinel-service";
3
3
  export { SkillRunner, type SkillTest, type TestResult, } from "./skill-runner";
4
4
  export * from "./workflows";
@@ -68,4 +68,3 @@ export declare class SentinelService {
68
68
  private timeToMinutes;
69
69
  }
70
70
  export declare function createDeepResearchWorkflow(): WorkflowDefinition;
71
- export declare function createMorningBootWorkflow(): WorkflowDefinition;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Test Harness for Thoth Skills
3
+ *
4
+ * Spawns fresh SDK sessions to test skills in isolation.
5
+ * Captures full transcript including tool calls for analysis.
6
+ *
7
+ * Usage:
8
+ * const harness = new TestHarness();
9
+ * await harness.connect();
10
+ * const result = await harness.runScenario("prepare me for the day");
11
+ * console.log(result.transcript);
12
+ * await harness.disconnect();
13
+ */
14
+ export interface Message {
15
+ id: string;
16
+ role: "user" | "assistant" | "tool";
17
+ content: string | MessagePart[];
18
+ toolCalls?: ToolCall[];
19
+ toolResults?: ToolResult[];
20
+ timestamp?: string;
21
+ }
22
+ export interface MessagePart {
23
+ type: "text" | "tool_use" | "tool_result";
24
+ text?: string;
25
+ toolUseId?: string;
26
+ toolName?: string;
27
+ input?: Record<string, unknown>;
28
+ output?: string;
29
+ }
30
+ export interface ToolCall {
31
+ id: string;
32
+ name: string;
33
+ input: Record<string, unknown>;
34
+ }
35
+ export interface ToolResult {
36
+ toolUseId: string;
37
+ output: string;
38
+ isError?: boolean;
39
+ }
40
+ export interface ScenarioResult {
41
+ sessionId: string;
42
+ success: boolean;
43
+ messages: Message[];
44
+ transcript: string;
45
+ toolCallsSummary: ToolCallSummary[];
46
+ errors: string[];
47
+ durationMs: number;
48
+ }
49
+ export interface ToolCallSummary {
50
+ tool: string;
51
+ count: number;
52
+ inputs: Array<Record<string, unknown>>;
53
+ errors: string[];
54
+ }
55
+ export interface TestHarnessConfig {
56
+ baseUrl?: string;
57
+ directory?: string;
58
+ agent?: string;
59
+ systemPrompt?: string;
60
+ model?: {
61
+ providerID: string;
62
+ modelID: string;
63
+ };
64
+ waitForCompletionMs?: number;
65
+ pollIntervalMs?: number;
66
+ maxWaitMs?: number;
67
+ }
68
+ export declare class TestHarness {
69
+ private client;
70
+ private config;
71
+ constructor(config?: TestHarnessConfig);
72
+ connect(): Promise<void>;
73
+ disconnect(): Promise<void>;
74
+ runScenario(prompt: string, options?: {
75
+ title?: string;
76
+ timeoutMs?: number;
77
+ }): Promise<ScenarioResult>;
78
+ runComparison(scenarios: Array<{
79
+ name: string;
80
+ prompt: string;
81
+ }>): Promise<Map<string, ScenarioResult>>;
82
+ private parseMessages;
83
+ private parseContent;
84
+ private formatTranscript;
85
+ private summarizeToolCalls;
86
+ private addToolCall;
87
+ private sleep;
88
+ }
89
+ export declare function quickTest(prompt: string, options?: TestHarnessConfig): Promise<ScenarioResult>;
90
+ export declare function printReport(result: ScenarioResult): void;
@@ -46,6 +46,7 @@ export declare class ThothClient {
46
46
  isHealthy(): Promise<boolean>;
47
47
  notify(message: string, level?: "info" | "success" | "warning" | "error"): Promise<void>;
48
48
  showToast(message: string, variant?: "info" | "success" | "warning" | "error"): Promise<void>;
49
+ writeFile(path: string, content: string): Promise<void>;
49
50
  private extractResponseText;
50
51
  }
51
52
  export declare function createThothClient(config?: ThothClientConfig): Promise<ThothClient>;
@@ -18,4 +18,3 @@ export interface TemporalContext {
18
18
  biologicalMode: BiologicalMode;
19
19
  isWeekend: boolean;
20
20
  }
21
- export declare function formatTemporalContext(ctx: TemporalContext): string;