create-principles-disciple 1.79.0 → 1.81.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__/admission-gate.test.js +6 -6
- package/core/dist/runtime-v2/__tests__/admission-gate.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +39 -0
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/artificer-runner-vslice.test.js +52 -0
- package/core/dist/runtime-v2/__tests__/artificer-runner-vslice.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice.test.js +245 -1
- package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.js +131 -1
- package/core/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.js.map +1 -1
- 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/__tests__/scribe-runner-vslice.test.js +425 -2
- package/core/dist/runtime-v2/__tests__/scribe-runner-vslice.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/telemetry-event.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/telemetry-event.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/telemetry-event.test.js +69 -0
- package/core/dist/runtime-v2/__tests__/telemetry-event.test.js.map +1 -0
- package/core/dist/runtime-v2/admission-gate.d.ts.map +1 -1
- package/core/dist/runtime-v2/admission-gate.js +0 -8
- package/core/dist/runtime-v2/admission-gate.js.map +1 -1
- package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.d.ts +15 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js +685 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js.map +1 -0
- package/core/dist/runtime-v2/config/index.d.ts +14 -0
- package/core/dist/runtime-v2/config/index.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/index.js +16 -0
- package/core/dist/runtime-v2/config/index.js.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-defaults.d.ts +14 -0
- package/core/dist/runtime-v2/config/pd-config-defaults.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-defaults.js +74 -0
- package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-effective.d.ts +14 -0
- package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-effective.js +118 -0
- package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-feature-flags.d.ts +35 -0
- package/core/dist/runtime-v2/config/pd-config-feature-flags.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-feature-flags.js +99 -0
- package/core/dist/runtime-v2/config/pd-config-feature-flags.js.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-redaction.d.ts +22 -0
- package/core/dist/runtime-v2/config/pd-config-redaction.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-redaction.js +179 -0
- package/core/dist/runtime-v2/config/pd-config-redaction.js.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-types.d.ts +124 -0
- package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-types.js +35 -0
- package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-validate.d.ts +16 -0
- package/core/dist/runtime-v2/config/pd-config-validate.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-validate.js +443 -0
- package/core/dist/runtime-v2/config/pd-config-validate.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js +10 -10
- package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js.map +1 -1
- package/core/dist/runtime-v2/feedback/index.d.ts +1 -1
- package/core/dist/runtime-v2/feedback/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/feedback/index.js +1 -1
- package/core/dist/runtime-v2/feedback/index.js.map +1 -1
- package/core/dist/runtime-v2/feedback/redact-sensitive.d.ts +2 -0
- package/core/dist/runtime-v2/feedback/redact-sensitive.d.ts.map +1 -1
- package/core/dist/runtime-v2/feedback/redact-sensitive.js +32 -3
- package/core/dist/runtime-v2/feedback/redact-sensitive.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +5 -1
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +9 -1
- package/core/dist/runtime-v2/index.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/__tests__/philosopher-runner-trust-boundary.test.d.ts +2 -0
- package/core/dist/runtime-v2/internalization/__tests__/philosopher-runner-trust-boundary.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/philosopher-runner-trust-boundary.test.js +398 -0
- package/core/dist/runtime-v2/internalization/__tests__/philosopher-runner-trust-boundary.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/artificer-output.d.ts +3 -2
- package/core/dist/runtime-v2/internalization/artificer-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-output.js +40 -31
- package/core/dist/runtime-v2/internalization/artificer-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.d.ts +59 -38
- package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.js +122 -394
- package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/dreamer-output.d.ts +4 -3
- package/core/dist/runtime-v2/internalization/dreamer-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/dreamer-output.js +11 -9
- package/core/dist/runtime-v2/internalization/dreamer-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/dreamer-runner.d.ts +31 -92
- package/core/dist/runtime-v2/internalization/dreamer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/dreamer-runner.js +80 -492
- package/core/dist/runtime-v2/internalization/dreamer-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-output.d.ts +2 -2
- package/core/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-output.js +29 -23
- package/core/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts +74 -48
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js +165 -443
- 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-output.d.ts +8 -2
- package/core/dist/runtime-v2/internalization/philosopher-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/philosopher-output.js +16 -11
- package/core/dist/runtime-v2/internalization/philosopher-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/philosopher-runner.d.ts +36 -55
- package/core/dist/runtime-v2/internalization/philosopher-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/philosopher-runner.js +118 -400
- 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-output.d.ts +8 -2
- package/core/dist/runtime-v2/internalization/scribe-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-output.js +33 -17
- package/core/dist/runtime-v2/internalization/scribe-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.d.ts +56 -49
- package/core/dist/runtime-v2/internalization/scribe-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.js +117 -397
- 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/core/dist/runtime-v2/runner/__tests__/base-peer-runner-trust-boundary.test.d.ts +2 -0
- package/core/dist/runtime-v2/runner/__tests__/base-peer-runner-trust-boundary.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/runner/__tests__/base-peer-runner-trust-boundary.test.js +379 -0
- package/core/dist/runtime-v2/runner/__tests__/base-peer-runner-trust-boundary.test.js.map +1 -0
- package/core/dist/runtime-v2/runner/base-peer-runner.d.ts +122 -0
- package/core/dist/runtime-v2/runner/base-peer-runner.d.ts.map +1 -0
- package/core/dist/runtime-v2/runner/base-peer-runner.js +528 -0
- package/core/dist/runtime-v2/runner/base-peer-runner.js.map +1 -0
- package/core/dist/runtime-v2/runner/peer-runner-types.d.ts +107 -0
- package/core/dist/runtime-v2/runner/peer-runner-types.d.ts.map +1 -0
- package/core/dist/runtime-v2/runner/peer-runner-types.js +13 -0
- package/core/dist/runtime-v2/runner/peer-runner-types.js.map +1 -0
- package/core/dist/telemetry-event.d.ts +2 -2
- package/core/dist/telemetry-event.d.ts.map +1 -1
- package/core/dist/telemetry-event.js +89 -0
- package/core/dist/telemetry-event.js.map +1 -1
- package/dist/installer.d.ts +1 -1
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +39 -10
- package/dist/installer.js.map +1 -1
- package/dist/mvp-config.d.ts +33 -0
- package/dist/mvp-config.d.ts.map +1 -1
- package/dist/mvp-config.js +174 -0
- package/dist/mvp-config.js.map +1 -1
- package/package.json +3 -3
- package/pd-cli/dist/commands/config-doctor.d.ts +17 -0
- package/pd-cli/dist/commands/config-doctor.d.ts.map +1 -0
- package/pd-cli/dist/commands/config-doctor.js +143 -0
- package/pd-cli/dist/commands/config-doctor.js.map +1 -0
- package/pd-cli/dist/commands/console.d.ts +18 -0
- package/pd-cli/dist/commands/console.d.ts.map +1 -1
- package/pd-cli/dist/commands/console.js +439 -0
- package/pd-cli/dist/commands/console.js.map +1 -1
- package/pd-cli/dist/commands/runtime-features.d.ts +23 -8
- package/pd-cli/dist/commands/runtime-features.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-features.js +72 -31
- package/pd-cli/dist/commands/runtime-features.js.map +1 -1
- package/pd-cli/dist/index.d.ts +1 -1
- package/pd-cli/dist/index.js +83 -31
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/services/config-doctor.d.ts +102 -0
- package/pd-cli/dist/services/config-doctor.d.ts.map +1 -0
- package/pd-cli/dist/services/config-doctor.js +426 -0
- package/pd-cli/dist/services/config-doctor.js.map +1 -0
- package/pd-cli/dist/services/console-launcher.d.ts +110 -0
- package/pd-cli/dist/services/console-launcher.d.ts.map +1 -0
- package/pd-cli/dist/services/console-launcher.js +282 -0
- package/pd-cli/dist/services/console-launcher.js.map +1 -0
- package/pd-cli/dist/services/pd-config-loader.d.ts +64 -0
- package/pd-cli/dist/services/pd-config-loader.d.ts.map +1 -0
- package/pd-cli/dist/services/pd-config-loader.js +156 -0
- package/pd-cli/dist/services/pd-config-loader.js.map +1 -0
- package/pd-cli/package.json +3 -1
- package/plugin/dist/core/event-log.d.ts +10 -0
- package/plugin/dist/core/event-log.js +85 -1
- package/plugin/dist/core/pd-config-loader.d.ts +96 -0
- package/plugin/dist/core/pd-config-loader.js +307 -0
- package/plugin/dist/core/runtime-v2-prompt-activation-reader.d.ts +4 -0
- package/plugin/dist/core/runtime-v2-prompt-activation-reader.js +12 -56
- package/plugin/dist/core/surface-guard.d.ts +12 -8
- package/plugin/dist/core/surface-guard.js +51 -2
- package/plugin/dist/hooks/gate.js +3 -0
- package/plugin/dist/hooks/prompt.js +4 -5
- package/plugin/dist/index.d.ts +4 -0
- package/plugin/dist/index.js +70 -94
- package/plugin/dist/service/correction-observer-service.d.ts +8 -0
- package/plugin/dist/service/correction-observer-service.js +48 -29
- package/plugin/dist/utils/workspace-resolver.d.ts +33 -1
- package/plugin/dist/utils/workspace-resolver.js +182 -3
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PD Config Loader (Plugin I/O boundary) — PRI-307
|
|
3
|
+
*
|
|
4
|
+
* Reads `.pd/config.yaml`, validates via core, computes effective config.
|
|
5
|
+
* Replaces the old `.pd/feature-flags.yaml` and `.state/workflows.yaml` reading
|
|
6
|
+
* for plugin production paths.
|
|
7
|
+
*
|
|
8
|
+
* ADR-0016: PD owns exactly one user config file.
|
|
9
|
+
* - Missing config → defaults with nextAction
|
|
10
|
+
* - Malformed config → fail loud with errors and nextAction
|
|
11
|
+
* - No secrets in output
|
|
12
|
+
* - Observer disabled → no start / no noisy log cycling
|
|
13
|
+
* - Observer enabled + missing setup → structured needs_setup + nextAction
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from 'fs';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
import yaml from 'js-yaml';
|
|
18
|
+
import { validatePdConfig, computeEffectivePdConfig, computeFeatureFlagsFromConfig, INTERNAL_AGENT_NAMES, } from '@principles/core/runtime-v2';
|
|
19
|
+
// ── Constants ────────────────────────────────────────────────────────────────
|
|
20
|
+
export const PD_CONFIG_DIR = '.pd';
|
|
21
|
+
export const PD_CONFIG_FILENAME = 'config.yaml';
|
|
22
|
+
// ── Config Path ──────────────────────────────────────────────────────────────
|
|
23
|
+
export function getPdConfigPath(workspaceDir) {
|
|
24
|
+
return path.join(workspaceDir, PD_CONFIG_DIR, PD_CONFIG_FILENAME);
|
|
25
|
+
}
|
|
26
|
+
// ── Load PD Config ───────────────────────────────────────────────────────────
|
|
27
|
+
/**
|
|
28
|
+
* Load and validate `.pd/config.yaml` from the workspace.
|
|
29
|
+
* Never throws on malformed input. Always provides a usable fallback.
|
|
30
|
+
*/
|
|
31
|
+
export function loadPdConfigForPlugin(workspaceDir) {
|
|
32
|
+
const configPath = getPdConfigPath(workspaceDir);
|
|
33
|
+
// 1) Config file missing → use defaults
|
|
34
|
+
if (!fs.existsSync(configPath)) {
|
|
35
|
+
const effective = computeEffectivePdConfig(null);
|
|
36
|
+
return {
|
|
37
|
+
ok: true,
|
|
38
|
+
effective,
|
|
39
|
+
source: 'defaults',
|
|
40
|
+
configPath,
|
|
41
|
+
warnings: effective.warnings,
|
|
42
|
+
errors: [],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// 2) Read the file
|
|
46
|
+
let raw;
|
|
47
|
+
try {
|
|
48
|
+
raw = fs.readFileSync(configPath, 'utf8');
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
52
|
+
const effective = computeEffectivePdConfig(null);
|
|
53
|
+
return {
|
|
54
|
+
ok: false,
|
|
55
|
+
effective,
|
|
56
|
+
source: 'malformed',
|
|
57
|
+
configPath,
|
|
58
|
+
warnings: [],
|
|
59
|
+
errors: [{ path: '', reason: `Failed to read .pd/config.yaml: ${message}`, nextAction: 'Check file permissions for .pd/config.yaml' }],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// 3) Parse YAML — treat as unknown (ERR-001)
|
|
63
|
+
let parsed;
|
|
64
|
+
try {
|
|
65
|
+
parsed = yaml.load(raw, { schema: yaml.JSON_SCHEMA });
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
69
|
+
const effective = computeEffectivePdConfig(null);
|
|
70
|
+
return {
|
|
71
|
+
ok: false,
|
|
72
|
+
effective,
|
|
73
|
+
source: 'malformed',
|
|
74
|
+
configPath,
|
|
75
|
+
warnings: [],
|
|
76
|
+
errors: [{ path: '', reason: `YAML parse error in .pd/config.yaml: ${message}`, nextAction: 'Fix YAML syntax in .pd/config.yaml' }],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// 4) Validate via core (ERR-001, ERR-005: no `as` bypasses)
|
|
80
|
+
const validationResult = validatePdConfig(parsed);
|
|
81
|
+
if (!validationResult.ok) {
|
|
82
|
+
const effective = computeEffectivePdConfig(null);
|
|
83
|
+
return {
|
|
84
|
+
ok: false,
|
|
85
|
+
effective,
|
|
86
|
+
source: 'malformed',
|
|
87
|
+
configPath,
|
|
88
|
+
warnings: [],
|
|
89
|
+
errors: validationResult.errors.map(e => ({
|
|
90
|
+
path: e.path,
|
|
91
|
+
reason: e.reason,
|
|
92
|
+
nextAction: e.nextAction,
|
|
93
|
+
})),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// 5) Compute effective config
|
|
97
|
+
const effective = computeEffectivePdConfig(validationResult.value);
|
|
98
|
+
return {
|
|
99
|
+
ok: true,
|
|
100
|
+
effective,
|
|
101
|
+
source: 'user_config',
|
|
102
|
+
configPath,
|
|
103
|
+
warnings: effective.warnings,
|
|
104
|
+
errors: [],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// ── Feature Flag from Config ─────────────────────────────────────────────────
|
|
108
|
+
/**
|
|
109
|
+
* Get a single feature flag's enabled state from .pd/config.yaml.
|
|
110
|
+
* Replaces the old `loadFeatureFlagFromWorkspace` which read .pd/feature-flags.yaml.
|
|
111
|
+
*/
|
|
112
|
+
export function loadFeatureFlagFromConfig(workspaceDir, flagId, logger) {
|
|
113
|
+
const result = loadPdConfigForPlugin(workspaceDir);
|
|
114
|
+
const flags = computeFeatureFlagsFromConfig(result.effective);
|
|
115
|
+
const flag = flags.flags[flagId];
|
|
116
|
+
if (!result.ok) {
|
|
117
|
+
logger?.warn?.(`[PD:Config] Config validation failed: ${result.errors.map(e => e.reason).join('; ')} — using defaults`);
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
enabled: flag?.enabled ?? false,
|
|
121
|
+
source: result.source,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
// ── Observer Config Resolution ───────────────────────────────────────────────
|
|
125
|
+
/**
|
|
126
|
+
* Resolve observer configuration from .pd/config.yaml.
|
|
127
|
+
*
|
|
128
|
+
* Returns structured state:
|
|
129
|
+
* - config_malformed: config file is invalid — no guessing, fail loud
|
|
130
|
+
* - disabled: observer feature flag is off OR agent.enabled=false → no start, no noisy logs
|
|
131
|
+
* - needs_setup: observer enabled but runtime profile missing, API key not set, or unsupported profile type
|
|
132
|
+
* - ready: observer enabled and fully configured (pi-ai with key present)
|
|
133
|
+
* - not_ready: observer enabled, API key present, but runtime availability unknown
|
|
134
|
+
*/
|
|
135
|
+
export function resolveObserverConfig(workspaceDir, observerFlagId, observerAgentName, _logger) {
|
|
136
|
+
const result = loadPdConfigForPlugin(workspaceDir);
|
|
137
|
+
// 0) Malformed config → fail loud, do NOT swallow as "disabled"
|
|
138
|
+
if (!result.ok) {
|
|
139
|
+
return {
|
|
140
|
+
enabled: false,
|
|
141
|
+
readiness: 'config_malformed',
|
|
142
|
+
source: 'malformed',
|
|
143
|
+
reason: `Config validation failed: ${result.errors.map(e => e.reason).join('; ')}`,
|
|
144
|
+
nextAction: result.errors[0]?.nextAction ?? 'Fix .pd/config.yaml and retry',
|
|
145
|
+
runtimeProfileId: null,
|
|
146
|
+
runtimeProfileType: null,
|
|
147
|
+
apiKeyEnv: null,
|
|
148
|
+
apiKeyPresent: false,
|
|
149
|
+
provider: null,
|
|
150
|
+
model: null,
|
|
151
|
+
timeoutMs: null,
|
|
152
|
+
baseUrl: null,
|
|
153
|
+
configErrors: result.errors,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const config = result.effective.config;
|
|
157
|
+
// 1) Check if the observer feature flag is enabled
|
|
158
|
+
const featureFlag = config.features[observerFlagId];
|
|
159
|
+
if (!featureFlag || !featureFlag.enabled) {
|
|
160
|
+
return {
|
|
161
|
+
enabled: false,
|
|
162
|
+
readiness: 'disabled',
|
|
163
|
+
source: result.source,
|
|
164
|
+
reason: `${observerFlagId} is disabled in .pd/config.yaml`,
|
|
165
|
+
nextAction: `Set features.${observerFlagId}.enabled=true in .pd/config.yaml to enable`,
|
|
166
|
+
runtimeProfileId: null,
|
|
167
|
+
runtimeProfileType: null,
|
|
168
|
+
apiKeyEnv: null,
|
|
169
|
+
apiKeyPresent: false,
|
|
170
|
+
provider: null,
|
|
171
|
+
model: null,
|
|
172
|
+
timeoutMs: null,
|
|
173
|
+
baseUrl: null,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// 2) Check if the agent itself is enabled (feature flag ≠ agent.enabled)
|
|
177
|
+
const knownNames = INTERNAL_AGENT_NAMES;
|
|
178
|
+
if (!knownNames.includes(observerAgentName)) {
|
|
179
|
+
return {
|
|
180
|
+
enabled: false,
|
|
181
|
+
readiness: 'needs_setup',
|
|
182
|
+
source: result.source,
|
|
183
|
+
reason: `Unknown agent name '${observerAgentName}'`,
|
|
184
|
+
nextAction: `Use one of the known agent names: ${INTERNAL_AGENT_NAMES.join(', ')}`,
|
|
185
|
+
runtimeProfileId: null,
|
|
186
|
+
runtimeProfileType: null,
|
|
187
|
+
apiKeyEnv: null,
|
|
188
|
+
apiKeyPresent: false,
|
|
189
|
+
provider: null,
|
|
190
|
+
model: null,
|
|
191
|
+
timeoutMs: null,
|
|
192
|
+
baseUrl: null,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
const agentKey = observerAgentName;
|
|
196
|
+
const agentConfig = config.internalAgents.agents[agentKey];
|
|
197
|
+
// Feature flag on but agent.enabled=false → disabled (not enabled)
|
|
198
|
+
if (!agentConfig || !agentConfig.enabled) {
|
|
199
|
+
return {
|
|
200
|
+
enabled: false,
|
|
201
|
+
readiness: 'disabled',
|
|
202
|
+
source: result.source,
|
|
203
|
+
reason: `${observerFlagId} feature flag is enabled but internalAgents.agents.${observerAgentName}.enabled is false`,
|
|
204
|
+
nextAction: `Set internalAgents.agents.${observerAgentName}.enabled=true in .pd/config.yaml, or disable features.${observerFlagId}`,
|
|
205
|
+
runtimeProfileId: null,
|
|
206
|
+
runtimeProfileType: null,
|
|
207
|
+
apiKeyEnv: null,
|
|
208
|
+
apiKeyPresent: false,
|
|
209
|
+
provider: null,
|
|
210
|
+
model: null,
|
|
211
|
+
timeoutMs: null,
|
|
212
|
+
baseUrl: null,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// 3) Find the agent's runtime profile
|
|
216
|
+
const runtimeProfileId = agentConfig.runtimeProfile ?? config.internalAgents.defaultRuntime;
|
|
217
|
+
const profile = config.runtimeProfiles[runtimeProfileId];
|
|
218
|
+
if (!profile) {
|
|
219
|
+
return {
|
|
220
|
+
enabled: true,
|
|
221
|
+
readiness: 'needs_setup',
|
|
222
|
+
source: result.source,
|
|
223
|
+
reason: `Runtime profile '${runtimeProfileId}' not found in .pd/config.yaml`,
|
|
224
|
+
nextAction: `Add runtime profile '${runtimeProfileId}' to .pd/config.yaml runtimeProfiles`,
|
|
225
|
+
runtimeProfileId,
|
|
226
|
+
runtimeProfileType: null,
|
|
227
|
+
apiKeyEnv: null,
|
|
228
|
+
apiKeyPresent: false,
|
|
229
|
+
provider: null,
|
|
230
|
+
model: null,
|
|
231
|
+
timeoutMs: null,
|
|
232
|
+
baseUrl: null,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
// 4) For pi-ai profiles, check API key
|
|
236
|
+
if (profile.type === 'pi-ai') {
|
|
237
|
+
const apiKeyEnv = profile.apiKeyEnv ?? null;
|
|
238
|
+
const apiKeyPresent = !!apiKeyEnv && Object.prototype.hasOwnProperty.call(process.env, apiKeyEnv) && !!process.env[apiKeyEnv];
|
|
239
|
+
if (!apiKeyEnv) {
|
|
240
|
+
return {
|
|
241
|
+
enabled: true,
|
|
242
|
+
readiness: 'needs_setup',
|
|
243
|
+
source: result.source,
|
|
244
|
+
reason: `pi-ai profile '${runtimeProfileId}' missing apiKeyEnv`,
|
|
245
|
+
nextAction: `Add apiKeyEnv to runtime profile '${runtimeProfileId}' in .pd/config.yaml`,
|
|
246
|
+
runtimeProfileId,
|
|
247
|
+
runtimeProfileType: profile.type,
|
|
248
|
+
apiKeyEnv: null,
|
|
249
|
+
apiKeyPresent: false,
|
|
250
|
+
provider: profile.provider ?? null,
|
|
251
|
+
model: profile.model ?? null,
|
|
252
|
+
timeoutMs: profile.timeoutMs ?? null,
|
|
253
|
+
baseUrl: profile.baseUrl ?? null,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
if (!apiKeyPresent) {
|
|
257
|
+
return {
|
|
258
|
+
enabled: true,
|
|
259
|
+
readiness: 'needs_setup',
|
|
260
|
+
source: result.source,
|
|
261
|
+
reason: `Environment variable '${apiKeyEnv}' is not set or empty`,
|
|
262
|
+
nextAction: `Set the environment variable '${apiKeyEnv}' with a valid API key`,
|
|
263
|
+
runtimeProfileId,
|
|
264
|
+
runtimeProfileType: profile.type,
|
|
265
|
+
apiKeyEnv,
|
|
266
|
+
apiKeyPresent: false,
|
|
267
|
+
provider: profile.provider ?? null,
|
|
268
|
+
model: profile.model ?? null,
|
|
269
|
+
timeoutMs: profile.timeoutMs ?? null,
|
|
270
|
+
baseUrl: profile.baseUrl ?? null,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
// pi-ai with key present — runtime availability unknown without actual probe
|
|
274
|
+
return {
|
|
275
|
+
enabled: true,
|
|
276
|
+
readiness: 'not_ready',
|
|
277
|
+
source: result.source,
|
|
278
|
+
reason: `pi-ai profile configured with apiKeyEnv='${apiKeyEnv}' (key present); runtime availability unknown`,
|
|
279
|
+
nextAction: 'Run pd runtime probe to verify end-to-end connectivity',
|
|
280
|
+
runtimeProfileId,
|
|
281
|
+
runtimeProfileType: profile.type,
|
|
282
|
+
apiKeyEnv,
|
|
283
|
+
apiKeyPresent: true,
|
|
284
|
+
provider: profile.provider ?? null,
|
|
285
|
+
model: profile.model ?? null,
|
|
286
|
+
timeoutMs: profile.timeoutMs ?? null,
|
|
287
|
+
baseUrl: profile.baseUrl ?? null,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
// 5) OpenClaw profile — CorrectionObserver does NOT support OpenClaw runtime
|
|
291
|
+
// Mark as needs_setup with nextAction to configure a pi-ai profile
|
|
292
|
+
return {
|
|
293
|
+
enabled: true,
|
|
294
|
+
readiness: 'needs_setup',
|
|
295
|
+
source: result.source,
|
|
296
|
+
reason: `OpenClaw profile '${runtimeProfileId}' is not supported for observer runtime. Observers require a pi-ai profile with an API key.`,
|
|
297
|
+
nextAction: `Configure a pi-ai runtime profile for ${observerAgentName} in .pd/config.yaml (e.g., add a pi-ai profile with provider, model, and apiKeyEnv)`,
|
|
298
|
+
runtimeProfileId,
|
|
299
|
+
runtimeProfileType: profile.type,
|
|
300
|
+
apiKeyEnv: null,
|
|
301
|
+
apiKeyPresent: false,
|
|
302
|
+
provider: profile.provider ?? null,
|
|
303
|
+
model: profile.model ?? null,
|
|
304
|
+
timeoutMs: null,
|
|
305
|
+
baseUrl: null,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
@@ -14,5 +14,9 @@ export declare class PromptActivationReader {
|
|
|
14
14
|
constructor(workspaceDir: string, deps?: PromptActivationReaderDeps);
|
|
15
15
|
readActivatedPrinciples(): Promise<PromptActivationReaderResult>;
|
|
16
16
|
private queryArtifactRow;
|
|
17
|
+
/**
|
|
18
|
+
* PRI-305/PRI-307: Load feature flags from .pd/config.yaml instead of .pd/feature-flags.yaml.
|
|
19
|
+
* Uses the shared plugin config loader for consistency.
|
|
20
|
+
*/
|
|
17
21
|
private loadFeatureFlags;
|
|
18
22
|
}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import * as yaml from 'js-yaml';
|
|
4
|
-
import { SqliteConnection, SqliteActivationStateStore, computeEffectiveFlags, DEFAULT_FEATURE_FLAGS, filterPromptActivations, resolvePrincipleFromArtifact } from '@principles/core/runtime-v2';
|
|
1
|
+
import { SqliteConnection, SqliteActivationStateStore, computeFeatureFlagsFromConfig, filterPromptActivations, resolvePrincipleFromArtifact } from '@principles/core/runtime-v2';
|
|
2
|
+
import { loadPdConfigForPlugin } from './pd-config-loader.js';
|
|
5
3
|
export { RUNTIME_V2_PRINCIPLE_BUDGET } from '@principles/core/runtime-v2';
|
|
6
|
-
const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
7
|
-
function isRecord(value) {
|
|
8
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
9
|
-
}
|
|
10
4
|
export class PromptActivationReader {
|
|
11
5
|
workspaceDir;
|
|
12
6
|
deps;
|
|
@@ -88,56 +82,18 @@ export class PromptActivationReader {
|
|
|
88
82
|
throw new Error(`artifact_query_failed: artifactId=${artifactId} reason=${msg}; nextAction=check_pi_artifacts_table`);
|
|
89
83
|
}
|
|
90
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* PRI-305/PRI-307: Load feature flags from .pd/config.yaml instead of .pd/feature-flags.yaml.
|
|
87
|
+
* Uses the shared plugin config loader for consistency.
|
|
88
|
+
*/
|
|
91
89
|
loadFeatureFlags() {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
raw = fs.readFileSync(configPath, 'utf8');
|
|
99
|
-
}
|
|
100
|
-
catch (e) {
|
|
101
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
102
|
-
this.deps.logger?.warn?.(`[PD:RuntimeV2] Feature flags unreadable: ${msg} — using defaults`);
|
|
103
|
-
return computeEffectiveFlags({}, DEFAULT_FEATURE_FLAGS, configPath);
|
|
104
|
-
}
|
|
105
|
-
let parsed;
|
|
106
|
-
try {
|
|
107
|
-
parsed = yaml.load(raw, { schema: yaml.JSON_SCHEMA });
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
this.deps.logger?.warn?.(`[PD:RuntimeV2] Feature flags YAML parse error — using defaults`);
|
|
111
|
-
return {
|
|
112
|
-
...computeEffectiveFlags({}, DEFAULT_FEATURE_FLAGS, configPath),
|
|
113
|
-
warnings: ['feature-flags.yaml: YAML parse error, using defaults'],
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
if (!isRecord(parsed)) {
|
|
117
|
-
this.deps.logger?.warn?.(`[PD:RuntimeV2] Feature flags not a mapping — using defaults`);
|
|
118
|
-
return {
|
|
119
|
-
...computeEffectiveFlags({}, DEFAULT_FEATURE_FLAGS, configPath),
|
|
120
|
-
warnings: ['feature-flags.yaml: expected a mapping, using defaults'],
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
const parsedRecord = Object.create(null);
|
|
124
|
-
const yamlWarnings = [];
|
|
125
|
-
for (const key of Object.keys(parsed)) {
|
|
126
|
-
if (DANGEROUS_KEYS.has(key)) {
|
|
127
|
-
yamlWarnings.push(`feature-flags.yaml: dangerous key '${key}' rejected`);
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
if (Object.hasOwn(parsed, key)) {
|
|
131
|
-
parsedRecord[key] = parsed[key];
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
const result = computeEffectiveFlags(parsedRecord, DEFAULT_FEATURE_FLAGS, configPath);
|
|
135
|
-
if (yamlWarnings.length > 0) {
|
|
136
|
-
result.warnings = [...yamlWarnings, ...result.warnings];
|
|
137
|
-
for (const w of yamlWarnings) {
|
|
138
|
-
this.deps.logger?.warn?.(`[PD:RuntimeV2] ${w}`);
|
|
90
|
+
const result = loadPdConfigForPlugin(this.workspaceDir);
|
|
91
|
+
const flags = computeFeatureFlagsFromConfig(result.effective);
|
|
92
|
+
if (!result.ok) {
|
|
93
|
+
for (const err of result.errors) {
|
|
94
|
+
this.deps.logger?.warn?.(`[PD:RuntimeV2] Config error at ${err.path}: ${err.reason}`);
|
|
139
95
|
}
|
|
140
96
|
}
|
|
141
|
-
return
|
|
97
|
+
return flags;
|
|
142
98
|
}
|
|
143
99
|
}
|
|
@@ -7,6 +7,16 @@ export interface SurfaceGuardResult {
|
|
|
7
7
|
violations: string[];
|
|
8
8
|
warnings: string[];
|
|
9
9
|
}
|
|
10
|
+
type LoggerLike = {
|
|
11
|
+
info?: (msg: string) => void;
|
|
12
|
+
debug?: (msg: string) => void;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Reset the per-process surface-guard skip log bookkeeping. Intended for tests
|
|
16
|
+
* that need to assert on the first-fire log without cross-test pollution.
|
|
17
|
+
* Not part of the production API surface; do not call from runtime code.
|
|
18
|
+
*/
|
|
19
|
+
export declare function __resetSurfaceGuardSkipLogStateForTests(): void;
|
|
10
20
|
export declare function checkSurfaceGuard(): SurfaceGuardResult;
|
|
11
21
|
export declare function getSurfaceIdForHook(hookEvent: string, label?: string): string;
|
|
12
22
|
export declare function getSurfaceIdForService(serviceName: string): string;
|
|
@@ -15,13 +25,7 @@ export declare function isSurfaceEnabled(surfaceId: string, overrides?: Record<s
|
|
|
15
25
|
reason?: string;
|
|
16
26
|
};
|
|
17
27
|
export type HookHandler<E, C, R> = (event: E, ctx: C) => R | Promise<R>;
|
|
18
|
-
export declare function guardHook<E, C, R>(surfaceId: string, logger:
|
|
19
|
-
|
|
20
|
-
debug?: (msg: string) => void;
|
|
21
|
-
} | undefined, handler: HookHandler<E, C, R>): HookHandler<E, C, R>;
|
|
22
|
-
export declare function guardService<T extends OpenClawPluginService>(surfaceId: string, service: T, logger?: {
|
|
23
|
-
info?: (msg: string) => void;
|
|
24
|
-
debug?: (msg: string) => void;
|
|
25
|
-
}): T | null;
|
|
28
|
+
export declare function guardHook<E, C, R>(surfaceId: string, logger: LoggerLike | undefined, handler: HookHandler<E, C, R>): HookHandler<E, C, R>;
|
|
29
|
+
export declare function guardService<T extends OpenClawPluginService>(surfaceId: string, service: T, logger?: LoggerLike): T | null;
|
|
26
30
|
export { PLUGIN_SURFACE_REGISTRY, validateSurfaceRegistry, getSurfacesByCategory };
|
|
27
31
|
export type { PluginSurfaceEntry, MvpCategory };
|
|
@@ -1,4 +1,42 @@
|
|
|
1
1
|
import { PLUGIN_SURFACE_REGISTRY, validateSurfaceRegistry, getSurfacesByCategory, } from '@principles/core/runtime-v2';
|
|
2
|
+
// Surface-level once-only log state (PRI-298).
|
|
3
|
+
// The first time a quiet/non-core surface guard actually fires in this
|
|
4
|
+
// process, the disabled reason is emitted once. Subsequent fires for the
|
|
5
|
+
// same surfaceId are still observable (the no-op handler preserves
|
|
6
|
+
// behaviour) but no longer flood the log. Fresh processes start with an
|
|
7
|
+
// empty set, so each plugin load gets one observable skip per surface.
|
|
8
|
+
//
|
|
9
|
+
// The Set is only updated when the log was actually emitted, so passing
|
|
10
|
+
// `undefined` for the logger on a quiet first fire does NOT consume the
|
|
11
|
+
// one-shot slot — a later registration that supplies a logger still gets
|
|
12
|
+
// the first-fire reason (PRI-298 / ERR-002).
|
|
13
|
+
const loggedSkipSurfaces = new Set();
|
|
14
|
+
/**
|
|
15
|
+
* Emit the disabled-reason log line for `surfaceId` at most once per
|
|
16
|
+
* process. Returns true if the log was emitted, false if it was suppressed
|
|
17
|
+
* (already logged, or no logger available). Only marks the surface as
|
|
18
|
+
* logged when the log was actually written, so a missing logger on first
|
|
19
|
+
* call does not consume the one-shot slot.
|
|
20
|
+
*/
|
|
21
|
+
function logSkipOnce(surfaceId, logger, message) {
|
|
22
|
+
if (loggedSkipSurfaces.has(surfaceId)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
if (!logger?.info) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
loggedSkipSurfaces.add(surfaceId);
|
|
29
|
+
logger.info(message);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Reset the per-process surface-guard skip log bookkeeping. Intended for tests
|
|
34
|
+
* that need to assert on the first-fire log without cross-test pollution.
|
|
35
|
+
* Not part of the production API surface; do not call from runtime code.
|
|
36
|
+
*/
|
|
37
|
+
export function __resetSurfaceGuardSkipLogStateForTests() {
|
|
38
|
+
loggedSkipSurfaces.clear();
|
|
39
|
+
}
|
|
2
40
|
export function checkSurfaceGuard() {
|
|
3
41
|
const validation = validateSurfaceRegistry(PLUGIN_SURFACE_REGISTRY);
|
|
4
42
|
const violations = [];
|
|
@@ -65,8 +103,15 @@ export function guardHook(surfaceId, logger, handler) {
|
|
|
65
103
|
return handler;
|
|
66
104
|
}
|
|
67
105
|
const reason = check.reason ?? 'surface not enabled';
|
|
106
|
+
// Log on the first ACTUAL no-op invocation, not at construction time
|
|
107
|
+
// (PRI-298). Construction-time logging would emit a `SKIP` line at
|
|
108
|
+
// plugin startup for every registered quiet hook, regardless of
|
|
109
|
+
// whether the hook ever fires — which is exactly the startup log
|
|
110
|
+
// noise this change is meant to prevent. The one-shot is consumed only
|
|
111
|
+
// when the log was actually written, so `undefined` logger on first
|
|
112
|
+
// call does not eat the slot.
|
|
68
113
|
return (_event, _ctx) => {
|
|
69
|
-
logger
|
|
114
|
+
logSkipOnce(surfaceId, logger, `[PD:surface-guard] SKIP ${surfaceId}: ${reason}`);
|
|
70
115
|
return undefined;
|
|
71
116
|
};
|
|
72
117
|
}
|
|
@@ -76,7 +121,11 @@ export function guardService(surfaceId, service, logger) {
|
|
|
76
121
|
return service;
|
|
77
122
|
}
|
|
78
123
|
const reason = check.reason ?? 'surface not enabled';
|
|
79
|
-
|
|
124
|
+
// guardService is called once per service during plugin registration,
|
|
125
|
+
// so the once-only check fires on the registration call itself. The
|
|
126
|
+
// shared helper makes the consumption rule identical to guardHook:
|
|
127
|
+
// a missing logger on first call does not consume the one-shot.
|
|
128
|
+
logSkipOnce(surfaceId, logger, `[PD:surface-guard] SKIP service ${surfaceId}: ${reason}`);
|
|
80
129
|
return null;
|
|
81
130
|
}
|
|
82
131
|
export { PLUGIN_SURFACE_REGISTRY, validateSurfaceRegistry, getSurfacesByCategory };
|
|
@@ -316,6 +316,9 @@ export function handleBeforeToolCall(event, ctx) {
|
|
|
316
316
|
// ---------------------------------------------------------------------------
|
|
317
317
|
function _extractParamsSummary(params) {
|
|
318
318
|
const summary = {};
|
|
319
|
+
// NOTE: Do NOT redact here — this feeds into RuleHost.evaluate() which
|
|
320
|
+
// may match against paramsSummary.command. Redaction happens at
|
|
321
|
+
// EventLog.record() before persistence.
|
|
319
322
|
if (params.file_path)
|
|
320
323
|
summary.file_path = params.file_path;
|
|
321
324
|
if (params.path)
|
|
@@ -127,7 +127,7 @@ export function loadContextInjectionConfig(workspaceDir) {
|
|
|
127
127
|
const raw = cachedReadFile(profilePath);
|
|
128
128
|
if (raw) {
|
|
129
129
|
const profile = JSON.parse(raw);
|
|
130
|
-
if (profile.contextInjection) {
|
|
130
|
+
if (profile && typeof profile === 'object' && profile.contextInjection && typeof profile.contextInjection === 'object') {
|
|
131
131
|
const contextInjection = profile.contextInjection;
|
|
132
132
|
return {
|
|
133
133
|
...defaultContextConfig,
|
|
@@ -267,6 +267,9 @@ export async function handleBeforePromptBuild(event, ctx) {
|
|
|
267
267
|
resetFriction(sessionId, workspaceDir);
|
|
268
268
|
}
|
|
269
269
|
// ──── 1. prependSystemContext: Minimal Agent Identity ────
|
|
270
|
+
// EvolutionWorker-era INTERNAL SYSTEM LAYOUT removed per PRI-294.
|
|
271
|
+
// The EVOLUTION_WORKER PathResolver key and system layout reference are
|
|
272
|
+
// not MVP-Core; agents discover what they need via tool calls.
|
|
270
273
|
prependSystemContext = `## 【AGENT IDENTITY】
|
|
271
274
|
|
|
272
275
|
You are a **self-evolving AI agent** powered by Principles Disciple.
|
|
@@ -284,10 +287,6 @@ You are a **self-evolving AI agent** powered by Principles Disciple.
|
|
|
284
287
|
- Use the current session for the normal user reply.
|
|
285
288
|
- Use sessions_send for cross-session messaging.
|
|
286
289
|
- Use agents_list / sessions_list for peer-agent or peer-session orchestration.
|
|
287
|
-
|
|
288
|
-
## 🔧 INTERNAL SYSTEM LAYOUT
|
|
289
|
-
- Your core plugin logic is rooted at: ${PathResolver.getExtensionRoot() || 'EXTENSION_ROOT (unresolved)'}
|
|
290
|
-
- If you need self-inspection, prioritize the worker entry pointed by PathResolver key: EVOLUTION_WORKER
|
|
291
290
|
`;
|
|
292
291
|
// ──── 2. Empathy Observer Spawn (async sidecar)
|
|
293
292
|
const empathySilenceConstraint = `
|
package/plugin/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { OpenClawPluginApi } from './openclaw-sdk.js';
|
|
2
2
|
declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* PRI-305/PRI-307: Load feature flag from .pd/config.yaml instead of .pd/feature-flags.yaml.
|
|
5
|
+
* Delegates to the shared plugin config loader for consistency.
|
|
6
|
+
*/
|
|
3
7
|
declare function loadFeatureFlagFromWorkspace(workspaceDir: string, flagId: string, logger?: {
|
|
4
8
|
warn?: (msg: string) => void;
|
|
5
9
|
info?: (msg: string) => void;
|