principles-disciple 1.191.0 → 1.193.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/pain.js +24 -0
- package/dist/core/system-logger.d.ts +16 -0
- package/dist/core/system-logger.js +53 -19
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/commands/pain.js
CHANGED
|
@@ -171,6 +171,18 @@ export function handlePainCommand(ctx) {
|
|
|
171
171
|
if (suggestionText) {
|
|
172
172
|
text += suggestionText;
|
|
173
173
|
}
|
|
174
|
+
else if (stats.totalRules === 0 && stats.totalHits === 0) {
|
|
175
|
+
// Fix-14 (P1-DESIGN-2): Empty-state onboarding guidance for fresh installs.
|
|
176
|
+
// Merges Fix-13's welcome message here instead of injecting into the
|
|
177
|
+
// before_prompt_build hook (avoids MVP-Core behavior change).
|
|
178
|
+
text += `\n🦞 **欢迎使用 Principles Disciple!**\n\n`;
|
|
179
|
+
text += `当前是全新工作区,还没有痛觉信号 —— 这是正常的。\n\n`;
|
|
180
|
+
text += `**下一步**:\n`;
|
|
181
|
+
text += `1. 让 Agent 工作,当它犯错时运行 \`/pd-pain <描述问题>\`\n`;
|
|
182
|
+
text += `2. 或运行演示: \`pd demo first-principle\`\n`;
|
|
183
|
+
text += `3. 配置 LLM runtime profile: \`pd console open --workspace "<path>"\`\n\n`;
|
|
184
|
+
text += `审批通过的原则会出现在这里。`;
|
|
185
|
+
}
|
|
174
186
|
else {
|
|
175
187
|
text += `*💡 提示: 使用 \`/pd-status empathy\` 查看详细情绪事件统计。*`;
|
|
176
188
|
}
|
|
@@ -189,6 +201,18 @@ export function handlePainCommand(ctx) {
|
|
|
189
201
|
if (suggestionText) {
|
|
190
202
|
text += suggestionText;
|
|
191
203
|
}
|
|
204
|
+
else if (stats.totalRules === 0 && stats.totalHits === 0) {
|
|
205
|
+
// Fix-14 (P1-DESIGN-2): Empty-state onboarding guidance for fresh installs.
|
|
206
|
+
// Merges Fix-13's welcome message here instead of injecting into the
|
|
207
|
+
// before_prompt_build hook (avoids MVP-Core behavior change).
|
|
208
|
+
text += `\n🦞 **Welcome to Principles Disciple!**\n\n`;
|
|
209
|
+
text += `This is a fresh workspace with no pain signals yet — that's expected.\n\n`;
|
|
210
|
+
text += `**Next steps**:\n`;
|
|
211
|
+
text += `1. Let your agent work and run \`/pd-pain <description>\` when it makes a mistake\n`;
|
|
212
|
+
text += `2. Or run the demo: \`pd demo first-principle\`\n`;
|
|
213
|
+
text += `3. Configure LLM runtime profile: \`pd console open --workspace "<path>"\`\n\n`;
|
|
214
|
+
text += `Approved principles will appear here once activated.`;
|
|
215
|
+
}
|
|
192
216
|
else {
|
|
193
217
|
text += `*💡 Hint: Use \`/pd-status empathy\` to view detailed empathy event statistics.*`;
|
|
194
218
|
}
|
|
@@ -3,6 +3,22 @@ export declare const SystemLogger: {
|
|
|
3
3
|
/**
|
|
4
4
|
* Force refresh of the cached log file path.
|
|
5
5
|
* Call this at midnight or when the date changes to ensure proper rotation.
|
|
6
|
+
*
|
|
7
|
+
* PRI-504: clears log-file and log-date caches for ALL workspaces (preserves
|
|
8
|
+
* the original "force refresh" semantics). Does NOT clear lastCleanupDates
|
|
9
|
+
* to avoid re-triggering cleanup for every workspace on the same day.
|
|
6
10
|
*/
|
|
7
11
|
refreshCache(): void;
|
|
8
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* PRI-504: dispose the SystemLogger cache for a single workspace.
|
|
15
|
+
* Useful for tests and for workspace teardown in multi-workspace processes.
|
|
16
|
+
* Pattern follows evolution-engine.ts:564-570 (disposeEvolutionEngine).
|
|
17
|
+
*/
|
|
18
|
+
export declare function disposeSystemLogger(workspaceDir: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* PRI-504: dispose ALL SystemLogger caches. Call this in test afterEach
|
|
21
|
+
* hooks to prevent state leakage between tests. Pattern follows
|
|
22
|
+
* evolution-engine.ts:572-577 (disposeAllEvolutionEngines).
|
|
23
|
+
*/
|
|
24
|
+
export declare function disposeAllSystemLoggers(): void;
|
|
@@ -11,9 +11,13 @@ import { resolvePdPath, PD_FILES } from './paths.js';
|
|
|
11
11
|
* Automatically rotates to a new file at midnight.
|
|
12
12
|
* Old log files are automatically cleaned up based on retention policy.
|
|
13
13
|
*/
|
|
14
|
-
//
|
|
15
|
-
let
|
|
16
|
-
|
|
14
|
+
// PRI-504: per-workspace caches keyed by path.resolve(workspaceDir).
|
|
15
|
+
// Previously these were module-level `let` variables, so the first workspace
|
|
16
|
+
// to call log() would pin the log file path for ALL subsequent workspaces in
|
|
17
|
+
// the same process — causing cross-workspace log leakage (ERR-092).
|
|
18
|
+
// Pattern follows evolution-engine.ts:551-577 (Map + path.resolve + dispose).
|
|
19
|
+
const cachedLogFiles = new Map();
|
|
20
|
+
const cachedLogDates = new Map();
|
|
17
21
|
/**
|
|
18
22
|
* Log retention: delete SYSTEM logs older than this many days.
|
|
19
23
|
* Set to 0 to disable cleanup.
|
|
@@ -64,28 +68,33 @@ function cleanupOldLogs(workspaceDir) {
|
|
|
64
68
|
// Silently fail cleanup - don't crash logging for cleanup failures
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
|
-
//
|
|
68
|
-
|
|
71
|
+
// PRI-504: per-workspace cleanup tracker (was module-level `let`).
|
|
72
|
+
// Keyed by path.resolve(workspaceDir) so each workspace runs its own
|
|
73
|
+
// daily cleanup independently.
|
|
74
|
+
const lastCleanupDates = new Map();
|
|
69
75
|
export const SystemLogger = {
|
|
70
76
|
log(workspaceDir, eventType, message) {
|
|
71
77
|
if (!workspaceDir)
|
|
72
78
|
return;
|
|
73
79
|
try {
|
|
80
|
+
const resolved = path.resolve(workspaceDir);
|
|
74
81
|
const today = getTodayStr();
|
|
75
|
-
// Check if date changed - invalidate cache and run cleanup
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// Run cleanup once per day when date changes
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
+
// Check if date changed for THIS workspace - invalidate its cache and run cleanup
|
|
83
|
+
if (cachedLogDates.get(resolved) !== today) {
|
|
84
|
+
cachedLogDates.set(resolved, today);
|
|
85
|
+
cachedLogFiles.delete(resolved);
|
|
86
|
+
// Run cleanup once per day per workspace when date changes
|
|
87
|
+
if (lastCleanupDates.get(resolved) !== today) {
|
|
88
|
+
lastCleanupDates.set(resolved, today);
|
|
82
89
|
cleanupOldLogs(workspaceDir);
|
|
83
90
|
}
|
|
84
91
|
}
|
|
85
|
-
// Get or create log file path
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
// Get or create log file path for this workspace
|
|
93
|
+
let logFile = cachedLogFiles.get(resolved);
|
|
94
|
+
if (!logFile) {
|
|
95
|
+
logFile = getSystemLogPath(workspaceDir, new Date());
|
|
96
|
+
cachedLogFiles.set(resolved, logFile);
|
|
97
|
+
const logDir = path.dirname(logFile);
|
|
89
98
|
if (!fs.existsSync(logDir)) {
|
|
90
99
|
fs.mkdirSync(logDir, { recursive: true });
|
|
91
100
|
}
|
|
@@ -94,7 +103,7 @@ export const SystemLogger = {
|
|
|
94
103
|
// Format: [YYYY-MM-DDTHH:mm:ss.sssZ] [EVENT_TYPE] Message
|
|
95
104
|
const logEntry = `[${timestamp}] [${eventType.padEnd(15)}] ${message}\n`;
|
|
96
105
|
// Use fire-and-forget async append to prevent blocking
|
|
97
|
-
fs.appendFile(
|
|
106
|
+
fs.appendFile(logFile, logEntry, 'utf8', (_err) => {
|
|
98
107
|
// Silently drop errors (e.g. disk full) to not crash the gateway
|
|
99
108
|
});
|
|
100
109
|
}
|
|
@@ -105,9 +114,34 @@ export const SystemLogger = {
|
|
|
105
114
|
/**
|
|
106
115
|
* Force refresh of the cached log file path.
|
|
107
116
|
* Call this at midnight or when the date changes to ensure proper rotation.
|
|
117
|
+
*
|
|
118
|
+
* PRI-504: clears log-file and log-date caches for ALL workspaces (preserves
|
|
119
|
+
* the original "force refresh" semantics). Does NOT clear lastCleanupDates
|
|
120
|
+
* to avoid re-triggering cleanup for every workspace on the same day.
|
|
108
121
|
*/
|
|
109
122
|
refreshCache() {
|
|
110
|
-
|
|
111
|
-
|
|
123
|
+
cachedLogFiles.clear();
|
|
124
|
+
cachedLogDates.clear();
|
|
112
125
|
}
|
|
113
126
|
};
|
|
127
|
+
/**
|
|
128
|
+
* PRI-504: dispose the SystemLogger cache for a single workspace.
|
|
129
|
+
* Useful for tests and for workspace teardown in multi-workspace processes.
|
|
130
|
+
* Pattern follows evolution-engine.ts:564-570 (disposeEvolutionEngine).
|
|
131
|
+
*/
|
|
132
|
+
export function disposeSystemLogger(workspaceDir) {
|
|
133
|
+
const resolved = path.resolve(workspaceDir);
|
|
134
|
+
cachedLogFiles.delete(resolved);
|
|
135
|
+
cachedLogDates.delete(resolved);
|
|
136
|
+
lastCleanupDates.delete(resolved);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* PRI-504: dispose ALL SystemLogger caches. Call this in test afterEach
|
|
140
|
+
* hooks to prevent state leakage between tests. Pattern follows
|
|
141
|
+
* evolution-engine.ts:572-577 (disposeAllEvolutionEngines).
|
|
142
|
+
*/
|
|
143
|
+
export function disposeAllSystemLoggers() {
|
|
144
|
+
cachedLogFiles.clear();
|
|
145
|
+
cachedLogDates.clear();
|
|
146
|
+
lastCleanupDates.clear();
|
|
147
|
+
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "principles-disciple",
|
|
3
3
|
"name": "Principles Disciple",
|
|
4
4
|
"description": "Evolutionary programming agent framework with strategic guardrails and reflection loops.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.193.0",
|
|
6
6
|
"activation": {
|
|
7
7
|
"onCapabilities": [
|
|
8
8
|
"hook"
|