stella-timeline-plugin 2.0.2 → 2.0.3

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/dist/index.js CHANGED
@@ -9,7 +9,7 @@ exports.timelinePluginEntry = (0, openclaw_sdk_compat_1.definePluginEntry)({
9
9
  name: plugin_metadata_1.TIMELINE_PLUGIN_NAME,
10
10
  description: plugin_metadata_1.TIMELINE_PLUGIN_DESCRIPTION,
11
11
  register(api) {
12
- api.registerTool((0, openclaw_sdk_compat_1.makeTimelineToolRegistration)());
12
+ api.registerTool((0, openclaw_sdk_compat_1.makeTimelineToolRegistration)(), { optional: true });
13
13
  },
14
14
  });
15
15
  exports.timelinePlugin = (0, openclaw_sdk_compat_1.materializePlugin)(exports.timelinePluginEntry);
@@ -20,7 +20,7 @@ const openClawTimelinePlugin = {
20
20
  description: plugin_metadata_1.TIMELINE_PLUGIN_DESCRIPTION,
21
21
  register(api) {
22
22
  const runtimeApi = api;
23
- api.registerTool((0, openclaw_timeline_runtime_1.makeOpenClawTimelineResolveToolFactory)(runtimeApi), { names: [...plugin_metadata_1.TIMELINE_TOOL_NAMES] });
23
+ api.registerTool((0, openclaw_timeline_runtime_1.makeOpenClawTimelineResolveToolFactory)(runtimeApi), { optional: true });
24
24
  },
25
25
  };
26
26
  exports.default = openClawTimelinePlugin;
