create-principles-disciple 1.78.0 → 1.80.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/console/package.json +1 -0
- package/core/dist/runtime-v2/__tests__/fixtures/llm-e2e-config.d.ts.map +1 -1
- package/core/dist/runtime-v2/__tests__/fixtures/llm-e2e-config.js +4 -2
- package/core/dist/runtime-v2/__tests__/fixtures/llm-e2e-config.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/peer-runner-lineage-injection.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/peer-runner-lineage-injection.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/peer-runner-lineage-injection.test.js +95 -0
- package/core/dist/runtime-v2/internalization/__tests__/peer-runner-lineage-injection.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.js +3 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/dreamer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/dreamer-runner.js +5 -1
- package/core/dist/runtime-v2/internalization/dreamer-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js +3 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/peer-runner-contracts.d.ts +14 -0
- package/core/dist/runtime-v2/internalization/peer-runner-contracts.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/peer-runner-contracts.js +21 -0
- package/core/dist/runtime-v2/internalization/peer-runner-contracts.js.map +1 -1
- package/core/dist/runtime-v2/internalization/philosopher-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/philosopher-runner.js +3 -1
- package/core/dist/runtime-v2/internalization/philosopher-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js +3 -1
- package/core/dist/runtime-v2/internalization/rollout-reviewer-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.js +3 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/trainer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/trainer-runner.js +3 -1
- package/core/dist/runtime-v2/internalization/trainer-runner.js.map +1 -1
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +15 -0
- package/dist/installer.js.map +1 -1
- package/package.json +4 -4
- package/plugin/dist/hooks/prompt.js +4 -5
- package/plugin/dist/index.js +62 -42
- package/plugin/dist/utils/workspace-resolver.d.ts +33 -1
- package/plugin/dist/utils/workspace-resolver.js +182 -3
- package/plugin/package.json +3 -3
|
@@ -2,11 +2,17 @@
|
|
|
2
2
|
* Workspace Directory Resolution Utilities
|
|
3
3
|
*
|
|
4
4
|
* Shared helpers for resolving workspace directories across commands and hooks.
|
|
5
|
+
*
|
|
6
|
+
* Hook resolution priority (PRI-259): PD canonical config → OpenClaw fallback.
|
|
7
|
+
* PD canonical sources: PD_WORKSPACE_DIR env → OPENCLAW_WORKSPACE env →
|
|
8
|
+
* principles-disciple.json → ~/.openclaw/workspace default.
|
|
9
|
+
* OpenClaw fallback: ctx.workspaceDir → api.runtime.agent.resolveAgentWorkspaceDir().
|
|
5
10
|
*/
|
|
6
11
|
import { validateWorkspaceDir } from '../core/workspace-dir-validation.js';
|
|
7
|
-
import { resolveWorkspaceDir } from '../core/workspace-dir-service.js';
|
|
8
12
|
import { resolveWorkspaceDirFromApi } from '../core/path-resolver.js';
|
|
9
13
|
import * as path from 'path';
|
|
14
|
+
import * as os from 'os';
|
|
15
|
+
import * as fs from 'fs';
|
|
10
16
|
/**
|
|
11
17
|
* Resolve workspace directory for command execution.
|
|
12
18
|
*
|
|
@@ -69,12 +75,185 @@ export function resolvePluginCommandWorkspaceDir(ctx, source) {
|
|
|
69
75
|
throw new Error(`[PD:Command:${source}] CRITICAL: workspaceDir is not set in ctx.workspaceDir or ctx.config.workspaceDir. ` +
|
|
70
76
|
`Commands cannot execute without a valid workspace. Set OPENCLAW_WORKSPACE_DIR env var or ensure the workspace is properly initialized.`);
|
|
71
77
|
}
|
|
78
|
+
const PD_CONFIG_FILENAME = 'principles-disciple.json';
|
|
79
|
+
function loadWorkspaceFromPdConfigFile() {
|
|
80
|
+
const candidates = [
|
|
81
|
+
path.join(os.homedir(), '.openclaw', PD_CONFIG_FILENAME),
|
|
82
|
+
path.join(os.homedir(), '.principles', PD_CONFIG_FILENAME),
|
|
83
|
+
path.join(process.cwd(), PD_CONFIG_FILENAME),
|
|
84
|
+
];
|
|
85
|
+
for (const configPath of candidates) {
|
|
86
|
+
if (!fs.existsSync(configPath))
|
|
87
|
+
continue;
|
|
88
|
+
try {
|
|
89
|
+
const raw = fs.readFileSync(configPath, 'utf8');
|
|
90
|
+
const parsed = JSON.parse(raw);
|
|
91
|
+
if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
92
|
+
if (Object.hasOwn(parsed, 'workspace')) {
|
|
93
|
+
const workspaceValue = parsed['workspace'];
|
|
94
|
+
if (typeof workspaceValue === 'string' && workspaceValue.trim()) {
|
|
95
|
+
return workspaceValue.trim();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
export function resolveCanonicalWorkspaceDir() {
|
|
107
|
+
const pdEnv = process.env.PD_WORKSPACE_DIR;
|
|
108
|
+
if (pdEnv && pdEnv.trim()) {
|
|
109
|
+
const dir = path.resolve(pdEnv.trim());
|
|
110
|
+
if (!validateWorkspaceDir(dir)) {
|
|
111
|
+
return { workspaceDir: dir, source: 'pd_env' };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const ocEnv = process.env.OPENCLAW_WORKSPACE;
|
|
115
|
+
if (ocEnv && ocEnv.trim()) {
|
|
116
|
+
const dir = path.resolve(ocEnv.trim());
|
|
117
|
+
if (!validateWorkspaceDir(dir)) {
|
|
118
|
+
return { workspaceDir: dir, source: 'openclaw_env' };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const configWorkspace = loadWorkspaceFromPdConfigFile();
|
|
122
|
+
if (configWorkspace) {
|
|
123
|
+
const dir = path.resolve(configWorkspace);
|
|
124
|
+
if (!validateWorkspaceDir(dir)) {
|
|
125
|
+
return { workspaceDir: dir, source: 'pd_config' };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const defaultDir = path.join(os.homedir(), '.openclaw', 'workspace');
|
|
129
|
+
if (!validateWorkspaceDir(defaultDir)) {
|
|
130
|
+
return { workspaceDir: defaultDir, source: 'pd_default' };
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve only PD explicit sources (env vars + config file), excluding pd_default.
|
|
136
|
+
* Used by hook resolution to ensure ctx.workspaceDir takes priority over the
|
|
137
|
+
* hardcoded default fallback.
|
|
138
|
+
*/
|
|
139
|
+
function resolveExplicitPdSources() {
|
|
140
|
+
const pdEnv = process.env.PD_WORKSPACE_DIR;
|
|
141
|
+
if (pdEnv && pdEnv.trim()) {
|
|
142
|
+
const dir = path.resolve(pdEnv.trim());
|
|
143
|
+
if (!validateWorkspaceDir(dir)) {
|
|
144
|
+
return { workspaceDir: dir, source: 'pd_env' };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const ocEnv = process.env.OPENCLAW_WORKSPACE;
|
|
148
|
+
if (ocEnv && ocEnv.trim()) {
|
|
149
|
+
const dir = path.resolve(ocEnv.trim());
|
|
150
|
+
if (!validateWorkspaceDir(dir)) {
|
|
151
|
+
return { workspaceDir: dir, source: 'openclaw_env' };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const configWorkspace = loadWorkspaceFromPdConfigFile();
|
|
155
|
+
if (configWorkspace) {
|
|
156
|
+
const dir = path.resolve(configWorkspace);
|
|
157
|
+
if (!validateWorkspaceDir(dir)) {
|
|
158
|
+
return { workspaceDir: dir, source: 'pd_config' };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
function tryResolveFromOpenClawApi(api, agentId) {
|
|
164
|
+
try {
|
|
165
|
+
const resolved = api.runtime?.agent?.resolveAgentWorkspaceDir?.(api.config, agentId ?? 'main');
|
|
166
|
+
if (resolved && !validateWorkspaceDir(resolved)) {
|
|
167
|
+
return resolved;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// Fall through
|
|
172
|
+
}
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
export function resolveHookWorkspaceDir(ctx, api, source, options) {
|
|
176
|
+
// Priority 1: PD explicit sources (env vars + config file) — these are
|
|
177
|
+
// owner-declared and intentionally override the live session context.
|
|
178
|
+
const resolveExplicit = options?.explicitPdResolver ?? resolveExplicitPdSources;
|
|
179
|
+
const explicit = resolveExplicit();
|
|
180
|
+
if (explicit) {
|
|
181
|
+
let consistencyWarning;
|
|
182
|
+
if (ctx.workspaceDir) {
|
|
183
|
+
const normalizedCtx = path.resolve(ctx.workspaceDir);
|
|
184
|
+
const normalizedExplicit = path.resolve(explicit.workspaceDir);
|
|
185
|
+
if (normalizedCtx !== normalizedExplicit) {
|
|
186
|
+
consistencyWarning =
|
|
187
|
+
`PD explicit workspace (${explicit.source}: ${explicit.workspaceDir}) ` +
|
|
188
|
+
`differs from OpenClaw context (${ctx.workspaceDir}). Using PD explicit.`;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
ok: true,
|
|
193
|
+
workspaceDir: explicit.workspaceDir,
|
|
194
|
+
source: explicit.source,
|
|
195
|
+
consistencyWarning,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
// Priority 2: OpenClaw live context — the real session workspace.
|
|
199
|
+
// This MUST take priority over pd_default (the hardcoded fallback).
|
|
200
|
+
if (ctx.workspaceDir) {
|
|
201
|
+
const issue = validateWorkspaceDir(ctx.workspaceDir);
|
|
202
|
+
if (!issue) {
|
|
203
|
+
return {
|
|
204
|
+
ok: true,
|
|
205
|
+
workspaceDir: ctx.workspaceDir,
|
|
206
|
+
source: 'openclaw_context',
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Priority 3: OpenClaw API resolution
|
|
211
|
+
const apiResolved = tryResolveFromOpenClawApi(api, ctx.agentId);
|
|
212
|
+
if (apiResolved) {
|
|
213
|
+
return {
|
|
214
|
+
ok: true,
|
|
215
|
+
workspaceDir: apiResolved,
|
|
216
|
+
source: 'openclaw_api',
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
// Priority 4: pd_default (hardcoded fallback) — only when nothing else works
|
|
220
|
+
const resolveCanonical = options?.canonicalResolver ?? resolveCanonicalWorkspaceDir;
|
|
221
|
+
const canonical = resolveCanonical();
|
|
222
|
+
if (canonical && canonical.source === 'pd_default') {
|
|
223
|
+
return {
|
|
224
|
+
ok: true,
|
|
225
|
+
workspaceDir: canonical.workspaceDir,
|
|
226
|
+
source: 'pd_default',
|
|
227
|
+
consistencyWarning: 'Using hardcoded default workspace (~/.openclaw/workspace). ' +
|
|
228
|
+
'Set PD_WORKSPACE_DIR or create ~/.openclaw/principles-disciple.json for stable resolution.',
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
ok: false,
|
|
233
|
+
reason: 'workspace_dir_unresolvable',
|
|
234
|
+
nextAction: 'Set PD_WORKSPACE_DIR environment variable, create ~/.openclaw/principles-disciple.json ' +
|
|
235
|
+
'with a "workspace" field, or ensure OpenClaw provides workspaceDir in hook context.',
|
|
236
|
+
message: `[PD:${source}] Cannot resolve workspace directory from any source. ` +
|
|
237
|
+
`PD explicit config (PD_WORKSPACE_DIR, principles-disciple.json) ` +
|
|
238
|
+
`and OpenClaw fallback (ctx.workspaceDir, api.resolveAgentWorkspaceDir, ~/.openclaw/workspace) all failed.`,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
72
241
|
/**
|
|
73
242
|
* Resolve workspace directory for tool hook execution (safe version).
|
|
74
243
|
* Returns undefined instead of throwing if resolution fails.
|
|
244
|
+
*
|
|
245
|
+
* PRI-259: Uses PD canonical config as primary source, OpenClaw as fallback.
|
|
75
246
|
*/
|
|
76
|
-
export function resolveToolHookWorkspaceDirSafe(ctx, api, source) {
|
|
77
|
-
|
|
247
|
+
export function resolveToolHookWorkspaceDirSafe(ctx, api, source, options) {
|
|
248
|
+
const result = resolveHookWorkspaceDir(ctx, api, source, options);
|
|
249
|
+
if (!result.ok) {
|
|
250
|
+
api.logger.warn(result.message);
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
if (result.consistencyWarning) {
|
|
254
|
+
api.logger.warn(`[PD:${source}] ${result.consistencyWarning}`);
|
|
255
|
+
}
|
|
256
|
+
return result.workspaceDir;
|
|
78
257
|
}
|
|
79
258
|
export class WorkspaceResolutionError extends Error {
|
|
80
259
|
reason;
|
package/plugin/package.json
CHANGED
|
@@ -52,12 +52,12 @@
|
|
|
52
52
|
"@types/ws": "^8.5.13",
|
|
53
53
|
"@typescript-eslint/eslint-plugin": "^8.58.2",
|
|
54
54
|
"@typescript-eslint/parser": "^8.58.0",
|
|
55
|
-
"@vitest/coverage-v8": "^4.1.
|
|
55
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
56
56
|
"esbuild": "^0.28.0",
|
|
57
|
-
"eslint": "^10.
|
|
57
|
+
"eslint": "^10.4.1",
|
|
58
58
|
"jsdom": "^29.1.1",
|
|
59
59
|
"typescript": "^6.0.3",
|
|
60
|
-
"vitest": "^4.1.
|
|
60
|
+
"vitest": "^4.1.8",
|
|
61
61
|
"ws": "^8.18.0"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|