@rzx/ohs 1.1.0 → 1.1.1

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
@@ -196887,6 +196887,18 @@ class OpenHarnessClient {
196887
196887
  signal: options.signal
196888
196888
  });
196889
196889
  }
196890
+ async listSkills(options = {}) {
196891
+ return await this.request("/skills", {
196892
+ signal: options.signal
196893
+ });
196894
+ }
196895
+ async removeSkill(id, input, options = {}) {
196896
+ return await this.request(`/skills/${encodeURIComponent(id)}`, {
196897
+ method: "DELETE",
196898
+ body: input,
196899
+ signal: options.signal
196900
+ });
196901
+ }
196890
196902
  async listAgentPersonas(options = {}) {
196891
196903
  const response = await this.request("/agent-personas", {
196892
196904
  signal: options.signal
@@ -276984,6 +276996,8 @@ function buildAgentTranscript(messages, parts) {
276984
276996
  const output = [];
276985
276997
  const attachmentsByMessageId = {};
276986
276998
  for (const message of [...messages].sort((a, b) => a.seq - b.seq)) {
276999
+ if (isPresentationOnlyMessage(message))
277000
+ continue;
276987
277001
  const messageParts = (byMessage.get(message.id) ?? []).sort((a, b) => a.seq - b.seq);
276988
277002
  const attachments = attachmentsFromParts(messageParts);
276989
277003
  if (attachments.length > 0)
@@ -277023,6 +277037,14 @@ function buildAgentTranscript(messages, parts) {
277023
277037
  }
277024
277038
  return { messages: output, attachmentsByMessageId };
277025
277039
  }
277040
+ function isPresentationOnlyMessage(message) {
277041
+ const presentation = message.metadata.presentation;
277042
+ if (!presentation || typeof presentation !== "object" || Array.isArray(presentation)) {
277043
+ return false;
277044
+ }
277045
+ const value = presentation;
277046
+ return value.kind === "model_switch" && typeof value.fromModel === "string" && Boolean(value.fromModel.trim()) && typeof value.toModel === "string" && Boolean(value.toModel.trim());
277047
+ }
277026
277048
  function agentMessagesToTranscript(messages) {
277027
277049
  const output = [];
277028
277050
  for (const message of messages) {
@@ -280509,15 +280531,39 @@ class SessionApplicationService {
280509
280531
  try {
280510
280532
  const before = this.context.events.checkpoint();
280511
280533
  const nextModel = metadata ? readSessionRuntimeConfig({ ...existing, metadata }).model : undefined;
280512
- const session = this.context.store.updateSession(sessionId, {
280513
- title: input.title,
280514
- model: nextModel,
280515
- agent: input.agent,
280516
- metadata
280534
+ const modelChanged = nextModel !== undefined && nextModel !== existing.model;
280535
+ const session = this.context.store.transaction(() => {
280536
+ const updated = this.context.store.updateSession(sessionId, {
280537
+ title: input.title,
280538
+ model: nextModel,
280539
+ agent: input.agent,
280540
+ metadata
280541
+ });
280542
+ if (!modelChanged)
280543
+ return updated;
280544
+ const message = this.context.store.createMessage({
280545
+ sessionId,
280546
+ role: "system",
280547
+ metadata: {
280548
+ presentation: {
280549
+ kind: "model_switch",
280550
+ fromModel: existing.model,
280551
+ toModel: nextModel
280552
+ }
280553
+ }
280554
+ });
280555
+ this.context.store.upsertMessagePart({
280556
+ sessionId,
280557
+ messageId: message.id,
280558
+ type: "text",
280559
+ status: "completed",
280560
+ text: `模型已切换 ${existing.model} → ${nextModel}`
280561
+ });
280562
+ return updated;
280517
280563
  });
280518
280564
  if (runtimeConfigurationChanged)
280519
280565
  await this.context.agentPool.close(sessionId);
280520
- if (nextModel !== undefined && nextModel !== existing.model) {
280566
+ if (modelChanged) {
280521
280567
  this.context.contextUsageCache?.invalidate(sessionId);
280522
280568
  }
280523
280569
  this.context.events.publishSince(before);
@@ -286913,6 +286959,148 @@ var init_default_node_application = __esm(() => {
286913
286959
  init_daemon_application();
286914
286960
  });
286915
286961
 
286962
+ // ../../packages/server/src/application/skill-management-service.ts
286963
+ import { createHash as createHash12 } from "node:crypto";
286964
+ import { readFile as readFile17, realpath as realpath7, stat as stat9, unlink as unlink4 } from "node:fs/promises";
286965
+ import {
286966
+ basename as basename12,
286967
+ dirname as dirname20,
286968
+ isAbsolute as isAbsolute12,
286969
+ join as join39,
286970
+ relative as relative9,
286971
+ resolve as resolve26,
286972
+ sep as sep4
286973
+ } from "node:path";
286974
+
286975
+ class SkillManagementService {
286976
+ options;
286977
+ personalSkillsDir;
286978
+ configDir;
286979
+ bundledSkills;
286980
+ constructor(options) {
286981
+ this.options = options;
286982
+ const defaultSkillsDir = getSkillsDir();
286983
+ this.configDir = resolve26(options.configDir ?? dirname20(defaultSkillsDir));
286984
+ this.personalSkillsDir = options.configDir ? join39(this.configDir, "skills") : resolve26(defaultSkillsDir);
286985
+ this.bundledSkills = options.bundledSkills ?? BUNDLED_SKILLS;
286986
+ }
286987
+ async list() {
286988
+ const warnings = [];
286989
+ const projects = await validProjects(this.options.projects.list(), warnings);
286990
+ const skills = this.bundledSkills.map((skill) => desktopSkill(skill, "bundled"));
286991
+ const seen = new Set;
286992
+ for (const project of projects) {
286993
+ await this.load(join39(project.root, ".agents", "skills"), "agent", skills, seen, warnings, project);
286994
+ await this.load(join39(project.root, ".claude", "skills"), "agent", skills, seen, warnings, project);
286995
+ const managed = join39(project.root, ".openharness-ts", "skills");
286996
+ if (key(managed) !== key(this.personalSkillsDir)) {
286997
+ await this.load(managed, "project", skills, seen, warnings, project);
286998
+ }
286999
+ }
287000
+ await this.load(this.personalSkillsDir, "personal", skills, seen, warnings);
287001
+ return { skills, projects: projects.map(({ info }) => info), warnings };
287002
+ }
287003
+ async remove(input) {
287004
+ const snapshot = await this.list();
287005
+ const item = snapshot.skills.find((candidate) => candidate.id === input.id);
287006
+ if (!item)
287007
+ throw new Error("找不到指定技能,请刷新后重试。");
287008
+ if (item.readOnly || item.source !== "project" && item.source !== "personal") {
287009
+ throw new Error("此技能来自只读目录,不能删除。");
287010
+ }
287011
+ const target = await this.secureTarget(item);
287012
+ const current = await readFile17(target, "utf8");
287013
+ if (current !== input.expectedContent)
287014
+ throw new Error("技能已在其他位置修改,请刷新后重试。");
287015
+ await unlink4(target);
287016
+ return await this.list();
287017
+ }
287018
+ async secureTarget(item) {
287019
+ const target = await realpath7(item.path);
287020
+ if (item.source === "personal") {
287021
+ await assertTarget(this.configDir, this.personalSkillsDir, target);
287022
+ return target;
287023
+ }
287024
+ if (!item.projectPath)
287025
+ throw new Error("技能缺少所属项目。");
287026
+ const project = await realpath7(item.projectPath);
287027
+ await assertTarget(project, join39(project, ".openharness-ts", "skills"), target);
287028
+ return target;
287029
+ }
287030
+ async load(directory, source, output, seen, warnings, project) {
287031
+ const loader = new SkillLoader(new SkillRegistry);
287032
+ const loaded = await loader.loadFromDirectory(directory, {
287033
+ source: source === "personal" ? "user" : "project",
287034
+ recursive: true
287035
+ });
287036
+ for (const skill of loaded) {
287037
+ try {
287038
+ const path = await realpath7(skill.path);
287039
+ if (seen.has(key(path)))
287040
+ continue;
287041
+ seen.add(key(path));
287042
+ output.push(desktopSkill({ ...skill, path }, source, project?.info));
287043
+ } catch {
287044
+ warnings.push(`无法读取技能文件:${skill.path}`);
287045
+ }
287046
+ }
287047
+ }
287048
+ }
287049
+ function createSkillManagementService(options) {
287050
+ return new SkillManagementService(options);
287051
+ }
287052
+ async function validProjects(input, warnings) {
287053
+ const projects = [];
287054
+ const seen = new Set;
287055
+ for (const project of input) {
287056
+ try {
287057
+ const root = await realpath7(resolve26(project.path));
287058
+ if (!(await stat9(root)).isDirectory() || seen.has(key(root)))
287059
+ continue;
287060
+ seen.add(key(root));
287061
+ projects.push({
287062
+ root,
287063
+ info: { name: project.name.trim() || basename12(root), path: root }
287064
+ });
287065
+ } catch {
287066
+ warnings.push(`项目不存在或不是目录:${project.path}`);
287067
+ }
287068
+ }
287069
+ return projects;
287070
+ }
287071
+ function desktopSkill(skill, source, project) {
287072
+ return {
287073
+ id: `skill_${createHash12("sha256").update(source).update("\x00").update(key(skill.path)).update("\x00").update(skill.name).digest("hex").slice(0, 24)}`,
287074
+ name: skill.name,
287075
+ description: skill.description,
287076
+ content: skill.content,
287077
+ path: skill.path,
287078
+ source,
287079
+ readOnly: source === "bundled" || source === "agent",
287080
+ ...project ? { projectPath: project.path, projectName: project.name } : {}
287081
+ };
287082
+ }
287083
+ async function assertTarget(owner, allowed, target) {
287084
+ const physicalOwner = await realpath7(owner);
287085
+ const physicalAllowed = await realpath7(allowed);
287086
+ if (!within(physicalOwner, physicalAllowed))
287087
+ throw new Error("技能目录通过符号链接指向了允许范围之外。");
287088
+ if (!within(physicalAllowed, target))
287089
+ throw new Error("技能文件位于允许范围之外。");
287090
+ }
287091
+ function within(root, target) {
287092
+ const path = relative9(root, target);
287093
+ return path !== "" && path !== ".." && !path.startsWith(`..${sep4}`) && !isAbsolute12(path);
287094
+ }
287095
+ function key(path) {
287096
+ const normalized = resolve26(path);
287097
+ return process.platform === "win32" ? normalized.toLowerCase() : normalized;
287098
+ }
287099
+ var init_skill_management_service = __esm(() => {
287100
+ init_src();
287101
+ init_src2();
287102
+ });
287103
+
286916
287104
  // ../../packages/server/src/shared/observability.ts
286917
287105
  function writeStructuredLog(event) {
286918
287106
  console.info(JSON.stringify({ timestamp: new Date().toISOString(), ...event }));
@@ -288121,7 +288309,9 @@ function createServiceRoutes(context) {
288121
288309
  if (!context.outputStyleService)
288122
288310
  return errorResponse(501, "Output style service is not configured");
288123
288311
  try {
288124
- return jsonResponse({ styles: await context.outputStyleService.list() });
288312
+ return jsonResponse({
288313
+ styles: await context.outputStyleService.list()
288314
+ });
288125
288315
  } catch (error) {
288126
288316
  return errorResponse(500, error instanceof Error ? error.message : String(error));
288127
288317
  }
@@ -288159,7 +288349,10 @@ function createServiceRoutes(context) {
288159
288349
  if (!lease)
288160
288350
  return errorResponse(409, "Cannot uninstall plugins while session runs are active");
288161
288351
  try {
288162
- const result = await context.pluginService.uninstall({ cwd, id: c.req.param("id") });
288352
+ const result = await context.pluginService.uninstall({
288353
+ cwd,
288354
+ id: c.req.param("id")
288355
+ });
288163
288356
  if (result.restartRuntimes)
288164
288357
  await context.control.closeAllRuntimes();
288165
288358
  return jsonResponse({ message: result.message });
@@ -288191,6 +288384,36 @@ function createServiceRoutes(context) {
288191
288384
  } finally {
288192
288385
  lease.release();
288193
288386
  }
288387
+ }).get("/skills", async () => {
288388
+ if (!context.skillService)
288389
+ return errorResponse(501, "Skill service is not configured");
288390
+ try {
288391
+ return jsonResponse(await context.skillService.list());
288392
+ } catch (error) {
288393
+ return errorResponse(500, error instanceof Error ? error.message : String(error));
288394
+ }
288395
+ }).delete("/skills/:id", async (c) => {
288396
+ if (!context.skillService)
288397
+ return errorResponse(501, "Skill service is not configured");
288398
+ const lease = context.control.acquireGlobalMutation();
288399
+ if (!lease)
288400
+ return errorResponse(409, "Cannot remove skills while session runs are active");
288401
+ try {
288402
+ const body = await readJson(c);
288403
+ if (typeof body.expectedContent !== "string") {
288404
+ return errorResponse(400, "expectedContent is required");
288405
+ }
288406
+ const result = await context.skillService.remove({
288407
+ id: c.req.param("id"),
288408
+ expectedContent: body.expectedContent
288409
+ });
288410
+ await context.control.closeAllRuntimes();
288411
+ return jsonResponse(result);
288412
+ } catch (error) {
288413
+ return errorResponse(400, error instanceof Error ? error.message : String(error));
288414
+ } finally {
288415
+ lease.release();
288416
+ }
288194
288417
  }).get("/agent-personas", async () => {
288195
288418
  if (!context.agentPersonaService)
288196
288419
  return errorResponse(501, "Agent persona service is not configured");
@@ -288207,7 +288430,10 @@ function createServiceRoutes(context) {
288207
288430
  return errorResponse(400, "cwd is required");
288208
288431
  const sessionId = c.req.query("sessionId") ?? undefined;
288209
288432
  try {
288210
- const listed = await context.hooksService.list({ cwd, ...sessionId ? { sessionId } : {} });
288433
+ const listed = await context.hooksService.list({
288434
+ cwd,
288435
+ ...sessionId ? { sessionId } : {}
288436
+ });
288211
288437
  const hooks = [...listed.hooks];
288212
288438
  if (sessionId && context.control.runtimeInspectionAvailable) {
288213
288439
  if (!context.control.sessionExists(sessionId)) {
@@ -288263,7 +288489,13 @@ async function installLocalPlugin(context, c, link) {
288263
288489
  if (!lease)
288264
288490
  return errorResponse(409, "Cannot install plugins while session runs are active");
288265
288491
  try {
288266
- const result = await context.pluginService.installLocal({ cwd, sourcePath, scope, approvedPermissions, link });
288492
+ const result = await context.pluginService.installLocal({
288493
+ cwd,
288494
+ sourcePath,
288495
+ scope,
288496
+ approvedPermissions,
288497
+ link
288498
+ });
288267
288499
  if (result.restartRuntimes)
288268
288500
  await context.control.closeAllRuntimes();
288269
288501
  return jsonResponse({ message: result.message });
@@ -289615,6 +289847,7 @@ class OpenHarnessHttpServer {
289615
289847
  outputStyleService: this.services.outputStyle,
289616
289848
  projectInitService: this.services.projectInit,
289617
289849
  pluginService: this.services.plugin,
289850
+ skillService: this.services.skill ?? createSkillManagementService({ projects: this.application.projects }),
289618
289851
  agentPersonaService: this.services.agentPersona,
289619
289852
  hooksService: this.services.hooks,
289620
289853
  control: this.application.control
@@ -289680,6 +289913,7 @@ var init_server = __esm(() => {
289680
289913
  init_dist2();
289681
289914
  init_dist3();
289682
289915
  init_default_node_application();
289916
+ init_skill_management_service();
289683
289917
  init_support2();
289684
289918
  init_auth();
289685
289919
  init_attachment4();
@@ -289896,10 +290130,10 @@ var init_auth_service = __esm(() => {
289896
290130
 
289897
290131
  // ../../packages/output-styles/src/index.ts
289898
290132
  import { readdirSync as readdirSync6, readFileSync as readFileSync14, mkdirSync as mkdirSync15 } from "node:fs";
289899
- import { join as join39 } from "node:path";
290133
+ import { join as join40 } from "node:path";
289900
290134
  import { homedir as homedir11 } from "node:os";
289901
290135
  function getOutputStylesDir() {
289902
- const dir = join39(homedir11(), ".openharness-ts", "output_styles");
290136
+ const dir = join40(homedir11(), ".openharness-ts", "output_styles");
289903
290137
  try {
289904
290138
  mkdirSync15(dir, { recursive: true });
289905
290139
  } catch {}
@@ -289916,7 +290150,7 @@ function loadOutputStyles() {
289916
290150
  }
289917
290151
  for (const file of files) {
289918
290152
  try {
289919
- const content = readFileSync14(join39(dir, file), "utf-8");
290153
+ const content = readFileSync14(join40(dir, file), "utf-8");
289920
290154
  styles.push({ name: file.replace(/\.md$/, ""), content, source: "user" });
289921
290155
  } catch {}
289922
290156
  }
@@ -290575,14 +290809,14 @@ var init_profile_service = __esm(() => {
290575
290809
  });
290576
290810
 
290577
290811
  // ../../packages/server/src/application/default-services/project-init-service.ts
290578
- import { join as join40 } from "node:path";
290812
+ import { join as join41 } from "node:path";
290579
290813
  function createDefaultProjectInitService() {
290580
290814
  return {
290581
290815
  async init({ cwd }) {
290582
290816
  const { writeFile, mkdir, access } = await import("node:fs/promises");
290583
290817
  const files = [
290584
290818
  {
290585
- path: join40(cwd, "CLAUDE.md"),
290819
+ path: join41(cwd, "CLAUDE.md"),
290586
290820
  content: `# Project Rules
290587
290821
 
290588
290822
  Add your project-specific rules and instructions here.
@@ -290590,7 +290824,7 @@ Add your project-specific rules and instructions here.
290590
290824
  label: "CLAUDE.md"
290591
290825
  },
290592
290826
  {
290593
- path: join40(cwd, PROJECT_CONFIG_DIR_NAME, "README.md"),
290827
+ path: join41(cwd, PROJECT_CONFIG_DIR_NAME, "README.md"),
290594
290828
  content: `# OpenHarness Config
290595
290829
 
290596
290830
  This directory contains OpenHarness project configuration.
@@ -290598,7 +290832,7 @@ This directory contains OpenHarness project configuration.
290598
290832
  label: `${PROJECT_CONFIG_DIR_NAME}/README.md`
290599
290833
  },
290600
290834
  {
290601
- path: join40(cwd, PROJECT_CONFIG_DIR_NAME, "memory", "MEMORY.md"),
290835
+ path: join41(cwd, PROJECT_CONFIG_DIR_NAME, "memory", "MEMORY.md"),
290602
290836
  content: `# Memory
290603
290837
 
290604
290838
  This file stores project memory for the AI assistant.
@@ -290607,10 +290841,10 @@ This file stores project memory for the AI assistant.
290607
290841
  }
290608
290842
  ];
290609
290843
  const dirs = [
290610
- join40(cwd, PROJECT_CONFIG_DIR_NAME),
290611
- join40(cwd, PROJECT_CONFIG_DIR_NAME, "memory"),
290612
- join40(cwd, PROJECT_CONFIG_DIR_NAME, "plugins"),
290613
- join40(cwd, PROJECT_CONFIG_DIR_NAME, "skills")
290844
+ join41(cwd, PROJECT_CONFIG_DIR_NAME),
290845
+ join41(cwd, PROJECT_CONFIG_DIR_NAME, "memory"),
290846
+ join41(cwd, PROJECT_CONFIG_DIR_NAME, "plugins"),
290847
+ join41(cwd, PROJECT_CONFIG_DIR_NAME, "skills")
290614
290848
  ];
290615
290849
  const lines = ["Initializing OpenHarness project...", ""];
290616
290850
  for (const dir of dirs) {
@@ -291041,6 +291275,7 @@ var init_application = __esm(() => {
291041
291275
  init_support();
291042
291276
  init_events2();
291043
291277
  init_project_application_service();
291278
+ init_skill_management_service();
291044
291279
  init_channel3();
291045
291280
  init_application_backup();
291046
291281
  init_application_retention_service();
@@ -291082,7 +291317,7 @@ var init_src23 = __esm(() => {
291082
291317
  });
291083
291318
 
291084
291319
  // src/ensure-daemon.ts
291085
- import { stat as stat9 } from "node:fs/promises";
291320
+ import { stat as stat10 } from "node:fs/promises";
291086
291321
  async function ensureLocalDaemon(options = {}) {
291087
291322
  const cliPath = options.cliPath ?? process.argv[1];
291088
291323
  if (!cliPath)
@@ -291090,7 +291325,7 @@ async function ensureLocalDaemon(options = {}) {
291090
291325
  const expectedVersion = options.expectedVersion ?? VERSION;
291091
291326
  const daemonProbeOptions = {
291092
291327
  expectedVersion,
291093
- minimumStartedAt: (await stat9(cliPath)).mtimeMs
291328
+ minimumStartedAt: (await stat10(cliPath)).mtimeMs
291094
291329
  };
291095
291330
  await Promise.resolve().then(() => init_src23());
291096
291331
  const waitForDaemonRegistry = async (spawned) => {
@@ -370332,13 +370567,13 @@ function createMcpCommand() {
370332
370567
  // src/commands/plugin.ts
370333
370568
  init_src15();
370334
370569
  init_src12();
370335
- import { join as join46, resolve as resolve28 } from "node:path";
370570
+ import { join as join47, resolve as resolve29 } from "node:path";
370336
370571
  import { mkdtemp as mkdtemp3, rm as rm8 } from "node:fs/promises";
370337
370572
  import { tmpdir as tmpdir5 } from "node:os";
370338
370573
  // ../../packages/plugin-converters/src/core/digest.ts
370339
- import { createHash as createHash12 } from "node:crypto";
370340
- import { readFile as readFile17, readdir as readdir9 } from "node:fs/promises";
370341
- import { join as join41, relative as relative9 } from "node:path";
370574
+ import { createHash as createHash13 } from "node:crypto";
370575
+ import { readFile as readFile18, readdir as readdir9 } from "node:fs/promises";
370576
+ import { join as join43, relative as relative10 } from "node:path";
370342
370577
  function stable(value) {
370343
370578
  if (Array.isArray(value))
370344
370579
  return `[${value.map(stable).join(",")}]`;
@@ -370347,14 +370582,14 @@ function stable(value) {
370347
370582
  return JSON.stringify(value);
370348
370583
  }
370349
370584
  function digestValue(value) {
370350
- return createHash12("sha256").update(stable(value)).digest("hex");
370585
+ return createHash13("sha256").update(stable(value)).digest("hex");
370351
370586
  }
370352
370587
  async function files(root, dir = root) {
370353
370588
  const out = [];
370354
370589
  for (const entry of (await readdir9(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
370355
- const full = join41(dir, entry.name);
370590
+ const full = join43(dir, entry.name);
370356
370591
  if (entry.isSymbolicLink())
370357
- throw new Error(`Source symlink is not allowed: ${relative9(root, full)}`);
370592
+ throw new Error(`Source symlink is not allowed: ${relative10(root, full)}`);
370358
370593
  if (entry.isDirectory())
370359
370594
  out.push(...await files(root, full));
370360
370595
  else if (entry.isFile())
@@ -370363,11 +370598,11 @@ async function files(root, dir = root) {
370363
370598
  return out;
370364
370599
  }
370365
370600
  async function digestSource(root) {
370366
- const hash = createHash12("sha256");
370601
+ const hash = createHash13("sha256");
370367
370602
  for (const file of await files(root)) {
370368
- hash.update(relative9(root, file).replaceAll("\\", "/"));
370603
+ hash.update(relative10(root, file).replaceAll("\\", "/"));
370369
370604
  hash.update("\x00");
370370
- hash.update(await readFile17(file));
370605
+ hash.update(await readFile18(file));
370371
370606
  hash.update("\x00");
370372
370607
  }
370373
370608
  return hash.digest("hex");
@@ -370411,22 +370646,22 @@ class ConverterRegistry {
370411
370646
  }
370412
370647
  // ../../packages/plugin-converters/src/claude-code/detector.ts
370413
370648
  import { access as access6 } from "node:fs/promises";
370414
- import { join as join43 } from "node:path";
370649
+ import { join as join44 } from "node:path";
370415
370650
  var exists4 = async (path) => access6(path).then(() => true, () => false);
370416
370651
  async function detectClaudeCodePlugin(root) {
370417
370652
  const evidence = [];
370418
- if (await exists4(join43(root, ".claude-plugin", "plugin.json")))
370653
+ if (await exists4(join44(root, ".claude-plugin", "plugin.json")))
370419
370654
  evidence.push(".claude-plugin/plugin.json");
370420
370655
  for (const name of ["skills", "commands", "agents", "hooks", ".mcp.json", "SKILL.md"])
370421
- if (await exists4(join43(root, name)))
370656
+ if (await exists4(join44(root, name)))
370422
370657
  evidence.push(name);
370423
- if (!evidence.length || evidence.length === 1 && evidence[0] === "SKILL.md" && !await exists4(join43(root, "SKILL.md")))
370658
+ if (!evidence.length || evidence.length === 1 && evidence[0] === "SKILL.md" && !await exists4(join44(root, "SKILL.md")))
370424
370659
  return null;
370425
370660
  return { converterId: "claude-code", confidence: evidence.includes(".claude-plugin/plugin.json") ? 1 : 0.7, evidence };
370426
370661
  }
370427
370662
  // ../../packages/plugin-converters/src/claude-code/parser.ts
370428
- import { access as access7, lstat as lstat6, readFile as readFile18, readdir as readdir10 } from "node:fs/promises";
370429
- import { basename as basename12, isAbsolute as isAbsolute12, join as join44, relative as relative10, resolve as resolve26 } from "node:path";
370663
+ import { access as access7, lstat as lstat6, readFile as readFile19, readdir as readdir10 } from "node:fs/promises";
370664
+ import { basename as basename13, isAbsolute as isAbsolute13, join as join45, relative as relative11, resolve as resolve27 } from "node:path";
370430
370665
  var exists5 = async (path) => access7(path).then(() => true, () => false);
370431
370666
  async function collect(root, path, extensions) {
370432
370667
  if (!await exists5(path))
@@ -370440,7 +370675,7 @@ async function collect(root, path, extensions) {
370440
370675
  for (const entry of (await readdir10(path, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
370441
370676
  if (entry.isSymbolicLink())
370442
370677
  throw new Error(`Claude source symlink is not allowed: ${entry.name}`);
370443
- const full = join44(path, entry.name);
370678
+ const full = join45(path, entry.name);
370444
370679
  if (entry.isDirectory())
370445
370680
  result.push(...await collect(root, full, extensions));
370446
370681
  else if (!extensions || extensions.some((x) => entry.name.toLowerCase().endsWith(x)))
@@ -370450,31 +370685,31 @@ async function collect(root, path, extensions) {
370450
370685
  }
370451
370686
  var asPaths = (value) => typeof value === "string" ? [value] : Array.isArray(value) && value.every((x) => typeof x === "string") ? value : [];
370452
370687
  function safe(root, value) {
370453
- const target = resolve26(root, value);
370454
- const rel = relative10(resolve26(root), target);
370455
- if (rel.startsWith("..") || isAbsolute12(rel) || target === resolve26(root))
370688
+ const target = resolve27(root, value);
370689
+ const rel = relative11(resolve27(root), target);
370690
+ if (rel.startsWith("..") || isAbsolute13(rel) || target === resolve27(root))
370456
370691
  throw new Error(`Claude component path escapes source: ${value}`);
370457
370692
  return target;
370458
370693
  }
370459
370694
  async function inspectClaudeCodePlugin(rootInput) {
370460
- const root = resolve26(rootInput);
370695
+ const root = resolve27(rootInput);
370461
370696
  let manifest = {};
370462
- const manifestPath = join44(root, ".claude-plugin", "plugin.json");
370697
+ const manifestPath = join45(root, ".claude-plugin", "plugin.json");
370463
370698
  if (await exists5(manifestPath))
370464
- manifest = JSON.parse(await readFile18(manifestPath, "utf8"));
370465
- const name = typeof manifest.name === "string" ? manifest.name : basename12(root).toLowerCase().replace(/[^a-z0-9-]+/g, "-");
370699
+ manifest = JSON.parse(await readFile19(manifestPath, "utf8"));
370700
+ const name = typeof manifest.name === "string" ? manifest.name : basename13(root).toLowerCase().replace(/[^a-z0-9-]+/g, "-");
370466
370701
  const inventory = {};
370467
- const skillRoots = [join44(root, "skills"), ...asPaths(manifest.skills).map((x) => safe(root, x))];
370468
- if (await exists5(join44(root, "SKILL.md")))
370469
- skillRoots.push(join44(root, "SKILL.md"));
370702
+ const skillRoots = [join45(root, "skills"), ...asPaths(manifest.skills).map((x) => safe(root, x))];
370703
+ if (await exists5(join45(root, "SKILL.md")))
370704
+ skillRoots.push(join45(root, "SKILL.md"));
370470
370705
  inventory.skills = (await Promise.all(skillRoots.map((x) => collect(root, x, ["skill.md"])))).flat();
370471
370706
  for (const kind of ["commands", "agents"]) {
370472
370707
  const custom = asPaths(manifest[kind]);
370473
- const roots = custom.length ? custom.map((x) => safe(root, x)) : [join44(root, kind)];
370708
+ const roots = custom.length ? custom.map((x) => safe(root, x)) : [join45(root, kind)];
370474
370709
  inventory[kind] = (await Promise.all(roots.map((x) => collect(root, x, [".md"])))).flat();
370475
370710
  }
370476
- const hooks = join44(root, "hooks", "hooks.json");
370477
- const mcp = join44(root, ".mcp.json");
370711
+ const hooks = join45(root, "hooks", "hooks.json");
370712
+ const mcp = join45(root, ".mcp.json");
370478
370713
  inventory.hooks = await exists5(hooks) ? [hooks] : [];
370479
370714
  inventory.mcpServers = await exists5(mcp) ? [mcp] : [];
370480
370715
  return { root, format: "claude-code", identity: { id: `converted.claude.${name}`, name, version: typeof manifest.version === "string" ? manifest.version : "0.0.0" }, inventory, diagnostics: [] };
@@ -370584,34 +370819,34 @@ function convertClaudeAgentMarkdown(content) {
370584
370819
  // ../../packages/plugin-converters/src/claude-code/converter.ts
370585
370820
  init_src12();
370586
370821
  import { randomUUID as randomUUID27 } from "node:crypto";
370587
- import { access as access8, cp as cp3, mkdir as mkdir14, readFile as readFile19, rename as rename4, rm as rm7, writeFile as writeFile11 } from "node:fs/promises";
370588
- import { basename as basename13, dirname as dirname20, join as join45, relative as relative11, resolve as resolve27 } from "node:path";
370589
- var rel = (inspection, path) => relative11(inspection.root, path).replaceAll("\\", "/");
370822
+ import { access as access8, cp as cp3, mkdir as mkdir14, readFile as readFile20, rename as rename4, rm as rm7, writeFile as writeFile11 } from "node:fs/promises";
370823
+ import { basename as basename14, dirname as dirname21, join as join46, relative as relative12, resolve as resolve28 } from "node:path";
370824
+ var rel = (inspection, path) => relative12(inspection.root, path).replaceAll("\\", "/");
370590
370825
  function componentPath(inspection, sourcePath, directory) {
370591
370826
  const parts = rel(inspection, sourcePath).split("/");
370592
370827
  const directoryIndex = parts.indexOf(directory);
370593
370828
  return (directoryIndex >= 0 ? parts.slice(directoryIndex + 1) : parts).join("/");
370594
370829
  }
370595
370830
  async function copySkillBundle(inspection, skillFile, targetRoot) {
370596
- const sourceDirectory = dirname20(skillFile);
370597
- const relativeDirectory = relative11(inspection.root, sourceDirectory);
370598
- const targetRelative = relativeDirectory === "" ? inspection.identity.name : dirname20(componentPath(inspection, skillFile, "skills"));
370599
- const targetDirectory = join45(targetRoot, targetRelative === "." ? inspection.identity.name : targetRelative);
370831
+ const sourceDirectory = dirname21(skillFile);
370832
+ const relativeDirectory = relative12(inspection.root, sourceDirectory);
370833
+ const targetRelative = relativeDirectory === "" ? inspection.identity.name : dirname21(componentPath(inspection, skillFile, "skills"));
370834
+ const targetDirectory = join46(targetRoot, targetRelative === "." ? inspection.identity.name : targetRelative);
370600
370835
  if (sourceDirectory !== inspection.root) {
370601
370836
  await cp3(sourceDirectory, targetDirectory, { recursive: true, errorOnExist: true, force: false });
370602
370837
  return;
370603
370838
  }
370604
370839
  await mkdir14(targetDirectory, { recursive: true });
370605
- await cp3(skillFile, join45(targetDirectory, "SKILL.md"), { errorOnExist: true, force: false });
370840
+ await cp3(skillFile, join46(targetDirectory, "SKILL.md"), { errorOnExist: true, force: false });
370606
370841
  for (const resourceDirectory of ["assets", "references", "scripts"]) {
370607
- const sourceResource = join45(sourceDirectory, resourceDirectory);
370842
+ const sourceResource = join46(sourceDirectory, resourceDirectory);
370608
370843
  if (await access8(sourceResource).then(() => true, () => false)) {
370609
- await cp3(sourceResource, join45(targetDirectory, resourceDirectory), { recursive: true, errorOnExist: true, force: false });
370844
+ await cp3(sourceResource, join46(targetDirectory, resourceDirectory), { recursive: true, errorOnExist: true, force: false });
370610
370845
  }
370611
370846
  }
370612
370847
  }
370613
370848
  async function convertHooks(source, target) {
370614
- const raw = JSON.parse(await readFile19(source, "utf8"));
370849
+ const raw = JSON.parse(await readFile20(source, "utf8"));
370615
370850
  const rows = raw.hooks && typeof raw.hooks === "object" ? raw.hooks : raw;
370616
370851
  const output = {};
370617
370852
  for (const [sourceEvent, entries] of Object.entries(rows)) {
@@ -370628,12 +370863,12 @@ async function convertHooks(source, target) {
370628
370863
  }
370629
370864
  if (!Object.keys(output).length)
370630
370865
  return false;
370631
- await mkdir14(dirname20(target), { recursive: true });
370866
+ await mkdir14(dirname21(target), { recursive: true });
370632
370867
  await writeFile11(target, JSON.stringify(output, null, 2));
370633
370868
  return true;
370634
370869
  }
370635
370870
  async function convertMcp(source, target) {
370636
- const raw = JSON.parse(await readFile19(source, "utf8"));
370871
+ const raw = JSON.parse(await readFile20(source, "utf8"));
370637
370872
  const servers = {};
370638
370873
  for (const [name, value] of Object.entries(raw.mcpServers ?? {})) {
370639
370874
  if (typeof value.command === "string")
@@ -370643,7 +370878,7 @@ async function convertMcp(source, target) {
370643
370878
  else
370644
370879
  throw new Error(`Ambiguous MCP server: ${name}`);
370645
370880
  }
370646
- await mkdir14(dirname20(target), { recursive: true });
370881
+ await mkdir14(dirname21(target), { recursive: true });
370647
370882
  await writeFile11(target, JSON.stringify({ servers }, null, 2));
370648
370883
  }
370649
370884
 
@@ -370668,7 +370903,7 @@ class ClaudeCodePluginConverter {
370668
370903
  });
370669
370904
  }
370670
370905
  for (const hookFile of inspection.inventory.hooks ?? []) {
370671
- const raw = JSON.parse(await readFile19(hookFile, "utf8"));
370906
+ const raw = JSON.parse(await readFile20(hookFile, "utf8"));
370672
370907
  const rows = raw.hooks && typeof raw.hooks === "object" ? raw.hooks : raw;
370673
370908
  if (Object.keys(rows).some((event) => CLAUDE_HOOK_EVENT_MAP[event])) {
370674
370909
  items.push({
@@ -370707,7 +370942,7 @@ class ClaudeCodePluginConverter {
370707
370942
  throw new Error(`Blocked conversion items require approval: ${blocked.map((x) => x.id).join(", ")}`);
370708
370943
  if (await digestSource(input.inspection.root) !== input.plan.sourceDigest)
370709
370944
  throw new Error("Source changed after conversion planning; inspect and plan again");
370710
- const output = resolve27(input.output);
370945
+ const output = resolve28(input.output);
370711
370946
  if (await access8(output).then(() => true, () => false))
370712
370947
  throw new Error(`Conversion output already exists: ${output}`);
370713
370948
  const temporary = `${output}.tmp-${randomUUID27()}`;
@@ -370717,31 +370952,31 @@ class ClaudeCodePluginConverter {
370717
370952
  const components = {};
370718
370953
  const skills = input.inspection.inventory.skills ?? [];
370719
370954
  for (const skill of skills) {
370720
- await copySkillBundle(input.inspection, skill, join45(temporary, "skills"));
370955
+ await copySkillBundle(input.inspection, skill, join46(temporary, "skills"));
370721
370956
  }
370722
370957
  const commands = input.inspection.inventory.commands ?? [];
370723
370958
  for (const command of commands) {
370724
- const name = basename13(command, ".md");
370725
- const target = join45(temporary, "skills", name, "SKILL.md");
370726
- await mkdir14(dirname20(target), { recursive: true });
370727
- await writeFile11(target, await readFile19(command, "utf8"));
370959
+ const name = basename14(command, ".md");
370960
+ const target = join46(temporary, "skills", name, "SKILL.md");
370961
+ await mkdir14(dirname21(target), { recursive: true });
370962
+ await writeFile11(target, await readFile20(command, "utf8"));
370728
370963
  }
370729
370964
  if (skills.length || commands.length)
370730
370965
  components.skills = ["./skills"];
370731
370966
  const agents = input.inspection.inventory.agents ?? [];
370732
370967
  for (const agent of agents) {
370733
- const target = join45(temporary, "agents", componentPath(input.inspection, agent, "agents"));
370734
- await mkdir14(dirname20(target), { recursive: true });
370735
- await writeFile11(target, convertClaudeAgentMarkdown(await readFile19(agent, "utf8")));
370968
+ const target = join46(temporary, "agents", componentPath(input.inspection, agent, "agents"));
370969
+ await mkdir14(dirname21(target), { recursive: true });
370970
+ await writeFile11(target, convertClaudeAgentMarkdown(await readFile20(agent, "utf8")));
370736
370971
  }
370737
370972
  if (agents.length)
370738
370973
  components.agents = ["./agents"];
370739
370974
  const hooks = input.inspection.inventory.hooks?.[0];
370740
- if (hooks && await convertHooks(hooks, join45(temporary, "hooks.json")))
370975
+ if (hooks && await convertHooks(hooks, join46(temporary, "hooks.json")))
370741
370976
  components.hooks = ["./hooks.json"];
370742
370977
  const mcp = input.inspection.inventory.mcpServers?.[0];
370743
370978
  if (mcp) {
370744
- await convertMcp(mcp, join45(temporary, "mcp.json"));
370979
+ await convertMcp(mcp, join46(temporary, "mcp.json"));
370745
370980
  components.mcpServers = ["./mcp.json"];
370746
370981
  }
370747
370982
  if (!Object.keys(components).length)
@@ -370754,13 +370989,13 @@ class ClaudeCodePluginConverter {
370754
370989
  metadata: { origin: "converted", sourceFormat: this.sourceFormat, converterId: this.id, converterVersion: this.version },
370755
370990
  components
370756
370991
  };
370757
- await mkdir14(join45(temporary, ".openharness-plugin"));
370758
- await writeFile11(join45(temporary, ".openharness-plugin", "plugin.json"), JSON.stringify(manifest, null, 2));
370992
+ await mkdir14(join46(temporary, ".openharness-plugin"));
370993
+ await writeFile11(join46(temporary, ".openharness-plugin", "plugin.json"), JSON.stringify(manifest, null, 2));
370759
370994
  const report = { schemaVersion: 1, status: input.plan.items.some((x) => x.fidelity === "unsupported") ? "partial" : "success", items: input.plan.items, diagnostics: input.plan.diagnostics };
370760
- await mkdir14(join45(temporary, ".openharness-conversion"));
370761
- await writeFile11(join45(temporary, ".openharness-conversion", "plan.json"), JSON.stringify(input.plan, null, 2));
370762
- await writeFile11(join45(temporary, ".openharness-conversion", "report.json"), JSON.stringify(report, null, 2));
370763
- await writeFile11(join45(temporary, ".openharness-conversion", "provenance.json"), JSON.stringify({ sourceFormat: this.sourceFormat, sourceDigest: input.plan.sourceDigest, converterId: this.id, converterVersion: this.version, mappingVersion: CLAUDE_MAPPING_VERSION }, null, 2));
370995
+ await mkdir14(join46(temporary, ".openharness-conversion"));
370996
+ await writeFile11(join46(temporary, ".openharness-conversion", "plan.json"), JSON.stringify(input.plan, null, 2));
370997
+ await writeFile11(join46(temporary, ".openharness-conversion", "report.json"), JSON.stringify(report, null, 2));
370998
+ await writeFile11(join46(temporary, ".openharness-conversion", "provenance.json"), JSON.stringify({ sourceFormat: this.sourceFormat, sourceDigest: input.plan.sourceDigest, converterId: this.id, converterVersion: this.version, mappingVersion: CLAUDE_MAPPING_VERSION }, null, 2));
370764
370999
  const validation = await validateNativePlugin(temporary);
370765
371000
  if (validation.status !== "valid")
370766
371001
  throw new Error(validation.diagnostics.map((x) => x.message).join("; "));
@@ -370856,11 +371091,11 @@ function formatPluginList(result, verbose = false) {
370856
371091
  function createPluginCommand() {
370857
371092
  const cmd = new Command3("plugin").description("Manage Native Plugins");
370858
371093
  cmd.command("list").option("--cwd <path>").option("--verbose", "show permissions, contributions, runtime, and diagnostics").option("--json", "print the complete machine-readable response").action(async (options) => {
370859
- const result = await (await client()).listPlugins({ cwd: resolve28(options.cwd ?? process.cwd()) });
371094
+ const result = await (await client()).listPlugins({ cwd: resolve29(options.cwd ?? process.cwd()) });
370860
371095
  console.log(options.json ? JSON.stringify(result, null, 2) : formatPluginList(result, options.verbose));
370861
371096
  });
370862
371097
  cmd.command("validate").argument("<path>").action(async (path) => {
370863
- const result = await validateNativePlugin(resolve28(path));
371098
+ const result = await validateNativePlugin(resolve29(path));
370864
371099
  if (result.status === "valid")
370865
371100
  console.log(`Valid Native Plugin: ${result.plugin.manifest.id}@${result.plugin.manifest.version}`);
370866
371101
  else {
@@ -370871,7 +371106,7 @@ function createPluginCommand() {
370871
371106
  });
370872
371107
  for (const [name, link] of [["install-local", false], ["link", true]]) {
370873
371108
  cmd.command(name).argument("<path>").option("--cwd <path>").option("--approve <permission>", "approve a requested permission", collect2, []).action(async (path, options) => {
370874
- const sourcePath = resolve28(path);
371109
+ const sourcePath = resolve29(path);
370875
371110
  const validation = await validateNativePlugin(sourcePath);
370876
371111
  if (!validation.plugin)
370877
371112
  throw new Error(validation.diagnostics.map((item) => item.message).join("; "));
@@ -370881,7 +371116,7 @@ function createPluginCommand() {
370881
371116
  if (missing.length)
370882
371117
  throw new Error(`Explicit approval required: ${missing.join(", ")}`);
370883
371118
  const result = await (await client()).installLocalPlugin({
370884
- cwd: resolve28(options.cwd ?? process.cwd()),
371119
+ cwd: resolve29(options.cwd ?? process.cwd()),
370885
371120
  sourcePath,
370886
371121
  scope: "user",
370887
371122
  approvedPermissions: approved,
@@ -370893,25 +371128,25 @@ function createPluginCommand() {
370893
371128
  for (const action of ["enable", "disable"])
370894
371129
  cmd.command(action).argument("<id>").option("--cwd <path>").action(async (id, options) => {
370895
371130
  const api = await client();
370896
- const input = { cwd: resolve28(options.cwd ?? process.cwd()) };
371131
+ const input = { cwd: resolve29(options.cwd ?? process.cwd()) };
370897
371132
  console.log((action === "enable" ? await api.enablePlugin(id, input) : await api.disablePlugin(id, input)).message);
370898
371133
  });
370899
371134
  cmd.command("uninstall").argument("<id>").option("--cwd <path>").action(async (id, options) => {
370900
- console.log((await (await client()).uninstallPlugin(id, { cwd: resolve28(options.cwd ?? process.cwd()) })).message);
371135
+ console.log((await (await client()).uninstallPlugin(id, { cwd: resolve29(options.cwd ?? process.cwd()) })).message);
370901
371136
  });
370902
371137
  cmd.command("details").argument("<id>").option("--cwd <path>").action(async (id, options) => {
370903
- const listed = await (await client()).listPlugins({ cwd: resolve28(options.cwd ?? process.cwd()) });
371138
+ const listed = await (await client()).listPlugins({ cwd: resolve29(options.cwd ?? process.cwd()) });
370904
371139
  const plugin = listed.plugins.find((item) => item.identity.id === id);
370905
371140
  if (!plugin)
370906
371141
  throw new Error(`Plugin not found: ${id}`);
370907
371142
  console.log(JSON.stringify(plugin, null, 2));
370908
371143
  });
370909
371144
  cmd.command("install").argument("<source>").requiredOption("--from <converter>").option("--cwd <path>").option("--approve <item>", "approve conversion item or permission", collect2, []).action(async (source, options) => {
370910
- const temporaryRoot = await mkdtemp3(join46(tmpdir5(), "ohs-plugin-import-"));
370911
- const output = join46(temporaryRoot, "native");
371145
+ const temporaryRoot = await mkdtemp3(join47(tmpdir5(), "ohs-plugin-import-"));
371146
+ const output = join47(temporaryRoot, "native");
370912
371147
  try {
370913
- const { converter } = await createBuiltinConverterRegistry().detect(resolve28(source), options.from);
370914
- const inspection = await converter.inspect(resolve28(source));
371148
+ const { converter } = await createBuiltinConverterRegistry().detect(resolve29(source), options.from);
371149
+ const inspection = await converter.inspect(resolve29(source));
370915
371150
  const plan = await converter.plan(inspection, {});
370916
371151
  await converter.convert({ inspection, plan, output, approvals: options.approve });
370917
371152
  const validation = await validateNativePlugin(output);
@@ -370922,7 +371157,7 @@ function createPluginCommand() {
370922
371157
  if (missing.length)
370923
371158
  throw new Error(`Explicit permission approval required: ${missing.join(", ")}`);
370924
371159
  const result = await (await client()).installLocalPlugin({
370925
- cwd: resolve28(options.cwd ?? process.cwd()),
371160
+ cwd: resolve29(options.cwd ?? process.cwd()),
370926
371161
  sourcePath: output,
370927
371162
  scope: "user",
370928
371163
  approvedPermissions: requested
@@ -370934,8 +371169,8 @@ function createPluginCommand() {
370934
371169
  });
370935
371170
  cmd.command("convert").argument("<source>").option("--from <converter>").option("--output <path>").option("--dry-run").option("--json").option("--approve <item>", "approve a blocked conversion item", collect2, []).action(async (source, options) => {
370936
371171
  const registry = createBuiltinConverterRegistry();
370937
- const { converter, detection } = await registry.detect(resolve28(source), options.from);
370938
- const inspection = await converter.inspect(resolve28(source));
371172
+ const { converter, detection } = await registry.detect(resolve29(source), options.from);
371173
+ const inspection = await converter.inspect(resolve29(source));
370939
371174
  const plan = await converter.plan(inspection, {});
370940
371175
  if (options.dryRun) {
370941
371176
  console.log(options.json ? JSON.stringify({ detection, inspection, plan }, null, 2) : plan.items.map((item) => `${item.fidelity.padEnd(11)} ${item.id}`).join(`
@@ -370944,7 +371179,7 @@ function createPluginCommand() {
370944
371179
  }
370945
371180
  if (!options.output)
370946
371181
  throw new Error("--output is required unless --dry-run is used");
370947
- const report = await converter.convert({ inspection, plan, output: resolve28(options.output), approvals: options.approve });
371182
+ const report = await converter.convert({ inspection, plan, output: resolve29(options.output), approvals: options.approve });
370948
371183
  console.log(options.json ? JSON.stringify(report, null, 2) : `Converted ${inspection.identity.id}: ${report.status}`);
370949
371184
  });
370950
371185
  return cmd;
@@ -371461,7 +371696,7 @@ function createSandboxCommand() {
371461
371696
  init_src3();
371462
371697
  init_src9();
371463
371698
  import { readFileSync as readFileSync15 } from "node:fs";
371464
- import { resolve as resolve29 } from "node:path";
371699
+ import { resolve as resolve30 } from "node:path";
371465
371700
  import { Command as Command8 } from "commander";
371466
371701
  function createWorkflowCommand() {
371467
371702
  const cmd = new Command8("workflow").description("Inspect and manage persisted workflow runs");
@@ -371618,7 +371853,7 @@ function readJsonOption(path, inlineJson) {
371618
371853
  if (inlineJson)
371619
371854
  return JSON.parse(inlineJson);
371620
371855
  if (path)
371621
- return JSON.parse(readFileSync15(resolve29(path), "utf-8"));
371856
+ return JSON.parse(readFileSync15(resolve30(path), "utf-8"));
371622
371857
  return;
371623
371858
  }
371624
371859
  function parseCsv(value) {
@@ -372215,4 +372450,4 @@ program.command("doctor").description("Check environment and dependencies").acti
372215
372450
  });
372216
372451
  program.parse();
372217
372452
 
372218
- //# debugId=2D32AB0B747CF29E64756E2164756E21
372453
+ //# debugId=A30D9095E02E07FA64756E2164756E21