@opentag/cli 0.2.0 → 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.
package/README.md CHANGED
@@ -12,6 +12,7 @@ Then run:
12
12
 
13
13
  ```bash
14
14
  opentag setup
15
+ opentag doctor
15
16
  opentag start
16
17
  ```
17
18
 
@@ -61,6 +62,16 @@ The setup wizard links to the matching guide for each platform:
61
62
  - A local coding agent if you choose Codex or Claude Code.
62
63
  - Platform credentials for the platform you connect.
63
64
 
65
+ ## No Install
66
+
67
+ The scoped CLI package supports one-off runs without a global install:
68
+
69
+ ```bash
70
+ npx @opentag/cli doctor
71
+ npx @opentag/cli setup
72
+ npx @opentag/cli start
73
+ ```
74
+
64
75
  ## Local Development
65
76
 
66
77
  Inside the OpenTag monorepo, install the development command:
@@ -12,12 +12,12 @@ export type ExecutorDetection = {
12
12
  reason: string;
13
13
  };
14
14
  export declare const EXECUTOR_CATALOG: ExecutorDescriptor[];
15
- export declare function parseExecutorId(value: string): ExecutorId;
15
+ export declare function isExecutorId(value: string): value is ExecutorId;
16
16
  export declare function detectExecutors(env?: NodeJS.ProcessEnv): ExecutorDetection[];
17
17
  export declare function defaultExecutorId(input?: {
18
18
  previous?: ExecutorId;
19
19
  detections?: ExecutorDetection[];
20
20
  }): ExecutorId;
21
- export declare function executorLabel(id: ExecutorId): string;
21
+ export declare function executorLabel(id: string): string;
22
22
  export declare function formatExecutors(env?: NodeJS.ProcessEnv): string;
23
23
  //# sourceMappingURL=executors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"executors.d.ts","sourceRoot":"","sources":["../../src/catalogs/executors.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;AAE1D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,UAAU,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAiBhD,CAAC;AAWF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAKzD;AAED,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,iBAAiB,EAAE,CAgBzF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,GAAE;IACvC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC7B,GAAG,UAAU,CAYlB;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAEpD;AASD,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAU5E"}
