# @neocompose/cli 中文文档

规范地址：https://npmcn.com/package/%40neocompose/cli/

版本：0\.93\.5
npm 元数据更新时间：2026-11-01T22:45:22.219Z
中文译文更新时间：2026-11-02T00:09:37.635Z
软件包许可：MIT

本文由上游 README 机器翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40neocompose/cli
原文对照：https://npmcn.com/package/%40neocompose/cli/?lang=original
项目主页：https://github.com/ryanbliss/neo-compose#readme
源码仓库：https://github.com/ryanbliss/neo-compose

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：13.1 MB，39 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- Node.js 要求：\>=22\.0\.0
- 运行依赖：7 个
- 首次发布：2026-06-12T03:19:29.299Z
- 最新版本发布：2026-11-01T22:45:22.074Z
- 已发布版本数：346（近 12 个月 346 个）

## 中文简介

neocompose原生项目源CLI与双向同步。

## 安装

```sh
npm install @neocompose/cli
```

也可以使用：`pnpm add @neocompose/cli`、`yarn add @neocompose/cli`、`bun add @neocompose/cli`

## README

# `neo` - Neo Compose项目源CLI

`neo` 将git友好的Neo Compose项目工作副本与 网页编辑器。工作拷贝格式4是Neo-native： `.neo` 定义项目 模型和撰写值； `.neoflow` 定义对话流和托管映像 音频文件以普通二进制文件的形式保存。

