@xiaohhhh1/canvas-agent 0.4.0 → 0.4.2

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.
@@ -15,7 +15,7 @@
15
15
  ## 流程 C:脚本分镜到视频
16
16
 
17
17
  - 用户要求打开带货任务时,调用 `open_flow_c_website`,不要输出或询问 Local URL、连接令牌。
18
- - 网站把脚本任务交给本机 Codex 后,使用 `flow_c_get_script_task` 读取完整、服务器持久化的任务,再用 `flow_c_submit_script_chunk` 每次回传 1–25 条。不要要求用户复制 JSON、选择交接文件或把短期令牌发到聊天中。
18
+ - 网站把脚本任务交给本机 Codex 后,使用 `flow_c_get_script_task` 读取完整、服务器持久化的任务,再用 `flow_c_submit_script_chunk` 每次回传 1–30 条。不要要求用户复制 JSON、选择交接文件或把短期令牌发到聊天中。
19
19
  - 大批量脚本按本机助手指定的序号分段创作;批量大小不能成为降低质量、缩短脚本或套用模板的理由。每条都必须独立构思、符合目标市场自然语言习惯、保持紧凑但清晰可说完的 10 秒节奏。
20
20
  - 写脚本和回传草案不创建付费任务。只有客户在网站审阅并确认费用后,中心服务才可开始故事板和视频生成。
21
21
 
@@ -8,6 +8,7 @@ import { CanvasSession } from "../canvas/session.js";
8
8
  import { DEFAULT_PORT, ensureSiteWorkspace, loadConfig, saveConfig, updateSiteWorkspace } from "../config.js";
9
9
  import { startRelayBridge } from "../relay-bridge.js";
10
10
  import { logger } from "../utils/logger.js";
11
+ import { windowsRootExecutable, windowsSystemExecutable } from "../utils/windows.js";
11
12
  import { WorkflowManager } from "../workflow/manager.js";
12
13
  /** 启动仅监听本机的 Canvas Agent HTTP 服务。 */
