principles-disciple 1.5.4

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 (189) hide show
  1. package/dist/commands/capabilities.d.ts +3 -0
  2. package/dist/commands/capabilities.js +73 -0
  3. package/dist/commands/evolver.d.ts +9 -0
  4. package/dist/commands/evolver.js +26 -0
  5. package/dist/commands/pain.d.ts +5 -0
  6. package/dist/commands/pain.js +114 -0
  7. package/dist/commands/strategy.d.ts +3 -0
  8. package/dist/commands/strategy.js +29 -0
  9. package/dist/commands/thinking-os.d.ts +2 -0
  10. package/dist/commands/thinking-os.js +162 -0
  11. package/dist/commands/trust.d.ts +4 -0
  12. package/dist/commands/trust.js +95 -0
  13. package/dist/core/agent-loader.d.ts +44 -0
  14. package/dist/core/agent-loader.js +147 -0
  15. package/dist/core/config-service.d.ts +15 -0
  16. package/dist/core/config-service.js +26 -0
  17. package/dist/core/config.d.ts +103 -0
  18. package/dist/core/config.js +186 -0
  19. package/dist/core/detection-funnel.d.ts +33 -0
  20. package/dist/core/detection-funnel.js +100 -0
  21. package/dist/core/detection-service.d.ts +15 -0
  22. package/dist/core/detection-service.js +28 -0
  23. package/dist/core/dictionary-service.d.ts +15 -0
  24. package/dist/core/dictionary-service.js +26 -0
  25. package/dist/core/dictionary.d.ts +36 -0
  26. package/dist/core/dictionary.js +136 -0
  27. package/dist/core/event-log.d.ts +53 -0
  28. package/dist/core/event-log.js +196 -0
  29. package/dist/core/evolution-engine.d.ts +119 -0
  30. package/dist/core/evolution-engine.js +542 -0
  31. package/dist/core/evolution-types.d.ts +126 -0
  32. package/dist/core/evolution-types.js +56 -0
  33. package/dist/core/hygiene/tracker.d.ts +22 -0
  34. package/dist/core/hygiene/tracker.js +106 -0
  35. package/dist/core/init.d.ts +12 -0
  36. package/dist/core/init.js +117 -0
  37. package/dist/core/migration.d.ts +6 -0
  38. package/dist/core/migration.js +90 -0
  39. package/dist/core/pain.d.ts +4 -0
  40. package/dist/core/pain.js +70 -0
  41. package/dist/core/path-resolver.d.ts +43 -0
  42. package/dist/core/path-resolver.js +259 -0
  43. package/dist/core/paths.d.ts +60 -0
  44. package/dist/core/paths.js +67 -0
  45. package/dist/core/profile.d.ts +62 -0
  46. package/dist/core/profile.js +210 -0
  47. package/dist/core/risk-calculator.d.ts +7 -0
  48. package/dist/core/risk-calculator.js +39 -0
  49. package/dist/core/session-tracker.d.ts +76 -0
  50. package/dist/core/session-tracker.js +286 -0
  51. package/dist/core/system-logger.d.ts +8 -0
  52. package/dist/core/system-logger.js +31 -0
  53. package/dist/core/trust-engine.d.ts +91 -0
  54. package/dist/core/trust-engine.js +284 -0
  55. package/dist/core/workspace-context.d.ts +64 -0
  56. package/dist/core/workspace-context.js +134 -0
  57. package/dist/hooks/gate.d.ts +6 -0
  58. package/dist/hooks/gate.js +487 -0
  59. package/dist/hooks/lifecycle.d.ts +5 -0
  60. package/dist/hooks/lifecycle.js +180 -0
  61. package/dist/hooks/llm.d.ts +4 -0
  62. package/dist/hooks/llm.js +153 -0
  63. package/dist/hooks/pain.d.ts +5 -0
  64. package/dist/hooks/pain.js +173 -0
  65. package/dist/hooks/prompt.d.ts +38 -0
  66. package/dist/hooks/prompt.js +285 -0
  67. package/dist/hooks/subagent.d.ts +2 -0
  68. package/dist/hooks/subagent.js +70 -0
  69. package/dist/i18n/commands.d.ts +26 -0
  70. package/dist/i18n/commands.js +88 -0
  71. package/dist/index.d.ts +7 -0
  72. package/dist/index.js +204 -0
  73. package/dist/service/evolution-worker.d.ts +17 -0
  74. package/dist/service/evolution-worker.js +293 -0
  75. package/dist/tools/agent-spawn.d.ts +33 -0
  76. package/dist/tools/agent-spawn.js +170 -0
  77. package/dist/tools/critique-prompt.d.ts +14 -0
  78. package/dist/tools/critique-prompt.js +81 -0
  79. package/dist/tools/deep-reflect.d.ts +19 -0
  80. package/dist/tools/deep-reflect.js +174 -0
  81. package/dist/tools/model-index.d.ts +9 -0
  82. package/dist/tools/model-index.js +82 -0
  83. package/dist/types/event-types.d.ts +229 -0
  84. package/dist/types/event-types.js +73 -0
  85. package/dist/types/hygiene-types.d.ts +20 -0
  86. package/dist/types/hygiene-types.js +12 -0
  87. package/dist/types.d.ts +1 -0
  88. package/dist/types.js +1 -0
  89. package/dist/utils/file-lock.d.ts +64 -0
  90. package/dist/utils/file-lock.js +270 -0
  91. package/dist/utils/glob-match.d.ts +28 -0
  92. package/dist/utils/glob-match.js +49 -0
  93. package/dist/utils/hashing.d.ts +9 -0
  94. package/dist/utils/hashing.js +25 -0
  95. package/dist/utils/io.d.ts +6 -0
  96. package/dist/utils/io.js +106 -0
  97. package/dist/utils/nlp.d.ts +9 -0
  98. package/dist/utils/nlp.js +59 -0
  99. package/dist/utils/plugin-logger.d.ts +39 -0
  100. package/dist/utils/plugin-logger.js +70 -0
  101. package/openclaw.plugin.json +46 -0
  102. package/package.json +63 -0
  103. package/templates/langs/en/core/AGENTS.md +206 -0
  104. package/templates/langs/en/core/BOOT.md +60 -0
  105. package/templates/langs/en/core/BOOTSTRAP.md +250 -0
  106. package/templates/langs/en/core/HEARTBEAT.md +74 -0
  107. package/templates/langs/en/core/IDENTITY.md +8 -0
  108. package/templates/langs/en/core/PRINCIPLES.md +10 -0
  109. package/templates/langs/en/core/SOUL.md +76 -0
  110. package/templates/langs/en/core/TOOLS.md +53 -0
  111. package/templates/langs/en/core/USER.md +10 -0
  112. package/templates/langs/en/pain/00_seed_samples.md +23 -0
  113. package/templates/langs/en/pain_dictionary.json +22 -0
  114. package/templates/langs/en/skills/admin/SKILL.md +40 -0
  115. package/templates/langs/en/skills/bootstrap-tools/SKILL.md +53 -0
  116. package/templates/langs/en/skills/deductive-audit/SKILL.md +36 -0
  117. package/templates/langs/en/skills/evolution-framework-update/SKILL.md +31 -0
  118. package/templates/langs/en/skills/evolve-system/SKILL.md +46 -0
  119. package/templates/langs/en/skills/evolve-task/SKILL.md +83 -0
  120. package/templates/langs/en/skills/feedback/SKILL.md +51 -0
  121. package/templates/langs/en/skills/init-strategy/SKILL.md +54 -0
  122. package/templates/langs/en/skills/inject-rule/SKILL.md +19 -0
  123. package/templates/langs/en/skills/manage-okr/SKILL.md +96 -0
  124. package/templates/langs/en/skills/pain/SKILL.md +19 -0
  125. package/templates/langs/en/skills/pd-daily/SKILL.md +199 -0
  126. package/templates/langs/en/skills/pd-grooming/SKILL.md +46 -0
  127. package/templates/langs/en/skills/pd-mentor/SKILL.md +230 -0
  128. package/templates/langs/en/skills/plan-script/SKILL.md +32 -0
  129. package/templates/langs/en/skills/profile/SKILL.md +24 -0
  130. package/templates/langs/en/skills/reflection/SKILL.md +40 -0
  131. package/templates/langs/en/skills/reflection-log/SKILL.md +37 -0
  132. package/templates/langs/en/skills/report/SKILL.md +13 -0
  133. package/templates/langs/en/skills/root-cause/SKILL.md +33 -0
  134. package/templates/langs/en/skills/triage/SKILL.md +29 -0
  135. package/templates/langs/en/skills/watch-evolution/SKILL.md +33 -0
  136. package/templates/langs/zh/core/AGENTS.md +207 -0
  137. package/templates/langs/zh/core/BOOT.md +60 -0
  138. package/templates/langs/zh/core/BOOTSTRAP.md +250 -0
  139. package/templates/langs/zh/core/HEARTBEAT.md +74 -0
  140. package/templates/langs/zh/core/IDENTITY.md +8 -0
  141. package/templates/langs/zh/core/SOUL.md +76 -0
  142. package/templates/langs/zh/core/TOOLS.md +53 -0
  143. package/templates/langs/zh/core/USER.md +10 -0
  144. package/templates/langs/zh/pain/00_seed_samples.md +24 -0
  145. package/templates/langs/zh/pain_dictionary.json +18 -0
  146. package/templates/langs/zh/skills/admin/SKILL.md +42 -0
  147. package/templates/langs/zh/skills/bootstrap-tools/SKILL.md +52 -0
  148. package/templates/langs/zh/skills/deductive-audit/SKILL.md +36 -0
  149. package/templates/langs/zh/skills/evolution-framework-update/SKILL.md +31 -0
  150. package/templates/langs/zh/skills/evolve-system/SKILL.md +46 -0
  151. package/templates/langs/zh/skills/evolve-task/SKILL.md +83 -0
  152. package/templates/langs/zh/skills/feedback/SKILL.md +53 -0
  153. package/templates/langs/zh/skills/init-strategy/SKILL.md +54 -0
  154. package/templates/langs/zh/skills/inject-rule/SKILL.md +19 -0
  155. package/templates/langs/zh/skills/manage-okr/SKILL.md +109 -0
  156. package/templates/langs/zh/skills/pain/SKILL.md +19 -0
  157. package/templates/langs/zh/skills/pd-daily/SKILL.md +199 -0
  158. package/templates/langs/zh/skills/pd-grooming/SKILL.md +46 -0
  159. package/templates/langs/zh/skills/pd-mentor/SKILL.md +230 -0
  160. package/templates/langs/zh/skills/plan-script/SKILL.md +32 -0
  161. package/templates/langs/zh/skills/profile/SKILL.md +24 -0
  162. package/templates/langs/zh/skills/reflection/SKILL.md +40 -0
  163. package/templates/langs/zh/skills/reflection-log/SKILL.md +37 -0
  164. package/templates/langs/zh/skills/report/SKILL.md +13 -0
  165. package/templates/langs/zh/skills/root-cause/SKILL.md +33 -0
  166. package/templates/langs/zh/skills/triage/SKILL.md +29 -0
  167. package/templates/langs/zh/skills/watch-evolution/SKILL.md +33 -0
  168. package/templates/pain_dictionary.json +36 -0
  169. package/templates/pain_settings.json +77 -0
  170. package/templates/workspace/.principles/00-kernel.md +51 -0
  171. package/templates/workspace/.principles/DECISION_POLICY.json +44 -0
  172. package/templates/workspace/.principles/PRINCIPLES.md +20 -0
  173. package/templates/workspace/.principles/PROFILE.json +52 -0
  174. package/templates/workspace/.principles/PROFILE.schema.json +56 -0
  175. package/templates/workspace/.principles/THINKING_OS.md +64 -0
  176. package/templates/workspace/.principles/THINKING_OS_ARCHIVE.md +7 -0
  177. package/templates/workspace/.principles/THINKING_OS_CANDIDATES.md +9 -0
  178. package/templates/workspace/.principles/models/_INDEX.md +27 -0
  179. package/templates/workspace/.principles/models/first_principles.md +62 -0
  180. package/templates/workspace/.principles/models/marketing_4p.md +52 -0
  181. package/templates/workspace/.principles/models/porter_five.md +63 -0
  182. package/templates/workspace/.principles/models/swot.md +60 -0
  183. package/templates/workspace/.principles/models/user_story_map.md +63 -0
  184. package/templates/workspace/.state/WORKBOARD.json +4 -0
  185. package/templates/workspace/AUDIT.md +15 -0
  186. package/templates/workspace/PLAN.md +2 -0
  187. package/templates/workspace/okr/RECOVERY_PROTOCOL.md +56 -0
  188. package/templates/workspace/okr/TASK_CHANGES.jsonl +6 -0
  189. package/templates/workspace/okr/WEEK_TASKS.json +6 -0
