principles-disciple 1.11.0 → 1.13.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.
Files changed (233) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +66 -0
  3. package/esbuild.config.js +1 -1
  4. package/openclaw.plugin.json +4 -4
  5. package/package.json +2 -3
  6. package/run-nocturnal.mjs +30 -0
  7. package/scripts/db-migrate.mjs +170 -0
  8. package/scripts/sync-plugin.mjs +250 -6
  9. package/src/commands/archive-impl.ts +136 -0
  10. package/src/commands/capabilities.ts +4 -2
  11. package/src/commands/context.ts +5 -1
  12. package/src/commands/disable-impl.ts +151 -0
  13. package/src/commands/evolution-status.ts +64 -19
  14. package/src/commands/export.ts +8 -6
  15. package/src/commands/focus.ts +8 -20
  16. package/src/commands/nocturnal-review.ts +5 -7
  17. package/src/commands/nocturnal-rollout.ts +1 -12
  18. package/src/commands/nocturnal-train.ts +21 -47
  19. package/src/commands/pain.ts +10 -5
  20. package/src/commands/principle-rollback.ts +4 -2
  21. package/src/commands/promote-impl.ts +274 -0
  22. package/src/commands/rollback-impl.ts +234 -0
  23. package/src/commands/rollback.ts +6 -3
  24. package/src/commands/samples.ts +2 -0
  25. package/src/commands/thinking-os.ts +3 -4
  26. package/src/commands/workflow-debug.ts +2 -1
  27. package/src/config/errors.ts +1 -0
  28. package/src/core/AGENTS.md +34 -0
  29. package/src/core/adaptive-thresholds.ts +4 -3
  30. package/src/core/code-implementation-storage.ts +241 -0
  31. package/src/core/config.ts +5 -2
  32. package/src/core/control-ui-db.ts +29 -10
  33. package/src/core/detection-funnel.ts +12 -7
  34. package/src/core/diagnostician-task-store.ts +156 -0
  35. package/src/core/dictionary.ts +4 -4
  36. package/src/core/empathy-keyword-matcher.ts +7 -3
  37. package/src/core/empathy-types.ts +13 -2
  38. package/src/core/event-log.ts +14 -6
  39. package/src/core/evolution-engine.ts +27 -31
  40. package/src/core/evolution-logger.ts +3 -2
  41. package/src/core/evolution-reducer.ts +110 -31
  42. package/src/core/evolution-types.ts +10 -0
  43. package/src/core/external-training-contract.ts +1 -0
  44. package/src/core/focus-history.ts +38 -24
  45. package/src/core/hygiene/tracker.ts +10 -6
  46. package/src/core/init.ts +5 -2
  47. package/src/core/migration.ts +3 -3
  48. package/src/core/model-deployment-registry.ts +6 -4
  49. package/src/core/model-training-registry.ts +5 -3
  50. package/src/core/nocturnal-arbiter.ts +13 -14
  51. package/src/core/nocturnal-artifact-lineage.ts +117 -0
  52. package/src/core/nocturnal-artificer.ts +257 -0
  53. package/src/core/nocturnal-candidate-scoring.ts +4 -2
  54. package/src/core/nocturnal-compliance.ts +67 -19
  55. package/src/core/nocturnal-dataset.ts +95 -2
  56. package/src/core/nocturnal-executability.ts +2 -3
  57. package/src/core/nocturnal-export.ts +6 -3
  58. package/src/core/nocturnal-rule-implementation-validator.ts +245 -0
  59. package/src/core/nocturnal-trajectory-extractor.ts +10 -3
  60. package/src/core/nocturnal-trinity.ts +319 -61
  61. package/src/core/pain-context-extractor.ts +29 -15
  62. package/src/core/pain.ts +7 -5
  63. package/src/core/path-resolver.ts +16 -15
  64. package/src/core/paths.ts +2 -1
  65. package/src/core/pd-task-reconciler.ts +463 -0
  66. package/src/core/pd-task-service.ts +42 -0
  67. package/src/core/pd-task-store.ts +77 -0
  68. package/src/core/pd-task-types.ts +128 -0
  69. package/src/core/principle-internalization/deprecated-readiness.ts +91 -0
  70. package/src/core/principle-internalization/internalization-routing-policy.ts +208 -0
  71. package/src/core/principle-internalization/lifecycle-metrics.ts +149 -0
  72. package/src/core/principle-internalization/lifecycle-read-model.ts +243 -0
  73. package/src/core/principle-internalization/lifecycle-refresh.ts +11 -0
  74. package/src/core/principle-internalization/principle-lifecycle-service.ts +167 -0
  75. package/src/core/principle-training-state.ts +95 -370
  76. package/src/core/principle-tree-ledger.ts +733 -0
  77. package/src/core/principle-tree-migration.ts +195 -0
  78. package/src/core/profile.ts +3 -1
  79. package/src/core/promotion-gate.ts +14 -18
  80. package/src/core/replay-engine.ts +562 -0
  81. package/src/core/risk-calculator.ts +6 -4
  82. package/src/core/rule-host-helpers.ts +39 -0
  83. package/src/core/rule-host-types.ts +82 -0
  84. package/src/core/rule-host.ts +245 -0
  85. package/src/core/rule-implementation-runtime.ts +38 -0
  86. package/src/core/schema/db-types.ts +16 -0
  87. package/src/core/schema/index.ts +26 -0
  88. package/src/core/schema/migration-runner.ts +207 -0
  89. package/src/core/schema/migrations/001-init-trajectory.ts +211 -0
  90. package/src/core/schema/migrations/002-init-central.ts +122 -0
  91. package/src/core/schema/migrations/003-init-workflow.ts +55 -0
  92. package/src/core/schema/migrations/004-add-thinking-and-gfi.ts +74 -0
  93. package/src/core/schema/migrations/index.ts +31 -0
  94. package/src/core/schema/schema-definitions.ts +650 -0
  95. package/src/core/session-tracker.ts +6 -4
  96. package/src/core/shadow-observation-registry.ts +6 -3
  97. package/src/core/system-logger.ts +2 -2
  98. package/src/core/thinking-models.ts +182 -46
  99. package/src/core/thinking-os-parser.ts +156 -0
  100. package/src/core/training-program.ts +7 -7
  101. package/src/core/trajectory.ts +42 -36
  102. package/src/core/workspace-context.ts +77 -11
  103. package/src/core/workspace-dir-validation.ts +152 -0
  104. package/src/hooks/AGENTS.md +31 -0
  105. package/src/hooks/bash-risk.ts +3 -1
  106. package/src/hooks/edit-verification.ts +9 -5
  107. package/src/hooks/gate-block-helper.ts +5 -1
  108. package/src/hooks/gate.ts +152 -5
  109. package/src/hooks/gfi-gate.ts +9 -2
  110. package/src/hooks/lifecycle-routing.ts +124 -0
  111. package/src/hooks/lifecycle.ts +12 -12
  112. package/src/hooks/llm.ts +17 -109
  113. package/src/hooks/message-sanitize.ts +5 -3
  114. package/src/hooks/pain.ts +19 -15
  115. package/src/hooks/progressive-trust-gate.ts +7 -1
  116. package/src/hooks/prompt.ts +169 -60
  117. package/src/hooks/subagent.ts +5 -4
  118. package/src/hooks/thinking-checkpoint.ts +2 -0
  119. package/src/hooks/trajectory-collector.ts +15 -12
  120. package/src/http/principles-console-route.ts +31 -68
  121. package/src/i18n/commands.ts +2 -2
  122. package/src/index.ts +130 -40
  123. package/src/service/central-database.ts +131 -43
  124. package/src/service/central-health-service.ts +47 -0
  125. package/src/service/central-overview-service.ts +135 -0
  126. package/src/service/central-sync-service.ts +87 -0
  127. package/src/service/control-ui-query-service.ts +46 -36
  128. package/src/service/event-log-auditor.ts +261 -0
  129. package/src/service/evolution-query-service.ts +23 -22
  130. package/src/service/evolution-worker.ts +565 -261
  131. package/src/service/health-query-service.ts +213 -36
  132. package/src/service/nocturnal-runtime.ts +8 -4
  133. package/src/service/nocturnal-service.ts +503 -59
  134. package/src/service/nocturnal-target-selector.ts +5 -7
  135. package/src/service/runtime-summary-service.ts +2 -1
  136. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +25 -336
  137. package/src/service/subagent-workflow/dynamic-timeout.ts +30 -0
  138. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +48 -386
  139. package/src/service/subagent-workflow/index.ts +2 -0
  140. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +169 -284
  141. package/src/service/subagent-workflow/runtime-direct-driver.ts +114 -16
  142. package/src/service/subagent-workflow/subagent-error-utils.ts +25 -0
  143. package/src/service/subagent-workflow/types.ts +9 -4
  144. package/src/service/subagent-workflow/workflow-manager-base.ts +573 -0
  145. package/src/service/subagent-workflow/workflow-store.ts +71 -11
  146. package/src/service/trajectory-service.ts +2 -1
  147. package/src/tools/critique-prompt.ts +1 -1
  148. package/src/tools/deep-reflect.ts +175 -209
  149. package/src/tools/model-index.ts +2 -1
  150. package/src/types/event-types.ts +2 -2
  151. package/src/types/principle-tree-schema.ts +29 -23
  152. package/src/utils/file-lock.ts +5 -3
  153. package/src/utils/io.ts +5 -2
  154. package/src/utils/nlp.ts +5 -46
  155. package/src/utils/node-vm-polyfill.ts +11 -0
  156. package/src/utils/plugin-logger.ts +2 -0
  157. package/src/utils/retry.ts +572 -0
  158. package/src/utils/subagent-probe.ts +1 -1
  159. package/templates/langs/en/core/AGENTS.md +0 -13
  160. package/templates/langs/en/core/SOUL.md +1 -31
  161. package/templates/langs/en/core/TOOLS.md +0 -4
  162. package/templates/langs/en/principles/THINKING_OS.md +77 -0
  163. package/templates/langs/en/skills/admin/SKILL.md +0 -1
  164. package/templates/langs/en/skills/evolution-framework-update/SKILL.md +1 -1
  165. package/templates/langs/en/skills/pd-diagnostician/SKILL.md +18 -5
  166. package/templates/langs/zh/core/AGENTS.md +0 -22
  167. package/templates/langs/zh/core/SOUL.md +1 -31
  168. package/templates/langs/zh/core/TOOLS.md +0 -4
  169. package/templates/langs/zh/principles/THINKING_OS.md +77 -0
  170. package/templates/langs/zh/skills/admin/SKILL.md +0 -1
  171. package/templates/langs/zh/skills/evolution-framework-update/SKILL.md +1 -1
  172. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +25 -4
  173. package/tests/commands/evolution-status.test.ts +119 -0
  174. package/tests/commands/implementation-lifecycle.test.ts +362 -0
  175. package/tests/core/code-implementation-storage.test.ts +398 -0
  176. package/tests/core/evolution-reducer.detector-metadata.test.ts +28 -28
  177. package/tests/core/nocturnal-artifact-lineage.test.ts +53 -0
  178. package/tests/core/nocturnal-artificer.test.ts +241 -0
  179. package/tests/core/nocturnal-compliance-p-principles.test.ts +133 -0
  180. package/tests/core/nocturnal-rule-implementation-validator.test.ts +127 -0
  181. package/tests/core/pd-task-store.test.ts +126 -0
  182. package/tests/core/principle-internalization/deprecated-readiness.test.ts +193 -0
  183. package/tests/core/principle-internalization/internalization-routing-policy.test.ts +212 -0
  184. package/tests/core/principle-internalization/lifecycle-metrics.test.ts +350 -0
  185. package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +211 -0
  186. package/tests/core/principle-training-state.test.ts +228 -1
  187. package/tests/core/principle-tree-ledger.test.ts +423 -0
  188. package/tests/core/regression-v1-9-1.test.ts +265 -0
  189. package/tests/core/replay-engine.test.ts +234 -0
  190. package/tests/core/rule-host-helpers.test.ts +120 -0
  191. package/tests/core/rule-host.test.ts +389 -0
  192. package/tests/core/rule-implementation-runtime.test.ts +64 -0
  193. package/tests/core/workspace-context.test.ts +53 -0
  194. package/tests/core/workspace-dir-validation.test.ts +272 -0
  195. package/tests/hooks/gate-rule-host-pipeline.test.ts +385 -0
  196. package/tests/hooks/pain.test.ts +74 -10
  197. package/tests/hooks/prompt.test.ts +63 -1
  198. package/tests/integration/principle-lifecycle.e2e.test.ts +197 -0
  199. package/tests/integration/tool-hooks-workspace-dir.e2e.test.ts +211 -0
  200. package/tests/service/data-endpoints-regression.test.ts +834 -0
  201. package/tests/service/evolution-worker.test.ts +0 -123
  202. package/tests/service/nocturnal-service-code-candidate.test.ts +330 -0
  203. package/tests/utils/nlp.test.ts +1 -19
  204. package/tests/utils/retry.test.ts +327 -0
  205. package/ui/src/App.tsx +1 -1
  206. package/ui/src/api.ts +4 -0
  207. package/ui/src/charts.tsx +366 -0
  208. package/ui/src/components/WorkspaceConfig.tsx +107 -75
  209. package/ui/src/i18n/ui.ts +89 -31
  210. package/ui/src/pages/EvolutionPage.tsx +1 -1
  211. package/ui/src/pages/OverviewPage.tsx +441 -81
  212. package/ui/src/pages/ThinkingModelsPage.tsx +287 -69
  213. package/ui/src/styles.css +43 -0
  214. package/ui/src/types.ts +17 -1
  215. package/src/agents/nocturnal-dreamer.md +0 -152
  216. package/src/agents/nocturnal-philosopher.md +0 -138
  217. package/src/agents/nocturnal-reflector.md +0 -126
  218. package/src/agents/nocturnal-scribe.md +0 -164
  219. package/templates/workspace/.principles/00-kernel.md +0 -51
  220. package/templates/workspace/.principles/DECISION_POLICY.json +0 -44
  221. package/templates/workspace/.principles/PRINCIPLES.md +0 -20
  222. package/templates/workspace/.principles/PROFILE.json +0 -54
  223. package/templates/workspace/.principles/PROFILE.schema.json +0 -56
  224. package/templates/workspace/.principles/THINKING_OS.md +0 -64
  225. package/templates/workspace/.principles/THINKING_OS_ARCHIVE.md +0 -7
  226. package/templates/workspace/.principles/THINKING_OS_CANDIDATES.md +0 -9
  227. package/templates/workspace/.principles/models/_INDEX.md +0 -27
  228. package/templates/workspace/.principles/models/first_principles.md +0 -62
  229. package/templates/workspace/.principles/models/marketing_4p.md +0 -52
  230. package/templates/workspace/.principles/models/porter_five.md +0 -63
  231. package/templates/workspace/.principles/models/swot.md +0 -60
  232. package/templates/workspace/.principles/models/user_story_map.md +0 -63
  233. package/templates/workspace/.state/WORKBOARD.json +0 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
