create-principles-disciple 1.104.2 → 1.106.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/dist/server/routes/update.js +91 -0
- package/console/dist/web/assets/app.css +3 -0
- package/core/dist/host/__tests__/host-adapter.test.js +12 -0
- package/core/dist/host/__tests__/host-adapter.test.js.map +1 -1
- package/core/dist/host/host-adapter.d.ts +4 -0
- package/core/dist/host/host-adapter.d.ts.map +1 -1
- package/core/dist/host/host-adapter.js +7 -0
- package/core/dist/host/host-adapter.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +10 -1
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.js +28 -0
- package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/sqlite-connection-readonly.test.js +18 -0
- package/core/dist/runtime-v2/__tests__/sqlite-connection-readonly.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.js +22 -1
- package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.d.ts +12 -1
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js +8 -1
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js.map +1 -1
- package/core/dist/runtime-v2/evidence-sanitizer.d.ts.map +1 -1
- package/core/dist/runtime-v2/evidence-sanitizer.js +17 -1
- package/core/dist/runtime-v2/evidence-sanitizer.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +15 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/__tests__/principle-receipt-block-copy-flag.test.d.ts +2 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/principle-receipt-block-copy-flag.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/principle-receipt-block-copy-flag.test.js +42 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/principle-receipt-block-copy-flag.test.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/principle-receipt-ledger-flag.test.d.ts +2 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/principle-receipt-ledger-flag.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/principle-receipt-ledger-flag.test.js +42 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/principle-receipt-ledger-flag.test.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +19 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.d.ts +3 -0
- package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js +33 -3
- package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
- package/dist/installer.d.ts +2 -0
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +63 -4
- package/dist/installer.js.map +1 -1
- package/dist/installers/codex-host-installer.d.ts +14 -0
- package/dist/installers/codex-host-installer.d.ts.map +1 -1
- package/dist/installers/codex-host-installer.js +53 -8
- package/dist/installers/codex-host-installer.js.map +1 -1
- package/dist/mvp-config.d.ts +20 -0
- package/dist/mvp-config.d.ts.map +1 -1
- package/dist/mvp-config.js +76 -0
- package/dist/mvp-config.js.map +1 -1
- package/dist/skill-language.d.ts +32 -0
- package/dist/skill-language.d.ts.map +1 -0
- package/dist/skill-language.js +107 -0
- package/dist/skill-language.js.map +1 -0
- package/dist/utils/config-file-io.d.ts +26 -0
- package/dist/utils/config-file-io.d.ts.map +1 -0
- package/dist/utils/config-file-io.js +128 -0
- package/dist/utils/config-file-io.js.map +1 -0
- package/host-runtime/dist/active-principle-prompt.d.ts +17 -0
- package/host-runtime/dist/active-principle-prompt.js +106 -0
- package/host-runtime/dist/index.d.ts +45 -0
- package/host-runtime/dist/index.js +148 -0
- package/host-runtime/dist/pd-config.d.ts +36 -0
- package/host-runtime/dist/pd-config.js +98 -0
- package/host-runtime/dist/production-pain-evidence.d.ts +24 -0
- package/host-runtime/dist/production-pain-evidence.js +293 -0
- package/host-runtime/dist/production-rulehost-gate.d.ts +23 -0
- package/host-runtime/dist/production-rulehost-gate.js +294 -0
- package/host-runtime/dist/rule-implementation-runtime.d.ts +25 -0
- package/host-runtime/dist/rule-implementation-runtime.js +114 -0
- package/host-runtime/package.json +37 -0
- package/package.json +2 -1
- package/pd-cli/dist/commands/console.d.ts.map +1 -1
- package/pd-cli/dist/commands/console.js +2 -0
- package/pd-cli/dist/commands/console.js.map +1 -1
- package/pd-cli/dist/commands/health-codex.d.ts +7 -0
- package/pd-cli/dist/commands/health-codex.d.ts.map +1 -0
- package/pd-cli/dist/commands/health-codex.js +209 -0
- package/pd-cli/dist/commands/health-codex.js.map +1 -0
- package/pd-cli/dist/commands/health.d.ts +24 -0
- package/pd-cli/dist/commands/health.d.ts.map +1 -1
- package/pd-cli/dist/commands/health.js +48 -0
- package/pd-cli/dist/commands/health.js.map +1 -1
- package/pd-cli/dist/index.js +2 -9
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/services/console-launcher.d.ts +6 -0
- package/pd-cli/dist/services/console-launcher.d.ts.map +1 -1
- package/pd-cli/dist/services/console-launcher.js.map +1 -1
- package/pd-cli/package.json +2 -0
- package/plugin/dist/bundle.js +749 -594
- package/plugin/dist/core/pd-config-loader.d.ts +7 -78
- package/plugin/dist/core/principle-application-ledger.d.ts +45 -0
- package/plugin/dist/core/principle-receipt-metadata.d.ts +15 -0
- package/plugin/dist/hooks/after-tool-call-helpers.d.ts +6 -2
- package/plugin/dist/hooks/gate-block-helper.d.ts +4 -0
- package/plugin/dist/hooks/gate.d.ts +29 -0
- package/plugin/dist/hooks/pain.d.ts +22 -0
- package/plugin/dist/hooks/prompt.d.ts +12 -2
- package/plugin/dist/host-runtime/openclaw-host-runtime.d.ts +19 -0
- package/plugin/dist/index.d.ts +8 -0
- package/plugin/dist/openclaw-sdk.d.ts +23 -1
- package/plugin/dist/openclaw.plugin.json +0 -1
- package/plugin/openclaw.plugin.json +1 -2
- package/plugin/package.json +2 -1
- package/plugin/scripts/sync-plugin.mjs +17 -8
- package/plugin/scripts/verify-build.mjs +19 -8
|
@@ -1,96 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 type { EffectivePdConfig } from '@principles/core/runtime-v2';
|
|
16
|
-
export declare const PD_CONFIG_DIR = ".pd";
|
|
17
|
-
export declare const PD_CONFIG_FILENAME = "config.yaml";
|
|
1
|
+
import { type PluginConfigLoadResult } from '@principles/host-runtime';
|
|
2
|
+
export { getPdConfigPath, loadFeatureFlagFromConfig, loadPdConfigForPlugin, PD_CONFIG_DIR, PD_CONFIG_FILENAME, } from '@principles/host-runtime';
|
|
3
|
+
export type { PluginConfigLoadResult } from '@principles/host-runtime';
|
|
18
4
|
export type ObserverReadiness = 'disabled' | 'needs_setup' | 'ready' | 'not_ready' | 'config_malformed';
|
|
19
5
|
export interface ObserverConfigResult {
|
|
20
|
-
/** Whether the observer feature is enabled in config */
|
|
21
6
|
enabled: boolean;
|
|
22
|
-
/** Observer readiness state */
|
|
23
7
|
readiness: ObserverReadiness;
|
|
24
|
-
/** Config source: 'defaults' | 'user_config' | 'malformed' */
|
|
25
8
|
source: string;
|
|
26
|
-
/** Reason for current state */
|
|
27
9
|
reason: string;
|
|
28
|
-
/** What the user should do next */
|
|
29
10
|
nextAction: string;
|
|
30
|
-
/** The runtime profile ID for this observer, if configured */
|
|
31
11
|
runtimeProfileId: string | null;
|
|
32
|
-
/** The runtime profile type, if configured */
|
|
33
12
|
runtimeProfileType: string | null;
|
|
34
|
-
/** The apiKeyEnv for the runtime profile, if applicable */
|
|
35
13
|
apiKeyEnv: string | null;
|
|
36
|
-
/** Whether the apiKeyEnv is present in process.env */
|
|
37
14
|
apiKeyPresent: boolean;
|
|
38
|
-
/** Provider name from runtime profile */
|
|
39
15
|
provider: string | null;
|
|
40
|
-
/** Model name from runtime profile */
|
|
41
16
|
model: string | null;
|
|
42
|
-
/** Timeout from runtime profile */
|
|
43
17
|
timeoutMs: number | null;
|
|
44
|
-
/** Base URL from runtime profile */
|
|
45
18
|
baseUrl: string | null;
|
|
46
|
-
|
|
47
|
-
configErrors?: Array<{
|
|
48
|
-
path: string;
|
|
49
|
-
reason: string;
|
|
50
|
-
nextAction: string;
|
|
51
|
-
}>;
|
|
19
|
+
configErrors?: PluginConfigLoadResult['errors'];
|
|
52
20
|
}
|
|
53
|
-
export interface PluginConfigLoadResult {
|
|
54
|
-
ok: boolean;
|
|
55
|
-
effective: EffectivePdConfig;
|
|
56
|
-
source: 'defaults' | 'user_config' | 'malformed';
|
|
57
|
-
configPath: string;
|
|
58
|
-
warnings: string[];
|
|
59
|
-
errors: Array<{
|
|
60
|
-
path: string;
|
|
61
|
-
reason: string;
|
|
62
|
-
nextAction: string;
|
|
63
|
-
}>;
|
|
64
|
-
}
|
|
65
|
-
export declare function getPdConfigPath(workspaceDir: string): string;
|
|
66
|
-
/**
|
|
67
|
-
* Load and validate `.pd/config.yaml` from the workspace.
|
|
68
|
-
* Never throws on malformed input. Always provides a usable fallback.
|
|
69
|
-
*/
|
|
70
|
-
export declare function loadPdConfigForPlugin(workspaceDir: string): PluginConfigLoadResult;
|
|
71
|
-
/**
|
|
72
|
-
* Get a single feature flag's enabled state from .pd/config.yaml.
|
|
73
|
-
* Replaces the old `loadFeatureFlagFromWorkspace` which read .pd/feature-flags.yaml.
|
|
74
|
-
*/
|
|
75
|
-
export declare function loadFeatureFlagFromConfig(workspaceDir: string, flagId: string, logger?: {
|
|
76
|
-
warn?: (msg: string) => void;
|
|
77
|
-
info?: (msg: string) => void;
|
|
78
|
-
}): {
|
|
79
|
-
enabled: boolean;
|
|
80
|
-
source: string;
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* Resolve observer configuration from .pd/config.yaml.
|
|
84
|
-
*
|
|
85
|
-
* Returns structured state:
|
|
86
|
-
* - config_malformed: config file is invalid — no guessing, fail loud
|
|
87
|
-
* - disabled: observer feature flag is off OR agent.enabled=false → no start, no noisy logs
|
|
88
|
-
* - needs_setup: observer enabled but runtime profile missing, API key not set, or unsupported profile type
|
|
89
|
-
* - ready: observer enabled and fully configured (pi-ai with key present)
|
|
90
|
-
* - not_ready: observer enabled, API key present, but runtime availability unknown
|
|
91
|
-
*/
|
|
92
21
|
export declare function resolveObserverConfig(workspaceDir: string, observerFlagId: string, observerAgentName: string, _logger?: {
|
|
93
|
-
warn?: (
|
|
94
|
-
info?: (
|
|
95
|
-
debug?: (
|
|
22
|
+
warn?: (message: string) => void;
|
|
23
|
+
info?: (message: string) => void;
|
|
24
|
+
debug?: (message: string) => void;
|
|
96
25
|
}): ObserverConfigResult;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type PrincipleApplicationLevel = 'effect' | 'presence';
|
|
2
|
+
export type PrincipleApplicationKind = 'rule_blocked' | 'auto_correct_applied' | 'self_reported' | 'prompt_injected';
|
|
3
|
+
export interface PrincipleApplicationInput {
|
|
4
|
+
principleId: string;
|
|
5
|
+
activationId?: string;
|
|
6
|
+
ruleId?: string;
|
|
7
|
+
channel: 'code_tool_hook' | 'prompt';
|
|
8
|
+
level: PrincipleApplicationLevel;
|
|
9
|
+
kind: PrincipleApplicationKind;
|
|
10
|
+
sessionId?: string;
|
|
11
|
+
toolName?: string;
|
|
12
|
+
filePath?: string;
|
|
13
|
+
digest?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Record one application event. Returns true when a row was written (or
|
|
17
|
+
* deduped), false on failure — callers must surface the reason (rc-9).
|
|
18
|
+
*/
|
|
19
|
+
export declare function recordPrincipleApplication(workspaceDir: string, input: PrincipleApplicationInput): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Align activation ids with the actually-injected principle subset (PRI-531
|
|
22
|
+
* review fix). Budget truncation can drop principles from the tail of the
|
|
23
|
+
* full list — pairing by raw index would attach the wrong activation_id to a
|
|
24
|
+
* presence row (rc-6-adjacent data pairing).
|
|
25
|
+
*/
|
|
26
|
+
export declare function alignActivationIds(principles: ReadonlyArray<{
|
|
27
|
+
principleId: string;
|
|
28
|
+
activationId?: string;
|
|
29
|
+
}>, injectedIds: ReadonlySet<string>): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Presence rows for a prompt injection event — one per principle, deduped per
|
|
32
|
+
* session×principle by the partial unique index (restarts included).
|
|
33
|
+
* Returns the number of NEW rows written (0 when all were already present).
|
|
34
|
+
* Failures are warned via the optional logger (rc-9) — never thrown.
|
|
35
|
+
*/
|
|
36
|
+
export declare function recordInjectionPresence(workspaceDir: string, principleIds: readonly string[], sessionId: string | undefined, activationIds?: readonly string[], logger?: {
|
|
37
|
+
warn?: (message: string) => void;
|
|
38
|
+
info?: (message: string) => void;
|
|
39
|
+
}): number;
|
|
40
|
+
export declare function recordSelfReportFromText(workspaceDir: string, text: unknown, sessionId: string | undefined, logger?: {
|
|
41
|
+
warn?: (message: string) => void;
|
|
42
|
+
info?: (message: string) => void;
|
|
43
|
+
}): number;
|
|
44
|
+
/** Test hook: close cached connections and reset the retention sweep clock. */
|
|
45
|
+
export declare function clearPrincipleApplicationLedgerCache(): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface PrincipleReceiptMetadata {
|
|
2
|
+
/** Resolved display title (fallback chain result; never empty). */
|
|
3
|
+
title: string;
|
|
4
|
+
/** Owner approval date (ISO string) — approvals.decided_at, fallback activations.activated_at. */
|
|
5
|
+
approvedAt?: string;
|
|
6
|
+
/** Source correction summary — only present when the artifact carries painReasonSummary. */
|
|
7
|
+
sourceSummary?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolve receipt metadata for a blocked rule. Returns undefined when nothing
|
|
11
|
+
* useful can be resolved (caller degrades to the generic copy).
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadPrincipleReceiptMetadata(workspaceDir: string, ruleId: string | undefined, principleId: string | undefined): PrincipleReceiptMetadata | undefined;
|
|
14
|
+
/** Test hook: clear caches between tests. */
|
|
15
|
+
export declare function clearPrincipleReceiptMetadataCache(): void;
|
|
@@ -44,13 +44,17 @@ export declare function buildToolCallObservation(event: PluginHookAfterToolCallE
|
|
|
44
44
|
*/
|
|
45
45
|
export declare function handleFrictionTrackingForFailure(sessionId: string, event: PluginHookAfterToolCallEvent, outcome: ToolCallOutcome, observation: ToolCallObservation, gfiBefore: number, workspaceDir: string, config: {
|
|
46
46
|
get: (key: string) => unknown;
|
|
47
|
-
}, wctx: WorkspaceContext
|
|
47
|
+
}, wctx: WorkspaceContext, options?: {
|
|
48
|
+
recordTrajectory?: boolean;
|
|
49
|
+
}): SessionState;
|
|
48
50
|
/**
|
|
49
51
|
* Handle friction relief and recording for a tool success.
|
|
50
52
|
*
|
|
51
53
|
* Relieves both tool_failure and dispatch_error GFI sources proportionally.
|
|
52
54
|
*/
|
|
53
|
-
export declare function handleFrictionTrackingForSuccess(sessionId: string, event: PluginHookAfterToolCallEvent, outcome: ToolCallOutcome, observation: ToolCallObservation, gfiBefore: number, workspaceDir: string, wctx: WorkspaceContext
|
|
55
|
+
export declare function handleFrictionTrackingForSuccess(sessionId: string, event: PluginHookAfterToolCallEvent, outcome: ToolCallOutcome, observation: ToolCallObservation, gfiBefore: number, workspaceDir: string, wctx: WorkspaceContext, options?: {
|
|
56
|
+
recordTrajectory?: boolean;
|
|
57
|
+
}): SessionState;
|
|
54
58
|
/**
|
|
55
59
|
* Record hygiene tracking for memory/plan persistence actions on success.
|
|
56
60
|
*/
|
|
@@ -21,6 +21,10 @@ export interface BlockContext {
|
|
|
21
21
|
sessionId?: string;
|
|
22
22
|
/** Source module that triggered the block (for audit trail) */
|
|
23
23
|
blockSource?: string;
|
|
24
|
+
/** RuleHost rule id — enables PRI-530 receipt copy attribution */
|
|
25
|
+
ruleId?: string;
|
|
26
|
+
/** Principle id from the rule result — enables PRI-530 receipt copy attribution */
|
|
27
|
+
principleId?: string;
|
|
24
28
|
}
|
|
25
29
|
/**
|
|
26
30
|
* Single authoritative block helper.
|
|
@@ -8,9 +8,38 @@
|
|
|
8
8
|
* 1. Early Return: Skip if not write/bash/agent tool or no workspace
|
|
9
9
|
* 2. Rule Host: Dynamic principle-based evaluation (sole gate)
|
|
10
10
|
*/
|
|
11
|
+
import { WorkspaceContext } from '../core/workspace-context.js';
|
|
12
|
+
import type { RuleContextV2 } from '@principles/core/runtime-v2';
|
|
11
13
|
import type { PluginHookBeforeToolCallEvent, PluginHookToolContext, PluginHookBeforeToolCallResult, PluginLogger } from '../openclaw-sdk.js';
|
|
14
|
+
import type { HostEventResult } from '@principles/core/host';
|
|
12
15
|
export declare function handleBeforeToolCall(event: PluginHookBeforeToolCallEvent, ctx: PluginHookToolContext & {
|
|
13
16
|
workspaceDir?: string;
|
|
14
17
|
pluginConfig?: Record<string, unknown>;
|
|
15
18
|
logger?: Partial<PluginLogger>;
|
|
16
19
|
}): PluginHookBeforeToolCallResult | void;
|
|
20
|
+
export declare function buildOpenClawRuleInputEnrichment(event: PluginHookBeforeToolCallEvent, workspaceDir: string, sessionId: string | undefined): {
|
|
21
|
+
currentGfi: number;
|
|
22
|
+
recentThinking: boolean;
|
|
23
|
+
epTier: number;
|
|
24
|
+
bashRisk: "dangerous" | "normal" | "safe" | "unknown";
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* PRI-483 Phase 4 — Build RuleContextV2 for RuleHost.evaluate when the
|
|
28
|
+
* `rulecode_context_v2` feature flag is ON. Returns `undefined` when the flag
|
|
29
|
+
* is OFF (v1 zero-change — does NOT touch trajectory) or when config loading
|
|
30
|
+
* fails (conservative fail-soft: can't determine flag state → v1-style).
|
|
31
|
+
*
|
|
32
|
+
* ERR-024 prevention: context assembly failures never skip RuleHost.evaluate.
|
|
33
|
+
* - loadPdConfigForPlugin throws → return undefined (v1-style)
|
|
34
|
+
* - buildProductionRuleContext throws → return UNAVAILABLE_RULE_CONTEXT
|
|
35
|
+
* (structured unavailable so v2 rules see "context unavailable" and allow)
|
|
36
|
+
*
|
|
37
|
+
* Spec: docs/superpowers/specs/2026-06-27-rulecode-context-vision-design.md §5.3
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildRuleContextIfEnabled(wctx: WorkspaceContext, targetPath: string, sessionId: string | undefined, logger: {
|
|
40
|
+
warn?: (msg: string) => void;
|
|
41
|
+
} | undefined): RuleContextV2 | undefined;
|
|
42
|
+
export declare function handleSharedRuleHostResult(event: PluginHookBeforeToolCallEvent, ctx: PluginHookToolContext & {
|
|
43
|
+
workspaceDir: string;
|
|
44
|
+
logger?: Partial<PluginLogger>;
|
|
45
|
+
}, result: HostEventResult): void;
|
|
@@ -17,8 +17,17 @@
|
|
|
17
17
|
import { WorkspaceContext } from '../core/workspace-context.js';
|
|
18
18
|
import type { EvolutionLoopEvent } from '../core/evolution-types.js';
|
|
19
19
|
import type { PluginHookAfterToolCallEvent, PluginHookToolContext, OpenClawPluginApi } from '../openclaw-sdk.js';
|
|
20
|
+
import type { ProductionPainEnrichment } from '@principles/host-runtime';
|
|
21
|
+
import type { HostEventResult } from '@principles/core/host';
|
|
20
22
|
import { buildTrajectoryEvidence } from './trajectory-evidence.js';
|
|
21
23
|
export { buildTrajectoryEvidence };
|
|
24
|
+
/**
|
|
25
|
+
* Host-owned best-effort continuation after durable shared persistence.
|
|
26
|
+
* The hook may return once SQLite commits, while rejections remain observable
|
|
27
|
+
* and tests/shutdown code can explicitly drain scheduled work.
|
|
28
|
+
*/
|
|
29
|
+
export declare function schedulePainContinuation(workspaceDir: string, continuation: Promise<void>): void;
|
|
30
|
+
export declare function drainPainContinuationsForTest(): Promise<void>;
|
|
22
31
|
export declare function emitPainDetectedEvent(wctx: WorkspaceContext, event: EvolutionLoopEvent, options?: {
|
|
23
32
|
recordObservability?: boolean;
|
|
24
33
|
}): Promise<void>;
|
|
@@ -33,3 +42,16 @@ export declare function handleAfterToolCall(event: PluginHookAfterToolCallEvent,
|
|
|
33
42
|
workspaceDir?: string;
|
|
34
43
|
pluginConfig?: Record<string, unknown>;
|
|
35
44
|
}, api?: OpenClawPluginApi): void;
|
|
45
|
+
/**
|
|
46
|
+
* OpenClaw-owned enrichment for the shared ordinary after-tool kernel.
|
|
47
|
+
* Session/GFI, event-log, probation, PROFILE and hygiene behavior stays here;
|
|
48
|
+
* the shared runtime owns classification/admission and the atomic trajectory write.
|
|
49
|
+
*/
|
|
50
|
+
export declare function prepareOrdinaryAfterToolCallForSharedRuntime(event: PluginHookAfterToolCallEvent, ctx: PluginHookToolContext & {
|
|
51
|
+
workspaceDir: string;
|
|
52
|
+
pluginConfig?: Record<string, unknown>;
|
|
53
|
+
}): ProductionPainEnrichment;
|
|
54
|
+
/** Restore OpenClaw-owned pain UX/diagnosis after the shared atomic evidence write. */
|
|
55
|
+
export declare function handleSharedPainEvidenceResult(event: PluginHookAfterToolCallEvent, ctx: PluginHookToolContext & {
|
|
56
|
+
workspaceDir: string;
|
|
57
|
+
}, result: HostEventResult): void;
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import type { PluginHookBeforePromptBuildEvent, PluginHookAgentContext, PluginHookBeforePromptBuildResult } from '../openclaw-sdk.js';
|
|
1
|
+
import type { PluginHookBeforePromptBuildEvent, PluginHookAgentContext, PluginHookBeforePromptBuildResult, PluginLogger } from '../openclaw-sdk.js';
|
|
2
|
+
import { WorkspaceContext } from '../core/workspace-context.js';
|
|
2
3
|
import type { ContextInjectionConfig } from '../types.js';
|
|
4
|
+
import type { ActivePrinciplePromptResult } from '@principles/host-runtime';
|
|
3
5
|
import type { PromptHookApi } from './prompt-types.js';
|
|
6
|
+
import type { InjectablePrinciple } from '../core/principle-injection.js';
|
|
7
|
+
export interface LegacyPrinciplePromptSelection {
|
|
8
|
+
active: InjectablePrinciple[];
|
|
9
|
+
probation: InjectablePrinciple[];
|
|
10
|
+
content: string;
|
|
11
|
+
selectedIds: ReadonlySet<string>;
|
|
12
|
+
}
|
|
13
|
+
export declare function selectLegacyPrinciplesForPrompt(workspaceDir: string, reducer: Pick<WorkspaceContext['evolutionReducer'], 'getActivePrinciples' | 'getProbationPrinciples'>, logger?: PluginLogger): LegacyPrinciplePromptSelection;
|
|
4
14
|
/**
|
|
5
15
|
* Reset all module-level prompt state for a workspace.
|
|
6
16
|
* Intended for test isolation — call in beforeEach().
|
|
@@ -19,4 +29,4 @@ export declare function resetPromptStateForTest(workspaceDir?: string): void;
|
|
|
19
29
|
export declare function loadContextInjectionConfig(workspaceDir: string): ContextInjectionConfig;
|
|
20
30
|
export declare function handleBeforePromptBuild(event: PluginHookBeforePromptBuildEvent, ctx: PluginHookAgentContext & {
|
|
21
31
|
api?: PromptHookApi;
|
|
22
|
-
}): Promise<PluginHookBeforePromptBuildResult | void>;
|
|
32
|
+
}, sharedActivePrinciplePrompt?: ActivePrinciplePromptResult, preparedLegacyPrinciples?: LegacyPrinciplePromptSelection): Promise<PluginHookBeforePromptBuildResult | void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ActivePrinciplePromptResult, type HostRuntime, type ProductionRuleContextRequest, type ProductionPainEnrichment } from '@principles/host-runtime';
|
|
2
|
+
import type { HostEventResult } from '@principles/core/host';
|
|
3
|
+
import type { PluginHookAgentContext, PluginHookAfterToolCallEvent, PluginHookBeforePromptBuildEvent, PluginHookBeforePromptBuildResult, PluginHookBeforeToolCallEvent, PluginHookBeforeToolCallResult, PluginHookToolContext } from '../openclaw-sdk.js';
|
|
4
|
+
export interface OpenClawHostRuntimeOptions {
|
|
5
|
+
beforePromptBuild(event: PluginHookBeforePromptBuildEvent, context: PluginHookAgentContext, prompt: ActivePrinciplePromptResult): Promise<PluginHookBeforePromptBuildResult | void>;
|
|
6
|
+
promptExcludePrincipleIds?(event: PluginHookBeforePromptBuildEvent, context: PluginHookAgentContext): ReadonlySet<string>;
|
|
7
|
+
ruleContextProvider?(event: PluginHookBeforeToolCallEvent, context: PluginHookToolContext, request: ProductionRuleContextRequest): unknown | Promise<unknown>;
|
|
8
|
+
ruleInputEnrichmentProvider?(event: PluginHookBeforeToolCallEvent, context: PluginHookToolContext, request: ProductionRuleContextRequest): unknown | Promise<unknown>;
|
|
9
|
+
onBeforeToolResult?(event: PluginHookBeforeToolCallEvent, context: PluginHookToolContext, result: HostEventResult): PluginHookBeforeToolCallResult | void;
|
|
10
|
+
painEnrichmentProvider?(event: PluginHookAfterToolCallEvent, context: PluginHookToolContext): ProductionPainEnrichment | Promise<ProductionPainEnrichment>;
|
|
11
|
+
onAfterToolResult?(event: PluginHookAfterToolCallEvent, context: PluginHookToolContext, result: HostEventResult): void | Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export interface OpenClawHostRuntime {
|
|
14
|
+
readonly runtime: HostRuntime;
|
|
15
|
+
dispatchBeforePromptBuild(event: PluginHookBeforePromptBuildEvent, context: PluginHookAgentContext): Promise<PluginHookBeforePromptBuildResult | void>;
|
|
16
|
+
dispatchBeforeToolCall(event: PluginHookBeforeToolCallEvent, context: PluginHookToolContext): Promise<PluginHookBeforeToolCallResult | void>;
|
|
17
|
+
dispatchAfterToolCall(event: PluginHookAfterToolCallEvent, context: PluginHookToolContext): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createOpenClawHostRuntime(options: OpenClawHostRuntimeOptions): OpenClawHostRuntime;
|
package/plugin/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,14 @@ export declare function shouldStartInternalizationAutoConsumer(workspaceDir: str
|
|
|
40
40
|
info?: (msg: string) => void;
|
|
41
41
|
warn?: (msg: string) => void;
|
|
42
42
|
}): InternalizationAutoConsumerGateResult;
|
|
43
|
+
export declare function shouldUseSharedHostRuntime(workspaceDir: string, logger: {
|
|
44
|
+
info?: (msg: string) => void;
|
|
45
|
+
warn?: (msg: string) => void;
|
|
46
|
+
}): {
|
|
47
|
+
enabled: boolean;
|
|
48
|
+
source: string;
|
|
49
|
+
rollbackReason: string | null;
|
|
50
|
+
};
|
|
43
51
|
declare const plugin: {
|
|
44
52
|
name: string;
|
|
45
53
|
description: string;
|
|
@@ -195,14 +195,28 @@ export interface PluginHookBeforePromptBuildResult {
|
|
|
195
195
|
}
|
|
196
196
|
export interface PluginHookBeforeToolCallEvent {
|
|
197
197
|
toolName: string;
|
|
198
|
+
/** Host-provided tool call arguments (OpenClaw 2026.7.x sends `params`). */
|
|
198
199
|
params?: Record<string, unknown>;
|
|
200
|
+
/** @deprecated Host sends `params`; kept for older adapter shims. */
|
|
199
201
|
toolArgs?: Record<string, unknown>;
|
|
200
202
|
agentId?: string;
|
|
201
203
|
sessionId?: string;
|
|
202
204
|
[key: string]: unknown;
|
|
203
205
|
}
|
|
204
206
|
export interface PluginHookBeforeToolCallResult {
|
|
207
|
+
/**
|
|
208
|
+
* Host merge contract (OpenClaw 2026.7.x, hook-before-tool-call-result.ts):
|
|
209
|
+
* only `params`, `block`, `blockReason`, `requireApproval` are read from the
|
|
210
|
+
* hook result. New code must use these fields.
|
|
211
|
+
*/
|
|
212
|
+
params?: Record<string, unknown>;
|
|
213
|
+
block?: boolean;
|
|
214
|
+
blockReason?: string;
|
|
215
|
+
/** Shape is host-defined (approval request details). */
|
|
216
|
+
requireApproval?: unknown;
|
|
217
|
+
/** @deprecated Use `params`. Host does not read `toolArgs`. */
|
|
205
218
|
toolArgs?: Record<string, unknown>;
|
|
219
|
+
/** @deprecated Blocking is expressed via `block: true`. Host does not read `skipToolCall`. */
|
|
206
220
|
skipToolCall?: boolean;
|
|
207
221
|
[key: string]: unknown;
|
|
208
222
|
}
|
|
@@ -250,15 +264,21 @@ export interface PluginHookSubagentEndedEvent {
|
|
|
250
264
|
[key: string]: unknown;
|
|
251
265
|
}
|
|
252
266
|
export interface PluginHookLlmOutputEvent {
|
|
253
|
-
|
|
267
|
+
/**
|
|
268
|
+
* @deprecated Host (OpenClaw 2026.7.x) does not send `output`. It fires once
|
|
269
|
+
* per model-loop attempt with `assistantTexts` + `lastAssistant`; read those.
|
|
270
|
+
*/
|
|
271
|
+
output?: string;
|
|
254
272
|
agentId?: string;
|
|
255
273
|
sessionId?: string;
|
|
256
274
|
runId?: string;
|
|
257
275
|
provider?: string;
|
|
258
276
|
model?: string;
|
|
259
277
|
usage?: TokenUsage;
|
|
278
|
+
/** Host-provided full assistant texts for this model-loop attempt. */
|
|
260
279
|
assistantTexts?: string[];
|
|
261
280
|
trigger?: string;
|
|
281
|
+
/** Last complete assistant message object (host-defined shape). */
|
|
262
282
|
lastAssistant?: unknown;
|
|
263
283
|
[key: string]: unknown;
|
|
264
284
|
}
|
|
@@ -314,6 +334,8 @@ export interface PluginHookBeforeMessageWriteResult {
|
|
|
314
334
|
role?: string;
|
|
315
335
|
content?: unknown;
|
|
316
336
|
};
|
|
337
|
+
/** Host contract: `block: true` prevents the transcript write entirely. */
|
|
338
|
+
block?: boolean;
|
|
317
339
|
[key: string]: unknown;
|
|
318
340
|
}
|
|
319
341
|
export interface OpenClawPluginHttpRouteParams {
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
"id": "principles-disciple",
|
|
3
3
|
"name": "Principles Disciple",
|
|
4
4
|
"description": "Turn repeated Agent corrections into Owner-approved, observable, reversible behavior principles. Stop correcting the same AI behavior across sessions.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.207.1",
|
|
6
6
|
"activation": {
|
|
7
7
|
"onCapabilities": [
|
|
8
8
|
"hook"
|
|
9
9
|
]
|
|
10
10
|
},
|
|
11
11
|
"skills": [
|
|
12
|
-
"templates/langs/en/skills",
|
|
13
12
|
"templates/langs/zh/skills"
|
|
14
13
|
],
|
|
15
14
|
"configSchema": {
|
package/plugin/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "principles-disciple",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.207.1",
|
|
4
4
|
"description": "Turn repeated Agent corrections into Owner-approved, observable, reversible behavior principles. Stop correcting the same AI behavior across sessions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"test": "vitest run",
|
|
63
63
|
"test:unit": "vitest run --config vitest.unit.config.ts tests/core tests/service tests/hooks tests/commands tests/utils tests/scripts --exclude tests/commands/evolver.test.ts",
|
|
64
64
|
"test:integration": "vitest run tests/integration/",
|
|
65
|
+
"test:host-runtime-parity": "vitest run --config vitest.parity.config.ts tests/bdd/openclaw-shared-host-runtime-parity.steps.test.ts tests/package/published-host-runtime-bundle.test.ts",
|
|
65
66
|
"test:coverage": "vitest run --coverage",
|
|
66
67
|
"test:all": "vitest run",
|
|
67
68
|
"lint": "eslint \"src/**/*.ts\"",
|
|
@@ -686,24 +686,33 @@ function syncFilteredManifest(lang) {
|
|
|
686
686
|
process.exit(1);
|
|
687
687
|
}
|
|
688
688
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
689
|
+
// PR #1332 companion: the source manifest declares exactly one root
|
|
690
|
+
// (zh, product default). REPLACE language roots with the selected one
|
|
691
|
+
// instead of only filtering, so `--lang en` works against a zh-default
|
|
692
|
+
// source manifest. Mirrors the production transform in
|
|
693
|
+
// create-principles-disciple/src/skill-language.ts.
|
|
694
|
+
const langRoots = {
|
|
695
|
+
zh: 'templates/langs/zh/skills',
|
|
696
|
+
en: 'templates/langs/en/skills',
|
|
697
|
+
};
|
|
698
|
+
const isLangRoot = (sp) =>
|
|
699
|
+
typeof sp === 'string' &&
|
|
700
|
+
(sp.replaceAll('\\', '/') === langRoots.zh || sp.replaceAll('\\', '/') === langRoots.en);
|
|
693
701
|
|
|
694
|
-
if (
|
|
695
|
-
console.error(`❌
|
|
702
|
+
if (!existsSync(join(SOURCE_DIR, langRoots[selectedLang]))) {
|
|
703
|
+
console.error(`❌ Skill templates missing for language "${selectedLang}": ${langRoots[selectedLang]}`);
|
|
696
704
|
process.exit(1);
|
|
697
705
|
}
|
|
698
706
|
|
|
699
|
-
manifest.skills
|
|
707
|
+
const kept = manifest.skills.filter((sp) => !isLangRoot(sp));
|
|
708
|
+
manifest.skills = [...kept, langRoots[selectedLang]];
|
|
700
709
|
|
|
701
710
|
// Use syncItem semantics: remove target, then write freshly
|
|
702
711
|
if (existsSync(targetPath)) {
|
|
703
712
|
rmSync(targetPath, { force: true });
|
|
704
713
|
}
|
|
705
714
|
writeFileSync(targetPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
|
|
706
|
-
console.log(` ✅ skills filtered to lang: ${selectedLang} (${
|
|
715
|
+
console.log(` ✅ skills filtered to lang: ${selectedLang} (${manifest.skills.length} path(s))`);
|
|
707
716
|
}
|
|
708
717
|
|
|
709
718
|
/**
|
|
@@ -94,14 +94,25 @@ for (const [path, config] of Object.entries(expectedCounts)) {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
// 3.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
// 3. Verify skill template roots for BOTH languages ship in dist — the
|
|
98
|
+
// installer rewrites the installed manifest per --lang (PR #1332 companion),
|
|
99
|
+
// so a missing root breaks install-time language selection. A "publishable"
|
|
100
|
+
// skill is an immediate child directory containing SKILL.md (what OpenClaw
|
|
101
|
+
// links into ~/.openclaw/plugin-skills).
|
|
102
|
+
for (const lang of ['zh', 'en']) {
|
|
103
|
+
const skillsDir = join(rootDir, 'dist/templates/langs', lang, 'skills');
|
|
104
|
+
if (!existsSync(skillsDir)) {
|
|
105
|
+
console.error(`❌ Missing skill templates: dist/templates/langs/${lang}/skills`);
|
|
106
|
+
hasError = true;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const publishable = readdirSync(skillsDir, { withFileTypes: true })
|
|
110
|
+
.filter((e) => e.isDirectory() && existsSync(join(skillsDir, e.name, 'SKILL.md')));
|
|
111
|
+
if (publishable.length < 20) {
|
|
112
|
+
console.error(`❌ dist/templates/langs/${lang}/skills has only ${publishable.length} publishable skills (expected at least 20)`);
|
|
113
|
+
hasError = true;
|
|
114
|
+
} else {
|
|
115
|
+
console.log(`✅ ${lang} skills: ${publishable.length} (dist/templates/langs/${lang}/skills/)`);
|
|
105
116
|
}
|
|
106
117
|
}
|
|
107
118
|
|