@lumi-ai-lab/harness-data 0.0.20 → 0.0.21

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumi-ai-lab/harness-data",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "description": "Installer and updater for Harness Data",
5
5
  "type": "module",
6
6
  "bin": {
@@ -344,7 +344,8 @@ export async function installCommand(options = {}) {
344
344
  blank();
345
345
 
346
346
  step(8, 8, "配置 Agent Hook");
347
- const linkedAgents = linkAgents(runtimeDir, await chooseAgent(options));
347
+ const selectedAgent = await chooseAgent(options);
348
+ const linkedAgents = linkAgents(runtimeDir, selectedAgent);
348
349
  for (const [source, target] of linkedAgents) {
349
350
  if (fs.existsSync(path.join(runtimeDir, target))) ok(`${target} -> ${source}`);
350
351
  }
@@ -363,6 +364,7 @@ export async function installCommand(options = {}) {
363
364
  tools: manifest.installedTools || {},
364
365
  manifestSha256: manifestDigest(manifest),
365
366
  packageVersion: packageVersion(),
367
+ agent: selectedAgent,
366
368
  lastCheckAt: new Date().toISOString()
367
369
  });
368
370
  console.log(`安装完成:${runtimeDir}`);
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { confirm } from "../lib/prompt.js";
3
+ import { chooseAgent, confirm } from "../lib/prompt.js";
4
4
  import { findWorkspaceDir, readUserState, writeState } from "../lib/paths.js";
5
5
  import { run } from "../lib/exec.js";
6
6
  import { installToolsFromManifest, manifestDigest, readManifest } from "../lib/manifest.js";
@@ -11,7 +11,7 @@ import { resolveLatestTool } from "../lib/tool-release.js";
11
11
  import { protocolFromUrl, runGitWithProtocol } from "../lib/git-auth.js";
12
12
  import { buildAndCheck, installRuntimeBundle, printDoctorSummary } from "./install.js";
13
13
  import { collectDoctor } from "./doctor.js";
14
- import { writeLocalConfig } from "../lib/config.js";
14
+ import { hasAnyAgentHook, linkAgents, writeLocalConfig } from "../lib/config.js";
15
15
  import { action, blank, header, ok, shortSha, skip, step, warn } from "../lib/log.js";
16
16
 
17
17
  export function isNonBlockingUpdateDoctorCheck(check) {
@@ -52,7 +52,7 @@ async function maybeUpdateTool(runtimeDir, manifest, tool, options, state) {
52
52
  return null;
53
53
  }
54
54
  action(`发现更新:${tool.name} ${current.version || "unknown"} -> ${tag}`);
55
- if (!(await confirm(`是否更新 ${tool.name}?`, { defaultNo: true }))) {
55
+ if (!(await confirm(`是否更新 ${tool.name}?`))) {
56
56
  skip(tool.name);
57
57
  options.skippedUpdates?.push(`${tool.name} ${tag}`);
58
58
  return null;
@@ -92,7 +92,7 @@ export async function updateWikis(runtimeDir, options, state) {
92
92
  return null;
93
93
  }
94
94
  action(`发现更新:harness-data-wikis ${shortSha(local)} -> ${shortSha(remote)}`);
95
- if (!(await confirm("是否更新 harness-data-wikis?", { defaultNo: true }))) {
95
+ if (!(await confirm("是否更新 harness-data-wikis?"))) {
96
96
  skip("harness-data-wikis");
97
97
  options.skippedUpdates?.push(`harness-data-wikis ${shortSha(remote)}`);
98
98
  return null;
@@ -103,6 +103,20 @@ export async function updateWikis(runtimeDir, options, state) {
103
103
  return { commit };
104
104
  }
105
105
 
106
+ export async function restoreAgentHooksIfMissing(runtimeDir, options = {}) {
107
+ if (hasAnyAgentHook(runtimeDir)) {
108
+ ok("Agent Hook 已配置");
109
+ return null;
110
+ }
111
+ action("未检测到 Agent Hook,重新配置");
112
+ const agent = await chooseAgent(options);
113
+ const linkedAgents = linkAgents(runtimeDir, agent);
114
+ for (const [source, target] of linkedAgents) {
115
+ if (fs.existsSync(path.join(runtimeDir, target))) ok(`${target} -> ${source}`);
116
+ }
117
+ return { agent, linkedAgents };
118
+ }
119
+
106
120
  export async function checkUpdates(workspace, options = {}) {
107
121
  const state = readUserState();
108
122
  const latestInstaller = await npmLatest();
@@ -131,7 +145,7 @@ export async function updateCommand(options = {}) {
131
145
  const skipped = [];
132
146
  const trackingOptions = { ...options, skippedUpdates: skipped };
133
147
 
134
- step(1, 6, "检查 installer");
148
+ step(1, 7, "检查 installer");
135
149
  const latestInstaller = await npmLatest();
136
150
  if (latestInstaller && latestInstaller !== packageVersion()) {
137
151
  warn(`installer 有新版本 ${packageVersion()} -> ${latestInstaller}`);
@@ -141,11 +155,11 @@ export async function updateCommand(options = {}) {
141
155
  }
142
156
  blank();
143
157
 
144
- step(2, 6, "检查 runtime bundle");
158
+ step(2, 7, "检查 runtime bundle");
145
159
  const runtimeRelease = await latestRelease("lumi-ai-lab/harness-data", options);
146
160
  if (state.runtimeTag && state.runtimeTag !== runtimeRelease.tag_name) {
147
161
  action(`发现更新:runtime bundle ${state.runtimeTag} -> ${runtimeRelease.tag_name}`);
148
- if (await confirm("是否更新 runtime bundle?", { defaultNo: true })) {
162
+ if (await confirm("是否更新 runtime bundle?")) {
149
163
  const bundle = await installRuntimeBundle(runtimeDir, { ...trackingOptions, force: true });
150
164
  runtimeTag = bundle.tag || runtimeRelease.tag_name;
151
165
  changed = true;
@@ -159,7 +173,7 @@ export async function updateCommand(options = {}) {
159
173
  }
160
174
  blank();
161
175
 
162
- step(3, 6, "检查 CLI 工具");
176
+ step(3, 7, "检查 CLI 工具");
163
177
  for (const tool of manifest.tools || []) {
164
178
  if (state.installMode === "local-path" && tool.name !== "data-harness-cli") {
165
179
  skip(`${tool.name} 为本地路径模式,请手动检查`);
@@ -174,7 +188,7 @@ export async function updateCommand(options = {}) {
174
188
  }
175
189
  blank();
176
190
 
177
- step(4, 6, "检查 Wikis 知识库");
191
+ step(4, 7, "检查 Wikis 知识库");
178
192
  const wikis = await updateWikis(runtimeDir, trackingOptions, state);
179
193
  if (wikis) {
180
194
  changed = true;
@@ -182,7 +196,11 @@ export async function updateCommand(options = {}) {
182
196
  }
183
197
  blank();
184
198
 
185
- step(5, 6, "构建 Wikis 索引");
199
+ step(5, 7, "检查 Agent Hook");
200
+ const restoredAgent = await restoreAgentHooksIfMissing(runtimeDir, trackingOptions);
201
+ blank();
202
+
203
+ step(6, 7, "构建 Wikis 索引");
186
204
  if (changed) {
187
205
  await buildAndCheck(runtimeDir, trackingOptions);
188
206
  } else {
@@ -190,7 +208,7 @@ export async function updateCommand(options = {}) {
190
208
  }
191
209
  blank();
192
210
 
193
- step(6, 6, "安装校验");
211
+ step(7, 7, "安装校验");
194
212
  if (changed) {
195
213
  writeLocalConfig(runtimeDir, { overwrite: true });
196
214
  ok("本地配置已刷新");
@@ -202,6 +220,7 @@ export async function updateCommand(options = {}) {
202
220
  runtimeTag,
203
221
  tools: nextTools,
204
222
  manifestSha256: manifestDigest(manifest),
223
+ ...(restoredAgent ? { agent: restoredAgent.agent } : {}),
205
224
  lastCheckAt: new Date().toISOString()
206
225
  });
207
226
  blank();
@@ -216,6 +235,24 @@ export async function updateCommand(options = {}) {
216
235
  console.log("已跳过:");
217
236
  for (const item of skipped) console.log(`- ${item}`);
218
237
  }
238
+ if (restoredAgent) {
239
+ console.log("");
240
+ console.log("已恢复:");
241
+ console.log(`- Agent Hook ${restoredAgent.agent}`);
242
+ }
243
+ } else if (restoredAgent) {
244
+ ok("Agent Hook 已恢复");
245
+ writeState(runtimeDir, { ...state, agent: restoredAgent.agent, lastCheckAt: new Date().toISOString() });
246
+ blank();
247
+ console.log(`配置已恢复:${runtimeDir}`);
248
+ console.log("");
249
+ console.log("已恢复:");
250
+ console.log(`- Agent Hook ${restoredAgent.agent}`);
251
+ if (skipped.length) {
252
+ console.log("");
253
+ console.log("已跳过:");
254
+ for (const item of skipped) console.log(`- ${item}`);
255
+ }
219
256
  } else {
220
257
  skip("没有组件更新");
221
258
  writeState(runtimeDir, { ...state, lastCheckAt: new Date().toISOString() });
package/src/lib/config.js CHANGED
@@ -21,6 +21,10 @@ export const agentLinks = {
21
21
  };
22
22
  export const agentChoiceText = agentChoices.join(", ");
23
23
 
24
+ export function hasAnyAgentHook(workspace) {
25
+ return concreteAgentNames.some((name) => fs.existsSync(path.join(workspace, `.${name}`)));
26
+ }
27
+
24
28
  export function writeLocalConfig(workspace, options = {}) {
25
29
  const configDir = path.join(workspace, "config");
26
30
  fs.mkdirSync(configDir, { recursive: true });