@yottameta/yotta-memory 0.5.3 → 0.5.4

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.md CHANGED
@@ -40,7 +40,7 @@
40
40
  | **检索与生命周期** | 索引 + TF 打分(中文分词友好);质量分 / 盖棺分 / 自动归档,记忆库不会无限膨胀 |
41
41
  | **生态分发** | GitHub + npm 双源同步发布;npx skills / npm / install.sh 三种方式,覆盖 17+ 类智能体目录 |
42
42
  | **便携记忆盘(随盘走)** | 记忆库即引擎:装在硬盘 / 主机上,插上即恢复全部记忆;引擎主机只需装 CLI 当存放点,无需装任何 AI 智能体 |
43
- | **局域网共享与自启** | 每智能体独立 token(Bearer + X-Agent-Id)鉴权、可吊销;`lan enable` 注册开机自启(默认登录自启,可选开机即启);MCP 工具集与 CLI 一致(8 个工具),管理动作不远程暴露 |
43
+ | **局域网共享与自启** | 每智能体独立 token(Bearer + X-Agent-Id)鉴权、可吊销;`lan enable` 注册开机自启(Windows:优先计划任务;非管理员自动降级用户级 Startup 静默自启);MCP 工具集与 CLI 一致(8 个工具),管理动作不远程暴露 |
44
44
  | **本地 / 局域网双模式** | 本地 `serve --stdio` 零进程、按需拉起(无常驻);局域网 streamable HTTP 常驻——两种模式可并存、按需选用 |
45
45
 
46
46
  ## 功能详解
@@ -106,7 +106,7 @@
106
106
 
107
107
  - **记忆库即引擎**:`serve` 把记忆目录挂成 MCP 服务,目录随盘走;引擎主机只需装 CLI 当存放点,无需装任何 AI 智能体。
108
108
  - **双模式可并存**:本地 `serve --stdio` 零进程(客户端按需拉起);局域网 streamable HTTP(默认 `0.0.0.0:8787`)+ 每智能体 token 鉴权。
109
- - **开机自启**:`lan enable` 注册 Windows 计划任务(默认登录自启,`--onstart` 开机即启需管理员);`lan disable` 移除,`lan status` 查询。
109
+ - **开机自启**:`lan enable` 注册 Windows 开机自启——优先计划任务(默认登录自启,`--onstart` 开机即启需管理员);非管理员(计划任务被拒)自动降级为**用户级 Startup 静默自启**(免管理员);`lan disable` 移除,`lan status` 查询。
110
110
  - **安全边界**:管理动作(init / config / token / lan / serve)不进 MCP,token 不远程暴露;远程智能体只能读写记忆,不能改配置、不能管 token。
111
111
  - 完整操作步骤见上文「局域网多机共享」章节与 [USER_GUIDE.md](USER_GUIDE.md)。
112
112
 
@@ -185,7 +185,7 @@ npm i -g @yottameta/yotta-memory
185
185
  | `yotta-memory iam <id> [--force]` | 登记本智能体唯一身份并自动落自我档案(`agents.json`,ID 必须唯一)|
186
186
  | `yotta-memory token new --agent <id> [--force]` / `token list` / `token revoke --agent <id>` | 为智能体生成 / 列出 / 吊销访问 token(登记于记忆库 `.server/tokens.json`;同 ID 已被其它来源占用需 `--force` 覆盖,防不同智能体合流)|
187
187
  | `yotta-memory serve [--host 0.0.0.0] [--port 8787] [--no-auth] [--stdio]` | 启动 MCP 记忆引擎(streamable HTTP 局域网 / --stdio 本地零进程模式;Bearer token + X-Agent-Id 鉴权)|
188
- | `yotta-memory lan enable [--onstart] / disable / status` | 开机自启管理(Windows 计划任务,默认 ONLOGON 登录自启;--onstart 开机即启需管理员)|
188
+ | `yotta-memory lan enable [--onstart] / disable / status` | 开机自启管理(Windows:计划任务,默认 ONLOGON 登录自启、--onstart 开机即启需管理员;非管理员自动降级用户级 Startup 静默自启)|
189
189
 
190
190
  类型:`FACT`(事实,公共共享)/ `PREF`(偏好)/ `BOUND`(边界)/ `COMMIT`(承诺)。
191
191
 