@@ -1,54 +1,54 @@
1
- {
2
- "id": "stella-timeline-plugin",
3
- "name": "Stella Timeline Plugin",
4
- "version": "2.0.0",
5
- "description": "OpenClaw timeline runtime with canonical timeline_resolve, LLM-based temporal reasoning, and guarded append-only writes.",
6
- "entry": "dist/index.js",
7
- "skills": [
8
- "skills/timeline"
9
- ],
10
- "configSchema": {
11
- "type": "object",
12
- "properties": {
13
- "enableTrace": {
14
- "type": "boolean",
15
- "default": true,
16
- "description": "Whether Timeline writes trace records for each runtime execution."
17
- },
18
- "traceLogPath": {
19
- "type": "string",
20
- "description": "Optional trace log path. Relative paths are resolved from the workspace."
21
- },
22
- "canonicalMemoryRoot": {
23
- "type": "string",
24
- "description": "Root directory for canonical timeline daily logs. Relative paths are resolved from the workspace."
25
- },
26
- "reasonerTimeoutMs": {
27
- "type": "integer",
28
- "default": 90000,
29
- "description": "Timeout for the internal timeline reasoner subagent, in milliseconds."
30
- },
31
- "reasonerSessionPrefix": {
32
- "type": "string",
33
- "default": "timeline-reasoner",
34
- "description": "Session key prefix used for the internal timeline reasoner subagent."
35
- },
36
- "reasonerMessageLimit": {
37
- "type": "integer",
38
- "default": 24,
39
- "description": "Maximum number of messages retained when reading the internal reasoner transcript."
40
- },
41
- "sessionHistoryLimit": {
42
- "type": "integer",
43
- "default": 12,
44
- "description": "Maximum number of current-session messages retained by the collector."
45
- },
46
- "memorySearchMaxResults": {
47
- "type": "integer",
48
- "default": 6,
49
- "description": "Maximum number of results requested when the collector calls OpenClaw memory_search."
50
- }
51
- },
52
- "additionalProperties": false
53
- }
54
- }
1
+ {
2
+ "id": "stella-timeline-plugin",
3
+ "name": "Stella Timeline Plugin",
4
+ "version": "2.0.0",
5
+ "description": "OpenClaw timeline runtime with canonical timeline_resolve, LLM-based temporal reasoning, and guarded append-only writes.",
6
+ "entry": "dist/index.js",
7
+ "skills": [
8
+ "skills/timeline"
9
+ ],
10
+ "configSchema": {
11
+ "type": "object",
12
+ "properties": {
13
+ "enableTrace": {
14
+ "type": "boolean",
15
+ "default": true,
16
+ "description": "Whether Timeline writes trace records for each runtime execution."
17
+ },
18
+ "traceLogPath": {
19
+ "type": "string",
20
+ "description": "Optional trace log path. Relative paths are resolved from the workspace."
21
+ },
22
+ "canonicalMemoryRoot": {
23
+ "type": "string",
24
+ "description": "Root directory for canonical timeline daily logs. Relative paths are resolved from the workspace."
25
+ },
26
+ "reasonerTimeoutMs": {
27
+ "type": "integer",
28
+ "default": 90000,
29
+ "description": "Timeout for the internal timeline reasoner subagent, in milliseconds."
30
+ },
31
+ "reasonerSessionPrefix": {
32
+ "type": "string",
33
+ "default": "timeline-reasoner",
34
+ "description": "Session key prefix used for the internal timeline reasoner subagent."
35
+ },
36
+ "reasonerMessageLimit": {
37
+ "type": "integer",
38
+ "default": 24,
39
+ "description": "Maximum number of messages retained when reading the internal reasoner transcript."
40
+ },
41
+ "sessionHistoryLimit": {
42
+ "type": "integer",
43
+ "default": 12,
44
+ "description": "Maximum number of current-session messages retained by the collector."
45
+ },
46
+ "memorySearchMaxResults": {
47
+ "type": "integer",
48
+ "default": 6,
49
+ "description": "Maximum number of results requested when the collector calls OpenClaw memory_search."
50
+ }
51
+ },
52
+ "additionalProperties": false
53
+ }
54
+ }
package/package.json CHANGED
@@ -1,73 +1,73 @@
1
- {
2
- "name": "stella-timeline-plugin",
3
- "version": "2.0.2",
4
- "description": "Native OpenClaw timeline plugin with a canonical timeline_resolve tool, bundled skill routing, and guarded append-only writes.",
5
- "keywords": [
6
- "openclaw",
7
- "skill",
8
- "timeline",
9
- "memory",
10
- "ai-agent",
11
- "episode",
12
- "persona"
13
- ],
14
- "author": "tao.zang",
15
- "license": "MIT-0",
16
- "repository": {
17
- "type": "git",
18
- "url": "https://github.com/tower1229/Her"
19
- },
20
- "homepage": "https://github.com/tower1229/Her#readme",
21
- "bugs": {
22
- "url": "https://github.com/tower1229/Her/issues"
23
- },
24
- "engines": {
25
- "node": ">=22.0.0"
26
- },
27
- "scripts": {
28
- "prebuild": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
29
- "build": "tsc -p tsconfig.build.json",
30
- "typecheck": "tsc --noEmit",
31
- "test": "node node_modules/jest/bin/jest.js --runInBand",
32
- "test:unit": "node node_modules/jest/bin/jest.js --runInBand",
33
- "test:smoke": "node ./scripts/run-openclaw-smoke.mjs",
34
- "test:live-experience": "node ./scripts/run-openclaw-live-e2e.mjs",
35
- "migrate:memory": "node ./scripts/migrate-existing-memory.mjs --apply",
36
- "setup:workspace": "node ./scripts/setup-openclaw-workspace.mjs",
37
- "doctor:workspace": "node ./scripts/doctor-openclaw-workspace.mjs",
38
- "verify": "npm run typecheck && npm run build && npm run test:unit",
39
- "pack:plugin": "npm pack",
40
- "release": "node ./scripts/release.mjs"
41
- },
42
- "bin": {
43
- "openclaw-timeline-setup": "./bin/openclaw-timeline-setup.mjs",
44
- "openclaw-timeline-doctor": "./bin/openclaw-timeline-doctor.mjs"
45
- },
46
- "publishConfig": {
47
- "access": "public"
48
- },
49
- "devDependencies": {
50
- "@types/jest": "^30.0.0",
51
- "@types/node": "^20.x",
52
- "jest": "^29.x",
53
- "ts-jest": "^29.x",
54
- "typescript": "^5.x"
55
- },
56
- "main": "dist/index.js",
57
- "files": [
58
- "dist",
59
- "bin",
60
- "scripts",
61
- "templates",
62
- "skills",
63
- "openclaw.plugin.json",
64
- "LICENSE",
65
- "README.md",
66
- "README_ZH.md"
67
- ],
68
- "openclaw": {
69
- "extensions": [
70
- "./dist/index.js"
71
- ]
72
- }
1
+ {
2
+ "name": "stella-timeline-plugin",
3
+ "version": "2.0.3",
4
+ "description": "Native OpenClaw timeline plugin with a canonical timeline_resolve tool, bundled skill routing, and guarded append-only writes.",
5
+ "keywords": [
6
+ "openclaw",
7
+ "skill",
8
+ "timeline",
9
+ "memory",
10
+ "ai-agent",
11
+ "episode",
12
+ "persona"
13
+ ],
14
+ "author": "tao.zang",
15
+ "license": "MIT-0",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/tower1229/Her"
19
+ },
20
+ "homepage": "https://github.com/tower1229/Her#readme",
21
+ "bugs": {
22
+ "url": "https://github.com/tower1229/Her/issues"
23
+ },
24
+ "engines": {
25
+ "node": ">=22.0.0"
26
+ },
27
+ "scripts": {
28
+ "prebuild": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
29
+ "build": "tsc -p tsconfig.build.json",
30
+ "typecheck": "tsc --noEmit",
31
+ "test": "node node_modules/jest/bin/jest.js --runInBand",
32
+ "test:unit": "node node_modules/jest/bin/jest.js --runInBand",
33
+ "test:smoke": "node ./scripts/run-openclaw-smoke.mjs",
34
+ "test:live-experience": "node ./scripts/run-openclaw-live-e2e.mjs",
35
+ "migrate:memory": "node ./scripts/migrate-existing-memory.mjs --apply",
36
+ "setup:workspace": "node ./scripts/setup-openclaw-workspace.mjs",
37
+ "doctor:workspace": "node ./scripts/doctor-openclaw-workspace.mjs",
38
+ "verify": "npm run typecheck && npm run build && npm run test:unit",
39
+ "pack:plugin": "npm pack",
40
+ "release": "node ./scripts/release.mjs"
41
+ },
42
+ "bin": {
43
+ "openclaw-timeline-setup": "./bin/openclaw-timeline-setup.mjs",
44
+ "openclaw-timeline-doctor": "./bin/openclaw-timeline-doctor.mjs"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "devDependencies": {
50
+ "@types/jest": "^30.0.0",
51
+ "@types/node": "^20.x",
52
+ "jest": "^29.x",
53
+ "ts-jest": "^29.x",
54
+ "typescript": "^5.x"
55
+ },
56
+ "main": "dist/index.js",
57
+ "files": [
58
+ "dist",
59
+ "bin",
60
+ "scripts",
61
+ "templates",
62
+ "skills",
63
+ "openclaw.plugin.json",
64
+ "LICENSE",
65
+ "README.md",
66
+ "README_ZH.md"
67
+ ],
68
+ "openclaw": {
69
+ "extensions": [
70
+ "./dist/index.js"
71
+ ]
72
+ }
73
73
  }
@@ -1,153 +1,94 @@
1
- #!/usr/bin/env node
2
- import fs from 'node:fs';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import {
6
- detectAgentsContract,
7
- detectSoulContract,
8
- normalizeRootName,
9
- resolveCanonicalRootPath,
10
- } from './workspace-contract.mjs';
11
-
12
- const PLUGIN_ID = 'stella-timeline-plugin';
13
- const DEFAULT_OPENCLAW_CONFIG = path.join(os.homedir(), '.openclaw', 'openclaw.json');
14
-
15
- function parseArgs(argv) {
16
- const options = {
17
- workspace: path.resolve(process.cwd()),
18
- canonicalRootName: 'memory',
19
- openclawConfig: DEFAULT_OPENCLAW_CONFIG,
20
- skipOpenclawConfig: false,
21
- };
22
-
23
- for (let i = 0; i < argv.length; i += 1) {
24
- const arg = argv[i];
25
- if (arg === '--workspace') {
26
- options.workspace = path.resolve(argv[++i] || '');
27
- continue;
28
- }
29
- if (arg === '--canonical-root-name') {
30
- options.canonicalRootName = normalizeRootName(argv[++i] || '');
31
- continue;
32
- }
33
- if (arg === '--openclaw-config') {
34
- options.openclawConfig = path.resolve(argv[++i] || '');
35
- continue;
36
- }
37
- if (arg === '--skip-openclaw-config') {
38
- options.skipOpenclawConfig = true;
39
- continue;
40
- }
41
- if (arg === '--help' || arg === '-h') {
42
- printHelp();
43
- process.exit(0);
44
- }
45
- throw new Error(`Unknown argument: ${arg}`);
46
- }
47
-
48
- return options;
49
- }
50
-
51
- function printHelp() {
52
- console.log([
53
- 'Usage: openclaw-timeline-doctor [options]',
54
- '',
55
- 'Checks whether the required Timeline workspace contracts and openclaw.json config are present.',
56
- '',
57
- 'Options:',
58
- ' --workspace <dir> Workspace to check AGENTS.md / SOUL.md (default: cwd)',
59
- ' --canonical-root-name <n> Memory root folder name (default: memory)',
60
- ' --openclaw-config <path> Path to openclaw.json (default: ~/.openclaw/openclaw.json)',
61
- ' --skip-openclaw-config Skip checking openclaw.json',
62
- ].join('\n'));
63
- }
64
-
65
- function readText(filePath) {
66
- return fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';
67
- }
68
-
69
- function check(label, passed, successDetail, failureDetail) {
70
- const prefix = passed ? '[ok]' : '[missing]';
71
- console.log(`${prefix} ${label}: ${passed ? successDetail : failureDetail}`);
72
- return passed;
73
- }
74
-
75
- function readOpenclawConfig(configPath) {
76
- if (!fs.existsSync(configPath)) return null;
77
- try {
78
- return JSON.parse(fs.readFileSync(configPath, 'utf8'));
79
- } catch {
80
- return null;
81
- }
82
- }
83
-
84
- function main() {
85
- const options = parseArgs(process.argv.slice(2));
86
- const agentsPath = path.join(options.workspace, 'AGENTS.md');
87
- const soulPath = path.join(options.workspace, 'SOUL.md');
88
- const canonicalRootPath = resolveCanonicalRootPath(options.workspace, options.canonicalRootName);
89
-
90
- const agentsContent = readText(agentsPath);
91
- const soulContent = readText(soulPath);
92
-
93
- let ok = true;
94
- ok = check(
95
- 'AGENTS contract',
96
- fs.existsSync(agentsPath) && detectAgentsContract(agentsContent),
97
- agentsPath,
98
- `${agentsPath} is missing the Timeline daily-log contract`,
99
- ) && ok;
100
- ok = check(
101
- 'SOUL contract',
102
- fs.existsSync(soulPath) && detectSoulContract(soulContent),
103
- soulPath,
104
- `${soulPath} is missing the Timeline recall contract`,
105
- ) && ok;
106
- ok = check(
107
- 'Canonical memory root',
108
- fs.existsSync(canonicalRootPath),
109
- canonicalRootPath,
110
- `${canonicalRootPath} does not exist`,
111
- ) && ok;
112
-
113
- if (!options.skipOpenclawConfig) {
114
- const config = readOpenclawConfig(options.openclawConfig);
115
- if (!config) {
116
- ok = check('openclaw.json', false, '', `${options.openclawConfig} not found or not valid JSON`) && ok;
117
- } else {
118
- const pluginAllowed = Array.isArray(config.plugins?.allow) && config.plugins.allow.includes(PLUGIN_ID);
119
- const pluginEnabled = config.plugins?.entries?.[PLUGIN_ID]?.enabled === true;
120
- const pluginPathSet = Array.isArray(config.plugins?.load?.paths) && config.plugins.load.paths.length > 0;
121
-
122
- ok = check(
123
- `plugins.allow contains "${PLUGIN_ID}"`,
124
- pluginAllowed,
125
- options.openclawConfig,
126
- `add "${PLUGIN_ID}" to plugins.allow in ${options.openclawConfig}`,
127
- ) && ok;
128
- ok = check(
129
- `plugins.entries.${PLUGIN_ID}.enabled`,
130
- pluginEnabled,
131
- options.openclawConfig,
132
- `set plugins.entries.${PLUGIN_ID}.enabled=true in ${options.openclawConfig}`,
133
- ) && ok;
134
- ok = check(
135
- 'plugins.load.paths is set',
136
- pluginPathSet,
137
- options.openclawConfig,
138
- `add plugin directory to plugins.load.paths in ${options.openclawConfig}`,
139
- ) && ok;
140
- }
141
- }
142
-
143
- if (!ok) {
144
- process.exitCode = 1;
145
- }
146
- }
147
-
148
- try {
149
- main();
150
- } catch (error) {
151
- console.error(error instanceof Error ? error.message : String(error));
152
- process.exit(1);
153
- }
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import {
5
+ detectAgentsContract,
6
+ detectSoulContract,
7
+ normalizeRootName,
8
+ resolveCanonicalRootPath,
9
+ } from './workspace-contract.mjs';
10
+
11
+ function parseArgs(argv) {
12
+ const options = {
13
+ workspace: path.resolve(process.cwd()),
14
+ canonicalRootName: 'memory',
15
+ };
16
+
17
+ for (let i = 0; i < argv.length; i += 1) {
18
+ const arg = argv[i];
19
+ if (arg === '--workspace') {
20
+ options.workspace = path.resolve(argv[++i] || '');
21
+ continue;
22
+ }
23
+ if (arg === '--canonical-root-name') {
24
+ options.canonicalRootName = normalizeRootName(argv[++i] || '');
25
+ continue;
26
+ }
27
+ if (arg === '--help' || arg === '-h') {
28
+ printHelp();
29
+ process.exit(0);
30
+ }
31
+ throw new Error(`Unknown argument: ${arg}`);
32
+ }
33
+
34
+ return options;
35
+ }
36
+
37
+ function printHelp() {
38
+ console.log([
39
+ 'Usage: openclaw-timeline-doctor [--workspace <dir>] [--canonical-root-name <name>]',
40
+ '',
41
+ 'Checks whether the required Timeline workspace contracts are present.',
42
+ ].join('\n'));
43
+ }
44
+
45
+ function readText(filePath) {
46
+ return fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';
47
+ }
48
+
49
+ function check(label, passed, successDetail, failureDetail) {
50
+ const prefix = passed ? '[ok]' : '[missing]';
51
+ console.log(`${prefix} ${label}: ${passed ? successDetail : failureDetail}`);
52
+ return passed;
53
+ }
54
+
55
+ function main() {
56
+ const options = parseArgs(process.argv.slice(2));
57
+ const agentsPath = path.join(options.workspace, 'AGENTS.md');
58
+ const soulPath = path.join(options.workspace, 'SOUL.md');
59
+ const canonicalRootPath = resolveCanonicalRootPath(options.workspace, options.canonicalRootName);
60
+
61
+ const agentsContent = readText(agentsPath);
62
+ const soulContent = readText(soulPath);
63
+
64
+ let ok = true;
65
+ ok = check(
66
+ 'AGENTS contract',
67
+ fs.existsSync(agentsPath) && detectAgentsContract(agentsContent),
68
+ agentsPath,
69
+ `${agentsPath} is missing the Timeline daily-log contract`,
70
+ ) && ok;
71
+ ok = check(
72
+ 'SOUL contract',
73
+ fs.existsSync(soulPath) && detectSoulContract(soulContent),
74
+ soulPath,
75
+ `${soulPath} is missing the Timeline recall contract`,
76
+ ) && ok;
77
+ ok = check(
78
+ 'Canonical memory root',
79
+ fs.existsSync(canonicalRootPath),
80
+ canonicalRootPath,
81
+ `${canonicalRootPath} does not exist`,
82
+ ) && ok;
83
+
84
+ if (!ok) {
85
+ process.exitCode = 1;
86
+ }
87
+ }
88
+
89
+ try {
90
+ main();
91
+ } catch (error) {
92
+ console.error(error instanceof Error ? error.message : String(error));
93
+ process.exit(1);
94
+ }