13
14
  export function startHttpServer() {
@@ -284,7 +285,7 @@ function permissionMode(value) {
284
285
  }
285
286
  /** 使用当前操作系统的文件管理器定位本地文件。 */
286
287
  function revealLocalFile(filePath, isDirectory) {
287
- const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "explorer.exe" : "xdg-open";
288
+ const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? windowsRootExecutable("explorer.exe") : "xdg-open";
288
289
  const args = process.platform === "darwin"
289
290
  ? ["-R", filePath]
290
291
  : process.platform === "win32"
@@ -301,7 +302,7 @@ function revealLocalFile(filePath, isDirectory) {
301
302
  }
302
303
  /** 在默认浏览器打开本机已经配对的网站;URL 内的连接参数会被网页立即移除。 */
303
304
  function openExternalUrl(url) {
304
- const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "rundll32.exe" : "xdg-open";
305
+ const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? windowsSystemExecutable("rundll32.exe") : "xdg-open";
305
306
  const args = process.platform === "win32" ? ["url.dll,FileProtocolHandler", url] : [url];
306
307
  return new Promise((resolve, reject) => {
307
308
  const child = spawn(command, args, { detached: true, stdio: "ignore", windowsHide: true });
@@ -22,7 +22,7 @@ function registerWorkflowTools(server, config) {
22
22
  inputSchema: { handoffId: z.string().uuid().describe("网站创建的脚本交接 ID") },
23
23
  }, async ({ handoffId }) => workflowTool(config, `/agent/workflow/script-handoffs/${encodeURIComponent(handoffId)}/task`, { method: "GET" }));
24
24
  server.registerTool("flow_c_submit_script_chunk", {
25
- description: "把本段独立完成的 Flow C 高质量脚本持久化回传给网站。每次 1–25 条;成功后再创作下一段。",
25
+ description: "把本段独立完成的 Flow C 高质量脚本持久化回传给网站。每次 1–30 条;成功后再创作下一段。",
26
26
  inputSchema: {
27
27
  handoffId: z.string().uuid().describe("脚本交接 ID"),
28
28
  jobs: z.array(z.object({
@@ -0,0 +1,5 @@
1
+ type WindowsEnvironment = NodeJS.ProcessEnv;
2
+ export declare function windowsRootExecutable(name: string, env?: WindowsEnvironment): string;
3
+ export declare function windowsSystemExecutable(name: string, env?: WindowsEnvironment): string;
4
+ export declare function windowsPowerShellExecutable(env?: WindowsEnvironment): string;
5
+ export {};
@@ -0,0 +1,14 @@
1
+ import path from "node:path";
2
+ /** Resolve Windows inbox executables without relying on a possibly restricted PATH. */
3
+ function windowsRoot(env = process.env) {
4
+ return env.SystemRoot || env.SYSTEMROOT || env.WINDIR || "C:\\Windows";
5
+ }
6
+ export function windowsRootExecutable(name, env = process.env) {
7
+ return path.win32.join(windowsRoot(env), name);
8
+ }
9
+ export function windowsSystemExecutable(name, env = process.env) {
10
+ return path.win32.join(windowsRoot(env), "System32", name);
11
+ }
12
+ export function windowsPowerShellExecutable(env = process.env) {
13
+ return path.win32.join(windowsRoot(env), "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
14
+ }
@@ -8,8 +8,9 @@ import { pipeline } from "node:stream/promises";
8
8
  import { runCodexTurn, startCodexThread } from "../agent/codex.js";
9
9
  import { CONFIG_DIR, ensureSiteWorkspace } from "../config.js";
10
10
  import { logger } from "../utils/logger.js";
11
+ import { windowsPowerShellExecutable } from "../utils/windows.js";
11
12
  const STATE_FILE = path.join(CONFIG_DIR, "workflow-state.json");
12
- const SCRIPT_CHUNK_SIZE = 10;
13
+ const SCRIPT_CHUNK_SIZE = 30;
13
14
  const DOWNLOAD_POLL_MS = 10_000;
14
15
  /** 本机持久化的 Flow C 控制器:脚本交给本机 Codex,视频直接落盘。 */
15
16
  export class WorkflowManager {
@@ -83,8 +84,8 @@ export class WorkflowManager {
83
84
  /** MCP 分段回传脚本,中心接口再次执行数量、产品索引和脚本完整性校验。 */
84
85
  async submitScriptChunk(idValue, jobsValue) {
85
86
  const record = this.scriptRecord(workflowId(idValue, "脚本交接 ID"));
86
- if (!Array.isArray(jobsValue) || !jobsValue.length || jobsValue.length > 25)
87
- throw new Error("每段必须包含 1–25 条脚本");
87
+ if (!Array.isArray(jobsValue) || !jobsValue.length || jobsValue.length > SCRIPT_CHUNK_SIZE)
88
+ throw new Error(`每段必须包含 1–${SCRIPT_CHUNK_SIZE} 条脚本`);
88
89
  const jobs = jobsValue;
89
90
  const data = await commerceJson(`${record.apiBase}/workflow-script-handoffs/${encodeURIComponent(record.id)}/draft-chunks`, record.accessToken, "x-workflow-handoff-token", { method: "POST", body: JSON.stringify({ jobs }) });
90
91
  const accepted = new Set(record.receivedOrdinals);
@@ -442,7 +443,7 @@ async function isExistingFile(filePath, expectedBytes, expectedSha256 = "") {
442
443
  function selectNativeDirectory() {
443
444
  if (process.platform === "win32") {
444
445
  const script = "$ErrorActionPreference='Stop'; Add-Type -AssemblyName System.Windows.Forms; $d=New-Object System.Windows.Forms.FolderBrowserDialog; $d.Description='选择抖音小辉跨境工具的本机视频保存位置'; $d.ShowNewFolderButton=$true; if($d.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK){[Console]::OutputEncoding=[Text.Encoding]::UTF8; Write-Output $d.SelectedPath}";
445
- return commandOutput("powershell.exe", ["-NoProfile", "-STA", "-Command", script]);
446
+ return commandOutput(windowsPowerShellExecutable(), ["-NoProfile", "-STA", "-Command", script]);
446
447
  }
447
448
  if (process.platform === "darwin")
448
449
  return commandOutput("osascript", ["-e", "POSIX path of (choose folder with prompt \"选择视频保存位置\")"]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiaohhhh1/canvas-agent",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -15,7 +15,7 @@
15
15
  "scripts": {
16
16
  "dev": "tsx src/index.ts",
17
17
  "debug": "tsx src/index.ts --debug",
18
- "test": "tsx --test src/canvas/session.test.ts",
18
+ "test": "tsx --test src/**/*.test.ts",
19
19
  "build": "tsc -p tsconfig.json",
20
20
  "start": "node dist/index.js",
21
21
  "prepack": "npm run build"