1
+ {"version":3,"file":"executors.d.ts","sourceRoot":"","sources":["../../src/catalogs/executors.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;AAE1D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,UAAU,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAiBhD,CAAC;AAWF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D;AAED,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,iBAAiB,EAAE,CAgBzF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,GAAE;IACvC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC7B,GAAG,UAAU,CAYlB;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEhD;AASD,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAU5E"}
package/dist/config.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { type OpenTagDaemonConfig } from "@opentag/local-runtime";
2
2
  import { z } from "zod";
3
- import type { ExecutorId } from "./catalogs/executors.js";
4
3
  import type { CliLanguage } from "./catalogs/languages.js";
5
4
  import type { PlatformId } from "./catalogs/platforms.js";
6
5
  export declare const OpenTagCliConfigSchema: z.ZodObject<{
@@ -22,7 +21,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
22
21
  language: z.ZodOptional<z.ZodEnum<["en", "zh-CN"]>>;
23
22
  lastSetup: z.ZodOptional<z.ZodObject<{
24
23
  platforms: z.ZodOptional<z.ZodArray<z.ZodEnum<["lark", "slack", "github", "telegram"]>, "many">>;
25
- executor: z.ZodOptional<z.ZodEnum<["echo", "codex", "claude-code"]>>;
24
+ executor: z.ZodOptional<z.ZodString>;
26
25
  projectPath: z.ZodOptional<z.ZodString>;
27
26
  larkSetupMethod: z.ZodOptional<z.ZodEnum<["saved", "scan", "manual"]>>;
28
27
  larkDomain: z.ZodOptional<z.ZodEnum<["lark", "feishu"]>>;
@@ -37,7 +36,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
37
36
  githubAutoCreatePullRequest: z.ZodOptional<z.ZodBoolean>;
38
37
  }, "strict", z.ZodTypeAny, {
39
38
  platforms?: ("lark" | "slack" | "github" | "telegram")[] | undefined;
40
- executor?: "echo" | "codex" | "claude-code" | undefined;
39
+ executor?: string | undefined;
41
40
  projectPath?: string | undefined;
42
41
  larkSetupMethod?: "saved" | "scan" | "manual" | undefined;
43
42
  larkDomain?: "lark" | "feishu" | undefined;
@@ -52,7 +51,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
52
51
  githubAutoCreatePullRequest?: boolean | undefined;
53
52
  }, {
54
53
  platforms?: ("lark" | "slack" | "github" | "telegram")[] | undefined;
55
- executor?: "echo" | "codex" | "claude-code" | undefined;
54
+ executor?: string | undefined;
56
55
  projectPath?: string | undefined;
57
56
  larkSetupMethod?: "saved" | "scan" | "manual" | undefined;
58
57
  larkDomain?: "lark" | "feishu" | undefined;
@@ -70,7 +69,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
70
69
  language?: "en" | "zh-CN" | undefined;
71
70
  lastSetup?: {
72
71
  platforms?: ("lark" | "slack" | "github" | "telegram")[] | undefined;
73
- executor?: "echo" | "codex" | "claude-code" | undefined;
72
+ executor?: string | undefined;
74
73
  projectPath?: string | undefined;
75
74
  larkSetupMethod?: "saved" | "scan" | "manual" | undefined;
76
75
  larkDomain?: "lark" | "feishu" | undefined;
@@ -88,7 +87,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
88
87
  language?: "en" | "zh-CN" | undefined;
89
88
  lastSetup?: {
90
89
  platforms?: ("lark" | "slack" | "github" | "telegram")[] | undefined;
91
- executor?: "echo" | "codex" | "claude-code" | undefined;
90
+ executor?: string | undefined;
92
91
  projectPath?: string | undefined;
93
92
  larkSetupMethod?: "saved" | "scan" | "manual" | undefined;
94
93
  larkDomain?: "lark" | "feishu" | undefined;
@@ -111,7 +110,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
111
110
  owner: z.ZodString;
112
111
  repo: z.ZodString;
113
112
  checkoutPath: z.ZodString;
114
- defaultExecutor: z.ZodEnum<["echo", "codex", "claude-code"]>;
113
+ defaultExecutor: z.ZodString;
115
114
  baseBranch: z.ZodString;
116
115
  pushRemote: z.ZodString;
117
116
  worktreeRoot: z.ZodString;
@@ -121,7 +120,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
121
120
  owner: string;
122
121
  repo: string;
123
122
  checkoutPath: string;
124
- defaultExecutor: "echo" | "codex" | "claude-code";
123
+ defaultExecutor: string;
125
124
  baseBranch: string;
126
125
  pushRemote: string;
127
126
  worktreeRoot: string;
@@ -131,7 +130,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
131
130
  owner: string;
132
131
  repo: string;
133
132
  checkoutPath: string;
134
- defaultExecutor: "echo" | "codex" | "claude-code";
133
+ defaultExecutor: string;
135
134
  baseBranch: string;
136
135
  pushRemote: string;
137
136
  worktreeRoot: string;
@@ -208,7 +207,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
208
207
  owner: string;
209
208
  repo: string;
210
209
  checkoutPath: string;
211
- defaultExecutor: "echo" | "codex" | "claude-code";
210
+ defaultExecutor: string;
212
211
  baseBranch: string;
213
212
  pushRemote: string;
214
213
  worktreeRoot: string;
@@ -249,7 +248,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
249
248
  owner: string;
250
249
  repo: string;
251
250
  checkoutPath: string;
252
- defaultExecutor: "echo" | "codex" | "claude-code";
251
+ defaultExecutor: string;
253
252
  baseBranch: string;
254
253
  pushRemote: string;
255
254
  worktreeRoot: string;
@@ -468,7 +467,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
468
467
  owner: string;
469
468
  repo: string;
470
469
  checkoutPath: string;
471
- defaultExecutor: "echo" | "codex" | "claude-code";
470
+ defaultExecutor: string;
472
471
  baseBranch: string;
473
472
  pushRemote: string;
474
473
  worktreeRoot: string;
@@ -506,7 +505,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
506
505
  language?: "en" | "zh-CN" | undefined;
507
506
  lastSetup?: {
508
507
  platforms?: ("lark" | "slack" | "github" | "telegram")[] | undefined;
509
- executor?: "echo" | "codex" | "claude-code" | undefined;
508
+ executor?: string | undefined;
510
509
  projectPath?: string | undefined;
511
510
  larkSetupMethod?: "saved" | "scan" | "manual" | undefined;
512
511
  larkDomain?: "lark" | "feishu" | undefined;
@@ -563,7 +562,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
563
562
  owner: string;
564
563
  repo: string;
565
564
  checkoutPath: string;
566
- defaultExecutor: "echo" | "codex" | "claude-code";
565
+ defaultExecutor: string;
567
566
  baseBranch: string;
568
567
  pushRemote: string;
569
568
  worktreeRoot: string;
@@ -601,7 +600,7 @@ export declare const OpenTagCliConfigSchema: z.ZodObject<{
601
600
  language?: "en" | "zh-CN" | undefined;
602
601
  lastSetup?: {
603
602
  platforms?: ("lark" | "slack" | "github" | "telegram")[] | undefined;
604
- executor?: "echo" | "codex" | "claude-code" | undefined;
603
+ executor?: string | undefined;
605
604
  projectPath?: string | undefined;
606
605
  larkSetupMethod?: "saved" | "scan" | "manual" | undefined;
607
606
  larkDomain?: "lark" | "feishu" | undefined;
@@ -624,7 +623,7 @@ export type OpenTagCliPreferences = NonNullable<OpenTagCliConfig["preferences"]>
624
623
  export type OpenTagCliLastSetup = NonNullable<OpenTagCliPreferences["lastSetup"]>;
625
624
  export type OpenTagCliLanguage = CliLanguage;
626
625
  export type OpenTagCliPlatform = PlatformId;
627
- export type OpenTagCliExecutor = ExecutorId;
626
+ export type OpenTagCliExecutor = string;
628
627
  export type PathEnvironment = Partial<Record<"OPENTAG_CONFIG_PATH" | "OPENTAG_CONFIG_HOME" | "OPENTAG_STATE_DIR" | "XDG_CONFIG_HOME" | "XDG_STATE_HOME", string>>;
629
628
  export declare function defaultConfigPath(env?: PathEnvironment, home?: string): string;
630
629
  export declare function defaultStateDirectory(env?: PathEnvironment, home?: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmE,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACnI,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAqJ1D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBxB,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,EAAE,QAAQ,CAAC,GAAG;IACtF,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,WAAW,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC;AACjF,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC;AAClF,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAC7C,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAC5C,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAE5C,MAAM,MAAM,eAAe,GAAG,OAAO,CACnC,MAAM,CAAC,qBAAqB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,gBAAgB,EAAE,MAAM,CAAC,CAC3H,CAAC;AAQF,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,eAA6B,EAAE,IAAI,SAAY,GAAG,MAAM,CAG9F;AAED,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,eAA6B,EAAE,IAAI,SAAY,GAAG,MAAM,CAIlG;AAMD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK3D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAM/D;AAED,wBAAgB,aAAa,CAAC,IAAI,SAAsB,GAAG,gBAAgB,CAG1E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKzD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAYjF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM1D;AAeD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAEnE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmE,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACnI,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAyJ1D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBxB,CAAC;AAEZ,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,EAAE,QAAQ,CAAC,GAAG;IACtF,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,WAAW,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC;AACjF,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC;AAClF,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAC7C,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAC5C,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAExC,MAAM,MAAM,eAAe,GAAG,OAAO,CACnC,MAAM,CAAC,qBAAqB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,gBAAgB,EAAE,MAAM,CAAC,CAC3H,CAAC;AAQF,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,eAA6B,EAAE,IAAI,SAAY,GAAG,MAAM,CAG9F;AAED,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,eAA6B,EAAE,IAAI,SAAY,GAAG,MAAM,CAIlG;AAMD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK3D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAM/D;AAED,wBAAgB,aAAa,CAAC,IAAI,SAAsB,GAAG,gBAAgB,CAG1E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKzD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAYjF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM1D;AAeD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAEnE"}
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import { homedir } from "os";
10
10
  import { dirname, join, resolve } from "path";
11
11
  import { formatConfigError as formatDaemonConfigError, parseDaemonConfig } from "@opentag/local-runtime";
12
12
  import { z } from "zod";
13
- var ExecutorSchema = z.enum(["echo", "codex", "claude-code"]);
13
+ var ExecutorIdSchema = z.string().trim().min(1);
14
14
  var KeepWorktreeSchema = z.enum(["always", "on_failure", "never"]);
15
15
  var PositiveIntegerSchema = z.number().int().positive();
16
16
  var CliLanguageSchema = z.enum(["en", "zh-CN"]);
@@ -24,7 +24,7 @@ var RepositoryBindingSchema = z.object({
24
24
  owner: z.string().min(1),
25
25
  repo: z.string().min(1),
26
26
  checkoutPath: z.string().min(1),
27
- defaultExecutor: ExecutorSchema,
27
+ defaultExecutor: ExecutorIdSchema,
28
28
  baseBranch: z.string().min(1),
29
29
  pushRemote: z.string().min(1),
30
30
  worktreeRoot: z.string().min(1),
@@ -110,7 +110,7 @@ var PreferencesSchema = z.object({
110
110
  language: CliLanguageSchema.optional(),
111
111
  lastSetup: z.object({
112
112
  platforms: z.array(PlatformSchema).optional(),
113
- executor: ExecutorSchema.optional(),
113
+ executor: ExecutorIdSchema.optional(),
114
114
  projectPath: z.string().min(1).optional(),
115
115
  larkSetupMethod: LarkSetupMethodSchema.optional(),
116
116
  larkDomain: z.enum(["lark", "feishu"]).optional(),
@@ -244,11 +244,8 @@ function pathExistsOnPath(command, env = process.env) {
244
244
  const candidates = process.platform === "win32" && !extname(command) ? [command, ...(env.PATHEXT?.split(delimiter).filter(Boolean) ?? [".COM", ".EXE", ".BAT", ".CMD"]).map((extension) => `${command}${extension.toLowerCase()}`)] : [command];
245
245
  return paths.some((directory) => candidates.some((candidate) => existsSync(join2(directory, candidate))));
246
246
  }
247
- function parseExecutorId(value) {
248
- if (value === "echo" || value === "codex" || value === "claude-code") {
249
- return value;
250
- }
251
- throw new Error("Executor must be echo, codex, or claude-code.");
247
+ function isExecutorId(value) {
248
+ return value === "echo" || value === "codex" || value === "claude-code";
252
249
  }
253
250
  function detectExecutors(env = process.env) {
254
251
  return EXECUTOR_CATALOG.map((executor) => {
@@ -652,6 +649,7 @@ var MESSAGES = {
652
649
  language: "Language / \u8BED\u8A00",
653
650
  platform: "Where should OpenTag listen?",
654
651
  executor: "Which coding agent should OpenTag use?",
652
+ executorCustomHint: "Currently configured custom executor",
655
653
  projectPath: "Which project should OpenTag use?",
656
654
  larkSetup: "How should OpenTag connect to Lark / Feishu?",
657
655
  larkDomain: "Which Lark domain should OpenTag use?",
@@ -681,6 +679,7 @@ var MESSAGES = {
681
679
  language: "Language / \u8BED\u8A00",
682
680
  platform: "OpenTag \u8981\u76D1\u542C\u54EA\u4E2A\u5E73\u53F0\uFF1F",
683
681
  executor: "OpenTag \u8981\u4F7F\u7528\u54EA\u4E2A coding agent\uFF1F",
682
+ executorCustomHint: "\u5F53\u524D\u914D\u7F6E\u7684\u81EA\u5B9A\u4E49\u6267\u884C\u5668",
684
683
  projectPath: "OpenTag \u8981\u4F7F\u7528\u54EA\u4E2A\u9879\u76EE\uFF1F",
685
684
  larkSetup: "OpenTag \u8981\u5982\u4F55\u8FDE\u63A5 Lark / \u98DE\u4E66\uFF1F",
686
685
  larkDomain: "OpenTag \u8981\u4F7F\u7528\u54EA\u4E2A Lark \u57DF\u540D\uFF1F",
@@ -822,7 +821,7 @@ function setupNeeds(platform, language) {
822
821
  case "lark":
823
822
  return ["\u63A8\u8350\u76F4\u63A5\u626B\u7801\u521B\u5EFA Personal Agent", "\u624B\u52A8\u914D\u7F6E\u65F6\u9700\u8981 Lark App ID \u548C App Secret"];
824
823
  case "slack":
825
- return ["\u63A8\u8350\u672C\u5730\u4F7F\u7528 Socket Mode", "Socket Mode \u9700\u8981 Slack App-Level Token \u548C Bot User OAuth Token", "Events API \u9700\u8981 Slack Signing Secret \u548C\u516C\u7F51 Request URL", "Slack bot scopes \u9700\u8981 app_mentions:read\u3001chat:write\u3001channels:history", "\u8BA2\u9605 bot events: app_mention\u3001message.channels", "Slack Team ID", "Slack Channel ID", "\u6D4B\u8BD5\u524D\u9700\u8981\u628A Slack app \u9080\u8BF7\u8FDB\u76EE\u6807 channel"];
824
+ return ["\u63A8\u8350\u672C\u5730\u4F7F\u7528 Socket Mode", "Socket Mode \u9700\u8981 Slack App-Level Token \u548C Bot User OAuth Token", "Events API \u9700\u8981 Slack Signing Secret \u548C\u516C\u7F51 Request URL", "\u5F00\u542F Interactivity & Shortcuts \u4EE5\u652F\u6301 Apply 1 \u6309\u94AE", "Slack bot scopes \u9700\u8981 app_mentions:read\u3001chat:write\u3001reactions:write\u3001channels:history", "\u8BA2\u9605 bot events: app_mention\u3001message.channels", "Slack Team ID", "Slack Channel ID", "\u6D4B\u8BD5\u524D\u9700\u8981\u628A Slack app \u9080\u8BF7\u8FDB\u76EE\u6807 channel"];
826
825
  case "github":
827
826
  return ["GitHub \u4ED3\u5E93 owner/repo", "GitHub token\uFF08\u7528\u4E8E\u56DE\u5199\u8BC4\u8BBA\uFF1B\u4F60\u56DE\u590D apply 1 \u540E\u4E5F\u7528\u4E8E\u521B\u5EFA PR\uFF09", "OpenTag \u4F1A\u81EA\u52A8\u751F\u6210 webhook secret", "\u672C\u5730 webhook \u7AEF\u53E3\uFF0C\u9ED8\u8BA4 3050", "\u9700\u8981\u4E00\u4E2A\u516C\u7F51 tunnel \u8F6C\u53D1 GitHub webhook"];
828
827
  case "telegram":
@@ -833,7 +832,7 @@ function setupNeeds(platform, language) {
833
832
  case "lark":
834
833
  return ["QR scan is the recommended path", "manual setup needs a Lark App ID and App Secret"];
835
834
  case "slack":
836
- return ["Socket Mode is recommended for local OpenTag", "Socket Mode needs a Slack App-Level Token and Bot User OAuth Token", "Events API needs a Slack Signing Secret and public Request URL", "Slack bot scopes need app_mentions:read, chat:write, channels:history", "Subscribe to bot events: app_mention, message.channels", "Slack Team ID", "Slack Channel ID", "Invite the Slack app to the target channel before testing"];
835
+ return ["Socket Mode is recommended for local OpenTag", "Socket Mode needs a Slack App-Level Token and Bot User OAuth Token", "Events API needs a Slack Signing Secret and public Request URL", "Enable Interactivity & Shortcuts for Apply 1 buttons", "Slack bot scopes need app_mentions:read, chat:write, reactions:write, channels:history", "Subscribe to bot events: app_mention, message.channels", "Slack Team ID", "Slack Channel ID", "Invite the Slack app to the target channel before testing"];
837
836
  case "github":
838
837
  return ["GitHub repository owner/repo", "GitHub token for comments and PR creation after you reply `apply 1`", "OpenTag generates the webhook secret", "Local webhook port, default 3050", "A public tunnel is required for GitHub webhook delivery"];
839
838
  case "telegram":
@@ -940,18 +939,19 @@ function formatSlackCredentialHelp(language, mode) {
940
939
  const modeSpecific2 = mode === "socket_mode" ? [
941
940
  `- Socket Mode \u5B98\u65B9\u6587\u6863: ${OFFICIAL_SETUP_LINKS.slackSocketModeDocs}`,
942
941
  "- Slack App-Level Token: Basic Information -> App-Level Tokens -> Generate Token and Scopes\uFF0Cscope \u9009 connections:write",
943
- "- Socket Mode \u4E0D\u9700\u8981 Request URL"
942
+ "- Interactivity & Shortcuts: \u6253\u5F00 Interactivity\uFF1BSocket Mode \u4E0D\u9700\u8981 Request URL"
944
943
  ] : [
945
944
  `- Signing Secret \u5B98\u65B9\u6587\u6863: ${OFFICIAL_SETUP_LINKS.slackSigningSecretDocs}`,
946
945
  "- Slack Signing Secret: Basic Information -> App Credentials",
947
- "- Request URL: \u586B\u4F60\u7684\u516C\u7F51 tunnel\uFF0C\u4F8B\u5982 https://<your-tunnel>/slack/events"
946
+ "- Event Subscriptions Request URL: \u586B\u4F60\u7684\u516C\u7F51 tunnel\uFF0C\u4F8B\u5982 https://<your-tunnel>/slack/events",
947
+ "- Interactivity & Shortcuts Request URL: \u586B\u540C\u4E00\u4E2A https://<your-tunnel>/slack/events"
948
948
  ];
949
949
  return [
950
950
  "Slack \u8FD9\u4E9B\u503C\u5728\u54EA\u91CC\u62FF:",
951
951
  `- Slack App \u7BA1\u7406\u9875: ${OFFICIAL_SETUP_LINKS.slackApps}`,
952
952
  ...modeSpecific2,
953
953
  "- Slack Bot User OAuth Token: OAuth & Permissions -> Bot User OAuth Token",
954
- "- Bot Token Scopes: app_mentions:read, chat:write, channels:history",
954
+ "- Bot Token Scopes: app_mentions:read, chat:write, reactions:write, channels:history",
955
955
  "- Bot Events: app_mention, message.channels",
956
956
  "- Team ID / Channel ID: \u7528\u6D4F\u89C8\u5668\u6253\u5F00 Slack channel\uFF0C\u4ECE\u5730\u5740\u91CC\u590D\u5236 T... \u548C C...",
957
957
  "- \u6D4B\u8BD5\u524D\u5728\u76EE\u6807 channel \u91CC\u8FD0\u884C /invite @\u4F60\u7684 App \u540D\u79F0\uFF0C\u628A app \u9080\u8BF7\u8FDB channel"
@@ -960,18 +960,19 @@ function formatSlackCredentialHelp(language, mode) {
960
960
  const modeSpecific = mode === "socket_mode" ? [
961
961
  `- Socket Mode docs: ${OFFICIAL_SETUP_LINKS.slackSocketModeDocs}`,
962
962
  "- Slack App-Level Token: Basic Information -> App-Level Tokens -> Generate Token and Scopes, then add connections:write",
963
- "- Socket Mode does not need a Request URL"
963
+ "- Interactivity & Shortcuts: turn Interactivity on; Socket Mode does not need a Request URL"
964
964
  ] : [
965
965
  `- Signing Secret docs: ${OFFICIAL_SETUP_LINKS.slackSigningSecretDocs}`,
966
966
  "- Slack Signing Secret: Basic Information -> App Credentials",
967
- "- Request URL: use your public tunnel, for example https://<your-tunnel>/slack/events"
967
+ "- Event Subscriptions Request URL: use your public tunnel, for example https://<your-tunnel>/slack/events",
968
+ "- Interactivity & Shortcuts Request URL: use the same https://<your-tunnel>/slack/events"
968
969
  ];
969
970
  return [
970
971
  "Where to find these Slack values:",
971
972
  `- Slack app settings: ${OFFICIAL_SETUP_LINKS.slackApps}`,
972
973
  ...modeSpecific,
973
974
  "- Slack Bot User OAuth Token: OAuth & Permissions -> Bot User OAuth Token",
974
- "- Bot Token Scopes: app_mentions:read, chat:write, channels:history",
975
+ "- Bot Token Scopes: app_mentions:read, chat:write, reactions:write, channels:history",
975
976
  "- Bot Events: app_mention, message.channels",
976
977
  "- Team ID / Channel ID: open the Slack channel in a browser and copy the T... and C... values from the URL",
977
978
  "- Before testing, run /invite @your app name in the target channel so Slack sends mentions to the app"
@@ -1342,32 +1343,42 @@ async function collectPlatform(options, defaults, prompts, language) {
1342
1343
  return selected;
1343
1344
  }
1344
1345
  async function collectExecutor(options, defaults, prompts, language, env) {
1345
- if (options.executor) {
1346
- return parseExecutorId(options.executor);
1346
+ if (options.executor !== void 0) {
1347
+ const executor = options.executor.trim();
1348
+ if (executor.length === 0) {
1349
+ throw new Error("Executor id must not be empty.");
1350
+ }
1351
+ return executor;
1347
1352
  }
1348
1353
  const detections = detectExecutors(env);
1349
- const previous = defaults.executor;
1350
- const initialValue = defaultExecutorId({
1351
- ...previous ? { previous } : {},
1354
+ const normalizedPrevious = defaults.executor?.trim();
1355
+ if (normalizedPrevious !== void 0 && normalizedPrevious.length === 0) {
1356
+ throw new Error("Executor id must not be empty.");
1357
+ }
1358
+ const previousBuiltIn = normalizedPrevious !== void 0 && isExecutorId(normalizedPrevious) ? normalizedPrevious : void 0;
1359
+ const customPrevious = normalizedPrevious !== void 0 && previousBuiltIn === void 0 ? normalizedPrevious : void 0;
1360
+ const initialValue = customPrevious ?? defaultExecutorId({
1361
+ ...previousBuiltIn ? { previous: previousBuiltIn } : {},
1352
1362
  detections
1353
1363
  });
1364
+ const builtInOptions = EXECUTOR_CATALOG.map((executor) => {
1365
+ const detection = detections.find((entry) => entry.id === executor.id);
1366
+ return {
1367
+ value: executor.id,
1368
+ label: executor.label,
1369
+ hint: formatExecutorHint({
1370
+ language,
1371
+ executor,
1372
+ available: detection?.available ?? false,
1373
+ current: executor.id === normalizedPrevious,
1374
+ selectedByDefault: executor.id === initialValue
1375
+ })
1376
+ };
1377
+ });
1354
1378
  return prompts.select({
1355
1379
  message: t(language, "executor"),
1356
1380
  initialValue,
1357
- options: EXECUTOR_CATALOG.map((executor) => {
1358
- const detection = detections.find((entry) => entry.id === executor.id);
1359
- return {
1360
- value: executor.id,
1361
- label: executor.label,
1362
- hint: formatExecutorHint({
1363
- language,
1364
- executor,
1365
- available: detection?.available ?? false,
1366
- current: executor.id === previous,
1367
- selectedByDefault: executor.id === initialValue
1368
- })
1369
- };
1370
- })
1381
+ options: customPrevious ? [{ value: customPrevious, label: customPrevious, hint: t(language, "executorCustomHint") }, ...builtInOptions] : builtInOptions
1371
1382
  });
1372
1383
  }
1373
1384
  async function collectProjectPath(options, defaults, prompts, language, cwd) {