@@ -0,0 +1,3 @@
1
+ import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
2
+ export declare function handleBootstrapTools(ctx: PluginCommandContext): PluginCommandResult;
3
+ export declare function handleResearchTools(ctx: PluginCommandContext): PluginCommandResult;
@@ -0,0 +1,73 @@
1
+ import { execSync } from 'child_process';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { WorkspaceContext } from '../core/workspace-context.js';
5
+ const TOOLS_TO_SCAN = [
6
+ { name: 'rg', cmd: ['rg', '--version'] },
7
+ { name: 'sg', cmd: ['sg', '--version'] },
8
+ { name: 'fd', cmd: ['fd', '--version'] },
9
+ { name: 'qmd', cmd: ['qmd', '--version'] },
10
+ { name: 'ast-grep', cmd: ['ast-grep', '--version'] },
11
+ { name: 'shellcheck', cmd: ['shellcheck', '--version'] },
12
+ ];
13
+ function scanEnvironment(wctx) {
14
+ const tools = {};
15
+ for (const tool of TOOLS_TO_SCAN) {
16
+ try {
17
+ const output = execSync(tool.cmd.join(' '), { stdio: ['ignore', 'pipe', 'ignore'] }).toString();
18
+ tools[tool.name] = {
19
+ available: true,
20
+ version: output.split('\n')[0].trim(),
21
+ };
22
+ }
23
+ catch (_e) {
24
+ tools[tool.name] = { available: false };
25
+ }
26
+ }
27
+ const capabilities = {
28
+ platform: process.platform,
29
+ arch: process.arch,
30
+ node: process.version,
31
+ tools,
32
+ timestamp: new Date().toISOString(),
33
+ };
34
+ const capsPath = wctx.resolve('SYSTEM_CAPABILITIES');
35
+ const capsDir = path.dirname(capsPath);
36
+ if (!fs.existsSync(capsDir)) {
37
+ fs.mkdirSync(capsDir, { recursive: true });
38
+ }
39
+ fs.writeFileSync(capsPath, JSON.stringify(capabilities, null, 2), 'utf8');
40
+ return capabilities;
41
+ }
42
+ export function handleBootstrapTools(ctx) {
43
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
44
+ const wctx = WorkspaceContext.fromHookContext({ workspaceDir, ...ctx.config });
45
+ try {
46
+ const caps = scanEnvironment(wctx);
47
+ const toolsMap = caps.tools;
48
+ const available = Object.entries(toolsMap)
49
+ .filter(([, data]) => data.available)
50
+ .map(([name]) => `\`${name}\``)
51
+ .join(', ');
52
+ return {
53
+ text: `🔍 Environment perception complete.\n` +
54
+ `**Detected tools:** ${available || '(none)'}\n` +
55
+ `**Platform:** ${process.platform}\n` +
56
+ `Capabilities saved to \`.state/SYSTEM_CAPABILITIES.json\`.`,
57
+ };
58
+ }
59
+ catch (err) {
60
+ return { text: `❌ bootstrap-tools failed: ${err instanceof Error ? err.message : String(err)}` };
61
+ }
62
+ }
63
+ export function handleResearchTools(ctx) {
64
+ const category = ctx.args?.trim() || "modern high-performance CLI tools for coding and architecture";
65
+ return {
66
+ text: `🚀 **Tool Evolution Research Initiated**\n\n` +
67
+ `**Instructions for Agent:**\n` +
68
+ `1. Use \`google_web_search\` or \`web_search_exa\` to find the latest tools in the category: "${category}".\n` +
69
+ `2. Compare findings with current capabilities in \`.state/SYSTEM_CAPABILITIES.json\`.\n` +
70
+ `3. Focus on tools that improve speed (like \`rg\`, \`sg\`), documentation (like \`qmd\`), or automation.\n` +
71
+ `4. Output a "Tool Upgrade Proposal" with installation commands and justification.`,
72
+ };
73
+ }
@@ -0,0 +1,9 @@
1
+ import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
2
+ /**
3
+ * /evolve-task [task description]
4
+ *
5
+ * Returns instructions that tell the Agent to invoke the sessions_spawn tool
6
+ * targeting the evolver agent. Plugin command handlers cannot directly call
7
+ * Gateway tools — only the AI agent can do that via sessions_spawn.
8
+ */
9
+ export declare function handleEvolveTask(ctx: PluginCommandContext): PluginCommandResult;
@@ -0,0 +1,26 @@
1
+ import { WorkspaceContext } from '../core/workspace-context.js';
2
+ /**
3
+ * /evolve-task [task description]
4
+ *
5
+ * Returns instructions that tell the Agent to invoke the sessions_spawn tool
6
+ * targeting the evolver agent. Plugin command handlers cannot directly call
7
+ * Gateway tools — only the AI agent can do that via sessions_spawn.
8
+ */
9
+ export function handleEvolveTask(ctx) {
10
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
11
+ const wctx = WorkspaceContext.fromHookContext({ workspaceDir, ...ctx.config });
12
+ const painFlagPath = wctx.resolve('PAIN_FLAG');
13
+ const relPainFlag = painFlagPath.replace(workspaceDir, '').replace(/^\/+/, '');
14
+ const task = ctx.args?.trim() || `Diagnose and fix the latest pain signals in ${relPainFlag}.`;
15
+ return {
16
+ text: `🔧 **Evolver Handoff Requested**\n\n` +
17
+ `To spin up the Evolver sub-agent, the Agent should call the \`sessions_spawn\` tool with:\n\n` +
18
+ `**spawnId**: \`evolver\`\n` +
19
+ `**task**: "${task}"\n\n` +
20
+ `**Instructions for Agent:**\n` +
21
+ `1. Use \`sessions_spawn\` now.\n` +
22
+ `2. Target \`evolver\`.\n` +
23
+ `3. Pass the task above.\n` +
24
+ `4. No other tools needed until the sub-agent returns.`,
25
+ };
26
+ }
@@ -0,0 +1,5 @@
1
+ import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
2
+ /**
3
+ * Handles the /pd-status command
4
+ */
5
+ export declare function handlePainCommand(ctx: PluginCommandContext): PluginCommandResult;
@@ -0,0 +1,114 @@
1
+ import { resetFriction, getSession } from '../core/session-tracker.js';
2
+ import { WorkspaceContext } from '../core/workspace-context.js';
3
+ /**
4
+ * Creates a visual progress bar (e.g., [██████░░░░])
5
+ */
6
+ function createProgressBar(value, max, length = 10) {
7
+ const filledLength = Math.round((value / max) * length);
8
+ const emptyLength = length - filledLength;
9
+ return `[${'█'.repeat(filledLength)}${'░'.repeat(emptyLength)}]`;
10
+ }
11
+ /**
12
+ * Handles the /pd-status command
13
+ */
14
+ export function handlePainCommand(ctx) {
15
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
16
+ const wctx = WorkspaceContext.fromHookContext({ workspaceDir, ...ctx.config });
17
+ const lang = ctx.config?.language || 'en';
18
+ const isZh = lang === 'zh';
19
+ const sessionId = ctx.sessionId;
20
+ const args = (ctx.args || '').trim();
21
+ if (args === 'reset') {
22
+ if (sessionId) {
23
+ resetFriction(sessionId);
24
+ return { text: isZh ? `✅ 当前会话的 GFI 阻力已强制归零。` : `✅ GFI for current session reset to 0.` };
25
+ }
26
+ return { text: isZh ? `❌ 无法识别当前会话。` : `❌ Session ID not found. Use /pd-status reset in a chat session.` };
27
+ }
28
+ if (args === 'trust-reset') {
29
+ wctx.trust.resetTrust();
30
+ const newScore = wctx.trust.getScore();
31
+ return { text: isZh ? `✅ 智能体信任分已重置为初始值 (${newScore})。` : `✅ Agent trust score has been reset to initial value (${newScore}).` };
32
+ }
33
+ // Default: Show status
34
+ const session = sessionId ? getSession(sessionId) : undefined;
35
+ const gfi = session ? session.currentGfi : 0;
36
+ const dictionary = wctx.dictionary;
37
+ const stats = dictionary.getStats();
38
+ const trust = wctx.trust;
39
+ const trustScore = trust.getScore();
40
+ const trustStage = trust.getStage();
41
+ const gfiBar = createProgressBar(gfi, 100, 15);
42
+ const trustBar = createProgressBar(trustScore, 100, 15);
43
+ // Determine health status based on GFI
44
+ let healthLabel = 'Healthy';
45
+ let suggestionText = '';
46
+ if (isZh) {
47
+ if (gfi > 80 || trustStage === 1) {
48
+ healthLabel = gfi > 80 ? '极度疲劳 🔴' : '信任破产 🔴';
49
+ suggestionText = `
50
+ 💡 **建议 (系统检测到您当前遇到较大阻力)**:
51
+ 1. 执行 \`/pd-status reset\` 清零疲劳值。
52
+ 2. 执行 \`/pd-status trust-reset\` 重置信任分。
53
+ 3. 让 AI 调用 \`deep_reflect\` 工具进行深度反思。
54
+ 4. 如果当前上下文太乱,考虑使用 \`/clear\` 开启新会话。`;
55
+ }
56
+ else if (gfi > 50)
57
+ healthLabel = '遇到阻力 🟡';
58
+ else if (gfi > 20)
59
+ healthLabel = '轻微受挫 🟢';
60
+ else
61
+ healthLabel = '运转良好 🟢';
62
+ }
63
+ else {
64
+ if (gfi > 80 || trustStage === 1) {
65
+ healthLabel = gfi > 80 ? 'Critical 🔴' : 'Trust Bankruptcy 🔴';
66
+ suggestionText = `
67
+ 💡 **Suggestion (High friction or low trust detected)**:
68
+ 1. Run \`/pd-status reset\` to clear friction.
69
+ 2. Run \`/pd-status trust-reset\` to reset trust score.
70
+ 3. Ask the AI to use the \`deep_reflect\` tool.
71
+ 4. Consider starting a new session with \`/clear\`.`;
72
+ }
73
+ else if (gfi > 50)
74
+ healthLabel = 'High Friction 🟡';
75
+ else if (gfi > 20)
76
+ healthLabel = 'Minor Issues 🟢';
77
+ else
78
+ healthLabel = 'Healthy 🟢';
79
+ }
80
+ if (isZh) {
81
+ let text = `📊 **Principles Disciple - 系统健康度监控**\n`;
82
+ text += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
83
+ text += `💊 **当前疲劳指数 (GFI)**: ${gfiBar} ${gfi}/100\n`;
84
+ text += `💰 **当前信任积分 (Trust)**: ${trustBar} ${trustScore}/100 (Stage ${trustStage})\n`;
85
+ text += ` ↳ 状态诊断: ${healthLabel}\n\n`;
86
+ text += `🧠 **痛苦进化词典**: 已吸收 ${stats.totalRules} 条规则\n`;
87
+ text += ` ↳ 累计帮您拦截了 ${stats.totalHits} 次无效操作\n`;
88
+ text += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
89
+ if (suggestionText) {
90
+ text += suggestionText;
91
+ }
92
+ else {
93
+ text += `*💡 提示: 如果 AI 陷入死循环,您可以使用 \`/pd-status reset\` 来强制清零疲劳值。*`;
94
+ }
95
+ return { text };
96
+ }
97
+ else {
98
+ let text = `📊 **Principles Disciple - System Health Monitor**\n`;
99
+ text += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
100
+ text += `💊 **Current Friction (GFI)**: ${gfiBar} ${gfi}/100\n`;
101
+ text += `💰 **Current Trust Score**: ${trustBar} ${trustScore}/100 (Stage ${trustStage})\n`;
102
+ text += ` ↳ Diagnosis: ${healthLabel}\n\n`;
103
+ text += `🧠 **Evolution Dictionary**: ${stats.totalRules} active rules\n`;
104
+ text += ` ↳ Successfully blocked ${stats.totalHits} invalid operations\n`;
105
+ text += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
106
+ if (suggestionText) {
107
+ text += suggestionText;
108
+ }
109
+ else {
110
+ text += `*💡 Hint: If the AI is stuck in a loop, use \`/pd-status reset\` to clear friction and restart.*`;
111
+ }
112
+ return { text };
113
+ }
114
+ }
@@ -0,0 +1,3 @@
1
+ import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
2
+ export declare function handleInitStrategy(ctx: PluginCommandContext): PluginCommandResult;
3
+ export declare function handleManageOkr(ctx: PluginCommandContext): PluginCommandResult;
@@ -0,0 +1,29 @@
1
+ import { WorkspaceContext } from '../core/workspace-context.js';
2
+ export function handleInitStrategy(ctx) {
3
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
4
+ const wctx = WorkspaceContext.fromHookContext({ workspaceDir, ...ctx.config });
5
+ const okrDir = wctx.resolve('OKR_DIR').replace(workspaceDir, '').replace(/^\/+/, '');
6
+ const focusPath = wctx.resolve('CURRENT_FOCUS').replace(workspaceDir, '').replace(/^\/+/, '');
7
+ const userContextPath = wctx.resolve('USER_CONTEXT').replace(workspaceDir, '').replace(/^\/+/, '');
8
+ return {
9
+ text: `🎯 **Strategy Initialization**\n\n` +
10
+ `The Agent will now conduct a deep interview to establish your project's vision and strategic OKRs.\n\n` +
11
+ `**Instructions for Agent:** Read \`${okrDir}/\` for existing context. ` +
12
+ `Generate \`${focusPath}\` with the top 1-3 strategic focus areas based on the user interview. ` +
13
+ `Then update \`${userContextPath}\` with key user preferences discovered.`,
14
+ };
15
+ }
16
+ export function handleManageOkr(ctx) {
17
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
18
+ const wctx = WorkspaceContext.fromHookContext({ workspaceDir, ...ctx.config });
19
+ const focusPath = wctx.resolve('CURRENT_FOCUS').replace(workspaceDir, '').replace(/^\/+/, '');
20
+ const weekStatePath = wctx.resolve('WEEK_STATE').replace(workspaceDir, '').replace(/^\/+/, '');
21
+ return {
22
+ text: `📊 **OKR Management**\n\n` +
23
+ `The Agent will analyze recent work and align sub-agent objectives.\n\n` +
24
+ `**Instructions for Agent:** Read \`${focusPath}\` and \`${weekStatePath}\`. ` +
25
+ `Compare them against recent session history. ` +
26
+ `Update OKRs as needed and output a brief alignment report. ` +
27
+ `If OKRs are stale (>7 days), prompt the user for a re-alignment conversation.`,
28
+ };
29
+ }
@@ -0,0 +1,2 @@
1
+ import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
2
+ export declare function handleThinkingOs(ctx: PluginCommandContext): PluginCommandResult;
@@ -0,0 +1,162 @@
1
+ import * as fs from 'fs';
2
+ import { WorkspaceContext } from '../core/workspace-context.js';
3
+ function getWorkspaceDir(ctx) {
4
+ return ctx.config?.workspaceDir || process.cwd();
5
+ }
6
+ function getModels(wctx) {
7
+ const modelsPath = wctx.resolve('THINKING_OS');
8
+ const models = {};
9
+ if (!fs.existsSync(modelsPath))
10
+ return models;
11
+ try {
12
+ const content = fs.readFileSync(modelsPath, 'utf8');
13
+ const lines = content.split('\n');
14
+ for (const line of lines) {
15
+ const match = line.match(/^###\s*(T-\d+):\s*(.*)/);
16
+ if (match) {
17
+ models[match[1]] = match[2].trim();
18
+ }
19
+ }
20
+ }
21
+ catch (e) {
22
+ console.debug('[PD] Failed to read THINKING_OS.md:', e);
23
+ }
24
+ return models;
25
+ }
26
+ function formatUsageReport(wctx) {
27
+ const logPath = wctx.resolve('THINKING_OS_USAGE');
28
+ if (!fs.existsSync(logPath)) {
29
+ return '📊 No usage data yet. The Thinking OS has not been active long enough to collect statistics.';
30
+ }
31
+ try {
32
+ const usage = JSON.parse(fs.readFileSync(logPath, 'utf8'));
33
+ const totalTurns = usage['_total_turns'] || 1;
34
+ const models = getModels(wctx);
35
+ let report = `# 🧠 Thinking OS — Usage Report\n\n`;
36
+ report += `Total turns tracked: **${totalTurns}**\n\n`;
37
+ report += `| Model | Name | Hits | Rate |\n|---|---|---|---|\n`;
38
+ for (const [id, name] of Object.entries(models)) {
39
+ const hits = usage[id] || 0;
40
+ const rate = totalTurns > 0 ? ((hits / totalTurns) * 100).toFixed(1) : '0.0';
41
+ const status = hits === 0 ? '⚠️' : (parseFloat(rate) < 5 ? '🔸' : '✅');
42
+ report += `| ${id} | ${name} | ${hits} | ${status} ${rate}% |\n`;
43
+ }
44
+ const dormant = Object.entries(models)
45
+ .filter(([id]) => (usage[id] || 0) === 0)
46
+ .map(([id, name]) => `- ${id}: ${name}`);
47
+ if (dormant.length > 0) {
48
+ report += `\n### ⚠️ Dormant Models (0 hits)\n${dormant.join('\n')}\n`;
49
+ report += `\nConsider: Are these models not applicable to current tasks, or is the agent ignoring them?\n`;
50
+ }
51
+ return report;
52
+ }
53
+ catch (e) {
54
+ return `❌ Failed to read usage data: ${String(e)}`;
55
+ }
56
+ }
57
+ function handlePropose(wctx, proposal) {
58
+ if (!proposal.trim()) {
59
+ return '❌ Usage: `/thinking-os propose <description of your proposed mental model>`';
60
+ }
61
+ if (!proposal.toLowerCase().includes('signal') && !proposal.includes('信号')) {
62
+ return '❌ Invalid proposal: A mental model must include a "Signal detection / 信号检测" section explaining how to detect its usage via regex.';
63
+ }
64
+ const candidatesPath = wctx.resolve('THINKING_OS_CANDIDATES');
65
+ if (fs.existsSync(candidatesPath)) {
66
+ try {
67
+ const content = fs.readFileSync(candidatesPath, 'utf8');
68
+ const snippet = proposal.substring(0, 30);
69
+ if (content.includes(snippet)) {
70
+ return '❌ Duplicate proposal detected. A similar candidate already exists.';
71
+ }
72
+ }
73
+ catch (e) {
74
+ console.debug('[PD] Error reading candidates file:', e);
75
+ }
76
+ }
77
+ const timestamp = new Date().toISOString();
78
+ const entry = `\n### Candidate (${timestamp})\n${proposal.trim()}\n- Status: PENDING\n- Validated in tasks: 0/3\n---\n`;
79
+ try {
80
+ fs.appendFileSync(candidatesPath, entry, 'utf8');
81
+ return `✅ Mental model proposal recorded in \`${candidatesPath.replace(wctx.workspaceDir, '')}\`.\nIt needs validation in ≥3 different task types and human approval before promotion.`;
82
+ }
83
+ catch (e) {
84
+ return `❌ Failed to write proposal: ${String(e)}`;
85
+ }
86
+ }
87
+ function formatAuditReport(wctx) {
88
+ const logPath = wctx.resolve('THINKING_OS_USAGE');
89
+ const thinkingOsPath = wctx.resolve('THINKING_OS');
90
+ let report = `# 🔍 Thinking OS — Audit Report\n\n`;
91
+ if (!fs.existsSync(thinkingOsPath)) {
92
+ report += `⚠️ **THINKING_OS.md not found.** The cognitive layer is not active.\n`;
93
+ return report;
94
+ }
95
+ const models = getModels(wctx);
96
+ const modelCount = Object.keys(models).length;
97
+ report += `**Active models**: ${modelCount}\n\n`;
98
+ if (!fs.existsSync(logPath)) {
99
+ report += `📊 No usage data collected yet. Run some tasks first.\n`;
100
+ return report;
101
+ }
102
+ try {
103
+ const usage = JSON.parse(fs.readFileSync(logPath, 'utf8'));
104
+ const totalTurns = usage['_total_turns'] || 1;
105
+ const overused = [];
106
+ const underused = [];
107
+ const healthy = [];
108
+ for (const [id, name] of Object.entries(models)) {
109
+ const hits = usage[id] || 0;
110
+ const rate = (hits / totalTurns) * 100;
111
+ if (rate > 50)
112
+ overused.push(`- ${id} (${name}): ${rate.toFixed(1)}% — possibly too broad a pattern?`);
113
+ else if (hits === 0 && totalTurns > 10)
114
+ underused.push(`- ${id} (${name}): 0 hits in ${totalTurns} turns — candidate for archival?`);
115
+ else
116
+ healthy.push(`- ${id} (${name}): ${rate.toFixed(1)}%`);
117
+ }
118
+ if (healthy.length > 0)
119
+ report += `### ✅ Healthy\n${healthy.join('\n')}\n\n`;
120
+ if (overused.length > 0)
121
+ report += `### 🔸 Possibly Over-triggered\n${overused.join('\n')}\n\n`;
122
+ if (underused.length > 0) {
123
+ report += `### ⚠️ Candidate for Archival\n${underused.join('\n')}\n`;
124
+ report += `> 💡 Suggestion: Review these models. If they are obsolete, move them to the archive.\n\n`;
125
+ }
126
+ const candidatesPath = wctx.resolve('THINKING_OS_CANDIDATES');
127
+ if (fs.existsSync(candidatesPath)) {
128
+ const candidates = fs.readFileSync(candidatesPath, 'utf8');
129
+ const pendingCount = (candidates.match(/Status: PENDING/g) || []).length;
130
+ if (pendingCount > 0) {
131
+ report += `### 📝 Pending Candidates: ${pendingCount}\nReview candidates to fill gaps.\n`;
132
+ }
133
+ }
134
+ return report;
135
+ }
136
+ catch (e) {
137
+ return `❌ Failed to generate audit report: ${String(e)}`;
138
+ }
139
+ }
140
+ export function handleThinkingOs(ctx) {
141
+ const workspaceDir = getWorkspaceDir(ctx);
142
+ const wctx = WorkspaceContext.fromHookContext({ workspaceDir, ...ctx.config });
143
+ const args = (ctx.args || '').trim();
144
+ const subCommand = args.split(/\s+/)[0]?.toLowerCase();
145
+ const rest = args.slice(subCommand?.length || 0).trim();
146
+ switch (subCommand) {
147
+ case 'status':
148
+ return { text: formatUsageReport(wctx) };
149
+ case 'propose':
150
+ return { text: handlePropose(wctx, rest) };
151
+ case 'audit':
152
+ return { text: formatAuditReport(wctx) };
153
+ default:
154
+ return {
155
+ text: `🧠 **Thinking OS — Governance Console**\n\n` +
156
+ `Usage:\n` +
157
+ `- \`/thinking-os status\` — View mental model usage statistics\n` +
158
+ `- \`/thinking-os propose <model description>\` — Propose a new mental model\n` +
159
+ `- \`/thinking-os audit\` — Audit model health and candidates`
160
+ };
161
+ }
162
+ }
@@ -0,0 +1,4 @@
1
+ import type { PluginHookAgentContext } from '../openclaw-sdk.js';
2
+ export declare function handleTrustCommand(ctx: PluginHookAgentContext & {
3
+ workspaceDir?: string;
4
+ }): string;
@@ -0,0 +1,95 @@
1
+ import { WorkspaceContext } from '../core/workspace-context.js';
2
+ /**
3
+ * Creates a visual progress bar (e.g., [██████░░░░])
4
+ */
5
+ function createProgressBar(value, max, length = 10) {
6
+ const filledLength = Math.round((value / max) * length);
7
+ const emptyLength = length - filledLength;
8
+ return `[${'█'.repeat(filledLength)}${'░'.repeat(emptyLength)}]`;
9
+ }
10
+ export function handleTrustCommand(ctx) {
11
+ const { workspaceDir } = ctx;
12
+ if (!workspaceDir)
13
+ return 'Error: Workspace directory not found.';
14
+ const wctx = WorkspaceContext.fromHookContext(ctx);
15
+ const trustEngine = wctx.trust;
16
+ const trustScore = trustEngine.getScore();
17
+ const trustSettings = wctx.config.get('trust');
18
+ const isZh = wctx.config.get('language') === 'zh';
19
+ let stage = 2;
20
+ let title = isZh ? '编辑者' : 'Editor';
21
+ let permissions = isZh
22
+ ? `- 允许小范围修改 (< ${trustSettings.limits.stage_2_max_lines} 行)\n- 禁止修改风险目录`
23
+ : `- Small modifications (< ${trustSettings.limits.stage_2_max_lines} lines)\n- Non-risk paths only`;
24
+ let nextLevel = `Trust Score >= ${trustSettings.stages.stage_3_developer}`;
25
+ if (trustScore < trustSettings.stages.stage_1_observer) {
26
+ stage = 1;
27
+ title = isZh ? '观察者 (只读模式)' : 'Observer (Read-only)';
28
+ permissions = isZh ? '- 仅限只读访问\n- 仅限诊断工具' : '- Read-only access\n- Diagnosis tools only';
29
+ nextLevel = `Trust Score >= ${trustSettings.stages.stage_1_observer}`;
30
+ }
31
+ else if (trustScore < trustSettings.stages.stage_2_editor) {
32
+ // Default stage 2
33
+ nextLevel = `Trust Score >= ${trustSettings.stages.stage_2_editor}`;
34
+ }
35
+ else if (trustScore < trustSettings.stages.stage_3_developer) {
36
+ stage = 3;
37
+ title = isZh ? '开发者' : 'Developer';
38
+ permissions = isZh
39
+ ? `- 允许中等范围修改 (< ${trustSettings.limits.stage_3_max_lines} 行)\n- 风险目录修改需要有 PLAN (计划)`
40
+ : `- Medium modifications (< ${trustSettings.limits.stage_3_max_lines} lines)\n- Risk paths require READY plan`;
41
+ nextLevel = `Trust Score >= ${trustSettings.stages.stage_3_developer}`;
42
+ }
43
+ else {
44
+ stage = 4;
45
+ title = isZh ? '架构师' : 'Architect';
46
+ permissions = isZh ? '- 🚨 **无限制访问**\n- 计划和审计非强制要求' : '- 🚨 **UNRESTRICTED access**\n- Plan and Audit are optional';
47
+ nextLevel = isZh ? '已达最高级' : 'MAX LEVEL REACHED';
48
+ }
49
+ const progressBar = createProgressBar(trustScore, 100, 15);
50
+ const hygiene = wctx.hygiene.getStats();
51
+ const persistenceScore = Math.min(100, hygiene.persistenceCount * 10); // 10 points per persistence
52
+ const hygieneBar = createProgressBar(persistenceScore, 100, 15);
53
+ if (isZh) {
54
+ return `
55
+ 📊 **Principles Disciple - 系统状态看板**
56
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
57
+ 🛡️ **安全阶级**: Stage ${stage} (${title})
58
+ 💰 **信任积分**: ${progressBar} ${trustScore}/100
59
+ 🧠 **认知卫生**: ${hygieneBar} ${hygiene.persistenceCount} 次落盘 (今日)
60
+
61
+ **当前操作权限**:
62
+ ${permissions}
63
+
64
+ **今日知识沉淀**:
65
+ - 物理落盘: ${hygiene.persistenceCount} 次
66
+ - 累计字符: ${hygiene.totalCharsPersisted} chars
67
+ - 空间整理: ${hygiene.groomingExecutedCount > 0 ? '🟢 良好' : '🟡 待整理'}
68
+
69
+ **下一次晋升条件**: ${nextLevel}
70
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
71
+ *💡 提示:勤记笔记 (PLAN.md/memory) 有助于对抗上下文遗忘,提升系统稳定性。*
72
+ `.trim();
73
+ }
74
+ else {
75
+ return `
76
+ 📊 **Principles Disciple - System Dashboard**
77
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
78
+ 🛡️ **Security Stage**: Stage ${stage} (${title})
79
+ 💰 **Trust Score**: ${progressBar} ${trustScore}/100
80
+ 🧠 **Cognitive Hygiene**: ${hygieneBar} ${hygiene.persistenceCount} actions (Today)
81
+
82
+ **Current Permissions**:
83
+ ${permissions}
84
+
85
+ **Knowledge Assets Today**:
86
+ - Physical Persists: ${hygiene.persistenceCount} actions
87
+ - Total Chars: ${hygiene.totalCharsPersisted} chars
88
+ - Workspace Grooming: ${hygiene.groomingExecutedCount > 0 ? '🟢 Good' : '🟡 Pending'}
89
+
90
+ **Next Promotion Requirement**: ${nextLevel}
91
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
92
+ *💡 Hint: Frequent notes (PLAN.md/memory) prevent amnesia and ensure task continuity.*
93
+ `.trim();
94
+ }
95
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Agent Definition Loader
3
+ *
4
+ * Parses agent definitions from agents/*.md files.
5
+ * These definitions are used to construct extraSystemPrompt for subagent runs.
6
+ */
7
+ /**
8
+ * Parsed agent definition from markdown file
9
+ */
10
+ export interface AgentDefinition {
11
+ /** Agent identifier (e.g., 'explorer', 'diagnostician') */
12
+ name: string;
13
+ /** Human-readable description */
14
+ description: string;
15
+ /** The markdown body (system prompt for subagent) */
16
+ systemPrompt: string;
17
+ /** Tools the agent can use (informational, not enforced by OpenClaw) */
18
+ tools?: string[];
19
+ /** Preferred model (informational, OpenClaw subagents use parent model) */
20
+ model?: string;
21
+ /** Permission mode (informational) */
22
+ permissionMode?: string;
23
+ /** Associated skills */
24
+ skills?: string[];
25
+ }
26
+ /**
27
+ * Load agent definition by name
28
+ *
29
+ * @param name - Agent name (e.g., 'explorer', 'diagnostician')
30
+ * @returns Agent definition or null if not found
31
+ */
32
+ export declare function loadAgentDefinition(name: string): AgentDefinition | null;
33
+ /**
34
+ * List all available agents
35
+ *
36
+ * @returns Array of agent names
37
+ */
38
+ export declare function listAvailableAgents(): string[];
39
+ /**
40
+ * Load all agent definitions
41
+ *
42
+ * @returns Map of agent name to definition
43
+ */
44
+ export declare function loadAllAgents(): Map<string, AgentDefinition>;