principles-disciple 1.5.4 → 1.6.0

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 (43) hide show
  1. package/dist/commands/context.d.ts +5 -0
  2. package/dist/commands/context.js +308 -0
  3. package/dist/commands/focus.d.ts +14 -0
  4. package/dist/commands/focus.js +579 -0
  5. package/dist/commands/pain.js +135 -6
  6. package/dist/commands/rollback.d.ts +19 -0
  7. package/dist/commands/rollback.js +119 -0
  8. package/dist/core/config.d.ts +32 -0
  9. package/dist/core/config.js +47 -0
  10. package/dist/core/event-log.d.ts +21 -1
  11. package/dist/core/event-log.js +316 -0
  12. package/dist/core/focus-history.d.ts +65 -0
  13. package/dist/core/focus-history.js +266 -0
  14. package/dist/core/init.js +30 -7
  15. package/dist/core/migration.js +0 -2
  16. package/dist/core/path-resolver.d.ts +3 -0
  17. package/dist/core/path-resolver.js +20 -0
  18. package/dist/hooks/gate.js +203 -1
  19. package/dist/hooks/llm.d.ts +8 -0
  20. package/dist/hooks/llm.js +234 -1
  21. package/dist/hooks/message-sanitize.d.ts +3 -0
  22. package/dist/hooks/message-sanitize.js +37 -0
  23. package/dist/hooks/prompt.d.ts +12 -0
  24. package/dist/hooks/prompt.js +309 -135
  25. package/dist/hooks/subagent.d.ts +9 -2
  26. package/dist/hooks/subagent.js +13 -2
  27. package/dist/i18n/commands.js +32 -20
  28. package/dist/index.js +181 -4
  29. package/dist/service/empathy-observer-manager.d.ts +42 -0
  30. package/dist/service/empathy-observer-manager.js +147 -0
  31. package/dist/service/evolution-worker.d.ts +1 -0
  32. package/dist/service/evolution-worker.js +4 -2
  33. package/dist/tools/deep-reflect.js +80 -0
  34. package/dist/types/event-types.d.ts +77 -2
  35. package/dist/types/event-types.js +33 -0
  36. package/dist/types.d.ts +42 -0
  37. package/dist/types.js +19 -1
  38. package/openclaw.plugin.json +1 -1
  39. package/package.json +3 -3
  40. package/templates/langs/zh/core/HEARTBEAT.md +28 -4
  41. package/templates/pain_settings.json +54 -2
  42. package/templates/workspace/.principles/PROFILE.json +2 -0
  43. package/templates/workspace/okr/CURRENT_FOCUS.md +57 -0