1
+ # principles-disciple
2
+
3
+ ## 1.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 650ae5a: ## v1.9.1: WebUI Data Source Fixes
8
+
9
+ ### Phase 16-20 Complete
10
+
11
+ - **Phase 16**: Data Source Tracing - mapped all 4 WebUI pages to API endpoints
12
+ - **Phase 17**: Overview Page Fix - fixed `/api/central/overview`, `/api/overview`, `/api/overview/health`
13
+ - **Phase 18**: Loop/Samples + Feedback Fix - fixed `/api/samples`, `/api/feedback/*` data sources
14
+ - **Phase 19**: Gate Monitor Frontend - fixed `/api/gate/stats`, `/api/gate/blocks` types
15
+ - **Phase 20**: E2E Validation - 19 regression tests added for all API endpoints
16
+
17
+ ### Bug Fixes
18
+
19
+ - Fixed `evolution-worker.ts` missing `runtimeAdapter` parameter
20
+ - Fixed `nocturnal-train.ts` mode field type annotation
21
+ - Fixed `sync-version.sh` to include `create-principles-disciple` package
22
+
23
+ ### Infrastructure
24
+
25
+ - Added `@changesets/cli` for monorepo version management
26
+ - Added `data-endpoints-regression.test.ts` with 19 tests
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ <!-- generated-by: gsd-doc-writer -->
2
+ # principles-disciple
3
+
4
+ Native OpenClaw plugin for Principles Disciple: an evolutionary programming agent framework with strategic guardrails and reflection loops.
5
+
6
+ ## Installation
7
+
8
+ ```bash
9
+ npm install principles-disciple
10
+ ```
11
+
12
+ Requires OpenClaw `>=2026.4.4` as a peer dependency.
13
+
14
+ ## Usage
15
+
16
+ This plugin integrates with OpenClaw to provide an evolutionary programming framework. It intercepts agent operations through hooks to enforce security guardrails, track pain points, collect trajectory data, and enable deep reflection capabilities.
17
+
18
+ ### Slash Commands
19
+
20
+ | Command | Description |
21
+ |---------|-------------|
22
+ | `/pd-init` | Initialize workspace |
23
+ | `/pd-bootstrap` | Scan environment tools |
24
+ | `/pd-research` | Research tools and capabilities |
25
+ | `/pd-thinking` | Manage thinking models |
26
+ | `/pd-status` | View evolution status |
27
+ | `/pd-context` | Control context injection |
28
+ | `/pd-focus` | Focus file management |
29
+ | `/pd-evolution-status` | View evolution state |
30
+ | `/pd-rollback` | Rollback to previous state |
31
+ | `/pd-export` | Export trajectory/correction data |
32
+ | `/pd-samples` | Review correction samples |
33
+ | `/pd-nocturnal-review` | Review nocturnal training samples |
34
+ | `/nocturnal-train` | Nocturnal training operations |
35
+ | `/nocturnal-rollout` | Nocturnal rollout and promotion |
36
+ | `/pd-workflow-debug` | Debug workflow state |
37
+ | `/pd-help` | Show command reference |
38
+
39
+ ### Tools
40
+
41
+ **`deep_reflect`** - Executes deep meta-cognitive reflection to analyze potential risks, logical gaps, or architectural improvements in the current task.
42
+
43
+ Parameters:
44
+ - `context` (required): Task context, code snippet, or current difficulty
45
+ - `depth` (optional): Reflection depth 1-3 (default: 2)
46
+ - `model_id` (optional): Force specific thinking model
47
+
48
+ ### Configuration
49
+
50
+ The plugin accepts the following configuration options:
51
+
52
+ | Option | Default | Description |
53
+ |--------|---------|-------------|
54
+ | `language` | `zh` | Interaction language (`en` or `zh`) |
55
+ | `auditLevel` | `medium` | Security guardrail level (`low`, `medium`, `high`) |
56
+ | `riskPaths` | `[]` | High-risk directories requiring explicit authorization |
57
+ | `deep_reflection.enabled` | `true` | Enable AI deep reflection |
58
+ | `deep_reflection.mode` | `auto` | Reflection trigger mode (`auto` or `forced`) |
59
+
60
+ ## Part of the principles monorepo
61
+
62
+ See the root [README.md](https://github.com/csuzngjh/principles#readme) for the full project overview.
63
+
64
+ ## License
65
+
66
+ MIT License - [LICENSE](https://github.com/csuzngjh/principles/blob/main/LICENSE)
package/esbuild.config.js CHANGED
@@ -46,7 +46,7 @@ async function bundlePlugin() {
46
46
 
47
47
  console.log('Bundle created: dist/bundle.js');
48
48
 
49
- const staticFiles = ['templates', 'agents', 'openclaw.plugin.json'];
49
+ const staticFiles = ['templates', 'openclaw.plugin.json'];
50
50
  const distDir = 'dist';
51
51
 
52
52
  for (const file of staticFiles) {
@@ -2,7 +2,7 @@
2
2
  "id": "principles-disciple",
3
3
  "name": "Principles Disciple",
4
4
  "description": "Evolutionary programming agent framework with strategic guardrails and reflection loops.",
5
- "version": "1.11.0",
5
+ "version": "1.13.0",
6
6
  "skills": [
7
7
  "./skills"
8
8
  ],
@@ -76,8 +76,8 @@
76
76
  }
77
77
  },
78
78
  "buildFingerprint": {
79
- "gitSha": "c159a298aac0",
80
- "bundleMd5": "e54bd6b71182252dd335aa016c9caa0e",
81
- "builtAt": "2026-04-06T05:28:57.508Z"
79
+ "gitSha": "ad52c5fcc9c5",
80
+ "bundleMd5": "3dc29cb961c7132e1ad419550686df6c",
81
+ "builtAt": "2026-04-10T01:19:54.357Z"
82
82
  }
83
83
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "principles-disciple",
3
- "version": "1.11.0",
3
+ "version": "1.13.0",
4
4
  "description": "Native OpenClaw plugin for Principles Disciple",
5
5
  "type": "module",
6
6
  "main": "./dist/bundle.js",
@@ -32,8 +32,7 @@
32
32
  "build:production": "node esbuild.config.js --production && node scripts/build-web.mjs --production && node scripts/verify-build.mjs",
33
33
  "test": "vitest run",
34
34
  "test:coverage": "vitest run --coverage",
35
- "lint": "eslint src/",
36
- "postinstall": "node scripts/install-dependencies.cjs"
35
+ "lint": "eslint src/"
37
36
  },
38
37
  "devDependencies": {
39
38
  "@testing-library/react": "^16.3.0",
@@ -0,0 +1,30 @@
1
+ import { randomUUID } from 'crypto';
2
+ import * as fs from 'fs';
3
+
4
+ const workspaceDir = '/home/csuzngjh/.openclaw/workspace-main';
5
+ const stateDir = '/home/csuzngjh/.openclaw/workspace-main/.state';
6
+
7
+ console.error('WorkspaceDir:', workspaceDir);
8
+ console.error('StateDir:', stateDir);
9
+
10
+ try {
11
+ const bundlePath = './dist/nocturnal-service.bundle.js';
12
+ console.error('Importing from:', bundlePath);
13
+
14
+ const mod = await import(bundlePath);
15
+
16
+ console.log('Available exports:', Object.keys(mod));
17
+
18
+ if (!mod.executeNocturnalReflection) {
19
+ throw new Error('executeNocturnalReflection not found in bundle. Available exports: ' + Object.keys(mod).join(', '));
20
+ }
21
+
22
+ console.error('Calling executeNocturnalReflection...');
23
+ const result = await mod.executeNocturnalReflection(workspaceDir, stateDir);
24
+
25
+ console.log(JSON.stringify(result, null, 2));
26
+ } catch (err) {
27
+ console.error('ERROR:', err.message);
28
+ if (err.stack) console.error(err.stack);
29
+ process.exit(1);
30
+ }
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Database Migration CLI
5
+ *
6
+ * Usage:
7
+ * node scripts/db-migrate.mjs status # Show migration status
8
+ * node scripts/db-migrate.mjs run [--db trajectory.db|central.db|workflow.db]
9
+ * node scripts/db-migrate.mjs rollback [--db trajectory.db|central.db|workflow.db]
10
+ */
11
+
12
+ import { Database } from 'better-sqlite3';
13
+ import { join } from 'path';
14
+ import { fileURLToPath } from 'url';
15
+ import { dirname } from 'path';
16
+
17
+ const __filename = fileURLToPath(import.meta.url);
18
+ const __dirname = dirname(__filename);
19
+
20
+ // Resolve paths
21
+ const PROJECT_ROOT = join(__dirname, '..');
22
+ const STATE_DIR = process.env.STATE_DIR || join(PROJECT_ROOT, '..', '.state');
23
+
24
+ // We need to dynamically import the schema module since it's TypeScript
25
+ // For CLI, we'll use the compiled JS version
26
+ async function run() {
27
+ let SchemaModule;
28
+ try {
29
+ SchemaModule = await import('../dist/core/schema/index.js');
30
+ } catch {
31
+ // Try running from source with tsx
32
+ console.error('Schema module not found in dist/. Running from source...');
33
+ console.error('Please build the plugin first: node esbuild.config.js --production');
34
+ process.exit(1);
35
+ }
36
+
37
+ const { MigrationRunner, ensureDatabaseSchema, ALL_MIGRATIONS, DB_TYPES } = SchemaModule;
38
+
39
+ const args = process.argv.slice(2);
40
+ const command = args[0];
41
+
42
+ if (!command || command === '--help' || command === '-h') {
43
+ console.log(`
44
+ Database Migration CLI
45
+
46
+ Usage:
47
+ node scripts/db-migrate.mjs status Show migration status for all databases
48
+ node scripts/db-migrate.mjs run [--db <db>] Run pending migrations
49
+ node scripts/db-migrate.mjs rollback [--db <db>] Rollback latest migration
50
+
51
+ Options:
52
+ --db <db> Target database: trajectory.db, central.db, or workflow.db
53
+ (default: all databases)
54
+ --state-dir Override state directory (default: .state/)
55
+
56
+ Examples:
57
+ node scripts/db-migrate.mjs status
58
+ node scripts/db-migrate.mjs run --db trajectory.db
59
+ node scripts/db-migrate.mjs rollback --db central.db
60
+ `);
61
+ return;
62
+ }
63
+
64
+ const dbFlag = args.indexOf('--db');
65
+ const targetDb = dbFlag >= 0 ? args[dbFlag + 1] : null;
66
+
67
+ const dbs = targetDb ? [targetDb] : DB_TYPES;
68
+
69
+ for (const dbType of dbs) {
70
+ if (!DB_TYPES.includes(dbType)) {
71
+ console.error(`Unknown database: ${dbType}. Valid options: ${DB_TYPES.join(', ')}`);
72
+ continue;
73
+ }
74
+
75
+ const dbPath = getDbPath(dbType);
76
+ const db = new Database(dbPath);
77
+
78
+ console.log(`\n=== ${dbType} (${dbPath}) ===`);
79
+
80
+ switch (command) {
81
+ case 'status':
82
+ showStatus(db, dbType, ALL_MIGRATIONS, MigrationRunner);
83
+ break;
84
+ case 'run':
85
+ runMigrations(db, dbType, ALL_MIGRATIONS, MigrationRunner);
86
+ break;
87
+ case 'rollback':
88
+ rollbackMigration(db, dbType, ALL_MIGRATIONS, MigrationRunner);
89
+ break;
90
+ case 'ensure':
91
+ console.log('Ensuring schema...');
92
+ ensureDatabaseSchema(db, dbType);
93
+ console.log('Schema ensured.');
94
+ break;
95
+ default:
96
+ console.error(`Unknown command: ${command}`);
97
+ }
98
+
99
+ db.close();
100
+ }
101
+ }
102
+
103
+ function getDbPath(dbType) {
104
+ switch (dbType) {
105
+ case 'trajectory.db':
106
+ return join(STATE_DIR, 'trajectory.db');
107
+ case 'central.db':
108
+ return join(process.env.HOME, '.openclaw', '.central', 'aggregated.db');
109
+ case 'workflow.db':
110
+ return join(STATE_DIR, 'subagent_workflows.db');
111
+ default:
112
+ throw new Error(`Unknown database type: ${dbType}`);
113
+ }
114
+ }
115
+
116
+ function showStatus(db, dbType, migrations, Runner) {
117
+ const runner = new Runner(db);
118
+ const current = runner.getCurrentVersion();
119
+ const info = runner.getMigrationInfo(migrations, dbType);
120
+
121
+ console.log(`Current version: ${current}`);
122
+ console.log('');
123
+
124
+ for (const m of info) {
125
+ const status = m.applied ? '✅' : '⏳';
126
+ console.log(` ${status} ${m.id}-${m.name}`);
127
+ }
128
+
129
+ if (info.length === 0) {
130
+ console.log(' No migrations defined for this database.');
131
+ }
132
+ }
133
+
134
+ function runMigrations(db, dbType, migrations, Runner) {
135
+ const runner = new Runner(db);
136
+
137
+ // First ensure base schema
138
+ console.log('Applying schema catalog...');
139
+ runner.applySchemaCatalog(dbType);
140
+
141
+ // Then run any additional migrations
142
+ const dbMigrations = migrations.filter(m => m.db === dbType);
143
+ if (dbMigrations.length > 0) {
144
+ const applied = runner.runMigrations(dbMigrations, dbType);
145
+ if (applied.length === 0) {
146
+ console.log('All migrations already applied.');
147
+ }
148
+ }
149
+
150
+ showStatus(db, dbType, migrations, Runner);
151
+ }
152
+
153
+ function rollbackMigration(db, dbType, migrations, Runner) {
154
+ const runner = new Runner(db);
155
+ const dbMigrations = migrations.filter(m => m.db === dbType);
156
+ const rolledBack = runner.rollback(dbMigrations, dbType);
157
+
158
+ if (rolledBack) {
159
+ console.log(`Rolled back migration ${rolledBack}`);
160
+ } else {
161
+ console.log('No migrations to roll back.');
162
+ }
163
+
164
+ showStatus(db, dbType, migrations, Runner);
165
+ }
166
+
167
+ run().catch(err => {
168
+ console.error('Migration CLI error:', err);
169
+ process.exit(1);
170
+ });
@@ -17,7 +17,7 @@
17
17
  * --help Show help message
18
18
  */
19
19
 
20
- import { copyFileSync, cpSync, existsSync, rmSync, readFileSync, readFileSync as readFileSyncRaw, mkdirSync, writeFileSync, readdirSync } from 'fs';
20
+ import { copyFileSync, cpSync, existsSync, rmSync, readFileSync, readFileSync as readFileSyncRaw, mkdirSync, writeFileSync, readdirSync, statSync } from 'fs';
21
21
  import { createHash } from 'crypto';
22
22
  import { join, dirname } from 'path';
23
23
  import { fileURLToPath } from 'url';
@@ -54,6 +54,7 @@ function parseArgs() {
54
54
  force: false,
55
55
  restart: false,
56
56
  dev: false,
57
+ bump: false,
57
58
  help: false,
58
59
  };
59
60
 
@@ -78,6 +79,11 @@ function parseArgs() {
78
79
  args.dev = true;
79
80
  args.force = true;
80
81
  args.restart = true;
82
+ args.bump = true;
83
+ break;
84
+ case '--bump':
85
+ case '-b':
86
+ args.bump = true;
81
87
  break;
82
88
  case '--force':
83
89
  case '-f':
@@ -112,7 +118,8 @@ Options:
112
118
  --skip-build Skip build step (use existing dist/)
113
119
  --skip-deps Skip dependency installation
114
120
  --restart Automatically restart OpenClaw gateway after installation
115
- --dev, -d Developer mode: --force + --restart + clean stale backups (default for local dev)
121
+ --dev, -d Developer mode: --force + --restart + --bump + clean stale backups
122
+ --bump, -b Auto-bump patch version if there are uncommitted source changes
116
123
  --force, -f Force overwrite without prompts
117
124
  --help, -h Show this help message
118
125
 
@@ -123,9 +130,12 @@ Examples:
123
130
  # Install with English skills
124
131
  node scripts/sync-plugin.mjs --lang en
125
132
 
126
- # Developer mode: build, deploy, restart, clean up (recommended for debugging)
133
+ # Developer mode: bump version, build, deploy, restart, clean up (recommended)
127
134
  node scripts/sync-plugin.mjs --dev
128
135
 
136
+ # Just bump version without deploying
137
+ node scripts/sync-plugin.mjs --bump --skip-build --skip-deps
138
+
129
139
  # Quick sync after local build
130
140
  node scripts/sync-plugin.mjs --skip-deps --skip-build
131
141
 
@@ -206,6 +216,80 @@ function getVersion(dir) {
206
216
  }
207
217
  }
208
218
 
219
+ /**
220
+ * Auto-bump patch version if there are uncommitted source changes.
221
+ * Updates all version files: package.json (root + plugin), openclaw.plugin.json, README_ZH.md.
222
+ */
223
+ function autoBumpVersion(sourceDir) {
224
+ const rootDir = join(sourceDir, '..', '..');
225
+ const pluginDir = sourceDir;
226
+
227
+ // Check for uncommitted changes in source files
228
+ try {
229
+ const diffOutput = execSync('git diff --name-only HEAD', {
230
+ cwd: rootDir,
231
+ encoding: 'utf-8',
232
+ }).trim();
233
+ const changedFiles = diffOutput ? diffOutput.split('\n').filter(f => {
234
+ return f.startsWith('packages/openclaw-plugin/src/') ||
235
+ f.startsWith('packages/openclaw-plugin/skills/') ||
236
+ f.startsWith('scripts/') ||
237
+ f === 'packages/openclaw-plugin/package.json' ||
238
+ f === 'package.json' ||
239
+ f === 'README_ZH.md';
240
+ }) : [];
241
+
242
+ if (changedFiles.length === 0) {
243
+ console.log('📋 No uncommitted source changes — skipping version bump');
244
+ return;
245
+ }
246
+
247
+ console.log(`📋 Found uncommitted changes in ${changedFiles.length} file(s) — bumping version...`);
248
+
249
+ const currentVersion = getVersion(pluginDir);
250
+ if (!currentVersion) {
251
+ console.error('❌ Cannot determine current version');
252
+ process.exit(1);
253
+ }
254
+
255
+ const [major, minor, patch] = currentVersion.split('.').map(Number);
256
+ const newVersion = `${major}.${minor}.${patch + 1}`;
257
+
258
+ // Update package.json (plugin)
259
+ const pkgPath = join(pluginDir, 'package.json');
260
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
261
+ pkg.version = newVersion;
262
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
263
+
264
+ // Update openclaw.plugin.json
265
+ const manifestPath = join(pluginDir, 'openclaw.plugin.json');
266
+ const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
267
+ manifest.version = newVersion;
268
+ writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
269
+
270
+ // Update root package.json
271
+ const rootPkgPath = join(rootDir, 'package.json');
272
+ if (existsSync(rootPkgPath)) {
273
+ const rootPkg = JSON.parse(readFileSync(rootPkgPath, 'utf-8'));
274
+ rootPkg.version = newVersion;
275
+ writeFileSync(rootPkgPath, JSON.stringify(rootPkg, null, 2) + '\n', 'utf-8');
276
+ }
277
+
278
+ // Update README_ZH.md
279
+ const readmePath = join(rootDir, 'README_ZH.md');
280
+ if (existsSync(readmePath)) {
281
+ let readme = readFileSync(readmePath, 'utf-8');
282
+ readme = readme.replace(/v\d+\.\d+\.\d+/g, `v${newVersion}`);
283
+ writeFileSync(readmePath, readme, 'utf-8');
284
+ }
285
+
286
+ console.log(`✅ Version bumped: ${currentVersion} → ${newVersion}`);
287
+ } catch (err) {
288
+ console.warn(`⚠️ Auto-bump failed: ${err.message}`);
289
+ console.warn(' Continuing with current version');
290
+ }
291
+ }
292
+
209
293
  /**
210
294
  * Install project dependencies
211
295
  */
@@ -583,6 +667,158 @@ function syncItem(item) {
583
667
  }
584
668
  }
585
669
 
670
+ /**
671
+ * Sync workspace templates to all workspace directories.
672
+ * This ensures workspaces get the latest template files when the plugin is updated.
673
+ *
674
+ * IMPORTANT SAFETY RULES:
675
+ * - Core files (AGENTS.md, SOUL.md, IDENTITY.md, USER.md, etc.) are NEVER overwritten.
676
+ * They are only copied on first-time workspace creation (file doesn't exist).
677
+ * Users heavily customize these files — overwriting would destroy their work.
678
+ * - Non-core templates (pain_samples, THINKING_OS.md, workspace boilerplate) are synced
679
+ * via MD5 comparison (only update if template content changed and workspace hasn't diverged).
680
+ *
681
+ * Syncs:
682
+ * - templates/workspace/** → workspace root (recursive, skip core files)
683
+ * - templates/langs/{lang}/core/** → workspace root (ONLY if missing)
684
+ * - templates/langs/{lang}/pain/** → .state/pain_samples/
685
+ * - templates/langs/{lang}/principles/THINKING_OS.md → .principles/THINKING_OS.md
686
+ */
687
+ function syncWorkspaceTemplates(lang) {
688
+ const workspacesRoot = OPENCLAW_DIR;
689
+ if (!existsSync(workspacesRoot)) return;
690
+
691
+ const entries = readdirSync(workspacesRoot);
692
+ const workspaceDirs = entries.filter(e =>
693
+ e.startsWith('workspace-') || e === 'workspace'
694
+ );
695
+
696
+ if (workspaceDirs.length === 0) return;
697
+
698
+ // Core files that should NEVER be overwritten after creation
699
+ const CORE_FILES = new Set([
700
+ 'AGENTS.md', 'SOUL.md', 'BOOT.md', 'BOOTSTRAP.md',
701
+ 'IDENTITY.md', 'USER.md', 'TOOLS.md', 'HEARTBEAT.md',
702
+ 'PRINCIPLES.md', 'PROFILE.json',
703
+ ]);
704
+
705
+ let updated = 0;
706
+
707
+ // Helper: compute MD5 of a file
708
+ function md5(filePath) {
709
+ try {
710
+ const content = readFileSyncRaw(filePath);
711
+ return createHash('md5').update(content).digest('hex');
712
+ } catch {
713
+ return null;
714
+ }
715
+ }
716
+
717
+ for (const ws of workspaceDirs) {
718
+ const wsDir = join(workspacesRoot, ws);
719
+
720
+ // 1. templates/workspace/** → workspace root (recursive)
721
+ const workspaceTemplateDir = join(SOURCE_DIR, 'templates', 'workspace');
722
+ if (existsSync(workspaceTemplateDir)) {
723
+ updated += syncDirRecursive(workspaceTemplateDir, wsDir, md5, CORE_FILES);
724
+ }
725
+
726
+ // 2. templates/langs/{lang}/core/** → workspace root (ONLY if file missing)
727
+ const coreDir = join(SOURCE_DIR, 'templates', 'langs', lang, 'core');
728
+ if (existsSync(coreDir)) {
729
+ updated += syncCoreFiles(coreDir, wsDir);
730
+ } else {
731
+ const zhCoreDir = join(SOURCE_DIR, 'templates', 'langs', 'zh', 'core');
732
+ if (existsSync(zhCoreDir)) {
733
+ updated += syncCoreFiles(zhCoreDir, wsDir);
734
+ }
735
+ }
736
+
737
+ // 3. templates/langs/{lang}/pain/** → .state/pain_samples/
738
+ const painSrc = join(SOURCE_DIR, 'templates', 'langs', lang, 'pain');
739
+ const painDest = join(wsDir, '.state', 'pain_samples');
740
+ if (existsSync(painSrc)) {
741
+ updated += syncDirRecursive(painSrc, painDest, md5, CORE_FILES);
742
+ }
743
+
744
+ // 4. templates/langs/{lang}/principles/THINKING_OS.md → .principles/THINKING_OS.md
745
+ const thinkingOsSrc = join(SOURCE_DIR, 'templates', 'langs', lang, 'principles', 'THINKING_OS.md');
746
+ const thinkingOsDest = join(wsDir, '.principles', 'THINKING_OS.md');
747
+ if (existsSync(thinkingOsSrc)) {
748
+ const srcMd5 = md5(thinkingOsSrc);
749
+ const destMd5 = existsSync(thinkingOsDest) ? md5(thinkingOsDest) : null;
750
+ if (srcMd5 !== destMd5) {
751
+ if (!existsSync(join(wsDir, '.principles'))) {
752
+ mkdirSync(join(wsDir, '.principles'), { recursive: true });
753
+ }
754
+ cpSync(thinkingOsSrc, thinkingOsDest, { force: true });
755
+ updated++;
756
+ }
757
+ }
758
+ }
759
+
760
+ if (updated > 0) {
761
+ console.log(` 📄 Workspace templates → ${updated} file(s) synced across ${workspaceDirs.length} workspace(s)`);
762
+ }
763
+ }
764
+
765
+ /**
766
+ * Sync core files ONLY if they don't exist yet.
767
+ * NEVER overwrites existing core files (user customizations).
768
+ */
769
+ function syncCoreFiles(srcDir, destDir) {
770
+ let count = 0;
771
+ if (!existsSync(srcDir)) return count;
772
+
773
+ const items = readdirSync(srcDir);
774
+ for (const item of items) {
775
+ const srcPath = join(srcDir, item);
776
+ const destPath = join(destDir, item);
777
+ const stat = statSync(srcPath);
778
+
779
+ if (stat.isDirectory()) continue;
780
+ // Core files: only copy if missing
781
+ if (!existsSync(destPath)) {
782
+ cpSync(srcPath, destPath, { force: false });
783
+ count++;
784
+ }
785
+ }
786
+ return count;
787
+ }
788
+
789
+ /**
790
+ * Recursively sync source dir to dest dir, skipping core files that already exist.
791
+ * Non-core files: only copy if missing or different (MD5).
792
+ */
793
+ function syncDirRecursive(srcDir, destDir, md5Fn, coreFiles) {
794
+ let count = 0;
795
+ if (!existsSync(destDir)) {
796
+ mkdirSync(destDir, { recursive: true });
797
+ }
798
+
799
+ const items = readdirSync(srcDir);
800
+ for (const item of items) {
801
+ const srcPath = join(srcDir, item);
802
+ const destPath = join(destDir, item);
803
+ const stat = statSync(srcPath);
804
+
805
+ if (stat.isDirectory()) {
806
+ count += syncDirRecursive(srcPath, destPath, md5Fn, coreFiles);
807
+ } else {
808
+ // Skip core files that already exist
809
+ if (coreFiles.has(item) && existsSync(destPath)) continue;
810
+
811
+ const srcMd5 = md5Fn(srcPath);
812
+ const destMd5 = existsSync(destPath) ? md5Fn(destPath) : null;
813
+ if (srcMd5 !== destMd5) {
814
+ cpSync(srcPath, destPath, { force: true });
815
+ count++;
816
+ }
817
+ }
818
+ }
819
+ return count;
820
+ }
821
+
586
822
  /**
587
823
  * Install production dependencies in target directory
588
824
  */
@@ -693,12 +929,17 @@ function main() {
693
929
  console.log('║ Principles Disciple Plugin Installer ║');
694
930
  console.log('╚════════════════════════════════════════════════════════════╝\n');
695
931
 
696
- // Dev mode: auto-force, auto-restart, clean stale backups
932
+ // Dev mode: auto-force, auto-restart, auto-bump, clean stale backups
697
933
  if (args.dev) {
698
- console.log('🛠️ DEV MODE: force + restart + stale backup cleanup\n');
934
+ console.log('🛠️ DEV MODE: force + restart + bump + stale backup cleanup\n');
935
+ }
936
+
937
+ // Auto-bump version if requested
938
+ if (args.bump) {
939
+ autoBumpVersion(SOURCE_DIR);
699
940
  }
700
941
 
701
- // Get source version
942
+ // Get source version (after potential bump)
702
943
  const sourceVersion = getVersion(SOURCE_DIR);
703
944
  if (!sourceVersion) {
704
945
  console.error('❌ Cannot determine source version. Check package.json.');
@@ -736,6 +977,9 @@ function main() {
736
977
  // Step 7: Sync skills
737
978
  syncSkills(args.lang);
738
979
 
980
+ // Step 7.5: Sync THINKING_OS.md to all workspace .principles/ directories
981
+ syncWorkspaceTemplates(args.lang);
982
+
739
983
  // Step 8: Install production dependencies in target (ALWAYS — cleanTargetDir wiped node_modules)
740
984
  // --skip-deps only applies to SOURCE directory deps, not the installed plugin.
741
985
  installTargetDependencies();