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.
- package/dist/commands/context.d.ts +5 -0
- package/dist/commands/context.js +308 -0
- package/dist/commands/focus.d.ts +14 -0
- package/dist/commands/focus.js +579 -0
- package/dist/commands/pain.js +135 -6
- package/dist/commands/rollback.d.ts +19 -0
- package/dist/commands/rollback.js +119 -0
- package/dist/core/config.d.ts +32 -0
- package/dist/core/config.js +47 -0
- package/dist/core/event-log.d.ts +21 -1
- package/dist/core/event-log.js +316 -0
- package/dist/core/focus-history.d.ts +65 -0
- package/dist/core/focus-history.js +266 -0
- package/dist/core/init.js +30 -7
- package/dist/core/migration.js +0 -2
- package/dist/core/path-resolver.d.ts +3 -0
- package/dist/core/path-resolver.js +20 -0
- package/dist/hooks/gate.js +203 -1
- package/dist/hooks/llm.d.ts +8 -0
- package/dist/hooks/llm.js +234 -1
- package/dist/hooks/message-sanitize.d.ts +3 -0
- package/dist/hooks/message-sanitize.js +37 -0
- package/dist/hooks/prompt.d.ts +12 -0
- package/dist/hooks/prompt.js +309 -135
- package/dist/hooks/subagent.d.ts +9 -2
- package/dist/hooks/subagent.js +13 -2
- package/dist/i18n/commands.js +32 -20
- package/dist/index.js +181 -4
- package/dist/service/empathy-observer-manager.d.ts +42 -0
- package/dist/service/empathy-observer-manager.js +147 -0
- package/dist/service/evolution-worker.d.ts +1 -0
- package/dist/service/evolution-worker.js +4 -2
- package/dist/tools/deep-reflect.js +80 -0
- package/dist/types/event-types.d.ts +77 -2
- package/dist/types/event-types.js +33 -0
- package/dist/types.d.ts +42 -0
- package/dist/types.js +19 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -3
- package/templates/langs/zh/core/HEARTBEAT.md +28 -4
- package/templates/pain_settings.json +54 -2
- package/templates/workspace/.principles/PROFILE.json +2 -0
- package/templates/workspace/okr/CURRENT_FOCUS.md +57 -0
|
@@ -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>;
|