maoda-commander-tt 0.0.45 → 0.0.47
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/README.md +90 -0
- package/dist/main.js +58 -29
- package/dist/main.js.map +1 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -58,6 +58,92 @@ pnpm build
|
|
|
58
58
|
pnpm start -- --help
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
## 发布到 npm
|
|
62
|
+
|
|
63
|
+
发布采用 GitHub Actions + npm Trusted Publishing(OIDC)。本地 `pnpm pub` 负责
|
|
64
|
+
检查、递增 patch 版本、提交版本和推送 `tt-v<版本>` 标签;GitHub Actions 在
|
|
65
|
+
`template-commander/` 中重新安装依赖、测试、构建,再发布 `maoda-commander-tt`。
|
|
66
|
+
|
|
67
|
+
### 首次配置
|
|
68
|
+
|
|
69
|
+
1. 将本次改造提交到 `main` 并推送到 `imaoda/local-multi-repo`,确保仓库根目录的
|
|
70
|
+
`.github/workflows/publish-tt.yml` 已在 GitHub 上,且仓库已启用 Actions。
|
|
71
|
+
2. 登录 [npm 包设置](https://www.npmjs.com/package/maoda-commander-tt/access),
|
|
72
|
+
在 Trusted publishing 中添加 GitHub Actions,填写:
|
|
73
|
+
|
|
74
|
+
| 字段 | 值 |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Organization or user | `imaoda` |
|
|
77
|
+
| Repository | `local-multi-repo` |
|
|
78
|
+
| Workflow filename | `publish-tt.yml` |
|
|
79
|
+
| Environment name | 留空 |
|
|
80
|
+
| Allowed actions | 允许直接执行 `npm publish` |
|
|
81
|
+
|
|
82
|
+
Workflow filename 只填文件名。只允许 `npm stage publish` 时,发布仍需人工批准。
|
|
83
|
+
保存信任配置时需完成一次 npm 账号验证,后续工作流发布使用 OIDC,无需配置
|
|
84
|
+
`NPM_TOKEN` 或逐次登录 npm。
|
|
85
|
+
3. 按下面的日常流程发布,在 GitHub Actions 中确认第一次发布成功。
|
|
86
|
+
|
|
87
|
+
网页保存异常时,也可以使用官方 CLI 配置同一个信任关系(终端登录及配置时
|
|
88
|
+
按 npm 提示完成账号验证):
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm exec --yes --package=npm@11.16.0 -- npm login --registry=https://registry.npmjs.org
|
|
92
|
+
npm exec --yes --package=npm@11.16.0 -- npm trust github maoda-commander-tt \
|
|
93
|
+
--repo imaoda/local-multi-repo --file publish-tt.yml --allow-publish --yes \
|
|
94
|
+
--registry=https://registry.npmjs.org
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
工作流使用 GitHub 托管的 runner、Node.js 24、npm 11.16.0 和 pnpm 11.1.2,
|
|
98
|
+
并固定第三方 Action 的提交 SHA。当前 GitHub 仓库为私有仓库,因此不会生成
|
|
99
|
+
npm provenance;这不影响 OIDC 发布。
|
|
100
|
+
|
|
101
|
+
### 日常发布
|
|
102
|
+
|
|
103
|
+
由 agent 代办时,直接说“发布 tt”即可;agent 按
|
|
104
|
+
[发布 harness](AGENTS.md) 执行检查、发布、等待 npm 目标版本可用,并在本机
|
|
105
|
+
全局安装该精确版本、验证 `tt --version`。无需用户自行执行下面的命令。
|
|
106
|
+
|
|
107
|
+
先提交代码,确保整个 Git 仓库没有未提交或未跟踪的文件,并切换到 `main`。
|
|
108
|
+
本地 `main` 可以有尚未推送的提交,但不能落后于远端或与远端分叉。
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
cd ~/work/local-multi-repo/template-commander
|
|
112
|
+
pnpm pub
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
命令会运行源码测试、发布脚本测试、构建和 CLI 帮助检查,然后只修改本包的
|
|
116
|
+
`package.json` 版本、创建发布提交和带注释的 `tt-v<版本>` 标签,原子推送
|
|
117
|
+
`main` 与这个标签。其他包的标签不会随之推送。CI 会校验标签与包版本一致;
|
|
118
|
+
普通代码推送不会触发 npm 发布。
|
|
119
|
+
|
|
120
|
+
推送成功表示已触发 CI,最终结果以
|
|
121
|
+
[Publish tt 工作流](https://github.com/imaoda/local-multi-repo/actions/workflows/publish-tt.yml)
|
|
122
|
+
为准。等待本次发布结束再发布下一版;GitHub 的并发队列可能替换尚未开始的
|
|
123
|
+
发布任务。发布后,在需要更新本机全局 `tt` 的电脑上运行 `pnpm upd`。
|
|
124
|
+
|
|
125
|
+
### 失败后继续
|
|
126
|
+
|
|
127
|
+
- 本地检查失败:先修复并提交,再运行 `pnpm pub`;检查失败不会递增版本。
|
|
128
|
+
- 推送失败但发布提交和标签已生成:按终端提示修复网络或权限,在原发布提交上
|
|
129
|
+
运行 `pnpm pub --retry`,重推同一版本,避免再次递增。
|
|
130
|
+
- 推送成功但 CI 失败:若只是 npm 信任配置错误,修正后在 Actions 中重跑失败的
|
|
131
|
+
工作流;若需修改代码,提交修复后通过 `pnpm pub` 发布新版本。
|
|
132
|
+
|
|
133
|
+
不要在 CI 中运行 `pnpm pub`:它负责本地版本提交和推送,CI 的最终发布步骤是
|
|
134
|
+
`npm publish`。已发布的版本不能重复发布。
|
|
135
|
+
|
|
136
|
+
参见 [npm Trusted Publishing 文档](https://docs.npmjs.com/trusted-publishers/)。
|
|
137
|
+
|
|
138
|
+
## Shell 快捷方式
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# 在 ~/work/web-proxy 中先执行 w2 start,成功后执行 pnpm gateway
|
|
142
|
+
tt sc w2
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
命令日志直接输出到当前终端,gateway 在前台运行。
|
|
146
|
+
|
|
61
147
|
## AI 音频生成
|
|
62
148
|
|
|
63
149
|
`ai audio` 接受一段自然语言提示词并等待 XYQ 返回 MP3。参考音频可选;提供时,
|
|
@@ -187,6 +273,10 @@ return missingNameError();
|
|
|
187
273
|
| `pnpm build` | TypeScript 编译 |
|
|
188
274
|
| `pnpm start` | 运行编译后产物 |
|
|
189
275
|
| `pnpm clean` | 清理 dist 目录 |
|
|
276
|
+
| `pnpm test:release` | 在临时 Git 仓库中验证发布脚本 |
|
|
277
|
+
| `pnpm pub` | 检查、升 patch 版本并推送 tt 标签,触发 CI 发布 |
|
|
278
|
+
| `pnpm pub --retry` | 重推当前发布提交和标签,不递增版本 |
|
|
279
|
+
| `pnpm upd` | 将本机全局 tt 更新到 npm 上的最新版本 |
|
|
190
280
|
|
|
191
281
|
## 技术栈
|
|
192
282
|
|
package/dist/main.js
CHANGED
|
@@ -2335,6 +2335,22 @@ var ShortcutEmoPippitCommand = class extends ShortcutBaseCommand {
|
|
|
2335
2335
|
}
|
|
2336
2336
|
};
|
|
2337
2337
|
|
|
2338
|
+
// src/commands/shortcut/shortcut-w2-command.ts
|
|
2339
|
+
import { homedir as homedir5 } from "node:os";
|
|
2340
|
+
import { join as join7 } from "node:path";
|
|
2341
|
+
var ShortcutW2Command = class extends ShortcutBaseCommand {
|
|
2342
|
+
_meta() {
|
|
2343
|
+
return {
|
|
2344
|
+
name: "w2",
|
|
2345
|
+
description: "\u542F\u52A8 web-proxy \u7684 whistle \u548C gateway"
|
|
2346
|
+
};
|
|
2347
|
+
}
|
|
2348
|
+
async _execute(_ctx) {
|
|
2349
|
+
const cwd = join7(homedir5(), "work", "web-proxy");
|
|
2350
|
+
return this._runCommandLine("w2 start && pnpm gateway", cwd);
|
|
2351
|
+
}
|
|
2352
|
+
};
|
|
2353
|
+
|
|
2338
2354
|
// src/commands/shortcut/shortcut-command.ts
|
|
2339
2355
|
var ShortcutCommand = class extends BaseSubcommandHost {
|
|
2340
2356
|
_meta() {
|
|
@@ -2348,6 +2364,7 @@ var ShortcutCommand = class extends BaseSubcommandHost {
|
|
|
2348
2364
|
this._addSubcommand(new ShortcutEmoLynxCommand());
|
|
2349
2365
|
this._addSubcommand(new ShortcutEmoPippitCommand());
|
|
2350
2366
|
this._addSubcommand(new ShortcutEmoPippitCnCommand());
|
|
2367
|
+
this._addSubcommand(new ShortcutW2Command());
|
|
2351
2368
|
}
|
|
2352
2369
|
};
|
|
2353
2370
|
|
|
@@ -2471,21 +2488,21 @@ var AiWebSearchCommand = class extends AiBaseCommand {
|
|
|
2471
2488
|
};
|
|
2472
2489
|
|
|
2473
2490
|
// src/commands/ai/ai-run-command.ts
|
|
2474
|
-
import { homedir as
|
|
2475
|
-
import { join as
|
|
2491
|
+
import { homedir as homedir7 } from "node:os";
|
|
2492
|
+
import { join as join9 } from "node:path";
|
|
2476
2493
|
import { ok as ok15 } from "rockbed/error";
|
|
2477
2494
|
|
|
2478
2495
|
// src/commands/ai/ai-context-path.ts
|
|
2479
2496
|
import { existsSync as existsSync2 } from "node:fs";
|
|
2480
|
-
import { homedir as
|
|
2481
|
-
import { join as
|
|
2497
|
+
import { homedir as homedir6 } from "node:os";
|
|
2498
|
+
import { join as join8 } from "node:path";
|
|
2482
2499
|
import { err as err7, ok as ok14 } from "rockbed/error";
|
|
2483
2500
|
function getCurrentCloudRootPath() {
|
|
2484
2501
|
if (process.platform !== "darwin") {
|
|
2485
2502
|
return err7(1, "`--my` \u4EC5\u652F\u6301\u5728 macOS \u4E0A\u4F7F\u7528");
|
|
2486
2503
|
}
|
|
2487
|
-
const cloudRootPath =
|
|
2488
|
-
|
|
2504
|
+
const cloudRootPath = join8(
|
|
2505
|
+
homedir6(),
|
|
2489
2506
|
"Library",
|
|
2490
2507
|
"Mobile Documents",
|
|
2491
2508
|
"com~apple~CloudDocs"
|
|
@@ -2513,7 +2530,7 @@ var AI_RUN_CONTEXT_ALIASES = [
|
|
|
2513
2530
|
return cloudRoot;
|
|
2514
2531
|
}
|
|
2515
2532
|
return ensureDirectoryExists(
|
|
2516
|
-
|
|
2533
|
+
join9(cloudRoot.value, "icloud-hub", "local-knowlege-base")
|
|
2517
2534
|
);
|
|
2518
2535
|
}
|
|
2519
2536
|
},
|
|
@@ -2522,7 +2539,7 @@ var AI_RUN_CONTEXT_ALIASES = [
|
|
|
2522
2539
|
optionDescription: "\u53C2\u8003 ~/work/smart-agent/dymamic-skills \u5B66\u4E60 skill",
|
|
2523
2540
|
resolveReferenceDir: () => {
|
|
2524
2541
|
return ensureDirectoryExists(
|
|
2525
|
-
|
|
2542
|
+
join9(homedir7(), "work", "smart-agent", "dynamic-skills")
|
|
2526
2543
|
);
|
|
2527
2544
|
}
|
|
2528
2545
|
}
|
|
@@ -3513,19 +3530,26 @@ var XyqSession = class {
|
|
|
3513
3530
|
const normalizedInput = normalizedInputResult.value;
|
|
3514
3531
|
const threadId = randomUUID3();
|
|
3515
3532
|
const clientRunId = `canvas_run_${randomUUID3()}`;
|
|
3533
|
+
const messageId = randomUUID3();
|
|
3516
3534
|
const requestId = randomUUID3();
|
|
3517
3535
|
const submittedAt = this._now();
|
|
3536
|
+
const runExtra = buildVideoPartRunExtra(clientRunId, messageId);
|
|
3518
3537
|
const body = buildSubmitVideoPartBody({
|
|
3519
3538
|
...normalizedInput,
|
|
3520
3539
|
threadId,
|
|
3521
3540
|
clientRunId,
|
|
3541
|
+
messageId,
|
|
3522
3542
|
requestId,
|
|
3523
3543
|
submittedAt,
|
|
3524
|
-
context: this.context
|
|
3544
|
+
context: this.context,
|
|
3545
|
+
runExtra
|
|
3525
3546
|
});
|
|
3547
|
+
const submitUrl = new URL(`${XYQ_ORIGIN}/api/biz/v1/agent/submit_run`);
|
|
3548
|
+
const { generate_id: _generateId, ...queryBabiParam } = runExtra.babi_param;
|
|
3549
|
+
submitUrl.searchParams.set("babi_param", JSON.stringify(queryBabiParam));
|
|
3526
3550
|
const responseResult = await requestXyqJson(
|
|
3527
3551
|
this._fetcher,
|
|
3528
|
-
|
|
3552
|
+
submitUrl.toString(),
|
|
3529
3553
|
{
|
|
3530
3554
|
method: "POST",
|
|
3531
3555
|
headers: {
|
|
@@ -3958,27 +3982,32 @@ function normalizeVideoAssetReferences(assets, label) {
|
|
|
3958
3982
|
}
|
|
3959
3983
|
return ok19(normalized);
|
|
3960
3984
|
}
|
|
3961
|
-
function
|
|
3962
|
-
|
|
3985
|
+
function buildVideoPartRunExtra(clientRunId, messageId) {
|
|
3986
|
+
return {
|
|
3963
3987
|
babi_param: {
|
|
3964
|
-
generate_id:
|
|
3965
|
-
|
|
3988
|
+
generate_id: clientRunId,
|
|
3989
|
+
user_message_id: messageId,
|
|
3990
|
+
section_id: clientRunId,
|
|
3966
3991
|
scene_lv1: "ai_agent",
|
|
3967
3992
|
scene_lv2: "front_tool",
|
|
3968
|
-
tool_id: "
|
|
3993
|
+
tool_id: "novel_canvas",
|
|
3969
3994
|
tab_name: "canvas",
|
|
3970
|
-
edit_type: "
|
|
3995
|
+
edit_type: "novel",
|
|
3971
3996
|
enter_from: "web"
|
|
3972
3997
|
},
|
|
3973
3998
|
client_extra: {
|
|
3974
|
-
edit_type: "
|
|
3999
|
+
edit_type: "novel",
|
|
4000
|
+
canvas_type: "novel",
|
|
3975
4001
|
position: "canvas",
|
|
3976
4002
|
entrance_from: "web",
|
|
3977
4003
|
tab_name: "canvas",
|
|
3978
4004
|
target: "video",
|
|
3979
|
-
run_source: "video_part"
|
|
4005
|
+
run_source: "video_part",
|
|
4006
|
+
placement_name: "canvas"
|
|
3980
4007
|
}
|
|
3981
4008
|
};
|
|
4009
|
+
}
|
|
4010
|
+
function buildSubmitVideoPartBody(input) {
|
|
3982
4011
|
const contentDataParam = {
|
|
3983
4012
|
prompt: input.prompt,
|
|
3984
4013
|
images: input.images,
|
|
@@ -4008,7 +4037,7 @@ function buildSubmitVideoPartBody(input) {
|
|
|
4008
4037
|
thread_id: input.threadId,
|
|
4009
4038
|
run_id: input.clientRunId,
|
|
4010
4039
|
created_at: input.submittedAt,
|
|
4011
|
-
message_id:
|
|
4040
|
+
message_id: input.messageId
|
|
4012
4041
|
},
|
|
4013
4042
|
user_info: {
|
|
4014
4043
|
consumer_uid: input.context.uid,
|
|
@@ -4018,7 +4047,7 @@ function buildSubmitVideoPartBody(input) {
|
|
|
4018
4047
|
},
|
|
4019
4048
|
agent_name: "pippit_novel_video_part_agent",
|
|
4020
4049
|
entrance_from: "web",
|
|
4021
|
-
run_extra: JSON.stringify(
|
|
4050
|
+
run_extra: JSON.stringify(input.runExtra),
|
|
4022
4051
|
request_id: input.requestId
|
|
4023
4052
|
};
|
|
4024
4053
|
}
|
|
@@ -4856,7 +4885,7 @@ function describeUnsuccessfulTerminalState(state) {
|
|
|
4856
4885
|
// src/commands/ai/ai-image-command-v2.ts
|
|
4857
4886
|
import { spawn as spawn3 } from "node:child_process";
|
|
4858
4887
|
import * as fs10 from "node:fs/promises";
|
|
4859
|
-
import { homedir as
|
|
4888
|
+
import { homedir as homedir10 } from "node:os";
|
|
4860
4889
|
import * as path11 from "node:path";
|
|
4861
4890
|
import { err as err10, ok as ok21 } from "rockbed/error";
|
|
4862
4891
|
|
|
@@ -4914,17 +4943,17 @@ var generateUuid = (() => {
|
|
|
4914
4943
|
// src/commands/ai/ai-image-command-v2.ts
|
|
4915
4944
|
var GENERATED_IMAGES_SUBDIR = "generated_imgs";
|
|
4916
4945
|
var GENERATED_IMAGES_DIR = path11.join(
|
|
4917
|
-
|
|
4946
|
+
homedir10(),
|
|
4918
4947
|
".codex",
|
|
4919
4948
|
GENERATED_IMAGES_SUBDIR
|
|
4920
4949
|
);
|
|
4921
4950
|
var GENERATED_IMAGES_PROMPT_DIR = `~/.codex/${GENERATED_IMAGES_SUBDIR}`;
|
|
4922
4951
|
var LEGACY_GENERATED_IMAGES_DIR = path11.join(
|
|
4923
|
-
|
|
4952
|
+
homedir10(),
|
|
4924
4953
|
".codex",
|
|
4925
4954
|
"generated_images"
|
|
4926
4955
|
);
|
|
4927
|
-
var CODEX_EMPTY_WORKDIR = path11.join(
|
|
4956
|
+
var CODEX_EMPTY_WORKDIR = path11.join(homedir10(), ".codex-empty");
|
|
4928
4957
|
var AiImageCommandV2 = class extends AiBaseCommand {
|
|
4929
4958
|
_meta() {
|
|
4930
4959
|
return {
|
|
@@ -6609,8 +6638,8 @@ async function readConfigValue2(settingsReader, key) {
|
|
|
6609
6638
|
|
|
6610
6639
|
// src/commands/tool/tool-random-files-command.ts
|
|
6611
6640
|
import { readdir as readdir2, stat as stat3 } from "node:fs/promises";
|
|
6612
|
-
import { homedir as
|
|
6613
|
-
import { extname as extname4, join as
|
|
6641
|
+
import { homedir as homedir11 } from "node:os";
|
|
6642
|
+
import { extname as extname4, join as join14, resolve as resolve8 } from "node:path";
|
|
6614
6643
|
var DEFAULT_COUNT = 1;
|
|
6615
6644
|
var DEFAULT_SUFFIXES = ["png", "jpeg", "jpg"];
|
|
6616
6645
|
var DEFAULT_DEPTH = 3;
|
|
@@ -6789,7 +6818,7 @@ async function collectMatchingFiles(options) {
|
|
|
6789
6818
|
const entries = await safeReadDir(options.folder);
|
|
6790
6819
|
const files = [];
|
|
6791
6820
|
for (const entry of entries) {
|
|
6792
|
-
const entryPath =
|
|
6821
|
+
const entryPath = join14(options.folder, entry.name);
|
|
6793
6822
|
if (entry.isFile()) {
|
|
6794
6823
|
if (hasAllowedSuffix(entry.name, options.suffixes)) {
|
|
6795
6824
|
files.push(entryPath);
|
|
@@ -6841,10 +6870,10 @@ async function safeStat(path13) {
|
|
|
6841
6870
|
}
|
|
6842
6871
|
function expandHomeDir(path13) {
|
|
6843
6872
|
if (path13 === "~") {
|
|
6844
|
-
return
|
|
6873
|
+
return homedir11();
|
|
6845
6874
|
}
|
|
6846
6875
|
if (path13.startsWith("~/")) {
|
|
6847
|
-
return
|
|
6876
|
+
return join14(homedir11(), path13.slice(2));
|
|
6848
6877
|
}
|
|
6849
6878
|
return resolve8(path13);
|
|
6850
6879
|
}
|