@@ -226,10 +226,10 @@ yotta-memory recall --type FACT --limit 10
226
226
  3. 启动服务(默认监听 0.0.0.0:8787,Bearer token + X-Agent-Id 鉴权)——临时运行或注册开机自启二选一:
227
227
  ```bash
228
228
  yotta-memory serve # 临时前台运行
229
- yotta-memory lan enable # 注册开机自启(Windows 计划任务,登录自启)
229
+ yotta-memory lan enable # 注册开机自启(Windows:计划任务;非管理员自动降级用户级 Startup 静默自启)
230
230
  yotta-memory lan status # 查看自启状态
231
231
  ```
232
- > `lan enable --onstart` 改为开机即启(需管理员);`lan disable` 移除自启。
232
+ > `lan enable --onstart` 改为开机即启(需管理员);非管理员时 `lan enable` 自动改用用户级 Startup 静默自启(无需管理员);`lan disable` 移除自启。
233
233
 
234
234
  > 首次监听 0.0.0.0 时,Windows / 系统防火墙可能询问是否放行,需允许放行,否则局域网内其它主机无法访问;`--no-auth` 会关闭鉴权,仅限可信内网使用。
235
235
 
package/SKILL.md CHANGED
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  name: yotta-memory
3
3
  description: "元忆 —— 有权限边界的文件式智能体记忆。文件式、零依赖、可 diff/回滚:让任何 AI 智能体活过会话,开工 recall 恢复上下文、重要信息 remember 落盘、收工归档。类型体系 FACT(公共共享)/ PREF / BOUND / COMMIT(私密隔离)。触发:记住、别忘了、记一笔、记忆、remember、recall、跨会话、上次说到、续测、交接、归档、记忆盘、共享记忆、局域网记忆"
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  license: MIT
6
6
  ---
7
7
 
8
8
  # yotta-memory(元忆)— 有权限边界的文件式智能体记忆
9
9
 
10
10
  > 一句话:元忆 —— 有权限边界的文件式智能体记忆(不注入、可 diff、能回滚;FACT 共享、PREF / BOUND / COMMIT 私密隔离)。
11
- > 版本:0.5.3 | 最后更新:2026-08-25
11
+ > 版本:0.5.4 | 最后更新:2026-08-25
12
12
 
13
13
  ## 这是什么
14
14
 
@@ -79,7 +79,7 @@ license: MIT
79
79
  | `yotta-memory iam <id> [--force]` | 登记本智能体唯一身份并自动落自我档案(`agents.json`,ID 必须唯一)|
80
80
  | `yotta-memory token new --agent <id> [--force]` / `token list` / `token revoke --agent <id>` | 每智能体访问 token:生成 / 列出 / 吊销(登记 `<记忆库>/.server/tokens.json`;同 ID 已被其它来源占用需 `--force` 覆盖,防不同智能体合流)|
81
81
  | `yotta-memory serve [--host 0.0.0.0] [--port 8787] [--no-auth] [--stdio]` | 启动 MCP 记忆引擎(streamable HTTP 局域网 / --stdio 本地零进程模式;Bearer token + X-Agent-Id 鉴权)|
82
- | `yotta-memory lan enable [--onstart] / disable / status` | 开机自启管理(Windows 计划任务,默认 ONLOGON 登录自启;--onstart 开机即启需管理员)|
82
+ | `yotta-memory lan enable [--onstart] / disable / status` | 开机自启管理(Windows:计划任务,默认 ONLOGON 登录自启、--onstart 开机即启需管理员;非管理员自动降级用户级 Startup 静默自启)|
83
83
 
84
84
  ## 存储格式(摘要)
85
85
 
@@ -137,7 +137,7 @@ yotta-memory --version # 或 command -v yotta-memory / where yotta-memory
137
137
  > 记忆盘场景:硬盘插上 → AI 检查盘上目录是否有数据 → 有则接入 + config 记住 → 插盘即恢复,机器记住位置。
138
138
 
139
139
  **步骤 0.5 启动记忆引擎(仅引擎主机,供远程接入)**
