{
  "version": 3,
  "sources": ["../node_modules/commander/lib/error.js", "../node_modules/commander/lib/argument.js", "../node_modules/commander/lib/help.js", "../node_modules/commander/lib/option.js", "../node_modules/commander/lib/suggestSimilar.js", "../node_modules/commander/lib/command.js", "../node_modules/commander/index.js", "../node_modules/commander/esm.mjs", "../src/profile/detect.ts", "../src/profile/paths.ts", "../src/profile/runtime-paths.ts", "../src/i18n/locale.ts", "../src/i18n/messages/en-US.ts", "../src/i18n/messages/zh-CN.ts", "../src/i18n/messages/index.ts", "../src/env.ts", "../src/i18n/translate.ts", "../src/auth/credentials.ts", "../src/fs-atomic.ts", "../src/i18n/skills-path.ts", "../src/i18n/response-locale.ts", "../src/cli/auth.ts", "../src/cli/helpers.ts", "../src/notification/app-name-map.ts", "../src/recording/time.ts", "../src/cli/ntf-query.ts", "../src/cli/ntf-search.ts", "../src/cli/ntf-summary.ts", "../src/cli/ntf-summary-job.ts", "../src/cli/ntf-stats.ts", "../src/cli/ntf-sync.ts", "../src/cli/ntf-monitor.ts", "../src/monitor/fetch-gen.ts", "../src/light/sender.ts", "../src/light/repeat.ts", "../src/light/validators.ts", "../src/light/protocol.ts", "../src/cli/light-send.ts", "../src/cli/light-setup-tools.ts", "../src/light-rules/names.ts", "../src/tunnel/messages.ts", "../src/tunnel/status.ts", "../src/cli/tunnel-status.ts", "../src/cli/ntf-storage-path.ts", "../src/cli/log-search.ts", "../src/cli/env.ts", "../src/update/restart.ts", "../src/cli/doctor.ts", "../src/cli/doctor/check-dangerous-flags.ts", "../src/cli/doctor/check-trusted-proxy.ts", "../src/cli/doctor/check-state-dir-perms.ts", "../src/cli/doctor/check-tool-policy.ts", "../src/cli/doctor/check-credentials.ts", "../src/cli/doctor/check-tunnel.ts", "../src/cli/doctor/check-local-gateway.ts", "../src/tunnel/gateway-target.ts", "../src/cli/doctor/check-node-version.ts", "../src/update/channel.ts", "../src/update/semver.ts", "../src/version.ts", "../src/cli/doctor/check-plugin-version.ts", "../src/cli/doctor/checkers.ts", "../src/cli/rec-list.ts", "../src/cli/rec-status.ts", "../src/cli/rec-storage-path.ts", "../src/cli/rec-setup.ts", "../src/cli/image-list.ts", "../src/cli/image-status.ts", "../src/cli/image-path.ts", "../src/cli/image-storage-path.ts", "../src/cli/web-list.ts", "../src/cli/web-path.ts", "../src/cli/web-search.ts", "../src/cli/web-storage-path.ts", "../src/cli/update.ts", "../src/cli/index.ts", "../src/bin/ntf.ts"],
  "sourcesContent": [
    "/**\n * CommanderError class\n */\nclass CommanderError extends Error {\n  /**\n   * Constructs the CommanderError class\n   * @param {number} exitCode suggested exit code which could be used with process.exit\n   * @param {string} code an id string representing the error\n   * @param {string} message human-readable description of the error\n   */\n  constructor(exitCode, code, message) {\n    super(message);\n    // properly capture stack trace in Node.js\n    Error.captureStackTrace(this, this.constructor);\n    this.name = this.constructor.name;\n    this.code = code;\n    this.exitCode = exitCode;\n    this.nestedError = undefined;\n  }\n}\n\n/**\n * InvalidArgumentError class\n */\nclass InvalidArgumentError extends CommanderError {\n  /**\n   * Constructs the InvalidArgumentError class\n   * @param {string} [message] explanation of why argument is invalid\n   */\n  constructor(message) {\n    super(1, 'commander.invalidArgument', message);\n    // properly capture stack trace in Node.js\n    Error.captureStackTrace(this, this.constructor);\n    this.name = this.constructor.name;\n  }\n}\n\nexports.CommanderError = CommanderError;\nexports.InvalidArgumentError = InvalidArgumentError;\n",
    "const { InvalidArgumentError } = require('./error.js');\n\nclass Argument {\n  /**\n   * Initialize a new command argument with the given name and description.\n   * The default is that the argument is required, and you can explicitly\n   * indicate this with <> around the name. Put [] around the name for an optional argument.\n   *\n   * @param {string} name\n   * @param {string} [description]\n   */\n\n  constructor(name, description) {\n    this.description = description || '';\n    this.variadic = false;\n    this.parseArg = undefined;\n    this.defaultValue = undefined;\n    this.defaultValueDescription = undefined;\n    this.argChoices = undefined;\n\n    switch (name[0]) {\n      case '<': // e.g. <required>\n        this.required = true;\n        this._name = name.slice(1, -1);\n        break;\n      case '[': // e.g. [optional]\n        this.required = false;\n        this._name = name.slice(1, -1);\n        break;\n      default:\n        this.required = true;\n        this._name = name;\n        break;\n    }\n\n    if (this._name.endsWith('...')) {\n      this.variadic = true;\n      this._name = this._name.slice(0, -3);\n    }\n  }\n\n  /**\n   * Return argument name.\n   *\n   * @return {string}\n   */\n\n  name() {\n    return this._name;\n  }\n\n  /**\n   * @package\n   */\n\n  _collectValue(value, previous) {\n    if (previous === this.defaultValue || !Array.isArray(previous)) {\n      return [value];\n    }\n\n    previous.push(value);\n    return previous;\n  }\n\n  /**\n   * Set the default value, and optionally supply the description to be displayed in the help.\n   *\n   * @param {*} value\n   * @param {string} [description]\n   * @return {Argument}\n   */\n\n  default(value, description) {\n    this.defaultValue = value;\n    this.defaultValueDescription = description;\n    return this;\n  }\n\n  /**\n   * Set the custom handler for processing CLI command arguments into argument values.\n   *\n   * @param {Function} [fn]\n   * @return {Argument}\n   */\n\n  argParser(fn) {\n    this.parseArg = fn;\n    return this;\n  }\n\n  /**\n   * Only allow argument value to be one of choices.\n   *\n   * @param {string[]} values\n   * @return {Argument}\n   */\n\n  choices(values) {\n    this.argChoices = values.slice();\n    this.parseArg = (arg, previous) => {\n      if (!this.argChoices.includes(arg)) {\n        throw new InvalidArgumentError(\n          `Allowed choices are ${this.argChoices.join(', ')}.`,\n        );\n      }\n      if (this.variadic) {\n        return this._collectValue(arg, previous);\n      }\n      return arg;\n    };\n    return this;\n  }\n\n  /**\n   * Make argument required.\n   *\n   * @returns {Argument}\n   */\n  argRequired() {\n    this.required = true;\n    return this;\n  }\n\n  /**\n   * Make argument optional.\n   *\n   * @returns {Argument}\n   */\n  argOptional() {\n    this.required = false;\n    return this;\n  }\n}\n\n/**\n * Takes an argument and returns its human readable equivalent for help usage.\n *\n * @param {Argument} arg\n * @return {string}\n * @private\n */\n\nfunction humanReadableArgName(arg) {\n  const nameOutput = arg.name() + (arg.variadic === true ? '...' : '');\n\n  return arg.required ? '<' + nameOutput + '>' : '[' + nameOutput + ']';\n}\n\nexports.Argument = Argument;\nexports.humanReadableArgName = humanReadableArgName;\n",
    "const { humanReadableArgName } = require('./argument.js');\n\n/**\n * TypeScript import types for JSDoc, used by Visual Studio Code IntelliSense and `npm run typescript-checkJS`\n * https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#import-types\n * @typedef { import(\"./argument.js\").Argument } Argument\n * @typedef { import(\"./command.js\").Command } Command\n * @typedef { import(\"./option.js\").Option } Option\n */\n\n// Although this is a class, methods are static in style to allow override using subclass or just functions.\nclass Help {\n  constructor() {\n    this.helpWidth = undefined;\n    this.minWidthToWrap = 40;\n    this.sortSubcommands = false;\n    this.sortOptions = false;\n    this.showGlobalOptions = false;\n  }\n\n  /**\n   * prepareContext is called by Commander after applying overrides from `Command.configureHelp()`\n   * and just before calling `formatHelp()`.\n   *\n   * Commander just uses the helpWidth and the rest is provided for optional use by more complex subclasses.\n   *\n   * @param {{ error?: boolean, helpWidth?: number, outputHasColors?: boolean }} contextOptions\n   */\n  prepareContext(contextOptions) {\n    this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;\n  }\n\n  /**\n   * Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.\n   *\n   * @param {Command} cmd\n   * @returns {Command[]}\n   */\n\n  visibleCommands(cmd) {\n    const visibleCommands = cmd.commands.filter((cmd) => !cmd._hidden);\n    const helpCommand = cmd._getHelpCommand();\n    if (helpCommand && !helpCommand._hidden) {\n      visibleCommands.push(helpCommand);\n    }\n    if (this.sortSubcommands) {\n      visibleCommands.sort((a, b) => {\n        // @ts-ignore: because overloaded return type\n        return a.name().localeCompare(b.name());\n      });\n    }\n    return visibleCommands;\n  }\n\n  /**\n   * Compare options for sort.\n   *\n   * @param {Option} a\n   * @param {Option} b\n   * @returns {number}\n   */\n  compareOptions(a, b) {\n    const getSortKey = (option) => {\n      // WYSIWYG for order displayed in help. Short used for comparison if present. No special handling for negated.\n      return option.short\n        ? option.short.replace(/^-/, '')\n        : option.long.replace(/^--/, '');\n    };\n    return getSortKey(a).localeCompare(getSortKey(b));\n  }\n\n  /**\n   * Get an array of the visible options. Includes a placeholder for the implicit help option, if there is one.\n   *\n   * @param {Command} cmd\n   * @returns {Option[]}\n   */\n\n  visibleOptions(cmd) {\n    const visibleOptions = cmd.options.filter((option) => !option.hidden);\n    // Built-in help option.\n    const helpOption = cmd._getHelpOption();\n    if (helpOption && !helpOption.hidden) {\n      // Automatically hide conflicting flags. Bit dubious but a historical behaviour that is convenient for single-command programs.\n      const removeShort = helpOption.short && cmd._findOption(helpOption.short);\n      const removeLong = helpOption.long && cmd._findOption(helpOption.long);\n      if (!removeShort && !removeLong) {\n        visibleOptions.push(helpOption); // no changes needed\n      } else if (helpOption.long && !removeLong) {\n        visibleOptions.push(\n          cmd.createOption(helpOption.long, helpOption.description),\n        );\n      } else if (helpOption.short && !removeShort) {\n        visibleOptions.push(\n          cmd.createOption(helpOption.short, helpOption.description),\n        );\n      }\n    }\n    if (this.sortOptions) {\n      visibleOptions.sort(this.compareOptions);\n    }\n    return visibleOptions;\n  }\n\n  /**\n   * Get an array of the visible global options. (Not including help.)\n   *\n   * @param {Command} cmd\n   * @returns {Option[]}\n   */\n\n  visibleGlobalOptions(cmd) {\n    if (!this.showGlobalOptions) return [];\n\n    const globalOptions = [];\n    for (\n      let ancestorCmd = cmd.parent;\n      ancestorCmd;\n      ancestorCmd = ancestorCmd.parent\n    ) {\n      const visibleOptions = ancestorCmd.options.filter(\n        (option) => !option.hidden,\n      );\n      globalOptions.push(...visibleOptions);\n    }\n    if (this.sortOptions) {\n      globalOptions.sort(this.compareOptions);\n    }\n    return globalOptions;\n  }\n\n  /**\n   * Get an array of the arguments if any have a description.\n   *\n   * @param {Command} cmd\n   * @returns {Argument[]}\n   */\n\n  visibleArguments(cmd) {\n    // Side effect! Apply the legacy descriptions before the arguments are displayed.\n    if (cmd._argsDescription) {\n      cmd.registeredArguments.forEach((argument) => {\n        argument.description =\n          argument.description || cmd._argsDescription[argument.name()] || '';\n      });\n    }\n\n    // If there are any arguments with a description then return all the arguments.\n    if (cmd.registeredArguments.find((argument) => argument.description)) {\n      return cmd.registeredArguments;\n    }\n    return [];\n  }\n\n  /**\n   * Get the command term to show in the list of subcommands.\n   *\n   * @param {Command} cmd\n   * @returns {string}\n   */\n\n  subcommandTerm(cmd) {\n    // Legacy. Ignores custom usage string, and nested commands.\n    const args = cmd.registeredArguments\n      .map((arg) => humanReadableArgName(arg))\n      .join(' ');\n    return (\n      cmd._name +\n      (cmd._aliases[0] ? '|' + cmd._aliases[0] : '') +\n      (cmd.options.length ? ' [options]' : '') + // simplistic check for non-help option\n      (args ? ' ' + args : '')\n    );\n  }\n\n  /**\n   * Get the option term to show in the list of options.\n   *\n   * @param {Option} option\n   * @returns {string}\n   */\n\n  optionTerm(option) {\n    return option.flags;\n  }\n\n  /**\n   * Get the argument term to show in the list of arguments.\n   *\n   * @param {Argument} argument\n   * @returns {string}\n   */\n\n  argumentTerm(argument) {\n    return argument.name();\n  }\n\n  /**\n   * Get the longest command term length.\n   *\n   * @param {Command} cmd\n   * @param {Help} helper\n   * @returns {number}\n   */\n\n  longestSubcommandTermLength(cmd, helper) {\n    return helper.visibleCommands(cmd).reduce((max, command) => {\n      return Math.max(\n        max,\n        this.displayWidth(\n          helper.styleSubcommandTerm(helper.subcommandTerm(command)),\n        ),\n      );\n    }, 0);\n  }\n\n  /**\n   * Get the longest option term length.\n   *\n   * @param {Command} cmd\n   * @param {Help} helper\n   * @returns {number}\n   */\n\n  longestOptionTermLength(cmd, helper) {\n    return helper.visibleOptions(cmd).reduce((max, option) => {\n      return Math.max(\n        max,\n        this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))),\n      );\n    }, 0);\n  }\n\n  /**\n   * Get the longest global option term length.\n   *\n   * @param {Command} cmd\n   * @param {Help} helper\n   * @returns {number}\n   */\n\n  longestGlobalOptionTermLength(cmd, helper) {\n    return helper.visibleGlobalOptions(cmd).reduce((max, option) => {\n      return Math.max(\n        max,\n        this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))),\n      );\n    }, 0);\n  }\n\n  /**\n   * Get the longest argument term length.\n   *\n   * @param {Command} cmd\n   * @param {Help} helper\n   * @returns {number}\n   */\n\n  longestArgumentTermLength(cmd, helper) {\n    return helper.visibleArguments(cmd).reduce((max, argument) => {\n      return Math.max(\n        max,\n        this.displayWidth(\n          helper.styleArgumentTerm(helper.argumentTerm(argument)),\n        ),\n      );\n    }, 0);\n  }\n\n  /**\n   * Get the command usage to be displayed at the top of the built-in help.\n   *\n   * @param {Command} cmd\n   * @returns {string}\n   */\n\n  commandUsage(cmd) {\n    // Usage\n    let cmdName = cmd._name;\n    if (cmd._aliases[0]) {\n      cmdName = cmdName + '|' + cmd._aliases[0];\n    }\n    let ancestorCmdNames = '';\n    for (\n      let ancestorCmd = cmd.parent;\n      ancestorCmd;\n      ancestorCmd = ancestorCmd.parent\n    ) {\n      ancestorCmdNames = ancestorCmd.name() + ' ' + ancestorCmdNames;\n    }\n    return ancestorCmdNames + cmdName + ' ' + cmd.usage();\n  }\n\n  /**\n   * Get the description for the command.\n   *\n   * @param {Command} cmd\n   * @returns {string}\n   */\n\n  commandDescription(cmd) {\n    // @ts-ignore: because overloaded return type\n    return cmd.description();\n  }\n\n  /**\n   * Get the subcommand summary to show in the list of subcommands.\n   * (Fallback to description for backwards compatibility.)\n   *\n   * @param {Command} cmd\n   * @returns {string}\n   */\n\n  subcommandDescription(cmd) {\n    // @ts-ignore: because overloaded return type\n    return cmd.summary() || cmd.description();\n  }\n\n  /**\n   * Get the option description to show in the list of options.\n   *\n   * @param {Option} option\n   * @return {string}\n   */\n\n  optionDescription(option) {\n    const extraInfo = [];\n\n    if (option.argChoices) {\n      extraInfo.push(\n        // use stringify to match the display of the default value\n        `choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(', ')}`,\n      );\n    }\n    if (option.defaultValue !== undefined) {\n      // default for boolean and negated more for programmer than end user,\n      // but show true/false for boolean option as may be for hand-rolled env or config processing.\n      const showDefault =\n        option.required ||\n        option.optional ||\n        (option.isBoolean() && typeof option.defaultValue === 'boolean');\n      if (showDefault) {\n        extraInfo.push(\n          `default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`,\n        );\n      }\n    }\n    // preset for boolean and negated are more for programmer than end user\n    if (option.presetArg !== undefined && option.optional) {\n      extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);\n    }\n    if (option.envVar !== undefined) {\n      extraInfo.push(`env: ${option.envVar}`);\n    }\n    if (extraInfo.length > 0) {\n      const extraDescription = `(${extraInfo.join(', ')})`;\n      if (option.description) {\n        return `${option.description} ${extraDescription}`;\n      }\n      return extraDescription;\n    }\n\n    return option.description;\n  }\n\n  /**\n   * Get the argument description to show in the list of arguments.\n   *\n   * @param {Argument} argument\n   * @return {string}\n   */\n\n  argumentDescription(argument) {\n    const extraInfo = [];\n    if (argument.argChoices) {\n      extraInfo.push(\n        // use stringify to match the display of the default value\n        `choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(', ')}`,\n      );\n    }\n    if (argument.defaultValue !== undefined) {\n      extraInfo.push(\n        `default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`,\n      );\n    }\n    if (extraInfo.length > 0) {\n      const extraDescription = `(${extraInfo.join(', ')})`;\n      if (argument.description) {\n        return `${argument.description} ${extraDescription}`;\n      }\n      return extraDescription;\n    }\n    return argument.description;\n  }\n\n  /**\n   * Format a list of items, given a heading and an array of formatted items.\n   *\n   * @param {string} heading\n   * @param {string[]} items\n   * @param {Help} helper\n   * @returns string[]\n   */\n  formatItemList(heading, items, helper) {\n    if (items.length === 0) return [];\n\n    return [helper.styleTitle(heading), ...items, ''];\n  }\n\n  /**\n   * Group items by their help group heading.\n   *\n   * @param {Command[] | Option[]} unsortedItems\n   * @param {Command[] | Option[]} visibleItems\n   * @param {Function} getGroup\n   * @returns {Map<string, Command[] | Option[]>}\n   */\n  groupItems(unsortedItems, visibleItems, getGroup) {\n    const result = new Map();\n    // Add groups in order of appearance in unsortedItems.\n    unsortedItems.forEach((item) => {\n      const group = getGroup(item);\n      if (!result.has(group)) result.set(group, []);\n    });\n    // Add items in order of appearance in visibleItems.\n    visibleItems.forEach((item) => {\n      const group = getGroup(item);\n      if (!result.has(group)) {\n        result.set(group, []);\n      }\n      result.get(group).push(item);\n    });\n    return result;\n  }\n\n  /**\n   * Generate the built-in help text.\n   *\n   * @param {Command} cmd\n   * @param {Help} helper\n   * @returns {string}\n   */\n\n  formatHelp(cmd, helper) {\n    const termWidth = helper.padWidth(cmd, helper);\n    const helpWidth = helper.helpWidth ?? 80; // in case prepareContext() was not called\n\n    function callFormatItem(term, description) {\n      return helper.formatItem(term, termWidth, description, helper);\n    }\n\n    // Usage\n    let output = [\n      `${helper.styleTitle('Usage:')} ${helper.styleUsage(helper.commandUsage(cmd))}`,\n      '',\n    ];\n\n    // Description\n    const commandDescription = helper.commandDescription(cmd);\n    if (commandDescription.length > 0) {\n      output = output.concat([\n        helper.boxWrap(\n          helper.styleCommandDescription(commandDescription),\n          helpWidth,\n        ),\n        '',\n      ]);\n    }\n\n    // Arguments\n    const argumentList = helper.visibleArguments(cmd).map((argument) => {\n      return callFormatItem(\n        helper.styleArgumentTerm(helper.argumentTerm(argument)),\n        helper.styleArgumentDescription(helper.argumentDescription(argument)),\n      );\n    });\n    output = output.concat(\n      this.formatItemList('Arguments:', argumentList, helper),\n    );\n\n    // Options\n    const optionGroups = this.groupItems(\n      cmd.options,\n      helper.visibleOptions(cmd),\n      (option) => option.helpGroupHeading ?? 'Options:',\n    );\n    optionGroups.forEach((options, group) => {\n      const optionList = options.map((option) => {\n        return callFormatItem(\n          helper.styleOptionTerm(helper.optionTerm(option)),\n          helper.styleOptionDescription(helper.optionDescription(option)),\n        );\n      });\n      output = output.concat(this.formatItemList(group, optionList, helper));\n    });\n\n    if (helper.showGlobalOptions) {\n      const globalOptionList = helper\n        .visibleGlobalOptions(cmd)\n        .map((option) => {\n          return callFormatItem(\n            helper.styleOptionTerm(helper.optionTerm(option)),\n            helper.styleOptionDescription(helper.optionDescription(option)),\n          );\n        });\n      output = output.concat(\n        this.formatItemList('Global Options:', globalOptionList, helper),\n      );\n    }\n\n    // Commands\n    const commandGroups = this.groupItems(\n      cmd.commands,\n      helper.visibleCommands(cmd),\n      (sub) => sub.helpGroup() || 'Commands:',\n    );\n    commandGroups.forEach((commands, group) => {\n      const commandList = commands.map((sub) => {\n        return callFormatItem(\n          helper.styleSubcommandTerm(helper.subcommandTerm(sub)),\n          helper.styleSubcommandDescription(helper.subcommandDescription(sub)),\n        );\n      });\n      output = output.concat(this.formatItemList(group, commandList, helper));\n    });\n\n    return output.join('\\n');\n  }\n\n  /**\n   * Return display width of string, ignoring ANSI escape sequences. Used in padding and wrapping calculations.\n   *\n   * @param {string} str\n   * @returns {number}\n   */\n  displayWidth(str) {\n    return stripColor(str).length;\n  }\n\n  /**\n   * Style the title for displaying in the help. Called with 'Usage:', 'Options:', etc.\n   *\n   * @param {string} str\n   * @returns {string}\n   */\n  styleTitle(str) {\n    return str;\n  }\n\n  styleUsage(str) {\n    // Usage has lots of parts the user might like to color separately! Assume default usage string which is formed like:\n    //    command subcommand [options] [command] <foo> [bar]\n    return str\n      .split(' ')\n      .map((word) => {\n        if (word === '[options]') return this.styleOptionText(word);\n        if (word === '[command]') return this.styleSubcommandText(word);\n        if (word[0] === '[' || word[0] === '<')\n          return this.styleArgumentText(word);\n        return this.styleCommandText(word); // Restrict to initial words?\n      })\n      .join(' ');\n  }\n  styleCommandDescription(str) {\n    return this.styleDescriptionText(str);\n  }\n  styleOptionDescription(str) {\n    return this.styleDescriptionText(str);\n  }\n  styleSubcommandDescription(str) {\n    return this.styleDescriptionText(str);\n  }\n  styleArgumentDescription(str) {\n    return this.styleDescriptionText(str);\n  }\n  styleDescriptionText(str) {\n    return str;\n  }\n  styleOptionTerm(str) {\n    return this.styleOptionText(str);\n  }\n  styleSubcommandTerm(str) {\n    // This is very like usage with lots of parts! Assume default string which is formed like:\n    //    subcommand [options] <foo> [bar]\n    return str\n      .split(' ')\n      .map((word) => {\n        if (word === '[options]') return this.styleOptionText(word);\n        if (word[0] === '[' || word[0] === '<')\n          return this.styleArgumentText(word);\n        return this.styleSubcommandText(word); // Restrict to initial words?\n      })\n      .join(' ');\n  }\n  styleArgumentTerm(str) {\n    return this.styleArgumentText(str);\n  }\n  styleOptionText(str) {\n    return str;\n  }\n  styleArgumentText(str) {\n    return str;\n  }\n  styleSubcommandText(str) {\n    return str;\n  }\n  styleCommandText(str) {\n    return str;\n  }\n\n  /**\n   * Calculate the pad width from the maximum term length.\n   *\n   * @param {Command} cmd\n   * @param {Help} helper\n   * @returns {number}\n   */\n\n  padWidth(cmd, helper) {\n    return Math.max(\n      helper.longestOptionTermLength(cmd, helper),\n      helper.longestGlobalOptionTermLength(cmd, helper),\n      helper.longestSubcommandTermLength(cmd, helper),\n      helper.longestArgumentTermLength(cmd, helper),\n    );\n  }\n\n  /**\n   * Detect manually wrapped and indented strings by checking for line break followed by whitespace.\n   *\n   * @param {string} str\n   * @returns {boolean}\n   */\n  preformatted(str) {\n    return /\\n[^\\S\\r\\n]/.test(str);\n  }\n\n  /**\n   * Format the \"item\", which consists of a term and description. Pad the term and wrap the description, indenting the following lines.\n   *\n   * So \"TTT\", 5, \"DDD DDDD DD DDD\" might be formatted for this.helpWidth=17 like so:\n   *   TTT  DDD DDDD\n   *        DD DDD\n   *\n   * @param {string} term\n   * @param {number} termWidth\n   * @param {string} description\n   * @param {Help} helper\n   * @returns {string}\n   */\n  formatItem(term, termWidth, description, helper) {\n    const itemIndent = 2;\n    const itemIndentStr = ' '.repeat(itemIndent);\n    if (!description) return itemIndentStr + term;\n\n    // Pad the term out to a consistent width, so descriptions are aligned.\n    const paddedTerm = term.padEnd(\n      termWidth + term.length - helper.displayWidth(term),\n    );\n\n    // Format the description.\n    const spacerWidth = 2; // between term and description\n    const helpWidth = this.helpWidth ?? 80; // in case prepareContext() was not called\n    const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;\n    let formattedDescription;\n    if (\n      remainingWidth < this.minWidthToWrap ||\n      helper.preformatted(description)\n    ) {\n      formattedDescription = description;\n    } else {\n      const wrappedDescription = helper.boxWrap(description, remainingWidth);\n      formattedDescription = wrappedDescription.replace(\n        /\\n/g,\n        '\\n' + ' '.repeat(termWidth + spacerWidth),\n      );\n    }\n\n    // Construct and overall indent.\n    return (\n      itemIndentStr +\n      paddedTerm +\n      ' '.repeat(spacerWidth) +\n      formattedDescription.replace(/\\n/g, `\\n${itemIndentStr}`)\n    );\n  }\n\n  /**\n   * Wrap a string at whitespace, preserving existing line breaks.\n   * Wrapping is skipped if the width is less than `minWidthToWrap`.\n   *\n   * @param {string} str\n   * @param {number} width\n   * @returns {string}\n   */\n  boxWrap(str, width) {\n    if (width < this.minWidthToWrap) return str;\n\n    const rawLines = str.split(/\\r\\n|\\n/);\n    // split up text by whitespace\n    const chunkPattern = /[\\s]*[^\\s]+/g;\n    const wrappedLines = [];\n    rawLines.forEach((line) => {\n      const chunks = line.match(chunkPattern);\n      if (chunks === null) {\n        wrappedLines.push('');\n        return;\n      }\n\n      let sumChunks = [chunks.shift()];\n      let sumWidth = this.displayWidth(sumChunks[0]);\n      chunks.forEach((chunk) => {\n        const visibleWidth = this.displayWidth(chunk);\n        // Accumulate chunks while they fit into width.\n        if (sumWidth + visibleWidth <= width) {\n          sumChunks.push(chunk);\n          sumWidth += visibleWidth;\n          return;\n        }\n        wrappedLines.push(sumChunks.join(''));\n\n        const nextChunk = chunk.trimStart(); // trim space at line break\n        sumChunks = [nextChunk];\n        sumWidth = this.displayWidth(nextChunk);\n      });\n      wrappedLines.push(sumChunks.join(''));\n    });\n\n    return wrappedLines.join('\\n');\n  }\n}\n\n/**\n * Strip style ANSI escape sequences from the string. In particular, SGR (Select Graphic Rendition) codes.\n *\n * @param {string} str\n * @returns {string}\n * @package\n */\n\nfunction stripColor(str) {\n  // eslint-disable-next-line no-control-regex\n  const sgrPattern = /\\x1b\\[\\d*(;\\d*)*m/g;\n  return str.replace(sgrPattern, '');\n}\n\nexports.Help = Help;\nexports.stripColor = stripColor;\n",
    "const { InvalidArgumentError } = require('./error.js');\n\nclass Option {\n  /**\n   * Initialize a new `Option` with the given `flags` and `description`.\n   *\n   * @param {string} flags\n   * @param {string} [description]\n   */\n\n  constructor(flags, description) {\n    this.flags = flags;\n    this.description = description || '';\n\n    this.required = flags.includes('<'); // A value must be supplied when the option is specified.\n    this.optional = flags.includes('['); // A value is optional when the option is specified.\n    // variadic test ignores <value,...> et al which might be used to describe custom splitting of single argument\n    this.variadic = /\\w\\.\\.\\.[>\\]]$/.test(flags); // The option can take multiple values.\n    this.mandatory = false; // The option must have a value after parsing, which usually means it must be specified on command line.\n    const optionFlags = splitOptionFlags(flags);\n    this.short = optionFlags.shortFlag; // May be a short flag, undefined, or even a long flag (if option has two long flags).\n    this.long = optionFlags.longFlag;\n    this.negate = false;\n    if (this.long) {\n      this.negate = this.long.startsWith('--no-');\n    }\n    this.defaultValue = undefined;\n    this.defaultValueDescription = undefined;\n    this.presetArg = undefined;\n    this.envVar = undefined;\n    this.parseArg = undefined;\n    this.hidden = false;\n    this.argChoices = undefined;\n    this.conflictsWith = [];\n    this.implied = undefined;\n    this.helpGroupHeading = undefined; // soft initialised when option added to command\n  }\n\n  /**\n   * Set the default value, and optionally supply the description to be displayed in the help.\n   *\n   * @param {*} value\n   * @param {string} [description]\n   * @return {Option}\n   */\n\n  default(value, description) {\n    this.defaultValue = value;\n    this.defaultValueDescription = description;\n    return this;\n  }\n\n  /**\n   * Preset to use when option used without option-argument, especially optional but also boolean and negated.\n   * The custom processing (parseArg) is called.\n   *\n   * @example\n   * new Option('--color').default('GREYSCALE').preset('RGB');\n   * new Option('--donate [amount]').preset('20').argParser(parseFloat);\n   *\n   * @param {*} arg\n   * @return {Option}\n   */\n\n  preset(arg) {\n    this.presetArg = arg;\n    return this;\n  }\n\n  /**\n   * Add option name(s) that conflict with this option.\n   * An error will be displayed if conflicting options are found during parsing.\n   *\n   * @example\n   * new Option('--rgb').conflicts('cmyk');\n   * new Option('--js').conflicts(['ts', 'jsx']);\n   *\n   * @param {(string | string[])} names\n   * @return {Option}\n   */\n\n  conflicts(names) {\n    this.conflictsWith = this.conflictsWith.concat(names);\n    return this;\n  }\n\n  /**\n   * Specify implied option values for when this option is set and the implied options are not.\n   *\n   * The custom processing (parseArg) is not called on the implied values.\n   *\n   * @example\n   * program\n   *   .addOption(new Option('--log', 'write logging information to file'))\n   *   .addOption(new Option('--trace', 'log extra details').implies({ log: 'trace.txt' }));\n   *\n   * @param {object} impliedOptionValues\n   * @return {Option}\n   */\n  implies(impliedOptionValues) {\n    let newImplied = impliedOptionValues;\n    if (typeof impliedOptionValues === 'string') {\n      // string is not documented, but easy mistake and we can do what user probably intended.\n      newImplied = { [impliedOptionValues]: true };\n    }\n    this.implied = Object.assign(this.implied || {}, newImplied);\n    return this;\n  }\n\n  /**\n   * Set environment variable to check for option value.\n   *\n   * An environment variable is only used if when processed the current option value is\n   * undefined, or the source of the current value is 'default' or 'config' or 'env'.\n   *\n   * @param {string} name\n   * @return {Option}\n   */\n\n  env(name) {\n    this.envVar = name;\n    return this;\n  }\n\n  /**\n   * Set the custom handler for processing CLI option arguments into option values.\n   *\n   * @param {Function} [fn]\n   * @return {Option}\n   */\n\n  argParser(fn) {\n    this.parseArg = fn;\n    return this;\n  }\n\n  /**\n   * Whether the option is mandatory and must have a value after parsing.\n   *\n   * @param {boolean} [mandatory=true]\n   * @return {Option}\n   */\n\n  makeOptionMandatory(mandatory = true) {\n    this.mandatory = !!mandatory;\n    return this;\n  }\n\n  /**\n   * Hide option in help.\n   *\n   * @param {boolean} [hide=true]\n   * @return {Option}\n   */\n\n  hideHelp(hide = true) {\n    this.hidden = !!hide;\n    return this;\n  }\n\n  /**\n   * @package\n   */\n\n  _collectValue(value, previous) {\n    if (previous === this.defaultValue || !Array.isArray(previous)) {\n      return [value];\n    }\n\n    previous.push(value);\n    return previous;\n  }\n\n  /**\n   * Only allow option value to be one of choices.\n   *\n   * @param {string[]} values\n   * @return {Option}\n   */\n\n  choices(values) {\n    this.argChoices = values.slice();\n    this.parseArg = (arg, previous) => {\n      if (!this.argChoices.includes(arg)) {\n        throw new InvalidArgumentError(\n          `Allowed choices are ${this.argChoices.join(', ')}.`,\n        );\n      }\n      if (this.variadic) {\n        return this._collectValue(arg, previous);\n      }\n      return arg;\n    };\n    return this;\n  }\n\n  /**\n   * Return option name.\n   *\n   * @return {string}\n   */\n\n  name() {\n    if (this.long) {\n      return this.long.replace(/^--/, '');\n    }\n    return this.short.replace(/^-/, '');\n  }\n\n  /**\n   * Return option name, in a camelcase format that can be used\n   * as an object attribute key.\n   *\n   * @return {string}\n   */\n\n  attributeName() {\n    if (this.negate) {\n      return camelcase(this.name().replace(/^no-/, ''));\n    }\n    return camelcase(this.name());\n  }\n\n  /**\n   * Set the help group heading.\n   *\n   * @param {string} heading\n   * @return {Option}\n   */\n  helpGroup(heading) {\n    this.helpGroupHeading = heading;\n    return this;\n  }\n\n  /**\n   * Check if `arg` matches the short or long flag.\n   *\n   * @param {string} arg\n   * @return {boolean}\n   * @package\n   */\n\n  is(arg) {\n    return this.short === arg || this.long === arg;\n  }\n\n  /**\n   * Return whether a boolean option.\n   *\n   * Options are one of boolean, negated, required argument, or optional argument.\n   *\n   * @return {boolean}\n   * @package\n   */\n\n  isBoolean() {\n    return !this.required && !this.optional && !this.negate;\n  }\n}\n\n/**\n * This class is to make it easier to work with dual options, without changing the existing\n * implementation. We support separate dual options for separate positive and negative options,\n * like `--build` and `--no-build`, which share a single option value. This works nicely for some\n * use cases, but is tricky for others where we want separate behaviours despite\n * the single shared option value.\n */\nclass DualOptions {\n  /**\n   * @param {Option[]} options\n   */\n  constructor(options) {\n    this.positiveOptions = new Map();\n    this.negativeOptions = new Map();\n    this.dualOptions = new Set();\n    options.forEach((option) => {\n      if (option.negate) {\n        this.negativeOptions.set(option.attributeName(), option);\n      } else {\n        this.positiveOptions.set(option.attributeName(), option);\n      }\n    });\n    this.negativeOptions.forEach((value, key) => {\n      if (this.positiveOptions.has(key)) {\n        this.dualOptions.add(key);\n      }\n    });\n  }\n\n  /**\n   * Did the value come from the option, and not from possible matching dual option?\n   *\n   * @param {*} value\n   * @param {Option} option\n   * @returns {boolean}\n   */\n  valueFromOption(value, option) {\n    const optionKey = option.attributeName();\n    if (!this.dualOptions.has(optionKey)) return true;\n\n    // Use the value to deduce if (probably) came from the option.\n    const preset = this.negativeOptions.get(optionKey).presetArg;\n    const negativeValue = preset !== undefined ? preset : false;\n    return option.negate === (negativeValue === value);\n  }\n}\n\n/**\n * Convert string from kebab-case to camelCase.\n *\n * @param {string} str\n * @return {string}\n * @private\n */\n\nfunction camelcase(str) {\n  return str.split('-').reduce((str, word) => {\n    return str + word[0].toUpperCase() + word.slice(1);\n  });\n}\n\n/**\n * Split the short and long flag out of something like '-m,--mixed <value>'\n *\n * @private\n */\n\nfunction splitOptionFlags(flags) {\n  let shortFlag;\n  let longFlag;\n  // short flag, single dash and single character\n  const shortFlagExp = /^-[^-]$/;\n  // long flag, double dash and at least one character\n  const longFlagExp = /^--[^-]/;\n\n  const flagParts = flags.split(/[ |,]+/).concat('guard');\n  // Normal is short and/or long.\n  if (shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift();\n  if (longFlagExp.test(flagParts[0])) longFlag = flagParts.shift();\n  // Long then short. Rarely used but fine.\n  if (!shortFlag && shortFlagExp.test(flagParts[0]))\n    shortFlag = flagParts.shift();\n  // Allow two long flags, like '--ws, --workspace'\n  // This is the supported way to have a shortish option flag.\n  if (!shortFlag && longFlagExp.test(flagParts[0])) {\n    shortFlag = longFlag;\n    longFlag = flagParts.shift();\n  }\n\n  // Check for unprocessed flag. Fail noisily rather than silently ignore.\n  if (flagParts[0].startsWith('-')) {\n    const unsupportedFlag = flagParts[0];\n    const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;\n    if (/^-[^-][^-]/.test(unsupportedFlag))\n      throw new Error(\n        `${baseError}\n- a short flag is a single dash and a single character\n  - either use a single dash and a single character (for a short flag)\n  - or use a double dash for a long option (and can have two, like '--ws, --workspace')`,\n      );\n    if (shortFlagExp.test(unsupportedFlag))\n      throw new Error(`${baseError}\n- too many short flags`);\n    if (longFlagExp.test(unsupportedFlag))\n      throw new Error(`${baseError}\n- too many long flags`);\n\n    throw new Error(`${baseError}\n- unrecognised flag format`);\n  }\n  if (shortFlag === undefined && longFlag === undefined)\n    throw new Error(\n      `option creation failed due to no flags found in '${flags}'.`,\n    );\n\n  return { shortFlag, longFlag };\n}\n\nexports.Option = Option;\nexports.DualOptions = DualOptions;\n",
    "const maxDistance = 3;\n\nfunction editDistance(a, b) {\n  // https://en.wikipedia.org/wiki/Damerau–Levenshtein_distance\n  // Calculating optimal string alignment distance, no substring is edited more than once.\n  // (Simple implementation.)\n\n  // Quick early exit, return worst case.\n  if (Math.abs(a.length - b.length) > maxDistance)\n    return Math.max(a.length, b.length);\n\n  // distance between prefix substrings of a and b\n  const d = [];\n\n  // pure deletions turn a into empty string\n  for (let i = 0; i <= a.length; i++) {\n    d[i] = [i];\n  }\n  // pure insertions turn empty string into b\n  for (let j = 0; j <= b.length; j++) {\n    d[0][j] = j;\n  }\n\n  // fill matrix\n  for (let j = 1; j <= b.length; j++) {\n    for (let i = 1; i <= a.length; i++) {\n      let cost = 1;\n      if (a[i - 1] === b[j - 1]) {\n        cost = 0;\n      } else {\n        cost = 1;\n      }\n      d[i][j] = Math.min(\n        d[i - 1][j] + 1, // deletion\n        d[i][j - 1] + 1, // insertion\n        d[i - 1][j - 1] + cost, // substitution\n      );\n      // transposition\n      if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {\n        d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);\n      }\n    }\n  }\n\n  return d[a.length][b.length];\n}\n\n/**\n * Find close matches, restricted to same number of edits.\n *\n * @param {string} word\n * @param {string[]} candidates\n * @returns {string}\n */\n\nfunction suggestSimilar(word, candidates) {\n  if (!candidates || candidates.length === 0) return '';\n  // remove possible duplicates\n  candidates = Array.from(new Set(candidates));\n\n  const searchingOptions = word.startsWith('--');\n  if (searchingOptions) {\n    word = word.slice(2);\n    candidates = candidates.map((candidate) => candidate.slice(2));\n  }\n\n  let similar = [];\n  let bestDistance = maxDistance;\n  const minSimilarity = 0.4;\n  candidates.forEach((candidate) => {\n    if (candidate.length <= 1) return; // no one character guesses\n\n    const distance = editDistance(word, candidate);\n    const length = Math.max(word.length, candidate.length);\n    const similarity = (length - distance) / length;\n    if (similarity > minSimilarity) {\n      if (distance < bestDistance) {\n        // better edit distance, throw away previous worse matches\n        bestDistance = distance;\n        similar = [candidate];\n      } else if (distance === bestDistance) {\n        similar.push(candidate);\n      }\n    }\n  });\n\n  similar.sort((a, b) => a.localeCompare(b));\n  if (searchingOptions) {\n    similar = similar.map((candidate) => `--${candidate}`);\n  }\n\n  if (similar.length > 1) {\n    return `\\n(Did you mean one of ${similar.join(', ')}?)`;\n  }\n  if (similar.length === 1) {\n    return `\\n(Did you mean ${similar[0]}?)`;\n  }\n  return '';\n}\n\nexports.suggestSimilar = suggestSimilar;\n",
    "const EventEmitter = require('node:events').EventEmitter;\nconst childProcess = require('node:child_process');\nconst path = require('node:path');\nconst fs = require('node:fs');\nconst process = require('node:process');\n\nconst { Argument, humanReadableArgName } = require('./argument.js');\nconst { CommanderError } = require('./error.js');\nconst { Help, stripColor } = require('./help.js');\nconst { Option, DualOptions } = require('./option.js');\nconst { suggestSimilar } = require('./suggestSimilar');\n\nclass Command extends EventEmitter {\n  /**\n   * Initialize a new `Command`.\n   *\n   * @param {string} [name]\n   */\n\n  constructor(name) {\n    super();\n    /** @type {Command[]} */\n    this.commands = [];\n    /** @type {Option[]} */\n    this.options = [];\n    this.parent = null;\n    this._allowUnknownOption = false;\n    this._allowExcessArguments = false;\n    /** @type {Argument[]} */\n    this.registeredArguments = [];\n    this._args = this.registeredArguments; // deprecated old name\n    /** @type {string[]} */\n    this.args = []; // cli args with options removed\n    this.rawArgs = [];\n    this.processedArgs = []; // like .args but after custom processing and collecting variadic\n    this._scriptPath = null;\n    this._name = name || '';\n    this._optionValues = {};\n    this._optionValueSources = {}; // default, env, cli etc\n    this._storeOptionsAsProperties = false;\n    this._actionHandler = null;\n    this._executableHandler = false;\n    this._executableFile = null; // custom name for executable\n    this._executableDir = null; // custom search directory for subcommands\n    this._defaultCommandName = null;\n    this._exitCallback = null;\n    this._aliases = [];\n    this._combineFlagAndOptionalValue = true;\n    this._description = '';\n    this._summary = '';\n    this._argsDescription = undefined; // legacy\n    this._enablePositionalOptions = false;\n    this._passThroughOptions = false;\n    this._lifeCycleHooks = {}; // a hash of arrays\n    /** @type {(boolean | string)} */\n    this._showHelpAfterError = false;\n    this._showSuggestionAfterError = true;\n    this._savedState = null; // used in save/restoreStateBeforeParse\n\n    // see configureOutput() for docs\n    this._outputConfiguration = {\n      writeOut: (str) => process.stdout.write(str),\n      writeErr: (str) => process.stderr.write(str),\n      outputError: (str, write) => write(str),\n      getOutHelpWidth: () =>\n        process.stdout.isTTY ? process.stdout.columns : undefined,\n      getErrHelpWidth: () =>\n        process.stderr.isTTY ? process.stderr.columns : undefined,\n      getOutHasColors: () =>\n        useColor() ?? (process.stdout.isTTY && process.stdout.hasColors?.()),\n      getErrHasColors: () =>\n        useColor() ?? (process.stderr.isTTY && process.stderr.hasColors?.()),\n      stripColor: (str) => stripColor(str),\n    };\n\n    this._hidden = false;\n    /** @type {(Option | null | undefined)} */\n    this._helpOption = undefined; // Lazy created on demand. May be null if help option is disabled.\n    this._addImplicitHelpCommand = undefined; // undecided whether true or false yet, not inherited\n    /** @type {Command} */\n    this._helpCommand = undefined; // lazy initialised, inherited\n    this._helpConfiguration = {};\n    /** @type {string | undefined} */\n    this._helpGroupHeading = undefined; // soft initialised when added to parent\n    /** @type {string | undefined} */\n    this._defaultCommandGroup = undefined;\n    /** @type {string | undefined} */\n    this._defaultOptionGroup = undefined;\n  }\n\n  /**\n   * Copy settings that are useful to have in common across root command and subcommands.\n   *\n   * (Used internally when adding a command using `.command()` so subcommands inherit parent settings.)\n   *\n   * @param {Command} sourceCommand\n   * @return {Command} `this` command for chaining\n   */\n  copyInheritedSettings(sourceCommand) {\n    this._outputConfiguration = sourceCommand._outputConfiguration;\n    this._helpOption = sourceCommand._helpOption;\n    this._helpCommand = sourceCommand._helpCommand;\n    this._helpConfiguration = sourceCommand._helpConfiguration;\n    this._exitCallback = sourceCommand._exitCallback;\n    this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;\n    this._combineFlagAndOptionalValue =\n      sourceCommand._combineFlagAndOptionalValue;\n    this._allowExcessArguments = sourceCommand._allowExcessArguments;\n    this._enablePositionalOptions = sourceCommand._enablePositionalOptions;\n    this._showHelpAfterError = sourceCommand._showHelpAfterError;\n    this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;\n\n    return this;\n  }\n\n  /**\n   * @returns {Command[]}\n   * @private\n   */\n\n  _getCommandAndAncestors() {\n    const result = [];\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    for (let command = this; command; command = command.parent) {\n      result.push(command);\n    }\n    return result;\n  }\n\n  /**\n   * Define a command.\n   *\n   * There are two styles of command: pay attention to where to put the description.\n   *\n   * @example\n   * // Command implemented using action handler (description is supplied separately to `.command`)\n   * program\n   *   .command('clone <source> [destination]')\n   *   .description('clone a repository into a newly created directory')\n   *   .action((source, destination) => {\n   *     console.log('clone command called');\n   *   });\n   *\n   * // Command implemented using separate executable file (description is second parameter to `.command`)\n   * program\n   *   .command('start <service>', 'start named service')\n   *   .command('stop [service]', 'stop named service, or all if no name supplied');\n   *\n   * @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`\n   * @param {(object | string)} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)\n   * @param {object} [execOpts] - configuration options (for executable)\n   * @return {Command} returns new command for action handler, or `this` for executable command\n   */\n\n  command(nameAndArgs, actionOptsOrExecDesc, execOpts) {\n    let desc = actionOptsOrExecDesc;\n    let opts = execOpts;\n    if (typeof desc === 'object' && desc !== null) {\n      opts = desc;\n      desc = null;\n    }\n    opts = opts || {};\n    const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);\n\n    const cmd = this.createCommand(name);\n    if (desc) {\n      cmd.description(desc);\n      cmd._executableHandler = true;\n    }\n    if (opts.isDefault) this._defaultCommandName = cmd._name;\n    cmd._hidden = !!(opts.noHelp || opts.hidden); // noHelp is deprecated old name for hidden\n    cmd._executableFile = opts.executableFile || null; // Custom name for executable file, set missing to null to match constructor\n    if (args) cmd.arguments(args);\n    this._registerCommand(cmd);\n    cmd.parent = this;\n    cmd.copyInheritedSettings(this);\n\n    if (desc) return this;\n    return cmd;\n  }\n\n  /**\n   * Factory routine to create a new unattached command.\n   *\n   * See .command() for creating an attached subcommand, which uses this routine to\n   * create the command. You can override createCommand to customise subcommands.\n   *\n   * @param {string} [name]\n   * @return {Command} new command\n   */\n\n  createCommand(name) {\n    return new Command(name);\n  }\n\n  /**\n   * You can customise the help with a subclass of Help by overriding createHelp,\n   * or by overriding Help properties using configureHelp().\n   *\n   * @return {Help}\n   */\n\n  createHelp() {\n    return Object.assign(new Help(), this.configureHelp());\n  }\n\n  /**\n   * You can customise the help by overriding Help properties using configureHelp(),\n   * or with a subclass of Help by overriding createHelp().\n   *\n   * @param {object} [configuration] - configuration options\n   * @return {(Command | object)} `this` command for chaining, or stored configuration\n   */\n\n  configureHelp(configuration) {\n    if (configuration === undefined) return this._helpConfiguration;\n\n    this._helpConfiguration = configuration;\n    return this;\n  }\n\n  /**\n   * The default output goes to stdout and stderr. You can customise this for special\n   * applications. You can also customise the display of errors by overriding outputError.\n   *\n   * The configuration properties are all functions:\n   *\n   *     // change how output being written, defaults to stdout and stderr\n   *     writeOut(str)\n   *     writeErr(str)\n   *     // change how output being written for errors, defaults to writeErr\n   *     outputError(str, write) // used for displaying errors and not used for displaying help\n   *     // specify width for wrapping help\n   *     getOutHelpWidth()\n   *     getErrHelpWidth()\n   *     // color support, currently only used with Help\n   *     getOutHasColors()\n   *     getErrHasColors()\n   *     stripColor() // used to remove ANSI escape codes if output does not have colors\n   *\n   * @param {object} [configuration] - configuration options\n   * @return {(Command | object)} `this` command for chaining, or stored configuration\n   */\n\n  configureOutput(configuration) {\n    if (configuration === undefined) return this._outputConfiguration;\n\n    this._outputConfiguration = {\n      ...this._outputConfiguration,\n      ...configuration,\n    };\n    return this;\n  }\n\n  /**\n   * Display the help or a custom message after an error occurs.\n   *\n   * @param {(boolean|string)} [displayHelp]\n   * @return {Command} `this` command for chaining\n   */\n  showHelpAfterError(displayHelp = true) {\n    if (typeof displayHelp !== 'string') displayHelp = !!displayHelp;\n    this._showHelpAfterError = displayHelp;\n    return this;\n  }\n\n  /**\n   * Display suggestion of similar commands for unknown commands, or options for unknown options.\n   *\n   * @param {boolean} [displaySuggestion]\n   * @return {Command} `this` command for chaining\n   */\n  showSuggestionAfterError(displaySuggestion = true) {\n    this._showSuggestionAfterError = !!displaySuggestion;\n    return this;\n  }\n\n  /**\n   * Add a prepared subcommand.\n   *\n   * See .command() for creating an attached subcommand which inherits settings from its parent.\n   *\n   * @param {Command} cmd - new subcommand\n   * @param {object} [opts] - configuration options\n   * @return {Command} `this` command for chaining\n   */\n\n  addCommand(cmd, opts) {\n    if (!cmd._name) {\n      throw new Error(`Command passed to .addCommand() must have a name\n- specify the name in Command constructor or using .name()`);\n    }\n\n    opts = opts || {};\n    if (opts.isDefault) this._defaultCommandName = cmd._name;\n    if (opts.noHelp || opts.hidden) cmd._hidden = true; // modifying passed command due to existing implementation\n\n    this._registerCommand(cmd);\n    cmd.parent = this;\n    cmd._checkForBrokenPassThrough();\n\n    return this;\n  }\n\n  /**\n   * Factory routine to create a new unattached argument.\n   *\n   * See .argument() for creating an attached argument, which uses this routine to\n   * create the argument. You can override createArgument to return a custom argument.\n   *\n   * @param {string} name\n   * @param {string} [description]\n   * @return {Argument} new argument\n   */\n\n  createArgument(name, description) {\n    return new Argument(name, description);\n  }\n\n  /**\n   * Define argument syntax for command.\n   *\n   * The default is that the argument is required, and you can explicitly\n   * indicate this with <> around the name. Put [] around the name for an optional argument.\n   *\n   * @example\n   * program.argument('<input-file>');\n   * program.argument('[output-file]');\n   *\n   * @param {string} name\n   * @param {string} [description]\n   * @param {(Function|*)} [parseArg] - custom argument processing function or default value\n   * @param {*} [defaultValue]\n   * @return {Command} `this` command for chaining\n   */\n  argument(name, description, parseArg, defaultValue) {\n    const argument = this.createArgument(name, description);\n    if (typeof parseArg === 'function') {\n      argument.default(defaultValue).argParser(parseArg);\n    } else {\n      argument.default(parseArg);\n    }\n    this.addArgument(argument);\n    return this;\n  }\n\n  /**\n   * Define argument syntax for command, adding multiple at once (without descriptions).\n   *\n   * See also .argument().\n   *\n   * @example\n   * program.arguments('<cmd> [env]');\n   *\n   * @param {string} names\n   * @return {Command} `this` command for chaining\n   */\n\n  arguments(names) {\n    names\n      .trim()\n      .split(/ +/)\n      .forEach((detail) => {\n        this.argument(detail);\n      });\n    return this;\n  }\n\n  /**\n   * Define argument syntax for command, adding a prepared argument.\n   *\n   * @param {Argument} argument\n   * @return {Command} `this` command for chaining\n   */\n  addArgument(argument) {\n    const previousArgument = this.registeredArguments.slice(-1)[0];\n    if (previousArgument?.variadic) {\n      throw new Error(\n        `only the last argument can be variadic '${previousArgument.name()}'`,\n      );\n    }\n    if (\n      argument.required &&\n      argument.defaultValue !== undefined &&\n      argument.parseArg === undefined\n    ) {\n      throw new Error(\n        `a default value for a required argument is never used: '${argument.name()}'`,\n      );\n    }\n    this.registeredArguments.push(argument);\n    return this;\n  }\n\n  /**\n   * Customise or override default help command. By default a help command is automatically added if your command has subcommands.\n   *\n   * @example\n   *    program.helpCommand('help [cmd]');\n   *    program.helpCommand('help [cmd]', 'show help');\n   *    program.helpCommand(false); // suppress default help command\n   *    program.helpCommand(true); // add help command even if no subcommands\n   *\n   * @param {string|boolean} enableOrNameAndArgs - enable with custom name and/or arguments, or boolean to override whether added\n   * @param {string} [description] - custom description\n   * @return {Command} `this` command for chaining\n   */\n\n  helpCommand(enableOrNameAndArgs, description) {\n    if (typeof enableOrNameAndArgs === 'boolean') {\n      this._addImplicitHelpCommand = enableOrNameAndArgs;\n      if (enableOrNameAndArgs && this._defaultCommandGroup) {\n        // make the command to store the group\n        this._initCommandGroup(this._getHelpCommand());\n      }\n      return this;\n    }\n\n    const nameAndArgs = enableOrNameAndArgs ?? 'help [command]';\n    const [, helpName, helpArgs] = nameAndArgs.match(/([^ ]+) *(.*)/);\n    const helpDescription = description ?? 'display help for command';\n\n    const helpCommand = this.createCommand(helpName);\n    helpCommand.helpOption(false);\n    if (helpArgs) helpCommand.arguments(helpArgs);\n    if (helpDescription) helpCommand.description(helpDescription);\n\n    this._addImplicitHelpCommand = true;\n    this._helpCommand = helpCommand;\n    // init group unless lazy create\n    if (enableOrNameAndArgs || description) this._initCommandGroup(helpCommand);\n\n    return this;\n  }\n\n  /**\n   * Add prepared custom help command.\n   *\n   * @param {(Command|string|boolean)} helpCommand - custom help command, or deprecated enableOrNameAndArgs as for `.helpCommand()`\n   * @param {string} [deprecatedDescription] - deprecated custom description used with custom name only\n   * @return {Command} `this` command for chaining\n   */\n  addHelpCommand(helpCommand, deprecatedDescription) {\n    // If not passed an object, call through to helpCommand for backwards compatibility,\n    // as addHelpCommand was originally used like helpCommand is now.\n    if (typeof helpCommand !== 'object') {\n      this.helpCommand(helpCommand, deprecatedDescription);\n      return this;\n    }\n\n    this._addImplicitHelpCommand = true;\n    this._helpCommand = helpCommand;\n    this._initCommandGroup(helpCommand);\n    return this;\n  }\n\n  /**\n   * Lazy create help command.\n   *\n   * @return {(Command|null)}\n   * @package\n   */\n  _getHelpCommand() {\n    const hasImplicitHelpCommand =\n      this._addImplicitHelpCommand ??\n      (this.commands.length &&\n        !this._actionHandler &&\n        !this._findCommand('help'));\n\n    if (hasImplicitHelpCommand) {\n      if (this._helpCommand === undefined) {\n        this.helpCommand(undefined, undefined); // use default name and description\n      }\n      return this._helpCommand;\n    }\n    return null;\n  }\n\n  /**\n   * Add hook for life cycle event.\n   *\n   * @param {string} event\n   * @param {Function} listener\n   * @return {Command} `this` command for chaining\n   */\n\n  hook(event, listener) {\n    const allowedValues = ['preSubcommand', 'preAction', 'postAction'];\n    if (!allowedValues.includes(event)) {\n      throw new Error(`Unexpected value for event passed to hook : '${event}'.\nExpecting one of '${allowedValues.join(\"', '\")}'`);\n    }\n    if (this._lifeCycleHooks[event]) {\n      this._lifeCycleHooks[event].push(listener);\n    } else {\n      this._lifeCycleHooks[event] = [listener];\n    }\n    return this;\n  }\n\n  /**\n   * Register callback to use as replacement for calling process.exit.\n   *\n   * @param {Function} [fn] optional callback which will be passed a CommanderError, defaults to throwing\n   * @return {Command} `this` command for chaining\n   */\n\n  exitOverride(fn) {\n    if (fn) {\n      this._exitCallback = fn;\n    } else {\n      this._exitCallback = (err) => {\n        if (err.code !== 'commander.executeSubCommandAsync') {\n          throw err;\n        } else {\n          // Async callback from spawn events, not useful to throw.\n        }\n      };\n    }\n    return this;\n  }\n\n  /**\n   * Call process.exit, and _exitCallback if defined.\n   *\n   * @param {number} exitCode exit code for using with process.exit\n   * @param {string} code an id string representing the error\n   * @param {string} message human-readable description of the error\n   * @return never\n   * @private\n   */\n\n  _exit(exitCode, code, message) {\n    if (this._exitCallback) {\n      this._exitCallback(new CommanderError(exitCode, code, message));\n      // Expecting this line is not reached.\n    }\n    process.exit(exitCode);\n  }\n\n  /**\n   * Register callback `fn` for the command.\n   *\n   * @example\n   * program\n   *   .command('serve')\n   *   .description('start service')\n   *   .action(function() {\n   *      // do work here\n   *   });\n   *\n   * @param {Function} fn\n   * @return {Command} `this` command for chaining\n   */\n\n  action(fn) {\n    const listener = (args) => {\n      // The .action callback takes an extra parameter which is the command or options.\n      const expectedArgsCount = this.registeredArguments.length;\n      const actionArgs = args.slice(0, expectedArgsCount);\n      if (this._storeOptionsAsProperties) {\n        actionArgs[expectedArgsCount] = this; // backwards compatible \"options\"\n      } else {\n        actionArgs[expectedArgsCount] = this.opts();\n      }\n      actionArgs.push(this);\n\n      return fn.apply(this, actionArgs);\n    };\n    this._actionHandler = listener;\n    return this;\n  }\n\n  /**\n   * Factory routine to create a new unattached option.\n   *\n   * See .option() for creating an attached option, which uses this routine to\n   * create the option. You can override createOption to return a custom option.\n   *\n   * @param {string} flags\n   * @param {string} [description]\n   * @return {Option} new option\n   */\n\n  createOption(flags, description) {\n    return new Option(flags, description);\n  }\n\n  /**\n   * Wrap parseArgs to catch 'commander.invalidArgument'.\n   *\n   * @param {(Option | Argument)} target\n   * @param {string} value\n   * @param {*} previous\n   * @param {string} invalidArgumentMessage\n   * @private\n   */\n\n  _callParseArg(target, value, previous, invalidArgumentMessage) {\n    try {\n      return target.parseArg(value, previous);\n    } catch (err) {\n      if (err.code === 'commander.invalidArgument') {\n        const message = `${invalidArgumentMessage} ${err.message}`;\n        this.error(message, { exitCode: err.exitCode, code: err.code });\n      }\n      throw err;\n    }\n  }\n\n  /**\n   * Check for option flag conflicts.\n   * Register option if no conflicts found, or throw on conflict.\n   *\n   * @param {Option} option\n   * @private\n   */\n\n  _registerOption(option) {\n    const matchingOption =\n      (option.short && this._findOption(option.short)) ||\n      (option.long && this._findOption(option.long));\n    if (matchingOption) {\n      const matchingFlag =\n        option.long && this._findOption(option.long)\n          ? option.long\n          : option.short;\n      throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'\n-  already used by option '${matchingOption.flags}'`);\n    }\n\n    this._initOptionGroup(option);\n    this.options.push(option);\n  }\n\n  /**\n   * Check for command name and alias conflicts with existing commands.\n   * Register command if no conflicts found, or throw on conflict.\n   *\n   * @param {Command} command\n   * @private\n   */\n\n  _registerCommand(command) {\n    const knownBy = (cmd) => {\n      return [cmd.name()].concat(cmd.aliases());\n    };\n\n    const alreadyUsed = knownBy(command).find((name) =>\n      this._findCommand(name),\n    );\n    if (alreadyUsed) {\n      const existingCmd = knownBy(this._findCommand(alreadyUsed)).join('|');\n      const newCmd = knownBy(command).join('|');\n      throw new Error(\n        `cannot add command '${newCmd}' as already have command '${existingCmd}'`,\n      );\n    }\n\n    this._initCommandGroup(command);\n    this.commands.push(command);\n  }\n\n  /**\n   * Add an option.\n   *\n   * @param {Option} option\n   * @return {Command} `this` command for chaining\n   */\n  addOption(option) {\n    this._registerOption(option);\n\n    const oname = option.name();\n    const name = option.attributeName();\n\n    // store default value\n    if (option.negate) {\n      // --no-foo is special and defaults foo to true, unless a --foo option is already defined\n      const positiveLongFlag = option.long.replace(/^--no-/, '--');\n      if (!this._findOption(positiveLongFlag)) {\n        this.setOptionValueWithSource(\n          name,\n          option.defaultValue === undefined ? true : option.defaultValue,\n          'default',\n        );\n      }\n    } else if (option.defaultValue !== undefined) {\n      this.setOptionValueWithSource(name, option.defaultValue, 'default');\n    }\n\n    // handler for cli and env supplied values\n    const handleOptionValue = (val, invalidValueMessage, valueSource) => {\n      // val is null for optional option used without an optional-argument.\n      // val is undefined for boolean and negated option.\n      if (val == null && option.presetArg !== undefined) {\n        val = option.presetArg;\n      }\n\n      // custom processing\n      const oldValue = this.getOptionValue(name);\n      if (val !== null && option.parseArg) {\n        val = this._callParseArg(option, val, oldValue, invalidValueMessage);\n      } else if (val !== null && option.variadic) {\n        val = option._collectValue(val, oldValue);\n      }\n\n      // Fill-in appropriate missing values. Long winded but easy to follow.\n      if (val == null) {\n        if (option.negate) {\n          val = false;\n        } else if (option.isBoolean() || option.optional) {\n          val = true;\n        } else {\n          val = ''; // not normal, parseArg might have failed or be a mock function for testing\n        }\n      }\n      this.setOptionValueWithSource(name, val, valueSource);\n    };\n\n    this.on('option:' + oname, (val) => {\n      const invalidValueMessage = `error: option '${option.flags}' argument '${val}' is invalid.`;\n      handleOptionValue(val, invalidValueMessage, 'cli');\n    });\n\n    if (option.envVar) {\n      this.on('optionEnv:' + oname, (val) => {\n        const invalidValueMessage = `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`;\n        handleOptionValue(val, invalidValueMessage, 'env');\n      });\n    }\n\n    return this;\n  }\n\n  /**\n   * Internal implementation shared by .option() and .requiredOption()\n   *\n   * @return {Command} `this` command for chaining\n   * @private\n   */\n  _optionEx(config, flags, description, fn, defaultValue) {\n    if (typeof flags === 'object' && flags instanceof Option) {\n      throw new Error(\n        'To add an Option object use addOption() instead of option() or requiredOption()',\n      );\n    }\n    const option = this.createOption(flags, description);\n    option.makeOptionMandatory(!!config.mandatory);\n    if (typeof fn === 'function') {\n      option.default(defaultValue).argParser(fn);\n    } else if (fn instanceof RegExp) {\n      // deprecated\n      const regex = fn;\n      fn = (val, def) => {\n        const m = regex.exec(val);\n        return m ? m[0] : def;\n      };\n      option.default(defaultValue).argParser(fn);\n    } else {\n      option.default(fn);\n    }\n\n    return this.addOption(option);\n  }\n\n  /**\n   * Define option with `flags`, `description`, and optional argument parsing function or `defaultValue` or both.\n   *\n   * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space. A required\n   * option-argument is indicated by `<>` and an optional option-argument by `[]`.\n   *\n   * See the README for more details, and see also addOption() and requiredOption().\n   *\n   * @example\n   * program\n   *     .option('-p, --pepper', 'add pepper')\n   *     .option('--pt, --pizza-type <TYPE>', 'type of pizza') // required option-argument\n   *     .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default\n   *     .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function\n   *\n   * @param {string} flags\n   * @param {string} [description]\n   * @param {(Function|*)} [parseArg] - custom option processing function or default value\n   * @param {*} [defaultValue]\n   * @return {Command} `this` command for chaining\n   */\n\n  option(flags, description, parseArg, defaultValue) {\n    return this._optionEx({}, flags, description, parseArg, defaultValue);\n  }\n\n  /**\n   * Add a required option which must have a value after parsing. This usually means\n   * the option must be specified on the command line. (Otherwise the same as .option().)\n   *\n   * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.\n   *\n   * @param {string} flags\n   * @param {string} [description]\n   * @param {(Function|*)} [parseArg] - custom option processing function or default value\n   * @param {*} [defaultValue]\n   * @return {Command} `this` command for chaining\n   */\n\n  requiredOption(flags, description, parseArg, defaultValue) {\n    return this._optionEx(\n      { mandatory: true },\n      flags,\n      description,\n      parseArg,\n      defaultValue,\n    );\n  }\n\n  /**\n   * Alter parsing of short flags with optional values.\n   *\n   * @example\n   * // for `.option('-f,--flag [value]'):\n   * program.combineFlagAndOptionalValue(true);  // `-f80` is treated like `--flag=80`, this is the default behaviour\n   * program.combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`\n   *\n   * @param {boolean} [combine] - if `true` or omitted, an optional value can be specified directly after the flag.\n   * @return {Command} `this` command for chaining\n   */\n  combineFlagAndOptionalValue(combine = true) {\n    this._combineFlagAndOptionalValue = !!combine;\n    return this;\n  }\n\n  /**\n   * Allow unknown options on the command line.\n   *\n   * @param {boolean} [allowUnknown] - if `true` or omitted, no error will be thrown for unknown options.\n   * @return {Command} `this` command for chaining\n   */\n  allowUnknownOption(allowUnknown = true) {\n    this._allowUnknownOption = !!allowUnknown;\n    return this;\n  }\n\n  /**\n   * Allow excess command-arguments on the command line. Pass false to make excess arguments an error.\n   *\n   * @param {boolean} [allowExcess] - if `true` or omitted, no error will be thrown for excess arguments.\n   * @return {Command} `this` command for chaining\n   */\n  allowExcessArguments(allowExcess = true) {\n    this._allowExcessArguments = !!allowExcess;\n    return this;\n  }\n\n  /**\n   * Enable positional options. Positional means global options are specified before subcommands which lets\n   * subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.\n   * The default behaviour is non-positional and global options may appear anywhere on the command line.\n   *\n   * @param {boolean} [positional]\n   * @return {Command} `this` command for chaining\n   */\n  enablePositionalOptions(positional = true) {\n    this._enablePositionalOptions = !!positional;\n    return this;\n  }\n\n  /**\n   * Pass through options that come after command-arguments rather than treat them as command-options,\n   * so actual command-options come before command-arguments. Turning this on for a subcommand requires\n   * positional options to have been enabled on the program (parent commands).\n   * The default behaviour is non-positional and options may appear before or after command-arguments.\n   *\n   * @param {boolean} [passThrough] for unknown options.\n   * @return {Command} `this` command for chaining\n   */\n  passThroughOptions(passThrough = true) {\n    this._passThroughOptions = !!passThrough;\n    this._checkForBrokenPassThrough();\n    return this;\n  }\n\n  /**\n   * @private\n   */\n\n  _checkForBrokenPassThrough() {\n    if (\n      this.parent &&\n      this._passThroughOptions &&\n      !this.parent._enablePositionalOptions\n    ) {\n      throw new Error(\n        `passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`,\n      );\n    }\n  }\n\n  /**\n   * Whether to store option values as properties on command object,\n   * or store separately (specify false). In both cases the option values can be accessed using .opts().\n   *\n   * @param {boolean} [storeAsProperties=true]\n   * @return {Command} `this` command for chaining\n   */\n\n  storeOptionsAsProperties(storeAsProperties = true) {\n    if (this.options.length) {\n      throw new Error('call .storeOptionsAsProperties() before adding options');\n    }\n    if (Object.keys(this._optionValues).length) {\n      throw new Error(\n        'call .storeOptionsAsProperties() before setting option values',\n      );\n    }\n    this._storeOptionsAsProperties = !!storeAsProperties;\n    return this;\n  }\n\n  /**\n   * Retrieve option value.\n   *\n   * @param {string} key\n   * @return {object} value\n   */\n\n  getOptionValue(key) {\n    if (this._storeOptionsAsProperties) {\n      return this[key];\n    }\n    return this._optionValues[key];\n  }\n\n  /**\n   * Store option value.\n   *\n   * @param {string} key\n   * @param {object} value\n   * @return {Command} `this` command for chaining\n   */\n\n  setOptionValue(key, value) {\n    return this.setOptionValueWithSource(key, value, undefined);\n  }\n\n  /**\n   * Store option value and where the value came from.\n   *\n   * @param {string} key\n   * @param {object} value\n   * @param {string} source - expected values are default/config/env/cli/implied\n   * @return {Command} `this` command for chaining\n   */\n\n  setOptionValueWithSource(key, value, source) {\n    if (this._storeOptionsAsProperties) {\n      this[key] = value;\n    } else {\n      this._optionValues[key] = value;\n    }\n    this._optionValueSources[key] = source;\n    return this;\n  }\n\n  /**\n   * Get source of option value.\n   * Expected values are default | config | env | cli | implied\n   *\n   * @param {string} key\n   * @return {string}\n   */\n\n  getOptionValueSource(key) {\n    return this._optionValueSources[key];\n  }\n\n  /**\n   * Get source of option value. See also .optsWithGlobals().\n   * Expected values are default | config | env | cli | implied\n   *\n   * @param {string} key\n   * @return {string}\n   */\n\n  getOptionValueSourceWithGlobals(key) {\n    // global overwrites local, like optsWithGlobals\n    let source;\n    this._getCommandAndAncestors().forEach((cmd) => {\n      if (cmd.getOptionValueSource(key) !== undefined) {\n        source = cmd.getOptionValueSource(key);\n      }\n    });\n    return source;\n  }\n\n  /**\n   * Get user arguments from implied or explicit arguments.\n   * Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches.\n   *\n   * @private\n   */\n\n  _prepareUserArgs(argv, parseOptions) {\n    if (argv !== undefined && !Array.isArray(argv)) {\n      throw new Error('first parameter to parse must be array or undefined');\n    }\n    parseOptions = parseOptions || {};\n\n    // auto-detect argument conventions if nothing supplied\n    if (argv === undefined && parseOptions.from === undefined) {\n      if (process.versions?.electron) {\n        parseOptions.from = 'electron';\n      }\n      // check node specific options for scenarios where user CLI args follow executable without scriptname\n      const execArgv = process.execArgv ?? [];\n      if (\n        execArgv.includes('-e') ||\n        execArgv.includes('--eval') ||\n        execArgv.includes('-p') ||\n        execArgv.includes('--print')\n      ) {\n        parseOptions.from = 'eval'; // internal usage, not documented\n      }\n    }\n\n    // default to using process.argv\n    if (argv === undefined) {\n      argv = process.argv;\n    }\n    this.rawArgs = argv.slice();\n\n    // extract the user args and scriptPath\n    let userArgs;\n    switch (parseOptions.from) {\n      case undefined:\n      case 'node':\n        this._scriptPath = argv[1];\n        userArgs = argv.slice(2);\n        break;\n      case 'electron':\n        // @ts-ignore: because defaultApp is an unknown property\n        if (process.defaultApp) {\n          this._scriptPath = argv[1];\n          userArgs = argv.slice(2);\n        } else {\n          userArgs = argv.slice(1);\n        }\n        break;\n      case 'user':\n        userArgs = argv.slice(0);\n        break;\n      case 'eval':\n        userArgs = argv.slice(1);\n        break;\n      default:\n        throw new Error(\n          `unexpected parse option { from: '${parseOptions.from}' }`,\n        );\n    }\n\n    // Find default name for program from arguments.\n    if (!this._name && this._scriptPath)\n      this.nameFromFilename(this._scriptPath);\n    this._name = this._name || 'program';\n\n    return userArgs;\n  }\n\n  /**\n   * Parse `argv`, setting options and invoking commands when defined.\n   *\n   * Use parseAsync instead of parse if any of your action handlers are async.\n   *\n   * Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!\n   *\n   * Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:\n   * - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that\n   * - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged\n   * - `'user'`: just user arguments\n   *\n   * @example\n   * program.parse(); // parse process.argv and auto-detect electron and special node flags\n   * program.parse(process.argv); // assume argv[0] is app and argv[1] is script\n   * program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]\n   *\n   * @param {string[]} [argv] - optional, defaults to process.argv\n   * @param {object} [parseOptions] - optionally specify style of options with from: node/user/electron\n   * @param {string} [parseOptions.from] - where the args are from: 'node', 'user', 'electron'\n   * @return {Command} `this` command for chaining\n   */\n\n  parse(argv, parseOptions) {\n    this._prepareForParse();\n    const userArgs = this._prepareUserArgs(argv, parseOptions);\n    this._parseCommand([], userArgs);\n\n    return this;\n  }\n\n  /**\n   * Parse `argv`, setting options and invoking commands when defined.\n   *\n   * Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!\n   *\n   * Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:\n   * - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that\n   * - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged\n   * - `'user'`: just user arguments\n   *\n   * @example\n   * await program.parseAsync(); // parse process.argv and auto-detect electron and special node flags\n   * await program.parseAsync(process.argv); // assume argv[0] is app and argv[1] is script\n   * await program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]\n   *\n   * @param {string[]} [argv]\n   * @param {object} [parseOptions]\n   * @param {string} parseOptions.from - where the args are from: 'node', 'user', 'electron'\n   * @return {Promise}\n   */\n\n  async parseAsync(argv, parseOptions) {\n    this._prepareForParse();\n    const userArgs = this._prepareUserArgs(argv, parseOptions);\n    await this._parseCommand([], userArgs);\n\n    return this;\n  }\n\n  _prepareForParse() {\n    if (this._savedState === null) {\n      this.saveStateBeforeParse();\n    } else {\n      this.restoreStateBeforeParse();\n    }\n  }\n\n  /**\n   * Called the first time parse is called to save state and allow a restore before subsequent calls to parse.\n   * Not usually called directly, but available for subclasses to save their custom state.\n   *\n   * This is called in a lazy way. Only commands used in parsing chain will have state saved.\n   */\n  saveStateBeforeParse() {\n    this._savedState = {\n      // name is stable if supplied by author, but may be unspecified for root command and deduced during parsing\n      _name: this._name,\n      // option values before parse have default values (including false for negated options)\n      // shallow clones\n      _optionValues: { ...this._optionValues },\n      _optionValueSources: { ...this._optionValueSources },\n    };\n  }\n\n  /**\n   * Restore state before parse for calls after the first.\n   * Not usually called directly, but available for subclasses to save their custom state.\n   *\n   * This is called in a lazy way. Only commands used in parsing chain will have state restored.\n   */\n  restoreStateBeforeParse() {\n    if (this._storeOptionsAsProperties)\n      throw new Error(`Can not call parse again when storeOptionsAsProperties is true.\n- either make a new Command for each call to parse, or stop storing options as properties`);\n\n    // clear state from _prepareUserArgs\n    this._name = this._savedState._name;\n    this._scriptPath = null;\n    this.rawArgs = [];\n    // clear state from setOptionValueWithSource\n    this._optionValues = { ...this._savedState._optionValues };\n    this._optionValueSources = { ...this._savedState._optionValueSources };\n    // clear state from _parseCommand\n    this.args = [];\n    // clear state from _processArguments\n    this.processedArgs = [];\n  }\n\n  /**\n   * Throw if expected executable is missing. Add lots of help for author.\n   *\n   * @param {string} executableFile\n   * @param {string} executableDir\n   * @param {string} subcommandName\n   */\n  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {\n    if (fs.existsSync(executableFile)) return;\n\n    const executableDirMessage = executableDir\n      ? `searched for local subcommand relative to directory '${executableDir}'`\n      : 'no directory for search for local subcommand, use .executableDir() to supply a custom directory';\n    const executableMissing = `'${executableFile}' does not exist\n - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead\n - if the default executable name is not suitable, use the executableFile option to supply a custom name or path\n - ${executableDirMessage}`;\n    throw new Error(executableMissing);\n  }\n\n  /**\n   * Execute a sub-command executable.\n   *\n   * @private\n   */\n\n  _executeSubCommand(subcommand, args) {\n    args = args.slice();\n    let launchWithNode = false; // Use node for source targets so do not need to get permissions correct, and on Windows.\n    const sourceExt = ['.js', '.ts', '.tsx', '.mjs', '.cjs'];\n\n    function findFile(baseDir, baseName) {\n      // Look for specified file\n      const localBin = path.resolve(baseDir, baseName);\n      if (fs.existsSync(localBin)) return localBin;\n\n      // Stop looking if candidate already has an expected extension.\n      if (sourceExt.includes(path.extname(baseName))) return undefined;\n\n      // Try all the extensions.\n      const foundExt = sourceExt.find((ext) =>\n        fs.existsSync(`${localBin}${ext}`),\n      );\n      if (foundExt) return `${localBin}${foundExt}`;\n\n      return undefined;\n    }\n\n    // Not checking for help first. Unlikely to have mandatory and executable, and can't robustly test for help flags in external command.\n    this._checkForMissingMandatoryOptions();\n    this._checkForConflictingOptions();\n\n    // executableFile and executableDir might be full path, or just a name\n    let executableFile =\n      subcommand._executableFile || `${this._name}-${subcommand._name}`;\n    let executableDir = this._executableDir || '';\n    if (this._scriptPath) {\n      let resolvedScriptPath; // resolve possible symlink for installed npm binary\n      try {\n        resolvedScriptPath = fs.realpathSync(this._scriptPath);\n      } catch {\n        resolvedScriptPath = this._scriptPath;\n      }\n      executableDir = path.resolve(\n        path.dirname(resolvedScriptPath),\n        executableDir,\n      );\n    }\n\n    // Look for a local file in preference to a command in PATH.\n    if (executableDir) {\n      let localFile = findFile(executableDir, executableFile);\n\n      // Legacy search using prefix of script name instead of command name\n      if (!localFile && !subcommand._executableFile && this._scriptPath) {\n        const legacyName = path.basename(\n          this._scriptPath,\n          path.extname(this._scriptPath),\n        );\n        if (legacyName !== this._name) {\n          localFile = findFile(\n            executableDir,\n            `${legacyName}-${subcommand._name}`,\n          );\n        }\n      }\n      executableFile = localFile || executableFile;\n    }\n\n    launchWithNode = sourceExt.includes(path.extname(executableFile));\n\n    let proc;\n    if (process.platform !== 'win32') {\n      if (launchWithNode) {\n        args.unshift(executableFile);\n        // add executable arguments to spawn\n        args = incrementNodeInspectorPort(process.execArgv).concat(args);\n\n        proc = childProcess.spawn(process.argv[0], args, { stdio: 'inherit' });\n      } else {\n        proc = childProcess.spawn(executableFile, args, { stdio: 'inherit' });\n      }\n    } else {\n      this._checkForMissingExecutable(\n        executableFile,\n        executableDir,\n        subcommand._name,\n      );\n      args.unshift(executableFile);\n      // add executable arguments to spawn\n      args = incrementNodeInspectorPort(process.execArgv).concat(args);\n      proc = childProcess.spawn(process.execPath, args, { stdio: 'inherit' });\n    }\n\n    if (!proc.killed) {\n      // testing mainly to avoid leak warnings during unit tests with mocked spawn\n      const signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP'];\n      signals.forEach((signal) => {\n        process.on(signal, () => {\n          if (proc.killed === false && proc.exitCode === null) {\n            // @ts-ignore because signals not typed to known strings\n            proc.kill(signal);\n          }\n        });\n      });\n    }\n\n    // By default terminate process when spawned process terminates.\n    const exitCallback = this._exitCallback;\n    proc.on('close', (code) => {\n      code = code ?? 1; // code is null if spawned process terminated due to a signal\n      if (!exitCallback) {\n        process.exit(code);\n      } else {\n        exitCallback(\n          new CommanderError(\n            code,\n            'commander.executeSubCommandAsync',\n            '(close)',\n          ),\n        );\n      }\n    });\n    proc.on('error', (err) => {\n      // @ts-ignore: because err.code is an unknown property\n      if (err.code === 'ENOENT') {\n        this._checkForMissingExecutable(\n          executableFile,\n          executableDir,\n          subcommand._name,\n        );\n        // @ts-ignore: because err.code is an unknown property\n      } else if (err.code === 'EACCES') {\n        throw new Error(`'${executableFile}' not executable`);\n      }\n      if (!exitCallback) {\n        process.exit(1);\n      } else {\n        const wrappedError = new CommanderError(\n          1,\n          'commander.executeSubCommandAsync',\n          '(error)',\n        );\n        wrappedError.nestedError = err;\n        exitCallback(wrappedError);\n      }\n    });\n\n    // Store the reference to the child process\n    this.runningCommand = proc;\n  }\n\n  /**\n   * @private\n   */\n\n  _dispatchSubcommand(commandName, operands, unknown) {\n    const subCommand = this._findCommand(commandName);\n    if (!subCommand) this.help({ error: true });\n\n    subCommand._prepareForParse();\n    let promiseChain;\n    promiseChain = this._chainOrCallSubCommandHook(\n      promiseChain,\n      subCommand,\n      'preSubcommand',\n    );\n    promiseChain = this._chainOrCall(promiseChain, () => {\n      if (subCommand._executableHandler) {\n        this._executeSubCommand(subCommand, operands.concat(unknown));\n      } else {\n        return subCommand._parseCommand(operands, unknown);\n      }\n    });\n    return promiseChain;\n  }\n\n  /**\n   * Invoke help directly if possible, or dispatch if necessary.\n   * e.g. help foo\n   *\n   * @private\n   */\n\n  _dispatchHelpCommand(subcommandName) {\n    if (!subcommandName) {\n      this.help();\n    }\n    const subCommand = this._findCommand(subcommandName);\n    if (subCommand && !subCommand._executableHandler) {\n      subCommand.help();\n    }\n\n    // Fallback to parsing the help flag to invoke the help.\n    return this._dispatchSubcommand(\n      subcommandName,\n      [],\n      [this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? '--help'],\n    );\n  }\n\n  /**\n   * Check this.args against expected this.registeredArguments.\n   *\n   * @private\n   */\n\n  _checkNumberOfArguments() {\n    // too few\n    this.registeredArguments.forEach((arg, i) => {\n      if (arg.required && this.args[i] == null) {\n        this.missingArgument(arg.name());\n      }\n    });\n    // too many\n    if (\n      this.registeredArguments.length > 0 &&\n      this.registeredArguments[this.registeredArguments.length - 1].variadic\n    ) {\n      return;\n    }\n    if (this.args.length > this.registeredArguments.length) {\n      this._excessArguments(this.args);\n    }\n  }\n\n  /**\n   * Process this.args using this.registeredArguments and save as this.processedArgs!\n   *\n   * @private\n   */\n\n  _processArguments() {\n    const myParseArg = (argument, value, previous) => {\n      // Extra processing for nice error message on parsing failure.\n      let parsedValue = value;\n      if (value !== null && argument.parseArg) {\n        const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;\n        parsedValue = this._callParseArg(\n          argument,\n          value,\n          previous,\n          invalidValueMessage,\n        );\n      }\n      return parsedValue;\n    };\n\n    this._checkNumberOfArguments();\n\n    const processedArgs = [];\n    this.registeredArguments.forEach((declaredArg, index) => {\n      let value = declaredArg.defaultValue;\n      if (declaredArg.variadic) {\n        // Collect together remaining arguments for passing together as an array.\n        if (index < this.args.length) {\n          value = this.args.slice(index);\n          if (declaredArg.parseArg) {\n            value = value.reduce((processed, v) => {\n              return myParseArg(declaredArg, v, processed);\n            }, declaredArg.defaultValue);\n          }\n        } else if (value === undefined) {\n          value = [];\n        }\n      } else if (index < this.args.length) {\n        value = this.args[index];\n        if (declaredArg.parseArg) {\n          value = myParseArg(declaredArg, value, declaredArg.defaultValue);\n        }\n      }\n      processedArgs[index] = value;\n    });\n    this.processedArgs = processedArgs;\n  }\n\n  /**\n   * Once we have a promise we chain, but call synchronously until then.\n   *\n   * @param {(Promise|undefined)} promise\n   * @param {Function} fn\n   * @return {(Promise|undefined)}\n   * @private\n   */\n\n  _chainOrCall(promise, fn) {\n    // thenable\n    if (promise?.then && typeof promise.then === 'function') {\n      // already have a promise, chain callback\n      return promise.then(() => fn());\n    }\n    // callback might return a promise\n    return fn();\n  }\n\n  /**\n   *\n   * @param {(Promise|undefined)} promise\n   * @param {string} event\n   * @return {(Promise|undefined)}\n   * @private\n   */\n\n  _chainOrCallHooks(promise, event) {\n    let result = promise;\n    const hooks = [];\n    this._getCommandAndAncestors()\n      .reverse()\n      .filter((cmd) => cmd._lifeCycleHooks[event] !== undefined)\n      .forEach((hookedCommand) => {\n        hookedCommand._lifeCycleHooks[event].forEach((callback) => {\n          hooks.push({ hookedCommand, callback });\n        });\n      });\n    if (event === 'postAction') {\n      hooks.reverse();\n    }\n\n    hooks.forEach((hookDetail) => {\n      result = this._chainOrCall(result, () => {\n        return hookDetail.callback(hookDetail.hookedCommand, this);\n      });\n    });\n    return result;\n  }\n\n  /**\n   *\n   * @param {(Promise|undefined)} promise\n   * @param {Command} subCommand\n   * @param {string} event\n   * @return {(Promise|undefined)}\n   * @private\n   */\n\n  _chainOrCallSubCommandHook(promise, subCommand, event) {\n    let result = promise;\n    if (this._lifeCycleHooks[event] !== undefined) {\n      this._lifeCycleHooks[event].forEach((hook) => {\n        result = this._chainOrCall(result, () => {\n          return hook(this, subCommand);\n        });\n      });\n    }\n    return result;\n  }\n\n  /**\n   * Process arguments in context of this command.\n   * Returns action result, in case it is a promise.\n   *\n   * @private\n   */\n\n  _parseCommand(operands, unknown) {\n    const parsed = this.parseOptions(unknown);\n    this._parseOptionsEnv(); // after cli, so parseArg not called on both cli and env\n    this._parseOptionsImplied();\n    operands = operands.concat(parsed.operands);\n    unknown = parsed.unknown;\n    this.args = operands.concat(unknown);\n\n    if (operands && this._findCommand(operands[0])) {\n      return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);\n    }\n    if (\n      this._getHelpCommand() &&\n      operands[0] === this._getHelpCommand().name()\n    ) {\n      return this._dispatchHelpCommand(operands[1]);\n    }\n    if (this._defaultCommandName) {\n      this._outputHelpIfRequested(unknown); // Run the help for default command from parent rather than passing to default command\n      return this._dispatchSubcommand(\n        this._defaultCommandName,\n        operands,\n        unknown,\n      );\n    }\n    if (\n      this.commands.length &&\n      this.args.length === 0 &&\n      !this._actionHandler &&\n      !this._defaultCommandName\n    ) {\n      // probably missing subcommand and no handler, user needs help (and exit)\n      this.help({ error: true });\n    }\n\n    this._outputHelpIfRequested(parsed.unknown);\n    this._checkForMissingMandatoryOptions();\n    this._checkForConflictingOptions();\n\n    // We do not always call this check to avoid masking a \"better\" error, like unknown command.\n    const checkForUnknownOptions = () => {\n      if (parsed.unknown.length > 0) {\n        this.unknownOption(parsed.unknown[0]);\n      }\n    };\n\n    const commandEvent = `command:${this.name()}`;\n    if (this._actionHandler) {\n      checkForUnknownOptions();\n      this._processArguments();\n\n      let promiseChain;\n      promiseChain = this._chainOrCallHooks(promiseChain, 'preAction');\n      promiseChain = this._chainOrCall(promiseChain, () =>\n        this._actionHandler(this.processedArgs),\n      );\n      if (this.parent) {\n        promiseChain = this._chainOrCall(promiseChain, () => {\n          this.parent.emit(commandEvent, operands, unknown); // legacy\n        });\n      }\n      promiseChain = this._chainOrCallHooks(promiseChain, 'postAction');\n      return promiseChain;\n    }\n    if (this.parent?.listenerCount(commandEvent)) {\n      checkForUnknownOptions();\n      this._processArguments();\n      this.parent.emit(commandEvent, operands, unknown); // legacy\n    } else if (operands.length) {\n      if (this._findCommand('*')) {\n        // legacy default command\n        return this._dispatchSubcommand('*', operands, unknown);\n      }\n      if (this.listenerCount('command:*')) {\n        // skip option check, emit event for possible misspelling suggestion\n        this.emit('command:*', operands, unknown);\n      } else if (this.commands.length) {\n        this.unknownCommand();\n      } else {\n        checkForUnknownOptions();\n        this._processArguments();\n      }\n    } else if (this.commands.length) {\n      checkForUnknownOptions();\n      // This command has subcommands and nothing hooked up at this level, so display help (and exit).\n      this.help({ error: true });\n    } else {\n      checkForUnknownOptions();\n      this._processArguments();\n      // fall through for caller to handle after calling .parse()\n    }\n  }\n\n  /**\n   * Find matching command.\n   *\n   * @private\n   * @return {Command | undefined}\n   */\n  _findCommand(name) {\n    if (!name) return undefined;\n    return this.commands.find(\n      (cmd) => cmd._name === name || cmd._aliases.includes(name),\n    );\n  }\n\n  /**\n   * Return an option matching `arg` if any.\n   *\n   * @param {string} arg\n   * @return {Option}\n   * @package\n   */\n\n  _findOption(arg) {\n    return this.options.find((option) => option.is(arg));\n  }\n\n  /**\n   * Display an error message if a mandatory option does not have a value.\n   * Called after checking for help flags in leaf subcommand.\n   *\n   * @private\n   */\n\n  _checkForMissingMandatoryOptions() {\n    // Walk up hierarchy so can call in subcommand after checking for displaying help.\n    this._getCommandAndAncestors().forEach((cmd) => {\n      cmd.options.forEach((anOption) => {\n        if (\n          anOption.mandatory &&\n          cmd.getOptionValue(anOption.attributeName()) === undefined\n        ) {\n          cmd.missingMandatoryOptionValue(anOption);\n        }\n      });\n    });\n  }\n\n  /**\n   * Display an error message if conflicting options are used together in this.\n   *\n   * @private\n   */\n  _checkForConflictingLocalOptions() {\n    const definedNonDefaultOptions = this.options.filter((option) => {\n      const optionKey = option.attributeName();\n      if (this.getOptionValue(optionKey) === undefined) {\n        return false;\n      }\n      return this.getOptionValueSource(optionKey) !== 'default';\n    });\n\n    const optionsWithConflicting = definedNonDefaultOptions.filter(\n      (option) => option.conflictsWith.length > 0,\n    );\n\n    optionsWithConflicting.forEach((option) => {\n      const conflictingAndDefined = definedNonDefaultOptions.find((defined) =>\n        option.conflictsWith.includes(defined.attributeName()),\n      );\n      if (conflictingAndDefined) {\n        this._conflictingOption(option, conflictingAndDefined);\n      }\n    });\n  }\n\n  /**\n   * Display an error message if conflicting options are used together.\n   * Called after checking for help flags in leaf subcommand.\n   *\n   * @private\n   */\n  _checkForConflictingOptions() {\n    // Walk up hierarchy so can call in subcommand after checking for displaying help.\n    this._getCommandAndAncestors().forEach((cmd) => {\n      cmd._checkForConflictingLocalOptions();\n    });\n  }\n\n  /**\n   * Parse options from `argv` removing known options,\n   * and return argv split into operands and unknown arguments.\n   *\n   * Side effects: modifies command by storing options. Does not reset state if called again.\n   *\n   * Examples:\n   *\n   *     argv => operands, unknown\n   *     --known kkk op => [op], []\n   *     op --known kkk => [op], []\n   *     sub --unknown uuu op => [sub], [--unknown uuu op]\n   *     sub -- --unknown uuu op => [sub --unknown uuu op], []\n   *\n   * @param {string[]} args\n   * @return {{operands: string[], unknown: string[]}}\n   */\n\n  parseOptions(args) {\n    const operands = []; // operands, not options or values\n    const unknown = []; // first unknown option and remaining unknown args\n    let dest = operands;\n\n    function maybeOption(arg) {\n      return arg.length > 1 && arg[0] === '-';\n    }\n\n    const negativeNumberArg = (arg) => {\n      // return false if not a negative number\n      if (!/^-(\\d+|\\d*\\.\\d+)(e[+-]?\\d+)?$/.test(arg)) return false;\n      // negative number is ok unless digit used as an option in command hierarchy\n      return !this._getCommandAndAncestors().some((cmd) =>\n        cmd.options\n          .map((opt) => opt.short)\n          .some((short) => /^-\\d$/.test(short)),\n      );\n    };\n\n    // parse options\n    let activeVariadicOption = null;\n    let activeGroup = null; // working through group of short options, like -abc\n    let i = 0;\n    while (i < args.length || activeGroup) {\n      const arg = activeGroup ?? args[i++];\n      activeGroup = null;\n\n      // literal\n      if (arg === '--') {\n        if (dest === unknown) dest.push(arg);\n        dest.push(...args.slice(i));\n        break;\n      }\n\n      if (\n        activeVariadicOption &&\n        (!maybeOption(arg) || negativeNumberArg(arg))\n      ) {\n        this.emit(`option:${activeVariadicOption.name()}`, arg);\n        continue;\n      }\n      activeVariadicOption = null;\n\n      if (maybeOption(arg)) {\n        const option = this._findOption(arg);\n        // recognised option, call listener to assign value with possible custom processing\n        if (option) {\n          if (option.required) {\n            const value = args[i++];\n            if (value === undefined) this.optionMissingArgument(option);\n            this.emit(`option:${option.name()}`, value);\n          } else if (option.optional) {\n            let value = null;\n            // historical behaviour is optional value is following arg unless an option\n            if (\n              i < args.length &&\n              (!maybeOption(args[i]) || negativeNumberArg(args[i]))\n            ) {\n              value = args[i++];\n            }\n            this.emit(`option:${option.name()}`, value);\n          } else {\n            // boolean flag\n            this.emit(`option:${option.name()}`);\n          }\n          activeVariadicOption = option.variadic ? option : null;\n          continue;\n        }\n      }\n\n      // Look for combo options following single dash, eat first one if known.\n      if (arg.length > 2 && arg[0] === '-' && arg[1] !== '-') {\n        const option = this._findOption(`-${arg[1]}`);\n        if (option) {\n          if (\n            option.required ||\n            (option.optional && this._combineFlagAndOptionalValue)\n          ) {\n            // option with value following in same argument\n            this.emit(`option:${option.name()}`, arg.slice(2));\n          } else {\n            // boolean option\n            this.emit(`option:${option.name()}`);\n            // remove the processed option and keep processing group\n            activeGroup = `-${arg.slice(2)}`;\n          }\n          continue;\n        }\n      }\n\n      // Look for known long flag with value, like --foo=bar\n      if (/^--[^=]+=/.test(arg)) {\n        const index = arg.indexOf('=');\n        const option = this._findOption(arg.slice(0, index));\n        if (option && (option.required || option.optional)) {\n          this.emit(`option:${option.name()}`, arg.slice(index + 1));\n          continue;\n        }\n      }\n\n      // Not a recognised option by this command.\n      // Might be a command-argument, or subcommand option, or unknown option, or help command or option.\n\n      // An unknown option means further arguments also classified as unknown so can be reprocessed by subcommands.\n      // A negative number in a leaf command is not an unknown option.\n      if (\n        dest === operands &&\n        maybeOption(arg) &&\n        !(this.commands.length === 0 && negativeNumberArg(arg))\n      ) {\n        dest = unknown;\n      }\n\n      // If using positionalOptions, stop processing our options at subcommand.\n      if (\n        (this._enablePositionalOptions || this._passThroughOptions) &&\n        operands.length === 0 &&\n        unknown.length === 0\n      ) {\n        if (this._findCommand(arg)) {\n          operands.push(arg);\n          unknown.push(...args.slice(i));\n          break;\n        } else if (\n          this._getHelpCommand() &&\n          arg === this._getHelpCommand().name()\n        ) {\n          operands.push(arg, ...args.slice(i));\n          break;\n        } else if (this._defaultCommandName) {\n          unknown.push(arg, ...args.slice(i));\n          break;\n        }\n      }\n\n      // If using passThroughOptions, stop processing options at first command-argument.\n      if (this._passThroughOptions) {\n        dest.push(arg, ...args.slice(i));\n        break;\n      }\n\n      // add arg\n      dest.push(arg);\n    }\n\n    return { operands, unknown };\n  }\n\n  /**\n   * Return an object containing local option values as key-value pairs.\n   *\n   * @return {object}\n   */\n  opts() {\n    if (this._storeOptionsAsProperties) {\n      // Preserve original behaviour so backwards compatible when still using properties\n      const result = {};\n      const len = this.options.length;\n\n      for (let i = 0; i < len; i++) {\n        const key = this.options[i].attributeName();\n        result[key] =\n          key === this._versionOptionName ? this._version : this[key];\n      }\n      return result;\n    }\n\n    return this._optionValues;\n  }\n\n  /**\n   * Return an object containing merged local and global option values as key-value pairs.\n   *\n   * @return {object}\n   */\n  optsWithGlobals() {\n    // globals overwrite locals\n    return this._getCommandAndAncestors().reduce(\n      (combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()),\n      {},\n    );\n  }\n\n  /**\n   * Display error message and exit (or call exitOverride).\n   *\n   * @param {string} message\n   * @param {object} [errorOptions]\n   * @param {string} [errorOptions.code] - an id string representing the error\n   * @param {number} [errorOptions.exitCode] - used with process.exit\n   */\n  error(message, errorOptions) {\n    // output handling\n    this._outputConfiguration.outputError(\n      `${message}\\n`,\n      this._outputConfiguration.writeErr,\n    );\n    if (typeof this._showHelpAfterError === 'string') {\n      this._outputConfiguration.writeErr(`${this._showHelpAfterError}\\n`);\n    } else if (this._showHelpAfterError) {\n      this._outputConfiguration.writeErr('\\n');\n      this.outputHelp({ error: true });\n    }\n\n    // exit handling\n    const config = errorOptions || {};\n    const exitCode = config.exitCode || 1;\n    const code = config.code || 'commander.error';\n    this._exit(exitCode, code, message);\n  }\n\n  /**\n   * Apply any option related environment variables, if option does\n   * not have a value from cli or client code.\n   *\n   * @private\n   */\n  _parseOptionsEnv() {\n    this.options.forEach((option) => {\n      if (option.envVar && option.envVar in process.env) {\n        const optionKey = option.attributeName();\n        // Priority check. Do not overwrite cli or options from unknown source (client-code).\n        if (\n          this.getOptionValue(optionKey) === undefined ||\n          ['default', 'config', 'env'].includes(\n            this.getOptionValueSource(optionKey),\n          )\n        ) {\n          if (option.required || option.optional) {\n            // option can take a value\n            // keep very simple, optional always takes value\n            this.emit(`optionEnv:${option.name()}`, process.env[option.envVar]);\n          } else {\n            // boolean\n            // keep very simple, only care that envVar defined and not the value\n            this.emit(`optionEnv:${option.name()}`);\n          }\n        }\n      }\n    });\n  }\n\n  /**\n   * Apply any implied option values, if option is undefined or default value.\n   *\n   * @private\n   */\n  _parseOptionsImplied() {\n    const dualHelper = new DualOptions(this.options);\n    const hasCustomOptionValue = (optionKey) => {\n      return (\n        this.getOptionValue(optionKey) !== undefined &&\n        !['default', 'implied'].includes(this.getOptionValueSource(optionKey))\n      );\n    };\n    this.options\n      .filter(\n        (option) =>\n          option.implied !== undefined &&\n          hasCustomOptionValue(option.attributeName()) &&\n          dualHelper.valueFromOption(\n            this.getOptionValue(option.attributeName()),\n            option,\n          ),\n      )\n      .forEach((option) => {\n        Object.keys(option.implied)\n          .filter((impliedKey) => !hasCustomOptionValue(impliedKey))\n          .forEach((impliedKey) => {\n            this.setOptionValueWithSource(\n              impliedKey,\n              option.implied[impliedKey],\n              'implied',\n            );\n          });\n      });\n  }\n\n  /**\n   * Argument `name` is missing.\n   *\n   * @param {string} name\n   * @private\n   */\n\n  missingArgument(name) {\n    const message = `error: missing required argument '${name}'`;\n    this.error(message, { code: 'commander.missingArgument' });\n  }\n\n  /**\n   * `Option` is missing an argument.\n   *\n   * @param {Option} option\n   * @private\n   */\n\n  optionMissingArgument(option) {\n    const message = `error: option '${option.flags}' argument missing`;\n    this.error(message, { code: 'commander.optionMissingArgument' });\n  }\n\n  /**\n   * `Option` does not have a value, and is a mandatory option.\n   *\n   * @param {Option} option\n   * @private\n   */\n\n  missingMandatoryOptionValue(option) {\n    const message = `error: required option '${option.flags}' not specified`;\n    this.error(message, { code: 'commander.missingMandatoryOptionValue' });\n  }\n\n  /**\n   * `Option` conflicts with another option.\n   *\n   * @param {Option} option\n   * @param {Option} conflictingOption\n   * @private\n   */\n  _conflictingOption(option, conflictingOption) {\n    // The calling code does not know whether a negated option is the source of the\n    // value, so do some work to take an educated guess.\n    const findBestOptionFromValue = (option) => {\n      const optionKey = option.attributeName();\n      const optionValue = this.getOptionValue(optionKey);\n      const negativeOption = this.options.find(\n        (target) => target.negate && optionKey === target.attributeName(),\n      );\n      const positiveOption = this.options.find(\n        (target) => !target.negate && optionKey === target.attributeName(),\n      );\n      if (\n        negativeOption &&\n        ((negativeOption.presetArg === undefined && optionValue === false) ||\n          (negativeOption.presetArg !== undefined &&\n            optionValue === negativeOption.presetArg))\n      ) {\n        return negativeOption;\n      }\n      return positiveOption || option;\n    };\n\n    const getErrorMessage = (option) => {\n      const bestOption = findBestOptionFromValue(option);\n      const optionKey = bestOption.attributeName();\n      const source = this.getOptionValueSource(optionKey);\n      if (source === 'env') {\n        return `environment variable '${bestOption.envVar}'`;\n      }\n      return `option '${bestOption.flags}'`;\n    };\n\n    const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;\n    this.error(message, { code: 'commander.conflictingOption' });\n  }\n\n  /**\n   * Unknown option `flag`.\n   *\n   * @param {string} flag\n   * @private\n   */\n\n  unknownOption(flag) {\n    if (this._allowUnknownOption) return;\n    let suggestion = '';\n\n    if (flag.startsWith('--') && this._showSuggestionAfterError) {\n      // Looping to pick up the global options too\n      let candidateFlags = [];\n      // eslint-disable-next-line @typescript-eslint/no-this-alias\n      let command = this;\n      do {\n        const moreFlags = command\n          .createHelp()\n          .visibleOptions(command)\n          .filter((option) => option.long)\n          .map((option) => option.long);\n        candidateFlags = candidateFlags.concat(moreFlags);\n        command = command.parent;\n      } while (command && !command._enablePositionalOptions);\n      suggestion = suggestSimilar(flag, candidateFlags);\n    }\n\n    const message = `error: unknown option '${flag}'${suggestion}`;\n    this.error(message, { code: 'commander.unknownOption' });\n  }\n\n  /**\n   * Excess arguments, more than expected.\n   *\n   * @param {string[]} receivedArgs\n   * @private\n   */\n\n  _excessArguments(receivedArgs) {\n    if (this._allowExcessArguments) return;\n\n    const expected = this.registeredArguments.length;\n    const s = expected === 1 ? '' : 's';\n    const forSubcommand = this.parent ? ` for '${this.name()}'` : '';\n    const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;\n    this.error(message, { code: 'commander.excessArguments' });\n  }\n\n  /**\n   * Unknown command.\n   *\n   * @private\n   */\n\n  unknownCommand() {\n    const unknownName = this.args[0];\n    let suggestion = '';\n\n    if (this._showSuggestionAfterError) {\n      const candidateNames = [];\n      this.createHelp()\n        .visibleCommands(this)\n        .forEach((command) => {\n          candidateNames.push(command.name());\n          // just visible alias\n          if (command.alias()) candidateNames.push(command.alias());\n        });\n      suggestion = suggestSimilar(unknownName, candidateNames);\n    }\n\n    const message = `error: unknown command '${unknownName}'${suggestion}`;\n    this.error(message, { code: 'commander.unknownCommand' });\n  }\n\n  /**\n   * Get or set the program version.\n   *\n   * This method auto-registers the \"-V, --version\" option which will print the version number.\n   *\n   * You can optionally supply the flags and description to override the defaults.\n   *\n   * @param {string} [str]\n   * @param {string} [flags]\n   * @param {string} [description]\n   * @return {(this | string | undefined)} `this` command for chaining, or version string if no arguments\n   */\n\n  version(str, flags, description) {\n    if (str === undefined) return this._version;\n    this._version = str;\n    flags = flags || '-V, --version';\n    description = description || 'output the version number';\n    const versionOption = this.createOption(flags, description);\n    this._versionOptionName = versionOption.attributeName();\n    this._registerOption(versionOption);\n\n    this.on('option:' + versionOption.name(), () => {\n      this._outputConfiguration.writeOut(`${str}\\n`);\n      this._exit(0, 'commander.version', str);\n    });\n    return this;\n  }\n\n  /**\n   * Set the description.\n   *\n   * @param {string} [str]\n   * @param {object} [argsDescription]\n   * @return {(string|Command)}\n   */\n  description(str, argsDescription) {\n    if (str === undefined && argsDescription === undefined)\n      return this._description;\n    this._description = str;\n    if (argsDescription) {\n      this._argsDescription = argsDescription;\n    }\n    return this;\n  }\n\n  /**\n   * Set the summary. Used when listed as subcommand of parent.\n   *\n   * @param {string} [str]\n   * @return {(string|Command)}\n   */\n  summary(str) {\n    if (str === undefined) return this._summary;\n    this._summary = str;\n    return this;\n  }\n\n  /**\n   * Set an alias for the command.\n   *\n   * You may call more than once to add multiple aliases. Only the first alias is shown in the auto-generated help.\n   *\n   * @param {string} [alias]\n   * @return {(string|Command)}\n   */\n\n  alias(alias) {\n    if (alias === undefined) return this._aliases[0]; // just return first, for backwards compatibility\n\n    /** @type {Command} */\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    let command = this;\n    if (\n      this.commands.length !== 0 &&\n      this.commands[this.commands.length - 1]._executableHandler\n    ) {\n      // assume adding alias for last added executable subcommand, rather than this\n      command = this.commands[this.commands.length - 1];\n    }\n\n    if (alias === command._name)\n      throw new Error(\"Command alias can't be the same as its name\");\n    const matchingCommand = this.parent?._findCommand(alias);\n    if (matchingCommand) {\n      // c.f. _registerCommand\n      const existingCmd = [matchingCommand.name()]\n        .concat(matchingCommand.aliases())\n        .join('|');\n      throw new Error(\n        `cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`,\n      );\n    }\n\n    command._aliases.push(alias);\n    return this;\n  }\n\n  /**\n   * Set aliases for the command.\n   *\n   * Only the first alias is shown in the auto-generated help.\n   *\n   * @param {string[]} [aliases]\n   * @return {(string[]|Command)}\n   */\n\n  aliases(aliases) {\n    // Getter for the array of aliases is the main reason for having aliases() in addition to alias().\n    if (aliases === undefined) return this._aliases;\n\n    aliases.forEach((alias) => this.alias(alias));\n    return this;\n  }\n\n  /**\n   * Set / get the command usage `str`.\n   *\n   * @param {string} [str]\n   * @return {(string|Command)}\n   */\n\n  usage(str) {\n    if (str === undefined) {\n      if (this._usage) return this._usage;\n\n      const args = this.registeredArguments.map((arg) => {\n        return humanReadableArgName(arg);\n      });\n      return []\n        .concat(\n          this.options.length || this._helpOption !== null ? '[options]' : [],\n          this.commands.length ? '[command]' : [],\n          this.registeredArguments.length ? args : [],\n        )\n        .join(' ');\n    }\n\n    this._usage = str;\n    return this;\n  }\n\n  /**\n   * Get or set the name of the command.\n   *\n   * @param {string} [str]\n   * @return {(string|Command)}\n   */\n\n  name(str) {\n    if (str === undefined) return this._name;\n    this._name = str;\n    return this;\n  }\n\n  /**\n   * Set/get the help group heading for this subcommand in parent command's help.\n   *\n   * @param {string} [heading]\n   * @return {Command | string}\n   */\n\n  helpGroup(heading) {\n    if (heading === undefined) return this._helpGroupHeading ?? '';\n    this._helpGroupHeading = heading;\n    return this;\n  }\n\n  /**\n   * Set/get the default help group heading for subcommands added to this command.\n   * (This does not override a group set directly on the subcommand using .helpGroup().)\n   *\n   * @example\n   * program.commandsGroup('Development Commands:);\n   * program.command('watch')...\n   * program.command('lint')...\n   * ...\n   *\n   * @param {string} [heading]\n   * @returns {Command | string}\n   */\n  commandsGroup(heading) {\n    if (heading === undefined) return this._defaultCommandGroup ?? '';\n    this._defaultCommandGroup = heading;\n    return this;\n  }\n\n  /**\n   * Set/get the default help group heading for options added to this command.\n   * (This does not override a group set directly on the option using .helpGroup().)\n   *\n   * @example\n   * program\n   *   .optionsGroup('Development Options:')\n   *   .option('-d, --debug', 'output extra debugging')\n   *   .option('-p, --profile', 'output profiling information')\n   *\n   * @param {string} [heading]\n   * @returns {Command | string}\n   */\n  optionsGroup(heading) {\n    if (heading === undefined) return this._defaultOptionGroup ?? '';\n    this._defaultOptionGroup = heading;\n    return this;\n  }\n\n  /**\n   * @param {Option} option\n   * @private\n   */\n  _initOptionGroup(option) {\n    if (this._defaultOptionGroup && !option.helpGroupHeading)\n      option.helpGroup(this._defaultOptionGroup);\n  }\n\n  /**\n   * @param {Command} cmd\n   * @private\n   */\n  _initCommandGroup(cmd) {\n    if (this._defaultCommandGroup && !cmd.helpGroup())\n      cmd.helpGroup(this._defaultCommandGroup);\n  }\n\n  /**\n   * Set the name of the command from script filename, such as process.argv[1],\n   * or require.main.filename, or __filename.\n   *\n   * (Used internally and public although not documented in README.)\n   *\n   * @example\n   * program.nameFromFilename(require.main.filename);\n   *\n   * @param {string} filename\n   * @return {Command}\n   */\n\n  nameFromFilename(filename) {\n    this._name = path.basename(filename, path.extname(filename));\n\n    return this;\n  }\n\n  /**\n   * Get or set the directory for searching for executable subcommands of this command.\n   *\n   * @example\n   * program.executableDir(__dirname);\n   * // or\n   * program.executableDir('subcommands');\n   *\n   * @param {string} [path]\n   * @return {(string|null|Command)}\n   */\n\n  executableDir(path) {\n    if (path === undefined) return this._executableDir;\n    this._executableDir = path;\n    return this;\n  }\n\n  /**\n   * Return program help documentation.\n   *\n   * @param {{ error: boolean }} [contextOptions] - pass {error:true} to wrap for stderr instead of stdout\n   * @return {string}\n   */\n\n  helpInformation(contextOptions) {\n    const helper = this.createHelp();\n    const context = this._getOutputContext(contextOptions);\n    helper.prepareContext({\n      error: context.error,\n      helpWidth: context.helpWidth,\n      outputHasColors: context.hasColors,\n    });\n    const text = helper.formatHelp(this, helper);\n    if (context.hasColors) return text;\n    return this._outputConfiguration.stripColor(text);\n  }\n\n  /**\n   * @typedef HelpContext\n   * @type {object}\n   * @property {boolean} error\n   * @property {number} helpWidth\n   * @property {boolean} hasColors\n   * @property {function} write - includes stripColor if needed\n   *\n   * @returns {HelpContext}\n   * @private\n   */\n\n  _getOutputContext(contextOptions) {\n    contextOptions = contextOptions || {};\n    const error = !!contextOptions.error;\n    let baseWrite;\n    let hasColors;\n    let helpWidth;\n    if (error) {\n      baseWrite = (str) => this._outputConfiguration.writeErr(str);\n      hasColors = this._outputConfiguration.getErrHasColors();\n      helpWidth = this._outputConfiguration.getErrHelpWidth();\n    } else {\n      baseWrite = (str) => this._outputConfiguration.writeOut(str);\n      hasColors = this._outputConfiguration.getOutHasColors();\n      helpWidth = this._outputConfiguration.getOutHelpWidth();\n    }\n    const write = (str) => {\n      if (!hasColors) str = this._outputConfiguration.stripColor(str);\n      return baseWrite(str);\n    };\n    return { error, write, hasColors, helpWidth };\n  }\n\n  /**\n   * Output help information for this command.\n   *\n   * Outputs built-in help, and custom text added using `.addHelpText()`.\n   *\n   * @param {{ error: boolean } | Function} [contextOptions] - pass {error:true} to write to stderr instead of stdout\n   */\n\n  outputHelp(contextOptions) {\n    let deprecatedCallback;\n    if (typeof contextOptions === 'function') {\n      deprecatedCallback = contextOptions;\n      contextOptions = undefined;\n    }\n\n    const outputContext = this._getOutputContext(contextOptions);\n    /** @type {HelpTextEventContext} */\n    const eventContext = {\n      error: outputContext.error,\n      write: outputContext.write,\n      command: this,\n    };\n\n    this._getCommandAndAncestors()\n      .reverse()\n      .forEach((command) => command.emit('beforeAllHelp', eventContext));\n    this.emit('beforeHelp', eventContext);\n\n    let helpInformation = this.helpInformation({ error: outputContext.error });\n    if (deprecatedCallback) {\n      helpInformation = deprecatedCallback(helpInformation);\n      if (\n        typeof helpInformation !== 'string' &&\n        !Buffer.isBuffer(helpInformation)\n      ) {\n        throw new Error('outputHelp callback must return a string or a Buffer');\n      }\n    }\n    outputContext.write(helpInformation);\n\n    if (this._getHelpOption()?.long) {\n      this.emit(this._getHelpOption().long); // deprecated\n    }\n    this.emit('afterHelp', eventContext);\n    this._getCommandAndAncestors().forEach((command) =>\n      command.emit('afterAllHelp', eventContext),\n    );\n  }\n\n  /**\n   * You can pass in flags and a description to customise the built-in help option.\n   * Pass in false to disable the built-in help option.\n   *\n   * @example\n   * program.helpOption('-?, --help' 'show help'); // customise\n   * program.helpOption(false); // disable\n   *\n   * @param {(string | boolean)} flags\n   * @param {string} [description]\n   * @return {Command} `this` command for chaining\n   */\n\n  helpOption(flags, description) {\n    // Support enabling/disabling built-in help option.\n    if (typeof flags === 'boolean') {\n      if (flags) {\n        if (this._helpOption === null) this._helpOption = undefined; // reenable\n        if (this._defaultOptionGroup) {\n          // make the option to store the group\n          this._initOptionGroup(this._getHelpOption());\n        }\n      } else {\n        this._helpOption = null; // disable\n      }\n      return this;\n    }\n\n    // Customise flags and description.\n    this._helpOption = this.createOption(\n      flags ?? '-h, --help',\n      description ?? 'display help for command',\n    );\n    // init group unless lazy create\n    if (flags || description) this._initOptionGroup(this._helpOption);\n\n    return this;\n  }\n\n  /**\n   * Lazy create help option.\n   * Returns null if has been disabled with .helpOption(false).\n   *\n   * @returns {(Option | null)} the help option\n   * @package\n   */\n  _getHelpOption() {\n    // Lazy create help option on demand.\n    if (this._helpOption === undefined) {\n      this.helpOption(undefined, undefined);\n    }\n    return this._helpOption;\n  }\n\n  /**\n   * Supply your own option to use for the built-in help option.\n   * This is an alternative to using helpOption() to customise the flags and description etc.\n   *\n   * @param {Option} option\n   * @return {Command} `this` command for chaining\n   */\n  addHelpOption(option) {\n    this._helpOption = option;\n    this._initOptionGroup(option);\n    return this;\n  }\n\n  /**\n   * Output help information and exit.\n   *\n   * Outputs built-in help, and custom text added using `.addHelpText()`.\n   *\n   * @param {{ error: boolean }} [contextOptions] - pass {error:true} to write to stderr instead of stdout\n   */\n\n  help(contextOptions) {\n    this.outputHelp(contextOptions);\n    let exitCode = Number(process.exitCode ?? 0); // process.exitCode does allow a string or an integer, but we prefer just a number\n    if (\n      exitCode === 0 &&\n      contextOptions &&\n      typeof contextOptions !== 'function' &&\n      contextOptions.error\n    ) {\n      exitCode = 1;\n    }\n    // message: do not have all displayed text available so only passing placeholder.\n    this._exit(exitCode, 'commander.help', '(outputHelp)');\n  }\n\n  /**\n   * // Do a little typing to coordinate emit and listener for the help text events.\n   * @typedef HelpTextEventContext\n   * @type {object}\n   * @property {boolean} error\n   * @property {Command} command\n   * @property {function} write\n   */\n\n  /**\n   * Add additional text to be displayed with the built-in help.\n   *\n   * Position is 'before' or 'after' to affect just this command,\n   * and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.\n   *\n   * @param {string} position - before or after built-in help\n   * @param {(string | Function)} text - string to add, or a function returning a string\n   * @return {Command} `this` command for chaining\n   */\n\n  addHelpText(position, text) {\n    const allowedValues = ['beforeAll', 'before', 'after', 'afterAll'];\n    if (!allowedValues.includes(position)) {\n      throw new Error(`Unexpected value for position to addHelpText.\nExpecting one of '${allowedValues.join(\"', '\")}'`);\n    }\n\n    const helpEvent = `${position}Help`;\n    this.on(helpEvent, (/** @type {HelpTextEventContext} */ context) => {\n      let helpStr;\n      if (typeof text === 'function') {\n        helpStr = text({ error: context.error, command: context.command });\n      } else {\n        helpStr = text;\n      }\n      // Ignore falsy value when nothing to output.\n      if (helpStr) {\n        context.write(`${helpStr}\\n`);\n      }\n    });\n    return this;\n  }\n\n  /**\n   * Output help information if help flags specified\n   *\n   * @param {Array} args - array of options to search for help flags\n   * @private\n   */\n\n  _outputHelpIfRequested(args) {\n    const helpOption = this._getHelpOption();\n    const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));\n    if (helpRequested) {\n      this.outputHelp();\n      // (Do not have all displayed text available so only passing placeholder.)\n      this._exit(0, 'commander.helpDisplayed', '(outputHelp)');\n    }\n  }\n}\n\n/**\n * Scan arguments and increment port number for inspect calls (to avoid conflicts when spawning new command).\n *\n * @param {string[]} args - array of arguments from node.execArgv\n * @returns {string[]}\n * @private\n */\n\nfunction incrementNodeInspectorPort(args) {\n  // Testing for these options:\n  //  --inspect[=[host:]port]\n  //  --inspect-brk[=[host:]port]\n  //  --inspect-port=[host:]port\n  return args.map((arg) => {\n    if (!arg.startsWith('--inspect')) {\n      return arg;\n    }\n    let debugOption;\n    let debugHost = '127.0.0.1';\n    let debugPort = '9229';\n    let match;\n    if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {\n      // e.g. --inspect\n      debugOption = match[1];\n    } else if (\n      (match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null\n    ) {\n      debugOption = match[1];\n      if (/^\\d+$/.test(match[3])) {\n        // e.g. --inspect=1234\n        debugPort = match[3];\n      } else {\n        // e.g. --inspect=localhost\n        debugHost = match[3];\n      }\n    } else if (\n      (match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\\d+)$/)) !== null\n    ) {\n      // e.g. --inspect=localhost:1234\n      debugOption = match[1];\n      debugHost = match[3];\n      debugPort = match[4];\n    }\n\n    if (debugOption && debugPort !== '0') {\n      return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;\n    }\n    return arg;\n  });\n}\n\n/**\n * @returns {boolean | undefined}\n * @package\n */\nfunction useColor() {\n  // Test for common conventions.\n  // NB: the observed behaviour is in combination with how author adds color! For example:\n  //   - we do not test NODE_DISABLE_COLORS, but util:styletext does\n  //   - we do test NO_COLOR, but Chalk does not\n  //\n  // References:\n  // https://no-color.org\n  // https://bixense.com/clicolors/\n  // https://github.com/nodejs/node/blob/0a00217a5f67ef4a22384cfc80eb6dd9a917fdc1/lib/internal/tty.js#L109\n  // https://github.com/chalk/supports-color/blob/c214314a14bcb174b12b3014b2b0a8de375029ae/index.js#L33\n  // (https://force-color.org recent web page from 2023, does not match major javascript implementations)\n\n  if (\n    process.env.NO_COLOR ||\n    process.env.FORCE_COLOR === '0' ||\n    process.env.FORCE_COLOR === 'false'\n  )\n    return false;\n  if (process.env.FORCE_COLOR || process.env.CLICOLOR_FORCE !== undefined)\n    return true;\n  return undefined;\n}\n\nexports.Command = Command;\nexports.useColor = useColor; // exporting for tests\n",
    "const { Argument } = require('./lib/argument.js');\nconst { Command } = require('./lib/command.js');\nconst { CommanderError, InvalidArgumentError } = require('./lib/error.js');\nconst { Help } = require('./lib/help.js');\nconst { Option } = require('./lib/option.js');\n\nexports.program = new Command();\n\nexports.createCommand = (name) => new Command(name);\nexports.createOption = (flags, description) => new Option(flags, description);\nexports.createArgument = (name, description) => new Argument(name, description);\n\n/**\n * Expose classes\n */\n\nexports.Command = Command;\nexports.Option = Option;\nexports.Argument = Argument;\nexports.Help = Help;\n\nexports.CommanderError = CommanderError;\nexports.InvalidArgumentError = InvalidArgumentError;\nexports.InvalidOptionArgumentError = InvalidArgumentError; // Deprecated\n",
    "import commander from './index.js';\n\n// wrapper to provide named exports for ESM.\nexport const {\n  program,\n  createCommand,\n  createArgument,\n  createOption,\n  CommanderError,\n  InvalidArgumentError,\n  InvalidOptionArgumentError, // deprecated old name\n  Command,\n  Argument,\n  Option,\n  Help,\n} = commander;\n",
    "/**\n * 宿主检测。\n *\n * - detectHostKind()：旧的路径/状态目录家族检测（openclaw | qclaw），行为与 host.ts 完全一致。\n * - resolveClawKind()：新的渠道 Profile 选择（openclaw | arkclaw | jvsclaw | eclaw），\n *   优先级 PHONE_NOTIFICATIONS_CLAW_PROFILE 环境变量 > 持久化 profile >\n *   eclaw env > jvsclaw 直解 tgz 痕迹 > openclaw。\n */\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ClawKind, HostKind } from \"./types.js\";\nimport {\n  DEFAULT_JVSCLAW_STATE_DIR,\n  loadQClawMeta,\n  hasOpenClawMarkers,\n  hasEclawMarkers,\n  resolveConfigPathFromEnv,\n  resolvePersistedProfileStateDirs,\n  resolvePluginConfigPathOverrideFromEnv,\n  resolveStateDirFromEnv,\n  trimToUndefined,\n} from \"./paths.js\";\n\nfunction detectHostKindFromPath(value: string | undefined): HostKind | undefined {\n  if (!value) {\n    return undefined;\n  }\n  const normalized = value.replace(/\\\\/g, \"/\").toLowerCase();\n  if (\n    normalized.endsWith(\"/.qclaw\") ||\n    normalized.includes(\"/.qclaw/\") ||\n    normalized.endsWith(\"/.qclow\") ||\n    normalized.includes(\"/.qclow/\")\n  ) {\n    return \"qclaw\";\n  }\n  if (normalized.endsWith(\"/.eclaw\") || normalized.includes(\"/.eclaw/\")) {\n    return \"openclaw\";\n  }\n  if (normalized.endsWith(\"/.openclaw\") || normalized.includes(\"/.openclaw/\")) {\n    return \"openclaw\";\n  }\n  return undefined;\n}\n\nexport function detectHostKind(): HostKind {\n  if (\n    trimToUndefined(process.env.QCLAW_STATE_DIR) ||\n    trimToUndefined(process.env.QCLAW_CONFIG_PATH) ||\n    trimToUndefined(process.env.QCLAW_HOME)\n  ) {\n    return \"qclaw\";\n  }\n\n  const pathHintKind =\n    detectHostKindFromPath(resolveStateDirFromEnv()) ??\n    detectHostKindFromPath(resolveConfigPathFromEnv());\n  if (pathHintKind) {\n    return pathHintKind;\n  }\n\n  if (hasEclawMarkers()) {\n    return \"openclaw\";\n  }\n\n  if (hasOpenClawMarkers()) {\n    return \"openclaw\";\n  }\n\n  if (loadQClawMeta()) {\n    return \"qclaw\";\n  }\n\n  return \"openclaw\";\n}\n\nconst VALID_CLAW_KINDS: ReadonlySet<string> = new Set<ClawKind>([\n  \"openclaw\",\n  \"arkclaw\",\n  \"jvsclaw\",\n  \"eclaw\",\n]);\nconst PLUGIN_ID = \"phone-notifications\";\n\n/** 读取持久化到可写 stateDir/.env 的 PHONE_NOTIFICATIONS_CLAW_PROFILE。 */\nfunction readPersistedClawProfile(): string | undefined {\n  for (const stateDir of resolvePersistedProfileStateDirs()) {\n    let content: string;\n    try {\n      content = readFileSync(join(stateDir, \".env\"), \"utf-8\");\n    } catch {\n      continue;\n    }\n    for (const line of content.split(\"\\n\")) {\n      const eq = line.indexOf(\"=\");\n      if (eq < 1) continue;\n      if (line.slice(0, eq).trim() === \"PHONE_NOTIFICATIONS_CLAW_PROFILE\") {\n        return line.slice(eq + 1).trim();\n      }\n    }\n  }\n  return undefined;\n}\n\nfunction hasEclawEnvHint(): boolean {\n  return Boolean(\n    trimToUndefined(process.env.ECLAW_STATE_DIR) ||\n      trimToUndefined(process.env.ECLAW_CONFIG_PATH) ||\n      trimToUndefined(process.env.ECLAW_HOME),\n  );\n}\n\nfunction hasJvsclawEnvHint(): boolean {\n  return Boolean(\n    trimToUndefined(process.env.JVSCLAW_STATE_DIR) ||\n      trimToUndefined(process.env.JVSCLAW_CONFIG_PATH) ||\n      trimToUndefined(process.env.JVSCLAW_HOME),\n  );\n}\n\nfunction readPluginLinkSecret(configPath: string | undefined): string | undefined {\n  if (!configPath) return undefined;\n\n  let config: unknown;\n  try {\n    config = JSON.parse(readFileSync(configPath, \"utf-8\"));\n  } catch {\n    return undefined;\n  }\n\n  const entries = readObject(readObject(config, \"plugins\"), \"entries\");\n  const pluginEntry = readObject(entries, PLUGIN_ID);\n  const pluginConfig = readObject(pluginEntry, \"config\");\n  const linkSecret = pluginConfig?.link_secret;\n  return typeof linkSecret === \"string\"\n    ? linkSecret.trim() || undefined\n    : undefined;\n}\n\nfunction hasJvsclawLinkSecret(): boolean {\n  const paths = [\n    resolvePluginConfigPathOverrideFromEnv(),\n    resolveConfigPathFromEnv(),\n    join(DEFAULT_JVSCLAW_STATE_DIR, \"openclaw.json\"),\n  ].filter((value, index, arr): value is string => Boolean(value) && arr.indexOf(value) === index);\n\n  return paths.some((configPath) => Boolean(readPluginLinkSecret(configPath)));\n}\n\nfunction readObject(\n  value: unknown,\n  key: string,\n): Record<string, unknown> | undefined {\n  if (!value || typeof value !== \"object\") {\n    return undefined;\n  }\n  const nested = (value as Record<string, unknown>)[key];\n  return nested && typeof nested === \"object\"\n    ? (nested as Record<string, unknown>)\n    : undefined;\n}\n\n/**\n * 选择渠道 Profile。\n * 优先级：PHONE_NOTIFICATIONS_CLAW_PROFILE 环境变量 > 持久化的 .env（安装脚本 --channel）\n * > eclaw env 痕迹 > jvsclaw 直解 tgz 的运行期/配置痕迹 > 默认 openclaw。\n * 安装脚本带 --channel 时写入 .env，运行期零歧义；jvsclaw 线上直解 tgz 时没有这一步，\n * 需要从 JVSCLAW_* env 或宿主注入的 link_secret 识别。\n */\nexport function resolveClawKind(): ClawKind {\n  const fromEnv = trimToUndefined(process.env.PHONE_NOTIFICATIONS_CLAW_PROFILE)?.toLowerCase();\n  if (fromEnv && VALID_CLAW_KINDS.has(fromEnv)) {\n    return fromEnv as ClawKind;\n  }\n\n  const persisted = readPersistedClawProfile()?.toLowerCase();\n  if (persisted && VALID_CLAW_KINDS.has(persisted)) {\n    return persisted as ClawKind;\n  }\n\n  if (hasEclawEnvHint()) {\n    return \"eclaw\";\n  }\n\n  if (hasJvsclawEnvHint() || hasJvsclawLinkSecret()) {\n    return \"jvsclaw\";\n  }\n\n  // 自动检测兜底：qclaw 与 openclaw 同属 apiKey 家族，统一归为 openclaw。\n  return \"openclaw\";\n}\n",
    "/**\n * 宿主原始路径解析。\n *\n * 注意：这里解析的是宿主暴露的目录，不保证可写。JvsClaw 可能把\n * JVSCLAW_STATE_DIR / JVSCLAW_HOME 指向只读 rootfs（例如 /opt/jvs-claw）。\n * 插件自己的可写目录必须通过 runtime-paths.ts 解析。\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\ninterface QClawMeta {\n  stateDir?: string;\n  configPath?: string;\n}\n\nexport const DEFAULT_JVSCLAW_STATE_DIR = \"/home/admin/.openclaw\";\nexport const PHONE_NOTIFICATIONS_STATE_DIR_ENV = \"PHONE_NOTIFICATIONS_STATE_DIR\";\nexport const PHONE_NOTIFICATIONS_CONFIG_PATH_ENV = \"PHONE_NOTIFICATIONS_CONFIG_PATH\";\n\nexport function trimToUndefined(value: unknown): string | undefined {\n  if (typeof value !== \"string\") {\n    return undefined;\n  }\n  const trimmed = value.trim();\n  return trimmed || undefined;\n}\n\nexport function homeDir(): string {\n  return process.env.HOME || process.env.USERPROFILE || \"/tmp\";\n}\n\nexport function expandUserPath(value: string | undefined): string | undefined {\n  if (!value) {\n    return undefined;\n  }\n  if (value === \"~\") {\n    return homeDir();\n  }\n  if (value.startsWith(\"~/\")) {\n    return join(homeDir(), value.slice(2));\n  }\n  return value;\n}\n\nfunction candidateMetaPaths(): string[] {\n  const home = homeDir();\n  return [\n    join(home, \".qclaw\", \"qclaw.json\"),\n    join(home, \".qclow\", \"qclaw.json\"),\n  ];\n}\n\nexport function loadQClawMeta(): QClawMeta | undefined {\n  for (const metaPath of candidateMetaPaths()) {\n    if (!existsSync(metaPath)) {\n      continue;\n    }\n    try {\n      const parsed = JSON.parse(readFileSync(metaPath, \"utf-8\")) as QClawMeta;\n      return {\n        stateDir: expandUserPath(trimToUndefined(parsed?.stateDir)),\n        configPath: expandUserPath(trimToUndefined(parsed?.configPath)),\n      };\n    } catch {\n      // ignore invalid metadata and keep trying\n    }\n  }\n  return undefined;\n}\n\n/** 插件可写状态目录的显式覆盖。与宿主原始 stateDir 分离。 */\nexport function resolvePluginStateDirOverrideFromEnv(): string | undefined {\n  return expandUserPath(\n    trimToUndefined(process.env[PHONE_NOTIFICATIONS_STATE_DIR_ENV]),\n  );\n}\n\n/** 插件使用的配置文件显式覆盖。与宿主原始 configPath 分离。 */\nexport function resolvePluginConfigPathOverrideFromEnv(): string | undefined {\n  return expandUserPath(\n    trimToUndefined(process.env[PHONE_NOTIFICATIONS_CONFIG_PATH_ENV]),\n  );\n}\n\n/** 解析宿主暴露的原始状态目录环境变量。返回值不保证可写。 */\nexport function resolveStateDirFromEnv(): string | undefined {\n  return expandUserPath(\n    trimToUndefined(process.env.ECLAW_STATE_DIR) ??\n      trimToUndefined(process.env.ECLAW_HOME) ??\n      trimToUndefined(process.env.JVSCLAW_STATE_DIR) ??\n      trimToUndefined(process.env.JVSCLAW_HOME) ??\n      trimToUndefined(process.env.OPENCLAW_STATE_DIR) ??\n      trimToUndefined(process.env.QCLAW_STATE_DIR) ??\n      trimToUndefined(process.env.OPENCLAW_ROOT) ??\n      trimToUndefined(process.env.OPENCLAW_HOME) ??\n      trimToUndefined(process.env.QCLAW_HOME),\n  );\n}\n\n/** 解析宿主暴露的原始配置文件环境变量。返回值不保证可写。 */\nexport function resolveConfigPathFromEnv(): string | undefined {\n  return expandUserPath(\n    trimToUndefined(process.env.ECLAW_CONFIG_PATH) ??\n      trimToUndefined(process.env.JVSCLAW_CONFIG_PATH) ??\n      trimToUndefined(process.env.OPENCLAW_CONFIG_PATH) ??\n      trimToUndefined(process.env.QCLAW_CONFIG_PATH),\n  );\n}\n\nexport function hasOpenClawMarkers(): boolean {\n  const baseDir = join(homeDir(), \".openclaw\");\n  return [\n    join(baseDir, \"openclaw.json\"),\n    join(baseDir, \"credentials.json\"),\n    join(baseDir, \"extensions\"),\n  ].some((candidate) => existsSync(candidate));\n}\n\nexport function hasEclawMarkers(): boolean {\n  const baseDir = join(homeDir(), \".eclaw\");\n  return [\n    join(baseDir, \"openclaw.json\"),\n    join(baseDir, \"credentials.json\"),\n    join(baseDir, \"extensions\"),\n  ].some((candidate) => existsSync(candidate));\n}\n\n/**\n * 解析宿主原始状态目录。仅用于必须与宿主运行时交互的场景，例如 Gateway\n * 设备配对。插件文件写入请使用 runtime-paths.ts 的 resolveStateDir()。\n */\nexport function resolveHostStateDir(stateDir?: string): string {\n  const explicitDir = expandUserPath(trimToUndefined(stateDir));\n  if (explicitDir) {\n    return explicitDir;\n  }\n\n  const envDir = resolveStateDirFromEnv();\n  if (envDir) {\n    return envDir;\n  }\n\n  if (hasEclawMarkers()) {\n    return join(homeDir(), \".eclaw\");\n  }\n\n  if (hasOpenClawMarkers()) {\n    return join(homeDir(), \".openclaw\");\n  }\n\n  const meta = loadQClawMeta();\n  if (meta?.stateDir) {\n    return meta.stateDir;\n  }\n  if (meta?.configPath) {\n    return dirname(meta.configPath);\n  }\n\n  return join(homeDir(), \".openclaw\");\n}\n\n/** 解析宿主原始配置文件路径。返回值不保证位于可写目录。 */\nexport function resolveHostConfigPath(\n  stateDir = resolveHostStateDir(),\n): string {\n  const envConfigPath = resolveConfigPathFromEnv();\n  if (envConfigPath) {\n    return envConfigPath;\n  }\n\n  const meta = loadQClawMeta();\n  if (\n    meta?.configPath &&\n    (!meta.stateDir || !stateDir || meta.stateDir === stateDir)\n  ) {\n    return meta.configPath;\n  }\n\n  return join(stateDir, \"openclaw.json\");\n}\n\n/**\n * 返回可能持久化 PHONE_NOTIFICATIONS_CLAW_PROFILE 的目录。\n * detect.ts 使用这些候选路径判断渠道，避免因宿主只读根目录而漏读 JvsClaw 配置。\n */\nexport function resolvePersistedProfileStateDirs(): string[] {\n  const dirs: string[] = [];\n  const add = (dir: string | undefined) => {\n    if (dir && !dirs.includes(dir)) {\n      dirs.push(dir);\n    }\n  };\n\n  add(resolvePluginStateDirOverrideFromEnv());\n  add(join(homeDir(), \".eclaw\"));\n  add(DEFAULT_JVSCLAW_STATE_DIR);\n  add(resolveHostStateDir());\n  return dirs;\n}\n",
    "/**\n * 插件可写路径解析。\n *\n * 宿主原始目录与插件可写目录在 OpenClaw / QClaw 下通常相同，但 JvsClaw\n * 可能把宿主目录指向只读 rootfs。所有插件文件写入都应经过这里。\n */\nimport { join } from \"node:path\";\nimport { resolveClawKind } from \"./detect.js\";\nimport {\n  DEFAULT_JVSCLAW_STATE_DIR,\n  resolveHostConfigPath,\n  resolveHostStateDir,\n  resolvePluginConfigPathOverrideFromEnv,\n  resolvePluginStateDirOverrideFromEnv,\n} from \"./paths.js\";\n\n/**\n * 解析插件可写状态目录。\n *\n * PHONE_NOTIFICATIONS_STATE_DIR 是明确的可写覆盖；JVSCLAW_STATE_DIR 等变量\n * 只描述宿主原始目录，不参与 JvsClaw 插件文件写入。\n */\nexport function resolveStateDir(hostStateDir?: string): string {\n  const override = resolvePluginStateDirOverrideFromEnv();\n  if (override) {\n    return override;\n  }\n\n  if (resolveClawKind() === \"jvsclaw\") {\n    return DEFAULT_JVSCLAW_STATE_DIR;\n  }\n\n  if (resolveClawKind() === \"eclaw\") {\n    return resolveHostStateDir(hostStateDir);\n  }\n\n  return resolveHostStateDir(hostStateDir);\n}\n\n/** 解析插件应使用的配置文件路径。 */\nexport function resolveConfigPath(hostStateDir?: string): string {\n  const override = resolvePluginConfigPathOverrideFromEnv();\n  if (override) {\n    return override;\n  }\n\n  if (resolveClawKind() === \"jvsclaw\") {\n    return join(resolveStateDir(hostStateDir), \"openclaw.json\");\n  }\n\n  if (resolveClawKind() === \"eclaw\") {\n    return resolveHostConfigPath(resolveHostStateDir(hostStateDir));\n  }\n\n  return resolveHostConfigPath(resolveHostStateDir(hostStateDir));\n}\n\n/** 解析插件可写状态目录中的文件。 */\nexport function resolveStateFile(\n  filename: string,\n  hostStateDir?: string,\n): string {\n  return join(resolveStateDir(hostStateDir), filename);\n}\n",
    "import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getMessagesForLocale, type MessageKey } from \"./messages/index.js\";\nimport { resolveStateFile } from \"../host.js\";\nimport { upsertStateDotEnv } from \"../env.js\";\n\nfunction interpolate(\n  template: string,\n  params?: Record<string, string | number>,\n): string {\n  if (!params) return template;\n  return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => {\n    const value = params[key];\n    return value === undefined ? `{${key}}` : String(value);\n  });\n}\n\nfunction localeMessage(\n  key: MessageKey,\n  params?: Record<string, string | number>,\n): string {\n  const template = getMessagesForLocale(activeLocale)[key];\n  if (!template) return key;\n  return interpolate(template, params);\n}\n\nexport const PHONE_NOTIFICATIONS_LANG_ENV = \"PHONE_NOTIFICATIONS_LANG\";\nexport const DEFAULT_LOCALE = \"zh-CN\";\nexport const SUPPORTED_LOCALES = [\"zh-CN\", \"zh-TW\", \"en-US\"] as const;\nexport const PLUGIN_LOCALE_CHANGED_EVENT = \"plugin.locale.changed\";\n\nexport type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];\nexport type LocaleSource = \"app\" | \"env\" | \"process\" | \"default\";\n\nconst LOCALE_ALIASES: Record<string, SupportedLocale> = {\n  zh: \"zh-CN\",\n  cn: \"zh-CN\",\n  chinese: \"zh-CN\",\n  \"zh-cn\": \"zh-CN\",\n  zh_cn: \"zh-CN\",\n  \"zh-hans\": \"zh-CN\",\n  zh_hans: \"zh-CN\",\n  \"zh-sg\": \"zh-CN\",\n  zh_sg: \"zh-CN\",\n  tw: \"zh-TW\",\n  hk: \"zh-TW\",\n  \"zh-tw\": \"zh-TW\",\n  zh_tw: \"zh-TW\",\n  \"zh-hk\": \"zh-TW\",\n  zh_hk: \"zh-TW\",\n  \"zh-mo\": \"zh-TW\",\n  zh_mo: \"zh-TW\",\n  \"zh-hant\": \"zh-TW\",\n  zh_hant: \"zh-TW\",\n  en: \"en-US\",\n  english: \"en-US\",\n  \"en-us\": \"en-US\",\n  en_us: \"en-US\",\n};\n\nfunction canonicalizeLocaleTag(input: string): string {\n  const segments = input.trim().replace(/_/g, \"-\").split(\"-\").filter(Boolean);\n  return segments\n    .map((segment, index) => {\n      const lower = segment.toLowerCase();\n      if (index === 0) return lower;\n      if (lower.length === 4) {\n        return lower.charAt(0).toUpperCase() + lower.slice(1);\n      }\n      if (lower.length === 2) return lower.toUpperCase();\n      return lower;\n    })\n    .join(\"-\");\n}\n\nfunction resolveLocaleFromBcp47Tag(input: string): SupportedLocale | null {\n  const canonical = canonicalizeLocaleTag(input);\n  if (isSupportedLocale(canonical)) return canonical;\n\n  const segments = canonical.split(\"-\");\n  const language = segments[0]?.toLowerCase();\n  if (!language) return null;\n\n  const script = segments.find((segment) => /^[A-Z][a-z]{3}$/.test(segment));\n  const region = segments.find((segment) => /^[A-Z]{2}$/.test(segment));\n\n  if (language === \"en\") return \"en-US\";\n\n  if (language === \"zh\") {\n    if (script === \"Hant\") return \"zh-TW\";\n    if (script === \"Hans\") return \"zh-CN\";\n    if (region === \"TW\" || region === \"HK\" || region === \"MO\") return \"zh-TW\";\n    if (region === \"CN\" || region === \"SG\") return \"zh-CN\";\n    return \"zh-CN\";\n  }\n\n  return null;\n}\n\nfunction parseEnvFile(envPath: string): Record<string, string> {\n  if (!existsSync(envPath)) return {};\n  const entries = new Map<string, string>();\n  const tokens = readFileSync(envPath, \"utf-8\")\n    .split(/\\r?\\n/)\n    .flatMap((line) => line.split(/(?<![A-Z0-9_])(?=[A-Z_][A-Z0-9_]*=)/));\n  for (const token of tokens) {\n    const trimmed = token.trim();\n    if (!trimmed || trimmed.startsWith(\"#\")) continue;\n    const eq = trimmed.indexOf(\"=\");\n    if (eq < 1) continue;\n    const key = trimmed.slice(0, eq).trim();\n    if (!/^[A-Z_][A-Z0-9_]*$/.test(key)) continue;\n    entries.set(key, trimmed.slice(eq + 1).trim());\n  }\n  return Object.fromEntries(entries);\n}\n\nfunction readDotEnv(): Record<string, string> {\n  return parseEnvFile(resolveStateFile(\".env\"));\n}\n\nfunction isSupportedLocale(value: string): value is SupportedLocale {\n  return (SUPPORTED_LOCALES as readonly string[]).includes(value);\n}\n\n/** 将输入规范化为支持的 locale；无法识别时返回 null。 */\nexport function normalizeLocale(input: unknown): SupportedLocale | null {\n  if (typeof input !== \"string\") return null;\n  const trimmed = input.trim();\n  if (!trimmed) return null;\n\n  if (isSupportedLocale(trimmed)) return trimmed;\n\n  const lower = trimmed.toLowerCase();\n  const alias = LOCALE_ALIASES[lower];\n  if (alias) return alias;\n\n  const underscored = lower.replace(/-/g, \"_\");\n  const aliasFromUnderscore = LOCALE_ALIASES[underscored];\n  if (aliasFromUnderscore) return aliasFromUnderscore;\n\n  const fromTag = resolveLocaleFromBcp47Tag(trimmed);\n  if (fromTag) return fromTag;\n\n  for (const locale of SUPPORTED_LOCALES) {\n    if (locale.toLowerCase() === lower) return locale;\n  }\n\n  return null;\n}\n\n/** 读取 .env 中由 App 上次同步的 locale。 */\nexport function readPersistedLocale(): SupportedLocale | undefined {\n  const fromDotEnv = readDotEnv()[PHONE_NOTIFICATIONS_LANG_ENV]?.trim();\n  if (!fromDotEnv) return undefined;\n  return normalizeLocale(fromDotEnv) ?? undefined;\n}\n\n/** 从指定 stateDir/.env 读取已持久化的 locale（用于 update 等显式 stateDir 场景）。 */\nexport function readPersistedLocaleFromStateDir(\n  stateDir: string,\n): SupportedLocale | undefined {\n  const fromDotEnv = parseEnvFile(join(stateDir, \".env\"))[PHONE_NOTIFICATIONS_LANG_ENV]?.trim();\n  if (!fromDotEnv) return undefined;\n  return normalizeLocale(fromDotEnv) ?? undefined;\n}\n\n/** 进程内当前生效 locale（插件 CLI / 文案输出读此值）。 */\nlet activeLocale: SupportedLocale = readPersistedLocale() ?? DEFAULT_LOCALE;\n/** App 显式切换后，本进程不再被启动时的 process env 覆盖。 */\nlet appLocaleApplied = false;\n\ntype LocaleAppliedListener = (\n  locale: SupportedLocale,\n  previous: SupportedLocale,\n) => void;\n\nconst localeAppliedListeners: LocaleAppliedListener[] = [];\n\n/** 注册 locale 变更回调（skills manifest、文案刷新等）。 */\nexport function onLocaleApplied(listener: LocaleAppliedListener): () => void {\n  localeAppliedListeners.push(listener);\n  return () => {\n    const index = localeAppliedListeners.indexOf(listener);\n    if (index >= 0) localeAppliedListeners.splice(index, 1);\n  };\n}\n\n/** 返回进程内当前 locale。 */\nexport function getActiveLocale(): SupportedLocale {\n  return activeLocale;\n}\n\n/** 云端 HTTP 请求用的 Accept-Language 简码（en / zh）。 */\nexport type AcceptLanguage = \"en\" | \"zh\";\n\n/** 将 SupportedLocale 映射为 Accept-Language 简码。 */\nexport function toAcceptLanguage(locale: SupportedLocale): AcceptLanguage {\n  return locale === \"en-US\" ? \"en\" : \"zh\";\n}\n\n/** 当前插件 locale 对应的 Accept-Language 简码。 */\nexport function getAcceptLanguage(): AcceptLanguage {\n  return toAcceptLanguage(getActiveLocale());\n}\n\n/**\n * App 切换语言时调用：立即更新内存并写入 .env。\n * 返回变更前的 locale。\n */\nexport function applyAppLocale(locale: SupportedLocale): SupportedLocale {\n  if (!isSupportedLocale(locale)) {\n    throw new Error(localeMessage(\"errors.INVALID_LOCALE_VALUE\", {\n      locale,\n      locales: SUPPORTED_LOCALES.join(\", \"),\n    }));\n  }\n  const previous = activeLocale;\n  activeLocale = locale;\n  appLocaleApplied = true;\n  upsertStateDotEnv(PHONE_NOTIFICATIONS_LANG_ENV, locale);\n  if (locale !== previous) {\n    for (const listener of localeAppliedListeners) {\n      listener(locale, previous);\n    }\n  }\n  return previous;\n}\n\n/** 解析当前 locale 及来源（不回退系统 LANG，未同步前默认 zh-CN）。 */\nexport function resolveLocale(): { locale: SupportedLocale; source: LocaleSource } {\n  if (!appLocaleApplied) {\n    const fromProcess = process.env[PHONE_NOTIFICATIONS_LANG_ENV]?.trim();\n    if (fromProcess) {\n      const normalized = normalizeLocale(fromProcess);\n      if (normalized) {\n        activeLocale = normalized;\n        return { locale: normalized, source: \"process\" };\n      }\n    }\n  }\n\n  const persisted = readPersistedLocale();\n  if (persisted) {\n    activeLocale = persisted;\n    return { locale: persisted, source: \"env\" };\n  }\n\n  if (activeLocale !== DEFAULT_LOCALE) {\n    return { locale: activeLocale, source: \"app\" };\n  }\n\n  return { locale: DEFAULT_LOCALE, source: \"default\" };\n}\n\n/** 持久化 locale（测试 / 安装脚本用；运行时请用 applyAppLocale）。 */\nexport function saveLocale(locale: SupportedLocale): void {\n  applyAppLocale(locale);\n}\n\n/** 仅测试用：重置进程内 locale，避免用例间泄漏。 */\nexport function resetLocaleStateForTest(locale: SupportedLocale = DEFAULT_LOCALE): void {\n  activeLocale = locale;\n  appLocaleApplied = false;\n}\n",
    "export const enUS = {\n  \"cli.ntf.description\": \"Phone notification data management\",\n  \"cli.ntf.version\": \"Show plugin version\",\n  \"plugin.registration.call\":\n    \"register() called: registrationMode={registrationMode} cliInvocation={cliInvocation}\",\n  \"plugin.registration.cli_registered\":\n    \"CLI commands registered: ntf, phone-notifications\",\n  \"plugin.registration.cli_only\":\n    \"Plugin CLI invocation detected; registered CLI commands only and skipped background services to avoid disrupting the persistent Relay tunnel connection\",\n  \"plugin.ntf_bin.target_missing\": \"ntf wrapper target does not exist: {path}; skipped\",\n  \"plugin.ntf_bin.visibility.immediate\": \"available immediately\",\n  \"plugin.ntf_bin.visibility.needs_path\": \"PATH update required\",\n  \"plugin.ntf_bin.registered\":\n    \"Standalone ntf command registered: {path} -> {target} ({label}, {visibility})\",\n  \"plugin.ntf_bin.path_hint\":\n    \"If the ntf command is not available yet, add its directory to PATH: export PATH=\\\"{dir}:$PATH\\\"\",\n  \"plugin.ntf_bin.register_failed\": \"Failed to register standalone ntf command: {failures}\",\n  \"plugin.ntf_bin.no_install_dir\": \"no usable installation directory\",\n  \"plugin.ntf_bin.candidate.node\": \"next to node\",\n  \"plugin.ntf_bin.candidate.host\": \"next to host CLI ({name})\",\n  \"plugin.ntf_bin.candidate.path\": \"PATH directory\",\n  \"plugin.ntf_bin.candidate.fallback\": \"stateDir/bin fallback\",\n  \"plugin.ntf_bin.mkdir_failed\": \"Failed to create {dir}: {error}\",\n  \"plugin.ntf_bin.target_occupied\": \"{path} already exists; refusing to overwrite it\",\n  \"plugin.ntf_bin.write_failed\": \"Failed to write {path}: {error}\",\n  \"plugin.tunnel.auth_not_ready\":\n    \"Relay tunnel authentication is not ready ({reason}, credentials={path}); skipping connection. Run ntf auth set-api-key <apiKey>\",\n  \"plugin.tunnel.invalid_gateway_env\": \"Ignoring invalid {key}={value}\",\n  \"auth.jvsclaw.skip_missing_secret\":\n    \"jvsclaw auth: apiKey already exists and link_secret was not found; skipping exchange\",\n  \"auth.jvsclaw.skip_unchanged_secret\":\n    \"jvsclaw auth: apiKey already exists and link_secret is unchanged; skipping exchange\",\n  \"auth.jvsclaw.exchange_succeeded\":\n    \"jvsclaw auth: instance/ready API key exchange succeeded (attempt {attempt})\",\n  \"auth.jvsclaw.exchange_fatal\":\n    \"jvsclaw auth: exchange failed with an unrecoverable error (code={code}): {message}; stopping retries\",\n  \"auth.jvsclaw.exchange_retry\":\n    \"jvsclaw auth: exchange failed (attempt {attempt}): {message}; retrying in {delayMs}ms\",\n  \"auth.jvsclaw.retry_aborted\":\n    \"jvsclaw auth: exchange retries aborted because the plugin is stopping\",\n  \"auth.jvsclaw.link_secret_missing\":\n    \"link_secret was not found in {path} (path: plugins.entries.phone-notifications.config.link_secret)\",\n  \"auth.jvsclaw.ready_url_missing\":\n    \"The instance/ready endpoint URL is empty; check the host configuration\",\n  \"auth.jvsclaw.ready_response_error\":\n    \"instance/ready returned code={code} msg={message}\",\n  \"auth.jvsclaw.api_key_missing\":\n    \"The instance/ready response did not include an apiKey\",\n  \"update.stale.log.detected\":\n    \"Plugin update is not active: {diskVersion} is installed on disk, but the process is still running {runningVersion}. In-process host restarts do not reload plugin code; fully restart the openclaw process.\",\n  \"update.stale.log.config_failed\": \"Failed to read configuration during stale-runtime check: {error}\",\n  \"update.stale.log.restart_triggered\":\n    \"Triggered a full gateway restart to load plugin {diskVersion}: {command}\",\n  \"update.stale.log.restart_failed\":\n    \"Automatic full restart failed ({error}); fully restart the openclaw process manually to load {diskVersion}\",\n  \"update.stale.log.restart_scheduled\":\n    \"A full gateway restart (openclaw gateway restart) will be attempted in {seconds}s to load {diskVersion}\",\n  \"storage.notifications.state_path\": \"Notifications will be stored under stateDir: {path}\",\n  \"storage.notifications.fallback\":\n    \"stateDir is unavailable; notifications will use the workspace path: {path}\",\n  \"storage.notifications.corrupt_quarantined\":\n    \"The notifications file was corrupted and moved to {path}; notifications for the day will restart from an empty file\",\n  \"storage.notifications.corrupt_failed\":\n    \"The notifications file is corrupted and could not be quarantined; later writes may overwrite it: {path}\",\n  \"storage.recordings.state_path\": \"Recordings will be stored under stateDir: {path}\",\n  \"storage.recordings.fallback\":\n    \"stateDir is unavailable; recordings will use the workspace path: {path}\",\n  \"storage.recordings.corrupt_quarantined\":\n    \"The recordings index was corrupted and moved to {path}; an empty index was rebuilt\",\n  \"storage.recordings.corrupt_failed\":\n    \"The recordings index is corrupted and could not be quarantined; an empty index was rebuilt: {path}\",\n  \"storage.images.state_path\": \"Images will be stored under stateDir: {path}\",\n  \"storage.images.fallback\":\n    \"stateDir is unavailable; images will use the workspace path: {path}\",\n  \"storage.images.corrupt_quarantined\":\n    \"The image index was corrupted and moved to {path}; an empty index was rebuilt\",\n  \"storage.images.corrupt_failed\":\n    \"The image index is corrupted and could not be quarantined; an empty index was rebuilt: {path}\",\n  \"plugin.registration.wire_once\":\n    \"register(): background services are already wired for this process (openclawDir={openclawDir}); registered tools for the current Agent collector and skipped duplicate background wiring\",\n  \"plugin.registration.light_rules\":\n    \"Light-rule methods registered: gateway={gateway}; tools={tools}\",\n  \"plugin.interfaces.notifications.tools\":\n    \"Agent notification tool registered: notifications_summary\",\n  \"plugin.interfaces.notifications.gateway\":\n    \"Gateway notification methods registered: notifications.push / notifications.summary.start / notifications.summary.status / notifications.summary.result\",\n  \"plugin.interfaces.notifications.http\":\n    \"HTTP notifications endpoint registered: POST /notifications\",\n  \"plugin.interfaces.recordings.gateway\":\n    \"Gateway recording methods registered: recordings.result.write / recordings.list / recordings.status / recordings.rename / recordings.delete\",\n  \"plugin.interfaces.recordings.http\":\n    \"HTTP recording endpoint registered: POST /recordings (waits for files)\",\n  \"plugin.interfaces.images.gateway\": \"Gateway image method registered: images.sync\",\n  \"plugin.interfaces.images.http\": \"HTTP images endpoint registered: POST /images\",\n  \"plugin.interfaces.system.gateway\": \"Gateway system method registered: system.os\",\n  \"plugin.interfaces.system.http\": \"HTTP system endpoint registered: GET /system/os\",\n  \"plugin.interfaces.locale.gateway\":\n    \"Gateway locale methods registered: plugin.locale.get / plugin.locale.set (event: {event})\",\n  \"plugin.interfaces.locale.http\":\n    \"HTTP locale endpoint registered: GET|POST /plugin/locale\",\n  \"plugin.interfaces.auto_update\": \"Automatic update-check service registered\",\n  \"plugin.lifecycle.storage.notifications_started\":\n    \"Notification storage service started: {path}\",\n  \"plugin.lifecycle.storage.recordings_started\":\n    \"Recording storage service started: {path}\",\n  \"plugin.lifecycle.storage.images_started\": \"Image storage service started: {path}\",\n  \"plugin.lifecycle.storage.stopped\":\n    \"Notification, recording, and image storage services stopped\",\n  \"plugin.lifecycle.tunnel.registered\": \"Relay tunnel service registered\",\n  \"cli.light.description\": \"Light effect management\",\n  \"cli.light.send.description\": \"Send a light effect command to the hardware device\",\n  \"cli.light.setup_tools.description\":\n    \"Allow one-shot light control and cloud light-rule tools (tools.allow / tools.alsoAllow)\",\n  \"cli.rec.description\": \"Recording management\",\n  \"cli.rec.list.description\": \"List all recordings (optional status filter)\",\n  \"cli.rec.status.description\": \"Show details for one recording\",\n  \"cli.rec.storage_path.description\": \"Show recordings storage path\",\n  \"cli.rec.setup.description\": \"Interactively configure ASR settings and save locally\",\n  \"cli.image.description\": \"Image management\",\n  \"cli.image.list.description\": \"List all images (optional status / source-app filter)\",\n  \"cli.image.status.description\": \"Show details for one image\",\n  \"cli.image.path.description\": \"Print the absolute local path of an image file\",\n  \"cli.image.storage_path.description\": \"Show images storage path\",\n  \"cli.web.description\": \"Local synchronized web-page management\",\n  \"cli.web.list.description\": \"List all locally synchronized web pages by capture time\",\n  \"cli.web.path.description\": \"Print a synchronized web page's absolute Markdown path by URL hash\",\n  \"cli.web.search.description\":\n    \"Search locally synchronized web-page titles, URLs, and Markdown content without accessing the Internet\",\n  \"cli.web.storage_path.description\": \"Show the local synchronized web-pages storage path\",\n  \"cli.web.list.opt.from\":\n    \"Include pages captured at or after this ISO 8601 time\",\n  \"cli.web.list.opt.to\":\n    \"Include pages captured before this ISO 8601 time\",\n  \"cli.auth.description\": \"User authentication management\",\n  \"cli.auth.set_api_key.description\": \"Set user API key (persisted locally)\",\n  \"cli.auth.set_token.description\": \"(compat) Set user API key (legacy command name)\",\n  \"cli.auth.status.description\": \"Show current auth status\",\n  \"cli.auth.clear.description\": \"Clear saved auth credentials\",\n  \"cli.env.description\": \"Environment management (switch test / production)\",\n  \"cli.env.show.description\": \"Show current environment and API endpoints\",\n  \"cli.env.set.description\": \"Switch environment (test / production)\",\n  \"cli.doctor.description\": \"Self-check environment for security risks and common issues\",\n  \"cli.update.description\": \"Check and update the plugin to the latest version, then restart\",\n  \"cli.log.description\": \"View / search plugin logs\",\n  \"cli.tunnel.status.description\":\n    \"Check Relay Tunnel status (read running service status file without affecting the connection)\",\n  \"tunnel.status.connected\": \"Tunnel connected (since {since})\",\n  \"tunnel.status.connecting\":\n    \"Tunnel connecting (since {since}, reconnect attempt #{attempt})\",\n  \"tunnel.status.disconnected\":\n    \"Tunnel disconnected (since {since}){reasonSuffix}; waiting to reconnect (attempt #{attempt})\",\n  \"tunnel.status.disconnected.reason\": \", reason: {reason}\",\n  \"tunnel.status.stopped\": \"Tunnel service stopped (since {since})\",\n  \"tunnel.status.unknown\": \"Unknown state: {state}\",\n  \"tunnel.issue.not_found\":\n    \"Tunnel status file not found. The tunnel service may not have started yet. Confirm the openclaw main process is running.\",\n  \"tunnel.issue.invalid.parse\":\n    \"Failed to parse the tunnel status file; contents are corrupted or incorrectly formatted. Restart the openclaw main process.\",\n  \"tunnel.issue.invalid.fields\":\n    \"The tunnel status file is missing required fields or has invalid field types. Restart the openclaw main process.\",\n  \"tunnel.issue.stale.connected_prefix\":\n    \"Status file shows connected (since {since})\",\n  \"tunnel.issue.stale.no_lock\":\n    \", but no local runtime lock was found; the status may be stale. Restart the openclaw main process.\",\n  \"tunnel.issue.stale.incomplete_lock\":\n    \", but the local runtime lock is incomplete, so the current connection cannot be verified. Restart the openclaw main process.\",\n  \"tunnel.issue.stale.dead_pid\":\n    \", but the local runtime lock still points to exited process pid={pid}; the status may be stale. Restart the openclaw main process.\",\n  \"tunnel.issue.stale.lock_newer\":\n    \", but the current runtime lock started at {lockStartedAt}, which is later than the status timestamp, so the status was not refreshed for the new process. Restart the openclaw main process.\",\n  \"cli.monitor.description\": \"Notification monitor task management\",\n  \"cli.monitor.list.description\": \"List all monitor tasks\",\n  \"cli.monitor.show.description\": \"Show monitor task details\",\n  \"cli.monitor.create.description\": \"Create a monitor task\",\n  \"cli.monitor.delete.description\": \"Delete a monitor task\",\n  \"cli.monitor.enable.description\": \"Enable a monitor task\",\n  \"cli.monitor.disable.description\": \"Pause a monitor task\",\n  \"cli.sync.description\": \"Sync notifications into the memory system\",\n  \"cli.sync.next.description\":\n    \"Return the next sync batch (≤100) with memory prompt path; done=true when finished\",\n  \"cli.sync.pending.description\":\n    \"Scan unprocessed notifications; by default returns today's pending summary only\",\n  \"cli.sync.fetch.description\": \"Fetch unprocessed notification details for a date\",\n  \"cli.sync.commit.description\":\n    \"Mark the current batch for a date as processed and update the checkpoint\",\n  \"cli.search.description\": \"Search notifications (time / app / sender / keyword)\",\n  \"cli.stats.description\":\n    \"Notification statistics (aggregate by date / app / sender / hour)\",\n  \"cli.summary.description\":\n    \"Build notification summary input (aggregates + samples for Agent)\",\n  \"cli.summary_job.description\": \"Chunked notification summary job management\",\n  \"cli.summary_job.create.description\": \"Create a chunked notification summary job\",\n  \"cli.summary_job.status.description\": \"Show chunked summary job status\",\n  \"cli.summary_job.next.description\": \"Claim or retry the next chunk to summarize\",\n  \"cli.summary_job.commit.description\": \"Submit a chunk summary and mark the chunk complete\",\n  \"cli.summary_job.run.description\":\n    \"Process pending chunks and generate the final result when done\",\n  \"cli.summary_job.result.description\": \"Merge committed chunk summaries and return the result\",\n  \"cli.summary_job.cancel.description\": \"Cancel a chunked notification summary job\",\n  \"cli.storage_path.description\": \"Show notifications storage path\",\n\n  \"cli.opt.from_time\": \"Start time ISO 8601, e.g. 2026-03-01T09:00:00+08:00\",\n  \"cli.opt.to_time\": \"End time ISO 8601, e.g. 2026-03-01T18:00:00+08:00\",\n  \"cli.opt.from_time_short\": \"Start time ISO 8601\",\n  \"cli.opt.to_time_short\": \"End time ISO 8601\",\n  \"cli.opt.app\": \"Filter by app name\",\n  \"cli.opt.sender\": \"Filter by sender\",\n  \"cli.opt.conversation_type\": \"Filter by conversation type (group/private)\",\n  \"cli.opt.keyword\": \"Search keyword in title and body\",\n  \"cli.opt.limit\": \"Maximum number of results\",\n  \"cli.opt.from_date\": \"Start date YYYY-MM-DD\",\n  \"cli.opt.to_date\": \"End date YYYY-MM-DD\",\n  \"cli.opt.json\": \"Output result as JSON (for scripts)\",\n  \"cli.opt.yes\": \"Skip confirmation\",\n  \"cli.opt.date_ymd\": \"Target date YYYY-MM-DD\",\n\n  \"cli.search.opt.limit\": \"Maximum number of results\",\n  \"cli.summary.opt.limit\": \"Maximum notifications included in the summary\",\n  \"cli.summary.opt.sample\": \"Number of recent samples to return\",\n  \"cli.summary.opt.top\": \"Number of aggregation ranking rows\",\n  \"cli.summary.opt.max_content\":\n    \"Max characters per sample title/body (truncated when exceeded)\",\n  \"cli.summary_job.opt.limit\": \"Maximum notifications included in the job\",\n  \"cli.summary_job.opt.chunk_size\": \"Notifications per chunk\",\n  \"cli.summary_job.opt.max_content\":\n    \"Max characters per notification title/body in a chunk\",\n  \"cli.summary_job.opt.chunk_id\": \"Chunk id returned by next\",\n  \"cli.summary_job.opt.summary\": \"Pass chunk summary text directly\",\n  \"cli.summary_job.opt.summary_file\": \"Read chunk summary from a file\",\n  \"cli.summary_job.opt.max_chunks\": \"Maximum chunks to process automatically this run\",\n  \"cli.summary_job.opt.include_result\": \"Include markdown result in output when complete\",\n  \"cli.stats.opt.app\": \"Only count a specific app\",\n  \"cli.stats.opt.dim\": \"Dimension: date/app/sender/hour/all\",\n  \"cli.log.opt.keyword\": \"Filter logs by keyword\",\n  \"cli.log.opt.limit\": \"Maximum number of results\",\n  \"cli.sync.scan.opt.all\": \"Scan all unprocessed notifications after the checkpoint\",\n  \"cli.sync.scan.opt.date\": \"Only scan a specific date YYYY-MM-DD\",\n  \"cli.sync.scan.opt.from_date\": \"Only scan on/after this date YYYY-MM-DD\",\n  \"cli.sync.scan.opt.to_date\": \"Only scan on/before this date YYYY-MM-DD\",\n  \"cli.sync.next.opt.all\": \"Process all unprocessed notifications after the checkpoint\",\n  \"cli.sync.next.opt.date\": \"Only process a specific date YYYY-MM-DD\",\n  \"cli.sync.next.opt.from_date\": \"Only process on/after this date YYYY-MM-DD\",\n  \"cli.sync.next.opt.to_date\": \"Only process on/before this date YYYY-MM-DD\",\n  \"cli.sync.fetch.opt.max_end_index\": \"Max endIndex allowed for this sync snapshot\",\n  \"cli.sync.commit.opt.end_index\": \"endIndex returned by this fetch batch\",\n  \"cli.monitor.create.opt.description\": \"Task description\",\n  \"cli.monitor.create.opt.match_rules\": \"Match rules JSON\",\n  \"cli.monitor.create.opt.schedule\": \"Cron expression\",\n  \"cli.doctor.opt.fix\": \"Auto-fix fixable issues (skip confirmation)\",\n  \"cli.update.opt.force\": \"Force reinstall the latest version even if versions match\",\n  \"cli.update.opt.beta\": \"Install the latest beta version\",\n  \"cli.light.send.opt.segments\": \"Light effect segments JSON\",\n  \"cli.light.send.opt.repeat\": \"Loop forever (default: play one round)\",\n  \"cli.light.send.opt.repeat_times\":\n    \"Repeat times for the whole sequence: 0=forever, 1=one round; ANCS path does not support >=2\",\n  \"cli.image.list.opt.status\": \"Filter by status (syncing|synced|sync_failed)\",\n  \"cli.image.list.opt.app\": \"Filter by source app\",\n  \"cli.rec.list.opt.status\": \"Filter by transfer status (e.g. synced, transcribed)\",\n  \"cli.rec.list.opt.from\": \"Inclusive recording-time start (ISO 8601 or YYYY-MM-DD)\",\n  \"cli.rec.list.opt.to\": \"Exclusive recording-time end (ISO 8601 or YYYY-MM-DD)\",\n  \"cli.web.search.opt.limit\": \"Maximum number of web pages to return (default: 20)\",\n\n  \"errors.INVALID_TIME\": \"{option} must be an ISO 8601 time, e.g. {example}\",\n  \"errors.INVALID_TIME_INVALID\": \"{option} is not a valid time, e.g. {example}\",\n  \"errors.INVALID_RECORDING_TIME\": \"Recording time boundaries must be ISO 8601 or YYYY-MM-DD\",\n  \"errors.INVALID_RECORDING_TIME_RANGE\": \"--from must be earlier than --to\",\n  \"errors.STORAGE_UNAVAILABLE\":\n    \"Cannot resolve recordings directory: stateDir and workspaceDir are unset\",\n  \"errors.STORAGE_UNAVAILABLE.notifications\": \"Notifications storage directory is unavailable\",\n  \"errors.STORAGE_UNAVAILABLE.images\": \"Images storage directory is unavailable\",\n  \"errors.STORAGE_UNAVAILABLE.recordings\": \"Recordings storage directory is unavailable\",\n  \"errors.STORAGE_UNAVAILABLE.web_pages\": \"Web-pages storage directory is unavailable\",\n  \"errors.LOGS_UNAVAILABLE\": \"Logs directory is unavailable\",\n  \"errors.NOT_FOUND\": \"Not found: {target}\",\n  \"errors.NOT_FOUND.monitor\": \"Monitor task '{name}' does not exist\",\n  \"errors.NOT_FOUND.image\": \"Image not found: {id}\",\n  \"errors.NOT_FOUND.recording\": \"Recording not found: {id}\",\n  \"errors.NOT_FOUND.web_page\": \"Web page not found: {urlHash}\",\n  \"errors.ALREADY_EXISTS\": \"Monitor task '{name}' already exists\",\n  \"errors.INVALID_TIME_RANGE\": \"--from must not be later than --to\",\n  \"errors.INVALID_POSITIVE_INT\": \"{option} must be a positive integer\",\n  \"errors.INVALID_NON_NEGATIVE_INT\": \"{option} must be a non-negative integer\",\n  \"errors.INVALID_DATE\": \"{option} must be in YYYY-MM-DD format\",\n  \"errors.INVALID_DATE_VALUE\": \"{option} is not a valid date\",\n  \"errors.INVALID_SCOPE\": \"Conflicting scope parameters\",\n  \"errors.INVALID_SCOPE.all_with_range\": \"--all cannot be combined with date range options\",\n  \"errors.INVALID_SCOPE.date_with_range\": \"--date cannot be combined with date range options\",\n  \"errors.INVALID_SCOPE.from_after_to\": \"--from-date must not be later than --to-date\",\n  \"errors.NO_DATA\": \"No notifications for date {date}\",\n  \"errors.INVALID_LOCALE\": \"locale must be one of: {locales}\",\n  \"errors.INVALID_CONVERSATION_TYPE\": \"--conversation-type must be group or private\",\n  \"errors.INVALID_END_INDEX\": \"--end-index must be a non-negative integer\",\n  \"errors.INVALID_END_INDEX.out_of_range\":\n    \"--end-index must fall within the notification file for that date\",\n  \"errors.INVALID_END_INDEX.beyond_batch\":\n    \"--end-index exceeds the single-batch fetch limit and would skip unprocessed notifications\",\n  \"errors.STALE_END_INDEX\":\n    \"--end-index is earlier than the current checkpoint; progress cannot move backwards\",\n  \"errors.INVALID_MAX_END_INDEX\": \"--max-end-index must be a non-negative integer\",\n  \"errors.CONFIG_NOT_FOUND\": \"Config file not found: {path}\",\n  \"errors.CONFIG_INVALID\": \"Failed to read/parse config: {detail}\",\n  \"errors.WRITE_FAILED\": \"Failed to write config: {detail}\",\n  \"errors.HTTP_ERROR\": \"Request failed: {status} {detail}\",\n  \"errors.IMAGE_NOT_READY\":\n    \"Image {id} is not ready yet (status={status}{errorSuffix})\",\n  \"errors.WEB_PAGE_FILE_UNAVAILABLE\":\n    \"Web-page Markdown file path is unavailable: {urlHash}\",\n  \"errors.INVALID_KEYWORD\": \"Search keyword must not be empty\",\n  \"errors.INVALID_JOB_ID\": \"Invalid summary job id\",\n  \"errors.READ_FAILED\": \"Failed to read JSON: {path}\",\n  \"errors.JOB_NOT_FOUND\": \"Summary job not found: {id}\",\n  \"errors.INVALID_JOB\": \"Summary job metadata is corrupted: {id}\",\n  \"errors.INVALID_CHUNK\": \"Summary job chunk is corrupted: {chunkId}\",\n  \"errors.INVALID_COMMIT.xor\": \"Provide only one of --summary or --summary-file\",\n  \"errors.INVALID_COMMIT.required\": \"Either --summary or --summary-file is required\",\n  \"errors.INVALID_COMMIT.empty\": \"Chunk summary must not be empty\",\n  \"errors.JOB_CANCELLED\": \"Summary job cancelled: {id}\",\n  \"errors.CHUNK_NOT_FOUND\": \"Summary job chunk not found: {chunkId}\",\n  \"errors.INVALID_ENV\": \"Invalid environment name: {env}; allowed: {available}\",\n  \"errors.INVALID_MATCH_RULES\": \"match-rules must be valid JSON\",\n  \"errors.TUNNEL_NOT_CONFIGURED\":\n    \"RELAY_TUNNEL_URL is not configured; tunnel features are disabled. Set RELAY_TUNNEL_URL at build time.\",\n  \"errors.TUNNEL_TOKEN_MISSING\":\n    \"API Key is not set; the tunnel cannot connect. Run: ntf auth set-api-key <apiKey>\",\n  \"errors.STATE_DIR_UNAVAILABLE\":\n    \"Cannot determine the state directory, so tunnel status cannot be checked. Run this command in the openclaw main environment.\",\n  \"errors.STATUS_NOT_FOUND\":\n    \"Tunnel status file not found. The tunnel service may not have started yet. Confirm the openclaw main process is running.\",\n\n  \"env.reload.gateway\": \"Gateway in-process reload triggered\",\n  \"env.reload.jvsclaw\":\n    \"Host is JvsClaw; reload or restart the instance from the control plane for the switch to take effect\",\n  \"env.reload.qclaw\":\n    \"Host is QClaw; restart the QClaw desktop app for the switch to take effect\",\n  \"env.reload.command\": \"Triggered {command}\",\n  \"env.reload.manual\":\n    \"Environment switched, but auto-reload did not finish; run manually: {command}\",\n  \"env.switched.with_reload\": \"Switched to {env} and triggered a reload\",\n  \"env.switched\": \"Switched to {env}\",\n\n  \"progress.searching\": \"Searching notifications...\",\n  \"progress.summary\": \"Building notification summary input...\",\n  \"progress.summary_job_create\": \"Creating chunked notification summary job...\",\n\n  \"doctor.checking\": \"🔍 Checking environment...\",\n  \"doctor.all_pass\": \"✅ All checks passed; no issues found.\",\n  \"doctor.fix_label\": \"Fix: {fix}\",\n  \"doctor.summary\": \"Done: {critical} critical · {warn} warn · {info} info\",\n  \"doctor.manual_only\": \"All issues above require manual fixes. See the hints above.\",\n  \"doctor.fixable_found\": \"Found {count} auto-fixable issue(s):\",\n  \"doctor.confirm_fix\": \"Run auto-fix now? [y/N]: \",\n  \"doctor.cancelled\": \"Cancelled.\",\n  \"doctor.fix_failed\": \"{title} fix failed: {message}\",\n  \"doctor.manual_remaining\":\n    \"{count} issue(s) still need manual attention. See the hints above.\",\n  \"doctor.fix_done\":\n    \"Fix complete ({fixed}/{total}). Suggested next step: openclaw gateway restart\",\n\n  \"doctor.credentials.title\": \"API Key not configured\",\n  \"doctor.credentials.detail\":\n    \"No apiKey found in credentials.json; tunnel and push features will not work.\",\n  \"doctor.credentials.fix\": \"Run: ntf auth set-api-key <your-api-key>\",\n  \"doctor.dangerous_flags.title\": \"gateway.controlUi.dangerouslyDisableDeviceAuth is enabled\",\n  \"doctor.dangerous_flags.detail\":\n    \"This disables Control UI device authentication; anyone can access the control panel.\",\n  \"doctor.dangerous_flags.fix\": \"Set to false\",\n  \"doctor.node_version.title\": \"Node.js version too old (v{version})\",\n  \"doctor.node_version.detail\": \"Requires >= {minVersion}; current is v{version}.\",\n  \"doctor.node_version.fix\": \"Upgrade Node.js to {minVersion} or newer\",\n  \"doctor.plugin_version.title\":\n    \"Plugin update available (current {current} → latest {latest})\",\n  \"doctor.plugin_version.detail\":\n    \"A newer version is available; update to get the latest features and fixes.\",\n  \"doctor.plugin_version.fix\": \"Run: ntf update\",\n  \"doctor.state_dir_perms.title\":\n    \"State directory permissions are too open ({stateDir} mode={mode})\",\n  \"doctor.state_dir_perms.detail\":\n    \"Other users may read credentials and config files under this directory.\",\n  \"doctor.tool_policy.title\": \"Extension plugin tool policy is permissive\",\n  \"doctor.tool_policy.detail\":\n    \"These agents use the default policy: {agents}. Plugin tools may be invoked without authorization.\",\n  \"doctor.tool_policy.fix\":\n    \"Prefer minimal or coding profile for agents handling untrusted input, or set an explicit tool allowlist.\",\n  \"doctor.trusted_proxy.title\": \"gateway.auth.mode is trusted-proxy\",\n  \"doctor.trusted_proxy.detail\":\n    \"Auth is delegated to a reverse proxy. Ensure: (1) the proxy terminates TLS and authenticates users; (2) gateway.trustedProxies is limited to proxy IPs; (3) the firewall blocks direct access to the Gateway port.\",\n  \"doctor.trusted_proxy.fix\": \"Manual proxy review required; cannot auto-fix\",\n  \"doctor.trusted_proxy_allow_users.title\": \"allowUsers is empty in trusted-proxy mode\",\n  \"doctor.trusted_proxy_allow_users.detail\":\n    \"Any user authenticated by the proxy can access Gateway.\",\n  \"doctor.trusted_proxy_allow_users.fix\":\n    'Edit openclaw.json and add allowed user emails to gateway.auth.trustedProxy.allowUsers, e.g. [\"nick@example.com\"]',\n  \"doctor.tunnel.not_found.title\": \"Tunnel status file not found\",\n  \"doctor.tunnel.not_found.detail\":\n    \"The tunnel service may never have started, or the status file was deleted.\",\n  \"doctor.tunnel.not_found.fix\": \"Confirm the openclaw main process is running\",\n  \"doctor.tunnel.invalid.title\": \"Failed to parse tunnel status file\",\n  \"doctor.tunnel.invalid.detail\": \"File contents are corrupted or incorrectly formatted.\",\n  \"doctor.tunnel.invalid.fix\": \"Restart the openclaw main process\",\n  \"doctor.tunnel.stale.title\": \"Tunnel status is stale\",\n  \"doctor.tunnel.stale.detail\":\n    \"The status file still shows connected, but the runtime status is no longer valid.\",\n  \"doctor.tunnel.stale.fix\": \"Restart the openclaw main process\",\n  \"doctor.tunnel.disconnected.title\": \"Tunnel not connected (state={state})\",\n  \"doctor.tunnel.disconnected.detail\":\n    \"Tunnel has been in {state} since {since}{reasonSuffix}; reconnect attempts: {attempts}\",\n  \"doctor.tunnel.disconnected.reason\": \", reason: {reason}\",\n  \"doctor.tunnel.disconnected.fix\": \"Check the network or restart the openclaw main process\",\n  \"doctor.local_gateway.invalid_url.title\": \"Local Gateway URL config is invalid\",\n  \"doctor.local_gateway.invalid_url.detail\": \"{warning}; falling back to {baseUrl}\",\n  \"doctor.local_gateway.invalid_url.fix\":\n    \"Fix PHONE_NOTIFICATIONS_GATEWAY_BASE_URL, or unset it and restart openclaw/gateway\",\n  \"doctor.local_gateway.tls.title\": \"Gateway TLS may block the Relay local proxy\",\n  \"doctor.local_gateway.tls.detail\":\n    \"Detected gateway.tls.enabled=true, but the plugin local proxy defaults to {baseUrl}. If Gateway only accepts HTTPS/WSS, local RPC handshake will fail.\",\n  \"doctor.local_gateway.tls.fix\":\n    \"Set PHONE_NOTIFICATIONS_GATEWAY_BASE_URL=https://127.0.0.1:<port>, or disable gateway.tls.enabled and restart gateway\",\n  \"doctor.local_gateway.unresolvable.title\": \"Local Gateway URL cannot be resolved\",\n  \"doctor.local_gateway.unresolvable.detail\":\n    \"Cannot resolve the local Gateway URL the plugin will use: {baseUrl}\",\n  \"doctor.local_gateway.unresolvable.fix\":\n    \"Set PHONE_NOTIFICATIONS_GATEWAY_BASE_URL=http://127.0.0.1:<port>\",\n  \"doctor.local_gateway.unreachable.title\": \"Local Gateway unreachable\",\n  \"doctor.local_gateway.unreachable.detail\":\n    \"Plugin will connect to {baseUrl}, but TCP probe failed{errorSuffix}\",\n  \"doctor.local_gateway.unreachable.fix\":\n    \"Run openclaw gateway status and confirm gateway.port matches PHONE_NOTIFICATIONS_GATEWAY_BASE_URL\",\n\n  \"monitor.delete.confirm\":\n    \"Confirm delete monitor task '{name}'? Add --yes to skip confirmation\",\n\n  \"update.checking\": \"Checking{beta} latest version ...\",\n  \"update.checking_beta\": \" beta\",\n  \"update.fetch_failed\": \"Failed to fetch latest version: {message}\",\n  \"update.already_latest\": \"Already on latest{beta} version v{version}\",\n  \"update.force\": \"Force update: v{current} → v{latest}\",\n  \"update.found\": \"New version found: v{current} → v{latest}; updating ...\",\n  \"update.downloading\": \"Downloading install script ...\",\n  \"update.download_failed\": \"Failed to download install script: {message}\",\n  \"update.write_failed\": \"Failed to write temp file: {message}\",\n  \"update.spawn_failed\": \"Install script failed to start: {message}\",\n  \"update.exit_code\": \"Install script exit code: {code}\",\n  \"update.request_failed\": \"Request failed: {url} (HTTP {status})\",\n  \"update.version_empty\": \"Version tag is empty: {baseUrl}\",\n\n  \"rec.setup.choice_prompt\": \"{prompt} [1-{max}, default {default}]: \",\n  \"rec.setup.choice_invalid\": \"  Enter a number between 1 and {max}\",\n  \"rec.setup.optional_suffix\": \" [optional, press Enter to skip]: \",\n  \"rec.setup.api_header\": \"─── Cloud ASR (model-proxy) setup ───\",\n  \"rec.setup.api_note\":\n    \"Note: no third-party API key needed; the plugin reuses the current account API key for the model-proxy long-recording API.\",\n  \"rec.setup.api.endpoint\": \"Custom model-proxy submit-task endpoint URL\",\n  \"rec.setup.api.language\": \"Language hint (e.g. zh / en)\",\n  \"rec.setup.api.itn\": \"Enable text normalization ITN? (y/N)\",\n  \"rec.setup.local_header\": \"─── Local Whisper transcription setup ───\",\n  \"rec.setup.local.model_label\": \"Model size:\",\n  \"rec.setup.local.model_auto\": \"Auto (recommend based on available memory)\",\n  \"rec.setup.local.choose_model\": \"Choose model\",\n  \"rec.setup.local.language\": \"Language hint (e.g. zh / en; leave empty for auto-detect)\",\n  \"rec.setup.local.backend_label\": \"Inference backend:\",\n  \"rec.setup.local.backend_auto\": \"Auto (recommend based on runtime)\",\n  \"rec.setup.local.backend_coreml\": \"coreml (recommended on Apple Silicon)\",\n  \"rec.setup.local.backend_cuda\": \"cuda (NVIDIA GPU)\",\n  \"rec.setup.local.choose_backend\": \"Choose backend\",\n  \"rec.setup.local.source_label\": \"Model download source:\",\n  \"rec.setup.local.source_auto\":\n    \"auto (probe HuggingFace first, fall back to domestic mirror)\",\n  \"rec.setup.local.source_hf\": \"huggingface (direct overseas)\",\n  \"rec.setup.local.source_domestic\": \"domestic (China mirror)\",\n  \"rec.setup.local.choose_source\": \"Choose download source\",\n  \"rec.setup.local.mirror\": \"Custom model download URL (overrides source)\",\n  \"rec.setup.existing\": \"Existing config: mode = {mode}\",\n  \"rec.setup.existing_updated\": \", updated at {updatedAt}\",\n  \"rec.setup.mode_label\": \"Transcription mode:\",\n  \"rec.setup.choose_mode\": \"Choose mode\",\n  \"rec.setup.mode_api\": \"api (cloud model-proxy long recording)\",\n  \"rec.setup.mode_local\": \"local (local Whisper)\",\n  \"rec.setup.saved\": \"✓ Config saved to {path}\",\n\n  \"prompt.light_rule.title\": \"Light-effect routing tips:\",\n  \"prompt.light_rule.persistent\":\n    \"- When the user says things like \\\"when/if/on receiving a certain notification or message, turn on/blink/show a light effect\\\", that is a persistent cloud light-rule request — you must call {create} or {update}.\",\n  \"prompt.light_rule.immediate\":\n    \"- When the user wants a light effect now/immediately, or after the current one-off task finishes, call light_control; do not create a light rule.\",\n  \"prompt.light_rule.display\":\n    \"- When the user asks to display/show content, text, or results on the hardware/screen/device, also call light_control: headline in title, body text in reason (gen-2 screen hardware shows the notification title and body on its screen). Do not create a light rule, and do not claim content cannot be shown on the hardware.\",\n  \"prompt.light_rule.rule_text\":\n    \"- When creating a rule, turn the user's natural-language request into ruleText; Notification Intelligence Service's dedicated Agent compiles and saves the rule.\",\n  \"prompt.light_rule.crud\":\n    \"- Create/update/delete/query light rules via lightrules_* tools; do not hand-edit tasks/*/meta.json.\",\n  \"prompt.light_rule.errors\":\n    \"- If a lightrules_* tool returns an error, report the failure honestly; do not pretend chat history or an old toolResult is the current cloud rule list.\",\n  \"prompt.light_rule.language\":\n    \"- Language: the reply AND the lightrules_create/update `ruleText` argument must use replyLanguage (from the original user-authored message that started this run). Prefer paraphrasing the user's own words into ruleText. Never translate an English request into Chinese ruleText (or the reverse) because App UI locale or tool schemas are another language—never mix languages.\",\n  \"prompt.reply.language\":\n    \"- Reply language: prose, tables, and natural-language strings inside code/tool samples must use replyLanguage (from the original user-authored message that started this run). If tool schemas or skills show examples in another language, translate them before writing the reply. Never mix languages in one reply (do not leave non-English sample phrases in an English reply).\",\n  \"locale.updated\": \"Global UI locale updated: {locale}\",\n\n  \"light.validation.must_array\": \"Must be an array\",\n  \"light.validation.must_not_empty\": \"Must not be empty\",\n  \"light.validation.max_segments\": \"At most {max} segments\",\n  \"light.validation.segments_json\": \"segments must be valid JSON\",\n  \"light.validation.must_object\": \"Must be an object\",\n  \"light.validation.unsupported_mode\": \"Unsupported mode '{mode}'; allowed: {modes}\",\n  \"light.validation.duration\": \"Must be a number ≥0 (0 means unlimited duration)\",\n  \"light.validation.color_flow_anchor\":\n    \"color_flow needs at least one non-zero color anchor (color or background)\",\n  \"light.validation.byte\": \"Must be a number 0–255\",\n  \"light.validation.brightness_zero\":\n    \"brightness=0 is only allowed in steady mode; other modes are filtered on firmware\",\n  \"light.validation.must_rgb_brightness\": \"Must include numeric r/g/b/brightness\",\n  \"light.validation.must_rgb\": \"Must include numeric r/g/b\",\n  \"light.validation.rise_ms\": \"rise_ms must be a number >0 (0ms not supported)\",\n  \"light.validation.hold_ms\": \"hold_ms must be a number ≥0\",\n  \"light.validation.fall_ms\": \"fall_ms must be a number >0 (0ms not supported)\",\n  \"light.validation.off_ms\": \"off_ms must be a number ≥0\",\n  \"light.validation.direction\": \"direction must be ltr or rtl\",\n  \"light.validation.window\": \"window only supports 1/2/3\",\n  \"light.validation.non_negative\": \"Must be a number ≥0\",\n  \"light.validation.color_flow_misuse\":\n    \"color_flow only has a single extreme solid foreground anchor (no effective background). The result is same-hue bright/dim ring flow, not a multi-color palette. If the user wants a \\\"single-color wave\\\", use mode='wave'; for multi-color flow, also set background as a second anchor.\",\n  \"light.repeat.ancs_only\":\n    \"The current ANCS path only supports repeat_times=0 (infinite) or 1 (one round); N>=2 requires a non-ANCS path\",\n  \"light.repeat.invalid\": \"repeat_times must be an integer >=0\",\n  \"light.rule.already_exists\": \"Light rule '{name}' already exists\",\n  \"light.rule.not_found\": \"Light rule '{name}' not found\",\n  \"light.rule.prompt.empty\": \"No enabled light rules.\",\n  \"light.rule.prompt.intro\":\n    \"You judge whether a notification matches a light rule.\",\n  \"light.rule.prompt.list_header\":\n    \"Enabled light rules (newest first):\",\n  \"light.rule.prompt.task\":\n    \"Task: given the next notification, decide which rules match.\",\n  \"light.rule.prompt.hit0\": \"- Match 0: call no tools and end.\",\n  \"light.rule.prompt.hit_n\":\n    \"- Match 1+: call trigger_light(rule_name) once per matched rule.\",\n  \"light.rule.prompt.no_text\":\n    \"- Do not reply with free text; express the decision **only** via tool calling.\",\n  \"light.rule.prompt.conservative\":\n    \"- When unsure, prefer not triggering to avoid bothering the user.\",\n  \"light.rule.trigger.simple\": \"Triggered light rule \\\"{rule}\\\"\",\n  \"light.rule.trigger.group\": \"{app} group \\\"{conversation}\\\"\",\n  \"light.rule.trigger.group_app\": \"{app} group chat\",\n  \"light.rule.trigger.sender_action\": \"{sender} sent a message\",\n  \"light.rule.trigger.new_message\": \"new message received\",\n  \"light.rule.trigger.detected\":\n    \"Detected {action} in {where}{detail}; triggered light rule \\\"{rule}\\\"\",\n  \"light.rule.tool.rule_text_desc\":\n    \"Natural-language rule in replyLanguage (same language as the user's original request). Prefer the user's own wording. English e.g. \\\"turn on red light when receiving a message containing 123\\\". Do not translate English requests into Chinese.\",\n  \"light.setup.next_restart\": \"Run: openclaw gateway restart\",\n\n  \"monitor.readme.description\": \"## Description\",\n  \"monitor.readme.guide_title\": \"## Handling guide\",\n  \"monitor.readme.guide_body\":\n    \"When fetch.py outputs matching notifications:\\n1. Read the matched notification content\\n2. Decide from the task description whether to notify the user\\n3. If needed, use the message tool to send a summary\",\n  \"monitor.cron.message\":\n    \"Phone notifications are captured in real time into JSON files under notifications/.\\nRun: python3 tasks/{name}/fetch.py --notifications-dir notifications\\n- NO_CHANGE or NO_MATCH → do not reply; end.\\n- Has output → read tasks/{name}/README.md to process data and notify the user.\",\n\n  \"summary_job.keyword.todo\": \"todo\",\n  \"summary_job.keyword.need\": \"need\",\n  \"summary_job.keyword.trouble\": \"please\",\n  \"summary_job.keyword.confirm\": \"confirm\",\n  \"summary_job.keyword.reply\": \"reply\",\n  \"summary_job.keyword.approve\": \"approve\",\n  \"summary_job.keyword.meet\": \"meeting\",\n  \"summary_job.keyword.meeting\": \"meeting\",\n  \"summary_job.keyword.schedule\": \"schedule\",\n  \"summary_job.keyword.deadline\": \"deadline\",\n  \"summary_job.keyword.urgent\": \"urgent\",\n  \"summary_job.keyword.abnormal\": \"abnormal\",\n  \"summary_job.keyword.fail\": \"fail\",\n  \"summary_job.keyword.risk\": \"risk\",\n  \"summary_job.none\": \"none\",\n  \"summary_job.chunk_title\": \"## Chunk {id}\",\n  \"summary_job.count\": \"- Count: {count}\",\n  \"summary_job.time_range\": \"- Time range: {oldest} to {newest}\",\n  \"summary_job.top_apps\": \"- Top apps: {apps}\",\n  \"summary_job.top_senders\": \"- Top senders/chats: {senders}\",\n  \"summary_job.attention\": \"### Needs attention\",\n  \"summary_job.no_attention\": \"- No clear todo, risk, or anomaly samples\",\n  \"summary_job.recent\": \"### Recent samples\",\n  \"summary_job.none_item\": \"- none\",\n  \"summary_job.result_title\": \"# Notification summary job {id}\",\n  \"summary_job.result_total\": \"- Notifications: {total}\",\n  \"summary_job.result_chunks\": \"- Chunks: {count}\",\n  \"summary_job.result_chunk_summaries\": \"## Chunk summaries\",\n  \"summary_job.result_chunk_line\":\n    \"### {id} · {count} items · {oldest} to {newest}\",\n  \"summary_job.uncommitted\": \"(summary not committed)\",\n\n  \"recording.summary.title\": \"# Summary\",\n  \"recording.summary.decisions\": \"Decisions\",\n  \"recording.summary.todos\": \"Todos\",\n  \"recording.summary.risks\": \"Risks\",\n  \"recording.summary.open_questions\": \"Open questions\",\n  \"recording.summary.meta_name\": \"> Recording name: {name}\",\n  \"recording.summary.meta_duration\": \"> Duration: {duration}\",\n  \"recording.summary.meta_created\": \"> Created at: {created}\",\n  \"recording.summary.meta_markers\": \"> Interest points: {count}\",\n  \"recording.marker_heading\": \"### Interest points\",\n  \"recording.error.not_found\": \"Recording not found: {id}\",\n  \"recording.error.storage_unavailable\": \"Recording storage unavailable: {path}\",\n  \"recording.error.download_failed\": \"Download failed\",\n  \"recording.error.empty_body\": \"Empty response body\",\n  \"recording.error.size_limit\": \"Recording exceeds limit of {maxBytes} bytes\",\n  \"recording.error.timeout\": \"timed out\",\n  \"recording.error.interrupted\": \"Transcription interrupted; please restart transcription\",\n  \"image.error.storage_unavailable\": \"Image storage unavailable: {path}\",\n  \"image.error.download_failed\": \"Download failed\",\n  \"notification.error.storage_unavailable\": \"Notification storage unavailable: {path}\",\n  \"auth.apikey_missing\": \"apiKey is not set\",\n  \"auth.apikey_missing_hint\":\n    \"apiKey is not set; run ntf auth set-api-key <apiKey> (or {path})\",\n  \"auth.credentials_missing\":\n    \"API Key is not set; write it to {path}, or run ntf auth set-api-key <apiKey> via the host CLI\",\n  \"auth.apikey_invalid_char\":\n    \"apiKey contains an illegal character (offset {index}, code point {code}) and cannot be sent as an HTTP header; this usually means a masked/truncated preview (e.g. oc_api…) was stored instead of the full key. Check the YOOOCLAW_API_KEY env var and {path}, then write the full apiKey again\",\n  \"errors.INVALID_ENV_VALUE\": \"Invalid environment name: {env}; allowed: {available}\",\n  \"errors.INVALID_LOCALE_VALUE\": \"Invalid locale: {locale}; allowed: {locales}\",\n\n  \"update.notify.failed_title\": \"Plugin update failed\",\n  \"update.notify.in_progress_title\": \"Plugin update in progress\",\n  \"update.notify.restart_failed_after_update\":\n    \"Plugin updated, but gateway auto-restart failed\",\n  \"update.notify.restart_failed_prepared\":\n    \"Plugin update prepared, but gateway auto-restart failed\",\n  \"update.notify.restart_failed_default\":\n    \"Gateway auto-restart failed; restart openclaw/gateway manually.\",\n  \"update.notify.pending\":\n    \"Update package is ready; waiting for gateway restart to apply.\",\n  \"update.notify.applying\": \"Plugin update is being applied; please wait.\",\n  \"update.notify.wait_restart\": \"Wait for gateway restart to finish\",\n  \"update.notify.manual_restart_if_stuck\":\n    \"If nothing changes for a long time, restart openclaw/gateway manually\",\n  \"update.action.manual_restart\": \"Restart openclaw/gateway manually\",\n  \"update.action.retry_trigger\": \"Re-trigger the plugin update after restart\",\n  \"update.action.retry_update\": \"Re-trigger the plugin update\",\n  \"update.action.reinstall_default\":\n    \"If it keeps failing, reinstall with the install script into the default extensions directory\",\n  \"update.action.check_mount\":\n    \"Check whether the plugin path points to an external/network/container mount or symlink\",\n  \"update.action.close_gateway_retry\": \"Close openclaw/gateway and retry\",\n  \"update.action.check_busy\": \"Check plugin directory permissions or file locks\",\n  \"update.action.check_av\":\n    \"Confirm antivirus, terminals, or editors are not locking the plugin directory\",\n  \"update.action.retry_later\": \"Retry the update later\",\n  \"update.action.report\": \"If it keeps failing, copy the error and report it to maintainers\",\n  \"update.action.enable_restart\": \"To auto-restart, enable commands.restart\",\n  \"update.action.wait_current\": \"Wait for the current update to finish\",\n  \"update.action.wait_apply\": \"Wait for gateway to auto-restart and apply the update\",\n  \"update.action.check_network\": \"Check network connectivity\",\n  \"update.action.check_tar\": \"Confirm the system tar command is available\",\n  \"update.action.wait_load\": \"Wait for gateway to auto-restart and load the new version\",\n  \"update.fail.timeout\":\n    \"Gateway did not exit in time; the update was not applied. Restart openclaw/gateway manually and retry.\",\n  \"update.fail.cross_device\":\n    \"Update install failed; plugin and temp dirs may be on different disks/mounts. Re-trigger the update; if it still fails, reinstall with the install script into the default extensions directory.\",\n  \"update.fail.busy\":\n    \"Update install failed; the plugin directory may be in use. Close openclaw/gateway and retry.\",\n  \"update.fail.generic\":\n    \"Update install failed; rollback was attempted. Fix the issue based on the error and retry.\",\n  \"update.fail.restart_disabled\":\n    \"Gateway auto-restart is disabled; restart openclaw/gateway manually to apply.\",\n  \"update.fail.no_sigusr1\":\n    \"This host does not support auto-restart; restart openclaw/gateway manually to apply.\",\n  \"update.fail.bg_start\":\n    \"Update package is ready, but the background installer failed to start; the update was not applied. Retry later.\",\n  \"update.fail.windows\":\n    \"Windows does not support auto-restarting gateway; restart manually for the update to take effect.\",\n  \"update.fail.windows_ready\": \"After restart, the plugin will apply the new version automatically\",\n  \"update.fail.restart_unavailable\":\n    \"Gateway auto-restart is unavailable; the update was not applied.\",\n  \"update.fail.enable_restart_retry\": \"Enable gateway auto-restart and retry the update\",\n  \"update.msg.not_pending\": \"Update {id} is not pending and cannot be applied\",\n  \"update.msg.missing_package\": \"Update {id} is missing packageDir and cannot be applied\",\n  \"update.msg.applied\": \"Applied update to {version}\",\n  \"update.msg.apply_failed\": \"Failed to apply update: {error}\",\n  \"update.msg.invalid_version\": \"Invalid version: {version}\",\n  \"update.msg.busy\":\n    \"Another update is already in progress ({version}, {status}/{phase}); try again later.\",\n  \"update.msg.busy_suggestion\":\n    \"Wait for the current update, or restart openclaw/gateway and retry.\",\n  \"update.msg.download_failed\": \"Download failed (HTTP {status}): {url}\",\n  \"update.msg.download_suggestion\": \"Failed to download the plugin package; check network or retry later.\",\n  \"update.msg.extract_failed\": \"Extract failed: {error}\",\n  \"update.msg.extract_suggestion\": \"Failed to extract the plugin package; confirm tar is available and retry.\",\n  \"update.msg.prepared\": \"Prepared update to {version}\",\n  \"update.msg.prepared_suggestion\":\n    \"Update package is ready; it will apply after gateway restarts.\",\n  \"update.msg.exec_error\": \"Update execution error: {error}\",\n  \"update.msg.prepared_manual\":\n    \"Prepared update to {version}; restart openclaw/gateway manually to apply\",\n  \"update.msg.prepared_no_restart\":\n    \"Prepared update to {version}, but gateway auto-restart is unavailable; update not applied\",\n  \"update.msg.bg_failed\":\n    \"Update prepared but background installer failed to start: {error}\",\n  \"update.msg.applied_restarting\":\n    \"Applied update to {version}; restarting gateway\",\n  \"recording.error.invalid_transition\": \"Invalid state transition: {from} → {to}\",\n  \"light.api.not_configured\":\n    \"Light API is not configured; confirm OPENCLAW_HOST_* / LIGHT_APP_KEY / LIGHT_TEMPLATE_ID were set at build time\",\n  \"update.version.fallback\": \"target version\",\n  \"update.plugin_name\": \"Phone Notifications\",\n  \"update.tool.version_desc\": \"Target version, e.g. 1.11.0\",\n  \"light.rule.match.intro\":\n    \"You match phone notifications to light rules.\",\n  \"light.rule.match.low_latency\":\n    \"This is a low-latency classification task; do not output reasoning, explanations, Markdown, or <think> content.\",\n  \"light.rule.match.no_guess\":\n    \"Judge only from rule description and notification fields; do not guess.\",\n  \"light.rule.match.conservative\": \"If unsure, do not trigger.\",\n  \"light.rule.match.output_format\": \"Output must be pure JSON in this exact shape:\",\n  \"light.rule.match.output_schema\":\n    \"{\\\"matches\\\":[{\\\"i\\\":<notification index>,\\\"rule\\\":\\\"<rule name>\\\"}]}\",\n  \"light.rule.match.zero_or_exact\":\n    \"For zero matches output {\\\"matches\\\":[]}; rule must exactly equal a name below.\",\n  \"light.rule.match.tips_header\": \"Matching tips:\",\n  \"light.rule.match.tip_sender\":\n    \"- Sender/contact rules: prefer sender, then conversation_name, title, or an \\\"X:\\\"/\\\"X：\\\" prefix at the start of content; ignore whitespace, emoji, and CJK/ASCII punctuation differences.\",\n  \"light.rule.match.tip_app\":\n    \"- App notification rules: check whether app/appDisplayName matches the description.\",\n  \"light.rule.match.tip_keyword\":\n    \"- Keyword rules: check whether title + content contain or are semantically equivalent to the keywords in the description.\",\n  \"light.rule.match.tip_semantic\":\n    \"- Semantic rules: judge from title + content together; do not treat names casually mentioned in the body as the sender.\",\n  \"light.rule.match.rules_header\": \"Enabled rules:\",\n  \"light.rule.match.notifications_header\":\n    \"The following {count} new phone notifications, numbered in order:\",\n  \"light.rule.match.ask_json\":\n    \"Decide which rules each notification matches and output JSON in the agreed format.\",\n  \"light.rule.api.jwt_plugin_path\":\n    \"{message}. The request hit the plugin-side API {path}; plugin auth should use only X-Api-Key-Id. The current 401 comes from the cloud JWT auth layer, meaning this plugin prefix was not routed to API Key auth by the gateway/server. Ask backend to check gateway allowlist and Notification Intelligence Service plugin routes: {url}\",\n  \"light.rule.api.jwt_app_path\":\n    \"{message}. Light rules should call the plugin-side API /api/plugin/notification-intelligence/light-rules with X-Api-Key-Id auth; this request may have hit the App JWT endpoint instead: {url}\",\n  \"tool.light.description\":\n    \"Control hardware lighting immediately (one-shot; does not create or save notification-triggered rules). Supports 1–12 sequential segments with five modes: wave / breath / strobe / steady / color_flow. The tool quantizes to embedded-protocol discrete steps, builds a compact ANCS control sequence per mode, and sends it over HTTP. Call when the user asks to turn lights on, change effects, set colors, set ambience, or preview/test lighting. Gen-2 hardware has a screen and shows this delivery's notification title and body on it: when the user asks to display/show content on the hardware/screen/device, also call this tool—put the headline in title and the body text in reason. If the user wants lights on certain notifications/messages, that is a persistent light rule—use {createTool} or {updateTool} instead.\",\n  \"tool.light.segments_desc\": \"Light segments, 1–12, played in order\",\n  \"tool.light.mode_desc\":\n    \"Mode: wave (single-color chase, foreground + optional background) / breath / strobe / steady / color_flow (palette flows around the ring with 1–2 color anchors; **not a rainbow**, cannot produce a 7-color rainbow wave). Common mistakes: user asks for a red/blue wave → use wave, not color_flow; user asks for rainbow → firmware has no true 7-color rainbow—explain the limit and suggest dual-anchor color_flow or multi-segment wave rotation; do not silently fake rainbow with a single-anchor color_flow.\",\n  \"tool.light.duration_s_desc\":\n    \"Segment duration in seconds; 0 means infinite. Recommended discrete values: 0.5/1/2/3/5/6/8/16/24/32/48; keep segments ≤8s when possible to save power\",\n  \"tool.light.brightness_desc\":\n    \"Foreground brightness 0–255. Required; brightness=0 is only valid in steady mode (explicit off)\",\n  \"tool.light.color_desc\":\n    \"Foreground RGB. Required; in color_flow it is the first color anchor—at least one of color/background must be non-zero\",\n  \"tool.light.interval_ms_desc\":\n    \"Step interval (ms) for wave/strobe/color_flow; default 200. Quantized steps: 50/100/200/300/500/600/800/1600/2400/3200/4800\",\n  \"tool.light.direction_desc\": \"Wave/color_flow direction; default ltr\",\n  \"tool.light.window_desc\": \"wave: window size, default 2; color_flow: palette shift step (speed)\",\n  \"tool.light.breath_rise_ms_desc\": \"Rise time (ms), quantized to 1040/1560/2080/2600/3100/4160\",\n  \"tool.light.breath_hold_ms_desc\": \"Hold at peak brightness (ms); 0ms supported\",\n  \"tool.light.breath_fall_ms_desc\": \"Fall time (ms), quantized to 1040/1560/2080/2600/3100/4160\",\n  \"tool.light.breath_off_ms_desc\": \"Off time (ms); 0ms supported\",\n  \"tool.light.breath_timing_desc\":\n    \"Breath four-phase timing; breath only. rise/fall quantized to 1040/1560/2080/2600/3100/4160; hold/off also support 0ms\",\n  \"tool.light.background_desc\":\n    \"Background RGB + brightness; wave uses it as the base layer; color_flow uses it as the second anchor (interpolated with foreground for a multi-color palette)\",\n  \"tool.light.background_brightness_desc\":\n    \"Background brightness; quantized steps: 0/32/64/96/128/192/255\",\n  \"tool.light.reason_desc\":\n    \"Summarize from the conversation context and keep reason within 30 characters. Briefly explain why to light up (e.g. comfort, birthday, hydration reminder). This records the intent of each lighting action. Gen-2 screen hardware shows it as the notification body alongside title: when the user wants to display content, summarize the body text here within 30 characters.\",\n  \"tool.light.title_desc\":\n    \"Short title/summary for this lighting action (e.g. warm ambience, birthday, hydration). Gen-2 screen hardware shows it as the notification title: when the user's intent is to display content, put the headline/main content here. Phone push notification length limits apply—keep it short or it gets truncated. Falls back to reason when omitted.\",\n  \"tool.light.repeat_desc\":\n    \"Legacy flag: true = loop forever, false/omitted = one round; repeat_times wins when both are set\",\n  \"tool.light.repeat_times_desc\":\n    \"Whole sequence repeat count: 0 = infinite loop, 1 = one round. ANCS path does not support N>=2\",\n  \"tool.lightrules.list_desc\":\n    \"List light rules for the current account in Notification Intelligence Service (enabled and disabled). Call when the user asks to list or view light rules.\",\n  \"tool.lightrules.create_desc\":\n    \"Create a persistent cloud light rule. Pass the user's original natural-language request as ruleText in replyLanguage (do not translate English into Chinese or Chinese into English). A separate Agent compiles name/title/description/segments/repeat_times and saves it. Call when the user wants lights on certain notifications/messages or asks to create a light rule.\",\n  \"tool.lightrules.update_desc\":\n    \"Update a cloud light rule. Prefer id; if only the display name or name is known, call lightrules_list first. ruleText recompiles semantics via the separate Agent and must stay in replyLanguage; title/enabled/description/segments/repeat_times are plain field patches. ruleText cannot be mixed with plain fields in one call.\",\n  \"tool.lightrules.delete_desc\":\n    \"Delete a cloud light rule (currently soft-delete on the server). Prefer id; call lightrules_list if unsure.\",\n  \"tool.lightrules.segments_desc\": \"Light segments, 1–12, played in order\",\n  \"tool.lightrules.mode_desc\":\n    \"Mode: wave / breath / strobe / steady / color_flow\",\n  \"tool.lightrules.duration_s_desc\": \"Duration in seconds; 0 means infinite\",\n  \"tool.lightrules.param.id_desc\": \"Cloud rule ID (preferred)\",\n  \"tool.lightrules.param.name_desc\": \"Semantic rule name (legacy compatibility)\",\n  \"tool.lightrules.param.rule_id_desc\": \"Rule ID (legacy field)\",\n  \"tool.lightrules.param.rule_name_desc\": \"Rule name (legacy field)\",\n  \"tool.lightrules.param.rule_text_desc\":\n    \"New natural-language rule in replyLanguage; separate Agent recompiles when set. Do not translate away from the user's language.\",\n  \"tool.lightrules.param.title_desc\": \"New display title (optional)\",\n  \"tool.lightrules.param.description_desc\": \"New trigger description (optional)\",\n  \"tool.lightrules.param.enabled_desc\": \"true = enabled, false = disabled\",\n  \"tool.lightrules.param.segments_desc\": \"New segment sequence (optional; unchanged when omitted)\",\n  \"tool.lightrules.param.repeat_times_desc\": \"New repeat count: 0 = infinite loop, 1 = one round\",\n  \"tool.lightrules.param.repeat_desc\": \"Legacy field: true = infinite loop, false = one round\",\n  \"tool.lightrules.error.rule_scope\":\n    \"Persistent light rules must include notification/message/call triggers; use light_control for one-shot lighting\",\n  \"tool.lightrules.error.rule_text_required\": \"ruleText is required\",\n  \"tool.lightrules.error.rule_text_empty\": \"ruleText must be a non-empty string\",\n  \"tool.lightrules.error.rule_text_mixed\":\n    \"ruleText cannot be mixed with title/enabled/description/segments/repeat_times/repeat in one call\",\n  \"tool.lightrules.error.title_empty\": \"title must be a non-empty string\",\n  \"tool.lightrules.error.description_type\": \"description must be a string\",\n  \"tool.lightrules.error.enabled_type\": \"enabled must be a boolean\",\n  \"tool.lightrules.error.repeat_times_type\": \"repeat_times must be a number\",\n  \"tool.lightrules.error.repeat_type\": \"repeat must be a boolean\",\n  \"tool.lightrules.error.update_field_required\": \"at least one update field is required\",\n  \"tool.lightrules.error.id_required_update\":\n    \"id is required; call lightrules_list first if needed\",\n  \"tool.lightrules.error.id_required_delete\": \"id is required\",\n  \"tool.lightrules.error.unknown\": \"Unknown error\",\n  \"update.tool.description\":\n    \"Update the phone-notifications plugin to a target version. Call only after the user explicitly agrees. After update, gateway auto-restart is attempted; manual restart if the host does not support it.\",\n  \"update.notice.new_version_available\":\n    \"[System notice] phone-notifications plugin update {latest} is available (current {current}).\\nTell the user in natural language when appropriate; if they agree, call plugin-update with the version parameter. Do not repeat if they decline.\",\n  \"update.stale.base\":\n    \"[System notice] phone-notifications was updated to {diskVersion} on disk, but the process still runs {runningVersion}: in-process gateway restart (SIGUSR1 / gateway.restart) does not reload plugin code.\",\n  \"update.stale.restart_scheduled\":\n    \"A full restart was triggered automatically. If this notice persists after a few minutes, auto-restart did not work—tell the user to fully restart the openclaw process (e.g. systemctl restart openclaw, or let the service manager relaunch after stopping the process).\",\n  \"update.stale.manual_required\":\n    \"Tell the user a full openclaw process restart is required{reason}: e.g. systemctl restart openclaw, or stop openclaw and let the service manager relaunch; in-process gateway restart alone is not enough.\",\n  \"update.stale.reason_suffix\": \" ({reason})\",\n  \"update.stale.reason.restart_disabled\":\n    \"commands.restart=false; automatic restart is disabled by config\",\n  \"update.stale.reason.already_attempted\":\n    \"a full restart for {diskVersion} was already attempted once and did not take effect (host may not be managed by a service manager)\",\n  \"update.stale.reason.record_failed\":\n    \"could not record the auto-restart attempt ({error}); not retrying to avoid a restart loop\",\n  \"recording.error.audio_download_failed\": \"Audio download failed: {error}\",\n  \"recording.error.audio_download_exception\": \"Audio download error: {error}\",\n  \"image.error.sync_failed\": \"Image sync failed: {error}\",\n  \"image.error.download_msg\": \"Image download failed: {error}\",\n  \"image.error.empty_body\": \"Empty response body\",\n  \"image.error.size_limit\": \"Image exceeds limit of {maxBytes} bytes\",\n  \"image.error.timeout\": \"Download timed out\",\n  \"apns.error.config_missing\":\n    \"APNs auth config missing: set OPENCLAW_APNS_TEAM_ID, OPENCLAW_APNS_KEY_ID, OPENCLAW_APNS_PRIVATE_KEY_P8\",\n  \"tunnel.slim.middle_omitted\": \"……[truncated, {omitted} chars omitted]……\",\n  \"tunnel.slim.preview_truncated\": \"…[truncated {omitted} chars]\",\n\n  \"ns.error.positive_int\": \"{field} must be an integer greater than 0\",\n  \"ns.error.iso_time\": \"{field} must be a valid ISO 8601 time\",\n  \"ns.error.conversation_type\": \"conversationType must be group or private\",\n  \"ns.error.from_after_to\": \"from must not be later than to\",\n  \"ns.none\": \"none\",\n  \"ns.sep\": \"; \",\n  \"ns.chunk.title\": \"### Chunk {id}\",\n  \"ns.chunk.count\": \"- Count: {count}\",\n  \"ns.chunk.top_apps\": \"- Top apps: {apps}\",\n  \"ns.chunk.top_senders\": \"- Top senders/chats: {senders}\",\n  \"ns.chunk.attention\": \"Needs attention:\",\n  \"ns.chunk.no_attention\": \"- No clear todo, risk, or anomaly samples\",\n  \"ns.chunk.recent\": \"Recent samples:\",\n  \"ns.chunk.none_item\": \"- none\",\n  \"ns.md.title\": \"# Notification summary\",\n  \"ns.md.total\": \"- Notifications: {total}\",\n  \"ns.md.cap_overflow\":\n    \"- Cap: request exceeded the limit; processed the latest {limit} items\",\n  \"ns.md.cap_recent\": \"- Cap: latest {limit} items\",\n  \"ns.md.time_range\": \"- Time range: {oldest} to {newest}\",\n  \"ns.md.scan\":\n    \"- Scan: {days} days / {items} items, matched {matched}, took {elapsedMs}ms\",\n  \"ns.md.distribution\": \"## Overall distribution\",\n  \"ns.md.top_apps\": \"- Top apps: {apps}\",\n  \"ns.md.top_senders\": \"- Top senders/chats: {senders}\",\n  \"ns.md.top_conversations\": \"- Top conversations: {conversations}\",\n  \"ns.md.attention\": \"## Needs attention\",\n  \"ns.md.no_attention\": \"- No clear todo, risk, failure, or urgent samples\",\n  \"ns.md.chunk_summaries\": \"## Chunk summaries\",\n  \"ns.md.no_notifications\": \"No notifications\",\n  \"ns.display.title\": \"# Unread notification summary\",\n  \"ns.display.empty\": \"No matching notifications found.\",\n  \"ns.display.scan_range\":\n    \"Scan range: {days} days / {items} items, took {elapsedMs}ms.\",\n  \"ns.display.coverage_overflow\":\n    \"request exceeded the limit; processed the latest {limit} items\",\n  \"ns.display.coverage_hit\": \"matched {total} within the latest {limit} items\",\n  \"ns.display.summary_line\":\n    \"Summarized {total} notifications; coverage: {coverage}.\",\n  \"ns.display.time_range\": \"Time range: {oldest} to {newest}.\",\n  \"ns.display.sources\": \"## Top sources\",\n  \"ns.display.app\": \"- Apps: {apps}\",\n  \"ns.display.sender\": \"- Senders/chats: {senders}\",\n  \"ns.display.conversation\": \"- Conversations: {conversations}\",\n  \"ns.display.attention\": \"## Needs attention\",\n  \"ns.display.recent\": \"## Recent samples\",\n  \"ns.progress.scanning\": \"Scanning notifications...\",\n  \"ns.progress.snapshot\":\n    \"Found {total} notifications; split into {chunks} chunks\",\n  \"ns.progress.summarizing\":\n    \"Summarizing notifications: {done}/{total} chunks\",\n  \"ns.progress.merging\": \"Merging summaries...\",\n  \"ns.progress.complete\":\n    \"Notification summary complete; pushing the result...\",\n\n  \"tool.notifications.summary_desc\":\n    \"Summarize phone notifications/messages and broadcast notification.summary.status progress events while running. Prefer this when the user asks to summarize recent/unread notifications or roughly N items. If the user gives ~N / latest N, pass N as limit unchanged; when unread has no dedicated filter, treat it as recent and do not inflate the count yourself. On completion, broadcast notification.summary.result with display-ready Markdown. The return value is compressed Markdown summary input; reply based on it and avoid listing every item.\",\n  \"tool.notifications.from_desc\":\n    \"Start time, ISO 8601, e.g. 2026-06-13T09:00:00+08:00\",\n  \"tool.notifications.to_desc\": \"End time, ISO 8601\",\n  \"tool.notifications.app_desc\": \"Filter by app name or display name\",\n  \"tool.notifications.sender_desc\": \"Filter by sender/title\",\n  \"tool.notifications.conversation_type_desc\": \"Filter by conversation type\",\n  \"tool.notifications.keyword_desc\":\n    \"Search keywords in title, body, sender, and conversation name\",\n  \"tool.notifications.limit_desc\":\n    \"Max notifications in the summary; default 700, max 3000\",\n  \"tool.notifications.chunk_size_desc\":\n    \"Notifications per chunk; default 150\",\n  \"ns.event.complete_message\": \"Notification summary complete\",\n  \"ns.event.complete_title\": \"Unread notification summary\",\n  \"ns.event.failed\": \"Notification summary failed: {message}\",\n  \"ns.event.summary_failed\": \"Notification summary failed: {message}\",\n  \"ns.event.started\": \"Notification summary job started...\",\n  \"ns.event.storage_not_ready\": \"Notification storage is not ready yet\",\n} as const;\n",
    "export const zhCN = {\n  \"cli.ntf.description\": \"手机通知数据管理\",\n  \"cli.ntf.version\": \"显示插件版本\",\n  \"plugin.registration.call\":\n    \"register() 调用: registrationMode={registrationMode} cliInvocation={cliInvocation}\",\n  \"plugin.registration.cli_registered\":\n    \"CLI 命令已注册: ntf, phone-notifications\",\n  \"plugin.registration.cli_only\":\n    \"检测到插件 CLI 命令执行上下文，仅注册 CLI，跳过后台服务以避免影响 Relay tunnel 常驻连接\",\n  \"plugin.ntf_bin.target_missing\": \"ntf wrapper: 目标不存在 {path}，跳过\",\n  \"plugin.ntf_bin.visibility.immediate\": \"立即生效\",\n  \"plugin.ntf_bin.visibility.needs_path\": \"需要加入 PATH\",\n  \"plugin.ntf_bin.registered\": \"独立 ntf 已注册: {path} -> {target}（{label}，{visibility}）\",\n  \"plugin.ntf_bin.path_hint\":\n    \"若 ntf 命令未立即生效，请把目录加入 PATH: export PATH=\\\"{dir}:$PATH\\\"\",\n  \"plugin.ntf_bin.register_failed\": \"独立 ntf 注册失败: {failures}\",\n  \"plugin.ntf_bin.no_install_dir\": \"无可用安装目录\",\n  \"plugin.ntf_bin.candidate.node\": \"node 同目录\",\n  \"plugin.ntf_bin.candidate.host\": \"宿主 CLI ({name}) 同目录\",\n  \"plugin.ntf_bin.candidate.path\": \"PATH 目录\",\n  \"plugin.ntf_bin.candidate.fallback\": \"stateDir/bin 兜底\",\n  \"plugin.ntf_bin.mkdir_failed\": \"mkdir {dir} 失败: {error}\",\n  \"plugin.ntf_bin.target_occupied\": \"已有 {path}，跳过覆盖\",\n  \"plugin.ntf_bin.write_failed\": \"写入 {path} 失败: {error}\",\n  \"plugin.tunnel.auth_not_ready\":\n    \"Relay tunnel: 认证未就绪（{reason}，credentials={path}），跳过隧道连接。请执行 ntf auth set-api-key <apiKey>\",\n  \"plugin.tunnel.invalid_gateway_env\": \"忽略无效的 {key}={value}\",\n  \"auth.jvsclaw.skip_missing_secret\":\n    \"jvsclaw auth: apiKey 已存在且未找到 link_secret，跳过置换\",\n  \"auth.jvsclaw.skip_unchanged_secret\":\n    \"jvsclaw auth: apiKey 已存在且 link_secret 未变化，跳过置换\",\n  \"auth.jvsclaw.exchange_succeeded\":\n    \"jvsclaw auth: instance/ready 置换 apiKey 成功（attempt {attempt}）\",\n  \"auth.jvsclaw.exchange_fatal\":\n    \"jvsclaw auth: 置换失败且不可恢复（code={code}）: {message}，停止轮询\",\n  \"auth.jvsclaw.exchange_retry\":\n    \"jvsclaw auth: 置换失败（attempt {attempt}）: {message}，{delayMs}ms 后重试\",\n  \"auth.jvsclaw.retry_aborted\": \"jvsclaw auth: 置换重试被中止（插件停止）\",\n  \"auth.jvsclaw.link_secret_missing\":\n    \"未在 {path} 找到 link_secret（路径: plugins.entries.phone-notifications.config.link_secret）\",\n  \"auth.jvsclaw.ready_url_missing\": \"instance/ready 接口地址为空（检查 host 配置）\",\n  \"auth.jvsclaw.ready_response_error\":\n    \"instance/ready 返回 code={code} msg={message}\",\n  \"auth.jvsclaw.api_key_missing\": \"instance/ready 响应未包含 apiKey\",\n  \"update.stale.log.detected\":\n    \"插件更新未生效：磁盘已安装 {diskVersion}，进程仍在运行 {runningVersion}。宿主的进程内重启不会重新加载插件代码，需要完整重启 openclaw 进程。\",\n  \"update.stale.log.config_failed\": \"陈旧运行时检查读取配置失败: {error}\",\n  \"update.stale.log.restart_triggered\":\n    \"已触发完整 gateway 重启以加载插件 {diskVersion}: {command}\",\n  \"update.stale.log.restart_failed\":\n    \"自动完整重启失败（{error}），请手动完整重启 openclaw 进程以加载 {diskVersion}\",\n  \"update.stale.log.restart_scheduled\":\n    \"将在 {seconds}s 后尝试完整重启 gateway（openclaw gateway restart）以加载 {diskVersion}\",\n  \"storage.notifications.state_path\": \"通知将写入 stateDir 路径: {path}\",\n  \"storage.notifications.fallback\":\n    \"stateDir 不可用，通知已回退到 workspace 路径: {path}\",\n  \"storage.notifications.corrupt_quarantined\":\n    \"通知文件损坏，已隔离到 {path}，当日通知从空文件重新累积\",\n  \"storage.notifications.corrupt_failed\":\n    \"通知文件损坏且隔离失败，后续写入可能覆盖原文件: {path}\",\n  \"storage.recordings.state_path\": \"录音将写入 stateDir 路径: {path}\",\n  \"storage.recordings.fallback\":\n    \"stateDir 不可用，录音已回退到 workspace 路径: {path}\",\n  \"storage.recordings.corrupt_quarantined\":\n    \"录音索引文件损坏，已隔离到 {path} 并重建空索引\",\n  \"storage.recordings.corrupt_failed\":\n    \"录音索引文件损坏且隔离失败，已重建空索引: {path}\",\n  \"storage.images.state_path\": \"图片将写入 stateDir 路径: {path}\",\n  \"storage.images.fallback\": \"stateDir 不可用，图片已回退到 workspace 路径: {path}\",\n  \"storage.images.corrupt_quarantined\":\n    \"图片索引文件损坏，已隔离到 {path} 并重建空索引\",\n  \"storage.images.corrupt_failed\":\n    \"图片索引文件损坏且隔离失败，已重建空索引: {path}\",\n  \"plugin.registration.wire_once\":\n    \"register(): 本进程已完成后台装配（openclawDir={openclawDir}），已为当前 Agent collector 补注册工具，跳过重复后台 wiring\",\n  \"plugin.registration.light_rules\":\n    \"灯效规则方法已注册: gateway={gateway}; tools={tools}\",\n  \"plugin.interfaces.notifications.tools\":\n    \"Agent 通知工具已注册: notifications_summary\",\n  \"plugin.interfaces.notifications.gateway\":\n    \"Gateway 通知方法已注册: notifications.push / notifications.summary.start / notifications.summary.status / notifications.summary.result\",\n  \"plugin.interfaces.notifications.http\": \"HTTP 通知端点已注册: POST /notifications\",\n  \"plugin.interfaces.recordings.gateway\":\n    \"Gateway 录音方法已注册: recordings.result.write / recordings.list / recordings.status / recordings.rename / recordings.delete\",\n  \"plugin.interfaces.recordings.http\":\n    \"HTTP 录音端点已注册: POST /recordings（等待文件完成）\",\n  \"plugin.interfaces.images.gateway\": \"Gateway 图片方法已注册: images.sync\",\n  \"plugin.interfaces.images.http\": \"HTTP 图片端点已注册: POST /images\",\n  \"plugin.interfaces.system.gateway\": \"Gateway 系统方法已注册: system.os\",\n  \"plugin.interfaces.system.http\": \"HTTP 系统端点已注册: GET /system/os\",\n  \"plugin.interfaces.locale.gateway\":\n    \"Gateway 语言方法已注册: plugin.locale.get / plugin.locale.set（事件: {event}）\",\n  \"plugin.interfaces.locale.http\":\n    \"HTTP 语言端点已注册: GET|POST /plugin/locale\",\n  \"plugin.interfaces.auto_update\": \"自动更新检查服务已注册\",\n  \"plugin.lifecycle.storage.notifications_started\": \"通知存储服务已启动: {path}\",\n  \"plugin.lifecycle.storage.recordings_started\": \"录音存储服务已启动: {path}\",\n  \"plugin.lifecycle.storage.images_started\": \"图片存储服务已启动: {path}\",\n  \"plugin.lifecycle.storage.stopped\": \"通知/录音/图片存储服务已停止\",\n  \"plugin.lifecycle.tunnel.registered\": \"Relay tunnel 服务已注册\",\n  \"cli.light.description\": \"灯效管理\",\n  \"cli.light.send.description\": \"发送灯效指令到硬件设备\",\n  \"cli.light.setup_tools.description\":\n    \"自动放行一次性灯效与云端灯效规则工具（兼容 tools.allow / tools.alsoAllow）\",\n  \"cli.rec.description\": \"录音管理\",\n  \"cli.rec.list.description\": \"列出所有录音（可按状态过滤）\",\n  \"cli.rec.status.description\": \"查看单条录音详情\",\n  \"cli.rec.storage_path.description\": \"查询录音存储路径\",\n  \"cli.rec.setup.description\": \"交互式配置 ASR 转写参数，保存到本地配置文件\",\n  \"cli.image.description\": \"图片管理\",\n  \"cli.image.list.description\": \"列出所有图片（可按状态/来源应用过滤）\",\n  \"cli.image.status.description\": \"查看单张图片详情\",\n  \"cli.image.path.description\": \"打印图片本地文件绝对路径\",\n  \"cli.image.storage_path.description\": \"查询图片存储路径\",\n  \"cli.web.description\": \"本地已同步网页管理\",\n  \"cli.web.list.description\": \"按收藏时间倒序列出所有已同步网页\",\n  \"cli.web.path.description\": \"根据 URL 哈希打印网页 Markdown 文件绝对路径\",\n  \"cli.web.search.description\":\n    \"在本地已同步网页的标题、URL 和 Markdown 正文中搜索，不访问互联网\",\n  \"cli.web.storage_path.description\": \"查询网页存储路径\",\n  \"cli.web.list.opt.from\": \"包含在该 ISO 8601 时间及之后抓取的网页\",\n  \"cli.web.list.opt.to\": \"包含在该 ISO 8601 时间之前抓取的网页\",\n  \"cli.auth.description\": \"用户认证管理\",\n  \"cli.auth.set_api_key.description\": \"设置用户 API Key（持久化到本地配置）\",\n  \"cli.auth.set_token.description\": \"（兼容）设置用户 API Key（旧命令名）\",\n  \"cli.auth.status.description\": \"查看当前认证状态\",\n  \"cli.auth.clear.description\": \"清除已保存的认证信息\",\n  \"cli.env.description\": \"环境管理（切换 test / production）\",\n  \"cli.env.show.description\": \"显示当前环境及对应的接口地址\",\n  \"cli.env.set.description\": \"切换环境（test / production）\",\n  \"cli.doctor.description\": \"自检环境配置，检测安全风险和常见问题\",\n  \"cli.update.description\": \"检查并更新插件到最新版本，更新后自动重启\",\n  \"cli.log.description\": \"查看/搜索插件日志\",\n  \"cli.tunnel.status.description\":\n    \"检查 Relay Tunnel 隧道连接状态（读取运行中服务的状态文件，不影响已有连接）\",\n  \"tunnel.status.connected\": \"隧道已连接（自 {since}）\",\n  \"tunnel.status.connecting\": \"隧道正在连接（自 {since}，第 {attempt} 次重连）\",\n  \"tunnel.status.disconnected\":\n    \"隧道已断开（自 {since}）{reasonSuffix}，等待重连（第 {attempt} 次）\",\n  \"tunnel.status.disconnected.reason\": \"，原因: {reason}\",\n  \"tunnel.status.stopped\": \"隧道服务已停止（自 {since}）\",\n  \"tunnel.status.unknown\": \"未知状态: {state}\",\n  \"tunnel.issue.not_found\":\n    \"未找到隧道状态文件，隧道服务可能尚未启动过。请确认 openclaw 主进程正在运行。\",\n  \"tunnel.issue.invalid.parse\":\n    \"隧道状态文件解析失败，文件内容损坏或格式不正确。请重启 openclaw 主进程。\",\n  \"tunnel.issue.invalid.fields\":\n    \"隧道状态文件缺少必要字段或字段类型不正确。请重启 openclaw 主进程。\",\n  \"tunnel.issue.stale.connected_prefix\": \"隧道状态文件显示已连接（自 {since}）\",\n  \"tunnel.issue.stale.no_lock\":\n    \"，但未找到本地运行锁，状态可能已过期。请重启 openclaw 主进程。\",\n  \"tunnel.issue.stale.incomplete_lock\":\n    \"，但本地运行锁内容不完整，无法确认当前连接是否仍然有效。请重启 openclaw 主进程。\",\n  \"tunnel.issue.stale.dead_pid\":\n    \"，但本地运行锁仍指向已退出的进程 pid={pid}，状态可能已过期。请重启 openclaw 主进程。\",\n  \"tunnel.issue.stale.lock_newer\":\n    \"，但当前运行锁启动于 {lockStartedAt}，晚于状态时间，说明状态未随新进程刷新。请重启 openclaw 主进程。\",\n  \"cli.monitor.description\": \"通知监控任务管理\",\n  \"cli.monitor.list.description\": \"列出所有监控任务\",\n  \"cli.monitor.show.description\": \"查看监控任务详情\",\n  \"cli.monitor.create.description\": \"创建监控任务\",\n  \"cli.monitor.delete.description\": \"删除监控任务\",\n  \"cli.monitor.enable.description\": \"启用监控任务\",\n  \"cli.monitor.disable.description\": \"暂停监控任务\",\n  \"cli.sync.description\": \"同步通知到记忆系统\",\n  \"cli.sync.next.description\":\n    \"返回范围内下一批待同步通知（≤100 条）及记忆写入提示词路径；全部处理完时返回 done=true\",\n  \"cli.sync.pending.description\":\n    \"扫描未处理的通知，默认只返回本地当天的待同步摘要\",\n  \"cli.sync.fetch.description\": \"获取指定日期的未处理通知详情\",\n  \"cli.sync.commit.description\": \"标记指定日期当前批次处理完成，更新 checkpoint\",\n  \"cli.search.description\": \"查询通知（按时间/应用/发送人/关键词筛选）\",\n  \"cli.stats.description\": \"通知统计分析（按日期/应用/发送人/时段聚合）\",\n  \"cli.summary.description\": \"生成通知摘要输入（聚合统计 + 样例，供 Agent 快速总结）\",\n  \"cli.summary_job.description\": \"分片通知总结任务管理\",\n  \"cli.summary_job.create.description\": \"创建分片通知总结任务\",\n  \"cli.summary_job.status.description\": \"查看分片通知总结任务状态\",\n  \"cli.summary_job.next.description\": \"领取或重试下一个待总结分片\",\n  \"cli.summary_job.commit.description\": \"提交分片摘要并标记分片完成\",\n  \"cli.summary_job.run.description\": \"自动处理待总结分片并在完成后生成结果\",\n  \"cli.summary_job.result.description\": \"合并已提交的分片摘要并返回结果\",\n  \"cli.summary_job.cancel.description\": \"取消分片通知总结任务\",\n  \"cli.storage_path.description\": \"查询通知存储路径\",\n\n  \"cli.opt.from_time\": \"开始时间 ISO 8601，例如 2026-03-01T09:00:00+08:00\",\n  \"cli.opt.to_time\": \"结束时间 ISO 8601，例如 2026-03-01T18:00:00+08:00\",\n  \"cli.opt.from_time_short\": \"开始时间 ISO 8601\",\n  \"cli.opt.to_time_short\": \"结束时间 ISO 8601\",\n  \"cli.opt.app\": \"按应用名过滤\",\n  \"cli.opt.sender\": \"按发送人过滤\",\n  \"cli.opt.conversation_type\": \"按会话类型过滤（group/private）\",\n  \"cli.opt.keyword\": \"在标题和内容中搜索关键词\",\n  \"cli.opt.limit\": \"最大返回条数\",\n  \"cli.opt.from_date\": \"开始日期 YYYY-MM-DD\",\n  \"cli.opt.to_date\": \"结束日期 YYYY-MM-DD\",\n  \"cli.opt.json\": \"以 JSON 格式输出结果（供脚本调用）\",\n  \"cli.opt.yes\": \"跳过确认\",\n  \"cli.opt.date_ymd\": \"目标日期 YYYY-MM-DD\",\n\n  \"cli.search.opt.limit\": \"最大返回条数\",\n  \"cli.summary.opt.limit\": \"纳入摘要的最大通知条数\",\n  \"cli.summary.opt.sample\": \"返回最近样例条数\",\n  \"cli.summary.opt.top\": \"返回聚合榜单条数\",\n  \"cli.summary.opt.max_content\": \"单条样例标题/正文最大字数（超出截断）\",\n  \"cli.summary_job.opt.limit\": \"纳入任务的最大通知条数\",\n  \"cli.summary_job.opt.chunk_size\": \"每个分片的通知条数\",\n  \"cli.summary_job.opt.max_content\": \"分片中单条通知标题/正文最大字数\",\n  \"cli.summary_job.opt.chunk_id\": \"next 返回的分片 id\",\n  \"cli.summary_job.opt.summary\": \"直接传入分片摘要文本\",\n  \"cli.summary_job.opt.summary_file\": \"读取文件内容作为分片摘要\",\n  \"cli.summary_job.opt.max_chunks\": \"本次最多自动处理的分片数\",\n  \"cli.summary_job.opt.include_result\": \"完成时在输出中包含 markdown 结果\",\n  \"cli.stats.opt.app\": \"只统计指定应用\",\n  \"cli.stats.opt.dim\": \"统计维度：date/app/sender/hour/all\",\n  \"cli.log.opt.keyword\": \"按关键词过滤日志\",\n  \"cli.log.opt.limit\": \"最大返回条数\",\n  \"cli.sync.scan.opt.all\": \"扫描 checkpoint 之后所有日期的未处理通知\",\n  \"cli.sync.scan.opt.date\": \"只扫描指定日期 YYYY-MM-DD\",\n  \"cli.sync.scan.opt.from_date\": \"只扫描该日期及之后的数据 YYYY-MM-DD\",\n  \"cli.sync.scan.opt.to_date\": \"只扫描该日期及之前的数据 YYYY-MM-DD\",\n  \"cli.sync.next.opt.all\": \"处理 checkpoint 之后所有日期的未处理通知\",\n  \"cli.sync.next.opt.date\": \"只处理指定日期 YYYY-MM-DD\",\n  \"cli.sync.next.opt.from_date\": \"只处理该日期及之后的数据 YYYY-MM-DD\",\n  \"cli.sync.next.opt.to_date\": \"只处理该日期及之前的数据 YYYY-MM-DD\",\n  \"cli.sync.fetch.opt.max_end_index\": \"本次同步快照允许读取的最大 endIndex\",\n  \"cli.sync.commit.opt.end_index\": \"本批次 fetch 返回的 endIndex\",\n  \"cli.monitor.create.opt.description\": \"任务描述\",\n  \"cli.monitor.create.opt.match_rules\": \"匹配规则 JSON\",\n  \"cli.monitor.create.opt.schedule\": \"cron 表达式\",\n  \"cli.doctor.opt.fix\": \"自动修复可修复的问题（跳过确认提示）\",\n  \"cli.update.opt.force\": \"强制重新安装当前最新版本，即使版本号相同\",\n  \"cli.update.opt.beta\": \"安装最新 beta 版本\",\n  \"cli.light.send.opt.segments\": \"灯效参数 JSON\",\n  \"cli.light.send.opt.repeat\": \"无限循环播放（默认仅播放一轮）\",\n  \"cli.light.send.opt.repeat_times\":\n    \"整条组合重复次数：0=无限，1=一轮；当前 ANCS 路径不支持 >=2\",\n  \"cli.image.list.opt.status\": \"按状态过滤（syncing|synced|sync_failed）\",\n  \"cli.image.list.opt.app\": \"按来源应用过滤\",\n  \"cli.rec.list.opt.status\": \"按传输状态过滤（如 synced, transcribed）\",\n  \"cli.rec.list.opt.from\": \"录音时间起点（含，ISO 8601 或 YYYY-MM-DD）\",\n  \"cli.rec.list.opt.to\": \"录音时间终点（不含，ISO 8601 或 YYYY-MM-DD）\",\n  \"cli.web.search.opt.limit\": \"最多返回的网页数量（默认 20）\",\n\n  \"errors.INVALID_TIME\": \"{option} 必须是 ISO 8601 时间，例如 {example}\",\n  \"errors.INVALID_TIME_INVALID\": \"{option} 不是合法时间，例如 {example}\",\n  \"errors.INVALID_RECORDING_TIME\": \"录音时间边界必须是 ISO 8601 或 YYYY-MM-DD\",\n  \"errors.INVALID_RECORDING_TIME_RANGE\": \"--from 必须早于 --to\",\n  \"errors.STORAGE_UNAVAILABLE\": \"无法确定录音存储目录：stateDir 和 workspaceDir 均未设置\",\n  \"errors.STORAGE_UNAVAILABLE.notifications\": \"通知存储目录不可用\",\n  \"errors.STORAGE_UNAVAILABLE.images\": \"图片存储目录不可用\",\n  \"errors.STORAGE_UNAVAILABLE.recordings\": \"录音存储目录不可用\",\n  \"errors.STORAGE_UNAVAILABLE.web_pages\": \"网页存储目录不可用\",\n  \"errors.LOGS_UNAVAILABLE\": \"日志目录不可用\",\n  \"errors.NOT_FOUND\": \"未找到: {target}\",\n  \"errors.NOT_FOUND.monitor\": \"监控任务 '{name}' 不存在\",\n  \"errors.NOT_FOUND.image\": \"图片不存在: {id}\",\n  \"errors.NOT_FOUND.recording\": \"录音不存在: {id}\",\n  \"errors.NOT_FOUND.web_page\": \"网页不存在: {urlHash}\",\n  \"errors.ALREADY_EXISTS\": \"监控任务 '{name}' 已存在\",\n  \"errors.INVALID_TIME_RANGE\": \"--from 不能晚于 --to\",\n  \"errors.INVALID_POSITIVE_INT\": \"{option} 必须是大于 0 的整数\",\n  \"errors.INVALID_NON_NEGATIVE_INT\": \"{option} 必须是非负整数\",\n  \"errors.INVALID_DATE\": \"{option} 必须是 YYYY-MM-DD 格式\",\n  \"errors.INVALID_DATE_VALUE\": \"{option} 不是合法日期\",\n  \"errors.INVALID_SCOPE\": \"参数范围冲突\",\n  \"errors.INVALID_SCOPE.all_with_range\": \"--all 不能与日期范围参数同时使用\",\n  \"errors.INVALID_SCOPE.date_with_range\": \"--date 不能与日期范围参数同时使用\",\n  \"errors.INVALID_SCOPE.from_after_to\": \"--from-date 不能晚于 --to-date\",\n  \"errors.NO_DATA\": \"日期 {date} 无通知数据\",\n  \"errors.INVALID_LOCALE\": \"locale 必须是以下之一: {locales}\",\n  \"errors.INVALID_CONVERSATION_TYPE\": \"--conversation-type 只能是 group 或 private\",\n  \"errors.INVALID_END_INDEX\": \"--end-index 必须是非负整数\",\n  \"errors.INVALID_END_INDEX.out_of_range\": \"--end-index 必须落在当前日期通知文件范围内\",\n  \"errors.INVALID_END_INDEX.beyond_batch\": \"--end-index 超出单批 fetch 上限，不能跳过未处理通知\",\n  \"errors.STALE_END_INDEX\": \"--end-index 早于当前 checkpoint，不能回退消费进度\",\n  \"errors.INVALID_MAX_END_INDEX\": \"--max-end-index 必须是非负整数\",\n  \"errors.CONFIG_NOT_FOUND\": \"未找到配置文件: {path}\",\n  \"errors.CONFIG_INVALID\": \"读取/解析配置失败: {detail}\",\n  \"errors.WRITE_FAILED\": \"写入配置失败: {detail}\",\n  \"errors.HTTP_ERROR\": \"请求失败: {status} {detail}\",\n  \"errors.IMAGE_NOT_READY\": \"图片 {id} 尚未下载完成（status={status}{errorSuffix}）\",\n  \"errors.WEB_PAGE_FILE_UNAVAILABLE\": \"网页 Markdown 文件路径不可用: {urlHash}\",\n  \"errors.INVALID_KEYWORD\": \"搜索关键词不能为空\",\n  \"errors.INVALID_JOB_ID\": \"summary job id 不合法\",\n  \"errors.READ_FAILED\": \"无法读取 JSON: {path}\",\n  \"errors.JOB_NOT_FOUND\": \"summary job 不存在: {id}\",\n  \"errors.INVALID_JOB\": \"summary job 元数据损坏: {id}\",\n  \"errors.INVALID_CHUNK\": \"summary job 分片损坏: {chunkId}\",\n  \"errors.INVALID_COMMIT.xor\": \"--summary 和 --summary-file 只能二选一\",\n  \"errors.INVALID_COMMIT.required\": \"必须提供 --summary 或 --summary-file\",\n  \"errors.INVALID_COMMIT.empty\": \"分片摘要不能为空\",\n  \"errors.JOB_CANCELLED\": \"summary job 已取消: {id}\",\n  \"errors.CHUNK_NOT_FOUND\": \"summary job 分片不存在: {chunkId}\",\n  \"errors.INVALID_ENV\": \"无效的环境名称: {env}，可选值: {available}\",\n  \"errors.INVALID_MATCH_RULES\": \"match-rules 必须是合法的 JSON\",\n  \"errors.TUNNEL_NOT_CONFIGURED\":\n    \"RELAY_TUNNEL_URL 未配置，隧道功能未启用。请在构建时设置 RELAY_TUNNEL_URL 环境变量。\",\n  \"errors.TUNNEL_TOKEN_MISSING\":\n    \"API Key 未设置，隧道无法连接。请执行 ntf auth set-api-key <apiKey>\",\n  \"errors.STATE_DIR_UNAVAILABLE\":\n    \"无法确定状态目录，无法检查隧道状态。请在 openclaw 主环境中执行该命令。\",\n  \"errors.STATUS_NOT_FOUND\":\n    \"未找到隧道状态文件，隧道服务可能尚未启动过。请确认 openclaw 主进程正在运行。\",\n\n  \"env.reload.gateway\": \"已自动触发 gateway 进程内重载\",\n  \"env.reload.jvsclaw\": \"当前宿主为 JvsClaw，请在控制面重载或重启实例后使环境切换生效\",\n  \"env.reload.qclaw\": \"当前宿主为 QClaw，请重启 QClaw 桌面应用后使环境切换生效\",\n  \"env.reload.command\": \"已自动触发 {command}\",\n  \"env.reload.manual\": \"已切换环境，但自动重载未完成，请手动运行: {command}\",\n  \"env.switched.with_reload\": \"已切换到 {env} 环境，并已触发重载\",\n  \"env.switched\": \"已切换到 {env} 环境\",\n\n  \"progress.searching\": \"正在搜索通知...\",\n  \"progress.summary\": \"正在生成通知摘要输入...\",\n  \"progress.summary_job_create\": \"正在创建分片通知总结任务...\",\n\n  \"doctor.checking\": \"🔍 正在检查环境...\",\n  \"doctor.all_pass\": \"✅ 所有检查通过，未发现问题。\",\n  \"doctor.fix_label\": \"修复: {fix}\",\n  \"doctor.summary\": \"检测完成: {critical} critical · {warn} warn · {info} info\",\n  \"doctor.manual_only\": \"以上问题均需手动修复，请参考上方提示。\",\n  \"doctor.fixable_found\": \"发现 {count} 个可自动修复的问题:\",\n  \"doctor.confirm_fix\": \"是否执行自动修复？[y/N]: \",\n  \"doctor.cancelled\": \"已取消。\",\n  \"doctor.fix_failed\": \"{title} 修复失败: {message}\",\n  \"doctor.manual_remaining\": \"还有 {count} 个问题需要手动处理，请参考上方提示。\",\n  \"doctor.fix_done\": \"修复完成 ({fixed}/{total})。建议执行: openclaw gateway restart\",\n\n  \"doctor.credentials.title\": \"API Key 未配置\",\n  \"doctor.credentials.detail\":\n    \"未在 credentials.json 中找到 apiKey，隧道和推送等功能无法正常工作。\",\n  \"doctor.credentials.fix\": \"请执行: ntf auth set-api-key <your-api-key>\",\n  \"doctor.dangerous_flags.title\": \"gateway.controlUi.dangerouslyDisableDeviceAuth 已启用\",\n  \"doctor.dangerous_flags.detail\":\n    \"这会关闭 Control UI 的设备身份验证，任何人都可以访问控制面板。\",\n  \"doctor.dangerous_flags.fix\": \"设为 false\",\n  \"doctor.node_version.title\": \"Node.js 版本过低 (v{version})\",\n  \"doctor.node_version.detail\": \"要求 >= {minVersion}，当前为 v{version}。\",\n  \"doctor.node_version.fix\": \"请升级 Node.js 到 {minVersion} 或更高版本\",\n  \"doctor.plugin_version.title\": \"插件版本可更新 (当前 {current} → 最新 {latest})\",\n  \"doctor.plugin_version.detail\": \"有新版本可用，建议更新以获取最新功能和修复。\",\n  \"doctor.plugin_version.fix\": \"请执行: ntf update\",\n  \"doctor.state_dir_perms.title\": \"状态目录权限过于宽松 ({stateDir} mode={mode})\",\n  \"doctor.state_dir_perms.detail\": \"其他用户可以读取该目录下的凭证和配置文件。\",\n  \"doctor.tool_policy.title\": \"扩展插件 tool policy 宽松\",\n  \"doctor.tool_policy.detail\":\n    \"以下 agent 使用了 default 策略: {agents}。插件工具可能被未授权调用。\",\n  \"doctor.tool_policy.fix\":\n    \"建议为处理不可信输入的 agent 使用 minimal 或 coding profile，或配置明确的 tool allowlist。\",\n  \"doctor.trusted_proxy.title\": \"gateway.auth.mode 为 trusted-proxy\",\n  \"doctor.trusted_proxy.detail\":\n    \"认证委托给了反向代理。请确保: (1) 代理终止 TLS 并认证用户; (2) gateway.trustedProxies 仅限代理 IP; (3) 防火墙阻止直接访问 Gateway 端口。\",\n  \"doctor.trusted_proxy.fix\": \"此项需手动检查代理配置，无法自动修复\",\n  \"doctor.trusted_proxy_allow_users.title\": \"trusted-proxy 模式下 allowUsers 为空\",\n  \"doctor.trusted_proxy_allow_users.detail\": \"任何通过代理认证的用户都可以访问 Gateway。\",\n  \"doctor.trusted_proxy_allow_users.fix\":\n    '请编辑 openclaw.json，在 gateway.auth.trustedProxy.allowUsers 中添加允许的用户邮箱，例如 [\"nick@example.com\"]',\n  \"doctor.tunnel.not_found.title\": \"隧道状态文件不存在\",\n  \"doctor.tunnel.not_found.detail\": \"隧道服务可能尚未启动过，或状态文件已被删除。\",\n  \"doctor.tunnel.not_found.fix\": \"请确认 openclaw 主进程正在运行\",\n  \"doctor.tunnel.invalid.title\": \"隧道状态文件解析失败\",\n  \"doctor.tunnel.invalid.detail\": \"文件内容损坏或格式不正确。\",\n  \"doctor.tunnel.invalid.fix\": \"请重启 openclaw 主进程\",\n  \"doctor.tunnel.stale.title\": \"隧道状态已过期\",\n  \"doctor.tunnel.stale.detail\": \"隧道状态文件仍显示已连接，但运行时状态已失效。\",\n  \"doctor.tunnel.stale.fix\": \"请重启 openclaw 主进程\",\n  \"doctor.tunnel.disconnected.title\": \"隧道未连接 (state={state})\",\n  \"doctor.tunnel.disconnected.detail\":\n    \"隧道自 {since} 处于 {state} 状态{reasonSuffix}，重连次数: {attempts}\",\n  \"doctor.tunnel.disconnected.reason\": \"，原因: {reason}\",\n  \"doctor.tunnel.disconnected.fix\": \"请检查网络连接或重启 openclaw 主进程\",\n  \"doctor.local_gateway.invalid_url.title\": \"本地 Gateway 地址配置无效\",\n  \"doctor.local_gateway.invalid_url.detail\": \"{warning}，当前回退到 {baseUrl}\",\n  \"doctor.local_gateway.invalid_url.fix\":\n    \"请修正 PHONE_NOTIFICATIONS_GATEWAY_BASE_URL，或清理该环境变量后重启 openclaw/gateway\",\n  \"doctor.local_gateway.tls.title\": \"Gateway TLS 可能阻断 Relay 本地代理\",\n  \"doctor.local_gateway.tls.detail\":\n    \"检测到 gateway.tls.enabled=true，但插件本地代理默认连接 {baseUrl}。如果 Gateway 只接受 HTTPS/WSS，本地 RPC 握手会失败。\",\n  \"doctor.local_gateway.tls.fix\":\n    \"设置 PHONE_NOTIFICATIONS_GATEWAY_BASE_URL=https://127.0.0.1:<port>，或关闭 gateway.tls.enabled 后重启 gateway\",\n  \"doctor.local_gateway.unresolvable.title\": \"本地 Gateway 地址无法解析\",\n  \"doctor.local_gateway.unresolvable.detail\": \"无法解析插件将使用的本地 Gateway 地址: {baseUrl}\",\n  \"doctor.local_gateway.unresolvable.fix\":\n    \"请设置 PHONE_NOTIFICATIONS_GATEWAY_BASE_URL=http://127.0.0.1:<port>\",\n  \"doctor.local_gateway.unreachable.title\": \"本地 Gateway 不可达\",\n  \"doctor.local_gateway.unreachable.detail\":\n    \"插件将连接 {baseUrl}，但 TCP 探测失败{errorSuffix}\",\n  \"doctor.local_gateway.unreachable.fix\":\n    \"请执行 openclaw gateway status，确认 gateway.port 与 PHONE_NOTIFICATIONS_GATEWAY_BASE_URL 是否一致\",\n\n  \"monitor.delete.confirm\": \"确认删除监控任务 '{name}'？添加 --yes 跳过确认\",\n\n  \"update.checking\": \"检查{beta}最新版本 ...\",\n  \"update.checking_beta\": \" beta\",\n  \"update.fetch_failed\": \"无法获取最新版本: {message}\",\n  \"update.already_latest\": \"已是最新{beta}版本 v{version}\",\n  \"update.force\": \"强制更新: v{current} → v{latest}\",\n  \"update.found\": \"发现新版本: v{current} → v{latest}，开始更新 ...\",\n  \"update.downloading\": \"下载安装脚本 ...\",\n  \"update.download_failed\": \"下载安装脚本失败: {message}\",\n  \"update.write_failed\": \"写入临时文件失败: {message}\",\n  \"update.spawn_failed\": \"安装脚本执行失败: {message}\",\n  \"update.exit_code\": \"安装脚本退出码: {code}\",\n  \"update.request_failed\": \"请求失败: {url} (HTTP {status})\",\n  \"update.version_empty\": \"版本标记为空: {baseUrl}\",\n\n  \"rec.setup.choice_prompt\": \"{prompt} [1-{max}，默认 {default}]: \",\n  \"rec.setup.choice_invalid\": \"  请输入 1-{max} 之间的数字\",\n  \"rec.setup.optional_suffix\": \" [可选，直接回车跳过]: \",\n  \"rec.setup.api_header\": \"─── 云端 ASR（model-proxy）配置 ───\",\n  \"rec.setup.api_note\":\n    \"说明：不再填写第三方 API Key，插件会复用当前账号的 API Key 调用 model-proxy 长录音接口。\",\n  \"rec.setup.api.endpoint\": \"自定义 model-proxy submit-task 端点 URL\",\n  \"rec.setup.api.language\": \"语言提示（如 zh / en）\",\n  \"rec.setup.api.itn\": \"启用文本规范化 ITN？（y/N）\",\n  \"rec.setup.local_header\": \"─── 本地 Whisper 转写配置 ───\",\n  \"rec.setup.local.model_label\": \"模型大小：\",\n  \"rec.setup.local.model_auto\": \"自动选择（根据可用内存推荐）\",\n  \"rec.setup.local.choose_model\": \"选择模型\",\n  \"rec.setup.local.language\": \"语言提示（如 zh / en，留空自动检测）\",\n  \"rec.setup.local.backend_label\": \"推理后端：\",\n  \"rec.setup.local.backend_auto\": \"自动选择（根据运行环境推荐）\",\n  \"rec.setup.local.backend_coreml\": \"coreml（Apple Silicon 推荐）\",\n  \"rec.setup.local.backend_cuda\": \"cuda（NVIDIA GPU）\",\n  \"rec.setup.local.choose_backend\": \"选择后端\",\n  \"rec.setup.local.source_label\": \"模型下载源：\",\n  \"rec.setup.local.source_auto\": \"auto（自动探测，优先 HuggingFace，失败回退国内镜像）\",\n  \"rec.setup.local.source_hf\": \"huggingface（海外直连）\",\n  \"rec.setup.local.source_domestic\": \"domestic（国内镜像）\",\n  \"rec.setup.local.choose_source\": \"选择下载源\",\n  \"rec.setup.local.mirror\": \"自定义模型下载地址（覆盖下载源）\",\n  \"rec.setup.existing\": \"当前已有配置：mode = {mode}\",\n  \"rec.setup.existing_updated\": \"，更新于 {updatedAt}\",\n  \"rec.setup.mode_label\": \"转写模式：\",\n  \"rec.setup.choose_mode\": \"选择模式\",\n  \"rec.setup.mode_api\": \"api（云端 model-proxy 长录音）\",\n  \"rec.setup.mode_local\": \"local（本地 Whisper）\",\n  \"rec.setup.saved\": \"✓ 配置已保存到 {path}\",\n\n  \"prompt.light_rule.title\": \"灯效路由提示：\",\n  \"prompt.light_rule.persistent\":\n    \"- 当用户表达“收到/当/如果/有某类通知或消息时，亮灯/闪灯/变成某种灯效”时，这是云端持久灯效规则请求，必须调用 {create} 或 {update}。\",\n  \"prompt.light_rule.immediate\":\n    \"- 当用户要求现在/立即亮灯，或在当前一次性任务完成后亮灯时，必须调用 light_control；不要创建灯效规则。\",\n  \"prompt.light_rule.display\":\n    \"- 当用户要求\\\"把内容/文字/结果展示到硬件/屏幕/设备上\\\"时，同样调用 light_control：展示标题放 title、正文放 reason（二代带屏硬件会把通知标题和正文显示在屏幕上）；不要创建灯效规则，也不要说\\\"无法在硬件上显示内容\\\"。\",\n  \"prompt.light_rule.rule_text\":\n    \"- 创建规则时把用户的自然语言诉求整理成 ruleText；由 Notification Intelligence Service 的独立 Agent 编译和保存规则。\",\n  \"prompt.light_rule.crud\":\n    \"- 灯效规则的创建、修改、删除和查询都走 lightrules_* 工具；不要手写或编辑 tasks/*/meta.json。\",\n  \"prompt.light_rule.errors\":\n    \"- 如果 lightrules_* 工具返回错误，必须如实说明本次查询/修改失败；不要使用聊天历史或旧 toolResult 里的规则列表冒充当前云端结果。\",\n  \"prompt.light_rule.language\":\n    \"- 语言：整段回复以及调用 lightrules_create/update 时的 `ruleText` 参数，都必须使用 replyLanguage（本轮起始用户原文的语言）。优先用用户原话改写成 ruleText。不要因为 App 界面语言或工具 schema 是另一种语言，就把英文诉求译成中文 ruleText（或反过来）；禁止中英夹杂。\",\n  \"prompt.reply.language\":\n    \"- 回复语言：说明文字、表格、代码块/tool 调用样例中的自然语言字符串，都必须使用 replyLanguage（本轮起始用户原文的语言）。工具 schema 或 skill 里若出现另一语言示例，必须翻译后再写入回复；禁止中英夹杂（英文回复中不要出现中文例句或「跑马灯」之类混写）。\",\n  \"locale.updated\": \"全局界面语言已更新: {locale}\",\n\n  \"light.validation.must_array\": \"必须是数组\",\n  \"light.validation.must_not_empty\": \"不能为空\",\n  \"light.validation.max_segments\": \"最多 {max} 段\",\n  \"light.validation.segments_json\": \"segments 必须是合法的 JSON\",\n  \"light.validation.must_object\": \"必须是对象\",\n  \"light.validation.unsupported_mode\": \"不支持的模式 '{mode}'，可选：{modes}\",\n  \"light.validation.duration\": \"必须是 ≥0 的数字（0 表示无限时长）\",\n  \"light.validation.color_flow_anchor\":\n    \"color_flow 至少需要一组非零颜色锚点（color 或 background）\",\n  \"light.validation.byte\": \"必须是 0–255 的数字\",\n  \"light.validation.brightness_zero\":\n    \"brightness=0 仅 steady 模式允许；其它模式会在固件侧被过滤\",\n  \"light.validation.must_rgb_brightness\": \"必须包含 r/g/b/brightness 数值\",\n  \"light.validation.must_rgb\": \"必须包含 r/g/b 数值\",\n  \"light.validation.rise_ms\": \"rise_ms 必须是 >0 的数字（不支持 0ms）\",\n  \"light.validation.hold_ms\": \"hold_ms 必须是 ≥0 的数字\",\n  \"light.validation.fall_ms\": \"fall_ms 必须是 >0 的数字（不支持 0ms）\",\n  \"light.validation.off_ms\": \"off_ms 必须是 ≥0 的数字\",\n  \"light.validation.direction\": \"direction 必须是 ltr 或 rtl\",\n  \"light.validation.window\": \"window 仅支持 1/2/3\",\n  \"light.validation.non_negative\": \"必须是 ≥0 的数字\",\n  \"light.validation.color_flow_misuse\":\n    \"color_flow 仅设置了单一极端纯色前景锚点（无有效底色锚点），实际效果是同色系亮暗环状流动，不是多色调色板流动。若用户期望的是\\\"单色波浪\\\"，请改用 mode='wave'；若期望多色流动，请同时设置 background 作为第二锚点。\",\n  \"light.repeat.ancs_only\":\n    \"当前 ANCS 路径仅支持 repeat_times=0（无限循环）或 1（播放一轮）；N>=2 需非 ANCS 路径\",\n  \"light.repeat.invalid\": \"repeat_times 必须是 >=0 的整数\",\n  \"light.rule.already_exists\": \"灯效规则 '{name}' 已存在\",\n  \"light.rule.not_found\": \"灯效规则 '{name}' 不存在\",\n  \"light.rule.prompt.empty\": \"当前没有启用任何灯效规则。\",\n  \"light.rule.prompt.intro\": \"你是一个判断\\\"通知 → 灯效规则\\\"是否命中的助手。\",\n  \"light.rule.prompt.list_header\": \"下面是用户当前启用的全部灯效规则（按创建时间倒序）：\",\n  \"light.rule.prompt.task\": \"任务：根据用户接下来发给你的\\\"通知\\\"内容，判断哪些规则被命中。\",\n  \"light.rule.prompt.hit0\": \"- 命中 0 条：不调用任何工具，直接结束。\",\n  \"light.rule.prompt.hit_n\":\n    \"- 命中 1 条或多条：对每一条命中的规则调用一次 trigger_light(rule_name)。\",\n  \"light.rule.prompt.no_text\":\n    \"- 不要回复任何自由文本；判定结果**只**通过 tool calling 表达。\",\n  \"light.rule.prompt.conservative\": \"- 拿不准的时候倾向于\\\"不触发\\\"，避免骚扰用户。\",\n  \"light.rule.trigger.simple\": \"触发\\\"{rule}\\\"灯效\",\n  \"light.rule.trigger.group\": \"{app}群聊\\\"{conversation}\\\"\",\n  \"light.rule.trigger.group_app\": \"{app}群聊\",\n  \"light.rule.trigger.sender_action\": \"{sender}发来消息\",\n  \"light.rule.trigger.new_message\": \"收到新消息\",\n  \"light.rule.trigger.detected\": \"检测到{where}中{action}{detail}，触发\\\"{rule}\\\"灯效\",\n  \"light.rule.tool.rule_text_desc\":\n    \"用户原始自然语言规则，语言必须与 replyLanguage 一致（跟用户原文同语言，不要把英文诉求译成中文）。中文例：「收到包含 123 的消息时亮红灯」；English e.g. \\\"turn on red light when receiving a message containing 123\\\"\",\n  \"light.setup.next_restart\": \"请执行: openclaw gateway restart\",\n\n  \"monitor.readme.description\": \"## 描述\",\n  \"monitor.readme.guide_title\": \"## 处理指南\",\n  \"monitor.readme.guide_body\":\n    \"当 fetch.py 输出匹配的通知时，请：\\n1. 阅读匹配到的通知内容\\n2. 根据任务描述判断是否需要通知用户\\n3. 如需通知用户，使用 message 工具发送摘要\",\n  \"monitor.cron.message\":\n    \"手机通知已由独立服务实时捕获到 notifications/ 目录的 JSON 文件中。\\n执行：python3 tasks/{name}/fetch.py --notifications-dir notifications\\n- NO_CHANGE 或 NO_MATCH → 不回复，直接结束。\\n- 有输出 → 读 tasks/{name}/README.md 了解如何处理数据并通知用户。\",\n\n  \"summary_job.keyword.todo\": \"待办\",\n  \"summary_job.keyword.need\": \"需要\",\n  \"summary_job.keyword.trouble\": \"麻烦\",\n  \"summary_job.keyword.confirm\": \"确认\",\n  \"summary_job.keyword.reply\": \"回复\",\n  \"summary_job.keyword.approve\": \"审批\",\n  \"summary_job.keyword.meet\": \"开会\",\n  \"summary_job.keyword.meeting\": \"会议\",\n  \"summary_job.keyword.schedule\": \"安排\",\n  \"summary_job.keyword.deadline\": \"截止\",\n  \"summary_job.keyword.urgent\": \"紧急\",\n  \"summary_job.keyword.abnormal\": \"异常\",\n  \"summary_job.keyword.fail\": \"失败\",\n  \"summary_job.keyword.risk\": \"风险\",\n  \"summary_job.none\": \"无\",\n  \"summary_job.chunk_title\": \"## 分片 {id}\",\n  \"summary_job.count\": \"- 数量: {count}\",\n  \"summary_job.time_range\": \"- 时间范围: {oldest} 至 {newest}\",\n  \"summary_job.top_apps\": \"- 主要 App: {apps}\",\n  \"summary_job.top_senders\": \"- 主要发送人/会话: {senders}\",\n  \"summary_job.attention\": \"### 可能需要关注\",\n  \"summary_job.no_attention\": \"- 无明显待办、风险或异常样例\",\n  \"summary_job.recent\": \"### 最近样例\",\n  \"summary_job.none_item\": \"- 无\",\n  \"summary_job.result_title\": \"# 通知总结任务 {id}\",\n  \"summary_job.result_total\": \"- 通知数: {total}\",\n  \"summary_job.result_chunks\": \"- 分片数: {count}\",\n  \"summary_job.result_chunk_summaries\": \"## 分片摘要\",\n  \"summary_job.result_chunk_line\":\n    \"### {id} · {count} 条 · {oldest} 至 {newest}\",\n  \"summary_job.uncommitted\": \"(未提交摘要)\",\n\n  \"recording.summary.title\": \"# 总结\",\n  \"recording.summary.decisions\": \"结论\",\n  \"recording.summary.todos\": \"待办\",\n  \"recording.summary.risks\": \"风险\",\n  \"recording.summary.open_questions\": \"未决问题\",\n  \"recording.summary.meta_name\": \"> 录音名称：{name}\",\n  \"recording.summary.meta_duration\": \"> 时长：{duration}\",\n  \"recording.summary.meta_created\": \"> 创建时间：{created}\",\n  \"recording.summary.meta_markers\": \"> 兴趣点数：{count}\",\n  \"recording.marker_heading\": \"### 兴趣点\",\n  \"recording.error.not_found\": \"录音不存在: {id}\",\n  \"recording.error.storage_unavailable\": \"录音存储目录不可用: {path}\",\n  \"recording.error.download_failed\": \"下载失败\",\n  \"recording.error.empty_body\": \"响应体为空\",\n  \"recording.error.size_limit\": \"录音文件超过上限 {maxBytes} 字节\",\n  \"recording.error.timeout\": \"超时\",\n  \"recording.error.interrupted\": \"转写任务已中断，请重新发起转写\",\n  \"image.error.storage_unavailable\": \"图片存储目录不可用: {path}\",\n  \"image.error.download_failed\": \"下载失败\",\n  \"notification.error.storage_unavailable\": \"通知存储目录不可用: {path}\",\n  \"auth.apikey_missing\": \"apiKey 未设置\",\n  \"auth.apikey_missing_hint\":\n    \"apiKey 未设置，请先执行 ntf auth set-api-key <apiKey>（或 {path}）\",\n  \"auth.credentials_missing\":\n    \"API Key 未设置，请先写入 {path}，或通过宿主 CLI 执行 ntf auth set-api-key <apiKey>\",\n  \"auth.apikey_invalid_char\":\n    \"apiKey 含非法字符（第 {index} 位，码点 {code}），无法作为 HTTP 请求头发送；通常是写入了掩码/截断后的预览值（如 oc_api…）而不是完整 key。请检查环境变量 YOOOCLAW_API_KEY 与 {path}，重新写入完整 apiKey\",\n  \"errors.INVALID_ENV_VALUE\": \"无效的环境名称: {env}，可选值: {available}\",\n  \"errors.INVALID_LOCALE_VALUE\": \"无效的 locale: {locale}，可选值: {locales}\",\n\n  \"update.notify.failed_title\": \"插件更新失败\",\n  \"update.notify.in_progress_title\": \"插件更新正在进行\",\n  \"update.notify.restart_failed_after_update\": \"插件已更新，但 gateway 自动重启失败\",\n  \"update.notify.restart_failed_prepared\": \"插件更新已准备，但 gateway 自动重启失败\",\n  \"update.notify.restart_failed_default\":\n    \"gateway 自动重启失败，请手动重启 openclaw/gateway。\",\n  \"update.notify.pending\": \"插件更新包已准备完成，正在等待 gateway 重启后应用。\",\n  \"update.notify.applying\": \"插件更新正在应用中，请稍候。\",\n  \"update.notify.wait_restart\": \"等待 gateway 重启完成\",\n  \"update.notify.manual_restart_if_stuck\": \"如果长时间无变化，请手动重启 openclaw/gateway\",\n  \"update.action.manual_restart\": \"手动重启 openclaw/gateway\",\n  \"update.action.retry_trigger\": \"重启后重新触发插件更新\",\n  \"update.action.retry_update\": \"重新触发插件更新\",\n  \"update.action.reinstall_default\": \"如果持续失败，请用安装脚本重新安装到默认 extensions 目录\",\n  \"update.action.check_mount\":\n    \"检查插件安装路径是否指向外置盘、网络盘、容器挂载或软链接目录\",\n  \"update.action.close_gateway_retry\": \"关闭 openclaw/gateway 后重试\",\n  \"update.action.check_busy\": \"检查插件目录权限或文件占用\",\n  \"update.action.check_av\": \"确认杀毒软件、终端或编辑器没有占用插件目录\",\n  \"update.action.retry_later\": \"稍后重试更新\",\n  \"update.action.report\": \"如果持续失败，请复制错误信息反馈给维护者\",\n  \"update.action.enable_restart\": \"如需自动重启，请启用 commands.restart\",\n  \"update.action.wait_current\": \"等待当前更新完成\",\n  \"update.action.wait_apply\": \"等待 gateway 自动重启并应用更新\",\n  \"update.action.check_network\": \"检查网络连接\",\n  \"update.action.check_tar\": \"确认系统 tar 命令可用\",\n  \"update.action.wait_load\": \"等待 gateway 自动重启并加载新版本\",\n  \"update.fail.timeout\":\n    \"gateway 未在预期时间内退出，更新尚未应用。请手动重启 openclaw/gateway 后重试。\",\n  \"update.fail.cross_device\":\n    \"更新安装失败，插件安装目录和临时目录可能位于不同磁盘或挂载点。请重新触发更新；若仍失败，请用安装脚本重新安装到默认 extensions 目录。\",\n  \"update.fail.busy\": \"更新安装失败，可能是插件目录正在被占用。请关闭 openclaw/gateway 后重试。\",\n  \"update.fail.generic\": \"更新安装失败，已尝试回滚。请根据错误信息处理后重试。\",\n  \"update.fail.restart_disabled\":\n    \"gateway 自动重启被配置禁用，请手动重启 openclaw/gateway 后生效。\",\n  \"update.fail.no_sigusr1\": \"当前宿主不支持自动重启，请手动重启 openclaw/gateway 后生效。\",\n  \"update.fail.bg_start\":\n    \"更新包已准备完成，但后台安装进程启动失败，更新尚未应用。请稍后重试。\",\n  \"update.fail.windows\": \"Windows 不支持自动重启 gateway，请手动重启后更新生效。\",\n  \"update.fail.windows_ready\": \"重启完成后插件会自动应用新版本\",\n  \"update.fail.restart_unavailable\": \"gateway 自动重启不可用，更新尚未应用。\",\n  \"update.fail.enable_restart_retry\": \"启用 gateway 自动重启后重试更新\",\n  \"update.msg.not_pending\": \"更新 {id} 状态不是 pending，无法应用\",\n  \"update.msg.missing_package\": \"更新 {id} 缺少 packageDir，无法应用\",\n  \"update.msg.applied\": \"已应用更新到 {version}\",\n  \"update.msg.apply_failed\": \"更新应用失败: {error}\",\n  \"update.msg.invalid_version\": \"非法版本号: {version}\",\n  \"update.msg.busy\":\n    \"已有更新正在进行（{version}，{status}/{phase}），请稍后再试。\",\n  \"update.msg.busy_suggestion\": \"等待当前更新完成，或重启 openclaw/gateway 后再试。\",\n  \"update.msg.download_failed\": \"下载失败 (HTTP {status}): {url}\",\n  \"update.msg.download_suggestion\": \"插件包下载失败，请检查网络或稍后重试。\",\n  \"update.msg.extract_failed\": \"解压失败: {error}\",\n  \"update.msg.extract_suggestion\": \"插件包解压失败，请确认系统 tar 可用后重试。\",\n  \"update.msg.prepared\": \"已准备更新到 {version}\",\n  \"update.msg.prepared_suggestion\": \"更新包已准备完成，gateway 重启后会自动应用。\",\n  \"update.msg.exec_error\": \"更新执行异常: {error}\",\n  \"update.msg.prepared_manual\":\n    \"已准备更新到 {version}，请手动重启 openclaw/gateway 后生效\",\n  \"update.msg.prepared_no_restart\":\n    \"已准备更新到 {version}，但 gateway 自动重启不可用，更新尚未应用\",\n  \"update.msg.bg_failed\": \"更新准备完成但后台安装进程启动失败：{error}\",\n  \"update.msg.applied_restarting\": \"已应用更新到 {version}，正在重启 gateway\",\n  \"recording.error.invalid_transition\": \"非法状态转换: {from} → {to}\",\n  \"light.api.not_configured\":\n    \"灯效 API 未配置，请确认构建时已封装 OPENCLAW_HOST_* / LIGHT_APP_KEY / LIGHT_TEMPLATE_ID\",\n  \"update.version.fallback\": \"目标版本\",\n  \"update.plugin_name\": \"消息通知\",\n  \"update.tool.version_desc\": \"目标版本号，如 1.11.0\",\n  \"light.rule.match.intro\": \"你是\\\"手机通知 → 灯效规则\\\"命中匹配助手。\",\n  \"light.rule.match.low_latency\":\n    \"这是低延迟分类任务；不要输出推理过程、解释、Markdown 或 <think> 内容。\",\n  \"light.rule.match.no_guess\": \"只根据规则 description 和通知字段判断，不要猜测。\",\n  \"light.rule.match.conservative\": \"拿不准就不触发。\",\n  \"light.rule.match.output_format\": \"输出必须是纯 JSON，格式固定为：\",\n  \"light.rule.match.output_schema\":\n    \"{\\\"matches\\\":[{\\\"i\\\":<通知下标>,\\\"rule\\\":\\\"<规则name>\\\"}]}\",\n  \"light.rule.match.zero_or_exact\":\n    \"0 命中输出 {\\\"matches\\\":[]}; rule 必须精确等于下方 name。\",\n  \"light.rule.match.tips_header\": \"匹配要点：\",\n  \"light.rule.match.tip_sender\":\n    \"- 发件人/联系人规则：优先看 sender，其次 conversation_name、title、content 开头的 \\\"X:\\\"/\\\"X：\\\" 前缀；忽略空白、emoji 和中英文标点差异。\",\n  \"light.rule.match.tip_app\": \"- App 通知规则：看 app/appDisplayName 是否符合 description。\",\n  \"light.rule.match.tip_keyword\":\n    \"- 关键词规则：看 title + content 是否包含或语义等价于 description 指定的关键词。\",\n  \"light.rule.match.tip_semantic\":\n    \"- 语义规则：综合 title + content 判断；不要把正文里随便提到的人名当发件人。\",\n  \"light.rule.match.rules_header\": \"当前启用规则：\",\n  \"light.rule.match.notifications_header\": \"以下 {count} 条新手机通知，按顺序编号：\",\n  \"light.rule.match.ask_json\": \"请判断每条通知命中了哪些规则，按约定格式输出 JSON。\",\n  \"light.rule.api.jwt_plugin_path\":\n    \"{message}。请求已命中插件侧 API {path}，插件侧鉴权应只使用 X-Api-Key-Id；当前 401 来自云端 JWT 鉴权层，说明该插件前缀没有被网关/服务端放行到 API Key 鉴权。请后端检查网关白名单和 Notification Intelligence Service 插件路由：{url}\",\n  \"light.rule.api.jwt_app_path\":\n    \"{message}。灯效规则应调用插件侧 API /api/plugin/notification-intelligence/light-rules，并通过 X-Api-Key-Id 鉴权；当前请求可能命中了 App 端 JWT 接口：{url}\",\n  \"tool.light.description\":\n    \"立即控制硬件灯效（一次性执行，不会创建或保存通知触发规则），支持 1–12 段顺序灯效，每段独立参数（5 种模式：波浪/呼吸/频闪/常亮/流光）。Tool 内部自动量化为嵌入式协议定义的离散档位，并按模式精简为变长 ANCS 控制序列，通过 HTTP 接口下发灯效指令。当用户说\\\"开灯\\\"、\\\"换个灯效\\\"、\\\"把灯调成红色\\\"、\\\"营造氛围\\\"、\\\"测试/预览灯效\\\"等与当前即时灯光控制相关的表达时调用。二代带屏硬件还会把本次下发通知的标题和正文显示在屏幕上：当用户说\\\"把 XXX 显示/展示到硬件/屏幕/设备上\\\"等内容展示类请求时，同样调用本工具——展示标题放 title、展示正文放 reason。如果用户说\\\"收到某类通知/消息时亮灯/闪灯/变灯效\\\"，那是持久灯效规则，改用 {createTool} 或 {updateTool}。\",\n  \"tool.light.segments_desc\": \"灯效段序列，1–12 段，按顺序播放\",\n  \"tool.light.mode_desc\":\n    \"灯效模式：wave 波浪（单色跑马，前景色+可选底色）/ breath 呼吸 / strobe 频闪 / steady 常亮 / color_flow 流光（调色板沿圆周流动，1~2 个颜色锚点插值；**不是彩虹**，无法生成 7 色彩虹波浪）。易错对照：用户说\\\"红色/蓝色波浪\\\"等单一颜色波浪 → 必须用 wave，不要用 color_flow；用户说\\\"彩虹/七彩/rainbow\\\" → 固件不支持真正的 7 色彩虹，需告知限制并给出近似方案（双锚点 color_flow 或多段 wave 轮播），禁止静默用 color_flow 单锚点冒充彩虹。\",\n  \"tool.light.duration_s_desc\":\n    \"本段持续时长（秒），0 表示无限时长。推荐离散值：0.5/1/2/3/5/6/8/16/24/32/48，建议单段 ≤8s 省电\",\n  \"tool.light.brightness_desc\":\n    \"前景亮度 0–255，必填；brightness=0 仅 steady 模式有效（显式灭灯）\",\n  \"tool.light.color_desc\":\n    \"前景色 RGB，必填；color_flow 下作为第一颜色锚点，至少 color/background 其一非零\",\n  \"tool.light.interval_ms_desc\":\n    \"步进间隔（ms），wave/strobe/color_flow 有效，默认 200。量化档位：50/100/200/300/500/600/800/1600/2400/3200/4800\",\n  \"tool.light.direction_desc\": \"波浪/流光方向，wave/color_flow 有效，默认 ltr\",\n  \"tool.light.window_desc\": \"wave：窗口灯数，默认 2；color_flow：调色板平移步幅（速度）\",\n  \"tool.light.breath_rise_ms_desc\": \"上升时间（ms），量化到 1040/1560/2080/2600/3100/4160\",\n  \"tool.light.breath_hold_ms_desc\": \"保持最高亮度时间（ms），支持 0ms\",\n  \"tool.light.breath_fall_ms_desc\": \"下降时间（ms），量化到 1040/1560/2080/2600/3100/4160\",\n  \"tool.light.breath_off_ms_desc\": \"熄灭时间（ms），支持 0ms\",\n  \"tool.light.breath_timing_desc\":\n    \"呼吸四段时间，仅 breath 有效；rise/fall 量化档位：1040/1560/2080/2600/3100/4160，hold/off 额外支持 0ms\",\n  \"tool.light.background_desc\":\n    \"底色 RGB + 亮度，wave 有效为底色层；color_flow 有效为第二颜色锚点（与前景色插值生成多色调色板）\",\n  \"tool.light.background_brightness_desc\": \"底色亮度，量化档位：0/32/64/96/128/192/255\",\n  \"tool.light.reason_desc\":\n    \"结合对话上下文总结并精简到 30 字以内，简要说明为什么要亮灯（例如：用户心情低落想要温暖氛围、庆祝生日、提醒喝水等）。这个字段帮助记录每次亮灯的意图和动机。二代带屏硬件会把它作为通知正文与 title 一起显示在屏幕上：当用户意图是\\\"展示内容\\\"时，reason 填要展示的正文内容，并总结精简到 30 字以内。\",\n  \"tool.light.title_desc\":\n    \"对本次亮灯的简短标题/摘要（例如：温暖氛围、生日庆祝、喝水提醒）。二代带屏硬件会把它作为通知标题显示在屏幕上：当用户意图是\\\"展示内容\\\"时，title 填要展示的标题或主要内容；沿用手机推送通知的长度限制，超长会被截断，保持简短。不填时默认回退到 reason。\",\n  \"tool.light.repeat_desc\":\n    \"兼容旧参数。true = 无限循环，false/不填 = 一轮；若同时提供 repeat_times，则以后者为准\",\n  \"tool.light.repeat_times_desc\":\n    \"整条组合重复次数：0 = 无限循环，1 = 播放一轮。当前 ANCS 路径不支持 N>=2\",\n  \"tool.lightrules.list_desc\":\n    \"列出云端 Notification Intelligence Service 中当前账号的灯效规则（包含 enabled/disabled 状态）。当用户说“列出灯效规则”“有哪些灯效规则”“查看规则”等时调用。\",\n  \"tool.lightrules.create_desc\":\n    \"创建一条云端持久灯效规则。必须把用户原始自然语言诉求整理成 ruleText 传入，由 Notification Intelligence Service 的独立 Agent 编译 name/title/description/segments/repeat_times 并保存。ruleText 与回复中的示例语言必须与 replyLanguage 一致（用户用英文提问时不要粘贴中文例句）。当用户说收到某类通知/消息时亮灯/闪灯、新增灯效规则时调用。\",\n  \"tool.lightrules.update_desc\":\n    \"修改云端灯效规则。优先传 id；如果只知道展示名或 name，先调用 lightrules_list 获取规则列表。传 ruleText 表示让独立 Agent 重新编译规则语义；传 title/enabled/description/segments/repeat_times 表示普通字段局部更新。ruleText 不能和普通字段在同一次调用中混用。\",\n  \"tool.lightrules.delete_desc\":\n    \"删除一条云端灯效规则（云端当前实现为软删除）。优先传 id；如果不确定 id，先调用 lightrules_list。\",\n  \"tool.lightrules.segments_desc\": \"灯效段序列，1-12 段，按顺序播放\",\n  \"tool.lightrules.mode_desc\":\n    \"灯效模式：wave 波浪 / breath 呼吸 / strobe 频闪 / steady 常亮 / color_flow 流光\",\n  \"tool.lightrules.duration_s_desc\": \"持续时长（秒），0 表示无限\",\n  \"tool.lightrules.param.id_desc\": \"云端规则 ID（优先使用）\",\n  \"tool.lightrules.param.name_desc\": \"规则语义化 name，兼容旧调用\",\n  \"tool.lightrules.param.rule_id_desc\": \"规则 ID，兼容字段\",\n  \"tool.lightrules.param.rule_name_desc\": \"规则 name，兼容字段\",\n  \"tool.lightrules.param.rule_text_desc\":\n    \"新的自然语言规则；示例语言必须与 replyLanguage 一致；传入后由独立 Agent 重编译\",\n  \"tool.lightrules.param.title_desc\": \"新的展示名/短标题（可选）\",\n  \"tool.lightrules.param.description_desc\": \"新的触发条件描述（可选）\",\n  \"tool.lightrules.param.enabled_desc\": \"true=启用，false=禁用\",\n  \"tool.lightrules.param.segments_desc\": \"新的灯效段序列（可选，不填则保持不变）\",\n  \"tool.lightrules.param.repeat_times_desc\": \"新的重复次数：0=无限循环，1=播放一轮\",\n  \"tool.lightrules.param.repeat_desc\": \"历史兼容字段：true=无限循环，false=播放一轮\",\n  \"tool.lightrules.error.rule_scope\":\n    \"持久灯效规则必须包含通知、消息、来电等触发条件；一次性亮灯请调用 light_control\",\n  \"tool.lightrules.error.rule_text_required\": \"ruleText 为必填项\",\n  \"tool.lightrules.error.rule_text_empty\": \"ruleText 必须为非空字符串\",\n  \"tool.lightrules.error.rule_text_mixed\":\n    \"ruleText 不能与 title/enabled/description/segments/repeat_times/repeat 在同一次调用中混用\",\n  \"tool.lightrules.error.title_empty\": \"title 必须为非空字符串\",\n  \"tool.lightrules.error.description_type\": \"description 必须为字符串\",\n  \"tool.lightrules.error.enabled_type\": \"enabled 必须为布尔值\",\n  \"tool.lightrules.error.repeat_times_type\": \"repeat_times 必须为数字\",\n  \"tool.lightrules.error.repeat_type\": \"repeat 必须为布尔值\",\n  \"tool.lightrules.error.update_field_required\": \"至少需要提供一个更新字段\",\n  \"tool.lightrules.error.id_required_update\": \"id 为必填项；如有需要先调用 lightrules_list\",\n  \"tool.lightrules.error.id_required_delete\": \"id 为必填项\",\n  \"tool.lightrules.error.unknown\": \"未知错误\",\n  \"update.tool.description\":\n    \"将 phone-notifications 插件更新到指定版本。仅在用户明确同意更新后调用。更新完成后会自动尝试重启 gateway；如宿主不支持，则需手动重启。\",\n  \"update.notice.new_version_available\":\n    \"[系统通知] phone-notifications 插件有新版本 {latest} 可用（当前版本 {current}）。\\n请用自然语言在合适时机告知用户，若用户同意更新，调用 plugin-update tool 并传入 version 参数。若用户拒绝，不再重复提醒。\",\n  \"update.stale.base\":\n    \"[系统通知] phone-notifications 插件已更新到 {diskVersion} 并安装完成，但当前进程仍在运行旧版本 {runningVersion}：宿主的进程内重启（SIGUSR1 / gateway.restart）不会重新加载插件代码。\",\n  \"update.stale.restart_scheduled\":\n    \"系统已自动触发一次完整重启，若几分钟后此提示仍出现，说明自动重启未生效，请告知用户需要完整重启 openclaw 进程（例如 systemctl restart openclaw，或结束进程后由服务管理器拉起）。\",\n  \"update.stale.manual_required\":\n    \"请告知用户需要完整重启 openclaw 进程才能生效{reason}：例如 systemctl restart openclaw，或结束 openclaw 进程后由服务管理器拉起；仅执行进程内的 gateway 重启无效。\",\n  \"update.stale.reason_suffix\": \"（{reason}）\",\n  \"update.stale.reason.restart_disabled\":\n    \"commands.restart=false，自动重启被配置禁用\",\n  \"update.stale.reason.already_attempted\":\n    \"已为 {diskVersion} 自动触发过一次完整重启但未生效（宿主可能未由 service manager 托管）\",\n  \"update.stale.reason.record_failed\":\n    \"无法记录自动重启尝试（{error}），为避免重启循环不再自动触发\",\n  \"recording.error.audio_download_failed\": \"音频下载失败: {error}\",\n  \"recording.error.audio_download_exception\": \"音频下载异常: {error}\",\n  \"image.error.sync_failed\": \"图片同步失败: {error}\",\n  \"image.error.download_msg\": \"图片下载失败: {error}\",\n  \"image.error.empty_body\": \"响应体为空\",\n  \"image.error.size_limit\": \"图片超过上限 {maxBytes} 字节\",\n  \"image.error.timeout\": \"下载超时\",\n  \"apns.error.config_missing\":\n    \"APNs 鉴权配置缺失：请设置 OPENCLAW_APNS_TEAM_ID、OPENCLAW_APNS_KEY_ID、OPENCLAW_APNS_PRIVATE_KEY_P8\",\n  \"tunnel.slim.middle_omitted\": \"……[truncated, {omitted} chars omitted]……\",\n  \"tunnel.slim.preview_truncated\": \"…[truncated {omitted} chars]\",\n\n  \"ns.error.positive_int\": \"{field} 必须是大于 0 的整数\",\n  \"ns.error.iso_time\": \"{field} 必须是合法 ISO 8601 时间\",\n  \"ns.error.conversation_type\": \"conversationType 只能是 group 或 private\",\n  \"ns.error.from_after_to\": \"from 不能晚于 to\",\n  \"ns.none\": \"无\",\n  \"ns.sep\": \"；\",\n  \"ns.chunk.title\": \"### 分片 {id}\",\n  \"ns.chunk.count\": \"- 数量: {count}\",\n  \"ns.chunk.top_apps\": \"- 主要 App: {apps}\",\n  \"ns.chunk.top_senders\": \"- 主要发送人/会话: {senders}\",\n  \"ns.chunk.attention\": \"可能需要关注：\",\n  \"ns.chunk.no_attention\": \"- 无明显待办、风险或异常样例\",\n  \"ns.chunk.recent\": \"最近样例：\",\n  \"ns.chunk.none_item\": \"- 无\",\n  \"ns.md.title\": \"# 通知总结\",\n  \"ns.md.total\": \"- 通知数: {total}\",\n  \"ns.md.cap_overflow\": \"- 覆盖上限: 请求数量超过上限，已按最近 {limit} 条处理\",\n  \"ns.md.cap_recent\": \"- 覆盖上限: 最近 {limit} 条\",\n  \"ns.md.time_range\": \"- 时间范围: {oldest} 至 {newest}\",\n  \"ns.md.scan\":\n    \"- 扫描: {days} 天 / {items} 条，命中 {matched} 条，用时 {elapsedMs}ms\",\n  \"ns.md.distribution\": \"## 总体分布\",\n  \"ns.md.top_apps\": \"- 主要 App: {apps}\",\n  \"ns.md.top_senders\": \"- 主要发送人/会话: {senders}\",\n  \"ns.md.top_conversations\": \"- 主要会话: {conversations}\",\n  \"ns.md.attention\": \"## 可能需要关注\",\n  \"ns.md.no_attention\": \"- 未发现明显待办、风险、失败或紧急样例\",\n  \"ns.md.chunk_summaries\": \"## 分片摘要\",\n  \"ns.md.no_notifications\": \"无通知\",\n  \"ns.display.title\": \"# 未读通知总结\",\n  \"ns.display.empty\": \"没有找到符合条件的通知。\",\n  \"ns.display.scan_range\":\n    \"扫描范围：{days} 天 / {items} 条，用时 {elapsedMs}ms。\",\n  \"ns.display.coverage_overflow\": \"请求数量超过上限，已按最近 {limit} 条处理\",\n  \"ns.display.coverage_hit\": \"最近 {limit} 条内命中 {total} 条\",\n  \"ns.display.summary_line\": \"共整理 {total} 条通知，覆盖 {coverage}。\",\n  \"ns.display.time_range\": \"时间范围：{oldest} 至 {newest}。\",\n  \"ns.display.sources\": \"## 主要来源\",\n  \"ns.display.app\": \"- App：{apps}\",\n  \"ns.display.sender\": \"- 发送人/会话：{senders}\",\n  \"ns.display.conversation\": \"- 会话：{conversations}\",\n  \"ns.display.attention\": \"## 需要关注\",\n  \"ns.display.recent\": \"## 最近样例\",\n  \"ns.progress.scanning\": \"正在扫描通知...\",\n  \"ns.progress.snapshot\": \"已找到 {total} 条通知，拆成 {chunks} 个分片\",\n  \"ns.progress.summarizing\": \"正在整理通知摘要：{done}/{total} 个分片\",\n  \"ns.progress.merging\": \"正在合并摘要...\",\n  \"ns.progress.complete\": \"通知摘要已完成，正在推送总结内容...\",\n\n  \"tool.notifications.summary_desc\":\n    \"总结手机通知/消息并在执行过程中广播 notification.summary.status 进度事件。当用户要求总结最近通知、未读通知、最近消息、约 N 条通知时优先调用。如果用户给出约 N 条/最近 N 条，必须把 N 原样传给 limit；未读通知没有独立过滤字段时按最近通知处理，不要自行放大数量。完成时会广播 notification.summary.result，携带可直接展示的完整总结 Markdown。返回的是压缩后的 Markdown 摘要输入，后续回复应基于它提炼总结，避免逐条罗列。\",\n  \"tool.notifications.from_desc\": \"开始时间，ISO 8601，例如 2026-06-13T09:00:00+08:00\",\n  \"tool.notifications.to_desc\": \"结束时间，ISO 8601\",\n  \"tool.notifications.app_desc\": \"按应用名或显示名过滤\",\n  \"tool.notifications.sender_desc\": \"按发送人/标题过滤\",\n  \"tool.notifications.conversation_type_desc\": \"按会话类型过滤\",\n  \"tool.notifications.keyword_desc\": \"在标题、正文、发送人、会话名中搜索关键词\",\n  \"tool.notifications.limit_desc\": \"纳入摘要的最大通知条数；默认 700，上限 3000\",\n  \"tool.notifications.chunk_size_desc\": \"每个分片的通知条数；默认 150\",\n  \"ns.event.complete_message\": \"通知总结已完成\",\n  \"ns.event.complete_title\": \"未读通知总结\",\n  \"ns.event.failed\": \"通知总结失败：{message}\",\n  \"ns.event.summary_failed\": \"通知摘要失败：{message}\",\n  \"ns.event.started\": \"已开始通知摘要任务...\",\n  \"ns.event.storage_not_ready\": \"通知存储服务尚未就绪\",\n} as const;\n",
    "import type { SupportedLocale } from \"../locale.js\";\nimport { enUS } from \"./en-US.js\";\nimport { zhCN } from \"./zh-CN.js\";\nimport { zhTW } from \"./zh-TW.js\";\n\nexport type MessageKey = keyof typeof zhCN;\n\nconst MESSAGE_TABLES: Record<SupportedLocale, Record<MessageKey, string>> = {\n  \"zh-CN\": zhCN,\n  \"zh-TW\": zhTW,\n  \"en-US\": enUS,\n};\n\nexport function getMessagesForLocale(locale: SupportedLocale): Record<MessageKey, string> {\n  return MESSAGE_TABLES[locale] ?? MESSAGE_TABLES[\"zh-CN\"];\n}\n",
    "import { randomBytes } from \"node:crypto\";\nimport {\n  existsSync,\n  mkdirSync,\n  readFileSync,\n  renameSync,\n  rmSync,\n  writeFileSync,\n} from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { t } from \"./i18n/translate.js\";\nimport { readCredentials } from \"./auth/credentials.js\";\nimport { resolveStateFile } from \"./host.js\";\n\n// 容错解析：先按换行切分，再按 KEY= 边界切分，恢复历史上把多条记录粘在同一行的 .env。\n// lookbehind 限定前一个字符不是标识符字符，避免在 key 内部错误切分。\nfunction parseEnvContent(content: string): Map<string, string> {\n  const entries = new Map<string, string>();\n  const tokens = content\n    .split(/\\r?\\n/)\n    .flatMap((line) => line.split(/(?<![A-Z0-9_])(?=[A-Z_][A-Z0-9_]*=)/));\n  for (const token of tokens) {\n    const trimmed = token.trim();\n    if (!trimmed || trimmed.startsWith(\"#\")) continue;\n    const eq = trimmed.indexOf(\"=\");\n    if (eq < 1) continue;\n    const key = trimmed.slice(0, eq).trim();\n    if (!/^[A-Z_][A-Z0-9_]*$/.test(key)) continue;\n    entries.set(key, trimmed.slice(eq + 1).trim());\n  }\n  return entries;\n}\n\n/** 向 stateDir/.env 写入或更新单个键值（供 env、locale 等模块复用）。 */\nexport function upsertStateDotEnv(key: string, value: string): void {\n  writeDotEnv(key, value);\n}\n\nfunction writeDotEnv(key: string, value: string): void {\n  const path = resolveStateFile(\".env\");\n  mkdirSync(dirname(path), { recursive: true });\n  const existing = existsSync(path) ? readFileSync(path, \"utf-8\") : \"\";\n  const entries = parseEnvContent(existing);\n  entries.set(key, value);\n  const output =\n    Array.from(entries, ([k, v]) => `${k}=${v}`).join(\"\\n\") + \"\\n\";\n  const tmpPath = `${path}.tmp.${process.pid}.${randomBytes(4).toString(\"hex\")}`;\n  try {\n    // JvsClaw may leave an existing .env read-only while its state directory\n    // remains writable. Replacing a sibling temp file avoids reopening it.\n    writeFileSync(tmpPath, output, { encoding: \"utf-8\", mode: 0o600 });\n    renameSync(tmpPath, path);\n  } catch (error) {\n    try {\n      rmSync(tmpPath, { force: true });\n    } catch {\n      // ignore tmp cleanup failure\n    }\n    throw error;\n  }\n}\n\nexport type EnvName = \"development\" | \"test\" | \"production\";\n\nconst DEFAULT_ENV_HOSTS: Record<EnvName, string> = {\n  development: \"openclaw-service-dev.yoooclaw.com\",\n  test: \"openclaw-service-test.yoooclaw.com\",\n  production: \"openclaw-service.yoooclaw.com\",\n};\n\nexport const NOTIFICATION_INTELLIGENCE_LIGHT_RULES_PLUGIN_PATH =\n  \"/api/plugin/notification-intelligence/light-rules\";\nexport const NOTIFICATION_INTELLIGENCE_LIGHT_EFFECTS_SEND_PLUGIN_PATH =\n  \"/api/plugin/notification-intelligence/light-effects/send\";\nconst NOTIFICATION_INTELLIGENCE_LIGHT_RULES_APP_PATH =\n  \"/api/notification-intelligence/light-rules\";\nconst NOTIFICATION_INTELLIGENCE_PLUGIN_BASE_PATH =\n  \"/api/plugin/notification-intelligence\";\nconst NOTIFICATION_INTELLIGENCE_APP_BASE_PATH =\n  \"/api/notification-intelligence\";\n\ninterface EnvUrls {\n  lightApiUrl: string;\n  notificationIntelligenceLightRulesPluginUrl: string;\n  notificationIntelligenceLightEffectsSendUrl: string;\n  appNameMapUrl: string;\n  relayTunnelUrl: string;\n  modelProxyLongRecordingSubmitTaskUrl: string;\n  modelProxyLongRecordingQueryTaskResultBaseUrl: string;\n  gatewayConnectStatusUrl: string;\n  /** jvsclaw 实例就绪/密文换 apiKey 接口（复用插件现有接口 host）。 */\n  clawManagerInstanceReadyUrl: string;\n}\n\nfunction normalizeHost(host: string | undefined): string | undefined {\n  const trimmed = host?.trim();\n  if (!trimmed) return undefined;\n  return trimmed\n    .replace(/^https?:\\/\\//, \"\")\n    .replace(/^wss?:\\/\\//, \"\")\n    .replace(/\\/+$/, \"\");\n}\n\nfunction getEnvHost(env: EnvName): string {\n  let host: string | undefined;\n  switch (env) {\n    case \"development\":\n      host = process.env.OPENCLAW_HOST_DEVELOPMENT;\n      break;\n    case \"test\":\n      host = process.env.OPENCLAW_HOST_TEST;\n      break;\n    case \"production\":\n      host = process.env.OPENCLAW_HOST_PRODUCTION;\n      break;\n  }\n  return normalizeHost(host) ?? DEFAULT_ENV_HOSTS[env];\n}\n\nexport function normalizeNotificationIntelligenceLightRulesPluginUrl(\n  url: string,\n): string {\n  const trimmed = url.trim().replace(/\\/+$/, \"\");\n  if (!trimmed) return trimmed;\n\n  if (trimmed.endsWith(NOTIFICATION_INTELLIGENCE_LIGHT_RULES_PLUGIN_PATH)) {\n    return trimmed;\n  }\n\n  if (trimmed.endsWith(NOTIFICATION_INTELLIGENCE_LIGHT_RULES_APP_PATH)) {\n    const origin = trimmed.slice(\n      0,\n      -NOTIFICATION_INTELLIGENCE_LIGHT_RULES_APP_PATH.length,\n    );\n    return `${origin}${NOTIFICATION_INTELLIGENCE_LIGHT_RULES_PLUGIN_PATH}`;\n  }\n\n  if (trimmed.endsWith(NOTIFICATION_INTELLIGENCE_PLUGIN_BASE_PATH)) {\n    return `${trimmed}/light-rules`;\n  }\n\n  if (trimmed.endsWith(NOTIFICATION_INTELLIGENCE_APP_BASE_PATH)) {\n    const origin = trimmed.slice(\n      0,\n      -NOTIFICATION_INTELLIGENCE_APP_BASE_PATH.length,\n    );\n    return `${origin}${NOTIFICATION_INTELLIGENCE_LIGHT_RULES_PLUGIN_PATH}`;\n  }\n\n  if (/^https?:\\/\\/[^/]+$/i.test(trimmed)) {\n    return `${trimmed}${NOTIFICATION_INTELLIGENCE_LIGHT_RULES_PLUGIN_PATH}`;\n  }\n\n  return trimmed;\n}\n\n/**\n * 一次性亮灯入口与规则入口同源：默认由规则插件 URL 推导，把结尾的\n * `/light-rules` 替换为 `/light-effects/send`，让 NOTIFICATION_INTELLIGENCE_LIGHT_RULES_URL\n * 的环境覆盖同时作用于两个入口。\n */\nexport function normalizeNotificationIntelligenceLightEffectsSendUrl(\n  url: string,\n): string {\n  const trimmed = url.trim().replace(/\\/+$/, \"\");\n  if (!trimmed) return trimmed;\n\n  if (trimmed.endsWith(NOTIFICATION_INTELLIGENCE_LIGHT_EFFECTS_SEND_PLUGIN_PATH)) {\n    return trimmed;\n  }\n\n  const normalizedRulesUrl =\n    normalizeNotificationIntelligenceLightRulesPluginUrl(trimmed);\n  if (normalizedRulesUrl.endsWith(NOTIFICATION_INTELLIGENCE_LIGHT_RULES_PLUGIN_PATH)) {\n    const origin = normalizedRulesUrl.slice(\n      0,\n      -NOTIFICATION_INTELLIGENCE_LIGHT_RULES_PLUGIN_PATH.length,\n    );\n    return `${origin}${NOTIFICATION_INTELLIGENCE_LIGHT_EFFECTS_SEND_PLUGIN_PATH}`;\n  }\n\n  return `${trimmed}/light-effects/send`;\n}\n\nfunction buildEnvUrls(host: string): EnvUrls {\n  const https = `https://${host}`;\n  const wss = `wss://${host}`;\n  const lightRulesUrl = normalizeNotificationIntelligenceLightRulesPluginUrl(\n    process.env.NOTIFICATION_INTELLIGENCE_LIGHT_RULES_URL ||\n      `${https}${NOTIFICATION_INTELLIGENCE_LIGHT_RULES_PLUGIN_PATH}`,\n  );\n  const lightEffectsSendUrl = normalizeNotificationIntelligenceLightEffectsSendUrl(\n    process.env.NOTIFICATION_INTELLIGENCE_LIGHT_EFFECTS_SEND_URL || lightRulesUrl,\n  );\n  return {\n    lightApiUrl: `${https}/api/message/tob/sendMessage`,\n    notificationIntelligenceLightRulesPluginUrl: lightRulesUrl,\n    notificationIntelligenceLightEffectsSendUrl: lightEffectsSendUrl,\n    relayTunnelUrl: `${wss}/message/messages/ws/plugin`,\n    appNameMapUrl: `${https}/api/application-config/app-package/config-all`,\n    modelProxyLongRecordingSubmitTaskUrl: `${https}/api/model-proxy/long-recording/submit-task`,\n    modelProxyLongRecordingQueryTaskResultBaseUrl: `${https}/api/model-proxy/long-recording/query-task-result`,\n    gatewayConnectStatusUrl: `${https}/api/message/messageBridge/plugin/gateway-connect-status`,\n    clawManagerInstanceReadyUrl: `${https}/claw-manager/internal/claw-manager/instance/ready`,\n  };\n}\n\nconst VALID_ENVS: ReadonlySet<string> = new Set<string>([\n  \"development\",\n  \"test\",\n  \"production\",\n]);\n\nfunction readDotEnv(): Record<string, string> {\n  const path = resolveStateFile(\".env\");\n  if (!existsSync(path)) return {};\n  return Object.fromEntries(parseEnvContent(readFileSync(path, \"utf-8\")));\n}\n\n/** 读取持久化到 .env 的环境名称；仅反映本地配置，不考虑进程环境变量。 */\nexport function readPersistedEnvName(): EnvName | undefined {\n  const fromDotEnv = readDotEnv()[\"PHONE_NOTIFICATIONS_ENV\"]?.trim();\n  if (fromDotEnv && VALID_ENVS.has(fromDotEnv)) return fromDotEnv as EnvName;\n  return undefined;\n}\n\n/**\n * 读取当前环境名称。优先级：状态目录 .env > credentials.json > 默认 production。\n *\n * 不再读取 process.env.PHONE_NOTIFICATIONS_ENV：launchd / systemd 等托管服务会把它作为\n * managed env 注入，并在每次重启时用进程当前值重新快照，从而以高于 .env 的优先级覆盖\n * `ntf env switch` 写入的 .env，导致环境切换始终不生效。状态目录 .env 是 switch 的唯一落点，\n * 因此作为最高优先级。\n */\nexport function loadEnvName(): EnvName {\n  const fromDotEnv = readPersistedEnvName();\n  if (fromDotEnv) return fromDotEnv;\n\n  const { env } = readCredentials();\n  if (env && VALID_ENVS.has(env)) return env as EnvName;\n\n  return \"production\";\n}\n\n/** 持久化当前环境到 .env */\nexport function saveEnvName(env: EnvName): void {\n  if (!VALID_ENVS.has(env)) {\n    throw new Error(t(\"errors.INVALID_ENV_VALUE\", {\n      env,\n      available: [...VALID_ENVS].join(\", \"),\n    }));\n  }\n  upsertStateDotEnv(\"PHONE_NOTIFICATIONS_ENV\", env);\n}\n\n/** 获取当前环境的 URL 配置 */\nexport function getEnvUrls(env?: EnvName): EnvUrls {\n  return buildEnvUrls(getEnvHost(env ?? loadEnvName()));\n}\n\n/** 获取所有可用环境名称 */\nexport function getAvailableEnvs(): EnvName[] {\n  return [\"development\", \"test\", \"production\"];\n}\n",
    "import { getActiveLocale, resolveLocale, type SupportedLocale } from \"./locale.js\";\nimport {\n  getMessagesForLocale,\n  type MessageKey,\n} from \"./messages/index.js\";\n\ntype ActiveMessages = ReturnType<typeof getMessagesForLocale>;\n\nlet activeMessages: ActiveMessages | undefined;\n\nfunction ensureActiveMessages(): ActiveMessages {\n  if (!activeMessages) {\n    activeMessages = getMessagesForLocale(getActiveLocale());\n  }\n  return activeMessages;\n}\n\nexport function setActiveMessages(locale: SupportedLocale): void {\n  activeMessages = getMessagesForLocale(locale);\n}\n\n/** CLI / 插件启动时初始化文案语言。 */\nexport function initI18n(options?: { locale?: SupportedLocale }): SupportedLocale {\n  const locale = options?.locale ?? resolveLocale().locale;\n  setActiveMessages(locale);\n  return locale;\n}\n\nfunction interpolate(\n  template: string,\n  params?: Record<string, string | number>,\n): string {\n  if (!params) return template;\n  return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => {\n    const value = params[key];\n    return value === undefined ? `{${key}}` : String(value);\n  });\n}\n\nexport function t(\n  key: MessageKey,\n  params?: Record<string, string | number>,\n): string {\n  const template = ensureActiveMessages()[key];\n  if (!template) return key;\n  return interpolate(template, params);\n}\n\nconst ERROR_CODE_TO_KEY: Record<string, MessageKey> = {\n  INVALID_TIME: \"errors.INVALID_TIME\",\n  STORAGE_UNAVAILABLE: \"errors.STORAGE_UNAVAILABLE\",\n  LOGS_UNAVAILABLE: \"errors.LOGS_UNAVAILABLE\",\n  NOT_FOUND: \"errors.NOT_FOUND\",\n  ALREADY_EXISTS: \"errors.ALREADY_EXISTS\",\n  INVALID_TIME_RANGE: \"errors.INVALID_TIME_RANGE\",\n  INVALID_LIMIT: \"errors.INVALID_POSITIVE_INT\",\n  INVALID_SAMPLE: \"errors.INVALID_POSITIVE_INT\",\n  INVALID_TOP: \"errors.INVALID_POSITIVE_INT\",\n  INVALID_DATE: \"errors.INVALID_DATE\",\n  INVALID_SCOPE: \"errors.INVALID_SCOPE\",\n  NO_DATA: \"errors.NO_DATA\",\n  INVALID_LOCALE: \"errors.INVALID_LOCALE\",\n  INVALID_CONVERSATION_TYPE: \"errors.INVALID_CONVERSATION_TYPE\",\n  INVALID_END_INDEX: \"errors.INVALID_END_INDEX\",\n  INVALID_MAX_END_INDEX: \"errors.INVALID_MAX_END_INDEX\",\n  STALE_END_INDEX: \"errors.STALE_END_INDEX\",\n  CONFIG_NOT_FOUND: \"errors.CONFIG_NOT_FOUND\",\n  CONFIG_INVALID: \"errors.CONFIG_INVALID\",\n  WRITE_FAILED: \"errors.WRITE_FAILED\",\n  HTTP_ERROR: \"errors.HTTP_ERROR\",\n  IMAGE_NOT_READY: \"errors.IMAGE_NOT_READY\",\n  INVALID_JOB_ID: \"errors.INVALID_JOB_ID\",\n  READ_FAILED: \"errors.READ_FAILED\",\n  JOB_NOT_FOUND: \"errors.JOB_NOT_FOUND\",\n  INVALID_JOB: \"errors.INVALID_JOB\",\n  INVALID_CHUNK: \"errors.INVALID_CHUNK\",\n  INVALID_COMMIT: \"errors.INVALID_COMMIT.required\",\n  JOB_CANCELLED: \"errors.JOB_CANCELLED\",\n  CHUNK_NOT_FOUND: \"errors.CHUNK_NOT_FOUND\",\n  INVALID_ENV: \"errors.INVALID_ENV\",\n  TUNNEL_NOT_CONFIGURED: \"errors.TUNNEL_NOT_CONFIGURED\",\n  TOKEN_MISSING: \"errors.TUNNEL_TOKEN_MISSING\",\n  STATE_DIR_UNAVAILABLE: \"errors.STATE_DIR_UNAVAILABLE\",\n  STATUS_NOT_FOUND: \"errors.STATUS_NOT_FOUND\",\n};\n\nexport function tError(\n  code: string,\n  params?: Record<string, string | number>,\n): string {\n  const key = ERROR_CODE_TO_KEY[code];\n  if (key) return t(key, params);\n  return code;\n}\n",
    "import {\n  existsSync,\n  mkdirSync,\n  readFileSync,\n  watch,\n} from \"node:fs\";\nimport { dirname, basename } from \"node:path\";\nimport { t } from \"../i18n/index.js\";\nimport { resolveStateFile } from \"../host.js\";\nimport { quarantineCorruptFile, writeFileAtomic } from \"../fs-atomic.js\";\n\ninterface Credentials {\n  /**\n   * 推荐：API Key 明文（例如 ock_xxx）\n   */\n  apiKey?: string;\n  /**\n   * CLI multi-key 共享格式。存在该字段时以它为准；空数组表示显式未配置 key。\n   */\n  apiKeys?: ApiKeyEntry[];\n  /**\n   * 兼容旧字段：历史上这里存的是 token；现在等价于 apiKey\n   */\n  token?: string;\n  /**\n   * 当前环境（development / production），由 ntf env switch 写入\n   */\n  env?: string;\n  /**\n   * jvsclaw 专用：上次置换 apiKey 时使用的 link_secret 哈希。\n   * 用于重置后检测宿主下发的密文是否变化，避免继续复用旧实例 apiKey。\n   */\n  jvsclawLinkSecretHash?: string;\n}\n\ninterface ApiKeyEntry {\n  label?: string;\n  key?: string;\n  default?: boolean;\n  createdAt?: string;\n}\n\nconst API_KEY_ENV = \"YOOOCLAW_API_KEY\";\n\nexport function credentialsPath(): string {\n  return resolveStateFile(\"credentials.json\");\n}\n\nexport function readCredentials(): Credentials {\n  const path = credentialsPath();\n  if (!existsSync(path)) return {};\n\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(readFileSync(path, \"utf-8\"));\n  } catch {\n    // 文件损坏时先隔离再返回空：否则下一次 writeCredentials 会直接覆盖，\n    // 把本可人工找回的 apiKey 静默销毁。\n    quarantineCorruptFile(path);\n    return {};\n  }\n\n  // JSON 合法但不是对象（如 `null` / `123`）时，直接返回会让调用方\n  // 在 `creds.apiKeys` 上抛 TypeError。\n  if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n    quarantineCorruptFile(path);\n    return {};\n  }\n  return parsed as Credentials;\n}\n\nexport function writeCredentials(creds: Credentials): void {\n  const path = credentialsPath();\n  mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n  // 原子写：直接 writeFileSync 时崩溃会留下半截文件，配合上面的隔离逻辑\n  // 等于丢失凭据。mode 0600 同时作用于临时文件，避免 rename 前短暂可读。\n  writeFileAtomic(path, JSON.stringify(creds, null, 2), { mode: 0o600 });\n}\n\nfunction normalizedKey(value: unknown): string | undefined {\n  return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction loadApiKeyFromMulti(creds: Credentials): string | undefined {\n  if (!Array.isArray(creds.apiKeys)) return undefined;\n  const entries = creds.apiKeys\n    .map((entry) => ({\n      key: normalizedKey(entry?.key),\n      default: entry?.default === true,\n    }))\n    .filter((entry): entry is { key: string; default: boolean } => Boolean(entry.key));\n  return entries.find((entry) => entry.default)?.key ?? entries[0]?.key;\n}\n\nexport function loadApiKey(): string | undefined {\n  const env = normalizedKey(process.env[API_KEY_ENV]);\n  if (env) return env;\n\n  const creds = readCredentials();\n  if (Array.isArray(creds.apiKeys)) {\n    return loadApiKeyFromMulti(creds);\n  }\n  return normalizedKey(creds.apiKey) ?? normalizedKey(creds.token);\n}\n\nexport function writeSingleApiKey(apiKey: string): void {\n  const creds = readCredentials();\n  delete creds.apiKeys;\n  writeCredentials({ ...creds, apiKey, token: undefined });\n}\n\nexport function clearApiKeys(): void {\n  const creds = readCredentials();\n  delete creds.apiKey;\n  delete creds.apiKeys;\n  delete creds.token;\n  writeCredentials(creds);\n}\n\nexport function requireApiKey(): string {\n  const apiKey = loadApiKey();\n  if (!apiKey) {\n    throw new Error(t(\"auth.credentials_missing\", { path: credentialsPath() }));\n  }\n  return apiKey;\n}\n\n// ---- Backward-compatible exports (旧代码仍可编译；语义等价于 apiKey) ----\nexport function loadToken(): string | undefined {\n  return loadApiKey();\n}\n\nexport function requireToken(): string {\n  return requireApiKey();\n}\n\n/** 监听 credentials 文件变化（如 set-token 后）触发 callback；返回取消监听的函数 */\nexport function watchCredentials(onChange: () => void): () => void {\n  const path = credentialsPath();\n  const dir = dirname(path);\n  const filename = basename(path);\n  let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n  const delayMs = 200;\n\n  const listener = (_event: string, changedName: string | null) => {\n    if (!changedName || (changedName !== filename && !changedName.endsWith(filename))) return;\n    if (debounceTimer) clearTimeout(debounceTimer);\n    debounceTimer = setTimeout(() => {\n      debounceTimer = null;\n      onChange();\n    }, delayMs);\n  };\n\n  let watcher: ReturnType<typeof watch> | null = null;\n  try {\n    watcher = watch(dir, { persistent: false }, listener);\n  } catch {\n    // 目录可能不存在\n  }\n\n  return () => {\n    if (debounceTimer) clearTimeout(debounceTimer);\n    watcher?.close();\n  };\n}\n",
    "import {\n  closeSync,\n  fsyncSync,\n  mkdirSync,\n  openSync,\n  renameSync,\n  rmSync,\n  writeFileSync,\n  writeSync,\n} from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nexport interface WriteFileAtomicOptions {\n  /** 文件权限；写敏感数据（凭据等）时传 0o600。默认沿用 umask。 */\n  mode?: number;\n  /**\n   * 是否 fsync 文件与父目录。默认 true：只 rename 不 fsync 时，\n   * 掉电后可能留下长度为 0 的文件（ext4/APFS 的已知行为）。\n   */\n  durable?: boolean;\n}\n\n/**\n * 原子写文件：先写临时文件再 rename 覆盖，避免进程崩溃/断电时\n * 留下半截文件导致后续读取解析失败。\n *\n * 临时文件与目标文件必须同目录，否则 rename 可能跨设备失败。\n */\nexport function writeFileAtomic(\n  path: string,\n  data: string,\n  options: WriteFileAtomicOptions = {},\n): void {\n  const { mode, durable = true } = options;\n  const dir = dirname(path);\n  mkdirSync(dir, { recursive: true });\n  const tmpPath = `${path}.tmp.${process.pid}.${Date.now()}`;\n\n  try {\n    if (durable) {\n      // 用 fd 写才能在 close 前 fsync，保证 rename 生效时数据已落盘\n      const fd = openSync(tmpPath, \"w\", mode ?? 0o666);\n      try {\n        writeSync(fd, data, 0, \"utf-8\");\n        fsyncSync(fd);\n      } finally {\n        closeSync(fd);\n      }\n    } else {\n      writeFileSync(tmpPath, data, mode === undefined ? \"utf-8\" : { encoding: \"utf-8\", mode });\n    }\n    renameSync(tmpPath, path);\n  } catch (err) {\n    // 写或 rename 失败时不能把临时文件留在目录里，否则会持续堆积\n    try {\n      rmSync(tmpPath, { force: true });\n    } catch {\n      // ignore\n    }\n    throw err;\n  }\n\n  if (durable) {\n    // rename 本身也需要 fsync 父目录才能在掉电后保留\n    try {\n      const dirFd = openSync(dir, \"r\");\n      try {\n        fsyncSync(dirFd);\n      } finally {\n        closeSync(dirFd);\n      }\n    } catch {\n      // 部分平台（如 Windows）不支持对目录 fsync，忽略\n    }\n  }\n}\n\n/**\n * 隔离损坏文件：把无法解析的文件改名为 `<path>.corrupt.<ts>` 保留现场，\n * 避免后续写入直接覆盖导致数据静默丢失。返回隔离后的路径；失败返回 null。\n */\nexport function quarantineCorruptFile(path: string): string | null {\n  const quarantinePath = `${path}.corrupt.${Date.now()}`;\n  try {\n    renameSync(path, quarantinePath);\n    return quarantinePath;\n  } catch {\n    return null;\n  }\n}\n",
    "import { existsSync, readFileSync, realpathSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport type { SupportedLocale } from \"./locale.js\";\n\nexport const SKILLS_RELATIVE_PATH = \"./skills\";\n\n/**\n * Skill 使用单一语言中性目录，不随 UI locale 切换。\n * 保留 locale 参数以兼容现有调用方。\n */\nexport function resolveSkillsRelativePath(_locale?: SupportedLocale): string {\n  return SKILLS_RELATIVE_PATH;\n}\n\n/** 解析 skill 内资源路径（相对仓库根目录）。 */\nexport function resolveSkillResourcePath(\n  relativePath: string,\n  _locale?: SupportedLocale,\n): string {\n  return `skills/${relativePath}`;\n}\n\nexport function resolveSkillsAbsolutePath(\n  pluginInstallDir: string,\n  _locale?: SupportedLocale,\n): string {\n  return join(pluginInstallDir, \"skills\");\n}\n\n/**\n * 从独立 ntf 入口的真实位置解析插件安装根目录。\n *\n * ntf 入口位于 <installDir>/dist/bin/ntf.cjs。先解析软链接，确保通过 PATH\n * 调用时仍定位到实际插件包，而不是 wrapper 所在目录。\n */\nexport function resolvePluginInstallDirFromNtfEntry(\n  ntfEntryPath: string,\n): string {\n  return resolve(dirname(realpathSync(ntfEntryPath)), \"..\", \"..\");\n}\n\n/** 解析已安装插件包内的 skill 资源绝对路径，不依赖进程 cwd。 */\nexport function resolveInstalledSkillResourcePath(\n  pluginInstallDir: string,\n  relativePath: string,\n  locale?: SupportedLocale,\n): string {\n  return resolve(\n    resolveSkillsAbsolutePath(pluginInstallDir, locale),\n    relativePath,\n  );\n}\n\n/** 将已安装插件包内 manifest 固定到语言中性 Skill 目录。 */\nexport function syncInstalledPluginSkillsManifest(\n  pluginInstallDir: string,\n  _locale?: SupportedLocale,\n): { updated: boolean; skillsPath: string } {\n  const skillsPath = SKILLS_RELATIVE_PATH;\n  const manifestPath = join(pluginInstallDir, \"openclaw.plugin.json\");\n  if (!existsSync(manifestPath)) {\n    return { updated: false, skillsPath };\n  }\n\n  let manifest: { skills?: string[] };\n  try {\n    manifest = JSON.parse(readFileSync(manifestPath, \"utf-8\")) as { skills?: string[] };\n  } catch {\n    return { updated: false, skillsPath };\n  }\n\n  const nextSkills = [skillsPath];\n  const changed = JSON.stringify(manifest.skills ?? []) !== JSON.stringify(nextSkills);\n  if (!changed) {\n    return { updated: false, skillsPath };\n  }\n\n  manifest.skills = nextSkills;\n  writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`, \"utf-8\");\n  return { updated: true, skillsPath };\n}\n",
    "import {\n  getActiveLocale,\n  normalizeLocale,\n  type SupportedLocale,\n} from \"./locale.js\";\n\nexport interface ResponseLocalePreference {\n  responseLocale: SupportedLocale;\n  targetLanguage: string | null;\n}\n\n/** 按 sessionKey 保存客户端语言偏好与任务产物语言；全局默认见 getActiveLocale()。 */\nexport class ResponseLocaleStore {\n  private readonly bySession = new Map<string, ResponseLocalePreference>();\n\n  setForSession(\n    sessionKey: string,\n    preference: ResponseLocalePreference,\n  ): ResponseLocalePreference {\n    this.bySession.set(sessionKey, preference);\n    return preference;\n  }\n\n  getForSession(sessionKey: string | undefined): ResponseLocalePreference | null {\n    if (!sessionKey) return null;\n    return this.bySession.get(sessionKey) ?? null;\n  }\n\n  resolve(sessionKey: string | undefined): ResponseLocalePreference {\n    const session = this.getForSession(sessionKey);\n    if (session) return session;\n    return {\n      responseLocale: getActiveLocale(),\n      targetLanguage: null,\n    };\n  }\n\n  clearForSession(sessionKey: string): void {\n    this.bySession.delete(sessionKey);\n  }\n\n  resetForTest(): void {\n    this.bySession.clear();\n  }\n}\n\nexport const responseLocaleStore = new ResponseLocaleStore();\n\nexport function normalizeTargetLanguage(input: unknown): string | null {\n  if (input === null || input === undefined) return null;\n  if (typeof input !== \"string\") return null;\n  const trimmed = input.trim();\n  return trimmed || null;\n}\n\nexport function resolveResponseLocaleInput(\n  params: {\n    locale?: unknown;\n    responseLocale?: unknown;\n  },\n): SupportedLocale | null {\n  return (\n    normalizeLocale(params.responseLocale)\n    ?? normalizeLocale(params.locale)\n  );\n}\n\n/**\n * Always-on reply language policy for before_prompt_build (system context).\n * Kept in English so App UI locale / Chinese skill examples do not bias the model.\n * Does not enumerate languages — the model follows the original user-authored message.\n */\nexport const REPLY_LANGUAGE_POLICY = [\n  \"## Output language\",\n  \"\",\n  \"At the beginning of each run:\",\n  \"\",\n  \"1. Detect language only from the original user-authored message that started this run.\",\n  \"2. Set replyLanguage.\",\n  \"3. Keep replyLanguage unchanged during this run.\",\n  \"\",\n  \"Never determine language from:\",\n  \"\",\n  \"- previous conversation\",\n  \"- memory\",\n  \"- tool output\",\n  \"- notification content\",\n  \"- external data\",\n  \"- skill description\",\n  \"- skill examples\",\n  \"\",\n  \"All user-facing responses must use replyLanguage.\",\n  \"\",\n  \"Natural-language tool arguments must also use replyLanguage — especially `ruleText` for light-rule create/update.\",\n  \"Do not translate an English user request into Chinese ruleText (or the reverse) just because App UI locale, tool schemas, or examples use another language.\",\n  \"\",\n  \"Keep unchanged:\",\n  \"\",\n  \"- code\",\n  \"- commands\",\n  \"- paths\",\n  \"- identifiers\",\n  \"- JSON keys\",\n  \"- API fields\",\n  \"- raw data\",\n].join(\"\\n\");\n\n/** Stable policy (+ optional artifact language) for system prompt space. */\nexport function buildResponseLocaleSystemContext(\n  preference: ResponseLocalePreference,\n): string {\n  if (!preference.targetLanguage) return REPLY_LANGUAGE_POLICY;\n\n  return [\n    REPLY_LANGUAGE_POLICY,\n    \"\",\n    `Task-specific target language: ${preference.targetLanguage}.`,\n    \"Use this language for generated artifacts (translation, summaries, etc.).\",\n    \"Surrounding explanations and progress still use replyLanguage.\",\n    \"Do not translate code, commands, identifiers, file paths, or quoted source text.\",\n  ].join(\"\\n\");\n}\n\n/**\n * @deprecated Prefer buildResponseLocaleSystemContext — policy belongs in system context.\n */\nexport function buildResponseLocalePrependContext(\n  preference: ResponseLocalePreference,\n): string {\n  return buildResponseLocaleSystemContext(preference);\n}\n",
    "import { existsSync, rmSync } from \"node:fs\";\nimport type { CliCommand } from \"./helpers.js\";\nimport { output } from \"./helpers.js\";\nimport {\n  credentialsPath,\n  loadApiKey,\n  readCredentials,\n  writeSingleApiKey,\n  writeCredentials,\n} from \"../auth/credentials.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerAuthCli(program: CliCommand): void {\n  const auth = program\n    .command(\"auth\")\n    .description(t(\"cli.auth.description\"));\n\n  auth\n    .command(\"set-api-key <apiKey>\")\n    .description(t(\"cli.auth.set_api_key.description\"))\n    .action((apiKey: string) => {\n      writeSingleApiKey(apiKey);\n      output({\n        ok: true,\n        apiKey: apiKey.slice(0, 8) + \"…\",\n        storedAt: credentialsPath(),\n      });\n    });\n\n  // 兼容旧命令：set-token <token>，现在等价于 set-api-key\n  auth\n    .command(\"set-token <token>\")\n    .description(t(\"cli.auth.set_token.description\"))\n    .action((token: string) => {\n      writeSingleApiKey(token);\n      output({\n        ok: true,\n        apiKey: token.slice(0, 8) + \"…\",\n        storedAt: credentialsPath(),\n      });\n    });\n\n  auth\n    .command(\"show\")\n    .description(t(\"cli.auth.status.description\"))\n    .action(() => {\n      const apiKey = loadApiKey();\n      if (apiKey) {\n        output({\n          ok: true,\n          hasApiKey: true,\n          apiKey: apiKey.slice(0, 8) + \"…\",\n          storedAt: credentialsPath(),\n        });\n      } else {\n        output({ ok: true, hasApiKey: false });\n      }\n    });\n\n  auth\n    .command(\"clear\")\n    .description(t(\"cli.auth.clear.description\"))\n    .action(() => {\n      const path = credentialsPath();\n      if (existsSync(path)) {\n        const creds = readCredentials();\n        delete creds.apiKey;\n        delete creds.apiKeys;\n        delete creds.token;\n        if (Object.keys(creds).length === 0) {\n          rmSync(path, { force: true });\n        } else {\n          writeCredentials(creds);\n        }\n      }\n      output({ ok: true, cleared: true });\n    });\n}\n",
    "import { existsSync, readFileSync, readdirSync, mkdirSync } from \"node:fs\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { join, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { StoredNotification } from \"../notification/storage.js\";\nimport { lookupAppDisplayName } from \"../notification/app-name-map.js\";\nimport { t, tError } from \"../i18n/index.js\";\nimport { sortRecordingsByEffectiveTime } from \"../recording/time.js\";\n\n/**\n * Minimal Commander.js Command interface.\n * The real `Command` instance comes from the openclaw runtime at registration time;\n * we only declare the subset we use so that `commander` need not be a direct dep.\n */\nexport interface CliCommand {\n  command(nameAndArgs: string): CliCommand;\n  description(str: string): CliCommand;\n  version(str: string, flags?: string, description?: string): CliCommand;\n  option(flags: string, description: string, defaultValue?: string): CliCommand;\n  requiredOption(flags: string, description: string): CliCommand;\n  action(fn: (...args: any[]) => void | Promise<void>): CliCommand;\n}\n\nexport interface CliContext {\n  workspaceDir?: string;\n  stateDir?: string;\n  /** 当前加载的 phone-notifications 插件包根目录（包含 skills/）。 */\n  pluginInstallDir?: string;\n}\n\n/** Resolve the notifications storage directory (stateDir → workspace fallback) */\nexport function resolveNotificationsDir(ctx: CliContext): string | null {\n  if (ctx.stateDir) {\n    const dir = join(\n      ctx.stateDir,\n      \"plugins\",\n      \"phone-notifications\",\n      \"notifications\",\n    );\n    if (existsSync(dir)) return dir;\n  }\n  if (ctx.workspaceDir) {\n    const dir = join(ctx.workspaceDir, \"notifications\");\n    if (existsSync(dir)) return dir;\n  }\n  return null;\n}\n\n/** List available date keys (YYYY-MM-DD) sorted descending */\nexport function listDateKeys(dir: string): string[] {\n  const pattern = /^(\\d{4}-\\d{2}-\\d{2})\\.json$/;\n  const keys: string[] = [];\n  for (const entry of readdirSync(dir, { withFileTypes: true })) {\n    if (!entry.isFile()) continue;\n    const m = pattern.exec(entry.name);\n    if (m) keys.push(m[1]);\n  }\n  return keys.sort().reverse();\n}\n\n/** Read notifications for a specific date */\nexport function readDateFile(\n  dir: string,\n  dateKey: string,\n): StoredNotification[] {\n  const filePath = join(dir, `${dateKey}.json`);\n  if (!existsSync(filePath)) return [];\n  try {\n    return JSON.parse(readFileSync(filePath, \"utf-8\"));\n  } catch {\n    return [];\n  }\n}\n\n/** Format today as YYYY-MM-DD */\nexport function today(): string {\n  return formatDate(new Date());\n}\n\n/** Format a Date as YYYY-MM-DD */\nexport function formatDate(d: Date): string {\n  const y = d.getFullYear();\n  const m = String(d.getMonth() + 1).padStart(2, \"0\");\n  const day = String(d.getDate()).padStart(2, \"0\");\n  return `${y}-${m}-${day}`;\n}\n\n/** Get date N days ago as YYYY-MM-DD */\nexport function daysAgo(n: number): string {\n  const d = new Date();\n  d.setDate(d.getDate() - n);\n  return formatDate(d);\n}\n\n/** Filter date keys to a [from, to] range (inclusive) */\nexport function filterDateRange(\n  keys: string[],\n  from: string,\n  to: string,\n): string[] {\n  return keys.filter((k) => k >= from && k <= to);\n}\n\n/** Parse an ISO 8601 timestamp and exit with a CLI error on invalid input */\nexport function parseIsoTime(\n  value: string,\n  optionName: \"--from\" | \"--to\",\n): number {\n  const isoPattern =\n    /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,3})?)?(Z|[+-]\\d{2}:\\d{2})$/;\n  if (!isoPattern.test(value)) {\n    exitError(\n      \"INVALID_TIME\",\n      t(\"errors.INVALID_TIME\", {\n        option: optionName,\n        example: \"2026-03-01T09:00:00+08:00\",\n      }),\n    );\n  }\n\n  const ts = Date.parse(value);\n  if (Number.isNaN(ts)) {\n    exitError(\n      \"INVALID_TIME\",\n      t(\"errors.INVALID_TIME_INVALID\", {\n        option: optionName,\n        example: \"2026-03-01T09:00:00+08:00\",\n      }),\n    );\n  }\n  return ts;\n}\n\n/** Sort notifications by timestamp descending (newest first) */\nexport function sortNotificationsByTimestampDesc(\n  items: StoredNotification[],\n): StoredNotification[] {\n  return items.sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp));\n}\n\nconst APP_ALIAS_GROUPS = [\n  [\"微信\", \"wechat\", \"weixin\", \"com.tencent.mm\", \"com.tencent.xin\"],\n  [\"企业微信\", \"wecom\", \"wxwork\", \"com.tencent.wework\"],\n  [\"飞书\", \"feishu\", \"lark\", \"com.ss.android.lark\", \"com.bytedance.ee.lark\", \"com.larksuite.suite\"],\n  [\"钉钉\", \"dingtalk\", \"com.alibaba.android.rimet\"],\n  [\"qq\", \"腾讯qq\", \"com.tencent.mobileqq\"],\n];\n\nfunction normalizeLookupText(value: string): string {\n  return value.trim().toLowerCase();\n}\n\nfunction appAliasGroup(value: string): string[] | null {\n  const normalized = normalizeLookupText(value);\n  if (!normalized) return null;\n  return APP_ALIAS_GROUPS.find((group) =>\n    group.some((candidate) => normalizeLookupText(candidate) === normalized),\n  ) ?? null;\n}\n\nexport function matchesNotificationAppFilter(\n  item: StoredNotification,\n  app: string,\n): boolean {\n  const filter = normalizeLookupText(app);\n  if (!filter) return true;\n\n  const candidates = [item.appName, item.appDisplayName, lookupAppDisplayName(item.appName)]\n    .filter((value): value is string => typeof value === \"string\" && value.length > 0);\n  if (candidates.some((candidate) => normalizeLookupText(candidate) === filter)) {\n    return true;\n  }\n\n  const filterGroup = appAliasGroup(app);\n  if (!filterGroup) return false;\n  return candidates.some((candidate) => appAliasGroup(candidate) === filterGroup);\n}\n\n/** Async version of listDateKeys */\nexport async function listDateKeysAsync(dir: string): Promise<string[]> {\n  const pattern = /^(\\d{4}-\\d{2}-\\d{2})\\.json$/;\n  const keys: string[] = [];\n  const entries = await readdir(dir, { withFileTypes: true });\n  for (const entry of entries) {\n    if (!entry.isFile()) continue;\n    const m = pattern.exec(entry.name);\n    if (m) keys.push(m[1]);\n  }\n  return keys.sort().reverse();\n}\n\n/** Async version of readDateFile */\nexport async function readDateFileAsync(\n  dir: string,\n  dateKey: string,\n): Promise<StoredNotification[]> {\n  const filePath = join(dir, `${dateKey}.json`);\n  if (!existsSync(filePath)) return [];\n  try {\n    const content = await readFile(filePath, \"utf-8\");\n    return JSON.parse(content);\n  } catch {\n    return [];\n  }\n}\n\n/** Write progress message to stderr (visible to caller, won't pollute JSON stdout) */\nexport function progress(message: string): void {\n  process.stderr.write(message + \"\\n\");\n}\n\n/** Print JSON result to stdout */\nexport function output(data: unknown): void {\n  process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\n/** Print error JSON and exit with code 1.\n *  - exitError(\"NO_DATA\", { date }) → 查 i18n\n *  - exitError(\"NO_DATA\", t(\"…\"), ) → 显式文案\n *  - exitError(\"STORAGE_UNAVAILABLE\") → tError(code)\n */\nexport function exitError(\n  code: string,\n  messageOrParams?: string | Record<string, string | number>,\n  params?: Record<string, string | number>,\n): never {\n  const resolved =\n    typeof messageOrParams === \"object\"\n      ? tError(code, messageOrParams)\n      : (messageOrParams ?? tError(code, params));\n  output({ ok: false, error: { code, message: resolved } });\n  process.exit(1);\n}\n\nexport function exitStorageUnavailable(\n  kind: \"notifications\" | \"images\" | \"recordings\" | \"web-pages\",\n): never {\n  const key =\n    kind === \"notifications\"\n      ? \"errors.STORAGE_UNAVAILABLE.notifications\"\n      : kind === \"images\"\n        ? \"errors.STORAGE_UNAVAILABLE.images\"\n        : kind === \"recordings\"\n          ? \"errors.STORAGE_UNAVAILABLE.recordings\"\n          : \"errors.STORAGE_UNAVAILABLE.web_pages\";\n  exitError(\"STORAGE_UNAVAILABLE\", t(key));\n}\n\n/** Resolve the recordings storage directory (stateDir → workspace fallback) */\nexport function resolveRecordingsDir(ctx: CliContext): string | null {\n  if (ctx.stateDir) {\n    const dir = join(\n      ctx.stateDir,\n      \"plugins\",\n      \"phone-notifications\",\n      \"recordings\",\n    );\n    if (existsSync(dir)) return dir;\n  }\n  if (ctx.workspaceDir) {\n    const dir = join(ctx.workspaceDir, \"recordings\");\n    if (existsSync(dir)) return dir;\n  }\n  return null;\n}\n\n/** Recording index entry (mirrors RecordingIndexEntry from storage.ts) */\nexport interface CliRecordingEntry {\n  id: string;\n  clientLabel?: string;\n  metadata: {\n    name: string;\n    duration_sec: number;\n    duration_display: string;\n    file_size_display?: string;\n    created_at: string;\n    transfer_status: string;\n    [key: string]: unknown;\n  };\n  status: string;\n  audioStatus?: \"pending\" | \"downloading\" | \"downloaded\" | \"failed\";\n  audioSourceUrl?: string;\n  audioFile?: string;\n  srtFile?: string;\n  transcriptDataFile?: string;\n  transcriptFile?: string;\n  summaryFile?: string;\n  title?: string;\n  lastError?: string;\n  ingestedAt: string;\n  updatedAt: string;\n}\n\n/** Resolve the asr-config.json path; creates parent dirs if needed */\nexport function resolveAsrConfigPath(ctx: CliContext): string {\n  let base: string;\n  if (ctx.stateDir) {\n    base = join(ctx.stateDir, \"plugins\", \"phone-notifications\", \"recordings\");\n  } else if (ctx.workspaceDir) {\n    base = join(ctx.workspaceDir, \"recordings\");\n  } else {\n    exitError(\n      \"STORAGE_UNAVAILABLE\",\n      t(\"errors.STORAGE_UNAVAILABLE\"),\n    );\n  }\n  mkdirSync(base, { recursive: true });\n  return join(base, \"asr-config.json\");\n}\n\n/** Mask an API key, keeping first 4 and last 4 chars */\nexport function maskApiKey(key: string): string {\n  if (key.length <= 8) return \"***\";\n  return `${key.slice(0, 4)}***${key.slice(-4)}`;\n}\n\n/** Read recording index.json */\nexport function readRecordingIndex(\n  dir: string,\n): CliRecordingEntry[] {\n  const indexPath = join(dir, \"index.json\");\n  if (!existsSync(indexPath)) return [];\n  try {\n    const raw = JSON.parse(readFileSync(indexPath, \"utf-8\"));\n    const recordings: CliRecordingEntry[] = Array.isArray(raw?.recordings)\n      ? raw.recordings\n      : [];\n    return sortRecordingsByEffectiveTime(recordings);\n  } catch {\n    return [];\n  }\n}\n\n/** Resolve the images storage directory (stateDir → workspace fallback) */\nexport function resolveImagesDir(ctx: CliContext): string | null {\n  if (ctx.stateDir) {\n    const dir = join(\n      ctx.stateDir,\n      \"plugins\",\n      \"phone-notifications\",\n      \"images\",\n    );\n    if (existsSync(dir)) return dir;\n  }\n  if (ctx.workspaceDir) {\n    const dir = join(ctx.workspaceDir, \"images\");\n    if (existsSync(dir)) return dir;\n  }\n  return null;\n}\n\n/** Image index entry (mirrors ImageIndexEntry from image/store.ts) */\nexport interface CliImageEntry {\n  imageId: string;\n  clientLabel?: string;\n  metadata: {\n    oss_image_url: string;\n    created_at: string;\n    mime_type?: string;\n    width?: number;\n    height?: number;\n    size_bytes?: number;\n    source_app?: string;\n    caption?: string;\n    [key: string]: unknown;\n  };\n  localFile?: string;\n  thumbnail?: string;\n  status: string;\n  lastError?: string;\n  syncedAt?: string;\n}\n\n/** Read image index.json (sorted by created_at desc) */\nexport function readImageIndex(dir: string): CliImageEntry[] {\n  const indexPath = join(dir, \"index.json\");\n  if (!existsSync(indexPath)) return [];\n  try {\n    const raw = JSON.parse(readFileSync(indexPath, \"utf-8\"));\n    const images: CliImageEntry[] = Array.isArray(raw?.images) ? raw.images : [];\n    return images.sort((a, b) =>\n      b.metadata.created_at.localeCompare(a.metadata.created_at),\n    );\n  } catch {\n    return [];\n  }\n}\n\n/** Resolve an image's stored file to an absolute path */\nexport function resolveImageFile(dir: string, relative: string): string {\n  return isAbsolute(relative) ? relative : join(dir, relative);\n}\n\n/** Resolve the captured web-pages storage directory (stateDir → workspace fallback) */\nexport function resolveWebPagesDir(ctx: CliContext): string | null {\n  if (ctx.stateDir) {\n    const dir = join(\n      ctx.stateDir,\n      \"plugins\",\n      \"phone-notifications\",\n      \"web-pages\",\n    );\n    if (existsSync(dir)) return dir;\n  }\n  if (ctx.workspaceDir) {\n    const dir = join(ctx.workspaceDir, \"web-pages\");\n    if (existsSync(dir)) return dir;\n  }\n  return null;\n}\n\n/** Web-page index entry (mirrors WebPageIndexEntry from web-page/types.ts) */\nexport interface CliWebPageEntry {\n  urlHash: string;\n  canonicalUrl: string;\n  url?: string;\n  title: string;\n  siteName?: string;\n  relativePath: string;\n  capturedAt: string;\n  firstCapturedAt: string;\n  captureCount: number;\n  contentHash?: string;\n  bytes: number;\n  clientLabel?: string;\n  archivePath?: string;\n  archiveBytes?: number;\n}\n\n/** Read web-page index.json (sorted by capturedAt desc) */\nexport function readWebPageIndex(dir: string): CliWebPageEntry[] {\n  const indexPath = join(dir, \"index.json\");\n  if (!existsSync(indexPath)) return [];\n  try {\n    const raw = JSON.parse(readFileSync(indexPath, \"utf-8\"));\n    const pages: CliWebPageEntry[] = Array.isArray(raw?.pages) ? raw.pages : [];\n    return pages.sort((a, b) => b.capturedAt.localeCompare(a.capturedAt));\n  } catch {\n    return [];\n  }\n}\n\n/**\n * Resolve an indexed web-page file while keeping it inside the storage root.\n * Web-page index paths are always relative; reject hand-edited absolute/parent paths.\n */\nexport function resolveWebPageFile(\n  dir: string,\n  relativePath: string,\n): string | null {\n  if (!relativePath || isAbsolute(relativePath)) return null;\n  const resolved = resolve(dir, relativePath);\n  const rel = relative(resolve(dir), resolved);\n  if (!rel || rel === \"..\" || rel.startsWith(`..${sep}`)) {\n    return null;\n  }\n  return resolved;\n}\n",
    "import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getAcceptLanguage, type AcceptLanguage } from \"../i18n/index.js\";\n\n/** 随代码分发的内置映射快照（发版前用 scripts/sync-app-name-map.ts 刷新） */\nconst DATA_FILE = \"app-name-map.data.json\";\n\ninterface Logger {\n  info: (message: string) => void;\n  warn: (message: string) => void;\n}\n\n/** 双语显示名（任一语言可缺） */\nexport interface LocalizedAppNames {\n  zh?: string;\n  en?: string;\n}\n\nfunction nonEmptyString(v: unknown): string | undefined {\n  if (typeof v !== \"string\") return undefined;\n  const trimmed = v.trim();\n  return trimmed ? trimmed : undefined;\n}\n\n/**\n * 按当前语言选显示名：\n * - zh: appName → appNameEn → packageName\n * - en: appNameEn → appName → packageName\n */\nexport function pickDisplayName(\n  names: LocalizedAppNames,\n  packageName: string,\n  lang: AcceptLanguage = getAcceptLanguage(),\n): string {\n  if (lang === \"en\") {\n    return names.en || names.zh || packageName;\n  }\n  return names.zh || names.en || packageName;\n}\n\nfunction parseEntry(value: unknown): LocalizedAppNames | null {\n  if (typeof value === \"string\") {\n    const zh = nonEmptyString(value);\n    return zh ? { zh } : null;\n  }\n  if (value === null || typeof value !== \"object\") return null;\n  const o = value as Record<string, unknown>;\n  const zh = nonEmptyString(o.zh);\n  const en = nonEmptyString(o.en);\n  if (!zh && !en) return null;\n  return {\n    ...(zh ? { zh } : {}),\n    ...(en ? { en } : {}),\n  };\n}\n\n// 打包后 index.cjs 位于 <installDir>/dist、ntf.cjs 位于 <installDir>/dist/bin，\n// 快照统一放 <installDir>/dist 下；源码/vitest 下则与本文件同目录。\n// 与 src/index.ts 一致：bun 注入的 `var __dirname` 已由 scripts/build.ts 后处理删除。\ndeclare const __dirname: string;\n\nfunction snapshotCandidates(): string[] {\n  const paths: string[] = [];\n  // 显式指定路径时视为唯一来源：读不出来就退化为包名，不再悄悄回落到内置快照\n  const override = nonEmptyString(process.env.APP_NAME_MAP_DATA_FILE);\n  if (override) return [override];\n  if (typeof __dirname === \"string\" && __dirname) {\n    paths.push(join(__dirname, DATA_FILE));\n    paths.push(join(__dirname, \"..\", DATA_FILE));\n  }\n  try {\n    paths.push(new URL(DATA_FILE, import.meta.url).pathname);\n  } catch {\n    /* CJS 产物里没有可用的 import.meta.url，忽略 */\n  }\n  return paths;\n}\n\nlet snapshot: Map<string, LocalizedAppNames> | null = null;\nlet snapshotPath: string | null = null;\n\nfunction loadSnapshot(): Map<string, LocalizedAppNames> {\n  if (snapshot) return snapshot;\n  const map = new Map<string, LocalizedAppNames>();\n  for (const path of snapshotCandidates()) {\n    if (!existsSync(path)) continue;\n    try {\n      const raw = JSON.parse(readFileSync(path, \"utf-8\")) as unknown;\n      if (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) continue;\n      for (const [packageName, value] of Object.entries(raw)) {\n        const names = parseEntry(value);\n        if (names) map.set(packageName, names);\n      }\n      snapshotPath = path;\n      break;\n    } catch {\n      /* 快照损坏时退化为空映射，显示名回落到包名 */\n    }\n  }\n  snapshot = map;\n  return map;\n}\n\n/** 仅供测试：丢弃已加载的快照，下次访问重新读盘 */\nexport function resetAppNameMapForTest(): void {\n  snapshot = null;\n  snapshotPath = null;\n}\n\n/** 已加载的快照条目数（未加载时触发加载） */\nexport function appNameMapSize(): number {\n  return loadSnapshot().size;\n}\n\n/** 命中返回显示名，未命中返回 undefined */\nexport function lookupAppDisplayName(\n  packageName: string,\n  lang: AcceptLanguage = getAcceptLanguage(),\n): string | undefined {\n  const key = packageName?.trim();\n  if (!key) return undefined;\n  const names = loadSnapshot().get(key);\n  return names ? pickDisplayName(names, key, lang) : undefined;\n}\n\n/** 命中返回显示名，未命中返回包名本身 */\nexport function resolveAppDisplayName(\n  packageName: string,\n  lang: AcceptLanguage = getAcceptLanguage(),\n): string {\n  return lookupAppDisplayName(packageName, lang) ?? packageName;\n}\n\n/**\n * 展示期解析：内置快照优先于落库时固化的 appDisplayName。\n * 这样升级插件带来的新映射能直接修正历史通知的展示，无需回填数据。\n */\nexport function preferAppDisplayName(\n  appName: string,\n  storedDisplayName?: string,\n): string {\n  return (\n    lookupAppDisplayName(appName)\n    ?? nonEmptyString(storedDisplayName)\n    ?? appName.trim()\n  );\n}\n\nexport interface AppNameMapProvider {\n  /** 解析包名为显示名（无网络请求，只查内置快照） */\n  resolveDisplayName(packageName: string): Promise<string>;\n  start(): Promise<void>;\n  stop(): void;\n}\n\n/**\n * 映射随代码分发，provider 只剩「加载快照 + 提供查询」：\n * 没有定时刷新、没有服务端请求、没有本地缓存写入。\n */\nexport function createAppNameMapProvider(opts: {\n  logger: Logger;\n}): AppNameMapProvider {\n  const { logger } = opts;\n\n  return {\n    async resolveDisplayName(packageName: string): Promise<string> {\n      return resolveAppDisplayName(packageName);\n    },\n\n    async start(): Promise<void> {\n      const size = loadSnapshot().size;\n      if (size > 0) {\n        logger.info(`[app-name-map] loaded ${size} bundled entries: ${snapshotPath}`);\n      } else {\n        logger.warn(\n          `[app-name-map] bundled snapshot not found or empty, display names fall back to package names`,\n        );\n      }\n    },\n\n    stop(): void {\n      /* 无定时器/监听需要清理；快照常驻进程内存 */\n    },\n  };\n}\n",
    "export interface RecordingTimeFields {\n  metadata?: {\n    created_at?: unknown;\n  };\n  ingestedAt?: unknown;\n  updatedAt?: unknown;\n}\n\nexport function parseRecordingTimestamp(value: unknown): number | undefined {\n  if (typeof value !== \"string\" || !value.trim()) {\n    return undefined;\n  }\n  const normalized = value.trim();\n  const dateOnly = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(normalized);\n  if (dateOnly) {\n    const year = Number(dateOnly[1]);\n    const month = Number(dateOnly[2]);\n    const day = Number(dateOnly[3]);\n    const local = new Date(year, month - 1, day);\n    if (\n      local.getFullYear() !== year ||\n      local.getMonth() !== month - 1 ||\n      local.getDate() !== day\n    ) {\n      return undefined;\n    }\n    return local.getTime();\n  }\n  const parsed = Date.parse(normalized);\n  return Number.isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * Resolve the best available recording time as an absolute instant.\n *\n * created_at is the capture time. Older or partially written entries may not\n * have it, so ingestion/update timestamps are used only as fallbacks.\n */\nexport function recordingEffectiveTime(entry: RecordingTimeFields): number {\n  for (const value of [\n    entry.metadata?.created_at,\n    entry.ingestedAt,\n    entry.updatedAt,\n  ]) {\n    const parsed = parseRecordingTimestamp(value);\n    if (parsed !== undefined) {\n      return parsed;\n    }\n  }\n  return Number.NEGATIVE_INFINITY;\n}\n\n/** Return a stable newest-first copy, comparing parsed instants rather than text. */\nexport function sortRecordingsByEffectiveTime<T extends RecordingTimeFields>(\n  entries: readonly T[],\n): T[] {\n  return entries\n    .map((entry, index) => ({ entry, index }))\n    .sort(\n      (a, b) =>\n        recordingEffectiveTime(b.entry) - recordingEffectiveTime(a.entry) ||\n        a.index - b.index,\n    )\n    .map(({ entry }) => entry);\n}\n",
    "import type { StoredNotification } from \"../notification/storage.js\";\nimport {\n  exitError,\n  listDateKeysAsync,\n  parseIsoTime,\n  readDateFileAsync,\n  sortNotificationsByTimestampDesc,\n  matchesNotificationAppFilter,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport interface RawNotificationQueryOptions {\n  from?: string;\n  to?: string;\n  app?: string;\n  sender?: string;\n  conversationType?: string;\n  keyword?: string;\n  limit?: string;\n  client?: string;\n}\n\nexport interface NotificationQueryOptions {\n  from?: string;\n  to?: string;\n  app?: string;\n  sender?: string;\n  conversationType?: string;\n  keyword?: string;\n  client?: string;\n  limit: number;\n  fromTs: number | null;\n  toTs: number | null;\n  fromDateKey: string | null;\n  toDateKey: string | null;\n}\n\nexport interface NotificationQueryStats {\n  daysScanned: number;\n  itemsScanned: number;\n  matched: number;\n  stoppedAfterLimit: boolean;\n}\n\nexport interface NotificationQueryResult {\n  notifications: StoredNotification[];\n  stats: NotificationQueryStats;\n}\n\nexport function parsePositiveIntegerOption(\n  rawValue: string | undefined,\n  defaultValue: number,\n  optionName: string,\n  errorCode: string,\n): number {\n  const value = rawValue && rawValue.length > 0 ? rawValue : String(defaultValue);\n  if (!/^\\d+$/.test(value)) {\n    exitError(errorCode, t(\"errors.INVALID_POSITIVE_INT\", { option: optionName }));\n  }\n\n  const parsed = Number.parseInt(value, 10);\n  if (parsed <= 0) {\n    exitError(errorCode, t(\"errors.INVALID_POSITIVE_INT\", { option: optionName }));\n  }\n  return parsed;\n}\n\nexport function parseNotificationQueryOptions(\n  opts: RawNotificationQueryOptions,\n  defaultLimit = 100,\n): NotificationQueryOptions {\n  const limit = parsePositiveIntegerOption(\n    opts.limit,\n    defaultLimit,\n    \"--limit\",\n    \"INVALID_LIMIT\",\n  );\n\n  if (\n    opts.conversationType\n    && opts.conversationType !== \"group\"\n    && opts.conversationType !== \"private\"\n  ) {\n    exitError(\"INVALID_CONVERSATION_TYPE\");\n  }\n\n  const hasFrom = typeof opts.from === \"string\" && opts.from.length > 0;\n  const hasTo = typeof opts.to === \"string\" && opts.to.length > 0;\n  const fromTs = hasFrom ? parseIsoTime(opts.from!, \"--from\") : null;\n  const toTs = hasTo ? parseIsoTime(opts.to!, \"--to\") : null;\n\n  if (fromTs !== null && toTs !== null && fromTs > toTs) {\n    exitError(\"INVALID_TIME_RANGE\");\n  }\n\n  return {\n    from: opts.from,\n    to: opts.to,\n    app: opts.app,\n    sender: opts.sender,\n    conversationType: opts.conversationType,\n    keyword: opts.keyword,\n    client: opts.client,\n    limit,\n    fromTs,\n    toTs,\n    fromDateKey: hasFrom ? opts.from!.slice(0, 10) : null,\n    toDateKey: hasTo ? opts.to!.slice(0, 10) : null,\n  };\n}\n\nexport function matchesNotificationQuery(\n  item: StoredNotification,\n  opts: NotificationQueryOptions,\n): boolean {\n  if (opts.client && opts.client !== \"all\") {\n    const label = item.clientLabel ?? \"legacy\";\n    if (label !== opts.client) return false;\n  }\n  if (opts.app && !matchesNotificationAppFilter(item, opts.app)) return false;\n  if (\n    opts.conversationType\n    && item.conversationType !== opts.conversationType\n  ) {\n    return false;\n  }\n\n  const senderHaystack = [item.senderName, item.title]\n    .filter((value): value is string => typeof value === \"string\" && value.length > 0)\n    .join(\"\\n\");\n  if (opts.sender && !senderHaystack.includes(opts.sender)) return false;\n\n  const keywordHaystack = [\n    item.title,\n    item.content,\n    item.senderName,\n    item.conversationName,\n  ]\n    .filter((value): value is string => typeof value === \"string\" && value.length > 0)\n    .join(\"\\n\");\n  if (opts.keyword && !keywordHaystack.includes(opts.keyword)) return false;\n\n  const itemTs = Date.parse(item.timestamp);\n  if (Number.isNaN(itemTs)) return false;\n  if (opts.fromTs !== null && itemTs < opts.fromTs) return false;\n  if (opts.toTs !== null && itemTs > opts.toTs) return false;\n\n  return true;\n}\n\nexport async function collectMatchingNotifications(\n  dir: string,\n  opts: NotificationQueryOptions,\n): Promise<StoredNotification[]> {\n  const result = await collectMatchingNotificationsWithStats(dir, opts);\n  return result.notifications;\n}\n\nexport async function collectMatchingNotificationsWithStats(\n  dir: string,\n  opts: NotificationQueryOptions,\n): Promise<NotificationQueryResult> {\n  const keys = await listDateKeysAsync(dir);\n  const results: StoredNotification[] = [];\n  const stats: NotificationQueryStats = {\n    daysScanned: 0,\n    itemsScanned: 0,\n    matched: 0,\n    stoppedAfterLimit: false,\n  };\n\n  for (const dateKey of keys) {\n    if (opts.fromDateKey && dateKey < opts.fromDateKey) continue;\n    if (opts.toDateKey && dateKey > opts.toDateKey) continue;\n\n    stats.daysScanned += 1;\n    const items = sortNotificationsByTimestampDesc([\n      ...(await readDateFileAsync(dir, dateKey)),\n    ]);\n    for (const item of items) {\n      stats.itemsScanned += 1;\n      if (!matchesNotificationQuery(item, opts)) continue;\n      stats.matched += 1;\n      results.push(item);\n      if (results.length >= opts.limit) {\n        stats.stoppedAfterLimit = true;\n        return { notifications: results, stats };\n      }\n    }\n  }\n\n  return {\n    notifications: sortNotificationsByTimestampDesc(results).slice(0, opts.limit),\n    stats,\n  };\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveNotificationsDir,\n  output,\n  progress,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport {\n  collectMatchingNotifications,\n  parseNotificationQueryOptions,\n} from \"./ntf-query.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerNtfSearch(ntf: CliCommand, ctx: CliContext): void {\n  ntf\n    .command(\"search\")\n    .description(t(\"cli.search.description\"))\n    .option(\"--from <time>\", t(\"cli.opt.from_time\"))\n    .option(\"--to <time>\", t(\"cli.opt.to_time\"))\n    .option(\"--app <name>\", t(\"cli.opt.app\"))\n    .option(\"--sender <name>\", t(\"cli.opt.sender\"))\n    .option(\"--conversation-type <type>\", t(\"cli.opt.conversation_type\"))\n    .option(\"--keyword <text>\", t(\"cli.opt.keyword\"))\n    .option(\"--limit <n>\", t(\"cli.search.opt.limit\"), \"100\")\n    .action(\n      async (opts: {\n        from?: string;\n        to?: string;\n        app?: string;\n        sender?: string;\n        conversationType?: string;\n        keyword?: string;\n        limit: string;\n      }) => {\n        const dir = resolveNotificationsDir(ctx);\n        if (!dir) exitStorageUnavailable(\"notifications\");\n\n        progress(t(\"progress.searching\"));\n\n        const query = parseNotificationQueryOptions(opts);\n        const notifications = await collectMatchingNotifications(dir, query);\n\n        output({\n          ok: true,\n          total: notifications.length,\n          notifications\n});\n      },\n    );\n}\n",
    "import type { StoredNotification } from \"../notification/storage.js\";\nimport {\n  type CliCommand,\n  type CliContext,\n  exitError,\n  output,\n  progress,\n  resolveNotificationsDir,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport {\n  collectMatchingNotificationsWithStats,\n  parseNotificationQueryOptions,\n  parsePositiveIntegerOption,\n} from \"./ntf-query.js\";\nimport { t } from \"../i18n/index.js\";\nimport { preferAppDisplayName } from \"../notification/app-name-map.js\";\n\ntype CountRow<T extends Record<string, unknown>> = T & { count: number };\n\ninterface CompactNotification {\n  appName: string;\n  appDisplayName?: string;\n  title: string;\n  content: string;\n  timestamp: string;\n  senderName?: string;\n  conversationType?: string;\n  conversationName?: string;\n}\n\nfunction compactNotification(\n  item: StoredNotification,\n  maxContent: number,\n): CompactNotification {\n  const result: CompactNotification = {\n    appName: item.appName,\n    title: truncate(item.title, maxContent),\n    content: truncate(item.content, maxContent),\n    timestamp: item.timestamp\n};\n  // 样例条目同样按当前快照解析，避免把落库时的旧显示名喂给 Agent\n  const appDisplayName = preferAppDisplayName(item.appName, item.appDisplayName);\n  if (appDisplayName !== item.appName) result.appDisplayName = appDisplayName;\n  if (item.senderName) result.senderName = item.senderName;\n  if (item.conversationType) result.conversationType = item.conversationType;\n  if (item.conversationName) result.conversationName = item.conversationName;\n  return result;\n}\n\nfunction truncate(value: string, maxLength = 120): string {\n  if (value.length <= maxLength) return value;\n  return `${value.slice(0, maxLength - 1)}…`;\n}\n\nfunction increment<T extends Record<string, unknown>>(\n  map: Map<string, CountRow<T>>,\n  key: string,\n  seed: T,\n): void {\n  const existing = map.get(key);\n  if (existing) {\n    existing.count += 1;\n    return;\n  }\n  map.set(key, { ...seed, count: 1 });\n}\n\nfunction topRows<T extends Record<string, unknown>>(\n  map: Map<string, CountRow<T>>,\n  limit: number,\n): CountRow<T>[] {\n  return [...map.values()].sort((a, b) => b.count - a.count).slice(0, limit);\n}\n\nfunction hourBucket(timestamp: string): string | null {\n  const match = /^(\\d{4}-\\d{2}-\\d{2})T(\\d{2}):/.exec(timestamp);\n  if (!match) return null;\n  return `${match[1]} ${match[2]}:00`;\n}\n\nfunction buildSamplesBySender(\n  notifications: StoredNotification[],\n  senderRows: CountRow<{ sender: string }>[],\n  maxContent: number,\n): Array<{ sender: string; count: number; samples: string[] }> {\n  return senderRows.map((row) => {\n    const samples: string[] = [];\n    for (const item of notifications) {\n      const sender = item.senderName?.trim() || item.title?.trim() || \"(unknown)\";\n      if (sender !== row.sender) continue;\n      const content = truncate(item.content.trim(), maxContent);\n      if (content && !samples.includes(content)) samples.push(content);\n      if (samples.length >= 5) break;\n    }\n    return { sender: row.sender, count: row.count, samples };\n  });\n}\n\nexport function registerNtfSummary(ntf: CliCommand, ctx: CliContext): void {\n  ntf\n    .command(\"summary\")\n    .description(t(\"cli.summary.description\"))\n    .option(\"--from <time>\", t(\"cli.opt.from_time\"))\n    .option(\"--to <time>\", t(\"cli.opt.to_time\"))\n    .option(\"--app <name>\", t(\"cli.opt.app\"))\n    .option(\"--sender <name>\", t(\"cli.opt.sender\"))\n    .option(\"--conversation-type <type>\", t(\"cli.opt.conversation_type\"))\n    .option(\"--keyword <text>\", t(\"cli.opt.keyword\"))\n    .option(\"--limit <n>\", t(\"cli.summary.opt.limit\"), \"100\")\n    .option(\"--sample <n>\", t(\"cli.summary.opt.sample\"), \"20\")\n    .option(\"--top <n>\", t(\"cli.summary.opt.top\"), \"10\")\n    .option(\"--max-content <n>\", t(\"cli.summary.opt.max_content\"), \"80\")\n    .action(\n      async (opts: {\n        from?: string;\n        to?: string;\n        app?: string;\n        sender?: string;\n        conversationType?: string;\n        keyword?: string;\n        limit: string;\n        sample: string;\n        top: string;\n        maxContent: string;\n      }) => {\n        const dir = resolveNotificationsDir(ctx);\n        if (!dir) exitStorageUnavailable(\"notifications\");\n\n        progress(t(\"progress.summary\"));\n\n        const query = parseNotificationQueryOptions(opts);\n        const sampleLimit = parsePositiveIntegerOption(\n          opts.sample,\n          30,\n          \"--sample\",\n          \"INVALID_SAMPLE\",\n        );\n        const topLimit = parsePositiveIntegerOption(\n          opts.top,\n          10,\n          \"--top\",\n          \"INVALID_TOP\",\n        );\n        const maxContent = parsePositiveIntegerOption(\n          opts.maxContent,\n          80,\n          \"--max-content\",\n          \"INVALID_MAX_CONTENT\",\n        );\n\n        const startedAtMs = Date.now();\n        const queryResult = await collectMatchingNotificationsWithStats(dir, query);\n        const elapsedMs = Date.now() - startedAtMs;\n        const { notifications, stats } = queryResult;\n        const byApp = new Map<\n          string,\n          CountRow<{ appName: string; appDisplayName?: string }>\n        >();\n        const bySender = new Map<string, CountRow<{ sender: string }>>();\n        const byConversation = new Map<\n          string,\n          CountRow<{ conversationName: string; conversationType?: string }>\n        >();\n        const byHour = new Map<string, CountRow<{ hour: string }>>();\n\n        for (const item of notifications) {\n          const appDisplayName = preferAppDisplayName(item.appName, item.appDisplayName);\n          const appKey = `${item.appName}\\0${appDisplayName}`;\n          increment(byApp, appKey, {\n            appName: item.appName,\n            ...(appDisplayName !== item.appName ? { appDisplayName } : {})\n});\n\n          const sender = item.senderName?.trim() || item.title?.trim() || \"(unknown)\";\n          increment(bySender, sender, { sender });\n\n          const conversationName =\n            item.conversationName?.trim() || item.title?.trim() || \"(unknown)\";\n          const conversationKey = `${conversationName}\\0${item.conversationType ?? \"\"}`;\n          increment(byConversation, conversationKey, {\n            conversationName,\n            ...(item.conversationType\n              ? { conversationType: item.conversationType }\n              : {})\n});\n\n          const hour = hourBucket(item.timestamp);\n          if (hour) increment(byHour, hour, { hour });\n        }\n\n        const senderRows = topRows(bySender, topLimit);\n        output({\n          ok: true,\n          limit: query.limit,\n          total: notifications.length,\n          range: {\n            newest: notifications[0]?.timestamp ?? null,\n            oldest: notifications[notifications.length - 1]?.timestamp ?? null\n},\n          scan: {\n            daysScanned: stats.daysScanned,\n            itemsScanned: stats.itemsScanned,\n            matched: stats.matched,\n            stoppedAfterLimit: stats.stoppedAfterLimit,\n            elapsedMs\n},\n          byApp: topRows(byApp, topLimit),\n          bySender: senderRows,\n          byConversation: topRows(byConversation, topLimit),\n          byHour: topRows(byHour, topLimit),\n          latest: notifications\n            .slice(0, sampleLimit)\n            .map((item) => compactNotification(item, maxContent)),\n          samplesBySender: buildSamplesBySender(\n            notifications,\n            senderRows,\n            maxContent,\n          )\n});\n      },\n    );\n}\n",
    "import { randomUUID } from \"node:crypto\";\nimport {\n  existsSync,\n  mkdirSync,\n  readFileSync,\n  writeFileSync,\n} from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { StoredNotification } from \"../notification/storage.js\";\nimport {\n  type CliCommand,\n  type CliContext,\n  exitError,\n  output,\n  progress,\n  resolveNotificationsDir,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport {\n  collectMatchingNotificationsWithStats,\n  parseNotificationQueryOptions,\n  parsePositiveIntegerOption,\n  type RawNotificationQueryOptions,\n} from \"./ntf-query.js\";\nimport { t } from \"../i18n/index.js\";\nimport { preferAppDisplayName } from \"../notification/app-name-map.js\";\n\ntype SummaryJobStatus =\n  | \"pending\"\n  | \"in_progress\"\n  | \"ready\"\n  | \"complete\"\n  | \"cancelled\";\n\ninterface CompactNotification {\n  appName: string;\n  appDisplayName?: string;\n  title: string;\n  content: string;\n  timestamp: string;\n  senderName?: string;\n  conversationType?: string;\n  conversationName?: string;\n}\n\ninterface SummaryJobChunk {\n  id: string;\n  index: number;\n  start: number;\n  end: number;\n  count: number;\n  status: \"pending\" | \"in_progress\" | \"done\";\n  range: {\n    newest: string | null;\n    oldest: string | null;\n  };\n  claimedAt?: string;\n  completedAt?: string;\n  summaryFile?: string;\n}\n\ninterface SummaryJobMeta {\n  schemaVersion: 1;\n  id: string;\n  status: SummaryJobStatus;\n  createdAt: string;\n  updatedAt: string;\n  query: {\n    from?: string;\n    to?: string;\n    app?: string;\n    sender?: string;\n    conversationType?: string;\n    keyword?: string;\n    limit: number;\n  };\n  chunkSize: number;\n  maxContent: number;\n  total: number;\n  range: {\n    newest: string | null;\n    oldest: string | null;\n  };\n  scan: {\n    daysScanned: number;\n    itemsScanned: number;\n    matched: number;\n    stoppedAfterLimit: boolean;\n    elapsedMs: number;\n  };\n  chunks: SummaryJobChunk[];\n  resultFile?: string;\n}\n\ninterface SummaryJobCreateOptions extends RawNotificationQueryOptions {\n  chunkSize?: string;\n  maxContent?: string;\n}\n\ninterface SummaryJobCommitOptions {\n  chunkId: string;\n  summary?: string;\n  summaryFile?: string;\n}\n\ninterface SummaryJobRunOptions {\n  maxChunks?: string;\n  includeResult?: boolean;\n}\n\ntype CountRow<T extends Record<string, unknown>> = T & { count: number };\n\nconst SUMMARY_ROOT = \".summaries\";\nconst JOBS_DIR = \"jobs\";\nconst CHUNKS_DIR = \"chunks\";\nconst SUMMARIES_DIR = \"summaries\";\nconst RESULT_FILE = \"result.md\";\nconst DEFAULT_JOB_LIMIT = 1000;\nconst DEFAULT_CHUNK_SIZE = 150;\nconst DEFAULT_MAX_CONTENT = 120;\nconst DEFAULT_RUN_MAX_CHUNKS = 20;\n\nconst ATTENTION_KEYWORDS = [\n  \"待办\",\n  \"需要\",\n  \"麻烦\",\n  \"确认\",\n  \"回复\",\n  \"审批\",\n  \"开会\",\n  \"会议\",\n  \"安排\",\n  \"截止\",\n  \"紧急\",\n  \"异常\",\n  \"失败\",\n  \"风险\",\n  \"todo\",\n  \"need\",\n  \"confirm\",\n  \"reply\",\n  \"approve\",\n  \"meeting\",\n  \"schedule\",\n  \"deadline\",\n  \"urgent\",\n  \"error\",\n  \"failed\",\n  \"risk\",\n];\n\nfunction getAttentionKeywords(): string[] {\n  return ATTENTION_KEYWORDS;\n}\n\nfunction truncate(value: string, maxLength = 120): string {\n  if (value.length <= maxLength) return value;\n  return `${value.slice(0, maxLength - 1)}…`;\n}\n\nfunction compactNotification(\n  item: StoredNotification,\n  maxContent: number,\n): CompactNotification {\n  const result: CompactNotification = {\n    appName: item.appName,\n    title: truncate(item.title, maxContent),\n    content: truncate(item.content, maxContent),\n    timestamp: item.timestamp,\n  };\n  // 样例条目同样按当前快照解析，避免把落库时的旧显示名喂给 Agent\n  const appDisplayName = preferAppDisplayName(item.appName, item.appDisplayName);\n  if (appDisplayName !== item.appName) result.appDisplayName = appDisplayName;\n  if (item.senderName) result.senderName = item.senderName;\n  if (item.conversationType) result.conversationType = item.conversationType;\n  if (item.conversationName) result.conversationName = item.conversationName;\n  return result;\n}\n\nfunction notificationSender(item: CompactNotification): string {\n  return item.senderName?.trim() || item.conversationName?.trim() || item.title.trim()\n    || \"(unknown)\";\n}\n\nfunction notificationApp(item: CompactNotification): string {\n  return preferAppDisplayName(item.appName, item.appDisplayName) || \"(unknown)\";\n}\n\nfunction increment<T extends Record<string, unknown>>(\n  map: Map<string, CountRow<T>>,\n  key: string,\n  seed: T,\n): void {\n  const existing = map.get(key);\n  if (existing) {\n    existing.count += 1;\n    return;\n  }\n  map.set(key, { ...seed, count: 1 });\n}\n\nfunction topRows<T extends Record<string, unknown>>(\n  map: Map<string, CountRow<T>>,\n  limit: number,\n): CountRow<T>[] {\n  return [...map.values()].sort((a, b) => b.count - a.count).slice(0, limit);\n}\n\nfunction formatTopRows<T extends Record<string, unknown>>(\n  rows: CountRow<T>[],\n  labelKey: keyof T,\n): string {\n  if (rows.length === 0) return t(\"summary_job.none\");\n  return rows\n    .map((row) => `${String(row[labelKey])} ${row.count}`)\n    .join(\"；\");\n}\n\nfunction compactLine(item: CompactNotification): string {\n  const app = notificationApp(item);\n  const sender = notificationSender(item);\n  return `[${item.timestamp}] ${app} · ${sender}: ${item.content}`;\n}\n\nfunction isAttentionCandidate(item: CompactNotification): boolean {\n  const text = `${item.title}\\n${item.content}`.toLowerCase();\n  return getAttentionKeywords().some((keyword) => text.includes(keyword.toLowerCase()));\n}\n\nfunction buildExtractiveChunkSummary(\n  chunk: SummaryJobChunk,\n  notifications: CompactNotification[],\n): string {\n  const byApp = new Map<string, CountRow<{ app: string }>>();\n  const bySender = new Map<string, CountRow<{ sender: string }>>();\n\n  for (const item of notifications) {\n    const app = notificationApp(item);\n    const sender = notificationSender(item);\n    increment(byApp, app, { app });\n    increment(bySender, sender, { sender });\n  }\n\n  const latest = notifications.slice(0, 5).map(compactLine);\n  const attention = notifications\n    .filter(isAttentionCandidate)\n    .slice(0, 5)\n    .map(compactLine);\n\n  const lines = [\n    t(\"summary_job.chunk_title\", { id: chunk.id }),\n    \"\",\n    t(\"summary_job.count\", { count: chunk.count }),\n    t(\"summary_job.time_range\", {\n      oldest: chunk.range.oldest ?? \"-\",\n      newest: chunk.range.newest ?? \"-\",\n    }),\n    t(\"summary_job.top_apps\", { apps: formatTopRows(topRows(byApp, 5), \"app\") }),\n    t(\"summary_job.top_senders\", {\n      senders: formatTopRows(topRows(bySender, 8), \"sender\"),\n    }),\n    \"\",\n    t(\"summary_job.attention\"),\n    ...(attention.length > 0\n      ? attention.map((line) => `- ${line}`)\n      : [t(\"summary_job.no_attention\")]),\n    \"\",\n    t(\"summary_job.recent\"),\n    ...(latest.length > 0\n      ? latest.map((line) => `- ${line}`)\n      : [t(\"summary_job.none_item\")]),\n    \"\",\n  ];\n\n  return lines.join(\"\\n\").trimEnd() + \"\\n\";\n}\n\nfunction nowIso(): string {\n  return new Date().toISOString();\n}\n\nfunction createJobId(): string {\n  const stamp = new Date()\n    .toISOString()\n    .replace(/[-:.TZ]/g, \"\")\n    .slice(0, 14);\n  return `${stamp}-${randomUUID().slice(0, 8)}`;\n}\n\nfunction assertJobId(id: string): void {\n  if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,100}$/.test(id)) {\n    exitError(\"INVALID_JOB_ID\");\n  }\n}\n\nfunction summaryJobsDir(notificationsDir: string): string {\n  return join(notificationsDir, SUMMARY_ROOT, JOBS_DIR);\n}\n\nfunction summaryJobDir(notificationsDir: string, id: string): string {\n  assertJobId(id);\n  return join(summaryJobsDir(notificationsDir), id);\n}\n\nfunction metaPath(jobDir: string): string {\n  return join(jobDir, \"meta.json\");\n}\n\nfunction chunkPath(jobDir: string, chunkId: string): string {\n  return join(jobDir, CHUNKS_DIR, `${chunkId}.json`);\n}\n\nfunction writeJson(path: string, value: unknown): void {\n  writeFileSync(path, JSON.stringify(value, null, 2), \"utf-8\");\n}\n\nfunction readJson(path: string): unknown {\n  try {\n    return JSON.parse(readFileSync(path, \"utf-8\"));\n  } catch {\n    exitError(\"READ_FAILED\", { path });\n  }\n}\n\nfunction readMeta(notificationsDir: string, id: string): SummaryJobMeta {\n  const dir = summaryJobDir(notificationsDir, id);\n  const path = metaPath(dir);\n  if (!existsSync(path)) {\n    exitError(\"JOB_NOT_FOUND\", { id });\n  }\n  const meta = readJson(path);\n  if (!isSummaryJobMeta(meta)) {\n    exitError(\"INVALID_JOB\", { id });\n  }\n  return meta;\n}\n\nfunction saveMeta(notificationsDir: string, meta: SummaryJobMeta): void {\n  meta.updatedAt = nowIso();\n  writeJson(metaPath(summaryJobDir(notificationsDir, meta.id)), meta);\n}\n\nfunction isSummaryJobMeta(value: unknown): value is SummaryJobMeta {\n  if (!value || typeof value !== \"object\") return false;\n  const obj = value as Record<string, unknown>;\n  return (\n    obj.schemaVersion === 1\n    && typeof obj.id === \"string\"\n    && Array.isArray(obj.chunks)\n    && typeof obj.total === \"number\"\n  );\n}\n\nfunction refreshStatus(meta: SummaryJobMeta): SummaryJobStatus {\n  if (meta.status === \"cancelled\" || meta.status === \"complete\") {\n    return meta.status;\n  }\n  if (meta.chunks.every((chunk) => chunk.status === \"done\")) {\n    return \"ready\";\n  }\n  if (meta.chunks.some((chunk) => chunk.status === \"in_progress\")) {\n    return \"in_progress\";\n  }\n  return \"pending\";\n}\n\nfunction progressFor(meta: SummaryJobMeta): {\n  totalChunks: number;\n  doneChunks: number;\n  totalNotifications: number;\n  doneNotifications: number;\n  remainingChunks: number;\n} {\n  const doneChunks = meta.chunks.filter((chunk) => chunk.status === \"done\");\n  const doneNotifications = doneChunks.reduce(\n    (sum, chunk) => sum + chunk.count,\n    0,\n  );\n  return {\n    totalChunks: meta.chunks.length,\n    doneChunks: doneChunks.length,\n    totalNotifications: meta.total,\n    doneNotifications,\n    remainingChunks: meta.chunks.length - doneChunks.length,\n  };\n}\n\nfunction toPublicStatus(meta: SummaryJobMeta): Record<string, unknown> {\n  return {\n    ok: true,\n    id: meta.id,\n    status: meta.status,\n    createdAt: meta.createdAt,\n    updatedAt: meta.updatedAt,\n    query: meta.query,\n    total: meta.total,\n    chunkSize: meta.chunkSize,\n    range: meta.range,\n    scan: meta.scan,\n    progress: progressFor(meta),\n    resultFile: meta.resultFile ?? null,\n    chunks: meta.chunks.map((chunk) => ({\n      id: chunk.id,\n      index: chunk.index,\n      count: chunk.count,\n      status: chunk.status,\n      range: chunk.range,\n      summaryFile: chunk.summaryFile ?? null,\n    })),\n  };\n}\n\nfunction readChunkNotifications(\n  jobDir: string,\n  chunkId: string,\n): CompactNotification[] {\n  const chunk = readJson(chunkPath(jobDir, chunkId));\n  if (\n    !chunk\n    || typeof chunk !== \"object\"\n    || !Array.isArray((chunk as { notifications?: unknown }).notifications)\n  ) {\n    exitError(\"INVALID_CHUNK\", { chunkId });\n  }\n  return (chunk as { notifications: CompactNotification[] }).notifications;\n}\n\nfunction buildCommitCommand(jobId: string, chunkId: string): string {\n  return `ntf summary-job commit ${jobId} --chunk-id ${chunkId} --summary-file <path>`;\n}\n\nfunction buildResultCommand(jobId: string): string {\n  return `ntf summary-job result ${jobId}`;\n}\n\nfunction resolveSummaryText(opts: SummaryJobCommitOptions): string {\n  const hasSummary = typeof opts.summary === \"string\" && opts.summary.length > 0;\n  const hasSummaryFile =\n    typeof opts.summaryFile === \"string\" && opts.summaryFile.length > 0;\n  if (hasSummary && hasSummaryFile) {\n    exitError(\"INVALID_COMMIT\", t(\"errors.INVALID_COMMIT.xor\"));\n  }\n  if (!hasSummary && !hasSummaryFile) {\n    exitError(\"INVALID_COMMIT\", t(\"errors.INVALID_COMMIT.required\"));\n  }\n\n  const text = hasSummary\n    ? opts.summary!\n    : readFileSync(resolve(opts.summaryFile!), \"utf-8\");\n  if (!text.trim()) {\n    exitError(\"INVALID_COMMIT\", t(\"errors.INVALID_COMMIT.empty\"));\n  }\n  return text.trimEnd() + \"\\n\";\n}\n\nfunction buildResultMarkdown(meta: SummaryJobMeta, jobDir: string): string {\n  const lines: string[] = [\n    t(\"summary_job.result_title\", { id: meta.id }),\n    \"\",\n    t(\"summary_job.result_total\", { total: meta.total }),\n    t(\"summary_job.time_range\", {\n      oldest: meta.range.oldest ?? \"-\",\n      newest: meta.range.newest ?? \"-\",\n    }),\n    t(\"summary_job.result_chunks\", { count: meta.chunks.length }),\n    \"\",\n    t(\"summary_job.result_chunk_summaries\"),\n    \"\",\n  ];\n\n  for (const chunk of meta.chunks) {\n    lines.push(\n      t(\"summary_job.result_chunk_line\", {\n        id: chunk.id,\n        count: chunk.count,\n        oldest: chunk.range.oldest ?? \"-\",\n        newest: chunk.range.newest ?? \"-\",\n      }),\n      \"\",\n    );\n    if (!chunk.summaryFile) {\n      lines.push(t(\"summary_job.uncommitted\"), \"\");\n      continue;\n    }\n    lines.push(readFileSync(join(jobDir, chunk.summaryFile), \"utf-8\").trim(), \"\");\n  }\n\n  return lines.join(\"\\n\").trimEnd() + \"\\n\";\n}\n\nfunction writeChunkSummary(\n  notificationsDir: string,\n  meta: SummaryJobMeta,\n  chunk: SummaryJobChunk,\n  text: string,\n): void {\n  const jobDir = summaryJobDir(notificationsDir, meta.id);\n  const relativeSummaryFile = join(SUMMARIES_DIR, `${chunk.id}.md`);\n  writeFileSync(join(jobDir, relativeSummaryFile), text, \"utf-8\");\n  chunk.status = \"done\";\n  chunk.completedAt = nowIso();\n  chunk.summaryFile = relativeSummaryFile;\n}\n\nfunction finalizeResultIfReady(\n  notificationsDir: string,\n  meta: SummaryJobMeta,\n): string | null {\n  meta.status = refreshStatus(meta);\n  if (meta.status !== \"ready\" && meta.status !== \"complete\") {\n    return null;\n  }\n  const jobDir = summaryJobDir(notificationsDir, meta.id);\n  const markdown = buildResultMarkdown(meta, jobDir);\n  writeFileSync(join(jobDir, RESULT_FILE), markdown, \"utf-8\");\n  meta.status = \"complete\";\n  meta.resultFile = RESULT_FILE;\n  return markdown;\n}\n\nexport function registerNtfSummaryJob(ntf: CliCommand, ctx: CliContext): void {\n  const summaryJob = ntf\n    .command(\"summary-job\")\n    .description(t(\"cli.summary_job.description\"));\n\n  summaryJob\n    .command(\"create\")\n    .description(t(\"cli.summary_job.create.description\"))\n    .option(\"--from <time>\", t(\"cli.opt.from_time_short\"))\n    .option(\"--to <time>\", t(\"cli.opt.to_time_short\"))\n    .option(\"--app <name>\", t(\"cli.opt.app\"))\n    .option(\"--sender <name>\", t(\"cli.opt.sender\"))\n    .option(\"--conversation-type <type>\", t(\"cli.opt.conversation_type\"))\n    .option(\"--keyword <text>\", t(\"cli.opt.keyword\"))\n    .option(\"--limit <n>\", t(\"cli.summary_job.opt.limit\"), String(DEFAULT_JOB_LIMIT))\n    .option(\"--chunk-size <n>\", t(\"cli.summary_job.opt.chunk_size\"), String(DEFAULT_CHUNK_SIZE))\n    .option(\n      \"--max-content <n>\",\n      t(\"cli.summary_job.opt.max_content\"),\n      String(DEFAULT_MAX_CONTENT),\n    )\n    .action(async (opts: SummaryJobCreateOptions) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      progress(t(\"progress.summary_job_create\"));\n\n      const query = parseNotificationQueryOptions(opts, DEFAULT_JOB_LIMIT);\n      const chunkSize = parsePositiveIntegerOption(\n        opts.chunkSize,\n        DEFAULT_CHUNK_SIZE,\n        \"--chunk-size\",\n        \"INVALID_CHUNK_SIZE\",\n      );\n      const maxContent = parsePositiveIntegerOption(\n        opts.maxContent,\n        DEFAULT_MAX_CONTENT,\n        \"--max-content\",\n        \"INVALID_MAX_CONTENT\",\n      );\n\n      const startedAtMs = Date.now();\n      const queryResult = await collectMatchingNotificationsWithStats(dir, query);\n      const elapsedMs = Date.now() - startedAtMs;\n      const notifications = queryResult.notifications;\n      const id = createJobId();\n      const createdAt = nowIso();\n      const jobDir = summaryJobDir(dir, id);\n      mkdirSync(join(jobDir, CHUNKS_DIR), { recursive: true });\n      mkdirSync(join(jobDir, SUMMARIES_DIR), { recursive: true });\n\n      const chunks: SummaryJobChunk[] = [];\n      for (let start = 0; start < notifications.length; start += chunkSize) {\n        const rawChunk = notifications.slice(start, start + chunkSize);\n        const chunkNotifications = rawChunk.map((item) =>\n          compactNotification(item, maxContent),\n        );\n        const index = chunks.length;\n        const chunkId = String(index + 1).padStart(4, \"0\");\n        const end = start + chunkNotifications.length - 1;\n        writeJson(chunkPath(jobDir, chunkId), {\n          id: chunkId,\n          index,\n          start,\n          end,\n          notifications: chunkNotifications,\n        });\n        chunks.push({\n          id: chunkId,\n          index,\n          start,\n          end,\n          count: chunkNotifications.length,\n          status: \"pending\",\n          range: {\n            newest: chunkNotifications[0]?.timestamp ?? null,\n            oldest: chunkNotifications[chunkNotifications.length - 1]?.timestamp\n              ?? null,\n          },\n        });\n      }\n\n      const meta: SummaryJobMeta = {\n        schemaVersion: 1,\n        id,\n        status: chunks.length === 0 ? \"ready\" : \"pending\",\n        createdAt,\n        updatedAt: createdAt,\n        query: {\n          ...(query.from ? { from: query.from } : {}),\n          ...(query.to ? { to: query.to } : {}),\n          ...(query.app ? { app: query.app } : {}),\n          ...(query.sender ? { sender: query.sender } : {}),\n          ...(query.conversationType\n            ? { conversationType: query.conversationType }\n            : {}),\n          ...(query.keyword ? { keyword: query.keyword } : {}),\n          limit: query.limit,\n        },\n        chunkSize,\n        maxContent,\n        total: notifications.length,\n        range: {\n          newest: notifications[0]?.timestamp ?? null,\n          oldest: notifications[notifications.length - 1]?.timestamp ?? null,\n        },\n        scan: {\n          daysScanned: queryResult.stats.daysScanned,\n          itemsScanned: queryResult.stats.itemsScanned,\n          matched: queryResult.stats.matched,\n          stoppedAfterLimit: queryResult.stats.stoppedAfterLimit,\n          elapsedMs,\n        },\n        chunks,\n      };\n      writeJson(metaPath(jobDir), meta);\n\n      output({\n        ...toPublicStatus(meta),\n        nextCommand: `ntf summary-job next ${id}`,\n        resultCommand: buildResultCommand(id),\n      });\n    });\n\n  summaryJob\n    .command(\"status <id>\")\n    .description(t(\"cli.summary_job.status.description\"))\n    .action((id: string) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const meta = readMeta(dir, id);\n      meta.status = refreshStatus(meta);\n      saveMeta(dir, meta);\n      output(toPublicStatus(meta));\n    });\n\n  summaryJob\n    .command(\"next <id>\")\n    .description(t(\"cli.summary_job.next.description\"))\n    .action((id: string) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const meta = readMeta(dir, id);\n      if (meta.status === \"cancelled\") {\n        exitError(\"JOB_CANCELLED\", { id });\n      }\n      const jobDir = summaryJobDir(dir, id);\n      let chunk = meta.chunks.find((item) => item.status === \"in_progress\");\n      if (!chunk) {\n        chunk = meta.chunks.find((item) => item.status === \"pending\");\n        if (chunk) {\n          chunk.status = \"in_progress\";\n          chunk.claimedAt = nowIso();\n        }\n      }\n\n      if (!chunk) {\n        meta.status = refreshStatus(meta);\n        saveMeta(dir, meta);\n        output({\n          ok: true,\n          id,\n          done: true,\n          status: meta.status,\n          progress: progressFor(meta),\n          resultCommand: buildResultCommand(id),\n        });\n        return;\n      }\n\n      meta.status = refreshStatus(meta);\n      saveMeta(dir, meta);\n      output({\n        ok: true,\n        id,\n        done: false,\n        status: meta.status,\n        chunk: {\n          id: chunk.id,\n          index: chunk.index,\n          start: chunk.start,\n          end: chunk.end,\n          count: chunk.count,\n          range: chunk.range,\n        },\n        progress: progressFor(meta),\n        commitCommand: buildCommitCommand(id, chunk.id),\n        notifications: readChunkNotifications(jobDir, chunk.id),\n      });\n    });\n\n  summaryJob\n    .command(\"commit <id>\")\n    .description(t(\"cli.summary_job.commit.description\"))\n    .requiredOption(\"--chunk-id <id>\", t(\"cli.summary_job.opt.chunk_id\"))\n    .option(\"--summary <text>\", t(\"cli.summary_job.opt.summary\"))\n    .option(\"--summary-file <path>\", t(\"cli.summary_job.opt.summary_file\"))\n    .action((id: string, opts: SummaryJobCommitOptions) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const meta = readMeta(dir, id);\n      if (meta.status === \"cancelled\") {\n        exitError(\"JOB_CANCELLED\", { id });\n      }\n      const chunk = meta.chunks.find((item) => item.id === opts.chunkId);\n      if (!chunk) {\n        exitError(\"CHUNK_NOT_FOUND\", { chunkId: opts.chunkId });\n      }\n\n      const text = resolveSummaryText(opts);\n      writeChunkSummary(dir, meta, chunk, text);\n      meta.status = refreshStatus(meta);\n      saveMeta(dir, meta);\n\n      output({\n        ok: true,\n        id,\n        chunkId: chunk.id,\n        status: meta.status,\n        progress: progressFor(meta),\n        nextCommand:\n          meta.status === \"ready\" ? null : `ntf summary-job next ${id}`,\n        resultCommand:\n          meta.status === \"ready\" ? buildResultCommand(id) : null,\n      });\n    });\n\n  summaryJob\n    .command(\"run <id>\")\n    .description(t(\"cli.summary_job.run.description\"))\n    .option(\n      \"--max-chunks <n>\",\n      t(\"cli.summary_job.opt.max_chunks\"),\n      String(DEFAULT_RUN_MAX_CHUNKS),\n    )\n    .option(\"--include-result\", t(\"cli.summary_job.opt.include_result\"))\n    .action((id: string, opts: SummaryJobRunOptions) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const meta = readMeta(dir, id);\n      if (meta.status === \"cancelled\") {\n        exitError(\"JOB_CANCELLED\", { id });\n      }\n\n      const maxChunks = parsePositiveIntegerOption(\n        opts.maxChunks,\n        DEFAULT_RUN_MAX_CHUNKS,\n        \"--max-chunks\",\n        \"INVALID_MAX_CHUNKS\",\n      );\n      const jobDir = summaryJobDir(dir, id);\n      const processed: Array<{ chunkId: string; count: number }> = [];\n\n      for (const chunk of meta.chunks) {\n        if (processed.length >= maxChunks) break;\n        if (chunk.status === \"done\") continue;\n\n        chunk.status = \"in_progress\";\n        chunk.claimedAt = nowIso();\n        const notifications = readChunkNotifications(jobDir, chunk.id);\n        const summary = buildExtractiveChunkSummary(chunk, notifications);\n        writeChunkSummary(dir, meta, chunk, summary);\n        processed.push({ chunkId: chunk.id, count: chunk.count });\n      }\n\n      const markdown = finalizeResultIfReady(dir, meta);\n      if (!markdown) {\n        meta.status = refreshStatus(meta);\n      }\n      saveMeta(dir, meta);\n\n      output({\n        ok: true,\n        id,\n        status: meta.status,\n        processed,\n        progress: progressFor(meta),\n        nextCommand:\n          meta.status === \"complete\" ? null : `ntf summary-job run ${id}`,\n        resultCommand:\n          meta.status === \"complete\" ? buildResultCommand(id) : null,\n        resultFile: meta.resultFile ?? null,\n        ...(opts.includeResult && markdown ? { markdown } : {}),\n      });\n    });\n\n  summaryJob\n    .command(\"result <id>\")\n    .description(t(\"cli.summary_job.result.description\"))\n    .action((id: string) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const meta = readMeta(dir, id);\n      meta.status = refreshStatus(meta);\n      if (meta.status !== \"ready\" && meta.status !== \"complete\") {\n        saveMeta(dir, meta);\n        output({\n          ok: true,\n          id,\n          done: false,\n          status: meta.status,\n          progress: progressFor(meta),\n          nextCommand: `ntf summary-job next ${id}`,\n        });\n        return;\n      }\n\n      const jobDir = summaryJobDir(dir, id);\n      const markdown = finalizeResultIfReady(dir, meta)\n        ?? buildResultMarkdown(meta, jobDir);\n      saveMeta(dir, meta);\n      output({\n        ok: true,\n        id,\n        done: true,\n        status: meta.status,\n        resultFile: RESULT_FILE,\n        markdown,\n      });\n    });\n\n  summaryJob\n    .command(\"cancel <id>\")\n    .description(t(\"cli.summary_job.cancel.description\"))\n    .action((id: string) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const meta = readMeta(dir, id);\n      meta.status = \"cancelled\";\n      saveMeta(dir, meta);\n      output({\n        ok: true,\n        id,\n        status: meta.status,\n        progress: progressFor(meta),\n      });\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveNotificationsDir,\n  listDateKeys,\n  readDateFile,\n  filterDateRange,\n  matchesNotificationAppFilter,\n  today,\n  daysAgo,\n  output,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\ntype Dimension = \"date\" | \"app\" | \"sender\" | \"hour\" | \"all\";\n\nexport function registerNtfStats(ntf: CliCommand, ctx: CliContext): void {\n  ntf\n    .command(\"stats\")\n    .description(t(\"cli.stats.description\"))\n    .option(\"--from <date>\", t(\"cli.opt.from_date\"), daysAgo(7))\n    .option(\"--to <date>\", t(\"cli.opt.to_date\"), today())\n    .option(\"--app <name>\", t(\"cli.stats.opt.app\"))\n    .option(\"--dim <dimension>\", t(\"cli.stats.opt.dim\"), \"all\")\n    .action(\n      (opts: { from: string; to: string; app?: string; dim: string }) => {\n        const dir = resolveNotificationsDir(ctx);\n        if (!dir) exitStorageUnavailable(\"notifications\");\n\n        const dim = opts.dim as Dimension;\n        const keys = filterDateRange(listDateKeys(dir), opts.from, opts.to);\n\n        const byDate: Record<string, number> = {};\n        const byApp: Record<string, number> = {};\n        const bySender: Record<string, number> = {};\n        const byHour: Record<string, number> = {};\n        let total = 0;\n\n        for (const dateKey of keys) {\n          const items = readDateFile(dir, dateKey);\n          let dateCount = 0;\n          for (const item of items) {\n            if (opts.app && !matchesNotificationAppFilter(item, opts.app)) continue;\n            total++;\n            dateCount++;\n\n            byApp[item.appName] = (byApp[item.appName] || 0) + 1;\n\n            const sender = item.senderName?.trim() || item.title?.trim();\n            if (sender) {\n              bySender[sender] = (bySender[sender] || 0) + 1;\n            }\n\n            const hourMatch = /T(\\d{2}):/.exec(item.timestamp);\n            if (hourMatch) {\n              const h = hourMatch[1];\n              byHour[h] = (byHour[h] || 0) + 1;\n            }\n          }\n          byDate[dateKey] = dateCount;\n        }\n\n        const result: Record<string, unknown> = {\n          ok: true,\n          range: { from: opts.from, to: opts.to },\n          total\n};\n\n        if (dim === \"date\" || dim === \"all\") {\n          result.byDate = byDate;\n        }\n        if (dim === \"app\" || dim === \"all\") {\n          result.byApp = byApp;\n        }\n        if (dim === \"sender\" || dim === \"all\") {\n          // Sort by count descending, return top 20\n          const sorted = Object.entries(bySender)\n            .sort((a, b) => b[1] - a[1])\n            .slice(0, 20)\n            .map(([sender, count]) => ({ sender, count }));\n          result.bySender = sorted;\n        }\n        if (dim === \"hour\" || dim === \"all\") {\n          result.byHour = byHour;\n        }\n\n        output(result);\n      },\n    );\n}\n",
    "import { execFileSync } from \"node:child_process\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n  type CliCommand,\n  type CliContext,\n  resolveNotificationsDir,\n  listDateKeys,\n  readDateFile,\n  today,\n  output,\n  exitError,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { resolveInstalledSkillResourcePath, t } from \"../i18n/index.js\";\n\ninterface CheckpointData {\n  [dateKey: string]: { lastIndex: number };\n}\n\n// 单批同步上限。刻意调小到 100，使每个批次（模型阅读+总结+写记忆）能在数十秒内完成，\n// 让前台/后台都能频繁提交 checkpoint 并快速给用户进度反馈，避免单回合塞太多导致超时卡死。\nconst SYNC_FETCH_LIMIT = 100;\n\ninterface SyncScanOptions {\n  all?: boolean;\n  date?: string;\n  fromDate?: string;\n  toDate?: string;\n}\n\ntype SyncScanScope =\n  | { mode: \"all\" }\n  | {\n      mode: \"today\" | \"date\" | \"range\";\n      fromDate?: string;\n      toDate?: string;\n    };\n\nfunction checkpointPath(dir: string): string {\n  return join(dir, \".checkpoint.json\");\n}\n\nfunction readCheckpoint(dir: string): CheckpointData {\n  const p = checkpointPath(dir);\n  if (!existsSync(p)) return {};\n  try {\n    return JSON.parse(readFileSync(p, \"utf-8\"));\n  } catch {\n    return {};\n  }\n}\n\nfunction writeCheckpoint(dir: string, data: CheckpointData): void {\n  writeFileSync(checkpointPath(dir), JSON.stringify(data, null, 2), \"utf-8\");\n}\n\nfunction validateDateKey(value: string, optionName: string): void {\n  const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n  if (!match) {\n    exitError(\"INVALID_DATE\", t(\"errors.INVALID_DATE\", { option: optionName }));\n  }\n\n  const year = Number(match[1]);\n  const month = Number(match[2]);\n  const day = Number(match[3]);\n  const parsed = new Date(Date.UTC(year, month - 1, day));\n  if (\n    parsed.getUTCFullYear() !== year ||\n    parsed.getUTCMonth() !== month - 1 ||\n    parsed.getUTCDate() !== day\n  ) {\n    exitError(\"INVALID_DATE\", t(\"errors.INVALID_DATE_VALUE\", { option: optionName }));\n  }\n}\n\nfunction resolveScanScope(opts: SyncScanOptions): SyncScanScope {\n  const hasRange = Boolean(opts.fromDate || opts.toDate);\n  if (opts.all && (opts.date || hasRange)) {\n    exitError(\"INVALID_SCOPE\", t(\"errors.INVALID_SCOPE.all_with_range\"));\n  }\n  if (opts.date && hasRange) {\n    exitError(\"INVALID_SCOPE\", t(\"errors.INVALID_SCOPE.date_with_range\"));\n  }\n\n  if (opts.all) return { mode: \"all\" };\n\n  if (opts.date) {\n    validateDateKey(opts.date, \"--date\");\n    return { mode: \"date\", fromDate: opts.date, toDate: opts.date };\n  }\n\n  if (hasRange) {\n    if (opts.fromDate) validateDateKey(opts.fromDate, \"--from-date\");\n    if (opts.toDate) validateDateKey(opts.toDate, \"--to-date\");\n    if (opts.fromDate && opts.toDate && opts.fromDate > opts.toDate) {\n      exitError(\"INVALID_SCOPE\", t(\"errors.INVALID_SCOPE.from_after_to\"));\n    }\n    return { mode: \"range\", fromDate: opts.fromDate, toDate: opts.toDate };\n  }\n\n  const currentDate = today();\n  return { mode: \"today\", fromDate: currentDate, toDate: currentDate };\n}\n\nfunction isDateInScope(dateKey: string, scope: SyncScanScope): boolean {\n  if (scope.mode === \"all\") return true;\n  if (scope.fromDate && dateKey < scope.fromDate) return false;\n  if (scope.toDate && dateKey > scope.toDate) return false;\n  return true;\n}\n\nconst MEMORY_PLUGIN_KEYWORD = \"memory-lancedb-ultra\";\n\ninterface MemoryBackendInfo {\n  backend: \"lancedb-plugin\" | \"openclaw-native\";\n  promptFile: string;\n}\n\n// 与 scripts/select-memory-prompt.sh 同语义：lancedb 插件存在且未 disabled 时\n// 使用插件提示词，否则（包括 openclaw 不可用）回退到原生记忆提示词。\nfunction resolveMemoryPromptFile(ctx: CliContext, relativePath: string): string {\n  if (!ctx.pluginInstallDir) {\n    throw new Error(\n      \"phone-notifications plugin install directory is unavailable\",\n    );\n  }\n  return resolveInstalledSkillResourcePath(ctx.pluginInstallDir, relativePath);\n}\n\nfunction detectMemoryBackend(ctx: CliContext): MemoryBackendInfo {\n  try {\n    const out = execFileSync(\"openclaw\", [\"plugins\", \"list\"], {\n      encoding: \"utf-8\",\n      timeout: 15000,\n      stdio: [\"ignore\", \"pipe\", \"ignore\"],\n    });\n    const matched = out\n      .split(\"\\n\")\n      .filter((line) => line.toLowerCase().includes(MEMORY_PLUGIN_KEYWORD));\n    if (matched.length > 0 && !matched.some((line) => /disabled/i.test(line))) {\n      return {\n        backend: \"lancedb-plugin\",\n        promptFile: resolveMemoryPromptFile(\n          ctx,\n          \"notification-to-memory/references/write-memory-lancedb-plugin.md\",\n        ),\n      };\n    }\n  } catch {\n    // openclaw CLI 不可用时按原生记忆处理\n  }\n  return {\n    backend: \"openclaw-native\",\n    promptFile: resolveMemoryPromptFile(\n      ctx,\n      \"notification-to-memory/references/write-memory-openclaw-native.md\",\n    ),\n  };\n}\n\nexport function registerNtfSync(ntf: CliCommand, ctx: CliContext): void {\n  const sync = ntf.command(\"sync\").description(t(\"cli.sync.description\"));\n\n  sync\n    .command(\"scan\")\n    .description(t(\"cli.sync.pending.description\"))\n    .option(\"--all\", t(\"cli.sync.scan.opt.all\"))\n    .option(\"--date <date>\", t(\"cli.sync.scan.opt.date\"))\n    .option(\"--from-date <date>\", t(\"cli.sync.scan.opt.from_date\"))\n    .option(\"--to-date <date>\", t(\"cli.sync.scan.opt.to_date\"))\n    .action((opts: SyncScanOptions) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const scope = resolveScanScope(opts);\n      const checkpoint = readCheckpoint(dir);\n      const keys = listDateKeys(dir); // descending\n      const pending: { date: string; count: number; startIndex: number }[] = [];\n      let totalPending = 0;\n      let outsideScopePending = 0;\n\n      for (const dateKey of keys) {\n        const items = readDateFile(dir, dateKey);\n        const lastIndex = checkpoint[dateKey]?.lastIndex ?? -1;\n        const unprocessed = items.length - (lastIndex + 1);\n        if (unprocessed > 0 && isDateInScope(dateKey, scope)) {\n          pending.push({\n            date: dateKey,\n            count: unprocessed,\n            startIndex: lastIndex + 1,\n          });\n          totalPending += unprocessed;\n        } else if (unprocessed > 0) {\n          outsideScopePending += unprocessed;\n        }\n      }\n\n      output({\n        ok: true,\n        scope,\n        pending,\n        totalPending,\n        outsideScopePending,\n        allDatesTotalPending: totalPending + outsideScopePending,\n      });\n    });\n\n  sync\n    .command(\"next\")\n    .description(t(\"cli.sync.next.description\"))\n    .option(\"--all\", t(\"cli.sync.next.opt.all\"))\n    .option(\"--date <date>\", t(\"cli.sync.next.opt.date\"))\n    .option(\"--from-date <date>\", t(\"cli.sync.next.opt.from_date\"))\n    .option(\"--to-date <date>\", t(\"cli.sync.next.opt.to_date\"))\n    .action((opts: SyncScanOptions) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const scope = resolveScanScope(opts);\n      const checkpoint = readCheckpoint(dir);\n      const keys = listDateKeys(dir); // descending: 从最新日期开始处理\n\n      let totalPending = 0;\n      let outsideScopePending = 0;\n      let nextDate: string | null = null;\n      let nextItems: ReturnType<typeof readDateFile> = [];\n      let nextStartIndex = 0;\n\n      for (const dateKey of keys) {\n        const items = readDateFile(dir, dateKey);\n        const lastIndex = checkpoint[dateKey]?.lastIndex ?? -1;\n        const unprocessed = items.length - (lastIndex + 1);\n        if (unprocessed <= 0) continue;\n        if (!isDateInScope(dateKey, scope)) {\n          outsideScopePending += unprocessed;\n          continue;\n        }\n        totalPending += unprocessed;\n        if (!nextDate) {\n          nextDate = dateKey;\n          nextItems = items;\n          nextStartIndex = lastIndex + 1;\n        }\n      }\n\n      if (!nextDate) {\n        output({\n          ok: true,\n          done: true,\n          scope,\n          totalPending: 0,\n          outsideScopePending,\n          allDatesTotalPending: outsideScopePending,\n        });\n        return;\n      }\n\n      const notifications = nextItems.slice(\n        nextStartIndex,\n        nextStartIndex + SYNC_FETCH_LIMIT,\n      );\n      const endIndex = nextStartIndex + notifications.length - 1;\n      const unprocessedInDate = nextItems.length - nextStartIndex;\n      const memory = detectMemoryBackend(ctx);\n\n      output({\n        ok: true,\n        done: false,\n        scope,\n        date: nextDate,\n        startIndex: nextStartIndex,\n        endIndex,\n        returned: notifications.length,\n        hasMoreInDate: unprocessedInDate > notifications.length,\n        remainingInScope: totalPending - notifications.length,\n        outsideScopePending,\n        memoryBackend: memory.backend,\n        memoryPromptFile: memory.promptFile,\n        commitCommand: `ntf sync commit --date ${nextDate} --end-index ${endIndex}`,\n        notifications,\n      });\n    });\n\n  sync\n    .command(\"fetch\")\n    .description(t(\"cli.sync.fetch.description\"))\n    .requiredOption(\"--date <date>\", t(\"cli.opt.date_ymd\"))\n    .option(\"--max-end-index <index>\", t(\"cli.sync.fetch.opt.max_end_index\"))\n    .action((opts: { date: string; maxEndIndex?: string }) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const items = readDateFile(dir, opts.date);\n      if (items.length === 0) {\n        exitError(\"NO_DATA\", { date: opts.date });\n      }\n\n      const checkpoint = readCheckpoint(dir);\n      const lastIndex = checkpoint[opts.date]?.lastIndex ?? -1;\n      const startIndex = lastIndex + 1;\n      let maxEndIndex = items.length - 1;\n      if (typeof opts.maxEndIndex === \"string\" && opts.maxEndIndex.length > 0) {\n        maxEndIndex = Number.parseInt(opts.maxEndIndex, 10);\n        if (!Number.isInteger(maxEndIndex) || String(maxEndIndex) !== opts.maxEndIndex) {\n          exitError(\"INVALID_MAX_END_INDEX\");\n        }\n        if (maxEndIndex < 0) {\n          exitError(\"INVALID_MAX_END_INDEX\");\n        }\n        maxEndIndex = Math.min(maxEndIndex, items.length - 1);\n      }\n      const snapshotEndExclusive = Math.max(startIndex, maxEndIndex + 1);\n      const unprocessed = items.slice(startIndex, snapshotEndExclusive);\n      const notifications = unprocessed.slice(0, SYNC_FETCH_LIMIT);\n      const endIndex =\n        notifications.length > 0 ? startIndex + notifications.length - 1 : lastIndex;\n      const hasMore = unprocessed.length > notifications.length;\n\n      if (unprocessed.length === 0) {\n        output({\n          ok: true,\n          date: opts.date,\n          startIndex,\n          endIndex,\n          nextStartIndex: null,\n          limit: SYNC_FETCH_LIMIT,\n          maxEndIndex,\n          returned: 0,\n          totalUnprocessed: 0,\n          hasMore: false,\n          notifications: [],\n        });\n        return;\n      }\n\n      output({\n        ok: true,\n        date: opts.date,\n        startIndex,\n        endIndex,\n        nextStartIndex: hasMore ? endIndex + 1 : null,\n        limit: SYNC_FETCH_LIMIT,\n        maxEndIndex,\n        returned: notifications.length,\n        totalUnprocessed: unprocessed.length,\n        hasMore,\n        notifications,\n      });\n    });\n\n  sync\n    .command(\"commit\")\n    .description(t(\"cli.sync.commit.description\"))\n    .requiredOption(\"--date <date>\", t(\"cli.opt.date_ymd\"))\n    .option(\"--end-index <index>\", t(\"cli.sync.commit.opt.end_index\"))\n    .action((opts: { date: string; endIndex?: string }) => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n\n      const items = readDateFile(dir, opts.date);\n      if (items.length === 0) {\n        exitError(\"NO_DATA\", { date: opts.date });\n      }\n\n      const checkpoint = readCheckpoint(dir);\n      const lastIndex = checkpoint[opts.date]?.lastIndex ?? -1;\n      let committedIndex: number;\n      if (typeof opts.endIndex === \"string\" && opts.endIndex.length > 0) {\n        committedIndex = Number.parseInt(opts.endIndex, 10);\n        if (!Number.isInteger(committedIndex) || String(committedIndex) !== opts.endIndex) {\n          exitError(\"INVALID_END_INDEX\");\n        }\n        if (committedIndex < 0 || committedIndex >= items.length) {\n          exitError(\"INVALID_END_INDEX\", t(\"errors.INVALID_END_INDEX.out_of_range\"));\n        }\n        if (committedIndex < lastIndex) {\n          exitError(\"STALE_END_INDEX\");\n        }\n        if (committedIndex > lastIndex + SYNC_FETCH_LIMIT) {\n          exitError(\"INVALID_END_INDEX\", t(\"errors.INVALID_END_INDEX.beyond_batch\"));\n        }\n      } else {\n        committedIndex = Math.min(items.length - 1, lastIndex + SYNC_FETCH_LIMIT);\n      }\n      const hasMore = committedIndex < items.length - 1;\n      checkpoint[opts.date] = { lastIndex: committedIndex };\n      writeCheckpoint(dir, checkpoint);\n\n      output({\n        ok: true,\n        date: opts.date,\n        committedIndex,\n        commitMode:\n          typeof opts.endIndex === \"string\" && opts.endIndex.length > 0\n            ? \"exact-end-index\"\n            : \"legacy-batch-limit\",\n        limit: SYNC_FETCH_LIMIT,\n        hasMore,\n        nextStartIndex: hasMore ? committedIndex + 1 : null,\n      });\n    });\n}\n",
    "import {\n  existsSync,\n  mkdirSync,\n  readFileSync,\n  writeFileSync,\n  rmSync,\n  readdirSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { type CliCommand, type CliContext, output, exitError } from \"./helpers.js\";\nimport { generateFetchPy } from \"../monitor/fetch-gen.js\";\nimport { t } from \"../i18n/index.js\";\n\ninterface MonitorMeta {\n  name: string;\n  type?: \"monitor\" | \"light-rule\";\n  description: string;\n  matchRules: Record<string, unknown>;\n  cronSchedule: string;\n  enabled: boolean;\n  createdAt: string;\n  updatedAt?: string;\n}\n\nfunction tasksDir(ctx: CliContext): string {\n  const base = ctx.workspaceDir || ctx.stateDir;\n  if (!base) throw new Error(\"workspaceDir and stateDir both unavailable\");\n  return join(base, \"tasks\");\n}\n\nfunction readMeta(taskDir: string): MonitorMeta | null {\n  const metaPath = join(taskDir, \"meta.json\");\n  if (!existsSync(metaPath)) return null;\n  try {\n    return JSON.parse(readFileSync(metaPath, \"utf-8\"));\n  } catch {\n    return null;\n  }\n}\n\nfunction writeMeta(taskDir: string, meta: MonitorMeta): void {\n  writeFileSync(join(taskDir, \"meta.json\"), JSON.stringify(meta, null, 2), \"utf-8\");\n}\n\nfunction generateReadme(name: string, description: string): string {\n  return `# Monitor Task: ${name}\n\n${t(\"monitor.readme.description\")}\n${description}\n\n${t(\"monitor.readme.guide_title\")}\n${t(\"monitor.readme.guide_body\")}\n`;\n}\n\nexport function registerNtfMonitor(ntf: CliCommand, ctx: CliContext): void {\n  const monitor = ntf.command(\"monitor\").description(t(\"cli.monitor.description\"));\n\n  monitor\n    .command(\"list\")\n    .description(t(\"cli.monitor.list.description\"))\n    .action(() => {\n      const dir = tasksDir(ctx);\n      if (!existsSync(dir)) {\n        output({ ok: true, tasks: [] });\n        return;\n      }\n\n      const tasks: MonitorMeta[] = [];\n      for (const entry of readdirSync(dir, { withFileTypes: true })) {\n        if (!entry.isDirectory()) continue;\n        const meta = readMeta(join(dir, entry.name));\n        if (meta) tasks.push(meta);\n      }\n\n      output({ ok: true, tasks });\n    });\n\n  monitor\n    .command(\"show <name>\")\n    .description(t(\"cli.monitor.show.description\"))\n    .action((name: string) => {\n      const taskDir = join(tasksDir(ctx), name);\n      const meta = readMeta(taskDir);\n      if (!meta) exitError(\"NOT_FOUND\", t(\"errors.NOT_FOUND.monitor\", { name }));\n\n      const checkpointPath = join(taskDir, \"checkpoint.json\");\n      let checkpoint = {};\n      if (existsSync(checkpointPath)) {\n        try {\n          checkpoint = JSON.parse(readFileSync(checkpointPath, \"utf-8\"));\n        } catch {\n          // ignore\n        }\n      }\n\n      output({\n        ok: true,\n        ...meta,\n        matchScript: `tasks/${name}/fetch.py`,\n        readme: `tasks/${name}/README.md`,\n        checkpoint,\n      });\n    });\n\n  monitor\n    .command(\"create <name>\")\n    .description(t(\"cli.monitor.create.description\"))\n    .requiredOption(\"--description <text>\", t(\"cli.monitor.create.opt.description\"))\n    .requiredOption(\"--match-rules <json>\", t(\"cli.monitor.create.opt.match_rules\"))\n    .requiredOption(\"--schedule <cron>\", t(\"cli.monitor.create.opt.schedule\"))\n    .action(\n      (\n        name: string,\n        opts: {\n          description: string;\n          matchRules: string;\n          schedule: string;\n        },\n      ) => {\n        const dir = tasksDir(ctx);\n        const taskDir = join(dir, name);\n\n        if (existsSync(taskDir)) {\n          exitError(\"ALREADY_EXISTS\", t(\"errors.ALREADY_EXISTS\", { name }));\n        }\n\n        let matchRules: Record<string, unknown>;\n        try {\n          matchRules = JSON.parse(opts.matchRules);\n        } catch {\n          exitError(\"VALIDATION_FAILED\", t(\"errors.INVALID_MATCH_RULES\"));\n        }\n\n        mkdirSync(taskDir, { recursive: true });\n\n        const meta: MonitorMeta = {\n          name,\n          description: opts.description,\n          matchRules,\n          cronSchedule: opts.schedule,\n          enabled: true,\n          createdAt: new Date().toISOString(),\n        };\n        writeMeta(taskDir, meta);\n        writeFileSync(\n          join(taskDir, \"fetch.py\"),\n          generateFetchPy(name, matchRules),\n          \"utf-8\",\n        );\n        writeFileSync(\n          join(taskDir, \"README.md\"),\n          generateReadme(name, opts.description),\n          \"utf-8\",\n        );\n\n        output({\n          ok: true,\n          name,\n          created: {\n            script: `tasks/${name}/fetch.py`,\n            readme: `tasks/${name}/README.md`,\n            cronJob: `notif-${name}`,\n          },\n          cronHint: {\n            action: \"add\",\n            job: {\n              name: `notif-${name}`,\n              schedule: opts.schedule,\n              sessionTarget: \"isolated\",\n              message: t(\"monitor.cron.message\", { name }),\n            },\n          },\n        });\n      },\n    );\n\n  monitor\n    .command(\"delete <name>\")\n    .description(t(\"cli.monitor.delete.description\"))\n    .option(\"--yes\", t(\"cli.opt.yes\"))\n    .action((name: string, opts: { yes?: boolean }) => {\n      const taskDir = join(tasksDir(ctx), name);\n      if (!existsSync(taskDir)) {\n        exitError(\"NOT_FOUND\", t(\"errors.NOT_FOUND.monitor\", { name }));\n      }\n\n      if (!opts.yes) {\n        output({\n          ok: false,\n          error: {\n            code: \"CONFIRMATION_REQUIRED\",\n            message: t(\"monitor.delete.confirm\", { name }),\n          },\n        });\n        process.exit(1);\n      }\n\n      rmSync(taskDir, { recursive: true, force: true });\n      output({\n        ok: true,\n        name,\n        deleted: true,\n        cronHint: {\n          action: \"remove\",\n          name: `notif-${name}`,\n        },\n      });\n    });\n\n  monitor\n    .command(\"enable <name>\")\n    .description(t(\"cli.monitor.enable.description\"))\n    .action((name: string) => {\n      const taskDir = join(tasksDir(ctx), name);\n      const meta = readMeta(taskDir);\n      if (!meta) exitError(\"NOT_FOUND\", t(\"errors.NOT_FOUND.monitor\", { name }));\n\n      meta.enabled = true;\n      writeMeta(taskDir, meta);\n      output({ ok: true, name, enabled: true });\n    });\n\n  monitor\n    .command(\"disable <name>\")\n    .description(t(\"cli.monitor.disable.description\"))\n    .action((name: string) => {\n      const taskDir = join(tasksDir(ctx), name);\n      const meta = readMeta(taskDir);\n      if (!meta) exitError(\"NOT_FOUND\", t(\"errors.NOT_FOUND.monitor\", { name }));\n\n      meta.enabled = false;\n      writeMeta(taskDir, meta);\n      output({ ok: true, name, enabled: false });\n    });\n}\n",
    "/**\n * 共享的 fetch.py 生成逻辑，供 ntf-monitor CLI 和 light-rules gateway 复用。\n */\nexport function generateFetchPy(\n  name: string,\n  matchRules: Record<string, unknown>,\n): string {\n  const appName = typeof matchRules.appName === \"string\" ? matchRules.appName : \"\";\n  const senderKeywords = stringArray(matchRules.senderKeywords);\n  const contentKeywords = stringArray(matchRules.contentKeywords);\n\n  return `#!/usr/bin/env python3\n\"\"\"Auto-generated fetch script for monitor task: ${name}\"\"\"\nimport json, sys, os\nfrom pathlib import Path\n\ndef matches(notification: dict) -> bool:\n    app = str(notification.get(\"appName\", \"\") or \"\")\n    title = str(notification.get(\"title\", \"\") or \"\")\n    content = str(notification.get(\"content\", \"\") or \"\")\n    body = str(notification.get(\"body\", \"\") or \"\")\n\n    app_name = ${pyLiteral(appName)}\n    if app_name and app != app_name:\n        return False\n\n    sender_keywords = ${pyLiteral(senderKeywords)}\n    sender_haystack = f\"{title}\\\\n{content}\\\\n{body}\"\n    if sender_keywords and not any(keyword in sender_haystack for keyword in sender_keywords):\n        return False\n\n    content_keywords = ${pyLiteral(contentKeywords)}\n    content_haystack = f\"{content}\\\\n{body}\"\n    if content_keywords and not any(keyword in content_haystack for keyword in content_keywords):\n        return False\n\n    return True\n\ndef main():\n    import argparse\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--notifications-dir\", required=True)\n    args = parser.parse_args()\n\n    checkpoint_path = Path(__file__).parent / \"checkpoint.json\"\n    checkpoint = {}\n    if checkpoint_path.exists():\n        checkpoint = json.loads(checkpoint_path.read_text())\n\n    ntf_dir = Path(args.notifications_dir)\n    matched = []\n    new_checkpoint = dict(checkpoint)\n\n    for f in sorted(ntf_dir.glob(\"*.json\")):\n        date_key = f.stem\n        items = json.loads(f.read_text())\n        last_idx = checkpoint.get(date_key, {}).get(\"lastIndex\", -1)\n        for i, item in enumerate(items):\n            if i <= last_idx:\n                continue\n            if matches(item):\n                matched.append(item)\n        new_checkpoint[date_key] = {\"lastIndex\": len(items) - 1}\n\n    checkpoint_path.write_text(json.dumps(new_checkpoint, indent=2))\n\n    if not matched:\n        print(\"NO_MATCH\")\n        return\n\n    for m in matched:\n        print(json.dumps(m, ensure_ascii=False))\n\nif __name__ == \"__main__\":\n    main()\n`;\n}\n\nfunction stringArray(value: unknown): string[] {\n  if (!Array.isArray(value)) return [];\n  return value.filter((item): item is string => typeof item === \"string\" && item.length > 0);\n}\n\nfunction pyLiteral(value: string | string[]): string {\n  return JSON.stringify(value);\n}\n",
    "import { randomUUID } from \"node:crypto\";\nimport { buildLightEffectApnsBody } from \"./protocol.js\";\nimport { getEnvUrls } from \"../env.js\";\nimport { getAcceptLanguage, t } from \"../i18n/index.js\";\nimport type { LightSegment } from \"../types.js\";\nimport { normalizeRepeatTimes, type RepeatArgument } from \"./repeat.js\";\n\nexport interface SendLightResult {\n  ok: boolean;\n  bizUniqueId?: string;\n  response?: unknown;\n  status?: number;\n  error?: string;\n  /** 本次实际走的下发链路：notification-intelligence 新入口或 message-service 旧链路 */\n  via?: \"notification-intelligence\" | \"message-service\";\n}\n\nexport interface SendLightOptions {\n  /**\n   * 调用方幂等标识，透传给一次性亮灯入口的 bizUniqueId；\n   * 未传时由服务端生成。仅对 notification-intelligence 链路生效。\n   */\n  bizUniqueId?: string;\n}\n\ninterface LightLogger {\n  info: (msg: string) => void;\n  warn: (msg: string) => void;\n}\n\nexport async function sendLightEffect(\n  apiKey: string,\n  segments: LightSegment[],\n  logger?: LightLogger,\n  repeatInput?: RepeatArgument,\n  reason?: string,\n  title?: string,\n  options?: SendLightOptions,\n): Promise<SendLightResult> {\n  const resolvedTitle = resolveLightTitle(title, reason, segments);\n\n  let repeatTimes: number;\n  try {\n    repeatTimes = normalizeRepeatTimes(repeatInput);\n  } catch (error: any) {\n    return { ok: false, error: error?.message ?? String(error) };\n  }\n\n  const intelligence = await sendViaNotificationIntelligence(\n    apiKey,\n    segments,\n    repeatTimes,\n    resolvedTitle,\n    reason,\n    options?.bizUniqueId,\n    logger,\n  );\n  if (!intelligence.fallback) {\n    return intelligence.result;\n  }\n\n  logger?.warn(\n    `Light sender: notification-intelligence entry unavailable (${intelligence.fallbackReason}), falling back to legacy message-service`,\n  );\n  return sendViaLegacyMessageService(\n    apiKey,\n    segments,\n    logger,\n    repeatInput,\n    reason,\n    resolvedTitle,\n  );\n}\n\ninterface IntelligenceAttempt {\n  fallback: boolean;\n  fallbackReason?: string;\n  result: SendLightResult;\n}\n\n/**\n * 调用 Notification Intelligence Service 插件侧一次性亮灯入口\n * POST /api/plugin/notification-intelligence/light-effects/send。\n * 服务端负责 segments/repeat_times 校验、灯效编码和 message-service 转发，\n * 插件侧不再自行编码 bizContent。\n */\nasync function sendViaNotificationIntelligence(\n  apiKey: string,\n  segments: LightSegment[],\n  repeatTimes: number,\n  title: string,\n  reason: string | undefined,\n  bizUniqueId: string | undefined,\n  logger?: LightLogger,\n): Promise<IntelligenceAttempt> {\n  const url = getEnvUrls().notificationIntelligenceLightEffectsSendUrl;\n  const requestBody: Record<string, unknown> = {\n    title,\n    repeat_times: repeatTimes,\n    segments,\n  };\n  if (reason?.trim()) requestBody.reason = reason;\n  const trimmedBizUniqueId = bizUniqueId?.trim();\n  if (trimmedBizUniqueId) requestBody.bizUniqueId = trimmedBizUniqueId;\n\n  logger?.info(\n    `Light sender: POST ${url}, bizUniqueId=${trimmedBizUniqueId ?? \"(server-generated)\"}, ` +\n      `title=${title}, repeat_times=${repeatTimes}, segments_count=${segments.length}`,\n  );\n\n  let res: Response;\n  try {\n    res = await fetch(url, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"Accept-Language\": getAcceptLanguage(),\n        \"X-Api-Key-Id\": stripBearer(apiKey),\n      },\n      body: JSON.stringify(requestBody),\n    });\n  } catch (error: any) {\n    return {\n      fallback: true,\n      fallbackReason: `network error: ${error?.message ?? String(error)}`,\n      result: { ok: false, error: error?.message ?? String(error) },\n    };\n  }\n\n  const resBody = await res.text();\n  if (!res.ok) {\n    // 入口未部署（404/405）或网关尚未放行插件前缀（JWT 层 401）时回退旧链路；\n    // 其余失败说明入口已生效，按新入口结果返回，避免旧链路重复下发。\n    if (\n      res.status === 404 ||\n      res.status === 405 ||\n      (res.status === 401 && /jwt is missing/i.test(resBody))\n    ) {\n      return {\n        fallback: true,\n        fallbackReason: `HTTP ${res.status}`,\n        result: { ok: false, status: res.status, error: resBody },\n      };\n    }\n    logger?.warn(\n      `Light sender: FAILED ${res.status}, url=${url}, resBody=${resBody.substring(0, 500)}`,\n    );\n    return {\n      fallback: false,\n      result: {\n        ok: false,\n        status: res.status,\n        error: resBody,\n        via: \"notification-intelligence\",\n      },\n    };\n  }\n\n  let parsed: any = null;\n  try {\n    parsed = resBody.trim() ? JSON.parse(resBody) : null;\n  } catch {\n    // ignore, treated as invalid response below\n  }\n  if (!parsed || typeof parsed !== \"object\") {\n    logger?.warn(\n      `Light sender: invalid JSON from ${url}, resBody=${resBody.substring(0, 200)}`,\n    );\n    return {\n      fallback: false,\n      result: {\n        ok: false,\n        error: \"invalid JSON response\",\n        via: \"notification-intelligence\",\n      },\n    };\n  }\n\n  const data = parsed.data ?? null;\n  if (parsed.code && parsed.code !== \"000000\") {\n    const message = parsed.msg ?? parsed.message ?? `remote code ${parsed.code}`;\n    logger?.warn(`Light sender: FAILED code=${parsed.code}, msg=${message}`);\n    return {\n      fallback: false,\n      result: {\n        ok: false,\n        error: String(message),\n        response: parsed,\n        via: \"notification-intelligence\",\n      },\n    };\n  }\n  if (data?.success === false) {\n    const message = data.message ?? \"remote business request failed\";\n    logger?.warn(`Light sender: FAILED business, message=${message}`);\n    return {\n      fallback: false,\n      result: {\n        ok: false,\n        error: String(message),\n        response: parsed,\n        via: \"notification-intelligence\",\n      },\n    };\n  }\n\n  const effectiveBizUniqueId =\n    (typeof data?.bizUniqueId === \"string\" && data.bizUniqueId.trim()) ||\n    trimmedBizUniqueId;\n  logger?.info(\n    `Light sender: OK bizUniqueId=${effectiveBizUniqueId ?? \"-\"}, resBody=${resBody.substring(0, 200)}`,\n  );\n  return {\n    fallback: false,\n    result: {\n      ok: true,\n      bizUniqueId: effectiveBizUniqueId || undefined,\n      response: parsed,\n      via: \"notification-intelligence\",\n    },\n  };\n}\n\n/** 历史兼容链路：插件侧直接编码 bizContent 并调用 message-service 外部入口。 */\nasync function sendViaLegacyMessageService(\n  apiKey: string,\n  segments: LightSegment[],\n  logger?: LightLogger,\n  repeatInput?: RepeatArgument,\n  reason?: string,\n  resolvedTitle?: string,\n): Promise<SendLightResult> {\n  const apiUrl = getEnvUrls().lightApiUrl;\n  const appKey = \"phone-notifications\";\n  const templateId = process.env.LIGHT_TEMPLATE_ID;\n\n  logger?.info(\n    `Light sender: apiUrl=${apiUrl ?? \"UNSET\"}, appKey=${appKey ? appKey.substring(0, 8) + \"…\" : \"UNSET\"}, templateId=${templateId ?? \"UNSET\"}, apiKey=${apiKey ? apiKey.substring(0, 20) + \"…\" : \"EMPTY\"}, title=${resolvedTitle}, reason=${reason ?? \"\"}, segments=${JSON.stringify(segments)}`,\n  );\n\n  if (!apiUrl || !appKey || !templateId) {\n    return {\n      ok: false,\n      error: t(\"light.api.not_configured\"),\n    };\n  }\n\n  let bizContent: string;\n  try {\n    bizContent = buildLightEffectApnsBody(segments, repeatInput, reason);\n  } catch (error: any) {\n    return { ok: false, error: error?.message ?? String(error) };\n  }\n  const bizUniqueId = randomUUID();\n\n  const requestBody = {\n    appKey,\n    bizMap: { noticeType: \"APP_NOTIFICATION_IMPORTANT\", title: resolvedTitle, reason },\n    bizUniqueId,\n    paramsMap: { bizContent },\n    pushType: \"SPECIFY_PUSH\",\n    templateId,\n  };\n\n  logger?.info(\n    `Light sender: POST ${apiUrl}, bizUniqueId=${bizUniqueId}, body=${JSON.stringify(requestBody).substring(0, 500)}`,\n  );\n\n  const res = await fetch(apiUrl, {\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application/json\",\n      \"Accept-Language\": getAcceptLanguage(),\n      \"X-Api-Key-Id\": stripBearer(apiKey),\n    },\n    body: JSON.stringify(requestBody),\n  });\n\n  const resBody = await res.text();\n  if (!res.ok) {\n    logger?.warn(\n      `Light sender: FAILED ${res.status}, url=${apiUrl}, resBody=${resBody.substring(0, 500)}`,\n    );\n    return { ok: false, status: res.status, error: resBody, via: \"message-service\" };\n  }\n\n  logger?.info(`Light sender: OK bizUniqueId=${bizUniqueId}, resBody=${resBody.substring(0, 200)}`);\n  return {\n    ok: true,\n    bizUniqueId,\n    response: JSON.parse(resBody),\n    via: \"message-service\",\n  };\n}\n\nfunction stripBearer(apiKey: string): string {\n  return apiKey.startsWith(\"Bearer \") ? apiKey.slice(\"Bearer \".length) : apiKey;\n}\n\nfunction resolveLightTitle(\n  title: string | undefined,\n  reason: string | undefined,\n  segments: LightSegment[],\n): string {\n  const trimmedTitle = title?.trim();\n  if (trimmedTitle) return trimmedTitle;\n\n  const trimmedReason = reason?.trim();\n  if (trimmedReason) return trimmedReason;\n\n  const modeDesc = segments.map((segment) => segment.mode).join(\"+\");\n  return `Effect: ${modeDesc || \"custom\"}`;\n}\n",
    "import { t } from \"../i18n/index.js\";\n\nexport interface RepeatConfig {\n  repeat?: boolean;\n  repeat_times?: number;\n}\n\nexport type RepeatArgument = RepeatConfig | boolean | number | undefined;\n\nexport function normalizeRepeatTimes(input?: RepeatArgument): number {\n  if (typeof input === \"boolean\") {\n    return input ? 0 : 1;\n  }\n\n  if (typeof input === \"number\") {\n    return validateRepeatTimes(input);\n  }\n\n  if (!input) {\n    return 1;\n  }\n\n  if (input.repeat_times !== undefined) {\n    return validateRepeatTimes(input.repeat_times);\n  }\n\n  if (input.repeat !== undefined) {\n    return input.repeat ? 0 : 1;\n  }\n\n  return 1;\n}\n\nexport function assertAncsRepeatTimes(repeatTimes: number): void {\n  if (repeatTimes !== 0 && repeatTimes !== 1) {\n    throw new Error(t(\"light.repeat.ancs_only\"));\n  }\n}\n\nfunction validateRepeatTimes(value: number): number {\n  if (!Number.isInteger(value) || value < 0) {\n    throw new Error(t(\"light.repeat.invalid\"));\n  }\n\n  return value;\n}\n",
    "import type { LightSegment } from \"../types.js\";\nimport { output, exitError } from \"../cli/helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport const VALID_MODES = [\n  \"wave\",\n  \"breath\",\n  \"strobe\",\n  \"steady\",\n  \"color_flow\",\n] as const;\nexport const MAX_SEGMENTS = 12;\n\nexport interface ValidationError {\n  field: string;\n  message: string;\n}\n\nexport interface ValidationWarning {\n  field: string;\n  code: string;\n  message: string;\n}\n\nexport type ValidationResult =\n  | { valid: true; segments: LightSegment[]; warnings: ValidationWarning[] }\n  | { valid: false; errors: ValidationError[] };\n\nexport function validateSegments(segments: unknown): ValidationResult {\n  if (!Array.isArray(segments)) {\n    return { valid: false, errors: [{ field: \"segments\", message: t(\"light.validation.must_array\") }] };\n  }\n  if (segments.length === 0) {\n    return { valid: false, errors: [{ field: \"segments\", message: t(\"light.validation.must_not_empty\") }] };\n  }\n  if (segments.length > MAX_SEGMENTS) {\n    return {\n      valid: false,\n      errors: [{ field: \"segments\", message: t(\"light.validation.max_segments\", { max: MAX_SEGMENTS }) }],\n    };\n  }\n\n  const errors: ValidationError[] = [];\n  const warnings: ValidationWarning[] = [];\n  for (let i = 0; i < segments.length; i++) {\n    validateSegment(segments[i], `segments[${i}]`, errors, warnings);\n  }\n\n  if (errors.length > 0) return { valid: false, errors };\n  return { valid: true, segments: segments as LightSegment[], warnings };\n}\n\n/**\n * 解析 JSON 字符串并校验 segments，失败时直接 exitError。\n * 适用于 CLI action 中的统一入口。\n */\nexport function parseAndValidateSegments(json: string): LightSegment[] {\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(json);\n  } catch {\n    exitError(\"VALIDATION_FAILED\", t(\"light.validation.segments_json\"));\n  }\n\n  const result = validateSegments(parsed);\n  if (!result.valid) {\n    output({ ok: false, error: { code: \"VALIDATION_FAILED\", details: result.errors } });\n    process.exit(1);\n  }\n\n  return result.segments;\n}\n\nfunction validateSegment(\n  seg: unknown,\n  prefix: string,\n  errors: ValidationError[],\n  warnings: ValidationWarning[],\n): void {\n  if (!isRecord(seg)) {\n    errors.push({ field: prefix, message: t(\"light.validation.must_object\") });\n    return;\n  }\n\n  const mode = seg.mode;\n  if (!VALID_MODES.includes(mode as (typeof VALID_MODES)[number])) {\n    errors.push({\n      field: `${prefix}.mode`,\n      message: t(\"light.validation.unsupported_mode\", {\n        mode: String(mode),\n        modes: VALID_MODES.join(\"/\"),\n      }),\n    });\n  }\n\n  validateNonNegativeNumber(seg.duration_s, `${prefix}.duration_s`, errors, t(\"light.validation.duration\"));\n\n  switch (mode) {\n    case \"wave\":\n      validateForegroundSegment(seg, prefix, errors);\n      validateOptionalNonNegativeNumber(seg.interval_ms, `${prefix}.interval_ms`, errors);\n      validateOptionalDirection(seg.direction, `${prefix}.direction`, errors);\n      validateOptionalWindow(seg.window, `${prefix}.window`, errors);\n      validateOptionalBackground(seg.background, `${prefix}.background`, errors);\n      break;\n    case \"color_flow\":\n      validateForegroundSegment(seg, prefix, errors);\n      validateOptionalNonNegativeNumber(seg.interval_ms, `${prefix}.interval_ms`, errors);\n      validateOptionalDirection(seg.direction, `${prefix}.direction`, errors);\n      validateOptionalWindow(seg.window, `${prefix}.window`, errors);\n      validateOptionalBackground(seg.background, `${prefix}.background`, errors);\n      type RgbLike = Parameters<typeof hasNonZeroRgb>[0];\n      if (!hasNonZeroRgb(seg.color as RgbLike) && !hasNonZeroRgb(seg.background as RgbLike)) {\n        errors.push({\n          field: prefix,\n          message: t(\"light.validation.color_flow_anchor\"),\n        });\n      }\n      detectColorFlowSingleAnchorMisuse(seg, prefix, warnings);\n      break;\n    case \"breath\":\n      validateForegroundSegment(seg, prefix, errors);\n      validateOptionalBreathTiming(seg.breath_timing, `${prefix}.breath_timing`, errors);\n      break;\n    case \"strobe\":\n      validateForegroundSegment(seg, prefix, errors);\n      validateOptionalNonNegativeNumber(seg.interval_ms, `${prefix}.interval_ms`, errors);\n      break;\n    case \"steady\":\n      validateForegroundSegment(seg, prefix, errors);\n      break;\n    default:\n      validateOptionalNonNegativeNumber(seg.brightness, `${prefix}.brightness`, errors);\n      validateOptionalColor(seg.color, `${prefix}.color`, errors);\n      validateOptionalNonNegativeNumber(seg.interval_ms, `${prefix}.interval_ms`, errors);\n      validateOptionalDirection(seg.direction, `${prefix}.direction`, errors);\n      validateOptionalWindow(seg.window, `${prefix}.window`, errors);\n      validateOptionalBreathTiming(seg.breath_timing, `${prefix}.breath_timing`, errors);\n      validateOptionalBackground(seg.background, `${prefix}.background`, errors);\n  }\n}\n\nfunction validateForegroundSegment(\n  seg: Record<string, unknown>,\n  prefix: string,\n  errors: ValidationError[],\n): void {\n  validateNumberInRange(\n    seg.brightness,\n    `${prefix}.brightness`,\n    errors,\n    0,\n    255,\n    t(\"light.validation.byte\"),\n  );\n  validateColor(seg.color, `${prefix}.color`, errors);\n\n  if (seg.mode !== \"steady\" && seg.brightness === 0) {\n    errors.push({\n      field: `${prefix}.brightness`,\n      message: t(\"light.validation.brightness_zero\"),\n    });\n  }\n}\n\nfunction validateOptionalBreathTiming(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n): void {\n  if (value === undefined) return;\n  if (!isRecord(value)) {\n    errors.push({ field, message: t(\"light.validation.must_object\") });\n    return;\n  }\n\n  validatePositiveNumber(\n    value.rise_ms,\n    `${field}.rise_ms`,\n    errors,\n    t(\"light.validation.rise_ms\"),\n  );\n  validateNonNegativeNumber(\n    value.hold_ms,\n    `${field}.hold_ms`,\n    errors,\n    t(\"light.validation.hold_ms\"),\n  );\n  validatePositiveNumber(\n    value.fall_ms,\n    `${field}.fall_ms`,\n    errors,\n    t(\"light.validation.fall_ms\"),\n  );\n  validateNonNegativeNumber(\n    value.off_ms,\n    `${field}.off_ms`,\n    errors,\n    t(\"light.validation.off_ms\"),\n  );\n}\n\nfunction validateOptionalBackground(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n): void {\n  if (value === undefined) return;\n  if (!isRecord(value)) {\n    errors.push({ field, message: t(\"light.validation.must_rgb_brightness\") });\n    return;\n  }\n\n  validateColor(value, field, errors);\n  validateNumberInRange(\n    value.brightness,\n    `${field}.brightness`,\n    errors,\n    0,\n    255,\n    t(\"light.validation.byte\"),\n  );\n}\n\nfunction validateOptionalColor(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n): void {\n  if (value === undefined) return;\n  validateColor(value, field, errors);\n}\n\nfunction validateColor(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n): void {\n  if (!isRecord(value)) {\n    errors.push({ field, message: t(\"light.validation.must_rgb\") });\n    return;\n  }\n\n  validateNumberInRange(value.r, `${field}.r`, errors, 0, 255, t(\"light.validation.byte\"));\n  validateNumberInRange(value.g, `${field}.g`, errors, 0, 255, t(\"light.validation.byte\"));\n  validateNumberInRange(value.b, `${field}.b`, errors, 0, 255, t(\"light.validation.byte\"));\n}\n\nfunction validateOptionalDirection(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n): void {\n  if (value === undefined) return;\n  if (value !== \"ltr\" && value !== \"rtl\") {\n    errors.push({ field, message: t(\"light.validation.direction\") });\n  }\n}\n\nfunction validateOptionalWindow(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n): void {\n  if (value === undefined) return;\n  if (value !== 1 && value !== 2 && value !== 3) {\n    errors.push({ field, message: t(\"light.validation.window\") });\n  }\n}\n\nfunction validateOptionalNonNegativeNumber(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n): void {\n  if (value === undefined) return;\n  validateNonNegativeNumber(value, field, errors, t(\"light.validation.non_negative\"));\n}\n\nfunction validatePositiveNumber(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n  message: string,\n): void {\n  if (value === undefined) return;\n  if (!isFiniteNumber(value) || value <= 0) {\n    errors.push({ field, message });\n  }\n}\n\nfunction validateNonNegativeNumber(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n  message: string,\n): void {\n  if (!isFiniteNumber(value) || value < 0) {\n    errors.push({ field, message });\n  }\n}\n\nfunction validateNumberInRange(\n  value: unknown,\n  field: string,\n  errors: ValidationError[],\n  min: number,\n  max: number,\n  message: string,\n): void {\n  if (!isFiniteNumber(value) || value < min || value > max) {\n    errors.push({ field, message });\n  }\n}\n\nfunction hasNonZeroRgb(value: { r?: unknown; g?: unknown; b?: unknown } | undefined): boolean {\n  if (!value) return false;\n  return [value.r, value.g, value.b].some((channel) => isFiniteNumber(channel) && channel > 0);\n}\n\n/**\n * color_flow 是「调色板沿圆周流动」，由 1~2 个颜色锚点插值得到。\n * 当用户/模型只给单一极端纯色锚点（如纯红 R=255、G=B=0）且没有底色锚点时，\n * 实际效果是「同色系亮暗环状流动」（红→暗红），而不是多色调色板流动。\n * 这是已知的 bug 模式（详见 imp-custom-led-ai-read.md「模式选择易错对照」）：\n * 上层往往是把用户的\"单色波浪\"误映射到 color_flow，应该改用 wave 模式。\n * 此处不阻塞，只 push 一条 warning 让前端/审计可见。\n */\nfunction detectColorFlowSingleAnchorMisuse(\n  seg: Record<string, unknown>,\n  prefix: string,\n  warnings: ValidationWarning[],\n): void {\n  const color = seg.color as { r?: unknown; g?: unknown; b?: unknown } | undefined;\n  const background = seg.background as\n    | { r?: unknown; g?: unknown; b?: unknown; brightness?: unknown }\n    | undefined;\n\n  const fgChannels = extractChannels(color);\n  const bgChannels = extractChannels(background);\n  if (!fgChannels) return;\n\n  const bgBrightnessRaw = background?.brightness;\n  const bgBrightness = isFiniteNumber(bgBrightnessRaw) ? bgBrightnessRaw : 0;\n  const bgActive = !!bgChannels && bgChannels.some((c) => c > 0) && bgBrightness > 0;\n  if (bgActive) return;\n\n  const fgActiveChannels = fgChannels.filter((c) => c > 0);\n  if (fgActiveChannels.length !== 1) return;\n  if (fgActiveChannels[0] < 192) return;\n\n  warnings.push({\n    field: prefix,\n    code: \"COLOR_FLOW_SINGLE_ANCHOR_MISUSE\",\n    message: t(\"light.validation.color_flow_misuse\"),\n  });\n}\n\nfunction extractChannels(\n  value: { r?: unknown; g?: unknown; b?: unknown } | undefined,\n): [number, number, number] | null {\n  if (!value) return null;\n  const r = isFiniteNumber(value.r) ? value.r : 0;\n  const g = isFiniteNumber(value.g) ? value.g : 0;\n  const b = isFiniteNumber(value.b) ? value.b : 0;\n  return [r, g, b];\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n  return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n  return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n",
    "import type { LightSegment } from \"../types.js\";\nimport { assertAncsRepeatTimes, normalizeRepeatTimes, type RepeatArgument } from \"./repeat.js\";\nimport { validateSegments } from \"./validators.js\";\n\nexport const MAX_LIGHT_SEGMENTS = 12;\n\nconst PROTOCOL_DIGITS = [\n  \"\\u0080\",\n  \"\\u0081\",\n  \"\\u0082\",\n  \"\\u0083\",\n  \"\\u0084\",\n  \"\\u0091\",\n  \"\\u0092\",\n  \"\\u0093\",\n  \"\\u0094\",\n  \"\\u0095\",\n  \"\\u0096\",\n  \"\\u0097\",\n] as const;\n\n/** \\u009A = play once, \\u009B = infinite loop */\nconst LED_SEPARATOR_ONCE = \"\\u009A\";\nconst LED_SEPARATOR_LOOP = \"\\u009B\";\n\n/** v0–v10 mapped by index; duration_s=0 is special-cased to v11 (infinite) */\nconst DURATION_STEPS_S = [0.5, 1, 2, 3, 5, 6, 8, 16, 24, 32, 48] as const;\n/** v0–v10 mapped by index; removed 400ms, added 50ms */\nconst INTERVAL_STEPS_MS = [50, 100, 200, 300, 500, 600, 800, 1600, 2400, 3200, 4800] as const;\nconst BREATH_STEPS_MS = [1040, 1560, 2080, 2600, 3100, 4160] as const;\nconst BRIGHTNESS_STEPS = [32, 64, 96, 128, 192, 255] as const;\nconst COLOR_STEPS = [0, 32, 64, 128, 192, 255] as const;\nconst BACKGROUND_BRIGHTNESS_STEPS = [0, 32, 64, 96, 128, 192, 255] as const;\nconst MULTI_CHANNEL_COLOR_COEFFICIENTS = { r: 1, g: 0.25, b: 0.25 } as const;\nconst PURE_WHITE_COLOR_COEFFICIENTS = { r: 1, g: 0.35, b: 0.35 } as const;\n\n/**\n * mode → wire-protocol M value.\n * color_flow encodes to M=v4 (firmware enum APP_LED_CUSTOM_MODE_WAVE_RAINBOW).\n * \"WAVE_RAINBOW\" is a legacy firmware name and does NOT imply rainbow/multi-color semantics;\n * the TS-side enum uses color_flow to avoid that confusion. See imp-custom-led-ai-read.md\n * \"模式选择易错对照\" for the mapping rules.\n */\nconst MODE_TO_INDEX: Record<LightSegment[\"mode\"], number> = {\n  wave: 0,\n  breath: 1,\n  strobe: 2,\n  steady: 3,\n  color_flow: 4,\n};\n\nexport function buildLightEffectApnsBody(\n  segments: LightSegment[],\n  repeatInput?: RepeatArgument,\n  visibleTextOverride?: string,\n): string {\n  assertSegmentCount(segments);\n  assertSegmentsValid(segments);\n\n  const repeatTimes = normalizeRepeatTimes(repeatInput);\n  assertAncsRepeatTimes(repeatTimes);\n\n  const visibleText = resolveVisibleText(visibleTextOverride, segments);\n  const separator = repeatTimes === 0 ? LED_SEPARATOR_LOOP : LED_SEPARATOR_ONCE;\n  const payload = segments.map((segment) => encodeSegment(segment)).join(\"\");\n  return `${visibleText}${separator}${payload}`;\n}\n\nfunction resolveVisibleText(\n  override: string | undefined,\n  segments: LightSegment[],\n): string {\n  const trimmed = override?.trim();\n  if (trimmed) return trimmed;\n  return summarizeSegments(segments);\n}\n\nfunction assertSegmentCount(segments: LightSegment[]): void {\n  if (segments.length < 1 || segments.length > MAX_LIGHT_SEGMENTS) {\n    throw new Error(`light_control supports 1-${MAX_LIGHT_SEGMENTS} segments`);\n  }\n}\n\nfunction summarizeSegments(segments: LightSegment[]): string {\n  const modeDesc = segments.map((segment) => segment.mode).join(\"+\");\n  return `Effect: ${modeDesc} (${segments.length} segment${segments.length > 1 ? \"s\" : \"\"})`;\n}\n\nfunction assertSegmentsValid(segments: LightSegment[]): void {\n  const validation = validateSegments(segments);\n  if (!validation.valid) {\n    throw new Error(\n      validation.errors.map((error) => `${error.field}: ${error.message}`).join(\"; \"),\n    );\n  }\n}\n\nfunction encodeSegment(segment: LightSegment): string {\n  const common = [\n    MODE_TO_INDEX[segment.mode],\n    quantizeDuration(segment.duration_s),\n  ];\n\n  let values: number[];\n  switch (segment.mode) {\n    case \"wave\":\n    case \"color_flow\":\n      const color = normalizeProtocolColor(segment.color);\n      const background = normalizeProtocolColor(segment.background);\n      values = [\n        ...common,\n        quantize(segment.interval_ms ?? 200, INTERVAL_STEPS_MS),\n        quantizeBrightnessValue(segment.brightness ?? 0),\n        quantize(color.r, COLOR_STEPS),\n        quantize(color.g, COLOR_STEPS),\n        quantize(color.b, COLOR_STEPS),\n        segment.direction === \"rtl\" ? 1 : 0,\n        quantizeWindow(segment.window ?? 2),\n        quantize(background.r, COLOR_STEPS),\n        quantize(background.g, COLOR_STEPS),\n        quantize(background.b, COLOR_STEPS),\n        quantize(segment.background?.brightness ?? 0, BACKGROUND_BRIGHTNESS_STEPS),\n      ];\n      break;\n    case \"breath\":\n      const breathColor = normalizeProtocolColor(segment.color);\n      values = [\n        ...common,\n        quantizeBreathRiseFall(segment.breath_timing?.rise_ms),\n        quantizeBreathHoldOff(segment.breath_timing?.hold_ms),\n        quantizeBreathRiseFall(segment.breath_timing?.fall_ms),\n        quantizeBreathHoldOff(segment.breath_timing?.off_ms),\n        quantizeBrightnessValue(segment.brightness ?? 0),\n        quantize(breathColor.r, COLOR_STEPS),\n        quantize(breathColor.g, COLOR_STEPS),\n        quantize(breathColor.b, COLOR_STEPS),\n      ];\n      break;\n    case \"strobe\":\n      const strobeColor = normalizeProtocolColor(segment.color);\n      values = [\n        ...common,\n        quantize(segment.interval_ms ?? 200, INTERVAL_STEPS_MS),\n        quantizeBrightnessValue(segment.brightness ?? 0),\n        quantize(strobeColor.r, COLOR_STEPS),\n        quantize(strobeColor.g, COLOR_STEPS),\n        quantize(strobeColor.b, COLOR_STEPS),\n      ];\n      break;\n    case \"steady\":\n      const steadyColor = normalizeProtocolColor(segment.color);\n      values = [\n        ...common,\n        quantizeBrightnessValue(segment.brightness ?? 0),\n        quantize(steadyColor.r, COLOR_STEPS),\n        quantize(steadyColor.g, COLOR_STEPS),\n        quantize(steadyColor.b, COLOR_STEPS),\n      ];\n      break;\n  }\n\n  return values.map((value) => PROTOCOL_DIGITS[value]).join(\"\");\n}\n\nexport function normalizeProtocolColor(\n  color:\n    | Pick<NonNullable<LightSegment[\"color\"]>, \"r\" | \"g\" | \"b\">\n    | Pick<NonNullable<LightSegment[\"background\"]>, \"r\" | \"g\" | \"b\">\n    | undefined,\n): { r: number; g: number; b: number } {\n  const normalized = {\n    r: color?.r ?? 0,\n    g: color?.g ?? 0,\n    b: color?.b ?? 0,\n  };\n\n  if (isPureWhiteProtocolColor(normalized)) {\n    return applyProtocolColorCoefficients(normalized, PURE_WHITE_COLOR_COEFFICIENTS);\n  }\n\n  if (countActiveProtocolColorChannels(normalized) <= 1) {\n    return normalized;\n  }\n\n  return applyProtocolColorCoefficients(normalized, MULTI_CHANNEL_COLOR_COEFFICIENTS);\n}\n\nfunction countActiveProtocolColorChannels(color: { r: number; g: number; b: number }): number {\n  return Number(color.r > 0) + Number(color.g > 0) + Number(color.b > 0);\n}\n\nfunction isPureWhiteProtocolColor(color: { r: number; g: number; b: number }): boolean {\n  return color.r === 255 && color.g === 255 && color.b === 255;\n}\n\nfunction applyProtocolColorCoefficients(\n  color: { r: number; g: number; b: number },\n  coefficients: { r: number; g: number; b: number },\n): { r: number; g: number; b: number } {\n  return {\n    r: scaleProtocolColorChannel(color.r, coefficients.r),\n    g: scaleProtocolColorChannel(color.g, coefficients.g),\n    b: scaleProtocolColorChannel(color.b, coefficients.b),\n  };\n}\n\nfunction scaleProtocolColorChannel(value: number, coefficient: number): number {\n  return Math.max(0, Math.min(255, Math.round(value * coefficient)));\n}\n\nfunction quantize(value: number, steps: readonly number[]): number {\n  let bestIndex = 0;\n  let bestDistance = Number.POSITIVE_INFINITY;\n\n  for (const [index, step] of steps.entries()) {\n    const distance = Math.abs(value - step);\n    if (distance < bestDistance) {\n      bestIndex = index;\n      bestDistance = distance;\n    }\n  }\n\n  return bestIndex;\n}\n\n/** duration_s=0 maps to v11 (infinite); otherwise quantize to DURATION_STEPS_S */\nfunction quantizeDuration(duration_s: number): number {\n  if (duration_s === 0) return 11;\n  return quantize(duration_s, DURATION_STEPS_S);\n}\n\n/**\n * brightness=0 maps to v11 (explicit off / pixel-off).\n * Otherwise quantize to BRIGHTNESS_STEPS (v0–v5).\n */\nfunction quantizeBrightnessValue(brightness: number): number {\n  if (brightness === 0) return 11;\n  return quantize(brightness, BRIGHTNESS_STEPS);\n}\n\nfunction quantizeBreathRiseFall(value: number | undefined): number {\n  return quantize(value ?? 1040, BREATH_STEPS_MS);\n}\n\nfunction quantizeBreathHoldOff(value: number | undefined): number {\n  if (value === 0) {\n    return 5;\n  }\n\n  return quantize(value ?? 1040, BREATH_STEPS_MS.slice(0, 5));\n}\n\nfunction quantizeWindow(value: 1 | 2 | 3): number {\n  return value - 1;\n}\n",
    "import { type CliCommand, output, exitError } from \"./helpers.js\";\nimport { requireApiKey } from \"../auth/credentials.js\";\nimport { sendLightEffect } from \"../light/sender.js\";\nimport { parseAndValidateSegments } from \"../light/validators.js\";\nimport { assertAncsRepeatTimes, normalizeRepeatTimes } from \"../light/repeat.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerLightSend(light: CliCommand): void {\n  light\n    .command(\"send\")\n    .description(t(\"cli.light.send.description\"))\n    .requiredOption(\"--segments <json>\", t(\"cli.light.send.opt.segments\"))\n    .option(\"--repeat\", t(\"cli.light.send.opt.repeat\"))\n    .option(\"--repeat-times <n>\", t(\"cli.light.send.opt.repeat_times\"))\n    .action(async (opts: { segments: string; repeat?: boolean; repeatTimes?: string }) => {\n      let apiKey: string;\n      try {\n        apiKey = requireApiKey();\n      } catch (e: any) {\n        exitError(\"AUTH_REQUIRED\", e.message);\n      }\n\n      const segments = parseAndValidateSegments(opts.segments);\n      let repeatTimes: number;\n      try {\n        repeatTimes = normalizeRepeatTimes({\n          repeat: opts.repeat,\n          repeat_times: opts.repeatTimes === undefined ? undefined : Number(opts.repeatTimes),\n        });\n        assertAncsRepeatTimes(repeatTimes);\n      } catch (e: any) {\n        exitError(\"VALIDATION_FAILED\", e.message);\n      }\n\n      const result = await sendLightEffect(\n        apiKey,\n        segments,\n        undefined,\n        { repeat_times: repeatTimes },\n      );\n\n      if (!result.ok) {\n        exitError(\"HTTP_ERROR\", t(\"errors.HTTP_ERROR\", {\n          status: result.status ?? \"\",\n          detail: result.error ?? \"\",\n        }));\n      }\n\n      output({ ok: true, bizUniqueId: result.bizUniqueId, response: result.response });\n    });\n}\n",
    "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { LIGHT_RULE_TOOL_NAME_LIST } from \"../light-rules/names.js\";\nimport { resolveConfigPath as resolveHostConfigPath } from \"../host.js\";\nimport { type CliCommand, output, exitError } from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\ntype JsonObject = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is JsonObject {\n  return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction ensureArray(obj: JsonObject, key: string): unknown[] {\n  const current = obj[key];\n  if (Array.isArray(current)) return current;\n  const next: unknown[] = [];\n  obj[key] = next;\n  return next;\n}\n\nfunction hasOwnProperty(obj: JsonObject, key: string): boolean {\n  return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\nfunction appendUniqueValues(target: unknown[], values: readonly string[]): boolean {\n  let changed = false;\n  for (const value of values) {\n    if (!target.includes(value)) {\n      target.push(value);\n      changed = true;\n    }\n  }\n  return changed;\n}\n\nfunction upsertToolsForPolicy(policy: JsonObject, tools: readonly string[]): boolean {\n  if (Array.isArray(policy.allow)) {\n    let changed = false;\n    if (Array.isArray(policy.alsoAllow)) {\n      changed = appendUniqueValues(\n        policy.allow,\n        policy.alsoAllow.filter((value): value is string => typeof value === \"string\"),\n      );\n    }\n    changed = appendUniqueValues(policy.allow, tools) || changed;\n    if (hasOwnProperty(policy, \"alsoAllow\")) {\n      delete policy.alsoAllow;\n      changed = true;\n    }\n    return changed;\n  }\n\n  if (hasOwnProperty(policy, \"allow\")) return false;\n\n  const alsoAllow = ensureArray(policy, \"alsoAllow\");\n  return appendUniqueValues(alsoAllow, tools);\n}\n\nfunction resolveConfigPath(): string {\n  return resolveHostConfigPath();\n}\n\nconst LIGHT_TOOLS = [\"light_control\", ...LIGHT_RULE_TOOL_NAME_LIST] as const;\n\nfunction upsertLightRuleToolsAlsoAllow(cfg: JsonObject): {\n  globalChanged: boolean;\n  mainAgentChanged: boolean;\n} {\n  if (!isObject(cfg.tools)) cfg.tools = {};\n  const globalChanged = upsertToolsForPolicy(cfg.tools as JsonObject, LIGHT_TOOLS);\n\n  if (!isObject(cfg.agents)) cfg.agents = {};\n  const agents = cfg.agents as JsonObject;\n  const list = ensureArray(agents, \"list\");\n  let mainAgent = list.find(\n    (item) => isObject(item) && item.id === \"main\",\n  ) as JsonObject | undefined;\n  if (!mainAgent) {\n    mainAgent = { id: \"main\" };\n    list.push(mainAgent);\n  }\n  if (!isObject(mainAgent.tools)) mainAgent.tools = {};\n  const mainAgentChanged = upsertToolsForPolicy(mainAgent.tools as JsonObject, LIGHT_TOOLS);\n\n  return { globalChanged, mainAgentChanged };\n}\n\nexport function registerLightSetupTools(light: CliCommand): void {\n  light\n    .command(\"setup\")\n    .description(t(\"cli.light.setup_tools.description\"))\n    .action(() => {\n      const configPath = resolveConfigPath();\n      if (!existsSync(configPath)) {\n        exitError(\"CONFIG_NOT_FOUND\", t(\"errors.CONFIG_NOT_FOUND\", { path: configPath }));\n      }\n\n      let cfg: JsonObject = {};\n      try {\n        const raw = readFileSync(configPath, \"utf-8\");\n        const parsed = JSON.parse(raw);\n        if (isObject(parsed)) cfg = parsed;\n      } catch (err: any) {\n        exitError(\"CONFIG_INVALID\", t(\"errors.CONFIG_INVALID\", { detail: err?.message ?? String(err) }));\n      }\n\n      const result = upsertLightRuleToolsAlsoAllow(cfg);\n      try {\n        mkdirSync(dirname(configPath), { recursive: true });\n        writeFileSync(configPath, JSON.stringify(cfg, null, 2) + \"\\n\", \"utf-8\");\n      } catch (err: any) {\n        exitError(\"WRITE_FAILED\", t(\"errors.WRITE_FAILED\", { detail: err?.message ?? String(err) }));\n      }\n\n      output({\n        ok: true,\n        configPath,\n        changed: result.globalChanged || result.mainAgentChanged,\n        updates: {\n          toolsAlsoAllow: result.globalChanged ? \"added\" : \"already_exists\",\n          mainAgentAlsoAllow: result.mainAgentChanged ? \"added\" : \"already_exists\",\n        },\n        next: t(\"light.setup.next_restart\"),\n      });\n    });\n}\n",
    "export const LIGHT_RULE_GATEWAY_METHODS = {\n  list: \"lightrules.list\",\n  create: \"lightrules.create\",\n  update: \"lightrules.update\",\n  delete: \"lightrules.delete\",\n} as const;\n\nexport const LIGHT_RULE_GATEWAY_METHOD_LIST = [\n  LIGHT_RULE_GATEWAY_METHODS.list,\n  LIGHT_RULE_GATEWAY_METHODS.create,\n  LIGHT_RULE_GATEWAY_METHODS.update,\n  LIGHT_RULE_GATEWAY_METHODS.delete,\n] as const;\n\nexport const LIGHT_RULE_TOOL_NAMES = {\n  list: \"lightrules_list\",\n  create: \"lightrules_create\",\n  update: \"lightrules_update\",\n  delete: \"lightrules_delete\",\n} as const;\n\nexport const LIGHT_RULE_TOOL_NAME_LIST = [\n  LIGHT_RULE_TOOL_NAMES.list,\n  LIGHT_RULE_TOOL_NAMES.create,\n  LIGHT_RULE_TOOL_NAMES.update,\n  LIGHT_RULE_TOOL_NAMES.delete,\n] as const;\n",
    "import { t } from \"../i18n/index.js\";\nimport type { TunnelStatusInfo } from \"./relay-client.js\";\n\ntype TunnelLockSnapshot = {\n  exists: boolean;\n  pid: number | null;\n  startedAt: string | null;\n  active: boolean | null;\n};\n\nexport function formatTunnelStatusMessage(status: TunnelStatusInfo): string {\n  switch (status.state) {\n    case \"connected\":\n      return t(\"tunnel.status.connected\", { since: status.since });\n    case \"connecting\":\n      return t(\"tunnel.status.connecting\", {\n        since: status.since,\n        attempt: status.reconnectAttempt,\n      });\n    case \"disconnected\": {\n      const reasonSuffix = status.lastDisconnectReason\n        ? t(\"tunnel.status.disconnected.reason\", {\n            reason: status.lastDisconnectReason,\n          })\n        : \"\";\n      return t(\"tunnel.status.disconnected\", {\n        since: status.since,\n        reasonSuffix,\n        attempt: status.reconnectAttempt,\n      });\n    }\n    case \"stopped\":\n      return t(\"tunnel.status.stopped\", { since: status.since });\n    default:\n      return t(\"tunnel.status.unknown\", { state: status.state });\n  }\n}\n\nexport function formatStaleTunnelStatusMessage(\n  status: TunnelStatusInfo,\n  lock: TunnelLockSnapshot,\n): string {\n  const prefix = t(\"tunnel.issue.stale.connected_prefix\", { since: status.since });\n\n  if (!lock.exists) {\n    return prefix + t(\"tunnel.issue.stale.no_lock\");\n  }\n\n  if (lock.pid === null || lock.startedAt === null) {\n    return prefix + t(\"tunnel.issue.stale.incomplete_lock\");\n  }\n\n  if (lock.active === false) {\n    return prefix + t(\"tunnel.issue.stale.dead_pid\", { pid: lock.pid });\n  }\n\n  return prefix + t(\"tunnel.issue.stale.lock_newer\", {\n    lockStartedAt: lock.startedAt,\n  });\n}\n",
    "import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { t } from \"../i18n/index.js\";\nimport type { TunnelStatusInfo } from \"./relay-client.js\";\nimport {\n  formatStaleTunnelStatusMessage,\n} from \"./messages.js\";\n\nexport const TUNNEL_STATUS_REL_PATH = join(\n  \"plugins\",\n  \"phone-notifications\",\n  \"tunnel-status.json\",\n);\nexport const TUNNEL_LOCK_REL_PATH = join(\n  \"plugins\",\n  \"phone-notifications\",\n  \"relay-tunnel.lock\",\n);\n\ntype TunnelState = TunnelStatusInfo[\"state\"];\n\ninterface TunnelLockInfo {\n  pid: number;\n  startedAt: string;\n}\n\nexport interface TunnelStatusAssessment {\n  status: TunnelStatusInfo | null;\n  issueCode: \"STATUS_NOT_FOUND\" | \"STATUS_INVALID\" | \"STATUS_STALE\" | null;\n  issueMessage: string | null;\n  statusFilePath: string;\n  lockFilePath: string;\n  lock: {\n    exists: boolean;\n    pid: number | null;\n    startedAt: string | null;\n    active: boolean | null;\n  };\n}\n\nfunction isTunnelState(value: unknown): value is TunnelState {\n  return (\n    value === \"connected\" ||\n    value === \"connecting\" ||\n    value === \"disconnected\" ||\n    value === \"stopped\"\n  );\n}\n\nfunction isTunnelStatusInfo(value: unknown): value is TunnelStatusInfo {\n  if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n  const obj = value as Record<string, unknown>;\n  return (\n    isTunnelState(obj.state) &&\n    typeof obj.since === \"string\" &&\n    typeof obj.reconnectAttempt === \"number\" &&\n    (obj.lastDisconnectReason === undefined ||\n      typeof obj.lastDisconnectReason === \"string\")\n  );\n}\n\nfunction parseTunnelLockInfo(value: unknown): TunnelLockInfo | null {\n  if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n  const obj = value as Record<string, unknown>;\n  return typeof obj.pid === \"number\" && typeof obj.startedAt === \"string\"\n    ? { pid: obj.pid, startedAt: obj.startedAt }\n    : null;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n  if (!Number.isInteger(pid) || pid <= 0) return false;\n  if (pid === process.pid) return true;\n  try {\n    process.kill(pid, 0);\n    return true;\n  } catch (err: any) {\n    return err?.code === \"EPERM\";\n  }\n}\n\nfunction isStatusOlderThanLock(\n  statusSince: string,\n  lockStartedAt: string,\n): boolean {\n  const statusTs = Date.parse(statusSince);\n  const lockTs = Date.parse(lockStartedAt);\n  if (Number.isNaN(statusTs) || Number.isNaN(lockTs)) return false;\n  return statusTs + 1000 < lockTs;\n}\n\nexport function assessTunnelStatus(stateDir: string): TunnelStatusAssessment {\n  const statusFilePath = join(stateDir, TUNNEL_STATUS_REL_PATH);\n  const lockFilePath = join(stateDir, TUNNEL_LOCK_REL_PATH);\n\n  if (!existsSync(statusFilePath)) {\n    return {\n      status: null,\n      issueCode: \"STATUS_NOT_FOUND\",\n      issueMessage: t(\"tunnel.issue.not_found\"),\n      statusFilePath,\n      lockFilePath,\n      lock: {\n        exists: existsSync(lockFilePath),\n        pid: null,\n        startedAt: null,\n        active: null,\n      },\n    };\n  }\n\n  let rawStatus: unknown;\n  try {\n    rawStatus = JSON.parse(readFileSync(statusFilePath, \"utf-8\"));\n  } catch {\n    return {\n      status: null,\n      issueCode: \"STATUS_INVALID\",\n      issueMessage: t(\"tunnel.issue.invalid.parse\"),\n      statusFilePath,\n      lockFilePath,\n      lock: {\n        exists: existsSync(lockFilePath),\n        pid: null,\n        startedAt: null,\n        active: null,\n      },\n    };\n  }\n\n  if (!isTunnelStatusInfo(rawStatus)) {\n    return {\n      status: null,\n      issueCode: \"STATUS_INVALID\",\n      issueMessage: t(\"tunnel.issue.invalid.fields\"),\n      statusFilePath,\n      lockFilePath,\n      lock: {\n        exists: existsSync(lockFilePath),\n        pid: null,\n        startedAt: null,\n        active: null,\n      },\n    };\n  }\n\n  const status = rawStatus;\n  const lockExists = existsSync(lockFilePath);\n  let lockInfo: TunnelLockInfo | null = null;\n\n  if (lockExists) {\n    try {\n      lockInfo = parseTunnelLockInfo(JSON.parse(readFileSync(lockFilePath, \"utf-8\")));\n    } catch {\n      lockInfo = null;\n    }\n  }\n\n  const lock = {\n    exists: lockExists,\n    pid: lockInfo?.pid ?? null,\n    startedAt: lockInfo?.startedAt ?? null,\n    active: lockInfo ? isProcessAlive(lockInfo.pid) : null,\n  };\n\n  if (status.state === \"connected\") {\n    const isStale =\n      !lock.exists ||\n      lock.pid === null ||\n      lock.startedAt === null ||\n      lock.active === false ||\n      isStatusOlderThanLock(status.since, lock.startedAt);\n\n    if (isStale) {\n      return {\n        status,\n        issueCode: \"STATUS_STALE\",\n        issueMessage: formatStaleTunnelStatusMessage(status, lock),\n        statusFilePath,\n        lockFilePath,\n        lock,\n      };\n    }\n  }\n\n  return {\n    status,\n    issueCode: null,\n    issueMessage: null,\n    statusFilePath,\n    lockFilePath,\n    lock,\n  };\n}\n",
    "import { loadApiKey } from \"../auth/credentials.js\";\nimport { getEnvUrls } from \"../env.js\";\nimport { output, exitError } from \"./helpers.js\";\nimport type { CliCommand, CliContext } from \"./helpers.js\";\nimport { formatTunnelStatusMessage } from \"../tunnel/messages.js\";\nimport { assessTunnelStatus } from \"../tunnel/status.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerTunnelStatus(ntf: CliCommand, ctx: CliContext): void {\n  ntf\n    .command(\"tunnel-status\")\n    .description(t(\"cli.tunnel.status.description\"))\n    .action(async () => {\n      const tunnelUrl = getEnvUrls().relayTunnelUrl;\n      const apiKey = loadApiKey();\n\n      if (!tunnelUrl) {\n        exitError(\"TUNNEL_NOT_CONFIGURED\");\n      }\n\n      if (!apiKey) {\n        exitError(\"TOKEN_MISSING\");\n      }\n\n      if (!ctx.stateDir) {\n        exitError(\"STATE_DIR_UNAVAILABLE\");\n      }\n\n      const assessment = assessTunnelStatus(ctx.stateDir);\n      const status = assessment.status;\n\n      if (!status) {\n        exitError(\n          assessment.issueCode ?? \"STATUS_NOT_FOUND\",\n          assessment.issueMessage ?? undefined,\n        );\n      }\n\n      if (assessment.issueCode) {\n        exitError(\n          assessment.issueCode,\n          assessment.issueMessage ?? formatTunnelStatusMessage(status),\n        );\n      }\n\n      const ok = status.state === \"connected\";\n      output({\n        ok,\n        tunnelUrl,\n        connection: {\n          state: status.state,\n          since: status.since,\n          reconnectAttempt: status.reconnectAttempt,\n          lastDisconnectReason: status.lastDisconnectReason,\n        },\n        runtime: {\n          lockOwnerPid: assessment.lock.pid,\n          lockOwnerStartedAt: assessment.lock.startedAt,\n          lockOwnerActive: assessment.lock.active,\n        },\n        message: formatTunnelStatusMessage(status),\n      });\n\n      if (!ok) process.exit(1);\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveNotificationsDir,\n  output,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerNtfStoragePath(ntf: CliCommand, ctx: CliContext): void {\n  ntf\n    .command(\"storage-path\")\n    .description(t(\"cli.storage_path.description\"))\n    .action(() => {\n      const dir = resolveNotificationsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"notifications\");\n      output({ ok: true, path: dir });\n    });\n}\n",
    "import { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n  type CliCommand,\n  type CliContext,\n  filterDateRange,\n  today,\n  daysAgo,\n  output,\n  exitError,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\n/** Resolve the plugin logs directory from stateDir */\nfunction resolveLogsDir(ctx: CliContext): string | null {\n  if (ctx.stateDir) {\n    const dir = join(\n      ctx.stateDir,\n      \"plugins\",\n      \"phone-notifications\",\n      \"logs\",\n    );\n    if (existsSync(dir)) return dir;\n  }\n  return null;\n}\n\n/** List available log date keys (YYYY-MM-DD) sorted descending */\nfunction listLogDateKeys(dir: string): string[] {\n  const pattern = /^(\\d{4}-\\d{2}-\\d{2})\\.log$/;\n  const keys: string[] = [];\n  for (const entry of readdirSync(dir, { withFileTypes: true })) {\n    if (!entry.isFile()) continue;\n    const m = pattern.exec(entry.name);\n    if (m) keys.push(m[1]);\n  }\n  return keys.sort().reverse();\n}\n\n/** Read log lines from a date file, optionally filtering by keyword */\nfunction collectLogLines(\n  dir: string,\n  dateKey: string,\n  keyword: string | undefined,\n  limit: number,\n  collected: string[],\n): void {\n  const filePath = join(dir, `${dateKey}.log`);\n  if (!existsSync(filePath)) return;\n\n  const content = readFileSync(filePath, \"utf-8\");\n  const lowerKeyword = keyword?.toLowerCase();\n\n  for (const line of content.split(\"\\n\")) {\n    if (collected.length >= limit) return;\n    if (!line) continue;\n    if (lowerKeyword && !line.toLowerCase().includes(lowerKeyword)) continue;\n    collected.push(`[${dateKey}] ${line}`);\n  }\n}\n\nexport function registerLogSearch(ntf: CliCommand, ctx: CliContext): void {\n  ntf\n    .command(\"log\")\n    .description(t(\"cli.log.description\"))\n    .option(\"--keyword <text>\", t(\"cli.log.opt.keyword\"))\n    .option(\"--from <date>\", t(\"cli.opt.from_date\"), daysAgo(7))\n    .option(\"--to <date>\", t(\"cli.opt.to_date\"), today())\n    .option(\"--limit <n>\", t(\"cli.log.opt.limit\"), \"50\")\n    .action(\n      (opts: {\n        keyword?: string;\n        from: string;\n        to: string;\n        limit: string;\n      }) => {\n        const dir = resolveLogsDir(ctx);\n        if (!dir) exitError(\"LOGS_UNAVAILABLE\");\n\n        const keys = filterDateRange(listLogDateKeys(dir), opts.from, opts.to);\n        const limit = parseInt(opts.limit, 10) || 50;\n        const results: string[] = [];\n\n        for (const dateKey of keys) {\n          if (results.length >= limit) break;\n          collectLogLines(dir, dateKey, opts.keyword, limit, results);\n        }\n\n        output({\n          ok: true,\n          keyword: opts.keyword ?? null,\n          total: results.length,\n          lines: results,\n        });\n      },\n    );\n}\n",
    "import { spawnSync } from \"node:child_process\";\nimport {\n  readPersistedEnvName,\n  saveEnvName,\n  getEnvUrls,\n  getAvailableEnvs,\n  type EnvName,\n} from \"../env.js\";\nimport { detectHostKind } from \"../host.js\";\nimport { resolveClawKind } from \"../profile/detect.js\";\nimport type { ClawKind } from \"../profile/types.js\";\nimport { output, exitError } from \"./helpers.js\";\nimport type { CliCommand } from \"./helpers.js\";\nimport { scheduleGatewayRestart } from \"../update/restart.js\";\nimport { t } from \"../i18n/index.js\";\n\nconst GATEWAY_RESTART_TIMEOUT_MS = 30_000;\n\nconst NOOP_LOGGER = {\n  info() {\n    // noop\n  },\n  warn() {\n    // noop\n  },\n  error() {\n    // noop\n  },\n};\n\nexport interface EnvShowPayload {\n  ok: true;\n  env: EnvName;\n  source: \".env\" | \"default\";\n  lightApiUrl: string;\n  relayTunnelUrl: string;\n  availableEnvs: EnvName[];\n}\n\nexport interface EnvReloadResult {\n  attempted: boolean;\n  ok: boolean;\n  method: \"signal\" | \"cli\" | \"skipped\";\n  command?: string;\n  message: string;\n  detail?: string;\n}\n\nexport interface EnvSwitchPayload {\n  ok: true;\n  message: string;\n  env: EnvName;\n  lightApiUrl: string;\n  relayTunnelUrl: string;\n  reload: EnvReloadResult;\n}\n\nexport interface EnvCliDeps {\n  readPersistedEnvName?: () => EnvName | undefined;\n  scheduleGatewayRestart?: () => { scheduled: boolean };\n  detectHostKind?: () => \"openclaw\" | \"qclaw\";\n  resolveClawKind?: () => ClawKind;\n  spawnSync?: typeof spawnSync;\n  hostCli?: string;\n}\n\nexport function buildEnvShowPayload(deps: EnvCliDeps = {}): EnvShowPayload {\n  const persistedEnv = deps.readPersistedEnvName?.() ?? readPersistedEnvName();\n  const env = persistedEnv ?? \"production\";\n  const urls = getEnvUrls(env);\n\n  return {\n    ok: true,\n    env,\n    source: persistedEnv ? \".env\" : \"default\",\n    lightApiUrl: urls.lightApiUrl,\n    relayTunnelUrl: urls.relayTunnelUrl,\n    availableEnvs: getAvailableEnvs(),\n  };\n}\n\nexport function triggerGatewayReloadAfterEnvSwitch(\n  deps: EnvCliDeps = {},\n): EnvReloadResult {\n  const scheduleRestart =\n    deps.scheduleGatewayRestart ??\n    (() => scheduleGatewayRestart(NOOP_LOGGER));\n  const scheduled = scheduleRestart();\n  if (scheduled.scheduled) {\n    return {\n      attempted: true,\n      ok: true,\n      method: \"signal\",\n      message: t(\"env.reload.gateway\"),\n    };\n  }\n\n  const clawKind = deps.resolveClawKind?.() ?? resolveClawKind();\n  if (clawKind === \"jvsclaw\") {\n    return {\n      attempted: false,\n      ok: false,\n      method: \"skipped\",\n      message: t(\"env.reload.jvsclaw\"),\n    };\n  }\n\n  const hostKind = deps.detectHostKind?.() ?? detectHostKind();\n  if (hostKind === \"qclaw\") {\n    return {\n      attempted: false,\n      ok: false,\n      method: \"skipped\",\n      message: t(\"env.reload.qclaw\"),\n    };\n  }\n\n  const hostCli = deps.hostCli?.trim() || process.env.HOST_CLI?.trim() || \"openclaw\";\n  const command = `${hostCli} gateway restart`;\n  const run = deps.spawnSync ?? spawnSync;\n  const result = run(hostCli, [\"gateway\", \"restart\"], {\n    encoding: \"utf-8\",\n    stdio: \"pipe\",\n    timeout: GATEWAY_RESTART_TIMEOUT_MS,\n  });\n\n  if (!result.error && result.status === 0) {\n    return {\n      attempted: true,\n      ok: true,\n      method: \"cli\",\n      command,\n      message: t(\"env.reload.command\", { command }),\n    };\n  }\n\n  const stderr =\n    typeof result.stderr === \"string\" ? result.stderr.trim() : \"\";\n  const errorMessage = result.error?.message?.trim();\n  return {\n    attempted: true,\n    ok: false,\n    method: \"cli\",\n    command,\n    message: t(\"env.reload.manual\", { command }),\n    detail:\n      stderr ||\n      errorMessage ||\n      (typeof result.status === \"number\"\n        ? `exit status=${result.status}`\n        : undefined),\n  };\n}\n\nexport function buildEnvSwitchPayload(\n  envName: EnvName,\n  deps: EnvCliDeps = {},\n): EnvSwitchPayload {\n  saveEnvName(envName);\n  const urls = getEnvUrls(envName);\n  const reload = triggerGatewayReloadAfterEnvSwitch(deps);\n\n  return {\n    ok: true,\n    message: reload.ok\n      ? t(\"env.switched.with_reload\", { env: envName })\n      : t(\"env.switched\", { env: envName }),\n    env: envName,\n    lightApiUrl: urls.lightApiUrl,\n    relayTunnelUrl: urls.relayTunnelUrl,\n    reload,\n  };\n}\n\nexport function registerEnvCli(ntf: CliCommand, deps: EnvCliDeps = {}): void {\n  const env = ntf.command(\"env\").description(t(\"cli.env.description\"));\n\n  env\n    .command(\"show\")\n    .description(t(\"cli.env.show.description\"))\n    .action(() => {\n      output(buildEnvShowPayload(deps));\n    });\n\n  env\n    .command(\"switch <env>\")\n    .description(t(\"cli.env.set.description\"))\n    .action((envName: string) => {\n      const available = getAvailableEnvs();\n      if (!available.includes(envName as any)) {\n        exitError(\"INVALID_ENV\", {\n          env: envName,\n          available: available.join(\", \"),\n        });\n      }\n      output(buildEnvSwitchPayload(envName as EnvName, deps));\n    });\n}\n",
    "import { t } from \"../i18n/index.js\";\nimport type { Logger } from \"../logger.js\";\n\ntype CommandsConfigLike = {\n  commands?: {\n    restart?: boolean;\n  };\n};\n\nconst DEFAULT_RESTART_GRACE_MS = 1_500;\n\nexport interface GatewayRestartScheduleDeps {\n  loadConfig?: () => CommandsConfigLike | undefined;\n  getListenerCount?: (signal: NodeJS.Signals) => number;\n  emitSignal?: (signal: NodeJS.Signals) => boolean;\n  schedule?: (task: () => void) => void;\n  beforeSchedule?: () => void;\n}\n\nexport interface GatewayRestartScheduleResult {\n  scheduled: boolean;\n  reason?: string;\n  suggestion?: string;\n  nextActions?: string[];\n}\n\n/**\n * planGatewayRestart 的两阶段返回：\n * - scheduled=true 时 `commit` 必定存在；调用它才会真正注册 SIGUSR1 fire。\n * - scheduled=false 时返回失败原因与用户提示，commit 为 undefined。\n *\n * 拆出 commit 的目的：让网关方法可以在 RPC `respond()` 同步执行完毕后再触发重启，\n * 确保 app 一定先收到回复，再发生 gateway 重启，避免依赖 grace window 的概率保证。\n */\nexport interface GatewayRestartPlan {\n  scheduled: boolean;\n  reason?: string;\n  suggestion?: string;\n  nextActions?: string[];\n  commit?: () => void;\n}\n\nexport function planGatewayRestart(\n  logger: Logger,\n  deps: GatewayRestartScheduleDeps = {},\n): GatewayRestartPlan {\n  try {\n    const cfg = deps.loadConfig?.();\n    if (cfg?.commands?.restart === false) {\n      logger.warn(\"更新后跳过 gateway 重启: commands.restart=false\");\n      return {\n        scheduled: false,\n        reason: \"commands.restart=false\",\n        suggestion: t(\"update.fail.restart_disabled\"),\n        nextActions: [t(\"update.action.manual_restart\"), t(\"update.action.enable_restart\")],\n      };\n    }\n  } catch (err) {\n    logger.warn(`更新后检查 gateway 重启配置失败: ${String(err)}`);\n  }\n\n  const getListenerCount =\n    deps.getListenerCount ?? ((signal: NodeJS.Signals) => process.listenerCount(signal));\n  if (getListenerCount(\"SIGUSR1\") < 1) {\n    logger.warn(\"更新后跳过 gateway 重启: 当前进程未注册 SIGUSR1 监听器\");\n    return {\n      scheduled: false,\n      reason: \"SIGUSR1 listener unavailable\",\n      suggestion: t(\"update.fail.no_sigusr1\"),\n      nextActions: [t(\"update.action.manual_restart\")],\n    };\n  }\n\n  try {\n    deps.beforeSchedule?.();\n  } catch (err) {\n    logger.warn(`更新后启动后台 updater 失败: ${String(err)}`);\n    return {\n      scheduled: false,\n      reason: err instanceof Error ? err.message : String(err),\n      suggestion: t(\"update.fail.bg_start\"),\n      nextActions: [t(\"update.action.retry_later\"), t(\"update.action.report\")],\n    };\n  }\n\n  const emitSignal =\n    deps.emitSignal ?? ((signal: NodeJS.Signals) => process.emit(signal));\n  const schedule =\n    deps.schedule ?? ((task: () => void) => { setTimeout(task, DEFAULT_RESTART_GRACE_MS); });\n\n  return {\n    scheduled: true,\n    commit: () => {\n      schedule(() => {\n        try {\n          const accepted = emitSignal(\"SIGUSR1\");\n          if (accepted) {\n            logger.info(\"更新完成，已触发 gateway SIGUSR1 重启\");\n          } else {\n            logger.warn(\"更新完成，但 gateway SIGUSR1 信号未被处理\");\n          }\n        } catch (err) {\n          logger.warn(`更新后触发 gateway 重启失败: ${String(err)}`);\n        }\n      });\n    },\n  };\n}\n\n/**\n * 兼容入口：等价于 `planGatewayRestart` + 立即 `commit()`。\n * 现存调用方（如对话通道 `plugin-update` tool 的 finalize 流程）继续走这个路径，\n * 保留原有\"一步式调度\"行为。\n *\n * 网关通道 `plugin.update` 已改为直接使用 `planGatewayRestart`，以便在 `respond()` 之后才触发 commit。\n */\nexport function scheduleGatewayRestart(\n  logger: Logger,\n  deps: GatewayRestartScheduleDeps = {},\n): GatewayRestartScheduleResult {\n  const plan = planGatewayRestart(logger, deps);\n  plan.commit?.();\n  return {\n    scheduled: plan.scheduled,\n    reason: plan.reason,\n    suggestion: plan.suggestion,\n    nextActions: plan.nextActions,\n  };\n}\n",
    "import { existsSync, readFileSync } from \"node:fs\";\nimport { createInterface } from \"node:readline\";\nimport { resolveConfigPath, resolveStateDir } from \"../host.js\";\nimport { output } from \"./helpers.js\";\nimport type { CliCommand, CliContext } from \"./helpers.js\";\nimport type { CheckResult, JsonObject, Severity } from \"./doctor/types.js\";\nimport { allCheckers } from \"./doctor/checkers.js\";\nimport { t } from \"../i18n/index.js\";\n\nfunction isObject(v: unknown): v is JsonObject {\n  return !!v && typeof v === \"object\" && !Array.isArray(v);\n}\n\nfunction readConfig(configPath: string): JsonObject {\n  if (!existsSync(configPath)) return {};\n  try {\n    const parsed = JSON.parse(readFileSync(configPath, \"utf-8\"));\n    return isObject(parsed) ? parsed : {};\n  } catch {\n    return {};\n  }\n}\n\nfunction severityIcon(s: Severity): string {\n  switch (s) {\n    case \"critical\":\n      return \"\\x1b[31m[CRITICAL]\\x1b[0m\";\n    case \"warn\":\n      return \"\\x1b[33m[WARN]\\x1b[0m\";\n    case \"info\":\n      return \"\\x1b[36m[INFO]\\x1b[0m\";\n  }\n}\n\nfunction severityOrder(s: Severity): number {\n  switch (s) {\n    case \"critical\":\n      return 0;\n    case \"warn\":\n      return 1;\n    case \"info\":\n      return 2;\n  }\n}\n\nfunction confirm(question: string): Promise<boolean> {\n  const rl = createInterface({ input: process.stdin, output: process.stderr });\n  return new Promise((resolve) => {\n    rl.question(question, (answer) => {\n      rl.close();\n      resolve(answer.trim().toLowerCase() === \"y\");\n    });\n  });\n}\n\nasync function runDoctor(ctx: CliContext, json: boolean, fix?: boolean): Promise<void> {\n  const stateDir = resolveStateDir(ctx.stateDir);\n  const configPath = resolveConfigPath(stateDir);\n  const cfg = readConfig(configPath);\n\n  const checkCtx = { cfg, configPath, stateDir };\n\n  // 执行所有 checker\n  const issues: CheckResult[] = [];\n  for (const checker of allCheckers) {\n    const result = await checker(checkCtx);\n    if (result) issues.push(result);\n  }\n\n  // 按严重级别排序\n  issues.sort((a, b) => severityOrder(a.severity) - severityOrder(b.severity));\n\n  // 统计\n  const summary = { critical: 0, warn: 0, info: 0 };\n  for (const issue of issues) {\n    summary[issue.severity]++;\n  }\n\n  // --json 模式\n  if (json) {\n    output({\n      ok: issues.length === 0,\n      summary,\n      checks: issues.map((i) => ({\n        id: i.id,\n        severity: i.severity,\n        title: i.title,\n        detail: i.detail,\n        autoFixable: i.fix !== null,\n        fixDescription: i.fixDescription,\n      })),\n    });\n    if (issues.length > 0) process.exit(1);\n    return;\n  }\n\n  // 人类可读输出\n  const log = console.error; // stderr，不污染 stdout\n  log(`\\n\\x1b[1m${t(\"doctor.checking\")}\\x1b[0m\\n`);\n\n  if (issues.length === 0) {\n    log(`\\x1b[32m${t(\"doctor.all_pass\")}\\x1b[0m\\n`);\n    output({ ok: true, summary });\n    return;\n  }\n\n  for (const issue of issues) {\n    log(`${severityIcon(issue.severity)} ${issue.title}`);\n    log(`  ↳ ${issue.detail}`);\n    log(`  ↳ ${t(\"doctor.fix_label\", { fix: issue.fixDescription })}`);\n    log();\n  }\n\n  log(\n    `${t(\"doctor.summary\", {\n      critical: summary.critical,\n      warn: summary.warn,\n      info: summary.info,\n    })}\\n`,\n  );\n\n  // 找出可自动修复的\n  const fixable = issues.filter((i) => i.fix !== null);\n\n  if (fixable.length === 0) {\n    log(`${t(\"doctor.manual_only\")}\\n`);\n    output({ ok: false, summary });\n    process.exit(1);\n    return;\n  }\n\n  log(t(\"doctor.fixable_found\", { count: fixable.length }));\n  for (const issue of fixable) {\n    log(`  • ${issue.title} → ${issue.fixDescription}`);\n  }\n  log();\n\n  const yes = fix === true || (await confirm(t(\"doctor.confirm_fix\")));\n  if (!yes) {\n    log(`\\n${t(\"doctor.cancelled\")}\\n`);\n    output({ ok: false, summary, fixed: 0 });\n    process.exit(1);\n    return;\n  }\n\n  log();\n  let fixed = 0;\n  for (const issue of fixable) {\n    try {\n      await issue.fix!();\n      log(`\\x1b[32m✅\\x1b[0m ${issue.title} → ${issue.fixDescription}`);\n      fixed++;\n    } catch (err: any) {\n      log(\n        `\\x1b[31m❌\\x1b[0m ${t(\"doctor.fix_failed\", {\n          title: issue.title,\n          message: err?.message ?? String(err),\n        })}`,\n      );\n    }\n  }\n\n  const manualCount = issues.length - fixable.length;\n  if (manualCount > 0) {\n    log(`\\n⚠️  ${t(\"doctor.manual_remaining\", { count: manualCount })}`);\n  }\n\n  log(`\\n${t(\"doctor.fix_done\", { fixed, total: fixable.length })}\\n`);\n  output({ ok: fixed === fixable.length && manualCount === 0, summary, fixed });\n  if (fixed < fixable.length || manualCount > 0) process.exit(1);\n}\n\nexport function registerDoctor(ntf: CliCommand, ctx: CliContext): void {\n  ntf\n    .command(\"doctor\")\n    .description(t(\"cli.doctor.description\"))\n    .option(\"--json\", t(\"cli.opt.json\"))\n    .option(\"--fix\", t(\"cli.doctor.opt.fix\"))\n    .action((opts: { json?: boolean; fix?: boolean }) => {\n      return runDoctor(ctx, opts.json === true, opts.fix);\n    });\n}\n",
    "import { readFileSync, writeFileSync, copyFileSync } from \"node:fs\";\nimport { t } from \"../../i18n/index.js\";\nimport type { Checker, JsonObject } from \"./types.js\";\n\nfunction isObject(v: unknown): v is JsonObject {\n  return !!v && typeof v === \"object\" && !Array.isArray(v);\n}\n\nexport const checkDangerousFlags: Checker = ({ cfg, configPath }) => {\n  const gateway = cfg.gateway;\n  if (!isObject(gateway)) return null;\n\n  const controlUi = gateway.controlUi;\n  if (!isObject(controlUi)) return null;\n\n  if (controlUi.dangerouslyDisableDeviceAuth !== true) return null;\n\n  return {\n    id: \"dangerous-flags\",\n    severity: \"critical\",\n    title: t(\"doctor.dangerous_flags.title\"),\n    detail: t(\"doctor.dangerous_flags.detail\"),\n    fixDescription: t(\"doctor.dangerous_flags.fix\"),\n    fix: () => {\n      const raw = readFileSync(configPath, \"utf-8\");\n      const config = JSON.parse(raw) as JsonObject;\n      const gw = config.gateway as JsonObject;\n      const cui = gw.controlUi as JsonObject;\n      cui.dangerouslyDisableDeviceAuth = false;\n      copyFileSync(configPath, configPath + \".bak\");\n      writeFileSync(configPath, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n    },\n  };\n};\n",
    "import { t } from \"../../i18n/index.js\";\nimport type { Checker, JsonObject } from \"./types.js\";\n\nfunction isObject(v: unknown): v is JsonObject {\n  return !!v && typeof v === \"object\" && !Array.isArray(v);\n}\n\nexport const checkTrustedProxy: Checker = ({ cfg }) => {\n  const gateway = cfg.gateway;\n  if (!isObject(gateway)) return null;\n\n  const auth = gateway.auth;\n  if (!isObject(auth)) return null;\n\n  if (auth.mode !== \"trusted-proxy\") return null;\n\n  return {\n    id: \"trusted-proxy\",\n    severity: \"critical\",\n    title: t(\"doctor.trusted_proxy.title\"),\n    detail: t(\"doctor.trusted_proxy.detail\"),\n    fixDescription: t(\"doctor.trusted_proxy.fix\"),\n    fix: null,\n  };\n};\n\nexport const checkTrustedProxyAllowUsers: Checker = ({ cfg }) => {\n  const gateway = cfg.gateway;\n  if (!isObject(gateway)) return null;\n\n  const auth = gateway.auth;\n  if (!isObject(auth)) return null;\n\n  if (auth.mode !== \"trusted-proxy\") return null;\n\n  const tp = auth.trustedProxy;\n  if (!isObject(tp)) return warnEmpty();\n\n  const allowUsers = tp.allowUsers;\n  if (!Array.isArray(allowUsers) || allowUsers.length === 0) return warnEmpty();\n\n  return null;\n};\n\nfunction warnEmpty() {\n  return {\n    id: \"trusted-proxy-allow-users\",\n    severity: \"warn\" as const,\n    title: t(\"doctor.trusted_proxy_allow_users.title\"),\n    detail: t(\"doctor.trusted_proxy_allow_users.detail\"),\n    fixDescription: t(\"doctor.trusted_proxy_allow_users.fix\"),\n    fix: null,\n  };\n}\n",
    "import { statSync, chmodSync } from \"node:fs\";\nimport { t } from \"../../i18n/index.js\";\nimport type { Checker } from \"./types.js\";\n\nexport const checkStateDirPerms: Checker = ({ stateDir }) => {\n  let mode: number;\n  try {\n    mode = statSync(stateDir).mode;\n  } catch {\n    return null;\n  }\n\n  // 检查 group 和 other 是否有任何权限\n  const otherBits = mode & 0o077;\n  if (otherBits === 0) return null;\n\n  const modeStr = \"0\" + (mode & 0o777).toString(8);\n\n  return {\n    id: \"state-dir-perms\",\n    severity: \"warn\",\n    title: t(\"doctor.state_dir_perms.title\", { stateDir, mode: modeStr }),\n    detail: t(\"doctor.state_dir_perms.detail\"),\n    fixDescription: \"chmod 700 \" + stateDir,\n    fix: () => {\n      chmodSync(stateDir, 0o700);\n    },\n  };\n};\n",
    "import { t } from \"../../i18n/index.js\";\nimport type { Checker, JsonObject } from \"./types.js\";\n\nfunction isObject(v: unknown): v is JsonObject {\n  return !!v && typeof v === \"object\" && !Array.isArray(v);\n}\n\nexport const checkToolPolicy: Checker = ({ cfg }) => {\n  const agents = cfg.agents;\n  if (!isObject(agents)) return null;\n\n  const list = agents.list;\n  if (!Array.isArray(list)) return null;\n\n  const permissiveAgents: string[] = [];\n\n  for (const agent of list) {\n    if (!isObject(agent)) continue;\n    const id = String(agent.id ?? \"unknown\");\n\n    // 如果 agent 没有设置 toolPolicy / profile，则视为使用 default（宽松）\n    const tools = agent.tools;\n    if (!isObject(tools)) {\n      permissiveAgents.push(id);\n      continue;\n    }\n\n    const profile = tools.profile;\n    if (!profile || profile === \"default\") {\n      permissiveAgents.push(id);\n    }\n  }\n\n  if (permissiveAgents.length === 0) return null;\n\n  return {\n    id: \"tool-policy\",\n    severity: \"warn\",\n    title: t(\"doctor.tool_policy.title\"),\n    detail: t(\"doctor.tool_policy.detail\", {\n      agents: permissiveAgents.join(\", \"),\n    }),\n    fixDescription: t(\"doctor.tool_policy.fix\"),\n    fix: null,\n  };\n};\n",
    "import { loadApiKey } from \"../../auth/credentials.js\";\nimport { t } from \"../../i18n/index.js\";\nimport type { Checker } from \"./types.js\";\n\nexport const checkCredentials: Checker = () => {\n  const apiKey = loadApiKey();\n  if (apiKey) return null;\n\n  return {\n    id: \"credentials\",\n    severity: \"critical\",\n    title: t(\"doctor.credentials.title\"),\n    detail: t(\"doctor.credentials.detail\"),\n    fixDescription: t(\"doctor.credentials.fix\"),\n    fix: null,\n  };\n};\n",
    "import { t } from \"../../i18n/index.js\";\nimport type { Checker } from \"./types.js\";\nimport { assessTunnelStatus } from \"../../tunnel/status.js\";\n\nexport const checkTunnel: Checker = ({ stateDir }) => {\n  const assessment = assessTunnelStatus(stateDir);\n  const status = assessment.status;\n\n  if (assessment.issueCode === \"STATUS_NOT_FOUND\") {\n    return {\n      id: \"tunnel\",\n      severity: \"warn\",\n      title: t(\"doctor.tunnel.not_found.title\"),\n      detail: t(\"doctor.tunnel.not_found.detail\"),\n      fixDescription: t(\"doctor.tunnel.not_found.fix\"),\n      fix: null,\n    };\n  }\n\n  if (assessment.issueCode === \"STATUS_INVALID\") {\n    return {\n      id: \"tunnel\",\n      severity: \"warn\",\n      title: t(\"doctor.tunnel.invalid.title\"),\n      detail: t(\"doctor.tunnel.invalid.detail\"),\n      fixDescription: t(\"doctor.tunnel.invalid.fix\"),\n      fix: null,\n    };\n  }\n\n  if (assessment.issueCode === \"STATUS_STALE\") {\n    return {\n      id: \"tunnel\",\n      severity: \"warn\",\n      title: t(\"doctor.tunnel.stale.title\"),\n      detail: t(\"doctor.tunnel.stale.detail\"),\n      fixDescription: t(\"doctor.tunnel.stale.fix\"),\n      fix: null,\n    };\n  }\n\n  if (!status || status.state === \"connected\") return null;\n\n  const reasonSuffix = status.lastDisconnectReason\n    ? t(\"doctor.tunnel.disconnected.reason\", {\n        reason: status.lastDisconnectReason,\n      })\n    : \"\";\n\n  return {\n    id: \"tunnel\",\n    severity: \"warn\",\n    title: t(\"doctor.tunnel.disconnected.title\", { state: status.state }),\n    detail: t(\"doctor.tunnel.disconnected.detail\", {\n      since: status.since,\n      state: status.state,\n      reasonSuffix,\n      attempts: status.reconnectAttempt,\n    }),\n    fixDescription: t(\"doctor.tunnel.disconnected.fix\"),\n    fix: null,\n  };\n};\n",
    "import { connect } from \"node:net\";\nimport { t } from \"../../i18n/index.js\";\nimport {\n  resolveLocalGatewayBaseUrl,\n  resolveLocalGatewayTcpTarget,\n} from \"../../tunnel/gateway-target.js\";\nimport type { Checker } from \"./types.js\";\n\nconst PROBE_TIMEOUT_MS = 1200;\n\ninterface TcpProbeResult {\n  ok: boolean;\n  error?: string;\n}\n\nfunction probeTcp(host: string, port: number): Promise<TcpProbeResult> {\n  return new Promise((resolve) => {\n    const socket = connect({ host, port });\n    let settled = false;\n\n    const finish = (result: TcpProbeResult) => {\n      if (settled) return;\n      settled = true;\n      socket.destroy();\n      resolve(result);\n    };\n\n    socket.setTimeout(PROBE_TIMEOUT_MS);\n    socket.once(\"connect\", () => finish({ ok: true }));\n    socket.once(\"timeout\", () => finish({ ok: false, error: \"timeout\" }));\n    socket.once(\"error\", (err) => finish({ ok: false, error: err.message }));\n  });\n}\n\nexport const checkLocalGateway: Checker = async ({ cfg }) => {\n  const resolution = resolveLocalGatewayBaseUrl({ config: cfg });\n  if (resolution.warning) {\n    return {\n      id: \"local-gateway\",\n      severity: \"warn\",\n      title: t(\"doctor.local_gateway.invalid_url.title\"),\n      detail: t(\"doctor.local_gateway.invalid_url.detail\", {\n        warning: resolution.warning,\n        baseUrl: resolution.baseUrl,\n      }),\n      fixDescription: t(\"doctor.local_gateway.invalid_url.fix\"),\n      fix: null,\n    };\n  }\n\n  if (resolution.tlsEnabled && !resolution.explicit) {\n    return {\n      id: \"local-gateway\",\n      severity: \"warn\",\n      title: t(\"doctor.local_gateway.tls.title\"),\n      detail: t(\"doctor.local_gateway.tls.detail\", {\n        baseUrl: resolution.baseUrl,\n      }),\n      fixDescription: t(\"doctor.local_gateway.tls.fix\"),\n      fix: null,\n    };\n  }\n\n  const target = resolveLocalGatewayTcpTarget(resolution.baseUrl);\n  if (!target) {\n    return {\n      id: \"local-gateway\",\n      severity: \"warn\",\n      title: t(\"doctor.local_gateway.unresolvable.title\"),\n      detail: t(\"doctor.local_gateway.unresolvable.detail\", {\n        baseUrl: resolution.baseUrl,\n      }),\n      fixDescription: t(\"doctor.local_gateway.unresolvable.fix\"),\n      fix: null,\n    };\n  }\n\n  const probe = await probeTcp(target.host, target.port);\n  if (probe.ok) return null;\n\n  return {\n    id: \"local-gateway\",\n    severity: \"warn\",\n    title: t(\"doctor.local_gateway.unreachable.title\"),\n    detail: t(\"doctor.local_gateway.unreachable.detail\", {\n      baseUrl: resolution.baseUrl,\n      errorSuffix: probe.error ? `: ${probe.error}` : \"\",\n    }),\n    fixDescription: t(\"doctor.local_gateway.unreachable.fix\"),\n    fix: null,\n  };\n};\n",
    "import { t } from \"../i18n/index.js\";\n\nconst DEFAULT_GATEWAY_PORT = \"18789\";\nconst DEFAULT_GATEWAY_HOST = \"127.0.0.1\";\n\nconst BASE_URL_ENV_KEYS = [\n  \"PHONE_NOTIFICATIONS_GATEWAY_BASE_URL\",\n  \"OPENCLAW_GATEWAY_BASE_URL\",\n  \"QCLAW_GATEWAY_BASE_URL\",\n] as const;\n\nconst PORT_ENV_KEYS = [\n  \"OPENCLAW_GATEWAY_PORT\",\n  \"QCLAW_GATEWAY_PORT\",\n] as const;\n\ninterface GatewayConfigLike {\n  gateway?: {\n    port?: unknown;\n    tls?: {\n      enabled?: unknown;\n    };\n  };\n}\n\nexport interface LocalGatewayBaseUrlResolution {\n  baseUrl: string;\n  source: string;\n  explicit: boolean;\n  tlsEnabled: boolean;\n  warning?: string;\n}\n\nexport interface LocalGatewayTcpTarget {\n  host: string;\n  port: number;\n}\n\nfunction trimToUndefined(value: unknown): string | undefined {\n  if (typeof value !== \"string\") return undefined;\n  const trimmed = value.trim();\n  return trimmed || undefined;\n}\n\nfunction firstEnv(\n  env: NodeJS.ProcessEnv,\n  keys: readonly string[],\n): { key: string; value: string } | undefined {\n  for (const key of keys) {\n    const value = trimToUndefined(env[key]);\n    if (value) return { key, value };\n  }\n  return undefined;\n}\n\nfunction normalizePort(value: unknown): string | undefined {\n  const raw =\n    typeof value === \"number\" && Number.isInteger(value)\n      ? String(value)\n      : trimToUndefined(value);\n  if (!raw || !/^\\d+$/.test(raw)) return undefined;\n\n  const port = Number.parseInt(raw, 10);\n  if (!Number.isInteger(port) || port <= 0 || port > 65_535) {\n    return undefined;\n  }\n  return String(port);\n}\n\nfunction normalizeBaseUrl(raw: string): string | undefined {\n  const withScheme = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(raw)\n    ? raw\n    : `http://${raw}`;\n\n  let parsed: URL;\n  try {\n    parsed = new URL(withScheme);\n  } catch {\n    return undefined;\n  }\n\n  if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n    return undefined;\n  }\n  if (!parsed.hostname) return undefined;\n  return `${parsed.protocol}//${parsed.host}`;\n}\n\nfunction isGatewayTlsEnabled(config: GatewayConfigLike): boolean {\n  return config.gateway?.tls?.enabled === true;\n}\n\nfunction resolveGatewayPort(params: {\n  config: GatewayConfigLike;\n  env: NodeJS.ProcessEnv;\n}): { port: string; source: string } {\n  const envPort = firstEnv(params.env, PORT_ENV_KEYS);\n  const normalizedEnvPort = envPort ? normalizePort(envPort.value) : undefined;\n  if (envPort && normalizedEnvPort) {\n    return { port: normalizedEnvPort, source: envPort.key };\n  }\n\n  const configPort = normalizePort(params.config.gateway?.port);\n  if (configPort) {\n    return { port: configPort, source: \"openclaw.json gateway.port\" };\n  }\n\n  return { port: DEFAULT_GATEWAY_PORT, source: \"default\" };\n}\n\nexport function resolveLocalGatewayBaseUrl(params: {\n  config?: unknown;\n  env?: NodeJS.ProcessEnv;\n} = {}): LocalGatewayBaseUrlResolution {\n  const config = (params.config ?? {}) as GatewayConfigLike;\n  const env = params.env ?? process.env;\n  const tlsEnabled = isGatewayTlsEnabled(config);\n  const envBaseUrl = firstEnv(env, BASE_URL_ENV_KEYS);\n\n  if (envBaseUrl) {\n    const normalized = normalizeBaseUrl(envBaseUrl.value);\n    if (normalized) {\n      return {\n        baseUrl: normalized,\n        source: envBaseUrl.key,\n        explicit: true,\n        tlsEnabled,\n      };\n    }\n  }\n\n  const { port, source } = resolveGatewayPort({ config, env });\n  const baseUrl = `http://${DEFAULT_GATEWAY_HOST}:${port}`;\n  const warning = envBaseUrl\n    ? t(\"plugin.tunnel.invalid_gateway_env\", {\n        key: envBaseUrl.key,\n        value: envBaseUrl.value,\n      })\n    : undefined;\n\n  return {\n    baseUrl,\n    source,\n    explicit: false,\n    tlsEnabled,\n    warning,\n  };\n}\n\n/**\n * 把 relay 下发的 path 解析成本地 gateway 的绝对 URL，并把 origin 钉死在 baseUrl 上。\n *\n * relay 帧里的 `path` 完全由对端控制，不能直接交给 `new URL(path, base)`：\n * 绝对 URL（`http://evil/x`）和协议相对 URL（`//evil/x`）都会让 base 被整体丢弃，\n * 字符串拼接则会被 userinfo（`@evil/x`）改写 host。两种写法都会把本地 gateway\n * 的 token/password 发到外部主机，因此这里只接受以单个 `/` 开头的相对路径，\n * 并在解析后再次校验 origin 未被改写。\n *\n * @returns 解析后的 URL；path 非法或 origin 被改写时返回 null。\n */\nexport function resolveGatewayRequestUrl(\n  baseUrl: string,\n  path: string,\n): URL | null {\n  // 必须是相对路径：排除绝对 URL（有 scheme）、协议相对 URL（//host）、userinfo 注入（@host）\n  if (typeof path !== \"string\" || !path.startsWith(\"/\") || path.startsWith(\"//\")) {\n    return null;\n  }\n  // 反斜杠在部分 URL 解析器里等价于 `/`，`/\\evil.com` 可能被当成协议相对 URL\n  if (path.startsWith(\"/\\\\\")) {\n    return null;\n  }\n\n  let base: URL;\n  let resolved: URL;\n  try {\n    base = new URL(baseUrl);\n    resolved = new URL(path, base);\n  } catch {\n    return null;\n  }\n\n  // 兜底：即便前面的字符串检查被绕过，origin 变了也一律拒绝\n  if (resolved.origin !== base.origin || resolved.protocol !== base.protocol) {\n    return null;\n  }\n  return resolved;\n}\n\n/** 同 resolveGatewayRequestUrl，但把 http/https 换成 ws/wss 用于 WebSocket 代理。 */\nexport function resolveGatewayWebSocketUrl(\n  baseUrl: string,\n  path: string,\n): URL | null {\n  const resolved = resolveGatewayRequestUrl(baseUrl, path);\n  if (!resolved) return null;\n  resolved.protocol = resolved.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n  return resolved;\n}\n\nexport function resolveLocalGatewayTcpTarget(\n  baseUrl: string,\n): LocalGatewayTcpTarget | null {\n  let parsed: URL;\n  try {\n    parsed = new URL(baseUrl);\n  } catch {\n    return null;\n  }\n\n  const port =\n    parsed.port\n      ? Number.parseInt(parsed.port, 10)\n      : parsed.protocol === \"https:\"\n        ? 443\n        : parsed.protocol === \"http:\"\n          ? 80\n          : Number.NaN;\n\n  if (!parsed.hostname || !Number.isInteger(port)) return null;\n  return { host: parsed.hostname, port };\n}\n",
    "import { t } from \"../../i18n/index.js\";\nimport type { Checker } from \"./types.js\";\n\nconst MIN_MAJOR = 22;\nconst MIN_MINOR = 12;\n\nexport const checkNodeVersion: Checker = () => {\n  const version = process.versions.node;\n  const [major, minor] = version.split(\".\").map(Number);\n\n  if (major > MIN_MAJOR || (major === MIN_MAJOR && minor >= MIN_MINOR)) {\n    return null;\n  }\n\n  const minVersion = `${MIN_MAJOR}.${MIN_MINOR}.0`;\n  return {\n    id: \"node-version\",\n    severity: \"warn\",\n    title: t(\"doctor.node_version.title\", { version }),\n    detail: t(\"doctor.node_version.detail\", { minVersion, version }),\n    fixDescription: t(\"doctor.node_version.fix\", { minVersion }),\n    fix: null,\n  };\n};\n",
    "import type { EnvName } from \"../env.js\";\nimport type { AutoUpdateConfig } from \"./types.js\";\n\nexport const PRODUCTION_UPDATE_BASE_URL = \"https://artifact.yoooclaw.com/plugin\";\nexport const TEST_UPDATE_BASE_URL = \"https://artifacts-test.yoooclaw.com/plugin\";\n\n/**\n * 解析自动更新频道。\n *\n * 默认规则：\n * - 生产环境的正式安装走 latest，避免正式客户端收到 beta 更新推送\n * - 生产环境的预发布安装继续走 beta，避免 beta 客户端漏掉后续修复\n * - 非生产环境用户显式配置时，以配置为准\n * - 非生产环境默认走 beta\n */\nexport function resolveUpdateChannel(params: {\n  configuredChannel?: AutoUpdateConfig[\"channel\"];\n  envName: EnvName;\n  installedVersion?: string;\n}): \"latest\" | \"beta\" {\n  if (params.envName === \"production\") {\n    return params.installedVersion?.includes(\"-\") ? \"beta\" : \"latest\";\n  }\n\n  if (params.configuredChannel) {\n    return params.configuredChannel;\n  }\n\n  return \"beta\";\n}\n\n/**\n * beta 订阅者同时检查 latest，确保正式版转正后能从 prerelease 平滑升级。\n * latest 订阅者只检查正式版，避免稳定安装收到 beta 推送。\n */\nexport function resolveUpdateTags(channel: \"latest\" | \"beta\"): ReadonlyArray<\"latest\" | \"beta\"> {\n  return channel === \"beta\" ? [\"latest\", \"beta\"] : [\"latest\"];\n}\n\n/** 解析自动更新制品源。生产默认走正式 OSS；测试环境默认走测试 OSS；其它环境可显式配置。 */\nexport function resolveUpdateBaseUrl(params: {\n  configuredBaseUrl?: AutoUpdateConfig[\"baseUrl\"];\n  envName: EnvName;\n}): string {\n  const configured = params.configuredBaseUrl?.trim().replace(/\\/+$/, \"\");\n  if (configured) return configured;\n\n  if (params.envName === \"test\") {\n    return TEST_UPDATE_BASE_URL;\n  }\n\n  return PRODUCTION_UPDATE_BASE_URL;\n}\n",
    "function parseSemver(v: string): { major: number; minor: number; patch: number; pre: string | null } {\n  const [main, pre = null] = v.split(\"-\", 2) as [string, string | undefined];\n  const [major = 0, minor = 0, patch = 0] = main.split(\".\").map(Number);\n  return { major, minor, patch, pre: pre ?? null };\n}\n\nfunction comparePreRelease(a: string, b: string): number {\n  const aParts = a.split(\".\");\n  const bParts = b.split(\".\");\n  for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {\n    const ap = aParts[i] ?? \"\";\n    const bp = bParts[i] ?? \"\";\n    const an = Number(ap);\n    const bn = Number(bp);\n    let diff: number;\n    if (!Number.isNaN(an) && !Number.isNaN(bn)) {\n      diff = an - bn;\n    } else if (ap < bp) {\n      diff = -1;\n    } else if (ap > bp) {\n      diff = 1;\n    } else {\n      diff = 0;\n    }\n    if (diff !== 0) return diff;\n  }\n  return 0;\n}\n\nexport function compareVersions(candidate: string, current: string): number {\n  const a = parseSemver(candidate);\n  const b = parseSemver(current);\n\n  if (a.major !== b.major) return a.major - b.major;\n  if (a.minor !== b.minor) return a.minor - b.minor;\n  if (a.patch !== b.patch) return a.patch - b.patch;\n\n  // Same major.minor.patch: stable > pre-release\n  if (a.pre === null) return b.pre === null ? 0 : 1;\n  if (b.pre === null) return -1;\n\n  return comparePreRelease(a.pre, b.pre);\n}\n\n/** Returns true if `candidate` is strictly newer than `current` per semver rules. */\nexport function isNewerVersion(candidate: string, current: string): boolean {\n  return compareVersions(candidate, current) > 0;\n}\n\nexport function pickNewestVersion(\n  versions: ReadonlyArray<string | null | undefined>,\n): string | null {\n  let newest: string | null = null;\n  for (const version of versions) {\n    if (!version) continue;\n    if (!newest || isNewerVersion(version, newest)) {\n      newest = version;\n    }\n  }\n  return newest;\n}\n",
    "import { readFileSync } from \"node:fs\";\n\ndeclare const __PLUGIN_VERSION__: string | undefined;\n\ninterface PackageJson {\n  version?: string;\n}\n\nfunction readBuildInjectedVersion(): string | undefined {\n  if (typeof __PLUGIN_VERSION__ !== \"string\") {\n    return undefined;\n  }\n\n  const version = __PLUGIN_VERSION__.trim();\n  return version || undefined;\n}\n\nfunction readPluginVersionFromPackageJson(): string | undefined {\n  try {\n    const packageJsonUrl = new URL(\"../package.json\", import.meta.url);\n    const packageJson = JSON.parse(\n      readFileSync(packageJsonUrl, \"utf-8\"),\n    ) as PackageJson;\n    const version = packageJson.version?.trim();\n    return version || undefined;\n  } catch {\n    return undefined;\n  }\n}\n\nexport const PLUGIN_VERSION =\n  readBuildInjectedVersion() ??\n  readPluginVersionFromPackageJson() ??\n  \"unknown\";\n",
    "import { loadEnvName } from \"../../env.js\";\nimport { t } from \"../../i18n/index.js\";\nimport {\n  resolveUpdateChannel,\n  resolveUpdateTags,\n} from \"../../update/channel.js\";\nimport { isNewerVersion, pickNewestVersion } from \"../../update/semver.js\";\nimport { PLUGIN_VERSION } from \"../../version.js\";\nimport type { Checker } from \"./types.js\";\n\nexport const checkPluginVersion: Checker = async () => {\n  const channel = resolveUpdateChannel({\n    envName: loadEnvName(),\n    installedVersion: PLUGIN_VERSION,\n  });\n\n  let latest: string | null;\n  try {\n    const candidates = await Promise.all(\n      resolveUpdateTags(channel).map(async (tag) => {\n        const res = await fetch(\n          `https://registry.npmjs.org/@yoooclaw/phone-notifications/${tag}`,\n          { signal: AbortSignal.timeout(5000) },\n        );\n        if (!res.ok) return null;\n        const data = (await res.json()) as { version?: string };\n        return data.version ?? null;\n      }),\n    );\n    latest = pickNewestVersion(candidates);\n  } catch {\n    // 网络不可用时跳过\n    return null;\n  }\n\n  if (!latest || !isNewerVersion(latest, PLUGIN_VERSION)) return null;\n\n  return {\n    id: \"plugin-version\",\n    severity: \"info\",\n    title: t(\"doctor.plugin_version.title\", {\n      current: PLUGIN_VERSION,\n      latest,\n    }),\n    detail: t(\"doctor.plugin_version.detail\"),\n    fixDescription: t(\"doctor.plugin_version.fix\"),\n    fix: null,\n  };\n};\n",
    "import type { Checker } from \"./types.js\";\nimport { checkDangerousFlags } from \"./check-dangerous-flags.js\";\nimport { checkTrustedProxy, checkTrustedProxyAllowUsers } from \"./check-trusted-proxy.js\";\nimport { checkStateDirPerms } from \"./check-state-dir-perms.js\";\nimport { checkToolPolicy } from \"./check-tool-policy.js\";\nimport { checkCredentials } from \"./check-credentials.js\";\nimport { checkTunnel } from \"./check-tunnel.js\";\nimport { checkLocalGateway } from \"./check-local-gateway.js\";\nimport { checkNodeVersion } from \"./check-node-version.js\";\nimport { checkPluginVersion } from \"./check-plugin-version.js\";\n\n/** 所有 checker，按优先级排列 */\nexport const allCheckers: Checker[] = [\n  // critical\n  checkDangerousFlags,\n  checkTrustedProxy,\n  checkCredentials,\n  // warn\n  checkTrustedProxyAllowUsers,\n  checkStateDirPerms,\n  checkToolPolicy,\n  checkTunnel,\n  checkLocalGateway,\n  // info\n  checkNodeVersion,\n  checkPluginVersion,\n];\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveRecordingsDir,\n  readRecordingIndex,\n  output,\n  exitError,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\nimport {\n  parseRecordingTimestamp,\n  recordingEffectiveTime,\n} from \"../recording/time.js\";\n\ninterface RecListOptions {\n  status?: string;\n  from?: string;\n  to?: string;\n}\n\nexport function registerRecList(rec: CliCommand, ctx: CliContext): void {\n  rec\n    .command(\"list\")\n    .description(t(\"cli.rec.list.description\"))\n    .option(\"--status <status>\", t(\"cli.rec.list.opt.status\"))\n    .option(\"--from <time>\", t(\"cli.rec.list.opt.from\"))\n    .option(\"--to <time>\", t(\"cli.rec.list.opt.to\"))\n    .action((opts: RecListOptions = {}) => {\n      const dir = resolveRecordingsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"recordings\");\n\n      let recordings = readRecordingIndex(dir);\n      const from = opts.from\n        ? parseRecordingTimestamp(opts.from)\n        : undefined;\n      const to = opts.to ? parseRecordingTimestamp(opts.to) : undefined;\n      if ((opts.from && from === undefined) || (opts.to && to === undefined)) {\n        exitError(\"INVALID_TIME\", t(\"errors.INVALID_RECORDING_TIME\"));\n      }\n      if (from !== undefined && to !== undefined && from >= to) {\n        exitError(\"INVALID_TIME_RANGE\", t(\"errors.INVALID_RECORDING_TIME_RANGE\"));\n      }\n\n      if (opts.status) {\n        recordings = recordings.filter((r) => r.status === opts.status);\n      }\n      if (from !== undefined || to !== undefined) {\n        recordings = recordings.filter((recording) => {\n          const occurredAt = recordingEffectiveTime(recording);\n          if (!Number.isFinite(occurredAt)) return false;\n          if (from !== undefined && occurredAt < from) return false;\n          if (to !== undefined && occurredAt >= to) return false;\n          return true;\n        });\n      }\n\n      const items = recordings.map((r) => ({\n        id: r.id,\n        name: r.metadata.name,\n        duration_sec: r.metadata.duration_sec,\n        duration_display: r.metadata.duration_display,\n        status: r.status,\n        audio_status: r.audioStatus ?? null,\n        file_size_display: r.metadata.file_size_display ?? \"--\",\n        has_audio: !!r.audioFile,\n        has_transcript: !!r.transcriptFile,\n        created_at: r.metadata.created_at,\n        updated_at: r.updatedAt,\n        error: r.lastError ?? null\n}));\n\n      output({ ok: true, total: items.length, recordings: items });\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveRecordingsDir,\n  readRecordingIndex,\n  output,\n  exitError,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerRecStatus(rec: CliCommand, ctx: CliContext): void {\n  rec\n    .command(\"status <id>\")\n    .description(t(\"cli.rec.status.description\"))\n    .action((id: string) => {\n      const dir = resolveRecordingsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"recordings\");\n\n      const recordings = readRecordingIndex(dir);\n      const entry = recordings.find((r) => r.id === id);\n\n      if (!entry) {\n        exitError(\"NOT_FOUND\", t(\"errors.NOT_FOUND.recording\", { id }));\n      }\n\n      output({\n        ok: true,\n        recording: {\n          id: entry.id,\n          name: entry.metadata.name,\n          duration_sec: entry.metadata.duration_sec,\n          duration_display: entry.metadata.duration_display,\n          file_size_display: entry.metadata.file_size_display ?? \"--\",\n          status: entry.status,\n          audio_status: entry.audioStatus ?? null,\n          created_at: entry.metadata.created_at,\n          location: entry.metadata.location ?? null,\n          markers: entry.metadata.markers ?? [],\n          audioFile: entry.audioFile ?? null,\n          srtFile: entry.srtFile ?? null,\n          transcriptDataFile: entry.transcriptDataFile ?? null,\n          transcriptFile: entry.transcriptFile ?? null,\n          summaryFile: entry.summaryFile ?? null,\n          title: entry.title ?? null,\n          error: entry.lastError ?? null,\n          ingestedAt: entry.ingestedAt,\n          updatedAt: entry.updatedAt,\n        },\n      });\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveRecordingsDir,\n  output,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerRecStoragePath(\n  rec: CliCommand,\n  ctx: CliContext,\n): void {\n  rec\n    .command(\"storage-path\")\n    .description(t(\"cli.rec.storage_path.description\"))\n    .action(() => {\n      const dir = resolveRecordingsDir(ctx);\n      if (!dir) exitStorageUnavailable(\"recordings\");\n      output({ ok: true, path: dir });\n    });\n}\n",
    "import { createInterface } from \"node:readline\";\nimport { writeFileSync, existsSync, readFileSync } from \"node:fs\";\nimport type { CliCommand, CliContext } from \"./helpers.js\";\nimport { resolveAsrConfigPath, output } from \"./helpers.js\";\nimport type { AsrConfig, WhisperModelSize, WhisperBackend, WhisperModelSource } from \"../types.js\";\nimport { t } from \"../i18n/index.js\";\n\n// ─── Prompt helpers ───\n\ntype Rl = ReturnType<typeof createInterface>;\n\nfunction ask(rl: Rl, question: string): Promise<string> {\n  return new Promise((resolve) => rl.question(question, resolve));\n}\n\n/**\n * Ask for a single choice from a numbered list.\n * Writes the list and prompt to stderr; returns the 0-based index of the chosen item.\n */\nasync function askChoice(\n  rl: Rl,\n  prompt: string,\n  choices: readonly string[],\n  defaultIdx = 0,\n): Promise<number> {\n  choices.forEach((c, i) => {\n    const marker = i === defaultIdx ? \"●\" : \"○\";\n    process.stderr.write(`  ${marker} ${i + 1}. ${c}\\n`);\n  });\n  while (true) {\n    const ans = (\n      await ask(\n        rl,\n        t(\"rec.setup.choice_prompt\", {\n          prompt,\n          max: choices.length,\n          default: defaultIdx + 1,\n        }),\n      )\n    ).trim();\n    if (!ans) return defaultIdx;\n    const n = parseInt(ans, 10);\n    if (!isNaN(n) && n >= 1 && n <= choices.length) return n - 1;\n    process.stderr.write(\n      `${t(\"rec.setup.choice_invalid\", { max: choices.length })}\\n`,\n    );\n  }\n}\n\n/** Ask for a value; returns undefined if user presses Enter with no input. */\nasync function askOptional(rl: Rl, prompt: string): Promise<string | undefined> {\n  const ans = (\n    await ask(rl, `${prompt}${t(\"rec.setup.optional_suffix\")}`)\n  ).trim();\n  return ans || undefined;\n}\n\n// ─── Mode-specific setup flows ───\n\nasync function setupApi(rl: Rl): Promise<AsrConfig> {\n  process.stderr.write(`\\n${t(\"rec.setup.api_header\")}\\n\\n`);\n  process.stderr.write(`${t(\"rec.setup.api_note\")}\\n\\n`);\n\n  const endpoint = await askOptional(rl, t(\"rec.setup.api.endpoint\"));\n  const language = await askOptional(rl, t(\"rec.setup.api.language\"));\n  const enableNormalizationInput = await askOptional(rl, t(\"rec.setup.api.itn\"));\n  const normalized = enableNormalizationInput?.trim().toLowerCase();\n  const enableNormalization =\n    normalized === \"y\" || normalized === \"yes\" || normalized === \"true\";\n\n  return {\n    mode: \"api\",\n    api: {\n      ...(endpoint ? { endpoint } : {}),\n      ...(language ? { language } : {}),\n      ...(enableNormalizationInput ? { enableNormalization } : {}),\n    },\n  };\n}\n\nasync function setupLocal(rl: Rl): Promise<AsrConfig> {\n  process.stderr.write(`\\n${t(\"rec.setup.local_header\")}\\n\\n`);\n\n  process.stderr.write(`${t(\"rec.setup.local.model_label\")}\\n`);\n  const modelChoices = [\n    t(\"rec.setup.local.model_auto\"),\n    \"tiny\",\n    \"base\",\n    \"small\",\n    \"medium\",\n    \"large-v3\",\n  ] as const;\n  const modelIdx = await askChoice(rl, t(\"rec.setup.local.choose_model\"), modelChoices);\n  const model: WhisperModelSize | undefined =\n    modelIdx === 0 ? undefined : (modelChoices[modelIdx] as WhisperModelSize);\n\n  const language = await askOptional(rl, t(\"rec.setup.local.language\"));\n\n  process.stderr.write(`\\n${t(\"rec.setup.local.backend_label\")}\\n`);\n  const backendChoices = [\n    t(\"rec.setup.local.backend_auto\"),\n    t(\"rec.setup.local.backend_coreml\"),\n    t(\"rec.setup.local.backend_cuda\"),\n    \"cpu\",\n  ] as const;\n  const backendIdx = await askChoice(rl, t(\"rec.setup.local.choose_backend\"), backendChoices);\n  const backend: WhisperBackend | undefined =\n    backendIdx === 0 ? undefined : ([\"coreml\", \"cuda\", \"cpu\"] as const)[backendIdx - 1];\n\n  process.stderr.write(`\\n${t(\"rec.setup.local.source_label\")}\\n`);\n  const sourceChoices = [\n    t(\"rec.setup.local.source_auto\"),\n    t(\"rec.setup.local.source_hf\"),\n    t(\"rec.setup.local.source_domestic\"),\n  ] as const;\n  const sourceIdx = await askChoice(rl, t(\"rec.setup.local.choose_source\"), sourceChoices);\n  const modelSource: WhisperModelSource = ([\"auto\", \"huggingface\", \"domestic\"] as const)[sourceIdx];\n\n  const modelMirrorUrl = await askOptional(rl, t(\"rec.setup.local.mirror\"));\n\n  return {\n    mode: \"local\",\n    local: {\n      ...(model ? { model } : {}),\n      ...(language ? { language } : {}),\n      ...(backend ? { backend } : {}),\n      modelSource,\n      ...(modelMirrorUrl ? { modelMirrorUrl } : {}),\n    },\n  };\n}\n\n// ─── Command registration ───\n\nexport function registerRecSetup(rec: CliCommand, ctx: CliContext): void {\n  rec\n    .command(\"setup\")\n    .description(t(\"cli.rec.setup.description\"))\n    .action(async () => {\n      const configPath = resolveAsrConfigPath(ctx);\n\n      // Show existing config hint if present\n      if (existsSync(configPath)) {\n        try {\n          const existing = JSON.parse(readFileSync(configPath, \"utf-8\")) as AsrConfig & { updatedAt?: string };\n          process.stderr.write(t(\"rec.setup.existing\", { mode: existing.mode }));\n          if (existing.updatedAt) {\n            process.stderr.write(\n              t(\"rec.setup.existing_updated\", { updatedAt: existing.updatedAt }),\n            );\n          }\n          process.stderr.write(\"\\n\");\n        } catch {\n          // ignore parse errors\n        }\n      }\n\n      const rl = createInterface({ input: process.stdin, output: process.stderr, terminal: true });\n\n      try {\n        process.stderr.write(`\\n${t(\"rec.setup.mode_label\")}\\n`);\n        const modeIdx = await askChoice(rl, t(\"rec.setup.choose_mode\"), [\n          t(\"rec.setup.mode_api\"),\n          t(\"rec.setup.mode_local\"),\n        ]);\n\n        const config: AsrConfig = modeIdx === 0 ? await setupApi(rl) : await setupLocal(rl);\n        const stored = { ...config, updatedAt: new Date().toISOString() };\n\n        writeFileSync(configPath, JSON.stringify(stored, null, 2), \"utf-8\");\n        process.stderr.write(`\\n${t(\"rec.setup.saved\", { path: configPath })}\\n\\n`);\n\n        output({ ok: true, ...stored });\n      } finally {\n        rl.close();\n      }\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveImagesDir,\n  readImageIndex,\n  output,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerImageList(image: CliCommand, ctx: CliContext): void {\n  image\n    .command(\"list\")\n    .description(t(\"cli.image.list.description\"))\n    .option(\"--status <status>\", t(\"cli.image.list.opt.status\"))\n    .option(\"--app <app>\", t(\"cli.image.list.opt.app\"))\n    .action((opts: { status?: string; app?: string }) => {\n      const dir = resolveImagesDir(ctx);\n      if (!dir) exitStorageUnavailable(\"images\");\n\n      let images = readImageIndex(dir);\n\n      if (opts.status) {\n        images = images.filter((e) => e.status === opts.status);\n      }\n      if (opts.app) {\n        images = images.filter((e) => e.metadata.source_app === opts.app);\n      }\n\n      const items = images.map((e) => ({\n        imageId: e.imageId,\n        status: e.status,\n        source_app: e.metadata.source_app ?? null,\n        caption: e.metadata.caption ?? null,\n        mime_type: e.metadata.mime_type ?? null,\n        size_bytes: e.metadata.size_bytes ?? null,\n        created_at: e.metadata.created_at,\n        has_file: !!e.localFile,\n        localFile: e.localFile ?? null,\n        syncedAt: e.syncedAt ?? null,\n        error: e.lastError ?? null\n}));\n\n      output({ ok: true, total: items.length, images: items });\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveImagesDir,\n  readImageIndex,\n  output,\n  exitError,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerImageStatus(image: CliCommand, ctx: CliContext): void {\n  image\n    .command(\"status <id>\")\n    .description(t(\"cli.image.status.description\"))\n    .action((id: string) => {\n      const dir = resolveImagesDir(ctx);\n      if (!dir) exitStorageUnavailable(\"images\");\n\n      const entry = readImageIndex(dir).find((e) => e.imageId === id);\n      if (!entry) {\n        exitError(\"NOT_FOUND\", t(\"errors.NOT_FOUND.image\", { id }));\n      }\n\n      output({\n        ok: true,\n        image: {\n          imageId: entry.imageId,\n          clientLabel: entry.clientLabel ?? null,\n          status: entry.status,\n          metadata: entry.metadata,\n          localFile: entry.localFile ?? null,\n          thumbnail: entry.thumbnail ?? null,\n          syncedAt: entry.syncedAt ?? null,\n          error: entry.lastError ?? null,\n        },\n      });\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveImagesDir,\n  readImageIndex,\n  resolveImageFile,\n  output,\n  exitError,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerImagePath(image: CliCommand, ctx: CliContext): void {\n  image\n    .command(\"path <id>\")\n    .description(t(\"cli.image.path.description\"))\n    .action((id: string) => {\n      const dir = resolveImagesDir(ctx);\n      if (!dir) exitStorageUnavailable(\"images\");\n\n      const entry = readImageIndex(dir).find((e) => e.imageId === id);\n      if (!entry) {\n        exitError(\"NOT_FOUND\", t(\"errors.NOT_FOUND.image\", { id }));\n      }\n\n      if (entry.status !== \"synced\" || !entry.localFile) {\n        exitError(\n          \"IMAGE_NOT_READY\",\n          t(\"errors.IMAGE_NOT_READY\", {\n            id,\n            status: entry.status,\n            errorSuffix: entry.lastError ? `, error=${entry.lastError}` : \"\",\n          }),\n        );\n      }\n\n      output({ ok: true, path: resolveImageFile(dir, entry.localFile) });\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveImagesDir,\n  output,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerImageStoragePath(\n  image: CliCommand,\n  ctx: CliContext,\n): void {\n  image\n    .command(\"storage-path\")\n    .description(t(\"cli.image.storage_path.description\"))\n    .action(() => {\n      const dir = resolveImagesDir(ctx);\n      if (!dir) exitStorageUnavailable(\"images\");\n      output({ ok: true, path: dir });\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveWebPagesDir,\n  readWebPageIndex,\n  output,\n  exitError,\n  exitStorageUnavailable,\n  parseIsoTime,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\ninterface WebListOptions {\n  from?: string;\n  to?: string;\n}\n\nexport function registerWebList(web: CliCommand, ctx: CliContext): void {\n  web\n    .command(\"list\")\n    .description(t(\"cli.web.list.description\"))\n    .option(\"--from <time>\", t(\"cli.web.list.opt.from\"))\n    .option(\"--to <time>\", t(\"cli.web.list.opt.to\"))\n    .action((opts: WebListOptions = {}) => {\n      const dir = resolveWebPagesDir(ctx);\n      if (!dir) exitStorageUnavailable(\"web-pages\");\n\n      const fromTs = opts.from ? parseIsoTime(opts.from, \"--from\") : null;\n      const toTs = opts.to ? parseIsoTime(opts.to, \"--to\") : null;\n      if (fromTs !== null && toTs !== null && fromTs > toTs) {\n        exitError(\"INVALID_TIME_RANGE\");\n      }\n\n      const pages = readWebPageIndex(dir)\n        .filter((page) => {\n          if (fromTs === null && toTs === null) return true;\n          const capturedTs = Date.parse(page.capturedAt);\n          if (Number.isNaN(capturedTs)) return false;\n          if (fromTs !== null && capturedTs < fromTs) return false;\n          if (toTs !== null && capturedTs >= toTs) return false;\n          return true;\n        })\n        .map((page) => ({\n          urlHash: page.urlHash,\n          title: page.title,\n          siteName: page.siteName ?? null,\n          canonicalUrl: page.canonicalUrl,\n          capturedAt: page.capturedAt,\n          firstCapturedAt: page.firstCapturedAt,\n          captureCount: page.captureCount,\n          bytes: page.bytes,\n          relativePath: page.relativePath,\n          hasArchive: !!page.archivePath,\n          clientLabel: page.clientLabel ?? null,\n        }));\n\n      output({ ok: true, total: pages.length, pages });\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  type CliWebPageEntry,\n  resolveWebPagesDir,\n  readWebPageIndex,\n  resolveWebPageFile,\n  output,\n  exitError,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nfunction findByHash(\n  pages: CliWebPageEntry[],\n  rawHash: string,\n): CliWebPageEntry | undefined {\n  const hash = rawHash.trim().toLowerCase();\n  const exact = pages.find((page) => page.urlHash.toLowerCase() === hash);\n  if (exact) return exact;\n  if (hash.length < 8) return undefined;\n\n  const matches = pages.filter((page) =>\n    page.urlHash.toLowerCase().startsWith(hash),\n  );\n  return matches.length === 1 ? matches[0] : undefined;\n}\n\nexport function registerWebPath(web: CliCommand, ctx: CliContext): void {\n  web\n    .command(\"path <urlHash>\")\n    .description(t(\"cli.web.path.description\"))\n    .action((urlHash: string) => {\n      const dir = resolveWebPagesDir(ctx);\n      if (!dir) exitStorageUnavailable(\"web-pages\");\n\n      const entry = findByHash(readWebPageIndex(dir), urlHash);\n      if (!entry) {\n        exitError(\"NOT_FOUND\", t(\"errors.NOT_FOUND.web_page\", { urlHash }));\n      }\n\n      const path = resolveWebPageFile(dir, entry.relativePath);\n      if (!path) {\n        exitError(\n          \"WEB_PAGE_FILE_UNAVAILABLE\",\n          t(\"errors.WEB_PAGE_FILE_UNAVAILABLE\", { urlHash }),\n        );\n      }\n\n      output({ ok: true, path });\n    });\n}\n",
    "import { existsSync, readFileSync } from \"node:fs\";\nimport {\n  type CliCommand,\n  type CliContext,\n  type CliWebPageEntry,\n  resolveWebPagesDir,\n  readWebPageIndex,\n  resolveWebPageFile,\n  output,\n  exitError,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { parsePositiveIntegerOption } from \"./ntf-query.js\";\nimport { t } from \"../i18n/index.js\";\n\nconst DEFAULT_LIMIT = 20;\nconst MAX_SNIPPETS_PER_PAGE = 3;\nconst MAX_SNIPPET_CHARS = 240;\n\nexport interface WebPageSearchMatch {\n  urlHash: string;\n  title: string;\n  siteName: string | null;\n  canonicalUrl: string;\n  capturedAt: string;\n  path: string;\n  matchedFields: string[];\n  matches: string[];\n}\n\nfunction clipSnippet(line: string, keyword: string): string {\n  const compact = line.trim().replace(/\\s+/g, \" \");\n  if (compact.length <= MAX_SNIPPET_CHARS) return compact;\n\n  const index = compact.toLowerCase().indexOf(keyword);\n  const start = Math.max(0, index - Math.floor(MAX_SNIPPET_CHARS / 3));\n  const end = Math.min(compact.length, start + MAX_SNIPPET_CHARS);\n  return `${start > 0 ? \"…\" : \"\"}${compact.slice(start, end)}${\n    end < compact.length ? \"…\" : \"\"\n  }`;\n}\n\nfunction matchingMetadataFields(\n  page: CliWebPageEntry,\n  keyword: string,\n): string[] {\n  const fields: Array<[string, string | undefined]> = [\n    [\"title\", page.title],\n    [\"siteName\", page.siteName],\n    [\"canonicalUrl\", page.canonicalUrl],\n    [\"url\", page.url],\n  ];\n  return fields\n    .filter(([, value]) => value?.toLowerCase().includes(keyword))\n    .map(([name]) => name);\n}\n\nfunction markdownBody(content: string): string {\n  const lines = content.split(\"\\n\");\n  if (lines[0]?.trim() !== \"---\") return content;\n\n  const closing = lines.findIndex(\n    (line, index) => index > 0 && line.trim() === \"---\",\n  );\n  return closing === -1 ? content : lines.slice(closing + 1).join(\"\\n\");\n}\n\nexport function searchWebPages(\n  dir: string,\n  pages: CliWebPageEntry[],\n  rawKeyword: string,\n  limit: number,\n): WebPageSearchMatch[] {\n  const keyword = rawKeyword.trim().toLowerCase();\n  if (!keyword) return [];\n\n  const results: WebPageSearchMatch[] = [];\n  for (const page of pages) {\n    if (results.length >= limit) break;\n\n    const path = resolveWebPageFile(dir, page.relativePath);\n    if (!path || !existsSync(path)) continue;\n\n    const content = readFileSync(path, \"utf-8\");\n    const matchedFields = matchingMetadataFields(page, keyword);\n    const matches: string[] = [];\n    const seen = new Set<string>();\n    for (const line of markdownBody(content).split(\"\\n\")) {\n      if (!line.toLowerCase().includes(keyword)) continue;\n      const snippet = clipSnippet(line, keyword);\n      if (!snippet || seen.has(snippet)) continue;\n      seen.add(snippet);\n      matches.push(snippet);\n      if (matches.length >= MAX_SNIPPETS_PER_PAGE) break;\n    }\n\n    if (matchedFields.length === 0 && matches.length === 0) continue;\n    results.push({\n      urlHash: page.urlHash,\n      title: page.title,\n      siteName: page.siteName ?? null,\n      canonicalUrl: page.canonicalUrl,\n      capturedAt: page.capturedAt,\n      path,\n      matchedFields,\n      matches,\n    });\n  }\n  return results;\n}\n\nexport function registerWebSearch(web: CliCommand, ctx: CliContext): void {\n  web\n    .command(\"search <keyword>\")\n    .description(t(\"cli.web.search.description\"))\n    .option(\"--limit <n>\", t(\"cli.web.search.opt.limit\"), String(DEFAULT_LIMIT))\n    .action((keyword: string, opts: { limit?: string }) => {\n      const dir = resolveWebPagesDir(ctx);\n      if (!dir) exitStorageUnavailable(\"web-pages\");\n\n      if (!keyword.trim()) {\n        exitError(\"INVALID_KEYWORD\", t(\"errors.INVALID_KEYWORD\"));\n      }\n      const limit = parsePositiveIntegerOption(\n        opts.limit,\n        DEFAULT_LIMIT,\n        \"--limit\",\n        \"INVALID_LIMIT\",\n      );\n      const pages = searchWebPages(\n        dir,\n        readWebPageIndex(dir),\n        keyword,\n        limit,\n      );\n\n      output({ ok: true, keyword, total: pages.length, pages });\n    });\n}\n",
    "import {\n  type CliCommand,\n  type CliContext,\n  resolveWebPagesDir,\n  output,\n  exitStorageUnavailable,\n} from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nexport function registerWebStoragePath(\n  web: CliCommand,\n  ctx: CliContext,\n): void {\n  web\n    .command(\"storage-path\")\n    .description(t(\"cli.web.storage_path.description\"))\n    .action(() => {\n      const dir = resolveWebPagesDir(ctx);\n      if (!dir) exitStorageUnavailable(\"web-pages\");\n      output({ ok: true, path: dir });\n    });\n}\n",
    "import { spawnSync } from \"node:child_process\";\nimport { writeFileSync, unlinkSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { loadEnvName } from \"../env.js\";\nimport { resolveStateDir } from \"../host.js\";\nimport { getActiveLocale, readPersistedLocaleFromStateDir } from \"../i18n/locale.js\";\nimport {\n  resolveUpdateBaseUrl,\n  resolveUpdateChannel,\n  resolveUpdateTags,\n} from \"../update/channel.js\";\nimport { isNewerVersion, pickNewestVersion } from \"../update/semver.js\";\nimport { PLUGIN_VERSION } from \"../version.js\";\nimport { output } from \"./helpers.js\";\nimport type { CliCommand, CliContext } from \"./helpers.js\";\nimport { t } from \"../i18n/index.js\";\n\nasync function fetchText(url: string): Promise<string> {\n  const res = await fetch(url, { signal: AbortSignal.timeout(30_000) });\n  if (!res.ok) {\n    throw new Error(t(\"update.request_failed\", { url, status: res.status }));\n  }\n  return res.text();\n}\n\nasync function fetchLatestVersion(\n  baseUrl: string,\n  tags: ReadonlyArray<\"latest\" | \"beta\">,\n): Promise<string> {\n  const results = await Promise.allSettled(\n    tags.map(async (tag) => {\n      return (await fetchText(`${baseUrl}/${tag}`)).trim();\n    }),\n  );\n  const latest = pickNewestVersion(\n    results.map((result) => result.status === \"fulfilled\" ? result.value : null),\n  );\n  if (latest) return latest;\n\n  const rejected = results.find((result) => result.status === \"rejected\");\n  if (rejected?.status === \"rejected\") throw rejected.reason;\n  throw new Error(t(\"update.version_empty\", { baseUrl }));\n}\n\nasync function runUpdate(\n  ctx: CliContext,\n  opts: { json?: boolean; force?: boolean; beta?: boolean },\n): Promise<void> {\n  const json = opts.json === true;\n  const force = opts.force === true;\n  const beta = opts.beta === true;\n  const envName = loadEnvName();\n  const channel = beta\n    ? \"beta\"\n    : resolveUpdateChannel({ envName, installedVersion: PLUGIN_VERSION });\n  const checkingBeta = channel === \"beta\";\n  const betaLabel = checkingBeta ? t(\"update.checking_beta\") : \"\";\n  const baseUrl = resolveUpdateBaseUrl({ envName });\n  const log = (msg: string) => {\n    if (!json) process.stderr.write(`${msg}\\n`);\n  };\n\n  log(t(\"update.checking\", { beta: betaLabel }));\n\n  let latest: string;\n  try {\n    latest = await fetchLatestVersion(\n      baseUrl,\n      beta ? [\"beta\"] : resolveUpdateTags(channel),\n    );\n  } catch (err: any) {\n    const msg = t(\"update.fetch_failed\", {\n      message: err?.message ?? String(err),\n    });\n    if (json) {\n      output({ ok: false, error: { code: \"FETCH_FAILED\", message: msg } });\n      process.exit(1);\n    }\n    process.stderr.write(`\\x1b[31m[update] ERROR:\\x1b[0m ${msg}\\n`);\n    process.exit(1);\n  }\n\n  const current = PLUGIN_VERSION;\n\n  if (!force && !isNewerVersion(latest, current)) {\n    log(\n      `\\x1b[32m${t(\"update.already_latest\", {\n        beta: betaLabel,\n        version: current,\n      })}\\x1b[0m`,\n    );\n    output({ ok: true, current, latest, channel, updated: false });\n    return;\n  }\n\n  if (force) {\n    log(\n      `\\x1b[36m${t(\"update.force\", { current, latest })}\\x1b[0m`,\n    );\n  } else {\n    log(\n      `\\x1b[36m${t(\"update.found\", { current, latest })}\\x1b[0m`,\n    );\n  }\n\n  // 下载 install-core.mjs\n  log(t(\"update.downloading\"));\n  let installScript: string;\n  try {\n    installScript = await fetchText(`${baseUrl}/install-core.mjs`);\n  } catch (err: any) {\n    const msg = t(\"update.download_failed\", {\n      message: err?.message ?? String(err),\n    });\n    if (json) {\n      output({ ok: false, error: { code: \"DOWNLOAD_FAILED\", message: msg } });\n      process.exit(1);\n    }\n    process.stderr.write(`\\x1b[31m[update] ERROR:\\x1b[0m ${msg}\\n`);\n    process.exit(1);\n  }\n\n  // 写入临时文件\n  const tmpScript = join(tmpdir(), `openclaw-install-${Date.now()}.mjs`);\n  try {\n    writeFileSync(tmpScript, installScript, \"utf-8\");\n  } catch (err: any) {\n    const msg = t(\"update.write_failed\", {\n      message: err?.message ?? String(err),\n    });\n    if (json) {\n      output({ ok: false, error: { code: \"WRITE_FAILED\", message: msg } });\n      process.exit(1);\n    }\n    process.stderr.write(`\\x1b[31m[update] ERROR:\\x1b[0m ${msg}\\n`);\n    process.exit(1);\n  }\n\n  const stateDir = resolveStateDir(ctx.stateDir);\n  const installLocale =\n    readPersistedLocaleFromStateDir(stateDir) ?? getActiveLocale();\n\n  // 执行安装脚本（同步，保证日志有序输出）\n  const result = spawnSync(\n    process.execPath,\n    [tmpScript, \"--version\", latest, \"--state-dir\", stateDir, \"--lang\", installLocale],\n    { stdio: \"inherit\" },\n  );\n\n  try {\n    unlinkSync(tmpScript);\n  } catch {\n    // 清理失败不影响结果\n  }\n\n  if (result.error) {\n    const msg = t(\"update.spawn_failed\", { message: result.error.message });\n    if (json) {\n      output({ ok: false, error: { code: \"SPAWN_FAILED\", message: msg } });\n    } else {\n      process.stderr.write(`\\x1b[31m[update] ERROR:\\x1b[0m ${msg}\\n`);\n    }\n    process.exit(1);\n  }\n\n  if (result.status !== 0) {\n    if (json) {\n      output({\n        ok: false,\n        error: {\n          code: \"INSTALL_FAILED\",\n          message: t(\"update.exit_code\", { code: result.status ?? \"unknown\" }),\n        },\n      });\n    }\n    process.exit(result.status ?? 1);\n  }\n\n  if (json) {\n    output({ ok: true, current, latest, channel, updated: true });\n  }\n}\n\nexport function registerUpdate(ntf: CliCommand, ctx: CliContext): void {\n  ntf\n    .command(\"update\")\n    .description(t(\"cli.update.description\"))\n    .option(\"--json\", t(\"cli.opt.json\"))\n    .option(\"--force\", t(\"cli.update.opt.force\"))\n    .option(\"--beta\", t(\"cli.update.opt.beta\"))\n    .action((opts: { json?: boolean; force?: boolean; beta?: boolean }) => {\n      return runUpdate(ctx, opts);\n    });\n}\n",
    "import type { CliCommand, CliContext } from \"./helpers.js\";\nimport { resolveStateDir } from \"../host.js\";\nimport { initI18n, t } from \"../i18n/index.js\";\nimport { registerAuthCli } from \"./auth.js\";\nimport { registerNtfSearch } from \"./ntf-search.js\";\nimport { registerNtfSummary } from \"./ntf-summary.js\";\nimport { registerNtfSummaryJob } from \"./ntf-summary-job.js\";\nimport { registerNtfStats } from \"./ntf-stats.js\";\nimport { registerNtfSync } from \"./ntf-sync.js\";\nimport { registerNtfMonitor } from \"./ntf-monitor.js\";\nimport { registerLightSend } from \"./light-send.js\";\nimport { registerLightSetupTools } from \"./light-setup-tools.js\";\nimport { registerTunnelStatus } from \"./tunnel-status.js\";\nimport { registerNtfStoragePath } from \"./ntf-storage-path.js\";\nimport { registerLogSearch } from \"./log-search.js\";\nimport { registerEnvCli } from \"./env.js\";\nimport { registerDoctor } from \"./doctor.js\";\nimport { registerRecList } from \"./rec-list.js\";\nimport { registerRecStatus } from \"./rec-status.js\";\nimport { registerRecStoragePath } from \"./rec-storage-path.js\";\nimport { registerRecSetup } from \"./rec-setup.js\";\nimport { registerImageList } from \"./image-list.js\";\nimport { registerImageStatus } from \"./image-status.js\";\nimport { registerImagePath } from \"./image-path.js\";\nimport { registerImageStoragePath } from \"./image-storage-path.js\";\nimport { registerWebList } from \"./web-list.js\";\nimport { registerWebPath } from \"./web-path.js\";\nimport { registerWebSearch } from \"./web-search.js\";\nimport { registerWebStoragePath } from \"./web-storage-path.js\";\nimport { registerUpdate } from \"./update.js\";\nimport { PLUGIN_VERSION } from \"../version.js\";\n\nexport function registerAllCli(\n  program: CliCommand,\n  ctx: CliContext,\n  rootCommandName: string | null = \"ntf\",\n): void {\n  initI18n();\n  const normalizedCtx: CliContext = {\n    ...ctx,\n    stateDir: ctx.stateDir ? resolveStateDir(ctx.stateDir) : undefined,\n  };\n\n  // rootCommandName=null 表示 program 自身就是 ntf 根（独立 bin 入口），\n  // 直接把子命令挂在 program 上，避免 `ntf ntf <sub>` 的双层嵌套。\n  const ntf =\n    rootCommandName === null\n      ? program.version(PLUGIN_VERSION, \"-v, --version\", t(\"cli.ntf.version\"))\n      : program\n          .command(rootCommandName)\n          .description(t(\"cli.ntf.description\"))\n          .version(PLUGIN_VERSION, \"-v, --version\", t(\"cli.ntf.version\"));\n\n  // ntf auth ...\n  registerAuthCli(ntf);\n\n  // ntf search / summary / stats / sync / monitor ...\n  registerNtfSearch(ntf, normalizedCtx);\n  registerNtfSummary(ntf, normalizedCtx);\n  registerNtfSummaryJob(ntf, normalizedCtx);\n  registerNtfStats(ntf, normalizedCtx);\n  registerNtfSync(ntf, normalizedCtx);\n  registerNtfMonitor(ntf, normalizedCtx);\n\n  // ntf light send / setup-tools ...\n  const light = ntf.command(\"light\").description(t(\"cli.light.description\"));\n  registerLightSend(light);\n  registerLightSetupTools(light);\n\n  // ntf storage-path\n  registerNtfStoragePath(ntf, normalizedCtx);\n\n  // ntf log <keyword>\n  registerLogSearch(ntf, normalizedCtx);\n\n  // ntf tunnel-status\n  registerTunnelStatus(ntf, normalizedCtx);\n\n  // ntf env show / switch\n  registerEnvCli(ntf);\n\n  // ntf doctor\n  registerDoctor(ntf, normalizedCtx);\n\n  // ntf rec list / status / storage-path / setup\n  const rec = ntf.command(\"rec\").description(t(\"cli.rec.description\"));\n  registerRecList(rec, normalizedCtx);\n  registerRecStatus(rec, normalizedCtx);\n  registerRecStoragePath(rec, normalizedCtx);\n  registerRecSetup(rec, normalizedCtx);\n\n  // ntf image list / status / path / storage-path\n  const image = ntf.command(\"image\").description(t(\"cli.image.description\"));\n  registerImageList(image, normalizedCtx);\n  registerImageStatus(image, normalizedCtx);\n  registerImagePath(image, normalizedCtx);\n  registerImageStoragePath(image, normalizedCtx);\n\n  // ntf synced-web-page list / path / search / storage-path\n  const web = ntf\n    .command(\"synced-web-page\")\n    .description(t(\"cli.web.description\"));\n  registerWebList(web, normalizedCtx);\n  registerWebPath(web, normalizedCtx);\n  registerWebSearch(web, normalizedCtx);\n  registerWebStoragePath(web, normalizedCtx);\n\n  // ntf update\n  registerUpdate(ntf, normalizedCtx);\n}\n",
    "import { Command } from \"commander\";\nimport { registerAllCli } from \"../cli/index.js\";\nimport { resolveStateDir } from \"../host.js\";\n\nimport {\n  initI18n,\n  resolvePluginInstallDirFromNtfEntry,\n  t,\n} from \"../i18n/index.js\";\n\ninitI18n();\nconst program = new Command();\nprogram.name(\"ntf\").description(t(\"cli.ntf.description\"));\n\nregisterAllCli(\n  program as unknown as Parameters<typeof registerAllCli>[0],\n  {\n    stateDir: resolveStateDir(),\n    pluginInstallDir: resolvePluginInstallDirFromNtfEntry(process.argv[1]),\n  },\n  null,\n);\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n  const msg = err instanceof Error ? err.message : String(err);\n  process.stderr.write(`${msg}\\n`);\n  process.exit(1);\n});\n"
  ],
  "mappings": "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",
  "debugId": "53A94DF2B243926464756E2164756E21",
  "names": []
}