release-skill 0.9.30 → 0.9.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.cursor-plugin/plugin.json +1 -1
- package/.kimi-plugin/plugin.json +1 -1
- package/.qoder-plugin/plugin.json +1 -1
- package/CHANGELOG.md +55 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +11 -15
- package/README.zh-CN.md +11 -15
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +195 -11
- package/adapters/claude/skills/release-help/SKILL.md +8 -2
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +195 -11
- package/adapters/codex/skills/release-help/SKILL.md +8 -2
- package/adapters/cursor/.cursor-plugin/plugin.json +1 -1
- package/adapters/cursor/bin/release-skill.bundle.mjs +195 -11
- package/adapters/cursor/skills/release-help/SKILL.md +8 -2
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +195 -11
- package/adapters/kimi/skills/release-help/SKILL.md +8 -2
- package/adapters/qoder/.qoder-plugin/plugin.json +1 -1
- package/adapters/qoder/bin/release-skill.bundle.mjs +195 -11
- package/adapters/qoder/skills/release-help/SKILL.md +8 -2
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +195 -11
- package/adapters/workbuddy/skills/release-help/SKILL.md +8 -2
- package/bin/release-skill.bundle.mjs +195 -11
- package/package.json +1 -1
- package/platform-manifest.json +4 -4
- package/skills/release-help/SKILL.md +8 -2
- package/skills-src/release-help/SKILL.md +8 -2
- package/src/commands/post-release-finish.mjs +1 -1
- package/src/commands/post-release-local.mjs +192 -8
|
@@ -9,9 +9,9 @@ const __bundlePkgRoot = __bundleResolve(__bundleDirname(__bundleFileURLToPath(im
|
|
|
9
9
|
// Provide a real require() for CJS packages bundled into ESM (e.g. yaml, ajv).
|
|
10
10
|
const __bundleRealRequire = __bundleCreateRequire(import.meta.url);
|
|
11
11
|
// Package identity injected at build time — closure-independent --version probe.
|
|
12
|
-
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.32"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "b023c0808411ba0bf3fea258860422e38fe89a744a6c33676eb07e08c2a43b0b";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -137228,17 +137228,198 @@ function parseCodeBuddyRemoteObservation(target, stdout) {
|
|
|
137228
137228
|
};
|
|
137229
137229
|
}
|
|
137230
137230
|
function kimiExpectProgram({ removePlugin } = {}) {
|
|
137231
|
-
const removeCommand = removePlugin ? `
|
|
137232
|
-
|
|
137233
|
-
|
|
137231
|
+
const removeCommand = removePlugin ? `proc kimi22RemoveIdentity {dialog} {
|
|
137232
|
+
set identity ""
|
|
137233
|
+
foreach rawLine [split $dialog "\\n"] {
|
|
137234
|
+
set line [string trim $rawLine]
|
|
137235
|
+
if {[regexp -nocase {Remove .+ \\(([^()]+)\\)\\?} $line match pluginId]} {
|
|
137236
|
+
if {$identity ne "" && $identity ne $pluginId} { return "" }
|
|
137237
|
+
set identity $pluginId
|
|
137238
|
+
}
|
|
137239
|
+
}
|
|
137240
|
+
return $identity
|
|
137241
|
+
}
|
|
137242
|
+
|
|
137243
|
+
proc kimi22RemoveDialogComplete {dialog} {
|
|
137244
|
+
set hasCancel 0
|
|
137245
|
+
set hasRemove 0
|
|
137246
|
+
foreach rawLine [split $dialog "\\n"] {
|
|
137247
|
+
set line [string trim $rawLine]
|
|
137248
|
+
regsub {^\u276F[ \\t]*} $line {} label
|
|
137249
|
+
set label [string trim $label]
|
|
137250
|
+
if {[string equal -nocase $label "Cancel"]} { set hasCancel 1 }
|
|
137251
|
+
if {[string equal -nocase $label "Remove plugin"]} { set hasRemove 1 }
|
|
137252
|
+
}
|
|
137253
|
+
return [expr {$hasCancel && $hasRemove}]
|
|
137254
|
+
}
|
|
137255
|
+
|
|
137256
|
+
proc kimi22RemoveAction {dialog state unknownCode} {
|
|
137257
|
+
set labels {}
|
|
137258
|
+
set selectedCount 0
|
|
137259
|
+
set selectedIndex -1
|
|
137260
|
+
set selectedLabel ""
|
|
137261
|
+
set removeCount 0
|
|
137262
|
+
set removeIndex -1
|
|
137263
|
+
foreach rawLine [split $dialog "\\n"] {
|
|
137264
|
+
set line [string trim $rawLine]
|
|
137265
|
+
if {$line eq ""} { continue }
|
|
137266
|
+
set selected [regexp {^\u276F[ \\t]*} $line]
|
|
137267
|
+
if {$selected} {
|
|
137268
|
+
regsub {^\u276F[ \\t]*} $line {} label
|
|
137269
|
+
set label [string trim $label]
|
|
137270
|
+
} else {
|
|
137271
|
+
set label $line
|
|
137272
|
+
}
|
|
137273
|
+
set knownAction [expr {
|
|
137274
|
+
[string equal -nocase $label "Cancel"]
|
|
137275
|
+
|| [string equal -nocase $label "Remove plugin"]
|
|
137276
|
+
}]
|
|
137277
|
+
if {!$knownAction && $selected} {
|
|
137278
|
+
puts stderr "KIMI_TUI_STATE:$state:unknown"
|
|
137279
|
+
exit $unknownCode
|
|
137280
|
+
}
|
|
137281
|
+
if {!$knownAction} { continue }
|
|
137282
|
+
set index [llength $labels]
|
|
137283
|
+
lappend labels $label
|
|
137284
|
+
if {[string equal -nocase $label "Remove plugin"]} {
|
|
137285
|
+
incr removeCount
|
|
137286
|
+
set removeIndex $index
|
|
137287
|
+
}
|
|
137288
|
+
if {$selected} {
|
|
137289
|
+
incr selectedCount
|
|
137290
|
+
set selectedIndex $index
|
|
137291
|
+
set selectedLabel $label
|
|
137292
|
+
}
|
|
137293
|
+
}
|
|
137294
|
+
if {[llength $labels] != 2 || $removeCount != 1 || $selectedCount != 1} {
|
|
137295
|
+
puts stderr "KIMI_TUI_STATE:$state:unknown"
|
|
137296
|
+
exit $unknownCode
|
|
137297
|
+
}
|
|
137298
|
+
if {[string equal -nocase $selectedLabel "Remove plugin"]} {
|
|
137299
|
+
return selected-remove
|
|
137300
|
+
}
|
|
137301
|
+
if {![string equal -nocase $selectedLabel "Cancel"]} {
|
|
137302
|
+
puts stderr "KIMI_TUI_STATE:$state:unknown"
|
|
137303
|
+
exit $unknownCode
|
|
137304
|
+
}
|
|
137305
|
+
if {$selectedIndex + 1 == $removeIndex} { return move-down }
|
|
137306
|
+
if {$selectedIndex - 1 == $removeIndex} { return move-up }
|
|
137307
|
+
puts stderr "KIMI_TUI_STATE:$state:unknown"
|
|
137308
|
+
exit $unknownCode
|
|
137309
|
+
}
|
|
137310
|
+
|
|
137311
|
+
proc readKimi22RemoveDialog {prefix state timeoutCode unknownCode eofCode} {
|
|
137312
|
+
global expect_out
|
|
137313
|
+
set dialogBuffer $prefix
|
|
137314
|
+
set cleaned [cleanScreen $dialogBuffer]
|
|
137315
|
+
if {![regexp -nocase {Remove .+ \\(([^()]+)\\)\\?} $cleaned]} {
|
|
137234
137316
|
expect {
|
|
137235
|
-
-
|
|
137236
|
-
|
|
137237
|
-
send -- "\\033\\[13u"
|
|
137317
|
+
-nocase -re {Remove [^\\r\\n]*\\([^\\r\\n]+\\)\\?} {
|
|
137318
|
+
append dialogBuffer $expect_out(buffer)
|
|
137238
137319
|
}
|
|
137239
|
-
timeout { failTimeout
|
|
137240
|
-
eof { failEof
|
|
137320
|
+
timeout { failTimeout $state $timeoutCode $unknownCode }
|
|
137321
|
+
eof { failEof $state $eofCode }
|
|
137241
137322
|
}
|
|
137323
|
+
set cleaned [cleanScreen $dialogBuffer]
|
|
137324
|
+
}
|
|
137325
|
+
while {![kimi22RemoveDialogComplete $cleaned]} {
|
|
137326
|
+
expect {
|
|
137327
|
+
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137328
|
+
-nocase -re {(?:Cancel|Remove plugin)[^\\r\\n]*\\r*\\n} {
|
|
137329
|
+
append dialogBuffer $expect_out(buffer)
|
|
137330
|
+
}
|
|
137331
|
+
-re {([^\\r\\n]+\\r*\\n)} {
|
|
137332
|
+
append dialogBuffer $expect_out(buffer)
|
|
137333
|
+
}
|
|
137334
|
+
timeout { failTimeout $state $timeoutCode $unknownCode }
|
|
137335
|
+
eof { failEof $state $eofCode }
|
|
137336
|
+
}
|
|
137337
|
+
set cleaned [cleanScreen $dialogBuffer]
|
|
137338
|
+
}
|
|
137339
|
+
# Consume the initial synchronized frame before sending a selection key.
|
|
137340
|
+
# Otherwise its remaining rows can be mistaken for the selection repaint.
|
|
137341
|
+
if {[string last "\\033\\[?2026h" $dialogBuffer] > [string last "\\033\\[?2026l" $dialogBuffer]} {
|
|
137342
|
+
expect {
|
|
137343
|
+
-exact "\\033\\[?2026l" { append dialogBuffer $expect_out(buffer) }
|
|
137344
|
+
timeout { failTimeout $state $timeoutCode $unknownCode }
|
|
137345
|
+
eof { failEof $state $eofCode }
|
|
137346
|
+
}
|
|
137347
|
+
set cleaned [cleanScreen $dialogBuffer]
|
|
137348
|
+
}
|
|
137349
|
+
return $cleaned
|
|
137350
|
+
}
|
|
137351
|
+
|
|
137352
|
+
proc readKimi22RemoveSelection {} {
|
|
137353
|
+
global expect_out removePlugin
|
|
137354
|
+
expect {
|
|
137355
|
+
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137356
|
+
-nocase -re {Remove [^\\r\\n]*\\([^\\r\\n]+\\)\\?} {
|
|
137357
|
+
set dialog [readKimi22RemoveDialog $expect_out(buffer) remove-confirm-selection 125 127 126]
|
|
137358
|
+
if {[kimi22RemoveIdentity $dialog] ne $removePlugin} {
|
|
137359
|
+
puts stderr "KIMI_TUI_STATE:remove-confirm-selection:unknown"
|
|
137360
|
+
exit 127
|
|
137361
|
+
}
|
|
137362
|
+
return $dialog
|
|
137363
|
+
}
|
|
137364
|
+
-exact "\\033\\[?2026l" {
|
|
137365
|
+
# Kimi 2.2 redraws only the changed menu rows, with no title or final newline.
|
|
137366
|
+
# The initial dialog already bound the plugin; require one complete new frame.
|
|
137367
|
+
if {[string first "\\033\\[?2026h" $expect_out(buffer)] < 0} {
|
|
137368
|
+
puts stderr "KIMI_TUI_STATE:remove-confirm-selection:unknown"
|
|
137369
|
+
exit 127
|
|
137370
|
+
}
|
|
137371
|
+
return [cleanScreen $expect_out(buffer)]
|
|
137372
|
+
}
|
|
137373
|
+
timeout { failTimeout remove-confirm-selection 125 127 }
|
|
137374
|
+
eof { failEof remove-confirm-selection 126 }
|
|
137375
|
+
}
|
|
137376
|
+
}
|
|
137377
|
+
|
|
137378
|
+
proc confirmKimi22Remove {} {
|
|
137379
|
+
global expect_out promptPattern removePlugin
|
|
137380
|
+
set dialog [readKimi22RemoveDialog $expect_out(buffer) remove-confirmation 125 127 126]
|
|
137381
|
+
set identity [kimi22RemoveIdentity $dialog]
|
|
137382
|
+
if {$identity eq "" || $identity ne $removePlugin} {
|
|
137383
|
+
puts stderr "KIMI_TUI_STATE:remove-confirmation:unknown"
|
|
137384
|
+
exit 127
|
|
137385
|
+
}
|
|
137386
|
+
set action [kimi22RemoveAction $dialog remove-confirmation 127]
|
|
137387
|
+
if {$action eq "move-down"} {
|
|
137388
|
+
send -- "\\033\\[B"
|
|
137389
|
+
} elseif {$action eq "move-up"} {
|
|
137390
|
+
send -- "\\033\\[A"
|
|
137391
|
+
}
|
|
137392
|
+
if {$action ne "selected-remove"} {
|
|
137393
|
+
set confirmedDialog [readKimi22RemoveSelection]
|
|
137394
|
+
set confirmedIdentity [kimi22RemoveIdentity $confirmedDialog]
|
|
137395
|
+
if {$confirmedIdentity ne "" && $confirmedIdentity ne $removePlugin} {
|
|
137396
|
+
puts stderr "KIMI_TUI_STATE:remove-confirm-selection:unknown"
|
|
137397
|
+
exit 127
|
|
137398
|
+
}
|
|
137399
|
+
set confirmedAction [kimi22RemoveAction $confirmedDialog remove-confirm-selection 127]
|
|
137400
|
+
if {$confirmedAction ne "selected-remove"} {
|
|
137401
|
+
puts stderr "KIMI_TUI_STATE:remove-confirm-selection:unknown"
|
|
137402
|
+
exit 127
|
|
137403
|
+
}
|
|
137404
|
+
}
|
|
137405
|
+
send -- "\\033\\[13u"
|
|
137406
|
+
expect {
|
|
137407
|
+
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137408
|
+
-re $promptPattern {}
|
|
137409
|
+
timeout { failTimeout remove-prompt 128 130 }
|
|
137410
|
+
eof { failEof remove-prompt 129 }
|
|
137411
|
+
}
|
|
137412
|
+
}
|
|
137413
|
+
|
|
137414
|
+
submitCommand "/plugins remove $removePlugin"
|
|
137415
|
+
expect {
|
|
137416
|
+
-nocase -re {Confirm remove plugin "([^"\\r\\n]+)"\\?\\r*\\n} {
|
|
137417
|
+
if {$expect_out(1,string) ne $removePlugin} {
|
|
137418
|
+
puts stderr "KIMI_TUI_STATE:remove-confirmation:unknown"
|
|
137419
|
+
exit 127
|
|
137420
|
+
}
|
|
137421
|
+
send -- "\\033\\[B"
|
|
137422
|
+
send -- "\\033\\[13u"
|
|
137242
137423
|
expect {
|
|
137243
137424
|
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137244
137425
|
-re $promptPattern {}
|
|
@@ -137246,6 +137427,9 @@ expect {
|
|
|
137246
137427
|
eof { failEof remove-prompt 129 }
|
|
137247
137428
|
}
|
|
137248
137429
|
}
|
|
137430
|
+
-nocase -re {Remove [^\\r\\n]*\\([^\\r\\n]+\\)\\?} {
|
|
137431
|
+
confirmKimi22Remove
|
|
137432
|
+
}
|
|
137249
137433
|
-re $promptPattern {}
|
|
137250
137434
|
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137251
137435
|
timeout { failTimeout remove-dialog 122 124 }
|
|
@@ -146909,7 +147093,7 @@ async function runPostReleaseFinish({
|
|
|
146909
147093
|
}
|
|
146910
147094
|
const setupSkill = loaded.config.releaseFinish?.setupSkill;
|
|
146911
147095
|
const candidates = observations.filter((entry) => entry.installation === "current" && entry.loaded === true && typeof entry.skillFile === "string");
|
|
146912
|
-
const candidateOwners = new Set(candidates.map((entry) => `${entry.
|
|
147096
|
+
const candidateOwners = new Set(candidates.map((entry) => `${entry.unitId}\0${entry.plugin}\0${entry.version}`));
|
|
146913
147097
|
const effectiveSetup = updateKeepsFeedback ? feedback.setup : null;
|
|
146914
147098
|
let setupStep;
|
|
146915
147099
|
if (!setupSkill) {
|
|
@@ -37,9 +37,15 @@ description: "Discoverable entry point for release-skill: dependency and environ
|
|
|
37
37
|
|
|
38
38
|
治理诊断只运行 release-skill 自己的只读检查程序,不运行目标 Skill、业务脚本、构建、hook 或发布动作,也不把 `prepare`、`verify`、`release-finish` 当作静态治理入口。用户要求实际接入或发布时,把已有授权带到对应原业务入口;各入口继续执行原有确认、副作用和状态机合同。
|
|
39
39
|
|
|
40
|
-
## 0.9.
|
|
40
|
+
## 0.9.32 能力与证据边界
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
0.9.32 修复了 Kimi 2.2.0 移除菜单移动后,适配器因等待完整标题而失败的问题。真实终端只重绘变动的菜单行,不重发插件标题,末行也没有换行。适配器在移动后必须先重新观察选中项,确认唯一选中 `Remove plugin` 后才允许提交操作。读取帧前先核实初始精确插件 ID,读完该帧后才发送方向键,再读取完整增量帧并核对唯一选中项,完整标题重绘时仍核对精确 ID。未知、歧义、未移动、帧未完成、timeout、EOF 均导致失败关闭,不继续安装。 移除确认页仍采用 `Remove <displayName> (<id>)?`,包含 Cancel 和 Remove plugin 选项;已选中 `Remove plugin` 时无需方向键。显示名含 Confirm 或 Sure,或标题分块到达,仍核对精确身份,不触发旧宽泛正则路径。
|
|
43
|
+
|
|
44
|
+
保留 Kimi 0.40.1 的实际确认措辞 `Confirm remove plugin "<id>"?`、括号粘贴与 CSI Enter 输入方式。冻结的安装 URL/ref/sha、安装后 name/version 与载荷核对规则未变。 真实 Kimi 2.2.0 已完成确认前的精确身份、移动及选中项观察,随后按 Esc 取消并退出,未执行移除、安装或更新。47 项聚焦测试通过,独立代码审阅无发现;真实消费者的完整更新与加载验收仍待执行。修复面向真实更新流程,提供方升级不扩大宿主授权,也无需重发原领域插件。
|
|
45
|
+
|
|
46
|
+
同一 `unitId/plugin/version` 的共享环境 setup 按单元、插件、版本归并,Claude/Codex 不同物理 `skillFile` 路径不再视为多个 setup 归属。仅需一个已加载宿主的精确 setup 反馈即可满足共享环境检查要求。各宿主的安装、加载及专属配置仍需分别核实,反馈继续绑定 `host/unit/path/plan/config/root`;真正多插件归属仍需消歧,Kimi 失败或其他宿主失败均导致收尾状态为 FAILED,不改变 `VERIFIED`/`DISTRIBUTED` 发布状态。
|
|
47
|
+
|
|
48
|
+
本版保留 Foundation 0.25.0 精确依赖、可选宿主覆盖诊断输入 `--host-coverage <file>` 与 `--observe-hosts`、Codex 0.154.0 对 11 份真实生成 Skill 的原字节静态检查能力。静态检查不证明安装、会话选择或业务执行通过,批准、发布和验证状态以对应计划、批准及执行记录为准。Qoder 本机更新路径处理维持既有能力,支持 `./adapters/qoder/skills/` 与 `./skills/` 两种布局,仍核对安装 name/version/skills、路径包含性与实际载荷。私有 Hub 的 `RELEASE_SKILL_HUB_RELEASE_EVIDENCE` 环境变量继续要求原始描述符指向的已有普通文件绝对路径(拒绝符号链接),交由 `npm run release:check -- --release-evidence <file>` 验证。实际版本能力不能等同于发布状态或真实宿主验收。
|
|
43
49
|
|
|
44
50
|
在冻结前,`prepare` 或新建 `ship` 状态时可重复传入 `--unit <id>`;未传入则默认选择全部单元。延期单元不进入发布计划,亦不获得发布状态。完整配置、生成物新鲜度检查及顶层 Hook 仍作用于全项目范围。`publicSourceAuthorityReceipt` 的 coordinator 与全部 subjects 必须共同选择。
|
|
45
51
|
|
|
@@ -9,9 +9,9 @@ const __bundlePkgRoot = __bundleResolve(__bundleDirname(__bundleFileURLToPath(im
|
|
|
9
9
|
// Provide a real require() for CJS packages bundled into ESM (e.g. yaml, ajv).
|
|
10
10
|
const __bundleRealRequire = __bundleCreateRequire(import.meta.url);
|
|
11
11
|
// Package identity injected at build time — closure-independent --version probe.
|
|
12
|
-
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.32"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "b023c0808411ba0bf3fea258860422e38fe89a744a6c33676eb07e08c2a43b0b";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -137228,17 +137228,198 @@ function parseCodeBuddyRemoteObservation(target, stdout) {
|
|
|
137228
137228
|
};
|
|
137229
137229
|
}
|
|
137230
137230
|
function kimiExpectProgram({ removePlugin } = {}) {
|
|
137231
|
-
const removeCommand = removePlugin ? `
|
|
137232
|
-
|
|
137233
|
-
|
|
137231
|
+
const removeCommand = removePlugin ? `proc kimi22RemoveIdentity {dialog} {
|
|
137232
|
+
set identity ""
|
|
137233
|
+
foreach rawLine [split $dialog "\\n"] {
|
|
137234
|
+
set line [string trim $rawLine]
|
|
137235
|
+
if {[regexp -nocase {Remove .+ \\(([^()]+)\\)\\?} $line match pluginId]} {
|
|
137236
|
+
if {$identity ne "" && $identity ne $pluginId} { return "" }
|
|
137237
|
+
set identity $pluginId
|
|
137238
|
+
}
|
|
137239
|
+
}
|
|
137240
|
+
return $identity
|
|
137241
|
+
}
|
|
137242
|
+
|
|
137243
|
+
proc kimi22RemoveDialogComplete {dialog} {
|
|
137244
|
+
set hasCancel 0
|
|
137245
|
+
set hasRemove 0
|
|
137246
|
+
foreach rawLine [split $dialog "\\n"] {
|
|
137247
|
+
set line [string trim $rawLine]
|
|
137248
|
+
regsub {^\u276F[ \\t]*} $line {} label
|
|
137249
|
+
set label [string trim $label]
|
|
137250
|
+
if {[string equal -nocase $label "Cancel"]} { set hasCancel 1 }
|
|
137251
|
+
if {[string equal -nocase $label "Remove plugin"]} { set hasRemove 1 }
|
|
137252
|
+
}
|
|
137253
|
+
return [expr {$hasCancel && $hasRemove}]
|
|
137254
|
+
}
|
|
137255
|
+
|
|
137256
|
+
proc kimi22RemoveAction {dialog state unknownCode} {
|
|
137257
|
+
set labels {}
|
|
137258
|
+
set selectedCount 0
|
|
137259
|
+
set selectedIndex -1
|
|
137260
|
+
set selectedLabel ""
|
|
137261
|
+
set removeCount 0
|
|
137262
|
+
set removeIndex -1
|
|
137263
|
+
foreach rawLine [split $dialog "\\n"] {
|
|
137264
|
+
set line [string trim $rawLine]
|
|
137265
|
+
if {$line eq ""} { continue }
|
|
137266
|
+
set selected [regexp {^\u276F[ \\t]*} $line]
|
|
137267
|
+
if {$selected} {
|
|
137268
|
+
regsub {^\u276F[ \\t]*} $line {} label
|
|
137269
|
+
set label [string trim $label]
|
|
137270
|
+
} else {
|
|
137271
|
+
set label $line
|
|
137272
|
+
}
|
|
137273
|
+
set knownAction [expr {
|
|
137274
|
+
[string equal -nocase $label "Cancel"]
|
|
137275
|
+
|| [string equal -nocase $label "Remove plugin"]
|
|
137276
|
+
}]
|
|
137277
|
+
if {!$knownAction && $selected} {
|
|
137278
|
+
puts stderr "KIMI_TUI_STATE:$state:unknown"
|
|
137279
|
+
exit $unknownCode
|
|
137280
|
+
}
|
|
137281
|
+
if {!$knownAction} { continue }
|
|
137282
|
+
set index [llength $labels]
|
|
137283
|
+
lappend labels $label
|
|
137284
|
+
if {[string equal -nocase $label "Remove plugin"]} {
|
|
137285
|
+
incr removeCount
|
|
137286
|
+
set removeIndex $index
|
|
137287
|
+
}
|
|
137288
|
+
if {$selected} {
|
|
137289
|
+
incr selectedCount
|
|
137290
|
+
set selectedIndex $index
|
|
137291
|
+
set selectedLabel $label
|
|
137292
|
+
}
|
|
137293
|
+
}
|
|
137294
|
+
if {[llength $labels] != 2 || $removeCount != 1 || $selectedCount != 1} {
|
|
137295
|
+
puts stderr "KIMI_TUI_STATE:$state:unknown"
|
|
137296
|
+
exit $unknownCode
|
|
137297
|
+
}
|
|
137298
|
+
if {[string equal -nocase $selectedLabel "Remove plugin"]} {
|
|
137299
|
+
return selected-remove
|
|
137300
|
+
}
|
|
137301
|
+
if {![string equal -nocase $selectedLabel "Cancel"]} {
|
|
137302
|
+
puts stderr "KIMI_TUI_STATE:$state:unknown"
|
|
137303
|
+
exit $unknownCode
|
|
137304
|
+
}
|
|
137305
|
+
if {$selectedIndex + 1 == $removeIndex} { return move-down }
|
|
137306
|
+
if {$selectedIndex - 1 == $removeIndex} { return move-up }
|
|
137307
|
+
puts stderr "KIMI_TUI_STATE:$state:unknown"
|
|
137308
|
+
exit $unknownCode
|
|
137309
|
+
}
|
|
137310
|
+
|
|
137311
|
+
proc readKimi22RemoveDialog {prefix state timeoutCode unknownCode eofCode} {
|
|
137312
|
+
global expect_out
|
|
137313
|
+
set dialogBuffer $prefix
|
|
137314
|
+
set cleaned [cleanScreen $dialogBuffer]
|
|
137315
|
+
if {![regexp -nocase {Remove .+ \\(([^()]+)\\)\\?} $cleaned]} {
|
|
137234
137316
|
expect {
|
|
137235
|
-
-
|
|
137236
|
-
|
|
137237
|
-
send -- "\\033\\[13u"
|
|
137317
|
+
-nocase -re {Remove [^\\r\\n]*\\([^\\r\\n]+\\)\\?} {
|
|
137318
|
+
append dialogBuffer $expect_out(buffer)
|
|
137238
137319
|
}
|
|
137239
|
-
timeout { failTimeout
|
|
137240
|
-
eof { failEof
|
|
137320
|
+
timeout { failTimeout $state $timeoutCode $unknownCode }
|
|
137321
|
+
eof { failEof $state $eofCode }
|
|
137241
137322
|
}
|
|
137323
|
+
set cleaned [cleanScreen $dialogBuffer]
|
|
137324
|
+
}
|
|
137325
|
+
while {![kimi22RemoveDialogComplete $cleaned]} {
|
|
137326
|
+
expect {
|
|
137327
|
+
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137328
|
+
-nocase -re {(?:Cancel|Remove plugin)[^\\r\\n]*\\r*\\n} {
|
|
137329
|
+
append dialogBuffer $expect_out(buffer)
|
|
137330
|
+
}
|
|
137331
|
+
-re {([^\\r\\n]+\\r*\\n)} {
|
|
137332
|
+
append dialogBuffer $expect_out(buffer)
|
|
137333
|
+
}
|
|
137334
|
+
timeout { failTimeout $state $timeoutCode $unknownCode }
|
|
137335
|
+
eof { failEof $state $eofCode }
|
|
137336
|
+
}
|
|
137337
|
+
set cleaned [cleanScreen $dialogBuffer]
|
|
137338
|
+
}
|
|
137339
|
+
# Consume the initial synchronized frame before sending a selection key.
|
|
137340
|
+
# Otherwise its remaining rows can be mistaken for the selection repaint.
|
|
137341
|
+
if {[string last "\\033\\[?2026h" $dialogBuffer] > [string last "\\033\\[?2026l" $dialogBuffer]} {
|
|
137342
|
+
expect {
|
|
137343
|
+
-exact "\\033\\[?2026l" { append dialogBuffer $expect_out(buffer) }
|
|
137344
|
+
timeout { failTimeout $state $timeoutCode $unknownCode }
|
|
137345
|
+
eof { failEof $state $eofCode }
|
|
137346
|
+
}
|
|
137347
|
+
set cleaned [cleanScreen $dialogBuffer]
|
|
137348
|
+
}
|
|
137349
|
+
return $cleaned
|
|
137350
|
+
}
|
|
137351
|
+
|
|
137352
|
+
proc readKimi22RemoveSelection {} {
|
|
137353
|
+
global expect_out removePlugin
|
|
137354
|
+
expect {
|
|
137355
|
+
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137356
|
+
-nocase -re {Remove [^\\r\\n]*\\([^\\r\\n]+\\)\\?} {
|
|
137357
|
+
set dialog [readKimi22RemoveDialog $expect_out(buffer) remove-confirm-selection 125 127 126]
|
|
137358
|
+
if {[kimi22RemoveIdentity $dialog] ne $removePlugin} {
|
|
137359
|
+
puts stderr "KIMI_TUI_STATE:remove-confirm-selection:unknown"
|
|
137360
|
+
exit 127
|
|
137361
|
+
}
|
|
137362
|
+
return $dialog
|
|
137363
|
+
}
|
|
137364
|
+
-exact "\\033\\[?2026l" {
|
|
137365
|
+
# Kimi 2.2 redraws only the changed menu rows, with no title or final newline.
|
|
137366
|
+
# The initial dialog already bound the plugin; require one complete new frame.
|
|
137367
|
+
if {[string first "\\033\\[?2026h" $expect_out(buffer)] < 0} {
|
|
137368
|
+
puts stderr "KIMI_TUI_STATE:remove-confirm-selection:unknown"
|
|
137369
|
+
exit 127
|
|
137370
|
+
}
|
|
137371
|
+
return [cleanScreen $expect_out(buffer)]
|
|
137372
|
+
}
|
|
137373
|
+
timeout { failTimeout remove-confirm-selection 125 127 }
|
|
137374
|
+
eof { failEof remove-confirm-selection 126 }
|
|
137375
|
+
}
|
|
137376
|
+
}
|
|
137377
|
+
|
|
137378
|
+
proc confirmKimi22Remove {} {
|
|
137379
|
+
global expect_out promptPattern removePlugin
|
|
137380
|
+
set dialog [readKimi22RemoveDialog $expect_out(buffer) remove-confirmation 125 127 126]
|
|
137381
|
+
set identity [kimi22RemoveIdentity $dialog]
|
|
137382
|
+
if {$identity eq "" || $identity ne $removePlugin} {
|
|
137383
|
+
puts stderr "KIMI_TUI_STATE:remove-confirmation:unknown"
|
|
137384
|
+
exit 127
|
|
137385
|
+
}
|
|
137386
|
+
set action [kimi22RemoveAction $dialog remove-confirmation 127]
|
|
137387
|
+
if {$action eq "move-down"} {
|
|
137388
|
+
send -- "\\033\\[B"
|
|
137389
|
+
} elseif {$action eq "move-up"} {
|
|
137390
|
+
send -- "\\033\\[A"
|
|
137391
|
+
}
|
|
137392
|
+
if {$action ne "selected-remove"} {
|
|
137393
|
+
set confirmedDialog [readKimi22RemoveSelection]
|
|
137394
|
+
set confirmedIdentity [kimi22RemoveIdentity $confirmedDialog]
|
|
137395
|
+
if {$confirmedIdentity ne "" && $confirmedIdentity ne $removePlugin} {
|
|
137396
|
+
puts stderr "KIMI_TUI_STATE:remove-confirm-selection:unknown"
|
|
137397
|
+
exit 127
|
|
137398
|
+
}
|
|
137399
|
+
set confirmedAction [kimi22RemoveAction $confirmedDialog remove-confirm-selection 127]
|
|
137400
|
+
if {$confirmedAction ne "selected-remove"} {
|
|
137401
|
+
puts stderr "KIMI_TUI_STATE:remove-confirm-selection:unknown"
|
|
137402
|
+
exit 127
|
|
137403
|
+
}
|
|
137404
|
+
}
|
|
137405
|
+
send -- "\\033\\[13u"
|
|
137406
|
+
expect {
|
|
137407
|
+
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137408
|
+
-re $promptPattern {}
|
|
137409
|
+
timeout { failTimeout remove-prompt 128 130 }
|
|
137410
|
+
eof { failEof remove-prompt 129 }
|
|
137411
|
+
}
|
|
137412
|
+
}
|
|
137413
|
+
|
|
137414
|
+
submitCommand "/plugins remove $removePlugin"
|
|
137415
|
+
expect {
|
|
137416
|
+
-nocase -re {Confirm remove plugin "([^"\\r\\n]+)"\\?\\r*\\n} {
|
|
137417
|
+
if {$expect_out(1,string) ne $removePlugin} {
|
|
137418
|
+
puts stderr "KIMI_TUI_STATE:remove-confirmation:unknown"
|
|
137419
|
+
exit 127
|
|
137420
|
+
}
|
|
137421
|
+
send -- "\\033\\[B"
|
|
137422
|
+
send -- "\\033\\[13u"
|
|
137242
137423
|
expect {
|
|
137243
137424
|
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137244
137425
|
-re $promptPattern {}
|
|
@@ -137246,6 +137427,9 @@ expect {
|
|
|
137246
137427
|
eof { failEof remove-prompt 129 }
|
|
137247
137428
|
}
|
|
137248
137429
|
}
|
|
137430
|
+
-nocase -re {Remove [^\\r\\n]*\\([^\\r\\n]+\\)\\?} {
|
|
137431
|
+
confirmKimi22Remove
|
|
137432
|
+
}
|
|
137249
137433
|
-re $promptPattern {}
|
|
137250
137434
|
-nocase -re {Trust this folder\\?} { unexpectedDirectoryTrust }
|
|
137251
137435
|
timeout { failTimeout remove-dialog 122 124 }
|
|
@@ -146909,7 +147093,7 @@ async function runPostReleaseFinish({
|
|
|
146909
147093
|
}
|
|
146910
147094
|
const setupSkill = loaded.config.releaseFinish?.setupSkill;
|
|
146911
147095
|
const candidates = observations.filter((entry) => entry.installation === "current" && entry.loaded === true && typeof entry.skillFile === "string");
|
|
146912
|
-
const candidateOwners = new Set(candidates.map((entry) => `${entry.
|
|
147096
|
+
const candidateOwners = new Set(candidates.map((entry) => `${entry.unitId}\0${entry.plugin}\0${entry.version}`));
|
|
146913
147097
|
const effectiveSetup = updateKeepsFeedback ? feedback.setup : null;
|
|
146914
147098
|
let setupStep;
|
|
146915
147099
|
if (!setupSkill) {
|
|
@@ -38,9 +38,15 @@ description: "Discoverable entry point for release-skill: dependency and environ
|
|
|
38
38
|
|
|
39
39
|
治理诊断只运行 release-skill 自己的只读检查程序,不运行目标 Skill、业务脚本、构建、hook 或发布动作,也不把 `prepare`、`verify`、`release-finish` 当作静态治理入口。用户要求实际接入或发布时,把已有授权带到对应原业务入口;各入口继续执行原有确认、副作用和状态机合同。
|
|
40
40
|
|
|
41
|
-
## 0.9.
|
|
41
|
+
## 0.9.32 能力与证据边界
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
0.9.32 修复了 Kimi 2.2.0 移除菜单移动后,适配器因等待完整标题而失败的问题。真实终端只重绘变动的菜单行,不重发插件标题,末行也没有换行。适配器在移动后必须先重新观察选中项,确认唯一选中 `Remove plugin` 后才允许提交操作。读取帧前先核实初始精确插件 ID,读完该帧后才发送方向键,再读取完整增量帧并核对唯一选中项,完整标题重绘时仍核对精确 ID。未知、歧义、未移动、帧未完成、timeout、EOF 均导致失败关闭,不继续安装。 移除确认页仍采用 `Remove <displayName> (<id>)?`,包含 Cancel 和 Remove plugin 选项;已选中 `Remove plugin` 时无需方向键。显示名含 Confirm 或 Sure,或标题分块到达,仍核对精确身份,不触发旧宽泛正则路径。
|
|
44
|
+
|
|
45
|
+
保留 Kimi 0.40.1 的实际确认措辞 `Confirm remove plugin "<id>"?`、括号粘贴与 CSI Enter 输入方式。冻结的安装 URL/ref/sha、安装后 name/version 与载荷核对规则未变。 真实 Kimi 2.2.0 已完成确认前的精确身份、移动及选中项观察,随后按 Esc 取消并退出,未执行移除、安装或更新。47 项聚焦测试通过,独立代码审阅无发现;真实消费者的完整更新与加载验收仍待执行。修复面向真实更新流程,提供方升级不扩大宿主授权,也无需重发原领域插件。
|
|
46
|
+
|
|
47
|
+
同一 `unitId/plugin/version` 的共享环境 setup 按单元、插件、版本归并,Claude/Codex 不同物理 `skillFile` 路径不再视为多个 setup 归属。仅需一个已加载宿主的精确 setup 反馈即可满足共享环境检查要求。各宿主的安装、加载及专属配置仍需分别核实,反馈继续绑定 `host/unit/path/plan/config/root`;真正多插件归属仍需消歧,Kimi 失败或其他宿主失败均导致收尾状态为 FAILED,不改变 `VERIFIED`/`DISTRIBUTED` 发布状态。
|
|
48
|
+
|
|
49
|
+
本版保留 Foundation 0.25.0 精确依赖、可选宿主覆盖诊断输入 `--host-coverage <file>` 与 `--observe-hosts`、Codex 0.154.0 对 11 份真实生成 Skill 的原字节静态检查能力。静态检查不证明安装、会话选择或业务执行通过,批准、发布和验证状态以对应计划、批准及执行记录为准。Qoder 本机更新路径处理维持既有能力,支持 `./adapters/qoder/skills/` 与 `./skills/` 两种布局,仍核对安装 name/version/skills、路径包含性与实际载荷。私有 Hub 的 `RELEASE_SKILL_HUB_RELEASE_EVIDENCE` 环境变量继续要求原始描述符指向的已有普通文件绝对路径(拒绝符号链接),交由 `npm run release:check -- --release-evidence <file>` 验证。实际版本能力不能等同于发布状态或真实宿主验收。
|
|
44
50
|
|
|
45
51
|
在冻结前,`prepare` 或新建 `ship` 状态时可重复传入 `--unit <id>`;未传入则默认选择全部单元。延期单元不进入发布计划,亦不获得发布状态。完整配置、生成物新鲜度检查及顶层 Hook 仍作用于全项目范围。`publicSourceAuthorityReceipt` 的 coordinator 与全部 subjects 必须共同选择。
|
|
46
52
|
|