chore: add continuity plugin package skeleton
This commit is contained in:
20
plugins/continuity/HOOK.md
Normal file
20
plugins/continuity/HOOK.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# HOOK.md
|
||||
|
||||
This document reserves the hook adapter contract for the continuity plugin MVP.
|
||||
|
||||
## Target adapter
|
||||
|
||||
Primary MVP integration target:
|
||||
|
||||
- `force-recall`
|
||||
|
||||
## Planned responsibilities
|
||||
|
||||
- derive continuity input from hook context
|
||||
- invoke the plugin evaluator
|
||||
- return a prompt block / gate result without duplicating continuity rules
|
||||
|
||||
## Current status
|
||||
|
||||
- contract placeholder only
|
||||
- implementation deferred to later plan tasks
|
||||
41
plugins/continuity/README.md
Normal file
41
plugins/continuity/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Continuity Plugin (MVP)
|
||||
|
||||
This package is the skeleton for extracting the current approved-plan continuity hard gate into an installable plugin.
|
||||
|
||||
## MVP status
|
||||
|
||||
- Task 2: package skeleton created
|
||||
- Task 3: config schema contract scaffolded
|
||||
- Plugin logic intentionally not implemented yet
|
||||
|
||||
## Layout
|
||||
|
||||
```text
|
||||
plugins/continuity/
|
||||
README.md
|
||||
README.zh-TW.md
|
||||
HOOK.md
|
||||
package.json
|
||||
examples/
|
||||
src/
|
||||
test/
|
||||
```
|
||||
|
||||
## Planned public surface
|
||||
|
||||
- `src/config/schema.mjs`
|
||||
- `src/config/defaults.mjs`
|
||||
- `src/continuity/evaluator.mjs`
|
||||
- `src/continuity/receipt-validator.mjs`
|
||||
- `src/adapters/force-recall.mjs`
|
||||
- `src/index.mjs`
|
||||
|
||||
## Example config
|
||||
|
||||
See `examples/openclaw.continuity.example.json`.
|
||||
|
||||
## Notes
|
||||
|
||||
- Current terminal states preserved by default: `waiting_user`, `blocked`, `pending_verification`
|
||||
- Default receipt directory target: `state/approved-plan-continuity`
|
||||
- `npm test` is reserved for the full plugin test suite defined by the implementation plan
|
||||
41
plugins/continuity/README.zh-TW.md
Normal file
41
plugins/continuity/README.zh-TW.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Continuity Plugin(MVP)
|
||||
|
||||
這個套件目前是把既有 approved-plan continuity hard gate 抽離成可安裝 plugin 的骨架。
|
||||
|
||||
## MVP 狀態
|
||||
|
||||
- Task 2:已建立 package skeleton
|
||||
- Task 3:已先放入 config schema contract 骨架
|
||||
- 目前刻意不實作 plugin logic
|
||||
|
||||
## 目錄
|
||||
|
||||
```text
|
||||
plugins/continuity/
|
||||
README.md
|
||||
README.zh-TW.md
|
||||
HOOK.md
|
||||
package.json
|
||||
examples/
|
||||
src/
|
||||
test/
|
||||
```
|
||||
|
||||
## 預計公開介面
|
||||
|
||||
- `src/config/schema.mjs`
|
||||
- `src/config/defaults.mjs`
|
||||
- `src/continuity/evaluator.mjs`
|
||||
- `src/continuity/receipt-validator.mjs`
|
||||
- `src/adapters/force-recall.mjs`
|
||||
- `src/index.mjs`
|
||||
|
||||
## 範例設定
|
||||
|
||||
請參考 `examples/openclaw.continuity.example.json`。
|
||||
|
||||
## 備註
|
||||
|
||||
- 預設保留目前 terminal states:`waiting_user`、`blocked`、`pending_verification`
|
||||
- 預設 receipt 目錄:`state/approved-plan-continuity`
|
||||
- `npm test` 先保留給後續依計畫補上的完整測試流程
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"planId": "example-plan",
|
||||
"currentTask": "task-01",
|
||||
"nextDerivedAction": {
|
||||
"kind": "delegate",
|
||||
"target": "subagent",
|
||||
"task": "placeholder"
|
||||
},
|
||||
"dispatchedAt": "2026-04-24T16:43:00+08:00",
|
||||
"dispatchRunId": "example-run",
|
||||
"childSessionKey": "session-placeholder",
|
||||
"replyClosureState": "pending_verification"
|
||||
}
|
||||
21
plugins/continuity/examples/openclaw.continuity.example.json
Normal file
21
plugins/continuity/examples/openclaw.continuity.example.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
13
plugins/continuity/package.json
Normal file
13
plugins/continuity/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "@openclaw/plugin-continuity",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "Continuity plugin MVP skeleton for approved-plan dispatch gating.",
|
||||
"exports": {
|
||||
".": "./src/index.mjs"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/continuity.config.test.mjs && node test/continuity.receipt-validator.test.mjs && node test/continuity.receipt-store.test.mjs && node test/continuity.evaluator.test.mjs && node test/continuity.plugin.test.mjs && node test/continuity.smoke.test.mjs"
|
||||
}
|
||||
}
|
||||
7
plugins/continuity/src/adapters/force-recall.mjs
Normal file
7
plugins/continuity/src/adapters/force-recall.mjs
Normal 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');
|
||||
}
|
||||
21
plugins/continuity/src/config/defaults.mjs
Normal file
21
plugins/continuity/src/config/defaults.mjs
Normal 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;
|
||||
59
plugins/continuity/src/config/schema.mjs
Normal file
59
plugins/continuity/src/config/schema.mjs
Normal 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;
|
||||
7
plugins/continuity/src/continuity/evaluator.mjs
Normal file
7
plugins/continuity/src/continuity/evaluator.mjs
Normal 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');
|
||||
}
|
||||
7
plugins/continuity/src/continuity/receipt-validator.mjs
Normal file
7
plugins/continuity/src/continuity/receipt-validator.mjs
Normal 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');
|
||||
}
|
||||
46
plugins/continuity/src/index.mjs
Normal file
46
plugins/continuity/src/index.mjs
Normal 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,
|
||||
};
|
||||
1
plugins/continuity/test/.gitkeep
Normal file
1
plugins/continuity/test/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user