psyche-ai 9.2.3 → 9.2.5
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/README.en.md +8 -175
- package/README.md +33 -16
- package/dist/adapters/http.js +1 -1
- package/dist/adapters/langchain.d.ts +14 -0
- package/dist/adapters/langchain.js +20 -0
- package/dist/adapters/mcp.js +5 -1
- package/dist/adapters/openclaw.d.ts +1 -0
- package/dist/adapters/openclaw.js +67 -15
- package/dist/adapters/vercel-ai.d.ts +2 -1
- package/dist/adapters/vercel-ai.js +8 -9
- package/dist/appraisal.d.ts +8 -0
- package/dist/appraisal.js +362 -0
- package/dist/autonomic.js +2 -2
- package/dist/classify.js +14 -3
- package/dist/cli.js +28 -3
- package/dist/core.d.ts +9 -3
- package/dist/core.js +194 -12
- package/dist/demo.js +1 -2
- package/dist/diagnostics.d.ts +8 -6
- package/dist/diagnostics.js +53 -17
- package/dist/ethics.js +1 -1
- package/dist/experiential-field.d.ts +2 -2
- package/dist/experiential-field.js +7 -16
- package/dist/generative-self.js +0 -2
- package/dist/host-controls.d.ts +5 -0
- package/dist/host-controls.js +48 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +7 -1
- package/dist/interaction.js +0 -2
- package/dist/metacognition.d.ts +13 -1
- package/dist/metacognition.js +164 -32
- package/dist/prompt.d.ts +4 -0
- package/dist/prompt.js +67 -31
- package/dist/psyche-file.d.ts +16 -1
- package/dist/psyche-file.js +103 -8
- package/dist/relation-dynamics.d.ts +21 -0
- package/dist/relation-dynamics.js +601 -0
- package/dist/response-contract.d.ts +8 -0
- package/dist/response-contract.js +374 -0
- package/dist/storage.d.ts +1 -0
- package/dist/storage.js +12 -5
- package/dist/subjectivity.d.ts +3 -0
- package/dist/subjectivity.js +477 -0
- package/dist/temporal.d.ts +2 -2
- package/dist/temporal.js +2 -2
- package/dist/types.d.ts +243 -0
- package/dist/types.js +43 -0
- package/dist/update.d.ts +37 -2
- package/dist/update.js +323 -44
- package/openclaw.plugin.json +20 -1
- package/package.json +1 -1
package/dist/update.js
CHANGED
|
@@ -1,43 +1,84 @@
|
|
|
1
1
|
// ============================================================
|
|
2
|
-
//
|
|
2
|
+
// Update manager — context-aware update checks and explicit upgrades
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
// Never
|
|
4
|
+
// Goals:
|
|
5
|
+
// - Never block agent startup
|
|
6
|
+
// - Never mutate a dirty local git worktree behind the user's back
|
|
7
|
+
// - Give the right update instruction for the current install shape
|
|
8
|
+
// - Allow explicit self-update via CLI when safe
|
|
6
9
|
// ============================================================
|
|
7
|
-
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
8
|
-
import {
|
|
10
|
+
import { readFile, writeFile, mkdir, access } from "node:fs/promises";
|
|
11
|
+
import { constants as fsConstants } from "node:fs";
|
|
12
|
+
import { join, dirname, resolve, sep } from "node:path";
|
|
9
13
|
import { homedir } from "node:os";
|
|
10
14
|
import { fileURLToPath } from "node:url";
|
|
11
15
|
import { execFile } from "node:child_process";
|
|
12
16
|
import { promisify } from "node:util";
|
|
13
17
|
const execFileAsync = promisify(execFile);
|
|
14
18
|
const PACKAGE_NAME = "psyche-ai";
|
|
15
|
-
|
|
16
|
-
let CURRENT_VERSION = "9.0.0"; // fallback
|
|
17
|
-
try {
|
|
18
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
|
-
const pkg = JSON.parse(await readFile(join(__dirname, "..", "package.json"), "utf-8"));
|
|
20
|
-
CURRENT_VERSION = pkg.version ?? CURRENT_VERSION;
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
// Silent — use fallback
|
|
24
|
-
}
|
|
19
|
+
const FALLBACK_VERSION = "0.0.0";
|
|
25
20
|
const CHECK_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
|
|
26
21
|
const CACHE_DIR = join(homedir(), ".psyche-ai");
|
|
27
22
|
const CACHE_FILE = join(CACHE_DIR, "update-check.json");
|
|
28
23
|
const FETCH_TIMEOUT_MS = 5000;
|
|
24
|
+
const APPLY_TIMEOUT_MS = 30_000;
|
|
25
|
+
const BUILD_TIMEOUT_MS = 60_000;
|
|
26
|
+
function shellQuote(value) {
|
|
27
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
28
|
+
}
|
|
29
|
+
async function readPackageMetadata(root) {
|
|
30
|
+
const raw = await readFile(join(root, "package.json"), "utf-8");
|
|
31
|
+
const pkg = JSON.parse(raw);
|
|
32
|
+
return {
|
|
33
|
+
version: pkg.version ?? FALLBACK_VERSION,
|
|
34
|
+
hasBuildScript: typeof pkg.scripts?.build === "string" && pkg.scripts.build.length > 0,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async function resolvePackageMetadata() {
|
|
38
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
39
|
+
const candidates = [
|
|
40
|
+
join(__dirname, ".."),
|
|
41
|
+
join(__dirname, "..", ".."),
|
|
42
|
+
];
|
|
43
|
+
for (const root of candidates) {
|
|
44
|
+
try {
|
|
45
|
+
const meta = await readPackageMetadata(root);
|
|
46
|
+
return { root, version: meta.version };
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Try next candidate.
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { root: process.cwd(), version: process.env.npm_package_version ?? FALLBACK_VERSION };
|
|
53
|
+
}
|
|
54
|
+
let packageMetadataPromise = null;
|
|
55
|
+
async function getPackageMetadata() {
|
|
56
|
+
packageMetadataPromise ??= resolvePackageMetadata();
|
|
57
|
+
return packageMetadataPromise;
|
|
58
|
+
}
|
|
59
|
+
export function getPackageVersion() {
|
|
60
|
+
return getPackageMetadata().then((meta) => meta.version);
|
|
61
|
+
}
|
|
62
|
+
function compareSemverPart(a, b) {
|
|
63
|
+
const na = Number(a ?? 0);
|
|
64
|
+
const nb = Number(b ?? 0);
|
|
65
|
+
if (na < nb)
|
|
66
|
+
return -1;
|
|
67
|
+
if (na > nb)
|
|
68
|
+
return 1;
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
29
71
|
/**
|
|
30
72
|
* Compare two semver strings. Returns:
|
|
31
73
|
* -1 if a < b, 0 if a == b, 1 if a > b
|
|
32
74
|
*/
|
|
33
|
-
function compareSemver(a, b) {
|
|
34
|
-
const pa = a.split(".")
|
|
35
|
-
const pb = b.split(".")
|
|
75
|
+
export function compareSemver(a, b) {
|
|
76
|
+
const pa = a.split(".");
|
|
77
|
+
const pb = b.split(".");
|
|
36
78
|
for (let i = 0; i < 3; i++) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return 1;
|
|
79
|
+
const cmp = compareSemverPart(pa[i], pb[i]);
|
|
80
|
+
if (cmp !== 0)
|
|
81
|
+
return cmp;
|
|
41
82
|
}
|
|
42
83
|
return 0;
|
|
43
84
|
}
|
|
@@ -56,7 +97,7 @@ async function writeCache(cache) {
|
|
|
56
97
|
await writeFile(CACHE_FILE, JSON.stringify(cache), "utf-8");
|
|
57
98
|
}
|
|
58
99
|
catch {
|
|
59
|
-
// Silent — cache is optional
|
|
100
|
+
// Silent — cache is optional.
|
|
60
101
|
}
|
|
61
102
|
}
|
|
62
103
|
async function fetchLatestVersion() {
|
|
@@ -74,45 +115,283 @@ async function fetchLatestVersion() {
|
|
|
74
115
|
return null;
|
|
75
116
|
}
|
|
76
117
|
}
|
|
77
|
-
async function
|
|
118
|
+
async function pathExists(path) {
|
|
78
119
|
try {
|
|
79
|
-
|
|
80
|
-
await execFileAsync("npm", ["update", PACKAGE_NAME, "--registry", "https://registry.npmjs.org"], {
|
|
81
|
-
timeout: 30000,
|
|
82
|
-
});
|
|
83
|
-
console.log(`[psyche-ai] ✓ Auto-updated to v${latestVersion}`);
|
|
120
|
+
await access(path, fsConstants.F_OK);
|
|
84
121
|
return true;
|
|
85
122
|
}
|
|
86
123
|
catch {
|
|
87
124
|
return false;
|
|
88
125
|
}
|
|
89
126
|
}
|
|
127
|
+
async function runCommand(file, args, cwd, timeout) {
|
|
128
|
+
try {
|
|
129
|
+
const { stdout, stderr } = await execFileAsync(file, args, {
|
|
130
|
+
cwd,
|
|
131
|
+
timeout,
|
|
132
|
+
});
|
|
133
|
+
return { ok: true, stdout, stderr };
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
const err = error;
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
stdout: err.stdout ?? "",
|
|
140
|
+
stderr: err.stderr ?? "",
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function detectGitContext(packageRoot, hasBuildScript) {
|
|
145
|
+
const topLevel = await runCommand("git", ["rev-parse", "--show-toplevel"], packageRoot, 5000);
|
|
146
|
+
if (!topLevel.ok)
|
|
147
|
+
return null;
|
|
148
|
+
const repoRoot = topLevel.stdout.trim();
|
|
149
|
+
if (!repoRoot)
|
|
150
|
+
return null;
|
|
151
|
+
const branchResult = await runCommand("git", ["rev-parse", "--abbrev-ref", "HEAD"], repoRoot, 5000);
|
|
152
|
+
const branch = branchResult.ok ? branchResult.stdout.trim() : null;
|
|
153
|
+
const upstreamResult = await runCommand("git", ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"], repoRoot, 5000);
|
|
154
|
+
const upstream = upstreamResult.ok ? upstreamResult.stdout.trim() : null;
|
|
155
|
+
const dirtyResult = await runCommand("git", ["status", "--porcelain"], repoRoot, 5000);
|
|
156
|
+
const dirty = dirtyResult.ok ? dirtyResult.stdout.trim().length > 0 : true;
|
|
157
|
+
const buildStep = hasBuildScript ? " && npm run build" : "";
|
|
158
|
+
const manualCommand = `cd ${shellQuote(repoRoot)} && git pull --ff-only${buildStep}`;
|
|
159
|
+
return {
|
|
160
|
+
mode: "git-worktree",
|
|
161
|
+
packageRoot,
|
|
162
|
+
updateCwd: repoRoot,
|
|
163
|
+
manualCommand,
|
|
164
|
+
autoApplyOnInit: false,
|
|
165
|
+
requiresRestart: true,
|
|
166
|
+
hasBuildScript,
|
|
167
|
+
gitBranch: branch,
|
|
168
|
+
gitUpstream: upstream,
|
|
169
|
+
dirty,
|
|
170
|
+
reason: dirty
|
|
171
|
+
? "working tree has local changes"
|
|
172
|
+
: upstream
|
|
173
|
+
? undefined
|
|
174
|
+
: "git branch has no tracked upstream",
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
export async function detectInstallContext(packageRootArg) {
|
|
178
|
+
const packageRoot = resolve(packageRootArg ?? (await getPackageMetadata()).root);
|
|
179
|
+
const { hasBuildScript } = await readPackageMetadata(packageRoot).catch(() => ({
|
|
180
|
+
version: FALLBACK_VERSION,
|
|
181
|
+
hasBuildScript: false,
|
|
182
|
+
}));
|
|
183
|
+
const gitContext = await detectGitContext(packageRoot, hasBuildScript);
|
|
184
|
+
if (gitContext)
|
|
185
|
+
return gitContext;
|
|
186
|
+
const marker = `${sep}node_modules${sep}${PACKAGE_NAME}`;
|
|
187
|
+
const idx = packageRoot.lastIndexOf(marker);
|
|
188
|
+
if (idx >= 0) {
|
|
189
|
+
const projectRoot = packageRoot.slice(0, idx) || sep;
|
|
190
|
+
return {
|
|
191
|
+
mode: "npm-project",
|
|
192
|
+
packageRoot,
|
|
193
|
+
updateCwd: projectRoot,
|
|
194
|
+
manualCommand: `cd ${shellQuote(projectRoot)} && npm update ${PACKAGE_NAME}`,
|
|
195
|
+
autoApplyOnInit: true,
|
|
196
|
+
requiresRestart: true,
|
|
197
|
+
hasBuildScript,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const localBuildStep = hasBuildScript && await pathExists(join(packageRoot, "tsconfig.json"))
|
|
201
|
+
? " && npm run build"
|
|
202
|
+
: "";
|
|
203
|
+
return {
|
|
204
|
+
mode: "local-path",
|
|
205
|
+
packageRoot,
|
|
206
|
+
updateCwd: packageRoot,
|
|
207
|
+
manualCommand: `cd ${shellQuote(packageRoot)} && npm update ${PACKAGE_NAME}${localBuildStep}`,
|
|
208
|
+
autoApplyOnInit: false,
|
|
209
|
+
requiresRestart: true,
|
|
210
|
+
hasBuildScript,
|
|
211
|
+
reason: "local path install is not package-manager managed",
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function formatAvailableMessage(latestVersion, currentVersion, context) {
|
|
215
|
+
return `[psyche-ai] v${latestVersion} available (current: v${currentVersion}). Run: psyche upgrade` +
|
|
216
|
+
(context.mode === "git-worktree" || context.mode === "local-path"
|
|
217
|
+
? ` or ${context.manualCommand}`
|
|
218
|
+
: "");
|
|
219
|
+
}
|
|
220
|
+
async function applyNpmProjectUpdate(context, latestVersion) {
|
|
221
|
+
const result = await runCommand("npm", ["update", PACKAGE_NAME, "--registry", "https://registry.npmjs.org"], context.updateCwd, APPLY_TIMEOUT_MS);
|
|
222
|
+
if (!result.ok) {
|
|
223
|
+
return {
|
|
224
|
+
status: "failed",
|
|
225
|
+
currentVersion: await getPackageVersion(),
|
|
226
|
+
latestVersion,
|
|
227
|
+
context,
|
|
228
|
+
manualCommand: context.manualCommand,
|
|
229
|
+
message: `[psyche-ai] Auto-update failed. Run manually: ${context.manualCommand}`,
|
|
230
|
+
restartRequired: false,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
const nextVersion = await readPackageMetadata(context.packageRoot)
|
|
234
|
+
.then((meta) => meta.version)
|
|
235
|
+
.catch(() => latestVersion);
|
|
236
|
+
return {
|
|
237
|
+
status: "updated",
|
|
238
|
+
currentVersion: nextVersion,
|
|
239
|
+
latestVersion,
|
|
240
|
+
context,
|
|
241
|
+
manualCommand: context.manualCommand,
|
|
242
|
+
message: `[psyche-ai] Updated to v${nextVersion}. Restart hosts using it to load the new build.`,
|
|
243
|
+
restartRequired: true,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
async function applyGitWorktreeUpdate(context, latestVersion) {
|
|
247
|
+
const currentVersion = await getPackageVersion();
|
|
248
|
+
if (context.dirty) {
|
|
249
|
+
return {
|
|
250
|
+
status: "skipped",
|
|
251
|
+
currentVersion,
|
|
252
|
+
latestVersion,
|
|
253
|
+
context,
|
|
254
|
+
manualCommand: context.manualCommand,
|
|
255
|
+
message: `[psyche-ai] Skipped self-update: ${context.reason}. Run manually: ${context.manualCommand}`,
|
|
256
|
+
restartRequired: false,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
if (!context.gitUpstream) {
|
|
260
|
+
return {
|
|
261
|
+
status: "skipped",
|
|
262
|
+
currentVersion,
|
|
263
|
+
latestVersion,
|
|
264
|
+
context,
|
|
265
|
+
manualCommand: context.manualCommand,
|
|
266
|
+
message: `[psyche-ai] Skipped self-update: ${context.reason}. Run manually: ${context.manualCommand}`,
|
|
267
|
+
restartRequired: false,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
const pullResult = await runCommand("git", ["pull", "--ff-only"], context.updateCwd, APPLY_TIMEOUT_MS);
|
|
271
|
+
if (!pullResult.ok) {
|
|
272
|
+
return {
|
|
273
|
+
status: "failed",
|
|
274
|
+
currentVersion,
|
|
275
|
+
latestVersion,
|
|
276
|
+
context,
|
|
277
|
+
manualCommand: context.manualCommand,
|
|
278
|
+
message: `[psyche-ai] Git update failed. Run manually: ${context.manualCommand}`,
|
|
279
|
+
restartRequired: false,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
if (context.hasBuildScript) {
|
|
283
|
+
const buildResult = await runCommand("npm", ["run", "build"], context.packageRoot, BUILD_TIMEOUT_MS);
|
|
284
|
+
if (!buildResult.ok) {
|
|
285
|
+
return {
|
|
286
|
+
status: "failed",
|
|
287
|
+
currentVersion,
|
|
288
|
+
latestVersion,
|
|
289
|
+
context,
|
|
290
|
+
manualCommand: context.manualCommand,
|
|
291
|
+
message: `[psyche-ai] Pulled latest code but build failed. Run manually: ${context.manualCommand}`,
|
|
292
|
+
restartRequired: false,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const nextVersion = await readPackageMetadata(context.packageRoot)
|
|
297
|
+
.then((meta) => meta.version)
|
|
298
|
+
.catch(() => latestVersion);
|
|
299
|
+
return {
|
|
300
|
+
status: "updated",
|
|
301
|
+
currentVersion: nextVersion,
|
|
302
|
+
latestVersion,
|
|
303
|
+
context,
|
|
304
|
+
manualCommand: context.manualCommand,
|
|
305
|
+
message: `[psyche-ai] Updated worktree to v${nextVersion}. Restart hosts using it to load the new build.`,
|
|
306
|
+
restartRequired: true,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
async function applyExplicitUpdate(context, latestVersion) {
|
|
310
|
+
switch (context.mode) {
|
|
311
|
+
case "npm-project":
|
|
312
|
+
return applyNpmProjectUpdate(context, latestVersion);
|
|
313
|
+
case "git-worktree":
|
|
314
|
+
return applyGitWorktreeUpdate(context, latestVersion);
|
|
315
|
+
case "local-path":
|
|
316
|
+
return {
|
|
317
|
+
status: "skipped",
|
|
318
|
+
currentVersion: await getPackageVersion(),
|
|
319
|
+
latestVersion,
|
|
320
|
+
context,
|
|
321
|
+
manualCommand: context.manualCommand,
|
|
322
|
+
message: `[psyche-ai] This install shape needs a manual update. Run: ${context.manualCommand}`,
|
|
323
|
+
restartRequired: false,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
export async function selfUpdate(opts) {
|
|
328
|
+
const currentVersion = opts?.packageRoot
|
|
329
|
+
? await readPackageMetadata(resolve(opts.packageRoot)).then((meta) => meta.version)
|
|
330
|
+
: await getPackageVersion();
|
|
331
|
+
const context = await detectInstallContext(opts?.packageRoot);
|
|
332
|
+
const latestVersion = opts?.latestVersion ?? await fetchLatestVersion();
|
|
333
|
+
if (!latestVersion) {
|
|
334
|
+
return {
|
|
335
|
+
status: "failed",
|
|
336
|
+
currentVersion,
|
|
337
|
+
latestVersion: null,
|
|
338
|
+
context,
|
|
339
|
+
manualCommand: context.manualCommand,
|
|
340
|
+
message: "[psyche-ai] Could not reach the registry to check for updates.",
|
|
341
|
+
restartRequired: false,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
if (compareSemver(currentVersion, latestVersion) >= 0) {
|
|
345
|
+
return {
|
|
346
|
+
status: "up-to-date",
|
|
347
|
+
currentVersion,
|
|
348
|
+
latestVersion,
|
|
349
|
+
context,
|
|
350
|
+
manualCommand: context.manualCommand,
|
|
351
|
+
message: `[psyche-ai] v${currentVersion} is up to date.`,
|
|
352
|
+
restartRequired: false,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
if (opts?.checkOnly) {
|
|
356
|
+
return {
|
|
357
|
+
status: "available",
|
|
358
|
+
currentVersion,
|
|
359
|
+
latestVersion,
|
|
360
|
+
context,
|
|
361
|
+
manualCommand: context.manualCommand,
|
|
362
|
+
message: formatAvailableMessage(latestVersion, currentVersion, context),
|
|
363
|
+
restartRequired: false,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
return applyExplicitUpdate(context, latestVersion);
|
|
367
|
+
}
|
|
90
368
|
/**
|
|
91
369
|
* Check for updates. Non-blocking, safe to fire-and-forget.
|
|
92
370
|
* - Checks at most once per hour (cached)
|
|
93
|
-
* -
|
|
94
|
-
* -
|
|
371
|
+
* - Auto-applies only for npm-managed installs
|
|
372
|
+
* - For git/local-path installs, prints the correct explicit upgrade command
|
|
95
373
|
* - Never throws
|
|
96
374
|
*/
|
|
97
375
|
export async function checkForUpdate() {
|
|
98
|
-
|
|
376
|
+
const currentVersion = await getPackageVersion();
|
|
377
|
+
const context = await detectInstallContext();
|
|
99
378
|
const cache = await readCache();
|
|
100
379
|
if (cache && Date.now() - cache.lastCheck < CHECK_INTERVAL_MS) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
console.log(`[psyche-ai] v${cache.latestVersion} available (current: v${CURRENT_VERSION}). Run: npm update ${PACKAGE_NAME}`);
|
|
380
|
+
if (cache.latestVersion && compareSemver(currentVersion, cache.latestVersion) < 0) {
|
|
381
|
+
console.log(formatAvailableMessage(cache.latestVersion, currentVersion, context));
|
|
104
382
|
}
|
|
105
383
|
return;
|
|
106
384
|
}
|
|
107
|
-
const
|
|
108
|
-
await writeCache({ lastCheck: Date.now(), latestVersion
|
|
109
|
-
if (!
|
|
110
|
-
return;
|
|
385
|
+
const latestVersion = await fetchLatestVersion();
|
|
386
|
+
await writeCache({ lastCheck: Date.now(), latestVersion });
|
|
387
|
+
if (!latestVersion || compareSemver(currentVersion, latestVersion) >= 0) {
|
|
388
|
+
return;
|
|
111
389
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (!updated) {
|
|
116
|
-
console.log(`[psyche-ai] Auto-update failed. Run manually: npm update ${PACKAGE_NAME}`);
|
|
390
|
+
if (!context.autoApplyOnInit) {
|
|
391
|
+
console.log(formatAvailableMessage(latestVersion, currentVersion, context));
|
|
392
|
+
return;
|
|
117
393
|
}
|
|
394
|
+
console.log(`[psyche-ai] New version v${latestVersion} available (current: v${currentVersion}), updating...`);
|
|
395
|
+
const result = await applyExplicitUpdate(context, latestVersion);
|
|
396
|
+
console.log(result.message);
|
|
118
397
|
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "psyche-ai",
|
|
3
3
|
"name": "Artificial Psyche",
|
|
4
4
|
"description": "Virtual endocrine system, empathy engine, and agency for OpenClaw agents",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "9.2.3",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"additionalProperties": false,
|
|
@@ -49,6 +49,15 @@
|
|
|
49
49
|
"type": "boolean",
|
|
50
50
|
"default": true,
|
|
51
51
|
"description": "Persist emotional state to disk. Set false for privacy."
|
|
52
|
+
},
|
|
53
|
+
"diagnostics": {
|
|
54
|
+
"type": "boolean",
|
|
55
|
+
"default": true,
|
|
56
|
+
"description": "Collect diagnostic metrics and write diagnostics.jsonl at session end."
|
|
57
|
+
},
|
|
58
|
+
"feedbackUrl": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"description": "Optional endpoint for auto-submitting anonymized diagnostic reports."
|
|
52
61
|
}
|
|
53
62
|
}
|
|
54
63
|
},
|
|
@@ -89,6 +98,16 @@
|
|
|
89
98
|
"label": "Persist State",
|
|
90
99
|
"sensitive": false,
|
|
91
100
|
"advanced": true
|
|
101
|
+
},
|
|
102
|
+
"diagnostics": {
|
|
103
|
+
"label": "Diagnostics Logging",
|
|
104
|
+
"sensitive": false,
|
|
105
|
+
"advanced": true
|
|
106
|
+
},
|
|
107
|
+
"feedbackUrl": {
|
|
108
|
+
"label": "Feedback Endpoint",
|
|
109
|
+
"sensitive": true,
|
|
110
|
+
"advanced": true
|
|
92
111
|
}
|
|
93
112
|
}
|
|
94
113
|
}
|