当前代理编写指南已导入 [`cli/skills/neocompose-cli/SKILL.md`](https://npmcn.com/package/%40neocompose/cli/skills/neocompose-cli/SKILL.md). 功能规格 [`neo-compose-specs/new-features`](https://github.com/ryanbliss/neo-compose-specs/tree/main/new-features) 文档设计意图和边缘情况；已发布的编译器、契约和 测试是可执行的事实来源。

## 源架构

CLI源代码将创作、文档投影和同步分开：

```text
project-source/   parse, lower, and emit .neo/.neoflow plus managed binaries
project-manifest/ semantic bridge between authored source and project documents
project-sync/     diff, merge, conflict, migration, and CAS state handling
```

流程是 `project source -> ProjectSchemaManifest -> project documents -> sync`. `ProjectSchemaManifest` 携带独立版本的序列化文件 契约使得源语法和服务器文档可以在不耦合的情况下发展 它们的版本号。当前的工作区格式仍然是格式4；这个 清单的数字契约版本不是第二个工作副本格式。 依赖项向下指向： `project-source` 可以使用两个较低的层，而 `project-sync` 永远不要导入源代码编写或清单代码。

## 运行

```sh
npm i -g @neocompose/cli       # published package; installs `neo` on PATH
node cli/bin/neo.mjs <command> # repository development
```

在自动化中设置一个带有显式id的工作副本：

```sh
neo login --profile editor
neo init --project <id> --version <id> --dir neo
```

交互式终端可以选择项目、版本和目录。Neo 不安装、不发现或不需要。net。 `neo doctor` 验证 format-4浏览器安全编译器，VS Code分析合同，跟踪源代码，和 托管的文件的能力。中的畸形记录也会失败 文档的时间。

## Format-4工作副本

```text
neo/
  neo.json                         # formatVersion: 4
  Project.neo                      # project defaults/settings
  Root.neo                         # protected root shape; editable root values
  Classes/{System/, ...}
  Interfaces/{System/, ...}
  Enums/{System/, ...}
  Relations.neo                    # generic project relations, when present
  Templates/
  Localization.neo
  LocalizationStatuses/
  Files/
    Images.neo                     # ImageRegistry Images
    AudioClips.neo                 # AudioClipRegistry AudioClips
    Images/                        # tracked image bytes
    AudioClips/                    # tracked audio bytes
  DialogueGroups/
  Dialogues/*.neoflow
  Migrations/*.neo
  **/*.spec.neo                   # colocated local-only NeoScript tests
  .neo/
    state.json                     # private merge/CAS bases; never hand-edit
    conflicts/
    test-build/                    # local test compilation metadata
```

生产 `.neo`， `.neoflow`，并跟踪受支持的托管二进制文件。 托管的 `.spec.neo` 文件仅用于测试：它们从不输入状态、源 标识，拉/复位，或推。 `.neo/` 被忽略的私有状态。没有图式 `.csproj`c#编写 树，Roslyn编译器，生成的创作DLL，每个函数的sidecar树，或 签入对话JSON。

只有 `formatVersion: 4` 被接受。格式4是一个彻底的突破；事实并非如此 读取或转换格式为3的c#签出。与老年人一起推动预期的变化 首先，保留您需要的任何本地源代码，然后从 权威服务器:

```sh
neo init --project <id> --version <id> --dir neo
```

对于现有的format-4工作区， `neo pull --reset` 再生规范 源代码和托管二进制文件。正常的 `neo pull` 执行一个稳定的id感知 三向合并，尽可能保留源位置，并使用持久的 事务游标，仅获取自上次同步以来更改的记录。 撤销/重置元数据将使该游标失效，并安全地退回到满的状态 快照。

在Unity项目中， `neo.json` 可以使用 `unityConfigPath` 而不是存储 `projectId` 和 `versionId`． 被引用的 `NeoComposeConfig.asset` 然后拥有 这些id并接收分支/版本切换。 `neo export` 写进去 统一项目;没有 `unityConfigPath`，它提供了链接配置资产 对于这个项目，它可以在Unity项目中找到工作副本。

验证源代码降低，提交准备，动画验证和Unity 的共享文件缓存中 `.neo/build/`． 一个新的CLI进程可以 重用;保持 `neo dev` 不需要运行。准确的输入和依赖关系 检查使受影响的结果无效。独立对话散文变化保存 结构性工作，包括提交这些更改的拉操作。结构性来源 编辑仍然需要更广泛的分析和准备。

Export检查输出字节并恢复丢失或修改的生成文件 在不重写未更改的文件的情况下，从其缓存中获取。 `neo dev` 使用相同的 每次保存后的准备和导出规则。

拉、推和导出拒绝其所拉项目或版本的工作副本 不同于配置，当资产在 CLI。运行 `neo branch switch <versionId>` 重置和拉配置 的版本。

### 在当地组织资源

移动 `.neo` 和 `.neoflow` 文件放入任何项目文件夹，并组声明 在您喜欢的文件中。保留现有的id。拉，用力，复位 在应用服务器状态之前的当前位置。新的服务器声明使用 默认文件夹。系统声明使用 `System` 子文件夹，例如 `Classes/System`， `Enums/System`，或者 `Interfaces/System`． 所有权来自于 保留的系统标识，因此项目类型保持其正常的默认值。 受管理的图像和音频也可以移动。更新他们键入的注册表路径。

将大型根或静态初始化器提取到类型化声明中，而不需要导入：

```neo
// Configuration/ProjectSortingLayers.neo
List<NeoSortingLayer> SORTING_LAYERS = [
  new NeoSortingLayer() { Name = "Default" }
];

// Inside the Root Assets initializer
SortingLayers = SORTING_LAYERS
```

现有的嵌套 `@id` 注释保留在提取的初始化器中。这个 消费成员保留其值ID；使用时不需要身份证。一个聚合 有一个归属赋值。其他参考资料使用 `Reference(NAME)` 哪里 成员支持引用。独立副本需要新的嵌套id； 编辑器的重复操作将删除旧的id。标量可能有好几个 的主人。如果网络编辑使这些值不同，则内联不同的用途。

共享语言服务为选定的完整文本提供提取到文件的功能 初始化器，内联用于单独使用，并重复。这些声明是局部的 项目设置，不创建运行时全局变量。将它们作为完整值使用 初始化;在可执行表达式中使用它们的名称，例如 `BASE + 1` 将被拒绝。初始化式循环和歧义 在同步之前聚合所有权验证失败。修复源错误 在使用提取的初始化器重置签出之前，以便它们的布局可以 恢复安全。

移民也可以移动。保持他们的 `/// @migration` 页眉和 `/// @order N` 指令，或保留用于排序的数字文件名前缀。

## 本土新作家

类、接口和枚举都是顶级声明。模式功能, getter和setter是内联的，并作为NeoScript编译；他们没有 分离源文件。

```neo
@id("enum-item-rarity-id")
enum ItemRarity {
  @id("rarity-common-id")
  Common = "Common text",
}

@id("class-inventory-item-id")
@storage(allowed: .Immutable)
abstract class InventoryItem<
  @id("inventory-context-generic-id")
  TContext extends SomeClass
> {
  @id("item-name-id")
  @settings(searchBy: .MemberKey)
  virtual string Name = "";

  @id("item-rarity-id")
  abstract ItemRarity Rarity;

  @id("item-stack-size-id")
  @settings(min: 1, max: 999)
  int StackSize = 1;

  @id("item-display-name-id")
  string DisplayName {
    get {
      return $"{Name} ({Rarity})";
    }
  }

  @id("item-use-id")
  abstract void Use(TContext context);
}
```

源标识符是持久化的名称。 `@settings` 和 `@storage` 是 由它们的声明上下文键入；无效字段和枚举情况为 诊断。Swift-like `.EnumCase` 语法适用于任何期望的枚举 类型是已知的。集中的注释，例如 `@id`， `@visibility`, `@relations` 进行横切行为。从来没有作者 `@system`;它是 为平台拥有的系统记录保留。 `@visibility(.Hidden)` 标志着 类的成员选择器和类树省略；缺席意味着可见。

列表可以重复 `@index` 和 `@column` 属性上命名字段的注释 entry类。索引需要一个非本地化的 `string` 或者单次选择 enum;列也可以针对保留的 `__other__` Key，它携带 子类添加的每个字段的默认布局。

```neo
@id("outpost-list-id")
@settings(kind: .Unordered)
@index(member: Slug, kind: .Unique)
@column(member: Slug, width: 158, pin: .Leading)
@column(member: Notes, visibility: .Hidden)
public List<Outpost> Outposts = [];
```

稳定id在重命名、重新排序和文件移动中保持身份。省略一个 `@id` 只是为了创造一些东西。成功的真实推送会分配ID和 重写来源;试运行、验证失败、上传失败和CAS失败 保持源字节对字节不变。集合项标识使用相同的 本机注释:

```neo
Tags = [
  @id("story-tag-item-id")
  "story",
];
```

## 根值和类拥有的值

`Root.neo` 包含编译器拥有的 `Root root = new() { ... }` 信封。 它的成员名、类型、id、锁注释和存储设置是 受保护，而 `root.Assets`， `root.Save`， `root.Session`, `root.User` 值初始化式是可编辑的。

可重用值存储在普通项目类的静态成员中。有 没有 `ValueRegistry` 或生成 `Values` 名称空间。

```neo
@id("assets-class-id")
@storage(allowed: .Immutable)
class Assets {
  @id("capitol-member-id")
  static Outpost Capitol = new {
    Name = "Capitol",
    Image = Images.Capitol.Slice(0),
  };

  @id("home-getter-id")
  static Outpost Home {
    get {
      return Assets.Capitol;
    }
  }
}
```

成员ID锚定存储的绑定；不添加第二个ID到静态 初始化器。嵌套的类和集合行保持独立标识。

默认值在创建值时实现一次。现有实例不需要 与以后的类默认值更改保持链接。逻辑查找/对话引用 使用本机类型的内部变量。对值类型的引用，例如 `Reference<int>`，指定成员路径：

```neo
Reference(Assets.Capitol)
Reference(root.Assets.Cosmetics.Pants)
Reference(root.Player.Gold)
Reference<PantsAsset>(key: "pants.long")
Reference<NeoDialogue>(id: "dialogue-id")
```

`Project.neo`，输入纹理/音频模板，本地化配置和 状态、优先组/选项、对话组和直接关系使用 相同的顶级类型声明语法。编译器派生出结构 行标识、存储位置、通用戳记、本地化文本链接以及 其他不可创作源的持久性细节。

## 文件

图像和音频在类型注册表中声明并直接引用：

```neo
ImageRegistry Images = new() {
  @id("sword-image-file-id")
  @settings(template: PixelArt)
  NeoImage Sword = new("Files/Images/Sword.png");
}

AudioClipRegistry AudioClips = new() {
  @id("sword-hit-audio-file-id")
  @settings(template: SoundEffect)
  NeoAudioClip SwordHit = new("Files/AudioClips/SwordHit.wav");
}
```

使用 `Images.Sword.Slice(0)` 来一杯雪碧和 `AudioClips.SwordHit` 对于音频 成员。将支持的二进制文件放入 `Files/Images/` 或者 `Files/AudioClips/` 创建一个临时符号；状态/差异报告它，和一个 成功的push写入显式声明和分配的ID。 `neo files add` 可以在push之前创建挂起的声明。

Pull和push比较服务器验证的SHA-256摘要。不同的本地/远程 字节保存本地文件，并将经过验证的远程端置于 `.neo/conflicts/files/<file-id>/` 直到显式解决。

## NeoFlow对话编写

每一个 `.neoflow` 文件直接包含一个密封的非泛型类 来源于系统 `NeoDialogue` 输入和一个所需的触发器 覆盖。对话函数和词法值绑定是普通类型的 新代码。主要语言环境散文是内联的；其他区域设置和工作流元数据 保留在本地化文本记录中。

图构造函数使用仅限neoflow的尾体。 `=> Node` 最后 `return Node;` 是相等的目的地；没有可授权的 `to:` 论点。终端文本/动作节点可以省略目的地，而触发器， 选择和结果都需要一个。

```neoflow
@id("capitol-dialogue-id")
@settings(name: "Capitol: cold boot", saveOptionChoices: true)
sealed class CapitolColdBoot : NeoDialogue {
  @primary Outpost capitol = Assets.Capitol;

  @id("can-start-function-id")
  bool CanStart() {
    return capitol.Name == "Capitol";
  }

  @id("capitol-trigger-id")
  override Trigger Trigger = new(
    group: CapitolDialogues.High,
    when: [
      @id("can-start-condition-use-id")
      CanStart,
    ]
  ) => Welcome;

  @id("welcome-node-id")
  Text Welcome = new(name: "Welcome!") {
    """
    Welcome to {capitol.Name}.
    """

    @id("continue-option-id")
    Option Continue = new() {
      """
      Tell me more.
      """
      return Finish;
    }
  }

  @id("finish-node-id")
  Text Finish = new() {
    """
    Until next time.
    """
  }
}
```

持久化条件使用、操作调用、突变、暂停、选项等 结果各有各的稳定 `@id`． 通过词汇进行引用 类的绑定和传递函数调用派生相同的链接值 网页编辑器。运行 `neo dialogue dryrun <ref>` 对话后编辑遍历 选项路径针对新的保存并捕获运行时存储所有权错误。

## 同步工作流程

```sh
neo pull
# edit .neo, .neoflow, and managed binaries
neo status
neo diff
neo dialogue dryrun <ref>
neo push --dry-run
neo push
```

拉紧跟着状态或推干跑必须是语义的 无操作。如果它报告创作更改，那么停止并报告一个往返错误 推动。

Pull按稳定标识合并源概念和集合，而不是按 索引。冲突是显式的，并阻塞编译。编辑源文件 期望的结果，或使用 `neo resolve --mine|--theirs` 作为整体 方便。没有强制cas旁路。接受所需的兼容性 只有在检查后才会碰撞 `neo push --accept-bump`.

一个push在本地准备提交：它重新编译改变了的NeoScript和 受模式影响的调用者，物化值，并验证整个图 对着被拉的头。服务器检查头部，每个更改的CAS库， 授权和行形状，然后自动提交语义记录更改， 本地化的主区域设置编辑和分级文件。它只接受来自 一个CLI在它自己的NeoScript编译器修订版。 `neo push --dry-run` 运行 同样的准备加上完整的从源到唱片的排练。

通过编辑它们的跟踪来创建类、存储值、文件声明和对话框 `.neo` 或者 `.neoflow` 直接来源。下添加托管二进制文件 `Files/Images/` 或者 `Files/AudioClips/`； `neo push` 发现它们并将它们与源事务放在一起。CLI故意没有并行支架或低级内容写入命令。

## NeoScript单元测试

的地方 `*.spec.neo` 文件在项目源代码旁边的任何地方。他们看到了完整的 本地准备的生产图——包括未推入的声明、值和 函数体-加上仅测试类型的前奏。生产源从未见过 测试全局。

```neo
describe("Player.TakeDamage", () => {
  test("rejects negative damage", () => {
    var player = new Player();
    expect(() => { player.TakeDamage(-1); }).toThrow("negative");
  });
});
```

运行所有测试，按文件/目录缩小范围，或使用。过滤完整测试名称 JavaScript正则表达式：

```sh
neo test
neo test Classes/Player.spec.neo
neo test -t "TakeDamage"
neo test --seed=17
neo test --maxWorkers=4
neo test --runInBand
neo test --reporter=json --outputFile=.neo/test-results.json
```

`--seed` 接受一个带符号的安全十进制整数，取2^32的约模。JSON 报告记录有效种子。没有它，项目指纹选择 种子。注册和每个隔离测试重新开始；beforeEach,身体, 和after共享测试的流。工作线程计数和过滤器不会改变 开始的水流。 `neo script eval --seed 17` 种子单一评价 服务器快照。

本地候选人评估保留待处理的身份 `.neo/export.json` 因此，随机存储的结构在测试、试运行、导出和推送中都是一致的。 一个只有身份的文件并不意味着Unity导出成功。缓存的候选人 恢复丢失的保留和重建冲突。推钩消耗 家长准备的候选人；不完整的钩子元数据显式失败。

默认情况下，规范文件与最多四个可用CPU工作线程并行运行。 集 `test.maxWorkers` 在 `neo.json` 或者用 `--maxWorkers <positive integer>`. `--runInBand` 覆盖两者并串行运行。单个选择 文件在主进程中运行。每个文件中的钩子和测试保持有序； fixture和mock保持隔离。报告、保存文件和测试注册命令。

JSON报告器使用 `schemaVersion: 2`． 失败帧包含一个成员名 和可选的 `file`， `line`, `column`． 没有文件的帧包括 `coordinateSpace` 区分身体相对位置；未知位置是 省略。从版本1升级的消费者必须允许这些可选位置。

JSON输出文件是自动写入的。报告区分已经过的启动 以及从总结的测试工作中执行，这可能会超过并行运行的时间 运行。JSON `timings.workerStartupMs` 测量worker初始化和 `timings.executeMs` 度量经过的执行。

测试编译并验证本地候选程序一次。他们省略了额外的来源 连载和重降排练使用的 `neo push --dry-run`;生产 语法、类型检查和整个图验证仍然是必需的。规范编制 跨缓存丢失共享一个不可变的编译器上下文和模式索引。

测试编译元数据和经过实验验证的准备项目缓存 住在 `.neo/test-build/`;它们和测试文件都不是服务器记录。 生产源，管理文件，配置，工作空间状态，CLI版本， 和编译器修订使准备的项目无效，而只编辑一个 `.spec.neo` File重用它。丢失、损坏或校验和不匹配的缓存 重新构建条目。工作空间必须初始化或拉一次 `.neo/state.json` 包含离线项目事实，但正在运行测试 不执行登录或网络请求。

本机函数不能在本地求值器中执行，因此会失败 除非被嘲笑，否则关闭。使用 `mock.native(Member)`， `mock.function(Member)`，或者 `spyOn(Member)`，然后配置 `returns`， `returnsOnce`， `throws`， `throwsOnce`， `doesNothing`，或者 `implementation`. 模拟和调用历史记录在每个测试中是隔离的。

要进行门推送，请将其中一个或两个命令添加到 `neo.json`：

```json
{
  "prePushHook": "neo test",
  "prePushDryRunHook": "neo test --reporter=json --outputFile=.neo/test-results.json"
}
```

real-push钩子故意不被用于演练：任意钩子 命令可能有副作用。每个适用的钩子只在local之后运行 候选人验证和认证前/网络活动；一个非零 退出中止。 `neo push --no-verify` 是显式本地旁路，而不是服务器 授权边界。

## 命令

| 命令 | 目的 |
| --- | --- |
| `--version` | 打印安装的CLI包版本。 |
| `login [--api <url>]` | 验证选定的概要文件。 |
| `whoami [--api <url>]` | 检查选定的概要文件。 |
| `logout [--api <url>]` | 删除一个API源的存储凭据并撤销其会话。 |
| `init --project <id> [--version <id>]` | 创建一个format-4工作副本并执行其第一次重置拉取。 |
| `doctor` | 验证格式/编译器/编辑器/源/文件契约；否。净的发现。 |
| `pull [--force|--reset] [--regenerate-source-names]` | 合并远程更改或重新生成规范源代码和二进制文件。 |
| `status [--json]` | 编译源代码和汇总语义记录和上传意图。 |
| `diff [--json]` | 显示语义记录、跨度、摘要和上传意图。 |
| `push [--dry-run] [--accept-bump] [--no-verify]` | 验证或提交一个原子比较-交换事务。 |
| `test [file-or-dir ...] [-t pattern]` | 编译未推送的本地候选程序并运行 `*.spec.neo` 测试。 |
| `dev [--unity-project <dir>]` | 运行 `neo export` 每次局部变化之后；不要拉或推。 |
| `resolve --mine|--theirs` | 用一方解决当前所有的源/二进制冲突。 |
| `script check|compile|eval` | 编译或预览带有项目上下文的NeoScript；永远不要提交写。 |
| `dialogue dryrun <ref>` | 模拟本地编写的对话候选人。 |
| `loc` | 检查或编辑未在主语言环境源中表示的本地化数据。 |
| `migrate new|list|check|run|prune` | 编写和管理跟踪的NeoScript迁移。 |
| `branch` | 管理写时复制分支。 |
| `merge` | 合并分支变更。 |
| `release` | 剪切、发布、存档或恢复发布。 |
| `channel` | 管理发布渠道。 |
| `history` | 检查并有意改写保留下来的历史。 |
| `export [--unity-project <dir>]` | 将工作副本（包括本地编辑）写入Unity项目中。 |

除了…之外 `neo loc`，内容创作通过 追踪原生来源和 `neo push`． 本地化命令可能会发生变化 权威本地化记录： `.neo` 不能完全代表；运行 `neo pull` 随后，在进一步的源代码编辑或推送之前。

`login`， `whoami`, `logout` 使用当前的工作区 `apiBaseUrl` 当 在下面跑 `neo.json`． 一个显式的 `--api` 需要优先。外 工作空间，它们使用CLI构建的默认API源。Login打印 在请求或存储凭据之前选择的来源。

令牌在可用时使用操作系统凭证存储和受保护的本地文件 只能作为退路。CI可以使用 `NEO_COMPOSE_TOKEN` 或者 `--token-stdin`。这个 编辑器配置文件无法发布版本；服务器授权仍然是 安全边界。

## 重新生成对话源名称

每次拉扯，包括 `--force` 和 `--reset`，保存对话源名称 服务器存储。来替换生成的默认值，例如 `Value_1a2b3c4d5e6f`， `NeoFunction_…`，或者 `Conditions1` 使用从编辑器派生的名称，运行：

```sh
neo pull --regenerate-source-names
neo status
neo push --dry-run
```

您选择的名字将被保留。当绑定被重命名时，引用它的代码也被重命名 重写以匹配。自定义链接值首选非空字符串成员 `Name`在对话范围内使用PascalCase，在节点内使用camelCase。

拉动将重新生成的名称作为局部更改留下。id不变，和 之前不会向服务器写入任何内容 `neo push` 成功。

## 包装

`node cli/build.mjs` 捆绑了Node编排器和浏览器安全的Neo 语言/编译器/编辑资产。npm包中没有c# SDK， Roslyn 应用程序、DLL或。NET运行时元数据。包检查拒绝那些 构件并验证是否存在共享的编译器资产和技能。

开发时的有用检查：

```sh
npm run typecheck
npx vitest run cli
npm --prefix cli run test:package
```

在发布、打包和发布之前运行存储库的完整验证套件 练习VS Code扩展，验证Hello World和live `neowyn` 格式-4无操作工作流，并运行 `npm run doctor` 最后的。

### 源格式

CLI和NeoScript VS Code扩展使用相同的格式化器。把项目 偏好, `.editorconfig`，包括在父目录 `neo/`：

```ini
[*.{neo,neoflow}]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
```

嵌套的EditorConfig节覆盖父节。没有明确的 按照惯例，CLI再生使用两个空格、LF和最后一个换行符。VS代码 扩展使用编辑器设置作为回退并禁用缩进 默认是猜测。要在同步和编辑器保存中使用四个空格或制表符， 将首选项设置为 `.editorconfig`.

当发出的令牌不变时，Push保留已授权的文本，包括 普通注释和空白行。Pull保留文件而不改变语义。 仅格式化的主体和源位置的差异不会创建稍后的推送， 甚至与其他编辑一起。本地测试使用当前文件位置； `neo push --force-recompile` 显式刷新存储位置。内部的变化 字符串字面值仍然很重要。 必须重新生成的文件使用共享格式化策略。网络编辑使用 共享的两个空格默认值，并将包装器缩进排除在存储体之外。

## 常见问题

### @neocompose/cli 是什么？

neocompose原生项目源CLI与双向同步。

### 如何安装 @neocompose/cli？

在项目目录运行 npm install @neocompose/cli，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 neo，可以用 npx neo 直接运行。

### @neocompose/cli 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/neocompose\_\_cli 是否存在。

### @neocompose/cli 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @neocompose/cli 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @neocompose/cli 可以商用吗？

@neocompose/cli 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @neocompose/cli 还在维护吗？

最新版本 0\.93\.5 发布于 2026/11/02（1 天前）；至今共发布 346 个版本，其中过去 12 个月发布了 346 个；首次发布于 2026/06/12。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