140
- - 本机若作引擎:🔒 **征得同意后**启动服务——临时运行 `yotta-memory serve`(默认 `0.0.0.0:8787`,Bearer token + X-Agent-Id 鉴权;`--no-auth` 仅限可信内网),或注册开机自启 `yotta-memory lan enable`(Windows 计划任务,默认登录自启;`--onstart` 开机即启需管理员)。
140
+ - 本机若作引擎:🔒 **征得同意后**启动服务——临时运行 `yotta-memory serve`(默认 `0.0.0.0:8787`,Bearer token + X-Agent-Id 鉴权;`--no-auth` 仅限可信内网),或注册开机自启 `yotta-memory lan enable`(Windows:优先计划任务,默认登录自启;非管理员自动降级用户级 Startup 静默自启,免管理员)。
141
141
  - 本地零进程模式:本机 AI 也可用 `serve --stdio` 由 MCP 客户端按需拉起 CLI(无常驻进程,照灵魂盘)。
142
142
  - 远程客户端接入前,先确认引擎主机 serve 已运行(`lan status` 可查)。
143
143
 
package/USER_GUIDE.md CHANGED
@@ -111,7 +111,7 @@ yotta-memory init --dir /srv/yotta-memory # 新库:初始化(
111
111
  **第 3 步:注册开机自启(可选,推荐)**
112
112
 
