taskmeld 0.1.1

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.
Files changed (204) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +172 -0
  3. package/README.zh-CN.md +172 -0
  4. package/dist/src/app/app-context-env.js +51 -0
  5. package/dist/src/app/create-app-context.js +127 -0
  6. package/dist/src/app/data-dir.js +29 -0
  7. package/dist/src/app/pipeline-config.js +105 -0
  8. package/dist/src/app/pipeline-plugin-config.js +2 -0
  9. package/dist/src/app/pipeline-registry.js +502 -0
  10. package/dist/src/app/pipeline-runtime.js +202 -0
  11. package/dist/src/app/runtime-store.js +151 -0
  12. package/dist/src/app/user-config.js +37 -0
  13. package/dist/src/artifacts/artifact-cleanup.js +192 -0
  14. package/dist/src/artifacts/artifact-index.js +262 -0
  15. package/dist/src/artifacts/artifact-rebuilder.js +120 -0
  16. package/dist/src/artifacts/storage-service.js +371 -0
  17. package/dist/src/cli/bootstrap.js +226 -0
  18. package/dist/src/cli/commands/agent.js +126 -0
  19. package/dist/src/cli/commands/artifact.js +175 -0
  20. package/dist/src/cli/commands/init.js +150 -0
  21. package/dist/src/cli/commands/pipeline/errors.js +37 -0
  22. package/dist/src/cli/commands/pipeline/result.js +179 -0
  23. package/dist/src/cli/commands/pipeline/selector.js +51 -0
  24. package/dist/src/cli/commands/pipeline/types.js +2 -0
  25. package/dist/src/cli/commands/pipeline/watch.js +67 -0
  26. package/dist/src/cli/commands/pipeline.js +339 -0
  27. package/dist/src/cli/commands/scheduler.js +81 -0
  28. package/dist/src/cli/commands/server.js +70 -0
  29. package/dist/src/cli/commands/system.js +21 -0
  30. package/dist/src/cli/errors.js +71 -0
  31. package/dist/src/cli/help.js +184 -0
  32. package/dist/src/cli/index.js +65 -0
  33. package/dist/src/cli/output.js +19 -0
  34. package/dist/src/cli/renderers/engine/json.js +67 -0
  35. package/dist/src/cli/renderers/engine/markdown.js +95 -0
  36. package/dist/src/cli/renderers/engine/types.js +2 -0
  37. package/dist/src/cli/renderers/engine/utils.js +32 -0
  38. package/dist/src/cli/renderers/index.js +27 -0
  39. package/dist/src/cli/renderers/specs/agent.js +78 -0
  40. package/dist/src/cli/renderers/specs/artifact.js +32 -0
  41. package/dist/src/cli/renderers/specs/index.js +36 -0
  42. package/dist/src/cli/renderers/specs/init.js +25 -0
  43. package/dist/src/cli/renderers/specs/pipeline.js +561 -0
  44. package/dist/src/cli/renderers/specs/scheduler.js +46 -0
  45. package/dist/src/cli/renderers/specs/server.js +38 -0
  46. package/dist/src/cli/renderers/specs/system.js +36 -0
  47. package/dist/src/cli/router.js +199 -0
  48. package/dist/src/cli/server-runtime-client.js +780 -0
  49. package/dist/src/cli/types.js +2 -0
  50. package/dist/src/gateway/frame-sanitizer.js +78 -0
  51. package/dist/src/gateway/gateway-client.js +462 -0
  52. package/dist/src/gateway/index.js +18 -0
  53. package/dist/src/gateway/types.js +2 -0
  54. package/dist/src/index.js +123 -0
  55. package/dist/src/logs/run-log-reader.js +141 -0
  56. package/dist/src/logs/run-log-service.js +42 -0
  57. package/dist/src/logs/run-log-types.js +2 -0
  58. package/dist/src/pipeline/agent-activity.js +191 -0
  59. package/dist/src/pipeline/artifact-storage.js +208 -0
  60. package/dist/src/pipeline/diagnostics/dependency-diagnostic.js +105 -0
  61. package/dist/src/pipeline/diagnostics/index.js +6 -0
  62. package/dist/src/pipeline/dispatch/pipeline-inbound-queue.js +215 -0
  63. package/dist/src/pipeline/dispatch/pipeline-link-dispatcher.js +66 -0
  64. package/dist/src/pipeline/dispatch/pipeline-link-store.js +94 -0
  65. package/dist/src/pipeline/dispatch/pipeline-queue-drainer.js +71 -0
  66. package/dist/src/pipeline/execution/dependency-check.js +52 -0
  67. package/dist/src/pipeline/execution/execution-result.js +2 -0
  68. package/dist/src/pipeline/execution/group-item-executor.js +128 -0
  69. package/dist/src/pipeline/execution/index.js +5 -0
  70. package/dist/src/pipeline/execution/node-item-executor.js +58 -0
  71. package/dist/src/pipeline/execution/node-runner.js +159 -0
  72. package/dist/src/pipeline/execution/readiness-state.js +10 -0
  73. package/dist/src/pipeline/execution/reject-handler.js +94 -0
  74. package/dist/src/pipeline/execution/rejected-artifact-archiver.js +45 -0
  75. package/dist/src/pipeline/execution/route-item-manager.js +253 -0
  76. package/dist/src/pipeline/execution/run-abort-controller.js +66 -0
  77. package/dist/src/pipeline/execution/run-state-helpers.js +257 -0
  78. package/dist/src/pipeline/execution/service.js +165 -0
  79. package/dist/src/pipeline/execution/session-registry.js +96 -0
  80. package/dist/src/pipeline/execution/structured-node-runner.js +411 -0
  81. package/dist/src/pipeline/execution-status.js +96 -0
  82. package/dist/src/pipeline/execution-timeout.js +21 -0
  83. package/dist/src/pipeline/identity/index.js +32 -0
  84. package/dist/src/pipeline/identity/types.js +2 -0
  85. package/dist/src/pipeline/item-batch-controller.js +227 -0
  86. package/dist/src/pipeline/output/pipeline-output-resolver.js +91 -0
  87. package/dist/src/pipeline/output/pipeline-output-store.js +60 -0
  88. package/dist/src/pipeline/runtime-model.js +173 -0
  89. package/dist/src/pipeline/scheduler/dependency-state.js +144 -0
  90. package/dist/src/pipeline/scheduler-service.js +314 -0
  91. package/dist/src/pipeline/state/group-item-state.js +50 -0
  92. package/dist/src/pipeline/state/group-run-state.js +41 -0
  93. package/dist/src/pipeline/state/index.js +20 -0
  94. package/dist/src/pipeline/state/node-item-state.js +67 -0
  95. package/dist/src/pipeline/state/node-run-state.js +51 -0
  96. package/dist/src/pipeline/state/types.js +2 -0
  97. package/dist/src/pipeline/state-machine.js +101 -0
  98. package/dist/src/pipeline/structured-output/contract.js +133 -0
  99. package/dist/src/pipeline/structured-output/index.js +22 -0
  100. package/dist/src/pipeline/structured-output/parser.js +214 -0
  101. package/dist/src/pipeline/structured-output/prompt.js +290 -0
  102. package/dist/src/pipeline/structured-output/waiter.js +139 -0
  103. package/dist/src/pipeline/template.js +135 -0
  104. package/dist/src/pipeline/timeline-log-store.js +57 -0
  105. package/dist/src/pipeline/tool-activity.js +94 -0
  106. package/dist/src/pipeline/types/pipeline-link.js +7 -0
  107. package/dist/src/pipeline/types/pipeline-output.js +11 -0
  108. package/dist/src/pipeline/types/workflow.js +2 -0
  109. package/dist/src/pipeline/workflow/branch-rules.js +74 -0
  110. package/dist/src/pipeline/workflow/defaults.js +48 -0
  111. package/dist/src/pipeline/workflow/io.js +89 -0
  112. package/dist/src/pipeline/workflow/normalize.js +347 -0
  113. package/dist/src/pipeline/workflow/routes.js +16 -0
  114. package/dist/src/pipeline/workflow/template-mapper.js +113 -0
  115. package/dist/src/pipeline/workflow/validate.js +312 -0
  116. package/dist/src/pipeline/workflow-graph.js +165 -0
  117. package/dist/src/server/api-handler.js +163 -0
  118. package/dist/src/server/http-utils.js +34 -0
  119. package/dist/src/server/middleware.js +61 -0
  120. package/dist/src/server/router.js +105 -0
  121. package/dist/src/server/routes/agents.js +189 -0
  122. package/dist/src/server/routes/artifacts.js +163 -0
  123. package/dist/src/server/routes/gateway.js +18 -0
  124. package/dist/src/server/routes/health.js +16 -0
  125. package/dist/src/server/routes/logs.js +73 -0
  126. package/dist/src/server/routes/pipeline-batch.js +163 -0
  127. package/dist/src/server/routes/pipeline-diagnostics.js +33 -0
  128. package/dist/src/server/routes/pipeline-identity.js +24 -0
  129. package/dist/src/server/routes/pipeline-links.js +117 -0
  130. package/dist/src/server/routes/pipeline-outputs.js +27 -0
  131. package/dist/src/server/routes/pipeline-queue.js +62 -0
  132. package/dist/src/server/routes/pipeline-runtime.js +162 -0
  133. package/dist/src/server/routes/pipeline-scheduler.js +69 -0
  134. package/dist/src/server/routes/pipeline-workflow.js +180 -0
  135. package/dist/src/server/routes/pipelines.js +96 -0
  136. package/dist/src/server/routes/sessions.js +244 -0
  137. package/dist/src/server/routes/timeline.js +14 -0
  138. package/dist/src/server/serve-static.js +42 -0
  139. package/dist/src/server/types.js +2 -0
  140. package/dist/src/services/agent-service.js +79 -0
  141. package/dist/src/services/artifact-service.js +74 -0
  142. package/dist/src/services/gateway-read-helpers.js +10 -0
  143. package/dist/src/services/index.js +23 -0
  144. package/dist/src/services/pipeline-service.js +529 -0
  145. package/dist/src/services/pipeline-status.js +93 -0
  146. package/dist/src/services/read-services.js +60 -0
  147. package/dist/src/services/scheduler-service.js +37 -0
  148. package/dist/src/services/session-service.js +227 -0
  149. package/dist/src/services/system-service.js +26 -0
  150. package/dist/src/transport/ws-broker.js +48 -0
  151. package/dist/src/utils/array.js +17 -0
  152. package/dist/src/utils/guards.js +5 -0
  153. package/dist/src/utils/session.js +60 -0
  154. package/dist/src/version.js +5 -0
  155. package/package.json +61 -0
  156. package/web/dist/assets/index-CWnfhkn-.js +65 -0
  157. package/web/dist/assets/index-gZ0xOfSO.css +1 -0
  158. package/web/dist/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  159. package/web/dist/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  160. package/web/dist/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  161. package/web/dist/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  162. package/web/dist/assets/jetbrains-mono-cyrillic-700-normal-BWTpRfYl.woff2 +0 -0
  163. package/web/dist/assets/jetbrains-mono-cyrillic-700-normal-CEoEElIJ.woff +0 -0
  164. package/web/dist/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  165. package/web/dist/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  166. package/web/dist/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  167. package/web/dist/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  168. package/web/dist/assets/jetbrains-mono-greek-700-normal-C6CZE3T8.woff2 +0 -0
  169. package/web/dist/assets/jetbrains-mono-greek-700-normal-DEigVDxa.woff +0 -0
  170. package/web/dist/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  171. package/web/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  172. package/web/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  173. package/web/dist/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  174. package/web/dist/assets/jetbrains-mono-latin-700-normal-BYuf6tUa.woff2 +0 -0
  175. package/web/dist/assets/jetbrains-mono-latin-700-normal-D3wTyLJW.woff +0 -0
  176. package/web/dist/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  177. package/web/dist/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  178. package/web/dist/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  179. package/web/dist/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  180. package/web/dist/assets/jetbrains-mono-latin-ext-700-normal-CZipNAKV.woff2 +0 -0
  181. package/web/dist/assets/jetbrains-mono-latin-ext-700-normal-CxPITLHs.woff +0 -0
  182. package/web/dist/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  183. package/web/dist/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  184. package/web/dist/assets/jetbrains-mono-vietnamese-700-normal-BDLVIk2r.woff +0 -0
  185. package/web/dist/assets/space-grotesk-latin-400-normal-BnQMeOim.woff +0 -0
  186. package/web/dist/assets/space-grotesk-latin-400-normal-CJ-V5oYT.woff2 +0 -0
  187. package/web/dist/assets/space-grotesk-latin-500-normal-CNSSEhBt.woff +0 -0
  188. package/web/dist/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
  189. package/web/dist/assets/space-grotesk-latin-700-normal-CwsQ-cCU.woff +0 -0
  190. package/web/dist/assets/space-grotesk-latin-700-normal-RjhwGPKo.woff2 +0 -0
  191. package/web/dist/assets/space-grotesk-latin-ext-400-normal-CfP_5XZW.woff2 +0 -0
  192. package/web/dist/assets/space-grotesk-latin-ext-400-normal-DRPE3kg4.woff +0 -0
  193. package/web/dist/assets/space-grotesk-latin-ext-500-normal-3dgZTiw9.woff +0 -0
  194. package/web/dist/assets/space-grotesk-latin-ext-500-normal-DUe3BAxM.woff2 +0 -0
  195. package/web/dist/assets/space-grotesk-latin-ext-700-normal-BQnZhY3m.woff2 +0 -0
  196. package/web/dist/assets/space-grotesk-latin-ext-700-normal-HVCqSBdx.woff +0 -0
  197. package/web/dist/assets/space-grotesk-vietnamese-400-normal-B7xT_GF5.woff2 +0 -0
  198. package/web/dist/assets/space-grotesk-vietnamese-400-normal-BIWiOVfw.woff +0 -0
  199. package/web/dist/assets/space-grotesk-vietnamese-500-normal-BTqKIpxg.woff +0 -0
  200. package/web/dist/assets/space-grotesk-vietnamese-500-normal-BmEvtly_.woff2 +0 -0
  201. package/web/dist/assets/space-grotesk-vietnamese-700-normal-DMty7AZE.woff2 +0 -0
  202. package/web/dist/assets/space-grotesk-vietnamese-700-normal-Duxec5Rn.woff +0 -0
  203. package/web/dist/favicon.svg +10 -0
  204. package/web/dist/index.html +14 -0
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertBooleanFlag = exports.assertRequiredArg = exports.withHelpHint = exports.toCliError = exports.CliError = void 0;
4
+ class CliError extends Error {
5
+ code;
6
+ exitCode;
7
+ details;
8
+ constructor(message, options) {
9
+ super(message);
10
+ this.name = "CliError";
11
+ this.code = options?.code ?? "CLI_ERROR";
12
+ this.exitCode = options?.exitCode ?? 1;
13
+ this.details = options?.details;
14
+ }
15
+ }
16
+ exports.CliError = CliError;
17
+ // 统一把未知异常规范化,避免 CLI 输出结构漂移。
18
+ const toCliError = (error) => {
19
+ if (error instanceof CliError)
20
+ return error;
21
+ if (error instanceof Error) {
22
+ return new CliError(error.message, {
23
+ code: "UNEXPECTED_ERROR",
24
+ exitCode: 1,
25
+ });
26
+ }
27
+ return new CliError("Unknown CLI error", {
28
+ code: "UNEXPECTED_ERROR",
29
+ exitCode: 1,
30
+ details: error,
31
+ });
32
+ };
33
+ exports.toCliError = toCliError;
34
+ // 在不改动原错误元信息的前提下,为参数类错误附加帮助提示。
35
+ const withHelpHint = (error, hint) => {
36
+ if (!hint.trim())
37
+ return error;
38
+ if (error.message.includes(hint))
39
+ return error;
40
+ return new CliError(`${error.message}. ${hint}`, {
41
+ code: error.code,
42
+ exitCode: error.exitCode,
43
+ details: error.details,
44
+ });
45
+ };
46
+ exports.withHelpHint = withHelpHint;
47
+ const assertRequiredArg = (value, name) => {
48
+ if (value && value.trim())
49
+ return value.trim();
50
+ throw new CliError(`Missing required argument: ${name}`, {
51
+ code: "INVALID_ARGUMENT",
52
+ exitCode: 2,
53
+ });
54
+ };
55
+ exports.assertRequiredArg = assertRequiredArg;
56
+ const assertBooleanFlag = (value, name) => {
57
+ if (typeof value === "boolean")
58
+ return value;
59
+ if (typeof value === "string") {
60
+ const normalized = value.trim().toLowerCase();
61
+ if (normalized === "true")
62
+ return true;
63
+ if (normalized === "false")
64
+ return false;
65
+ }
66
+ throw new CliError(`Invalid boolean flag: --${name}`, {
67
+ code: "INVALID_ARGUMENT",
68
+ exitCode: 2,
69
+ });
70
+ };
71
+ exports.assertBooleanFlag = assertBooleanFlag;
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveHelpHintByRouteKey = exports.resolveHelpHint = exports.resolveHelp = void 0;
4
+ const ROOT_USAGE = "taskmeld <resource> <action> [args] [--flags]";
5
+ const GROUP_DESCRIPTIONS = {
6
+ agent: "智能体管理",
7
+ artifact: "产物管理",
8
+ init: "First-time setup",
9
+ pipeline: "流水线管理",
10
+ scheduler: "调度控制",
11
+ server: "后端服务管理",
12
+ system: "系统信息",
13
+ };
14
+ const COMMON_OPTIONS_LINES = [
15
+ "Common Options:",
16
+ " -f, --format <json|md> 输出格式(默认: md)",
17
+ " --envelope 仅与 --format json 搭配可用,输出完整包装层",
18
+ " -h, --help 显示当前命令帮助",
19
+ ];
20
+ const listPublicRoutes = (routes) => {
21
+ return routes.filter((route) => route.hidden !== true);
22
+ };
23
+ const uniqueGroups = (routes) => {
24
+ return [...new Set(listPublicRoutes(routes).map((route) => route.path[0]))].sort();
25
+ };
26
+ const listGroupActions = (routes, group) => {
27
+ return listPublicRoutes(routes)
28
+ .filter((route) => route.path[0] === group)
29
+ .sort((a, b) => a.path[1].localeCompare(b.path[1]));
30
+ };
31
+ const findCommandRoute = (routes, group, action) => {
32
+ return routes.find((route) => route.path[0] === group && route.path[1] === action);
33
+ };
34
+ const formatArgsBlock = (args) => {
35
+ if (!args || args.length === 0)
36
+ return [];
37
+ return [
38
+ "Arguments:",
39
+ ...args.map((item) => {
40
+ const printableName = item.name.startsWith("<") ? item.name : `<${item.name}>`;
41
+ const requiredLabel = item.required ? "必填" : "可选";
42
+ const detail = item.description ? `,${item.description}` : "";
43
+ return ` ${printableName} ${requiredLabel}${detail}`;
44
+ }),
45
+ ];
46
+ };
47
+ const formatOptionsBlock = (options) => {
48
+ if (!options || options.length === 0)
49
+ return [];
50
+ return [
51
+ "Options:",
52
+ ...options.map((item) => {
53
+ const flagName = item.flags.join(", ");
54
+ const valueHint = item.valueName ? ` <${item.valueName}>` : "";
55
+ const requiredLabel = item.required ? "必填" : "可选";
56
+ const detail = item.description ? `,${item.description}` : "";
57
+ return ` ${flagName}${valueHint} ${requiredLabel}${detail}`;
58
+ }),
59
+ ];
60
+ };
61
+ const formatExamplesBlock = (examples) => {
62
+ if (!examples || examples.length === 0)
63
+ return [];
64
+ return ["Examples:", ...examples.map((example) => ` ${example}`)];
65
+ };
66
+ const formatNotesBlock = (notes) => {
67
+ if (!notes || notes.length === 0)
68
+ return [];
69
+ return ["Notes:", ...notes.map((note) => ` ${note}`)];
70
+ };
71
+ const appendCommonOptions = (lines) => {
72
+ lines.push("", ...COMMON_OPTIONS_LINES);
73
+ };
74
+ const renderRoot = (routes) => {
75
+ const groups = uniqueGroups(routes);
76
+ const lines = [
77
+ "Usage:",
78
+ ` ${ROOT_USAGE}`,
79
+ "",
80
+ "Resources:",
81
+ ...groups.map((group) => {
82
+ const desc = GROUP_DESCRIPTIONS[group];
83
+ return desc ? ` ${group.padEnd(12)}${desc}` : ` ${group}`;
84
+ }),
85
+ "",
86
+ "Tips:",
87
+ " taskmeld <resource> -h 查看一级命令帮助",
88
+ " taskmeld <resource> <action> -h 查看二级命令帮助",
89
+ ];
90
+ return lines.join("\n");
91
+ };
92
+ const renderGroup = (routes, group) => {
93
+ const commands = listGroupActions(routes, group);
94
+ const lines = [
95
+ "Usage:",
96
+ ` taskmeld ${group} <action> [args] [--flags]`,
97
+ "",
98
+ "Actions:",
99
+ ...commands.map((route) => ` ${route.path[1]} ${route.description}`),
100
+ "",
101
+ "Tips:",
102
+ ` taskmeld ${group} <action> -h`,
103
+ ];
104
+ return lines.join("\n");
105
+ };
106
+ const renderAutoCommandHelp = (route) => {
107
+ const help = route.help;
108
+ const lines = ["Usage:", ` ${help.usage}`];
109
+ const summary = help.summary ?? route.description;
110
+ lines.push("", "Description:", ` ${summary}`);
111
+ const argsBlock = formatArgsBlock(help.args);
112
+ if (argsBlock.length > 0) {
113
+ lines.push("", ...argsBlock);
114
+ }
115
+ const optionsBlock = formatOptionsBlock(help.options);
116
+ if (optionsBlock.length > 0) {
117
+ lines.push("", ...optionsBlock);
118
+ }
119
+ const examplesBlock = formatExamplesBlock(help.examples);
120
+ if (examplesBlock.length > 0) {
121
+ lines.push("", ...examplesBlock);
122
+ }
123
+ const notesBlock = formatNotesBlock(help.notes);
124
+ if (notesBlock.length > 0) {
125
+ lines.push("", ...notesBlock);
126
+ }
127
+ return lines.join("\n");
128
+ };
129
+ const renderCommand = (route) => {
130
+ // 保留特例出口是为了兼容未来极少数需要完全自定义排版的命令;默认路径必须使用路由元数据生成。
131
+ const text = route.renderHelp ? route.renderHelp(route) : renderAutoCommandHelp(route);
132
+ const lines = text.split("\n");
133
+ appendCommonOptions(lines);
134
+ return lines.join("\n");
135
+ };
136
+ const resolveHelp = (routes, args) => {
137
+ if (args.length === 0) {
138
+ return { scope: "root", text: renderRoot(routes) };
139
+ }
140
+ const group = args[0];
141
+ if (!group) {
142
+ return { scope: "root", text: renderRoot(routes) };
143
+ }
144
+ if (args.length === 1) {
145
+ const standaloneRoute = routes.find((r) => r.path.length === 1 && r.path[0] === group);
146
+ if (standaloneRoute) {
147
+ return { scope: "command", text: renderCommand(standaloneRoute) };
148
+ }
149
+ const commands = listGroupActions(routes, group);
150
+ if (commands.length === 0)
151
+ return null;
152
+ return { scope: "group", text: renderGroup(routes, group) };
153
+ }
154
+ const action = args[1];
155
+ const route = findCommandRoute(routes, group, action);
156
+ if (!route)
157
+ return null;
158
+ return { scope: "command", text: renderCommand(route) };
159
+ };
160
+ exports.resolveHelp = resolveHelp;
161
+ const resolveHelpHint = (routes, args) => {
162
+ if (args.length >= 2) {
163
+ const group = args[0];
164
+ const hasGroup = listGroupActions(routes, group).length > 0;
165
+ if (hasGroup) {
166
+ return `Use: taskmeld ${group} -h`;
167
+ }
168
+ }
169
+ if (args.length >= 2) {
170
+ return `Use: taskmeld ${args[0]} ${args[1]} -h`;
171
+ }
172
+ if (args.length === 1) {
173
+ return `Use: taskmeld ${args[0]} -h`;
174
+ }
175
+ return "Use: taskmeld -h";
176
+ };
177
+ exports.resolveHelpHint = resolveHelpHint;
178
+ const resolveHelpHintByRouteKey = (routes, routeKey) => {
179
+ const route = routes.find((item) => item.key === routeKey);
180
+ if (!route)
181
+ return "Use: taskmeld -h";
182
+ return `Use: taskmeld ${route.path[0]} ${route.path[1]} -h`;
183
+ };
184
+ exports.resolveHelpHintByRouteKey = resolveHelpHintByRouteKey;
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.main = exports.runCli = void 0;
5
+ require("dotenv/config");
6
+ const version_1 = require("../version");
7
+ const errors_1 = require("./errors");
8
+ const bootstrap_1 = require("./bootstrap");
9
+ const output_1 = require("./output");
10
+ const help_1 = require("./help");
11
+ const router_1 = require("./router");
12
+ const runCli = async (options, runOptions) => {
13
+ const stdout = runOptions.stdout ?? process.stdout;
14
+ const stderr = runOptions.stderr ?? process.stderr;
15
+ let routeKey;
16
+ let routeGlobal = { format: "json", envelope: false };
17
+ let bootstrapped = null;
18
+ try {
19
+ const routeMatch = (0, router_1.resolveRoute)(runOptions);
20
+ routeKey = routeMatch.key;
21
+ routeGlobal = routeMatch.global;
22
+ const route = (0, router_1.getRouteDefinition)(routeMatch.key);
23
+ bootstrapped = await options.bootstrap({ routeKey: routeMatch.key, route });
24
+ const result = await route.handler(routeMatch.input, {
25
+ app: bootstrapped.app,
26
+ global: routeMatch.global,
27
+ });
28
+ (0, output_1.writeResult)(stdout, route.key, result, routeMatch.global);
29
+ return 0;
30
+ }
31
+ catch (error) {
32
+ let cliError = (0, errors_1.toCliError)(error);
33
+ if (cliError.code === "HELP_REQUESTED") {
34
+ (0, output_1.writeHelp)(stdout, cliError.message);
35
+ return 0;
36
+ }
37
+ if (cliError.code === "VERSION_REQUESTED") {
38
+ stdout.write(`${version_1.APP_VERSION}\n`);
39
+ return 0;
40
+ }
41
+ if (cliError.code === "INVALID_ARGUMENT" || cliError.code === "UNKNOWN_COMMAND") {
42
+ const hint = routeKey
43
+ ? (0, help_1.resolveHelpHintByRouteKey)(router_1.CLI_ROUTES, routeKey)
44
+ : (0, help_1.resolveHelpHint)(router_1.CLI_ROUTES, runOptions.argv);
45
+ cliError = (0, errors_1.withHelpHint)(cliError, hint);
46
+ }
47
+ (0, output_1.writeError)(stderr, cliError, routeKey, routeGlobal);
48
+ return cliError.exitCode;
49
+ }
50
+ finally {
51
+ await bootstrapped?.dispose?.();
52
+ }
53
+ };
54
+ exports.runCli = runCli;
55
+ const main = async (argv) => {
56
+ return (0, exports.runCli)({
57
+ bootstrap: (0, bootstrap_1.createMainCliBootstrap)(),
58
+ }, { argv, stdin: process.stdin });
59
+ };
60
+ exports.main = main;
61
+ if (require.main === module) {
62
+ void (0, exports.main)(process.argv.slice(2)).then((exitCode) => {
63
+ process.exitCode = exitCode;
64
+ });
65
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.writeHelp = exports.writeError = exports.writeResult = void 0;
4
+ const renderers_1 = require("./renderers");
5
+ // 成功输出由 renderer 统一分发,命令层不直接拼接文本。
6
+ const writeResult = (stream, command, data, global) => {
7
+ stream.write(`${(0, renderers_1.renderSuccessByMode)(command, data, global)}\n`);
8
+ };
9
+ exports.writeResult = writeResult;
10
+ // 错误统一写 stderr,避免污染 stdout 结果流。
11
+ const writeError = (stream, error, command, global) => {
12
+ stream.write(`${(0, renderers_1.renderErrorByMode)(command, error, global)}\n`);
13
+ };
14
+ exports.writeError = writeError;
15
+ // 帮助信息输出纯文本到 stdout,便于人类直接阅读。
16
+ const writeHelp = (stream, helpText) => {
17
+ stream.write(`${helpText}\n`);
18
+ };
19
+ exports.writeHelp = writeHelp;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderJsonError = exports.formatJson = exports.irToData = void 0;
4
+ const utils_1 = require("./utils");
5
+ const camelKey = (title) => {
6
+ const cleaned = title.replace(/[^a-zA-Z0-9\s]/g, "");
7
+ const words = cleaned.split(/\s+/);
8
+ const first = (words[0] ?? "").toLowerCase();
9
+ const rest = words.slice(1).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase());
10
+ return [first, ...rest].join("");
11
+ };
12
+ const irToData = (ir) => {
13
+ if (ir.kind === "text")
14
+ return ir.content;
15
+ if (ir.kind === "list") {
16
+ return (0, utils_1.extractListRows)(ir);
17
+ }
18
+ // kind: "detail"
19
+ const result = {};
20
+ for (const section of ir.sections) {
21
+ const key = camelKey(section.title);
22
+ if (section.kind === "key-value") {
23
+ const obj = {};
24
+ for (const row of section.rows) {
25
+ obj[row.field] = row.value;
26
+ }
27
+ result[key] = obj;
28
+ }
29
+ else if (section.kind === "table") {
30
+ result[key] = (0, utils_1.extractListRows)(section);
31
+ }
32
+ // custom sections are markdown-only, skip in JSON
33
+ }
34
+ return result;
35
+ };
36
+ exports.irToData = irToData;
37
+ const formatJson = (ir, envelope, command) => {
38
+ const data = (0, exports.irToData)(ir);
39
+ if (!envelope)
40
+ return JSON.stringify(data);
41
+ const output = {
42
+ ok: true,
43
+ ...(command ? { command } : {}),
44
+ data,
45
+ meta: {
46
+ ts: new Date().toISOString(),
47
+ },
48
+ };
49
+ return JSON.stringify(output);
50
+ };
51
+ exports.formatJson = formatJson;
52
+ const renderJsonError = (command, error) => {
53
+ const payload = {
54
+ ok: false,
55
+ ...(command ? { command } : {}),
56
+ error: {
57
+ code: error.code,
58
+ message: error.message,
59
+ details: error.details ?? null,
60
+ },
61
+ meta: {
62
+ ts: new Date().toISOString(),
63
+ },
64
+ };
65
+ return JSON.stringify(payload);
66
+ };
67
+ exports.renderJsonError = renderJsonError;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatMarkdown = exports.extractIr = exports.escapeCell = void 0;
4
+ const utils_1 = require("./utils");
5
+ const escapeCell = (value) => {
6
+ return (0, utils_1.pickText)(value).replace(/\|/g, "\\|");
7
+ };
8
+ exports.escapeCell = escapeCell;
9
+ const renderTable = (headers, rows) => {
10
+ const lines = [
11
+ `| ${headers.join(" | ")} |`,
12
+ `| ${headers.map(() => "---").join(" | ")} |`,
13
+ ];
14
+ for (const row of rows) {
15
+ lines.push(`| ${row.join(" | ")} |`);
16
+ }
17
+ return lines;
18
+ };
19
+ const renderListIr = (ir) => {
20
+ const lines = [`# ${ir.title}`, ""];
21
+ if (ir.rows.length === 0) {
22
+ lines.push(ir.emptyText ?? "(none)");
23
+ return lines.join("\n");
24
+ }
25
+ const headers = ir.columns.map((c) => c.title);
26
+ const stringRows = ir.rows.map((row) => ir.columns.map((c) => (0, exports.escapeCell)(c.render(row))));
27
+ return [...lines, ...renderTable(headers, stringRows)].join("\n");
28
+ };
29
+ const extractIr = (spec, data) => {
30
+ if (spec.kind === "text") {
31
+ return { kind: "text", title: spec.title, content: spec.render(data) };
32
+ }
33
+ if (spec.kind === "list") {
34
+ const rows = (0, utils_1.asArray)(data).map((row) => (0, utils_1.readRecord)(row));
35
+ return { kind: "list", title: spec.title, columns: spec.columns, rows, emptyText: spec.emptyText };
36
+ }
37
+ // kind: "detail"
38
+ const sections = [];
39
+ for (const section of spec.sections) {
40
+ if (section.visible && !section.visible(data))
41
+ continue;
42
+ if (section.kind === "key-value") {
43
+ const rows = section.rows(data);
44
+ if (!rows || rows.length === 0)
45
+ continue;
46
+ sections.push({ kind: "key-value", title: section.title, rows });
47
+ }
48
+ else if (section.kind === "table") {
49
+ const rows = section.rows(data);
50
+ if (!rows || rows.length === 0)
51
+ continue;
52
+ const recordRows = rows.map((r) => (0, utils_1.readRecord)(r));
53
+ sections.push({ kind: "table", title: section.title, columns: section.columns, rows: recordRows });
54
+ }
55
+ else {
56
+ // kind: "custom"
57
+ const lines = section.render(data);
58
+ if (!lines || lines.length === 0)
59
+ continue;
60
+ sections.push({ kind: "custom", title: section.title, lines });
61
+ }
62
+ }
63
+ return { kind: "detail", title: spec.title, sections };
64
+ };
65
+ exports.extractIr = extractIr;
66
+ const formatMarkdown = (ir) => {
67
+ if (ir.kind === "text") {
68
+ return ir.content;
69
+ }
70
+ if (ir.kind === "list") {
71
+ return renderListIr(ir);
72
+ }
73
+ // kind: "detail"
74
+ const lines = [`# ${ir.title}`];
75
+ for (const section of ir.sections) {
76
+ lines.push("", `## ${section.title}`, "");
77
+ if (section.kind === "key-value") {
78
+ lines.push("| Field | Value |", "| --- | --- |");
79
+ for (const row of section.rows) {
80
+ lines.push(`| ${(0, exports.escapeCell)(row.field)} | ${(0, exports.escapeCell)(row.value)} |`);
81
+ }
82
+ }
83
+ else if (section.kind === "table") {
84
+ const headers = section.columns.map((c) => c.title);
85
+ const stringRows = section.rows.map((row) => section.columns.map((c) => (0, exports.escapeCell)(c.render(row))));
86
+ lines.push(...renderTable(headers, stringRows));
87
+ }
88
+ else {
89
+ // custom: 直接拼入
90
+ lines.push(...section.lines);
91
+ }
92
+ }
93
+ return lines.join("\n");
94
+ };
95
+ exports.formatMarkdown = formatMarkdown;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractListRows = exports.readRecord = exports.asArray = exports.pickText = void 0;
4
+ const guards_1 = require("../../../utils/guards");
5
+ const pickText = (value) => {
6
+ if (value === null || value === undefined)
7
+ return "-";
8
+ if (typeof value === "string")
9
+ return value || "-";
10
+ if (typeof value === "number" || typeof value === "boolean")
11
+ return String(value);
12
+ return JSON.stringify(value);
13
+ };
14
+ exports.pickText = pickText;
15
+ const asArray = (value) => {
16
+ return Array.isArray(value) ? value : [];
17
+ };
18
+ exports.asArray = asArray;
19
+ const readRecord = (value) => {
20
+ return (0, guards_1.isRecord)(value) ? value : {};
21
+ };
22
+ exports.readRecord = readRecord;
23
+ const extractListRows = (ir) => {
24
+ return ir.rows.map((row) => {
25
+ const entry = {};
26
+ for (const col of ir.columns) {
27
+ entry[col.title] = col.render(row);
28
+ }
29
+ return entry;
30
+ });
31
+ };
32
+ exports.extractListRows = extractListRows;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderErrorByMode = exports.renderSuccessByMode = void 0;
4
+ const errors_1 = require("../errors");
5
+ const specs_1 = require("./specs");
6
+ const markdown_1 = require("./engine/markdown");
7
+ const json_1 = require("./engine/json");
8
+ const renderSuccessByMode = (command, data, global) => {
9
+ const spec = specs_1.commandRenderSpecs[command];
10
+ if (!spec) {
11
+ throw new errors_1.CliError(`No render spec registered for command: ${command}`, {
12
+ code: "MISSING_RENDER_SPEC",
13
+ exitCode: 1,
14
+ details: { command },
15
+ });
16
+ }
17
+ const ir = (0, markdown_1.extractIr)(spec, data);
18
+ return global.format === "md" ? (0, markdown_1.formatMarkdown)(ir) : (0, json_1.formatJson)(ir, global.envelope, command);
19
+ };
20
+ exports.renderSuccessByMode = renderSuccessByMode;
21
+ const renderErrorByMode = (command, error, global) => {
22
+ if (global.format === "md") {
23
+ return `# Error\n\n**${error.code}** — ${error.message}`;
24
+ }
25
+ return (0, json_1.renderJsonError)(command, error);
26
+ };
27
+ exports.renderErrorByMode = renderErrorByMode;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.agentRenderSpecs = void 0;
4
+ const utils_1 = require("../engine/utils");
5
+ exports.agentRenderSpecs = {
6
+ "agent.list": {
7
+ kind: "list",
8
+ title: "Agent List",
9
+ columns: [
10
+ {
11
+ title: "Agent ID",
12
+ render: (row) => row.id ?? "-",
13
+ },
14
+ {
15
+ title: "Name",
16
+ render: (row) => {
17
+ const raw = (0, utils_1.readRecord)(row.raw);
18
+ return raw.name ?? row.name ?? "-";
19
+ },
20
+ },
21
+ {
22
+ title: "Workspace",
23
+ render: (row) => {
24
+ const raw = (0, utils_1.readRecord)(row.raw);
25
+ return raw.workspace ?? "-";
26
+ },
27
+ },
28
+ {
29
+ title: "Runtime",
30
+ render: (row) => {
31
+ const raw = (0, utils_1.readRecord)(row.raw);
32
+ const runtime = (0, utils_1.readRecord)(raw.agentRuntime);
33
+ return runtime.id ?? "-";
34
+ },
35
+ },
36
+ {
37
+ title: "Model Primary",
38
+ render: (row) => {
39
+ const raw = (0, utils_1.readRecord)(row.raw);
40
+ const model = (0, utils_1.readRecord)(raw.model);
41
+ return model.primary ?? "-";
42
+ },
43
+ },
44
+ {
45
+ title: "Last Active At",
46
+ render: (row) => row.lastActiveAt ?? row.lastActiveAtMs ?? "-",
47
+ },
48
+ ],
49
+ },
50
+ "agent.session": {
51
+ kind: "list",
52
+ title: "Session List",
53
+ columns: [
54
+ {
55
+ title: "Agent ID",
56
+ render: (row) => row.agentId ?? "-",
57
+ },
58
+ {
59
+ title: "Session ID",
60
+ render: (row) => row.sessionId ?? "-",
61
+ },
62
+ ],
63
+ },
64
+ "agent.send": {
65
+ kind: "text",
66
+ render: (data) => {
67
+ const d = data;
68
+ if (d.streamed === true)
69
+ return "";
70
+ if (!d.reply) {
71
+ const timedOut = d.timedOut === true;
72
+ return timedOut ? "(timed out, no reply)" : "(no reply)";
73
+ }
74
+ const reply = d.reply;
75
+ return String(reply.content ?? "-");
76
+ },
77
+ },
78
+ };
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.artifactRenderSpecs = void 0;
4
+ exports.artifactRenderSpecs = {
5
+ "artifact.list": {
6
+ kind: "list",
7
+ title: "Artifact List",
8
+ emptyText: "(none)",
9
+ columns: [
10
+ {
11
+ title: "Artifact ID",
12
+ render: (row) => row.id ?? row.artifactId ?? "-",
13
+ },
14
+ {
15
+ title: "Pipeline ID",
16
+ render: (row) => row.pipelineId ?? "-",
17
+ },
18
+ {
19
+ title: "Node ID",
20
+ render: (row) => row.nodeId ?? "-",
21
+ },
22
+ {
23
+ title: "Type",
24
+ render: (row) => row.type ?? "-",
25
+ },
26
+ {
27
+ title: "Created At",
28
+ render: (row) => row.createdAt ?? "-",
29
+ },
30
+ ],
31
+ },
32
+ };