@@ -0,0 +1,5 @@
1
+ import type { PluginCommandContext, PluginCommandResult } from '../openclaw-sdk.js';
2
+ /**
3
+ * Main command handler
4
+ */
5
+ export declare function handleContextCommand(ctx: PluginCommandContext): PluginCommandResult;
@@ -0,0 +1,308 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { loadContextInjectionConfig } from '../hooks/prompt.js';
4
+ /**
5
+ * Get workspace directory from context
6
+ */
7
+ function getWorkspaceDir(ctx) {
8
+ const workspaceDir = ctx.config?.workspaceDir || process.cwd();
9
+ if (!workspaceDir) {
10
+ throw new Error('[PD:Context] workspaceDir is required but not provided');
11
+ }
12
+ return workspaceDir;
13
+ }
14
+ /**
15
+ * Save context injection config to PROFILE.json
16
+ */
17
+ function saveConfig(workspaceDir, config) {
18
+ const profilePath = path.join(workspaceDir, '.principles', 'PROFILE.json');
19
+ try {
20
+ // Ensure directory exists
21
+ const dir = path.dirname(profilePath);
22
+ if (!fs.existsSync(dir)) {
23
+ fs.mkdirSync(dir, { recursive: true });
24
+ }
25
+ // Load existing profile or create new one
26
+ let profile = {};
27
+ if (fs.existsSync(profilePath)) {
28
+ const raw = fs.readFileSync(profilePath, 'utf-8');
29
+ profile = JSON.parse(raw);
30
+ }
31
+ // Update contextInjection
32
+ profile.contextInjection = config;
33
+ // Write back
34
+ fs.writeFileSync(profilePath, JSON.stringify(profile, null, 2), 'utf-8');
35
+ return true;
36
+ }
37
+ catch (e) {
38
+ console.error(`[PD:Context] Failed to save config: ${String(e)}`);
39
+ return false;
40
+ }
41
+ }
42
+ /**
43
+ * Format project focus value for display
44
+ */
45
+ function formatProjectFocus(value, isZh) {
46
+ const labels = {
47
+ full: { zh: '📦 完整', en: '📦 Full' },
48
+ summary: { zh: '📝 摘要', en: '📝 Summary' },
49
+ off: { zh: '❌ 关闭', en: '❌ Off' }
50
+ };
51
+ return labels[value][isZh ? 'zh' : 'en'];
52
+ }
53
+ /**
54
+ * Show current context injection status
55
+ */
56
+ function showStatus(workspaceDir, isZh) {
57
+ const config = loadContextInjectionConfig(workspaceDir);
58
+ if (isZh) {
59
+ return `
60
+ 📊 **上下文注入状态**
61
+
62
+ | 内容 | 状态 | 说明 |
63
+ |------|------|------|
64
+ | 核心原则 | ✅ 始终开启 | 不可关闭 |
65
+ | 思维模型 | ${config.thinkingOs ? '✅ 开启' : '❌ 关闭'} | /pd-context thinking on/off |
66
+ | 信任分数 | ${config.trustScore ? '✅ 开启' : '❌ 关闭'} | /pd-context trust on/off |
67
+ | 反思日志 | ${config.reflectionLog ? '✅ 开启' : '❌ 关闭'} | /pd-context reflection on/off |
68
+ | 项目上下文 | ${formatProjectFocus(config.projectFocus, isZh)} | /pd-context focus full/summary/off |
69
+
70
+ 💡 输入 \`/pd-context help\` 查看更多选项
71
+ `.trim();
72
+ }
73
+ else {
74
+ return `
75
+ 📊 **Context Injection Status**
76
+
77
+ | Content | Status | Control |
78
+ |---------|--------|---------|
79
+ | Core Principles | ✅ Always ON | Not configurable |
80
+ | Thinking OS | ${config.thinkingOs ? '✅ ON' : '❌ OFF'} | /pd-context thinking on/off |
81
+ | Trust Score | ${config.trustScore ? '✅ ON' : '❌ OFF'} | /pd-context trust on/off |
82
+ | Reflection Log | ${config.reflectionLog ? '✅ ON' : '❌ OFF'} | /pd-context reflection on/off |
83
+ | Project Context | ${formatProjectFocus(config.projectFocus, isZh)} | /pd-context focus full/summary/off |
84
+
85
+ 💡 Type \`/pd-context help\` for more options
86
+ `.trim();
87
+ }
88
+ }
89
+ /**
90
+ * Toggle a boolean setting
91
+ */
92
+ function toggleSetting(workspaceDir, key, value, isZh) {
93
+ const config = loadContextInjectionConfig(workspaceDir);
94
+ const oldValue = config[key];
95
+ if (value === 'on') {
96
+ config[key] = true;
97
+ }
98
+ else if (value === 'off') {
99
+ config[key] = false;
100
+ }
101
+ else {
102
+ return isZh
103
+ ? `❌ 无效值: "${value}"。使用 "on" 或 "off"。`
104
+ : `❌ Invalid value: "${value}". Use "on" or "off".`;
105
+ }
106
+ const newValue = config[key];
107
+ const keyName = isZh
108
+ ? { thinkingOs: '思维模型', trustScore: '信任分数', reflectionLog: '反思日志' }[key]
109
+ : key;
110
+ // No change needed
111
+ if (oldValue === newValue) {
112
+ return isZh
113
+ ? `ℹ️ ${keyName} 已经是 ${newValue ? '开启' : '关闭'} 状态`
114
+ : `ℹ️ ${keyName} is already ${newValue ? 'ON' : 'OFF'}`;
115
+ }
116
+ if (saveConfig(workspaceDir, config)) {
117
+ // Verify the save by re-reading
118
+ const verifyConfig = loadContextInjectionConfig(workspaceDir);
119
+ const verifyValue = verifyConfig[key];
120
+ if (verifyValue !== newValue) {
121
+ return isZh
122
+ ? `⚠️ ${keyName} 保存后验证失败,请重试`
123
+ : `⚠️ ${keyName} verification failed after save, please retry`;
124
+ }
125
+ const arrow = isZh ? '→' : '→';
126
+ const oldLabel = oldValue ? (isZh ? '开启' : 'ON') : (isZh ? '关闭' : 'OFF');
127
+ const newLabel = newValue ? (isZh ? '开启' : 'ON') : (isZh ? '关闭' : 'OFF');
128
+ return isZh
129
+ ? `✅ ${keyName} 已更新: ${oldLabel} ${arrow} ${newLabel}\n\n💡 下次对话时生效`
130
+ : `✅ ${keyName} updated: ${oldLabel} ${arrow} ${newLabel}\n\n💡 Takes effect on next turn`;
131
+ }
132
+ else {
133
+ return isZh
134
+ ? `❌ 保存配置失败`
135
+ : `❌ Failed to save configuration`;
136
+ }
137
+ }
138
+ /**
139
+ * Set project focus mode
140
+ */
141
+ function setProjectFocus(workspaceDir, value, isZh) {
142
+ const config = loadContextInjectionConfig(workspaceDir);
143
+ const oldValue = config.projectFocus;
144
+ const validModes = ['full', 'summary', 'off'];
145
+ if (!validModes.includes(value)) {
146
+ return isZh
147
+ ? `❌ 无效值: "${value}"。使用 "full"、"summary" 或 "off"。`
148
+ : `❌ Invalid value: "${value}". Use "full", "summary", or "off".`;
149
+ }
150
+ const newValue = value;
151
+ config.projectFocus = newValue;
152
+ // No change needed
153
+ if (oldValue === newValue) {
154
+ return isZh
155
+ ? `ℹ️ 项目上下文已经是 ${formatProjectFocus(newValue, isZh)} 状态`
156
+ : `ℹ️ Project context is already ${formatProjectFocus(newValue, isZh)}`;
157
+ }
158
+ if (saveConfig(workspaceDir, config)) {
159
+ // Verify the save by re-reading
160
+ const verifyConfig = loadContextInjectionConfig(workspaceDir);
161
+ if (verifyConfig.projectFocus !== newValue) {
162
+ return isZh
163
+ ? `⚠️ 项目上下文保存后验证失败,请重试`
164
+ : `⚠️ Project context verification failed after save, please retry`;
165
+ }
166
+ const arrow = '→';
167
+ return isZh
168
+ ? `✅ 项目上下文已更新: ${formatProjectFocus(oldValue, isZh)} ${arrow} ${formatProjectFocus(newValue, isZh)}\n\n💡 下次对话时生效`
169
+ : `✅ Project context updated: ${formatProjectFocus(oldValue, isZh)} ${arrow} ${formatProjectFocus(newValue, isZh)}\n\n💡 Takes effect on next turn`;
170
+ }
171
+ else {
172
+ return isZh
173
+ ? `❌ 保存配置失败`
174
+ : `❌ Failed to save configuration`;
175
+ }
176
+ }
177
+ /**
178
+ * Apply a preset configuration
179
+ */
180
+ function applyPreset(workspaceDir, preset, isZh) {
181
+ let config;
182
+ switch (preset) {
183
+ case 'minimal':
184
+ config = {
185
+ thinkingOs: false,
186
+ trustScore: true,
187
+ reflectionLog: false,
188
+ projectFocus: 'off'
189
+ };
190
+ break;
191
+ case 'standard':
192
+ config = {
193
+ thinkingOs: true,
194
+ trustScore: true,
195
+ reflectionLog: false,
196
+ projectFocus: 'off'
197
+ };
198
+ break;
199
+ case 'full':
200
+ config = {
201
+ thinkingOs: true,
202
+ trustScore: true,
203
+ reflectionLog: true,
204
+ projectFocus: 'summary'
205
+ };
206
+ break;
207
+ }
208
+ if (saveConfig(workspaceDir, config)) {
209
+ const presetName = isZh
210
+ ? { minimal: '最小模式', standard: '标准模式', full: '完整模式' }[preset]
211
+ : `${preset} mode`;
212
+ return isZh
213
+ ? `✅ 已应用预设: ${presetName}\n\n${showStatus(workspaceDir, isZh)}`
214
+ : `✅ Applied preset: ${presetName}\n\n${showStatus(workspaceDir, isZh)}`;
215
+ }
216
+ else {
217
+ return isZh
218
+ ? `❌ 保存配置失败`
219
+ : `❌ Failed to save configuration`;
220
+ }
221
+ }
222
+ /**
223
+ * Show help message
224
+ */
225
+ function showHelp(isZh) {
226
+ if (isZh) {
227
+ return `
228
+ 📖 **/pd-context 命令帮助**
229
+
230
+ **查看状态**:
231
+ \`/pd-context status\` - 显示当前上下文注入状态
232
+
233
+ **单项控制**:
234
+ \`/pd-context thinking on/off\` - 开关思维模型
235
+ \`/pd-context trust on/off\` - 开关信任分数
236
+ \`/pd-context reflection on/off\` - 开关反思日志
237
+ \`/pd-context focus full/summary/off\` - 设置项目上下文模式
238
+
239
+ **预设模式**:
240
+ \`/pd-context minimal\` - 最小模式(仅信任分数)
241
+ \`/pd-context standard\` - 标准模式(原则+思维模型+信任分数)
242
+ \`/pd-context full\` - 完整模式(全部开启)
243
+
244
+ **注意**: 核心原则始终注入,不可关闭。
245
+ `.trim();
246
+ }
247
+ else {
248
+ return `
249
+ 📖 **/pd-context Command Help**
250
+
251
+ **View Status**:
252
+ \`/pd-context status\` - Show current context injection status
253
+
254
+ **Individual Control**:
255
+ \`/pd-context thinking on/off\` - Toggle Thinking OS
256
+ \`/pd-context trust on/off\` - Toggle Trust Score
257
+ \`/pd-context reflection on/off\` - Toggle Reflection Log
258
+ \`/pd-context focus full/summary/off\` - Set Project Context mode
259
+
260
+ **Presets**:
261
+ \`/pd-context minimal\` - Minimal mode (trust score only)
262
+ \`/pd-context standard\` - Standard mode (principles + thinking + trust)
263
+ \`/pd-context full\` - Full mode (all enabled)
264
+
265
+ **Note**: Core Principles are always injected and cannot be disabled.
266
+ `.trim();
267
+ }
268
+ }
269
+ /**
270
+ * Main command handler
271
+ */
272
+ export function handleContextCommand(ctx) {
273
+ const workspaceDir = getWorkspaceDir(ctx);
274
+ const args = (ctx.args || '').trim().split(/\s+/);
275
+ const subCommand = args[0]?.toLowerCase() || 'status';
276
+ const value = args[1]?.toLowerCase() || '';
277
+ // Detect language from context
278
+ const isZh = ctx.config?.language === 'zh';
279
+ let result;
280
+ switch (subCommand) {
281
+ case 'status':
282
+ result = showStatus(workspaceDir, isZh);
283
+ break;
284
+ case 'thinking':
285
+ result = toggleSetting(workspaceDir, 'thinkingOs', value, isZh);
286
+ break;
287
+ case 'trust':
288
+ result = toggleSetting(workspaceDir, 'trustScore', value, isZh);
289
+ break;
290
+ case 'reflection':
291
+ result = toggleSetting(workspaceDir, 'reflectionLog', value, isZh);
292
+ break;
293
+ case 'focus':
294
+ result = setProjectFocus(workspaceDir, value, isZh);
295
+ break;
296
+ case 'minimal':
297
+ case 'standard':
298
+ case 'full':
299
+ result = applyPreset(workspaceDir, subCommand, isZh);
300
+ break;
301
+ case 'help':
302
+ result = showHelp(isZh);
303
+ break;
304
+ default:
305
+ result = showHelp(isZh);
306
+ }
307
+ return { text: result };
308
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * /pd-focus 命令 - 管理 CURRENT_FOCUS.md
3
+ *
4
+ * 功能:
5
+ * - status: 查看当前状态和历史版本
6
+ * - compress: 手动压缩并备份
7
+ * - history: 查看历史版本列表
8
+ * - rollback: 回滚到指定历史版本
9
+ */
10
+ import type { PluginCommandContext, PluginCommandResult, OpenClawPluginApi } from '../openclaw-sdk.js';
11
+ /**
12
+ * 处理 /pd-focus 命令
13
+ */
14
+ export declare function handleFocusCommand(ctx: PluginCommandContext, api: OpenClawPluginApi): Promise<PluginCommandResult>;