create-principles-disciple 1.147.7 → 1.147.8
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/_release/product-identity.json +1 -1
- package/core/dist/host/host-installer.d.ts +15 -0
- package/core/dist/host/host-installer.d.ts.map +1 -1
- package/core/dist/host/host-installer.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +2 -2
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -1
- package/core/dist/runtime-v2/pain-recall-capability.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-recall-capability.js +53 -2
- package/core/dist/runtime-v2/pain-recall-capability.js.map +1 -1
- package/core/dist/runtime-v2/pain-recall-read-model.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-recall-read-model.js +60 -5
- package/core/dist/runtime-v2/pain-recall-read-model.js.map +1 -1
- package/core/dist/runtime-v2/signal-collector/keyword-stage.d.ts.map +1 -1
- package/core/dist/runtime-v2/signal-collector/keyword-stage.js +35 -0
- package/core/dist/runtime-v2/signal-collector/keyword-stage.js.map +1 -1
- package/core/package.json +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -29
- package/dist/index.js.map +1 -1
- package/dist/install-summary.d.ts +38 -0
- package/dist/install-summary.d.ts.map +1 -0
- package/dist/install-summary.js +115 -0
- package/dist/install-summary.js.map +1 -0
- package/dist/installer.d.ts +36 -0
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +120 -26
- package/dist/installer.js.map +1 -1
- package/dist/installers/workbuddy-host-installer.d.ts +51 -17
- package/dist/installers/workbuddy-host-installer.d.ts.map +1 -1
- package/dist/installers/workbuddy-host-installer.js +510 -186
- package/dist/installers/workbuddy-host-installer.js.map +1 -1
- package/dist/prompts.js +1 -1
- package/dist/prompts.js.map +1 -1
- package/host-runtime/dist/governance-signal-admission.d.ts +2 -2
- package/host-runtime/dist/governance-signal-admission.js +2 -6
- package/host-runtime/package.json +1 -1
- package/package.json +3 -3
- package/pd-cli/dist/commands/health-mcp.d.ts +19 -0
- package/pd-cli/dist/commands/health-mcp.d.ts.map +1 -1
- package/pd-cli/dist/commands/health-mcp.js +226 -0
- package/pd-cli/dist/commands/health-mcp.js.map +1 -1
- package/pd-cli/dist/commands/health.d.ts.map +1 -1
- package/pd-cli/dist/commands/health.js +18 -1
- package/pd-cli/dist/commands/health.js.map +1 -1
- package/pd-cli/dist/commands/mcp-logs-export.d.ts +7 -0
- package/pd-cli/dist/commands/mcp-logs-export.d.ts.map +1 -0
- package/pd-cli/dist/commands/mcp-logs-export.js +267 -0
- package/pd-cli/dist/commands/mcp-logs-export.js.map +1 -0
- package/pd-cli/dist/commands/workbuddy-worker.d.ts.map +1 -1
- package/pd-cli/dist/commands/workbuddy-worker.js +2 -1
- package/pd-cli/dist/commands/workbuddy-worker.js.map +1 -1
- package/pd-cli/dist/index.js +35 -0
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/services/zip-writer.d.ts +6 -0
- package/pd-cli/dist/services/zip-writer.d.ts.map +1 -0
- package/pd-cli/dist/services/zip-writer.js +97 -0
- package/pd-cli/dist/services/zip-writer.js.map +1 -0
- package/pd-mcp-server/dist/index.d.ts +1 -0
- package/pd-mcp-server/dist/index.js +167 -10
- package/pd-mcp-server/dist/log-file.d.ts +26 -0
- package/pd-mcp-server/dist/log-file.js +312 -0
- package/pd-mcp-server/dist/logging.d.ts +2 -1
- package/pd-mcp-server/dist/logging.js +25 -14
- package/pd-mcp-server/dist/server.js +78 -24
- package/pd-mcp-server/dist/version.d.ts +1 -1
- package/pd-mcp-server/dist/version.js +1 -1
- package/pd-mcp-server/dist/workspace.d.ts +3 -0
- package/pd-mcp-server/dist/workspace.js +5 -0
- package/pd-mcp-server/package.json +1 -1
- package/plugin/dist/bundle.js +274 -273
- package/plugin/dist/openclaw.plugin.json +1 -1
- package/plugin/mcp/launcher.cjs +561 -0
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
- package/release-manager/dist/installer.js +120 -26
- package/release-manager/dist/installers/workbuddy-host-installer.js +510 -186
- package/release-manager/package.json +1 -1
- package/workbuddy-adapter/dist/pd-hook.js +3 -2
- package/workbuddy-adapter/package.json +1 -1
- package/workbuddy-adapter/plugin/.codebuddy-plugin/plugin.json +1 -1
- package/workbuddy-adapter/plugin/mcp/launcher.cjs +215 -1
- package/workbuddy-adapter/plugin/skills/pd-pain-signal/SKILL.md +4 -0
|
@@ -3444,40 +3444,124 @@ function assertUsableWorkspaceDir(workspaceDir) {
|
|
|
3444
3444
|
'Re-run with the path quoted, so the shell cannot strip its separators:\n' +
|
|
3445
3445
|
' --workspace "D:\\.openclaw\\workspace"');
|
|
3446
3446
|
}
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3447
|
+
/**
|
|
3448
|
+
* Where the OpenClaw plugin (and therefore the MCP launcher) reads the
|
|
3449
|
+
* Owner-declared governance workspace. The gateway process, hook processes and
|
|
3450
|
+
* MCP children all run with different environments, and the MCP child has its
|
|
3451
|
+
* environment sanitized by the host (PD_WORKSPACE_DIR / HOME are stripped), so
|
|
3452
|
+
* this FILE is the only signal every one of them can see.
|
|
3453
|
+
*/
|
|
3454
|
+
const OPENCLAW_PD_CONFIG_FILENAME = 'principles-disciple.json';
|
|
3455
|
+
function describeError(error) {
|
|
3456
|
+
return error instanceof Error ? error.message : String(error);
|
|
3457
|
+
}
|
|
3458
|
+
/** Same-directory identity for a workspace pointer (Windows is case-insensitive). */
|
|
3459
|
+
function sameWorkspaceTarget(left, right) {
|
|
3460
|
+
const normalize = (value) => {
|
|
3461
|
+
const resolved = path.resolve(value);
|
|
3462
|
+
const trimmed = resolved.length > 1 ? resolved.replace(/[\\/]+$/, '') : resolved;
|
|
3463
|
+
return process.platform === 'win32' ? trimmed.toLowerCase() : trimmed;
|
|
3464
|
+
};
|
|
3465
|
+
return normalize(left) === normalize(right);
|
|
3466
|
+
}
|
|
3467
|
+
/**
|
|
3468
|
+
* Read the existing declaration as UNTRUSTED input (it is a plain file on disk)
|
|
3469
|
+
* and classify it. Never overwrites and never silently repairs anything.
|
|
3470
|
+
*/
|
|
3471
|
+
export function inspectOpenClawWorkspaceDeclaration(workspaceDir) {
|
|
3472
|
+
const configPath = path.join(getOpenClawDir(), OPENCLAW_PD_CONFIG_FILENAME);
|
|
3473
|
+
if (!existsSync(configPath))
|
|
3474
|
+
return { configPath, state: 'absent' };
|
|
3475
|
+
let raw;
|
|
3476
|
+
try {
|
|
3477
|
+
raw = readFileSync(configPath, 'utf-8');
|
|
3478
|
+
}
|
|
3479
|
+
catch (e) {
|
|
3480
|
+
return { configPath, state: 'unreadable', reason: describeError(e) };
|
|
3481
|
+
}
|
|
3482
|
+
let parsed;
|
|
3483
|
+
try {
|
|
3484
|
+
parsed = JSON.parse(raw);
|
|
3485
|
+
}
|
|
3486
|
+
catch (e) {
|
|
3487
|
+
return { configPath, state: 'invalid', reason: `it is not valid JSON (${describeError(e)})` };
|
|
3488
|
+
}
|
|
3489
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
3490
|
+
return { configPath, state: 'invalid', reason: 'the root value is not a JSON object' };
|
|
3491
|
+
}
|
|
3492
|
+
const declaredRaw = Object.hasOwn(parsed, 'workspace') ? Reflect.get(parsed, 'workspace') : undefined;
|
|
3493
|
+
if (typeof declaredRaw !== 'string' || declaredRaw.trim().length === 0) {
|
|
3494
|
+
return { configPath, state: 'invalid', reason: 'it has no non-empty string "workspace" field' };
|
|
3495
|
+
}
|
|
3496
|
+
const declared = declaredRaw.trim();
|
|
3497
|
+
if (!isUsableWorkspacePointer(declared)) {
|
|
3498
|
+
return {
|
|
3499
|
+
configPath,
|
|
3500
|
+
state: 'invalid',
|
|
3501
|
+
declaredWorkspace: declared,
|
|
3502
|
+
reason: 'the "workspace" value does not name one fixed absolute directory',
|
|
3503
|
+
};
|
|
3504
|
+
}
|
|
3505
|
+
if (!sameWorkspaceTarget(declared, workspaceDir)) {
|
|
3506
|
+
return { configPath, state: 'conflict', declaredWorkspace: declared };
|
|
3507
|
+
}
|
|
3508
|
+
return { configPath, state: 'compatible', declaredWorkspace: declared };
|
|
3509
|
+
}
|
|
3510
|
+
function throwOnIncompatibleDeclaration(inspection, workspaceDir) {
|
|
3511
|
+
if (inspection.state === 'absent' || inspection.state === 'compatible')
|
|
3512
|
+
return;
|
|
3513
|
+
if (inspection.state === 'conflict') {
|
|
3514
|
+
throw new Error('An existing OpenClaw PD config declares a DIFFERENT workspace; it was left unchanged.\n' +
|
|
3515
|
+
` Config: ${inspection.configPath}\n` +
|
|
3516
|
+
` Declared: ${JSON.stringify(inspection.declaredWorkspace)}\n` +
|
|
3517
|
+
` Requested: ${JSON.stringify(path.resolve(workspaceDir))}\n` +
|
|
3518
|
+
'The pd-recall MCP server can only serve the workspace declared in this file, so the installer\n' +
|
|
3519
|
+
'never overwrites it. Otherwise the host would report a successful install while recall served\n' +
|
|
3520
|
+
'another workspace.\n' +
|
|
3521
|
+
` To keep the existing workspace, re-run with --workspace ${JSON.stringify(inspection.declaredWorkspace)}.\n` +
|
|
3522
|
+
` To switch deliberately, back up ${inspection.configPath}, remove it, then re-run for the new workspace.`);
|
|
3523
|
+
}
|
|
3524
|
+
throw new Error(`The existing OpenClaw PD config cannot be verified and was left unchanged (${inspection.reason}).\n` +
|
|
3525
|
+
` Config: ${inspection.configPath}\n` +
|
|
3526
|
+
'Expected a JSON object with an absolute "workspace" string.\n' +
|
|
3527
|
+
' Fix it manually, or back it up and remove it, then re-run the installer.');
|
|
3528
|
+
}
|
|
3529
|
+
/**
|
|
3530
|
+
* Read-only preflight: refuse BEFORE any runtime mutation when the existing
|
|
3531
|
+
* declaration points somewhere else (or cannot be trusted). This is the check
|
|
3532
|
+
* that keeps an install from "succeeding" while pd-recall serves a different
|
|
3533
|
+
* workspace.
|
|
3534
|
+
*/
|
|
3535
|
+
export function assertOpenClawWorkspaceDeclarationCompatible(workspaceDir) {
|
|
3536
|
+
throwOnIncompatibleDeclaration(inspectOpenClawWorkspaceDeclaration(workspaceDir), workspaceDir);
|
|
3537
|
+
}
|
|
3538
|
+
/**
|
|
3539
|
+
* Ensure the OpenClaw plugin can locate the governance workspace through the
|
|
3540
|
+
* file declaration. Idempotent: a compatible existing declaration is left
|
|
3541
|
+
* byte-identical (no rewrite, no installedAt churn). A conflicting/invalid one
|
|
3542
|
+
* fails loud and is never overwritten.
|
|
3543
|
+
*/
|
|
3544
|
+
export async function ensureOpenClawWorkspaceDeclaration(workspaceDir, channels) {
|
|
3450
3545
|
// Defense in depth: the same refusal the install entry makes, kept here
|
|
3451
3546
|
// because this is the only writer of the pointer the plugin reads on every
|
|
3452
3547
|
// hook, and other callers reach it without passing through install().
|
|
3453
3548
|
assertUsableWorkspaceDir(workspaceDir);
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
if (
|
|
3457
|
-
|
|
3458
|
-
const existing = JSON.parse(existingRaw);
|
|
3459
|
-
if (existing !== null && typeof existing === 'object' && !Array.isArray(existing)) {
|
|
3460
|
-
const existingObj = existing;
|
|
3461
|
-
if (Object.hasOwn(existingObj, 'channels') && Array.isArray(existingObj.channels)) {
|
|
3462
|
-
existingChannels = existingObj.channels.filter((c) => typeof c === 'string');
|
|
3463
|
-
}
|
|
3464
|
-
if (Object.hasOwn(existingObj, 'features') && Array.isArray(existingObj.features)) {
|
|
3465
|
-
existingFeatures = existingObj.features.filter((f) => typeof f === 'string');
|
|
3466
|
-
}
|
|
3467
|
-
}
|
|
3549
|
+
const inspection = inspectOpenClawWorkspaceDeclaration(workspaceDir);
|
|
3550
|
+
throwOnIncompatibleDeclaration(inspection, workspaceDir);
|
|
3551
|
+
if (inspection.state === 'compatible') {
|
|
3552
|
+
return { configPath: inspection.configPath, action: 'unchanged' };
|
|
3468
3553
|
}
|
|
3554
|
+
const resolvedWorkspace = path.resolve(workspaceDir);
|
|
3469
3555
|
const config = {
|
|
3470
|
-
workspace:
|
|
3471
|
-
state: path.join(
|
|
3472
|
-
channels
|
|
3556
|
+
workspace: resolvedWorkspace,
|
|
3557
|
+
state: path.join(resolvedWorkspace, '.state'),
|
|
3558
|
+
channels,
|
|
3473
3559
|
installedAt: new Date().toISOString(),
|
|
3474
3560
|
mvpFirst: true,
|
|
3475
3561
|
};
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
}
|
|
3479
|
-
await fse.ensureDir(configDir);
|
|
3480
|
-
await fse.writeJson(configPath, config, { spaces: 2 });
|
|
3562
|
+
await fse.ensureDir(path.dirname(inspection.configPath));
|
|
3563
|
+
await fse.writeJson(inspection.configPath, config, { spaces: 2 });
|
|
3564
|
+
return { configPath: inspection.configPath, action: 'created' };
|
|
3481
3565
|
}
|
|
3482
3566
|
/**
|
|
3483
3567
|
* ADR-0020 §2.3: Run host installers for the selected HostTarget.
|
|
@@ -3872,6 +3956,14 @@ transaction) {
|
|
|
3872
3956
|
// (permissions / invalid path) flows into the unified failure result
|
|
3873
3957
|
// below instead of rejecting the install() promise (P1 review finding).
|
|
3874
3958
|
await fse.ensureDir(path.resolve(options.workspaceDir));
|
|
3959
|
+
// OpenClaw only: the MCP launcher re-derives the governance workspace from
|
|
3960
|
+
// this PD-owned file, because the host strips PD_WORKSPACE_DIR / HOME from
|
|
3961
|
+
// MCP children. An existing declaration for a DIFFERENT workspace must
|
|
3962
|
+
// refuse the install BEFORE any runtime mutation — otherwise the install
|
|
3963
|
+
// would report success while pd-recall served another workspace.
|
|
3964
|
+
if (installsOpenClaw(options.host)) {
|
|
3965
|
+
assertOpenClawWorkspaceDeclarationCompatible(options.workspaceDir);
|
|
3966
|
+
}
|
|
3875
3967
|
if (spinner)
|
|
3876
3968
|
updateProgress(spinner, stepIndex, 'Checking built plugin...');
|
|
3877
3969
|
await checkBuiltPlugin(pluginDir);
|
|
@@ -4116,7 +4208,9 @@ transaction) {
|
|
|
4116
4208
|
stepIndex++;
|
|
4117
4209
|
if (spinner)
|
|
4118
4210
|
updateProgress(spinner, stepIndex, 'Creating config...');
|
|
4119
|
-
|
|
4211
|
+
if (installsOpenClaw(options.host)) {
|
|
4212
|
+
await ensureOpenClawWorkspaceDeclaration(options.workspaceDir, options.channels);
|
|
4213
|
+
}
|
|
4120
4214
|
stepIndex++;
|
|
4121
4215
|
// PRI-686 Fix C: after pinning PD canonical, check OpenClaw's resolved
|
|
4122
4216
|
// main-agent workspace against it. Read-only; a divergence means PD
|