113
113
  ```bash
114
- # Windows:内置命令(计划任务)
114
+ # Windows:内置命令(优先计划任务;非管理员自动降级用户级 Startup 静默自启)
115
115
  yotta-memory lan enable # 登录后自动启动(默认)
116
116
  yotta-memory lan enable --onstart # 开机即启(需管理员)
117
117
  yotta-memory lan status # 查看状态
@@ -242,7 +242,7 @@ yotta-memory remember FACT 主题 内容 # 智能体落盘
242
242
  | `yotta-memory iam <id> [--force]` | 登记本智能体唯一身份并自动落自我档案(`agents.json`,ID 必须唯一)|
243
243
  | `yotta-memory token new --agent <id> [--force]` / `token list` / `token revoke --agent <id>` | 访问 token(同 ID 已被其它来源占用需 `--force` 覆盖)|
244
244
  | `yotta-memory serve [--port 8787] [--stdio] [--no-auth]` | 启动记忆引擎(--no-auth 关闭鉴权,仅限可信内网)|
245
- | `yotta-memory lan enable [--onstart] / disable / status` | 开机自启管理 |
245
+ | `yotta-memory lan enable [--onstart] / disable / status` | 开机自启管理(Windows:计划任务;非管理员自动降级用户级 Startup 静默自启)|
246
246
 
247
247
  类型:`FACT`(事实,共享)/ `PREF`(偏好)/ `BOUND`(边界)/ `COMMIT`(承诺),后三类按智能体物理分目录隔离(`private/<owner>/<type>/`)。
248
248
 
@@ -259,7 +259,7 @@ yotta-memory remember FACT 主题 内容 # 智能体落盘
259
259
  - 返回 401:服务在运行,是鉴权问题(token / 请求头不对)。
260
260
  - 连接被拒 / 超时:服务没启动,或防火墙拦截。
261
261
 
262
- **`lan enable` 失败提示 Access denied:** 需要管理员权限,请用管理员终端重新执行;`--onstart` 模式必须管理员。
262
+ **`lan enable` 计划任务被拒(Access denied 等):** 无需担心——会自动降级为**用户级 Startup 静默自启**(免管理员,重新登录后生效,启动脚本位于用户 Startup 目录);如确需计划任务,请用管理员终端重新执行;`--onstart` 模式必须管理员。
263
263
 
264
264
  **启动引擎报端口被占用(EADDRINUSE):** 用 `--port <其它端口>` 换端口启动,两端保持一致;或先查占用:Linux `ss -tlnp | grep 8787`,Windows `netstat -ano | findstr 8787`。
265
265
 
@@ -4,6 +4,7 @@
4
4
  // v0.5.0 新增:隐私硬隔离——私密物理分目录 private/<agent_id>/{prefs,bounds,commits}/ + 关闭 --agent 越权读 + 私密写跨智能体需 --unsafe + 禁 shell 直读写(文档红线)
5
5
  // v0.4.2 新增:iam/whoami 智能体身份自注册(agents.json 唯一性)+ 自我档案 PREF + 私密记忆须声明 owner
6
6
  // v0.5.3 新增:CLI 选项可前置(--agent 等允许放在子命令前,不再误报"未知命令")/ lan enable 成功补"服务不会立刻启动"提示(v0.5.2 lan 引号修复无回归)
7
+ // v0.5.4 新增:lan enable 在非管理员(schtasks Access denied)时自动降级为用户级 Startup 静默自启(VBS sh.Run 窗口0 + autostart.cmd,node 路径 process.execPath 自动探测);lan disable/status 同时管理计划任务与 Startup 双机制
7
8
  'use strict';
8
9
 
9
10
  const fs = require('fs');
@@ -13,7 +14,7 @@ const crypto = require('crypto');
13
14
  const http = require('http');
14
15
  const child_process = require('child_process');
15
16
 
16
- const VERSION = '0.5.3';
17
+ const VERSION = '0.5.4';
17
18
  const TYPES = ['FACT', 'PREF', 'BOUND', 'COMMIT'];
18
19
  const TYPE_DIRS = { FACT: 'facts', PREF: 'prefs', BOUND: 'bounds', COMMIT: 'commits' };
19
20
  const PUBLIC_DIR = 'facts';
@@ -960,8 +961,11 @@ function cmdServeStdio() {
960
961
  process.stdin.on('end', function () { process.exit(0); });
961
962
  }
962
963
 
963
- // ---- lan 命令(Windows 计划任务管理开机自启 serve)----
964
+ // ---- lan 命令(Windows 开机自启管理 serve)----
965
+ // 双机制:① schtasks 计划任务(默认,需相应权限);② 非管理员(Access denied)自动降级为
966
+ // 用户级 Startup 静默自启(VBS sh.Run <autostart.cmd>, 0, False + autostart.cmd;node 路径 process.execPath 自动探测,0.5.4)
964
967
  const LAN_TASK_NAME = 'YottaMemoryServe';
968
+ const LAN_GEN_MARKER = 'Generated by yotta-memory lan enable';
965
969
  function lanTaskRunCmd(opts) {
966
970
  const host = opts.host || '0.0.0.0';
967
971
  const port = opts.port || 8787;
@@ -969,59 +973,158 @@ function lanTaskRunCmd(opts) {
969
973
  const q = (p) => /[\s"]/.test(p) ? '\\"' + p.replace(/"/g, '\\"') + '\\"' : p;
970
974
  return q(process.execPath) + ' ' + q(__filename) + ' serve --host ' + host + ' --port ' + port;
971
975
  }
976
+ function lanStartupDir() {
977
+ // 测试/高级用途可用 YOTTA_LAN_STARTUP_DIR 覆盖(默认用户级 Startup 目录,免管理员)
978
+ if (process.env.YOTTA_LAN_STARTUP_DIR) return process.env.YOTTA_LAN_STARTUP_DIR;
979
+ const base = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
980
+ return path.join(base, 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup');
981
+ }
982
+ function lanAutostartDir() {
983
+ // 产品自有目录 ~/.yottamemory/autostart/(引擎数据目录内,非系统配置);测试可用 YOTTA_LAN_AUTOSTART_DIR 覆盖
984
+ if (process.env.YOTTA_LAN_AUTOSTART_DIR) return process.env.YOTTA_LAN_AUTOSTART_DIR;
985
+ return path.join(os.homedir(), '.yottamemory', 'autostart');
986
+ }
987
+ function lanVbsPath() { return path.join(lanStartupDir(), 'yotta-memory-serve.vbs'); }
988
+ function lanAutostartCmdPath() { return path.join(lanAutostartDir(), 'yotta-memory-autostart.cmd'); }
989
+ function lanLogPath(opts) {
990
+ if (process.env.YOTTA_LAN_LOG_FILE) return process.env.YOTTA_LAN_LOG_FILE;
991
+ return path.join(os.homedir(), '.yottamemory', 'serve-' + (opts.port || 8787) + '.log');
992
+ }
993
+ function lanAutostartCmdContent(opts) {
994
+ const host = opts.host || '0.0.0.0';
995
+ const port = opts.port || 8787;
996
+ const q = (p) => '"' + String(p).replace(/"/g, '""') + '"';
997
+ // 生成文件用纯 ASCII(避免 cmd/VBS 按系统代码页读取中文注释乱码)
998
+ return '@echo off\r\n'
999
+ + 'chcp 65001 >nul\r\n'
1000
+ + 'rem ' + LAN_GEN_MARKER + '; remove with: yotta-memory lan disable\r\n'
1001
+ + q(process.execPath) + ' ' + q(__filename) + ' serve --host ' + host + ' --port ' + port + ' >> ' + q(lanLogPath(opts)) + ' 2>&1\r\n';
1002
+ }
1003
+ function lanVbsContent() {
1004
+ return "' " + LAN_GEN_MARKER + '; remove with: yotta-memory lan disable\r\n'
1005
+ + 'Set sh = CreateObject("WScript.Shell")\r\n'
1006
+ + 'sh.Run "' + String(lanAutostartCmdPath()).replace(/"/g, '""') + '", 0, False\r\n';
1007
+ }
1008
+ function lanInstallStartup(opts) {
1009
+ fs.mkdirSync(lanAutostartDir(), { recursive: true });
1010
+ fs.writeFileSync(lanAutostartCmdPath(), lanAutostartCmdContent(opts), 'utf8');
1011
+ fs.mkdirSync(lanStartupDir(), { recursive: true });
1012
+ // VBS 用 UTF-16LE+BOM:wscript 按 Unicode 读取,中文路径不乱码(纯 ANSI 读取会按系统代码页误读)
1013
+ fs.writeFileSync(lanVbsPath(), '\ufeff' + lanVbsContent(), 'utf16le');
1014
+ }
1015
+ function lanRemoveStartupFiles() {
1016
+ // 只删除带产品标记的生成文件,绝不误删用户自己的 Startup 文件
1017
+ const removed = [];
1018
+ for (const f of [lanVbsPath(), lanAutostartCmdPath()]) {
1019
+ try {
1020
+ if (lanFileHasMarker(f)) { fs.unlinkSync(f); removed.push(f); }
1021
+ } catch (e) { /* 单个文件失败不阻断其它清理 */ }
1022
+ }
1023
+ return removed;
1024
+ }
1025
+ function lanFileHasMarker(f) {
1026
+ try {
1027
+ if (!fs.existsSync(f)) return false;
1028
+ const buf = fs.readFileSync(f);
1029
+ const m8 = Buffer.from(LAN_GEN_MARKER, 'utf8');
1030
+ const m16 = Buffer.from(LAN_GEN_MARKER, 'utf16le');
1031
+ return buf.indexOf(m8) !== -1 || buf.indexOf(m16) !== -1;
1032
+ } catch (e) { return false; }
1033
+ }
1034
+ function isSchtasksAccessDenied(e) {
1035
+ const msg = String((e && e.stderr) || (e && e.message) || e);
1036
+ return /access\s+is\s+denied|access\s+denied|拒绝访问/i.test(msg);
1037
+ }
972
1038
  function cmdLanEnable(opts) {
973
1039
  if (process.platform !== 'win32') {
974
- console.error('lan 命令当前仅支持 Windows(计划任务);本机平台: ' + process.platform);
1040
+ console.error('lan 命令当前仅支持 Windows(计划任务 / Startup 自启);本机平台: ' + process.platform);
975
1041
  process.exit(2);
976
1042
  }
977
1043
  const trigger = opts.onstart ? 'onstart' : 'onlogon';
978
1044
  const tr = lanTaskRunCmd(opts);
979
1045
  try {
980
1046
  child_process.execFileSync('schtasks', ['/create', '/tn', LAN_TASK_NAME, '/tr', tr, '/sc', trigger, '/f'], { stdio: 'inherit' });
1047
+ console.log('已注册开机自启: 计划任务 ' + LAN_TASK_NAME + '(触发器 ' + trigger + ')');
1048
+ console.log('运行命令: ' + tr);
1049
+ console.log('备注: 服务不会立刻启动,需重启/重新登录后自动启动;如需现在运行请执行 yotta-memory serve');
1050
+ return;
981
1051
  } catch (e) {
982
- console.error('注册计划任务失败(ONSTART 需要管理员权限;ONLOGON 一般不需要;如仍失败请用管理员终端执行): ' + String((e && e.stderr) || (e && e.message) || e).split(/\r?\n/)[0]);
983
- process.exit(1);
1052
+ const firstLine = String((e && e.stderr) || (e && e.message) || e).split(/\r?\n/)[0];
1053
+ if (isSchtasksAccessDenied(e)) console.error('计划任务注册被拒绝(当前用户非管理员,Access denied): ' + firstLine);
1054
+ else console.error('计划任务注册失败(当前环境不可用计划任务): ' + firstLine);
1055
+ console.log('自动改用用户级 Startup 静默自启(免管理员)...');
1056
+ try {
1057
+ lanInstallStartup(opts);
1058
+ } catch (e2) {
1059
+ console.error('写 Startup 自启失败: ' + String((e2 && e2.message) || e2).split(/\r?\n/)[0]);
1060
+ console.error('请用管理员终端执行 yotta-memory lan enable,或将以下命令手动加入启动项: ' + tr);
1061
+ process.exit(1);
1062
+ }
1063
+ console.log('已启用用户级 Startup 静默自启(无需管理员)');
1064
+ console.log('启动脚本: ' + lanVbsPath());
1065
+ console.log('启动命令: ' + lanAutostartCmdPath());
1066
+ console.log('日志: ' + lanLogPath(opts));
1067
+ console.log('备注: 服务不会立刻启动,需重新登录后自动启动;如需现在运行请执行 yotta-memory serve');
1068
+ console.log('提示: 如需改回计划任务,请用管理员终端重新执行 yotta-memory lan enable');
1069
+ return;
984
1070
  }
985
- console.log('已注册开机自启: 计划任务 ' + LAN_TASK_NAME + '(触发器 ' + trigger + ')');
986
- console.log('运行命令: ' + tr);
987
- console.log('备注: 服务不会立刻启动,需重启/重新登录后自动启动;如需现在运行请执行 yotta-memory serve');
988
1071
  }
989
1072
  function cmdLanDisable() {
990
1073
  if (process.platform !== 'win32') {
991
- console.error('lan 命令当前仅支持 Windows(计划任务);本机平台: ' + process.platform);
1074
+ console.error('lan 命令当前仅支持 Windows(计划任务 / Startup 自启);本机平台: ' + process.platform);
992
1075
  process.exit(2);
993
1076
  }
1077
+ let sawError = false;
1078
+ let removedAny = false;
994
1079
  try {
995
- child_process.execFileSync('schtasks', ['/delete', '/tn', LAN_TASK_NAME, '/f'], { stdio: ['ignore', 'pipe', 'ignore'] });
1080
+ child_process.execFileSync('schtasks', ['/delete', '/tn', LAN_TASK_NAME, '/f'], { stdio: ['ignore', 'pipe', 'pipe'] });
1081
+ console.log('已移除开机自启计划任务 ' + LAN_TASK_NAME);
1082
+ removedAny = true;
996
1083
  } catch (e) {
997
1084
  const msg = String((e && e.stderr) || (e && e.message) || e);
998
- if (msg.indexOf('cannot find the path') !== -1 || msg.indexOf('没有找到') !== -1) {
999
- console.log('未启用: 计划任务 ' + LAN_TASK_NAME + ' 不存在,无需移除');
1000
- return;
1085
+ if (!/cannot find the (path|file)|没有找到|找不到|不存在/i.test(msg)) {
1086
+ console.error('移除计划任务失败: ' + msg.split(/\r?\n/)[0]);
1087
+ sawError = true;
1001
1088
  }
1002
- console.error('移除计划任务失败: ' + msg.split(/\r?\n/)[0]);
1003
- process.exit(1);
1004
1089
  }
1005
- console.log('已移除开机自启计划任务 ' + LAN_TASK_NAME);
1090
+ for (const f of lanRemoveStartupFiles()) {
1091
+ console.log('已移除 Startup 自启文件: ' + f);
1092
+ removedAny = true;
1093
+ }
1094
+ if (!removedAny && !sawError) console.log('未启用: 未发现任何自启配置(计划任务与 Startup 文件均不存在)');
1095
+ if (sawError) process.exit(1);
1006
1096
  }
1007
1097
  function cmdLanStatus() {
1008
1098
  if (process.platform !== 'win32') {
1009
- console.log('lan 命令当前仅支持 Windows(计划任务);本机平台: ' + process.platform);
1099
+ console.log('lan 命令当前仅支持 Windows(计划任务 / Startup 自启);本机平台: ' + process.platform);
1010
1100
  return;
1011
1101
  }
1102
+ let taskFound = false;
1012
1103
  try {
1013
1104
  const out = child_process.execFileSync('schtasks', ['/query', '/tn', LAN_TASK_NAME, '/fo', 'LIST', '/v'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
1014
- console.log('已启用: 计划任务 ' + LAN_TASK_NAME + ' 存在');
1105
+ taskFound = true;
1106
+ console.log('计划任务 ' + LAN_TASK_NAME + ': 已启用');
1015
1107
  const re = /^(状态|Status)\s*:\s*(.+)$/;
1016
1108
  for (const line of String(out).split(/\r?\n/)) {
1017
1109
  const m = re.exec(line.trim());
1018
- if (m) console.log(m[1] + ': ' + m[2]);
1110
+ if (m) console.log(' ' + m[1] + ': ' + m[2]);
1019
1111
  }
1020
1112
  } catch (e) {
1021
- console.log('未启用: 计划任务 ' + LAN_TASK_NAME + ' 不存在(可用 yotta-memory lan enable 注册)');
1113
+ console.log('计划任务 ' + LAN_TASK_NAME + ': 未启用');
1022
1114
  }
1115
+ const vbsOk = lanFileHasMarker(lanVbsPath());
1116
+ const cmdOk = lanFileHasMarker(lanAutostartCmdPath());
1117
+ if (vbsOk && cmdOk) {
1118
+ console.log('Startup 静默自启(免管理员): 已启用');
1119
+ console.log(' 启动脚本: ' + lanVbsPath());
1120
+ console.log(' 启动命令: ' + lanAutostartCmdPath());
1121
+ } else if (vbsOk || cmdOk) {
1122
+ console.log('Startup 静默自启: 部分残留(建议执行 yotta-memory lan disable 后重新 lan enable)');
1123
+ } else {
1124
+ console.log('Startup 静默自启(免管理员): 未启用');
1125
+ }
1126
+ if (!taskFound && !vbsOk && !cmdOk) console.log('未启用任何开机自启(可用 yotta-memory lan enable 注册)');
1023
1127
  }
1024
-
1025
1128
  // ---- usage / main ----
1026
1129
  function usage() {
1027
1130
  console.log([
@@ -1044,7 +1147,7 @@ function usage() {
1044
1147
  ' yotta-memory token list 列出已登记智能体',
1045
1148
  ' yotta-memory token revoke --agent <id> 吊销某智能体 token',
1046
1149
  ' yotta-memory serve [--host 0.0.0.0] [--port 8787] [--no-auth] [--stdio] 启动 MCP 记忆引擎(streamable HTTP;--stdio 本地零进程模式)',
1047
- ' yotta-memory lan enable [--onstart] | disable | status 开机自启管理(Windows 计划任务,默认 ONLOGON)',
1150
+ ' yotta-memory lan enable [--onstart] | disable | status 开机自启管理(Windows 计划任务,默认 ONLOGON;非管理员自动降级用户级 Startup 静默自启)',
1048
1151
  ' yotta-memory --version 版本',
1049
1152
  '',
1050
1153
  '类型: FACT(公共共享) / PREF(偏好) / BOUND(边界) / COMMIT(承诺)',
@@ -1155,4 +1258,16 @@ module.exports = {
1155
1258
  collectEntryFiles: collectEntryFiles,
1156
1259
  migrateLayout: migrateLayout,
1157
1260
  typeSubdir: typeSubdir,
1261
+ lanTaskRunCmd: lanTaskRunCmd,
1262
+ lanStartupDir: lanStartupDir,
1263
+ lanAutostartDir: lanAutostartDir,
1264
+ lanVbsPath: lanVbsPath,
1265
+ lanAutostartCmdPath: lanAutostartCmdPath,
1266
+ lanLogPath: lanLogPath,
1267
+ lanAutostartCmdContent: lanAutostartCmdContent,
1268
+ lanVbsContent: lanVbsContent,
1269
+ lanInstallStartup: lanInstallStartup,
1270
+ lanRemoveStartupFiles: lanRemoveStartupFiles,
1271
+ lanFileHasMarker: lanFileHasMarker,
1272
+ isSchtasksAccessDenied: isSchtasksAccessDenied,
1158
1273
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yottameta/yotta-memory",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "元忆 —— 有权限边界的文件式智能体记忆。文件式、零依赖、可 diff/回滚;FACT/PREF/BOUND/COMMIT 四分类(公共共享/私密隔离),用户级+项目级双级存储。",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -1,4 +1,4 @@
1
- # yotta-memory 协议规范 v0.5.3
1
+ # yotta-memory 协议规范 v0.5.4
2
2
 
3
3
  > 本文件定义 yotta-memory 记忆标准:存储位置、目录结构、文件格式、类型体系与 CLI 命令参考。
4
4
  > 目标:任何支持 Agent Skills 开放标准的智能体,装完即可读写同一份记忆。