ctx_cli 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +3 -1
- data/docs/migration.md +7 -1
- data/docs/superpowers/plans/2026-10-24-configuration-source-paths.md +46 -0
- data/docs/superpowers/specs/2026-10-24-configuration-source-paths.md +27 -0
- data/lib/ctx_cli/configuration.rb +4 -3
- data/lib/ctx_cli/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 993414ac12bd17c37f136bb85d871efc2f217c7ca81fb7c9c57faca557030686
|
|
4
|
+
data.tar.gz: d1cfd1282ef0e9ddf5cd23243bf09076d0ffc8fed4c00186f5471e5e96bbcb94
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6a72826b05f4e540be4999b61acbf9e89517c41949ccefd475e2e67ea039e39a49754f4ddcf179de83f164954032c0d250463db0b0ac6925d51e11665d98b6d2
|
|
7
|
+
data.tar.gz: aa88dbda8a415b0f3db1a52a9283a6711951e35c5003814f75724e1ace72ae35472d7f09beda808597c04f746d6dabe7fbd6946f4a55f241cd104c05e831c5a5
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.3.0 (2026-10-24)
|
|
6
|
+
|
|
7
|
+
- Use JSON Pointer keys in configuration field provenance, separating literal dots, slashes, tildes, empty keys and nested mappings.
|
|
8
|
+
- Remove only actual descendant sources when a mapping is replaced; preserve array replacement and empty-mapping merge behavior.
|
|
9
|
+
- Breaking change: sources.fields and host --show-config output no longer expose dotted-path aliases; migrate field lookups to JSON Pointer.
|
|
10
|
+
|
|
5
11
|
## 0.2.1 (2026-10-23)
|
|
6
12
|
|
|
7
13
|
- Use English command help, prompts and collection/review diagnostics.
|
data/README.md
CHANGED
|
@@ -53,6 +53,8 @@ files.environment # .env 加原进程环境;不修改 ENV
|
|
|
53
53
|
files.sources # 路径与字段来源,不包含环境值
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
`sources["fields"]` 使用 JSON Pointer 作为字段键,例如 `/parallel`、`/ssh/known_hosts`。字面键 `a.b` 对应 `/a.b`,嵌套 `a → b` 对应 `/a/b`;键内 `/` 编为 `~1`、`~` 编为 `~0`。数组作为整体字段记录来源。宿主的 `path_fields` 声明语法不变,来源索引不保留点分键别名。
|
|
57
|
+
|
|
56
58
|
默认依次搜索 `/etc/<namespace>`、`/usr/local/etc/<namespace>`、`$XDG_CONFIG_HOME/<namespace>`(否则 `~/.config/<namespace>`)、入口目录和启动目录。每层读取 `<namespace>.yml` 与 `<name>.yml`,显式文件最后。共享文件按 `common` 和工具名称分区;name 与 namespace 相同时使用普通独立文件。`directories:` 可以完整替换搜索范围。
|
|
57
59
|
|
|
58
60
|
宿主把各层公共环境值转换成领域字段后,通过 `Configuration.merge(defaults, dotenv_values, yaml, process_values, cli)` 实现 CLI > 进程环境 > YAML > .env > 默认值。数组整层替换,false/nil 保留。相对路径按来源目录解释;支持 `path_literals:`(如 `system`)和 URI。`load` 重复调用不重新读文件。
|
|
@@ -73,7 +75,7 @@ Options 协作者沿用现有入口协议:`informational?`、`validate_interac
|
|
|
73
75
|
bundle install
|
|
74
76
|
bundle exec rake
|
|
75
77
|
bundle exec rake build
|
|
76
|
-
ruby script/verify_package.rb pkg/ctx_cli-0.
|
|
78
|
+
ruby script/verify_package.rb pkg/ctx_cli-0.3.0.gem
|
|
77
79
|
```
|
|
78
80
|
|
|
79
81
|
默认任务包括 RSpec、RuboCop 和离线示例。安装验证在独立 GEM_HOME/GEM_PATH 下运行普通与最小 Bundler 应用,检查实际加载来源。CI 参照 ctx_parser 的固定 action 提交和候选制品校验;发布需另行明确授权。
|
data/docs/migration.md
CHANGED
|
@@ -17,4 +17,10 @@ ctx_cli 初始版本为 0.1.0。首次发布依赖顺序先 ctx_cli,再 net-co
|
|
|
17
17
|
- `CtxCli::Initialization` / `ctx_cli/initialization` 改为 `CtxCli::Initializer` / `ctx_cli/initializer`,仅负责模板安全发布。
|
|
18
18
|
- `CtxCli::Application` / `ctx_cli/application` 改为 `CtxCli::Router` / `ctx_cli/router`,仅负责全局信息和子命令分发。
|
|
19
19
|
|
|
20
|
-
旧常量和 require
|
|
20
|
+
旧常量和 require 路径不保留别名。宿主需同步修改引用,并在应用锁文件中选择包含新接口的 ctx_cli 版本。`create`、`existing?`、`run` 的结果约定不变;初始化参数询问和厂商语义不迁入这两个对象。这些名称从 0.2.0 起使用。
|
|
21
|
+
|
|
22
|
+
## 0.3.0 配置来源字段
|
|
23
|
+
|
|
24
|
+
`Configuration#sources["fields"]` 的键统一使用 [JSON Pointer](https://www.rfc-editor.org/rfc/rfc6901):`parallel` 改为 `/parallel`,`ssh.port` 的嵌套路径改为 `/ssh/port`。字面键 `ssh.port` 则为 `/ssh.port`,两者拥有独立来源。空键为 `/`;每段中的 `~` 编为 `~0`,`/` 编为 `~1`,不作 Unicode 归一化。
|
|
25
|
+
|
|
26
|
+
来源值仍是 YAML 文件路径;数组整体替换,来源记在数组字段上。空映射合并不覆盖既有非空映射的来源。宿主透传的 `--show-config` 同步采用此结构;外部来源索引调用方须迁移键查找,不提供点分键回退或格式开关。`path_fields` 仍是宿主声明哪些字段要解析为文件路径的独立语法。
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Configuration Source Paths Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Give every merged configuration field an unambiguous source identity.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Configuration emits JSON Pointer keys in sources.fields. Existing hosts forward the source map unchanged; their tests and documentation migrate together. No new abstraction or alternate format.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Ruby, YAML, RSpec/Minitest, Bundler.
|
|
10
|
+
|
|
11
|
+
**Spec:** `docs/superpowers/specs/2026-10-24-configuration-source-paths.md`
|
|
12
|
+
|
|
13
|
+
## Global Constraints
|
|
14
|
+
|
|
15
|
+
- Ruby >= 3.4; no dependency or version-policy change.
|
|
16
|
+
- lib method comments Chinese; business literals English.
|
|
17
|
+
- Preserve WIP, no commit/push/release.
|
|
18
|
+
- Preserve merge semantics, source-relative paths and domain ownership.
|
|
19
|
+
- JSON Pointer applies to sources.fields only; no dot-path aliases.
|
|
20
|
+
|
|
21
|
+
## Review Focus
|
|
22
|
+
|
|
23
|
+
- Literal dots/slashes cannot collide with nesting.
|
|
24
|
+
- Tilde escape order preserves literal ~1 and ~0.
|
|
25
|
+
- Empty keys and Unicode keys retain exact identity without normalization.
|
|
26
|
+
- Replacing a parent removes only its actual descendant sources.
|
|
27
|
+
- Arrays and empty mappings keep their existing merge/source semantics.
|
|
28
|
+
|
|
29
|
+
### Task 1: Replace ambiguous source keys and migrate consumers
|
|
30
|
+
|
|
31
|
+
**Files:**
|
|
32
|
+
- Modify ctx_cli: `lib/ctx_cli/configuration.rb`, `spec/configuration_spec.rb`, `README.md`, `docs/migration.md`, `CHANGELOG.md`.
|
|
33
|
+
- Create ctx_cli: this plan and its spec.
|
|
34
|
+
- Modify VXLAN: `spec/cli/configuration_sources_spec.rb`.
|
|
35
|
+
- Modify Wireless: `spec/cli/options_spec.rb`.
|
|
36
|
+
- Modify net-connector: `test/config_test.rb`, `test/cli_setup_test.rb`.
|
|
37
|
+
|
|
38
|
+
**Interfaces:**
|
|
39
|
+
- Consumes: validated string-keyed YAML mappings and previous merged mapping.
|
|
40
|
+
- Produces: `Configuration#sources["fields"]` mapping from JSON Pointer to file path, deeply frozen; examples `/parallel`, `/ssh/port`, `/a.b`, `/a~1b`, `/m~0n`, `/`.
|
|
41
|
+
|
|
42
|
+
- [x] **Step 1:** Add real layered-YAML regressions for colliding literal and nested keys, parent replacement, escaped tokens, empty/Unicode keys, arrays and nil/false. Migrate existing source expectations to pointer keys.
|
|
43
|
+
- [x] **Step 2:** Run `bundle exec rspec spec/configuration_spec.rb`; expect RED from dot-path collisions or missing pointer keys.
|
|
44
|
+
- [x] **Step 3:** Change `record_fields` prefix construction to escaped slash tokens and descendant removal to slash-separated prefixes. Keep all merge and ownership logic. Update consumer source-key assertions and docs; no compatibility branch.
|
|
45
|
+
- [x] **Step 4:** Run ctx_cli default rake, consumer targeted tests and complete gates in isolated worktrees. Run the existing three-size benchmark before/after; verify same configuration/source counts. Expect green gates and no return to quadratic leaf scans.
|
|
46
|
+
- [x] **Step 5:** One independent final review. Guard-copy only listed files into actual checkouts, validate ordinary consumer gates using exact installed CLI candidate, and run plain/Bundler installed source/preview probes. Compare all package metadata/source bytes. Keep uncommitted work and evidence; mark all steps only with passing receipts.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Configuration 来源身份
|
|
2
|
+
|
|
3
|
+
## 问题与选择
|
|
4
|
+
|
|
5
|
+
Configuration 合并结果允许任意字符串键,但来源索引把层级拼为点分字符串。字面键 `a.b` 和嵌套 `a → b` 共享索引;用标量替换映射 `a` 时,前缀删除还会误删字面键的来源。这使 `--show-config` 的来源与实际配置不一致。
|
|
6
|
+
|
|
7
|
+
使用 [RFC 6901](https://www.rfc-editor.org/rfc/rfc6901) JSON Pointer 表达 `sources["fields"]` 的键。每层以 `/` 分隔;token 内 `~` 编为 `~0`,`/` 编为 `~1`。字面点不转义,空键使用 `/`。只生成指针,不增加求值器或依赖。来源值仍为文件路径,不含配置值。
|
|
8
|
+
|
|
9
|
+
拒绝含点的合法键会人为限制宿主数据;自定义点转义会新增不必要的语法。采用标准指针统一迁移,不保留点分别名或旧格式选择。
|
|
10
|
+
|
|
11
|
+
## 不变量与职责
|
|
12
|
+
|
|
13
|
+
- 合并、来源相对路径、数组替换、false/nil/缺失、空映射合并语义保持不变。
|
|
14
|
+
- 来源索引的叶子/祖先替换必须与实际合并一致;兄弟字面键不能被前缀删除。
|
|
15
|
+
- 数组是整体替换值,在数组字段指针上记录来源,不逐元素建表;空映射作为值时也记录其字段。
|
|
16
|
+
- `path_fields` 是宿主声明路径字段的既有语法,和来源输出不同,不在此阶段改变。
|
|
17
|
+
- 库保持 Ruby >= 3.4,不依赖 Runner/Parser/connector;lib 方法说明中文、业务字面量英文。
|
|
18
|
+
- VXLAN/Wireless/connector 仍透传来源结构;其领域校验、命令、状态与资源所有权不迁移。
|
|
19
|
+
- 保留所有既有 WIP 和当前依赖政策,不提交、推送或发布。
|
|
20
|
+
|
|
21
|
+
## 范围
|
|
22
|
+
|
|
23
|
+
11 个文件:ctx_cli 的 configuration.rb、configuration_spec.rb、README、migration、Changelog、本规格及计划;VXLAN/Wireless 各一个参数来源测试;connector 的 config_test 和 cli_setup_test。没有新增配置项或生产适配器。
|
|
24
|
+
|
|
25
|
+
## 验收
|
|
26
|
+
|
|
27
|
+
回归从真实 YAML 层证明字面点与层级不同、slash/tilde/空键/Unicode 不碰撞、替换映射只删除真正后代、数组整体替换、冻结及不含秘密值。先观察旧实现失败,再修改来源键构造与后代前缀。迁移消费端断言后运行四模块 gates、实际入口和精确候选普通/Bundler 安装。使用既有 500/1000/3000 字段基准检查规模趋势,不为共享主机设硬性能阈值。一次独立审查,无双格式接口。
|
|
@@ -341,9 +341,10 @@ module CtxCli
|
|
|
341
341
|
self.class.merge(previous, resolved)
|
|
342
342
|
end
|
|
343
343
|
|
|
344
|
-
|
|
344
|
+
# 用 JSON Pointer 区分字面键与层级,只移除被替换映射的真正后代来源。
|
|
345
|
+
def record_fields(document, source, fields, prefix = "", previous: {})
|
|
345
346
|
document.each do |key, value|
|
|
346
|
-
name =
|
|
347
|
+
name = "#{prefix}/#{key.gsub("~", "~0").gsub("/", "~1")}"
|
|
347
348
|
before = previous.is_a?(Hash) ? previous[key] : nil
|
|
348
349
|
next if value.is_a?(Hash) && value.empty? && before.is_a?(Hash) && !before.empty?
|
|
349
350
|
|
|
@@ -353,7 +354,7 @@ module CtxCli
|
|
|
353
354
|
else
|
|
354
355
|
# 只有旧映射被整体替换才需要删除后代;新增/覆盖叶子直接赋值。
|
|
355
356
|
if before.is_a?(Hash) && !before.empty?
|
|
356
|
-
descendant_prefix = "#{name}
|
|
357
|
+
descendant_prefix = "#{name}/"
|
|
357
358
|
fields.delete_if { |field, _| field.start_with?(descendant_prefix) }
|
|
358
359
|
end
|
|
359
360
|
fields[name] = source
|
data/lib/ctx_cli/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ctx_cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gatework contributors
|
|
@@ -117,6 +117,8 @@ files:
|
|
|
117
117
|
- LICENSE
|
|
118
118
|
- README.md
|
|
119
119
|
- docs/migration.md
|
|
120
|
+
- docs/superpowers/plans/2026-10-24-configuration-source-paths.md
|
|
121
|
+
- docs/superpowers/specs/2026-10-24-configuration-source-paths.md
|
|
120
122
|
- examples/configuration.rb
|
|
121
123
|
- examples/offline.rb
|
|
122
124
|
- lib/ctx_cli.rb
|