chore: add continuity plugin package skeleton

This commit is contained in:
Eve
2026-04-24 16:45:06 +08:00
parent 82d0d94b5f
commit b3483098c1
13 changed files with 297 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
export function createForceRecallContinuityAdapter() {
throw new Error('Not implemented: force-recall continuity adapter contract placeholder');
}
export function runForceRecallContinuityAdapter() {
throw new Error('Not implemented: force-recall continuity adapter contract placeholder');
}

View File

@@ -0,0 +1,21 @@
export const defaultConfig = Object.freeze({
enabled: true,
planMatchers: ['approved-plan'],
legalTerminalStates: ['waiting_user', 'blocked', 'pending_verification'],
receiptDir: 'state/approved-plan-continuity',
requireRealDispatchReceipt: true,
allowReplyClosureWithoutDispatch: false,
debug: false,
adapter: {
forceRecall: {
enabled: true,
injectBlockLabel: 'APPROVED_PLAN_CONTINUITY_GATE',
},
},
});
export function cloneDefaultConfig() {
return structuredClone(defaultConfig);
}
export default defaultConfig;

View File

@@ -0,0 +1,59 @@
import defaultConfig, { cloneDefaultConfig } from './defaults.mjs';
export const continuityConfigSchema = Object.freeze({
enabled: 'boolean',
planMatchers: 'string[]',
legalTerminalStates: 'string[]',
receiptDir: 'string',
requireRealDispatchReceipt: 'boolean',
allowReplyClosureWithoutDispatch: 'boolean',
debug: 'boolean',
adapter: {
forceRecall: {
enabled: 'boolean',
injectBlockLabel: 'string',
},
},
});
function isPlainObject(value) {
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
}
export function normalizeContinuityConfig(input = {}) {
const base = cloneDefaultConfig();
if (!isPlainObject(input)) {
return base;
}
return {
...base,
...input,
planMatchers: Array.isArray(input.planMatchers) ? [...input.planMatchers] : [...base.planMatchers],
legalTerminalStates: Array.isArray(input.legalTerminalStates)
? [...input.legalTerminalStates]
: [...base.legalTerminalStates],
adapter: {
...base.adapter,
...(isPlainObject(input.adapter) ? input.adapter : {}),
forceRecall: {
...base.adapter.forceRecall,
...(isPlainObject(input.adapter?.forceRecall) ? input.adapter.forceRecall : {}),
},
},
};
}
export function validateContinuityConfig(input = {}) {
const normalizedConfig = normalizeContinuityConfig(input);
return {
ok: true,
errors: [],
normalizedConfig,
};
}
export { defaultConfig };
export default continuityConfigSchema;

View File

@@ -0,0 +1,7 @@
export function evaluateContinuity() {
throw new Error('Not implemented: continuity evaluator contract placeholder');
}
export function buildContinuityGateBlock() {
throw new Error('Not implemented: continuity gate block contract placeholder');
}

View File

@@ -0,0 +1,7 @@
export function validateReceipt() {
throw new Error('Not implemented: receipt validator contract placeholder');
}
export function isValidReceipt() {
throw new Error('Not implemented: receipt validator contract placeholder');
}

View File

@@ -0,0 +1,46 @@
import { defaultConfig, cloneDefaultConfig } from './config/defaults.mjs';
import {
continuityConfigSchema,
validateContinuityConfig,
normalizeContinuityConfig,
} from './config/schema.mjs';
import {
evaluateContinuity,
buildContinuityGateBlock,
} from './continuity/evaluator.mjs';
import {
validateReceipt,
isValidReceipt,
} from './continuity/receipt-validator.mjs';
import {
createForceRecallContinuityAdapter,
runForceRecallContinuityAdapter,
} from './adapters/force-recall.mjs';
export {
defaultConfig,
cloneDefaultConfig,
continuityConfigSchema,
validateContinuityConfig,
normalizeContinuityConfig,
evaluateContinuity,
buildContinuityGateBlock,
validateReceipt,
isValidReceipt,
createForceRecallContinuityAdapter,
runForceRecallContinuityAdapter,
};
export default {
name: '@openclaw/plugin-continuity',
defaultConfig,
continuityConfigSchema,
validateContinuityConfig,
normalizeContinuityConfig,
evaluateContinuity,
buildContinuityGateBlock,
validateReceipt,
isValidReceipt,
createForceRecallContinuityAdapter,
runForceRecallContinuityAdapter,
};