@jiraacp/cli 2026.405.4

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 (113) hide show
  1. package/README.md +283 -0
  2. package/dist/abort-GQE4OI5S.js +103 -0
  3. package/dist/abort-GQE4OI5S.js.map +1 -0
  4. package/dist/abort-VMRQOADY.js +96 -0
  5. package/dist/abort-VMRQOADY.js.map +1 -0
  6. package/dist/bot-WOTETAJY.js +13 -0
  7. package/dist/bot-WOTETAJY.js.map +1 -0
  8. package/dist/cancel-clarification-4G5S2HJZ.js +64 -0
  9. package/dist/cancel-clarification-4G5S2HJZ.js.map +1 -0
  10. package/dist/chunk-3U373M37.js +67 -0
  11. package/dist/chunk-3U373M37.js.map +1 -0
  12. package/dist/chunk-3YHD4SIN.js +97 -0
  13. package/dist/chunk-3YHD4SIN.js.map +1 -0
  14. package/dist/chunk-6IY6CRUJ.js +690 -0
  15. package/dist/chunk-6IY6CRUJ.js.map +1 -0
  16. package/dist/chunk-B6OA3XJK.js +1167 -0
  17. package/dist/chunk-B6OA3XJK.js.map +1 -0
  18. package/dist/chunk-BM4R6NST.js +191 -0
  19. package/dist/chunk-BM4R6NST.js.map +1 -0
  20. package/dist/chunk-FLPIU2QO.js +77 -0
  21. package/dist/chunk-FLPIU2QO.js.map +1 -0
  22. package/dist/chunk-H7YXX4UA.js +86 -0
  23. package/dist/chunk-H7YXX4UA.js.map +1 -0
  24. package/dist/chunk-IT74N3UH.js +19 -0
  25. package/dist/chunk-IT74N3UH.js.map +1 -0
  26. package/dist/chunk-JOT4UVSO.js +186 -0
  27. package/dist/chunk-JOT4UVSO.js.map +1 -0
  28. package/dist/chunk-KSJKCLEJ.js +222 -0
  29. package/dist/chunk-KSJKCLEJ.js.map +1 -0
  30. package/dist/chunk-LIEW4ULF.js +139 -0
  31. package/dist/chunk-LIEW4ULF.js.map +1 -0
  32. package/dist/chunk-M4V3YOCY.js +82 -0
  33. package/dist/chunk-M4V3YOCY.js.map +1 -0
  34. package/dist/chunk-MMWQHH25.js +207 -0
  35. package/dist/chunk-MMWQHH25.js.map +1 -0
  36. package/dist/chunk-OJ4CNF73.js +78 -0
  37. package/dist/chunk-OJ4CNF73.js.map +1 -0
  38. package/dist/chunk-PFJAC3RO.js +137 -0
  39. package/dist/chunk-PFJAC3RO.js.map +1 -0
  40. package/dist/chunk-PVKVCUNR.js +159 -0
  41. package/dist/chunk-PVKVCUNR.js.map +1 -0
  42. package/dist/chunk-RXT4WSIY.js +35 -0
  43. package/dist/chunk-RXT4WSIY.js.map +1 -0
  44. package/dist/chunk-RZK74PDF.js +34 -0
  45. package/dist/chunk-RZK74PDF.js.map +1 -0
  46. package/dist/chunk-UDTWVKRX.js +68 -0
  47. package/dist/chunk-UDTWVKRX.js.map +1 -0
  48. package/dist/chunk-VCEONSWJ.js +307 -0
  49. package/dist/chunk-VCEONSWJ.js.map +1 -0
  50. package/dist/chunk-VWBCDZWQ.js +119 -0
  51. package/dist/chunk-VWBCDZWQ.js.map +1 -0
  52. package/dist/chunk-WEJCTFQB.js +228 -0
  53. package/dist/chunk-WEJCTFQB.js.map +1 -0
  54. package/dist/chunk-YJK7IRPI.js +223 -0
  55. package/dist/chunk-YJK7IRPI.js.map +1 -0
  56. package/dist/claude-md-HQ6L4CRP.js +8 -0
  57. package/dist/claude-md-HQ6L4CRP.js.map +1 -0
  58. package/dist/cli.js +276 -0
  59. package/dist/cli.js.map +1 -0
  60. package/dist/commands-RG45VBTZ.js +407 -0
  61. package/dist/commands-RG45VBTZ.js.map +1 -0
  62. package/dist/commands-WYVRVE5Z.js +400 -0
  63. package/dist/commands-WYVRVE5Z.js.map +1 -0
  64. package/dist/config-edit-G7O56HXO.js +50 -0
  65. package/dist/config-edit-G7O56HXO.js.map +1 -0
  66. package/dist/config-set-QN3JRNZL.js +63 -0
  67. package/dist/config-set-QN3JRNZL.js.map +1 -0
  68. package/dist/daemon-CGBV55JK.js +104 -0
  69. package/dist/daemon-CGBV55JK.js.map +1 -0
  70. package/dist/dashboard-YVFJ5DXR.js +143 -0
  71. package/dist/dashboard-YVFJ5DXR.js.map +1 -0
  72. package/dist/doctor-BPTLVLTD.js +98 -0
  73. package/dist/doctor-BPTLVLTD.js.map +1 -0
  74. package/dist/human-loop-RBTA2TYK.js +16 -0
  75. package/dist/human-loop-RBTA2TYK.js.map +1 -0
  76. package/dist/human-loop-XGWXUNCS.js +18 -0
  77. package/dist/human-loop-XGWXUNCS.js.map +1 -0
  78. package/dist/index.d.ts +583 -0
  79. package/dist/index.js +28 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/loader-DGW7HCJ5.js +21 -0
  82. package/dist/loader-DGW7HCJ5.js.map +1 -0
  83. package/dist/logs-JUVQWN6C.js +93 -0
  84. package/dist/logs-JUVQWN6C.js.map +1 -0
  85. package/dist/mcp.js +132 -0
  86. package/dist/mcp.js.map +1 -0
  87. package/dist/orchestrator-3MGXX3QW.js +22 -0
  88. package/dist/orchestrator-3MGXX3QW.js.map +1 -0
  89. package/dist/orchestrator-BVUKN5N3.js +13 -0
  90. package/dist/orchestrator-BVUKN5N3.js.map +1 -0
  91. package/dist/pause-FLDZ3OD6.js +62 -0
  92. package/dist/pause-FLDZ3OD6.js.map +1 -0
  93. package/dist/projects-QMIGNW7U.js +129 -0
  94. package/dist/projects-QMIGNW7U.js.map +1 -0
  95. package/dist/replay-M4JEG4Z4.js +151 -0
  96. package/dist/replay-M4JEG4Z4.js.map +1 -0
  97. package/dist/schedule-CDHD77VZ.js +17 -0
  98. package/dist/schedule-CDHD77VZ.js.map +1 -0
  99. package/dist/serve-XI7JTIPZ.js +231 -0
  100. package/dist/serve-XI7JTIPZ.js.map +1 -0
  101. package/dist/sprint-KZZWVNK6.js +200 -0
  102. package/dist/sprint-KZZWVNK6.js.map +1 -0
  103. package/dist/status-I6GU2LWE.js +48 -0
  104. package/dist/status-I6GU2LWE.js.map +1 -0
  105. package/dist/topic-manager-4AMEPMFI.js +12 -0
  106. package/dist/topic-manager-4AMEPMFI.js.map +1 -0
  107. package/dist/triage-WNHGPVZQ.js +251 -0
  108. package/dist/triage-WNHGPVZQ.js.map +1 -0
  109. package/dist/usage-AWWBI37F.js +155 -0
  110. package/dist/usage-AWWBI37F.js.map +1 -0
  111. package/dist/wizard-CYEJJLNF.js +190 -0
  112. package/dist/wizard-CYEJJLNF.js.map +1 -0
  113. package/package.json +56 -0
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getRunDir
4
+ } from "./chunk-VWBCDZWQ.js";
5
+
6
+ // src/commands/logs.ts
7
+ import fs from "fs";
8
+ import path from "path";
9
+ import pc from "picocolors";
10
+ async function showLogs(projectName, ticketKey, stage, follow) {
11
+ const runDir = getRunDir(projectName, ticketKey);
12
+ const statePath = path.join(runDir, "state.json");
13
+ if (!fs.existsSync(statePath)) {
14
+ console.error(pc.red(`No runs found for ${projectName}/${ticketKey}`));
15
+ process.exit(1);
16
+ }
17
+ const events = fs.readFileSync(statePath, "utf8").split("\n").filter(Boolean).map((line) => {
18
+ try {
19
+ return JSON.parse(line);
20
+ } catch {
21
+ return null;
22
+ }
23
+ }).filter(Boolean);
24
+ const filtered = stage ? events.filter((e) => e.stage === stage) : events;
25
+ console.log(
26
+ pc.bold(
27
+ `
28
+ Logs: ${projectName}/${ticketKey}${stage ? ` / ${stage}` : ""}
29
+ `
30
+ )
31
+ );
32
+ for (const event of filtered) {
33
+ if (!event) continue;
34
+ const time = pc.gray(new Date(event.timestamp).toLocaleTimeString());
35
+ const type = formatEventType(event.type);
36
+ const detail = event.stage ? pc.cyan(event.stage) : "";
37
+ const extra = event.error ? pc.red(String(event.error)) : "";
38
+ console.log(` ${time} ${type} ${detail} ${extra}`);
39
+ }
40
+ if (follow) {
41
+ console.log(pc.gray("\n Watching for new events... (Ctrl+C to stop)"));
42
+ let size = fs.statSync(statePath).size;
43
+ setInterval(() => {
44
+ const newSize = fs.statSync(statePath).size;
45
+ if (newSize > size) {
46
+ const newContent = fs.readFileSync(statePath, "utf8").slice(size);
47
+ size = newSize;
48
+ for (const line of newContent.split("\n").filter(Boolean)) {
49
+ try {
50
+ const event = JSON.parse(line);
51
+ const time = pc.gray(
52
+ new Date(event.timestamp).toLocaleTimeString()
53
+ );
54
+ console.log(
55
+ ` ${time} ${formatEventType(event.type)} ${event.stage ? pc.cyan(event.stage) : ""}`
56
+ );
57
+ } catch {
58
+ }
59
+ }
60
+ }
61
+ }, 500);
62
+ } else {
63
+ console.log();
64
+ }
65
+ }
66
+ function formatEventType(type) {
67
+ switch (type) {
68
+ case "STARTED":
69
+ return pc.blue("STARTED");
70
+ case "STAGE_STARTED":
71
+ return pc.cyan("\u2192 START");
72
+ case "STAGE_COMPLETED":
73
+ return pc.green("\u2713 DONE");
74
+ case "STAGE_FAILED":
75
+ return pc.red("\u2717 FAIL");
76
+ case "STAGE_SKIPPED":
77
+ return pc.gray("\u2298 SKIP");
78
+ case "CLARIFICATION_REQUESTED":
79
+ return pc.yellow("? CLARIFY");
80
+ case "CLARIFICATION_RECEIVED":
81
+ return pc.green("\u2713 ANSWER");
82
+ case "PIPELINE_COMPLETED":
83
+ return pc.green("\u2705 COMPLETE");
84
+ case "PIPELINE_ABORTED":
85
+ return pc.red("\u274C ABORTED");
86
+ default:
87
+ return pc.gray(type);
88
+ }
89
+ }
90
+ export {
91
+ showLogs
92
+ };
93
+ //# sourceMappingURL=logs-JUVQWN6C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/logs.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport pc from \"picocolors\";\nimport { getRunDir } from \"../pipeline/state.js\";\n\nexport async function showLogs(\n projectName: string,\n ticketKey: string,\n stage?: string,\n follow?: boolean,\n): Promise<void> {\n const runDir = getRunDir(projectName, ticketKey);\n const statePath = path.join(runDir, \"state.json\");\n\n if (!fs.existsSync(statePath)) {\n console.error(pc.red(`No runs found for ${projectName}/${ticketKey}`));\n process.exit(1);\n }\n\n const events = fs\n .readFileSync(statePath, \"utf8\")\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => {\n try {\n return JSON.parse(line) as {\n type: string;\n stage?: string;\n timestamp: string;\n [k: string]: unknown;\n };\n } catch {\n return null;\n }\n })\n .filter(Boolean);\n\n const filtered = stage ? events.filter((e) => e!.stage === stage) : events;\n\n console.log(\n pc.bold(\n `\\n Logs: ${projectName}/${ticketKey}${stage ? ` / ${stage}` : \"\"}\\n`,\n ),\n );\n\n for (const event of filtered) {\n if (!event) continue;\n const time = pc.gray(new Date(event.timestamp).toLocaleTimeString());\n const type = formatEventType(event.type);\n const detail = event.stage ? pc.cyan(event.stage) : \"\";\n const extra = event.error ? pc.red(String(event.error)) : \"\";\n console.log(` ${time} ${type} ${detail} ${extra}`);\n }\n\n if (follow) {\n console.log(pc.gray(\"\\n Watching for new events... (Ctrl+C to stop)\"));\n let size = fs.statSync(statePath).size;\n setInterval(() => {\n const newSize = fs.statSync(statePath).size;\n if (newSize > size) {\n const newContent = fs.readFileSync(statePath, \"utf8\").slice(size);\n size = newSize;\n for (const line of newContent.split(\"\\n\").filter(Boolean)) {\n try {\n const event = JSON.parse(line) as {\n type: string;\n stage?: string;\n timestamp: string;\n };\n const time = pc.gray(\n new Date(event.timestamp).toLocaleTimeString(),\n );\n console.log(\n ` ${time} ${formatEventType(event.type)} ${event.stage ? pc.cyan(event.stage) : \"\"}`,\n );\n } catch {\n /* ignore */\n }\n }\n }\n }, 500);\n } else {\n console.log();\n }\n}\n\nfunction formatEventType(type: string): string {\n switch (type) {\n case \"STARTED\":\n return pc.blue(\"STARTED\");\n case \"STAGE_STARTED\":\n return pc.cyan(\"→ START\");\n case \"STAGE_COMPLETED\":\n return pc.green(\"✓ DONE\");\n case \"STAGE_FAILED\":\n return pc.red(\"✗ FAIL\");\n case \"STAGE_SKIPPED\":\n return pc.gray(\"⊘ SKIP\");\n case \"CLARIFICATION_REQUESTED\":\n return pc.yellow(\"? CLARIFY\");\n case \"CLARIFICATION_RECEIVED\":\n return pc.green(\"✓ ANSWER\");\n case \"PIPELINE_COMPLETED\":\n return pc.green(\"✅ COMPLETE\");\n case \"PIPELINE_ABORTED\":\n return pc.red(\"❌ ABORTED\");\n default:\n return pc.gray(type);\n }\n}\n"],"mappings":"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","names":[]}
package/dist/mcp.js ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ AddCommentSchema,
4
+ GetTasksSchema,
5
+ GetTicketSchema,
6
+ GetTransitionsSchema,
7
+ INSTANCES,
8
+ ReassignSchema,
9
+ TransitionTicketSchema,
10
+ addComment,
11
+ getTasks,
12
+ getTicket,
13
+ getTransitions,
14
+ reassign,
15
+ transitionTicket
16
+ } from "./chunk-JOT4UVSO.js";
17
+
18
+ // src/mcp.ts
19
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
20
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
21
+ import {
22
+ CallToolRequestSchema,
23
+ ListToolsRequestSchema
24
+ } from "@modelcontextprotocol/sdk/types.js";
25
+ var server = new Server(
26
+ { name: "jiraACP-mcp", version: "0.1.0" },
27
+ { capabilities: { tools: {} } }
28
+ );
29
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
30
+ tools: [
31
+ {
32
+ name: "jira_get_tasks",
33
+ description: "Get Jira tasks assigned to specific users.",
34
+ inputSchema: {
35
+ type: "object",
36
+ properties: GetTasksSchema.shape,
37
+ required: ["instance", "assignees"]
38
+ }
39
+ },
40
+ {
41
+ name: "jira_get_ticket",
42
+ description: "Get full details of a single Jira ticket.",
43
+ inputSchema: {
44
+ type: "object",
45
+ properties: GetTicketSchema.shape,
46
+ required: ["instance", "ticket_key"]
47
+ }
48
+ },
49
+ {
50
+ name: "jira_get_transitions",
51
+ description: "Get available status transitions for a ticket.",
52
+ inputSchema: {
53
+ type: "object",
54
+ properties: GetTransitionsSchema.shape,
55
+ required: ["instance", "ticket_key"]
56
+ }
57
+ },
58
+ {
59
+ name: "jira_transition_ticket",
60
+ description: "Change the status of a Jira ticket.",
61
+ inputSchema: {
62
+ type: "object",
63
+ properties: TransitionTicketSchema.shape,
64
+ required: ["instance", "ticket_key", "transition_name"]
65
+ }
66
+ },
67
+ {
68
+ name: "jira_add_comment",
69
+ description: "Add a comment to a Jira ticket.",
70
+ inputSchema: {
71
+ type: "object",
72
+ properties: AddCommentSchema.shape,
73
+ required: ["instance", "ticket_key", "comment"]
74
+ }
75
+ },
76
+ {
77
+ name: "jira_reassign",
78
+ description: "Reassign a Jira ticket to another user by accountId.",
79
+ inputSchema: {
80
+ type: "object",
81
+ properties: ReassignSchema.shape,
82
+ required: ["instance", "ticket_key", "account_id"]
83
+ }
84
+ }
85
+ ]
86
+ }));
87
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
88
+ const { name, arguments: args } = request.params;
89
+ try {
90
+ let result;
91
+ switch (name) {
92
+ case "jira_get_tasks":
93
+ result = await getTasks(GetTasksSchema.parse(args));
94
+ break;
95
+ case "jira_get_ticket":
96
+ result = await getTicket(GetTicketSchema.parse(args));
97
+ break;
98
+ case "jira_get_transitions":
99
+ result = await getTransitions(GetTransitionsSchema.parse(args));
100
+ break;
101
+ case "jira_transition_ticket":
102
+ result = await transitionTicket(TransitionTicketSchema.parse(args));
103
+ break;
104
+ case "jira_add_comment":
105
+ result = await addComment(AddCommentSchema.parse(args));
106
+ break;
107
+ case "jira_reassign":
108
+ result = await reassign(ReassignSchema.parse(args));
109
+ break;
110
+ default:
111
+ throw new Error(`Unknown tool: ${name}`);
112
+ }
113
+ return { content: [{ type: "text", text: result }] };
114
+ } catch (err) {
115
+ const message = err instanceof Error ? err.message : String(err);
116
+ return {
117
+ content: [{ type: "text", text: `Error: ${message}` }],
118
+ isError: true
119
+ };
120
+ }
121
+ });
122
+ var instanceList = Object.keys(INSTANCES);
123
+ if (instanceList.length === 0) {
124
+ console.error(
125
+ "No Jira instances configured. Add JIRA_{NAME}_URL/TOKEN/EMAIL to env."
126
+ );
127
+ process.exit(1);
128
+ }
129
+ console.error(`jiraACP-mcp started. Instances: ${instanceList.join(", ")}`);
130
+ var transport = new StdioServerTransport();
131
+ await server.connect(transport);
132
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp.ts"],"sourcesContent":["import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { INSTANCES } from \"./integrations/jira/client.js\";\nimport {\n GetTasksSchema,\n GetTicketSchema,\n GetTransitionsSchema,\n TransitionTicketSchema,\n AddCommentSchema,\n ReassignSchema,\n getTasks,\n getTicket,\n getTransitions,\n transitionTicket,\n addComment,\n reassign,\n} from \"./integrations/jira/tools.js\";\n\nconst server = new Server(\n { name: \"jiraACP-mcp\", version: \"0.1.0\" },\n { capabilities: { tools: {} } },\n);\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: \"jira_get_tasks\",\n description: \"Get Jira tasks assigned to specific users.\",\n inputSchema: {\n type: \"object\",\n properties: GetTasksSchema.shape,\n required: [\"instance\", \"assignees\"],\n },\n },\n {\n name: \"jira_get_ticket\",\n description: \"Get full details of a single Jira ticket.\",\n inputSchema: {\n type: \"object\",\n properties: GetTicketSchema.shape,\n required: [\"instance\", \"ticket_key\"],\n },\n },\n {\n name: \"jira_get_transitions\",\n description: \"Get available status transitions for a ticket.\",\n inputSchema: {\n type: \"object\",\n properties: GetTransitionsSchema.shape,\n required: [\"instance\", \"ticket_key\"],\n },\n },\n {\n name: \"jira_transition_ticket\",\n description: \"Change the status of a Jira ticket.\",\n inputSchema: {\n type: \"object\",\n properties: TransitionTicketSchema.shape,\n required: [\"instance\", \"ticket_key\", \"transition_name\"],\n },\n },\n {\n name: \"jira_add_comment\",\n description: \"Add a comment to a Jira ticket.\",\n inputSchema: {\n type: \"object\",\n properties: AddCommentSchema.shape,\n required: [\"instance\", \"ticket_key\", \"comment\"],\n },\n },\n {\n name: \"jira_reassign\",\n description: \"Reassign a Jira ticket to another user by accountId.\",\n inputSchema: {\n type: \"object\",\n properties: ReassignSchema.shape,\n required: [\"instance\", \"ticket_key\", \"account_id\"],\n },\n },\n ],\n}));\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n try {\n let result: string;\n switch (name) {\n case \"jira_get_tasks\":\n result = await getTasks(GetTasksSchema.parse(args));\n break;\n case \"jira_get_ticket\":\n result = await getTicket(GetTicketSchema.parse(args));\n break;\n case \"jira_get_transitions\":\n result = await getTransitions(GetTransitionsSchema.parse(args));\n break;\n case \"jira_transition_ticket\":\n result = await transitionTicket(TransitionTicketSchema.parse(args));\n break;\n case \"jira_add_comment\":\n result = await addComment(AddCommentSchema.parse(args));\n break;\n case \"jira_reassign\":\n result = await reassign(ReassignSchema.parse(args));\n break;\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n return { content: [{ type: \"text\", text: result }] };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: [{ type: \"text\", text: `Error: ${message}` }],\n isError: true,\n };\n }\n});\n\nconst instanceList = Object.keys(INSTANCES);\nif (instanceList.length === 0) {\n console.error(\n \"No Jira instances configured. Add JIRA_{NAME}_URL/TOKEN/EMAIL to env.\",\n );\n process.exit(1);\n}\n\nconsole.error(`jiraACP-mcp started. Instances: ${instanceList.join(\", \")}`);\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n"],"mappings":"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","names":[]}
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resumePipeline,
4
+ runPipeline
5
+ } from "./chunk-6IY6CRUJ.js";
6
+ import "./chunk-RXT4WSIY.js";
7
+ import "./chunk-VCEONSWJ.js";
8
+ import "./chunk-UDTWVKRX.js";
9
+ import "./chunk-JOT4UVSO.js";
10
+ import "./chunk-YJK7IRPI.js";
11
+ import "./chunk-FLPIU2QO.js";
12
+ import "./chunk-PVKVCUNR.js";
13
+ import "./chunk-RZK74PDF.js";
14
+ import "./chunk-VWBCDZWQ.js";
15
+ import "./chunk-3U373M37.js";
16
+ import "./chunk-OJ4CNF73.js";
17
+ import "./chunk-IT74N3UH.js";
18
+ export {
19
+ resumePipeline,
20
+ runPipeline
21
+ };
22
+ //# sourceMappingURL=orchestrator-3MGXX3QW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,13 @@
1
+ import {
2
+ resumePipeline,
3
+ runPipeline
4
+ } from "./chunk-B6OA3XJK.js";
5
+ import "./chunk-KSJKCLEJ.js";
6
+ import "./chunk-WEJCTFQB.js";
7
+ import "./chunk-BM4R6NST.js";
8
+ import "./chunk-M4V3YOCY.js";
9
+ export {
10
+ resumePipeline,
11
+ runPipeline
12
+ };
13
+ //# sourceMappingURL=orchestrator-BVUKN5N3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ readLockData
4
+ } from "./chunk-FLPIU2QO.js";
5
+ import {
6
+ getLockPath
7
+ } from "./chunk-VWBCDZWQ.js";
8
+ import {
9
+ loadConfig
10
+ } from "./chunk-3YHD4SIN.js";
11
+ import "./chunk-LIEW4ULF.js";
12
+ import {
13
+ createLogger
14
+ } from "./chunk-IT74N3UH.js";
15
+
16
+ // src/commands/pause.ts
17
+ async function pausePipeline(ticketKey, projectName) {
18
+ const logger = createLogger("pause");
19
+ loadConfig(projectName);
20
+ const lockPath = getLockPath(projectName, ticketKey);
21
+ const lockData = readLockData(lockPath);
22
+ if (!lockData) {
23
+ process.stderr.write(`No running pipeline found for ${ticketKey}
24
+ `);
25
+ process.exitCode = 1;
26
+ return;
27
+ }
28
+ try {
29
+ process.kill(lockData.pid, 0);
30
+ } catch (err) {
31
+ const code = err instanceof Error && "code" in err ? err.code : void 0;
32
+ if (code === "ESRCH") {
33
+ process.stderr.write(
34
+ `Pipeline process (PID ${lockData.pid}) is no longer running
35
+ `
36
+ );
37
+ process.exitCode = 1;
38
+ return;
39
+ }
40
+ throw err;
41
+ }
42
+ try {
43
+ process.kill(lockData.pid, "SIGSTOP");
44
+ logger.info({ ticketKey, pid: lockData.pid }, "SIGSTOP sent");
45
+ process.stdout.write(
46
+ `\u2713 Pipeline ${ticketKey} paused (PID ${lockData.pid}). Resume with: jiraACP resume ${ticketKey}
47
+ `
48
+ );
49
+ } catch (err) {
50
+ const code = err instanceof Error && "code" in err ? err.code : void 0;
51
+ if (code === "ESRCH") {
52
+ process.stdout.write(`Pipeline ${ticketKey} already stopped.
53
+ `);
54
+ return;
55
+ }
56
+ throw err;
57
+ }
58
+ }
59
+ export {
60
+ pausePipeline
61
+ };
62
+ //# sourceMappingURL=pause-FLDZ3OD6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/pause.ts"],"sourcesContent":["import { loadConfig } from \"../config/loader.js\";\nimport { getLockPath } from \"../pipeline/state.js\";\nimport { readLockData } from \"../utils/lock.js\";\nimport { createLogger } from \"../utils/logger.js\";\n\nexport async function pausePipeline(\n ticketKey: string,\n projectName: string,\n): Promise<void> {\n const logger = createLogger(\"pause\");\n loadConfig(projectName);\n\n const lockPath = getLockPath(projectName, ticketKey);\n const lockData = readLockData(lockPath);\n\n if (!lockData) {\n process.stderr.write(`No running pipeline found for ${ticketKey}\\n`);\n process.exitCode = 1;\n return;\n }\n\n // Check process is alive\n try {\n process.kill(lockData.pid, 0);\n } catch (err: unknown) {\n const code =\n err instanceof Error && \"code\" in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === \"ESRCH\") {\n process.stderr.write(\n `Pipeline process (PID ${lockData.pid}) is no longer running\\n`,\n );\n process.exitCode = 1;\n return;\n }\n throw err;\n }\n\n // Send SIGSTOP\n try {\n process.kill(lockData.pid, \"SIGSTOP\");\n logger.info({ ticketKey, pid: lockData.pid }, \"SIGSTOP sent\");\n process.stdout.write(\n `✓ Pipeline ${ticketKey} paused (PID ${lockData.pid}). Resume with: jiraACP resume ${ticketKey}\\n`,\n );\n } catch (err: unknown) {\n const code =\n err instanceof Error && \"code\" in err\n ? (err as NodeJS.ErrnoException).code\n : undefined;\n if (code === \"ESRCH\") {\n process.stdout.write(`Pipeline ${ticketKey} already stopped.\\n`);\n return;\n }\n throw err;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAKA,eAAsB,cACpB,WACA,aACe;AACf,QAAM,SAAS,aAAa,OAAO;AACnC,aAAW,WAAW;AAEtB,QAAM,WAAW,YAAY,aAAa,SAAS;AACnD,QAAM,WAAW,aAAa,QAAQ;AAEtC,MAAI,CAAC,UAAU;AACb,YAAQ,OAAO,MAAM,iCAAiC,SAAS;AAAA,CAAI;AACnE,YAAQ,WAAW;AACnB;AAAA,EACF;AAGA,MAAI;AACF,YAAQ,KAAK,SAAS,KAAK,CAAC;AAAA,EAC9B,SAAS,KAAc;AACrB,UAAM,OACJ,eAAe,SAAS,UAAU,MAC7B,IAA8B,OAC/B;AACN,QAAI,SAAS,SAAS;AACpB,cAAQ,OAAO;AAAA,QACb,yBAAyB,SAAS,GAAG;AAAA;AAAA,MACvC;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAGA,MAAI;AACF,YAAQ,KAAK,SAAS,KAAK,SAAS;AACpC,WAAO,KAAK,EAAE,WAAW,KAAK,SAAS,IAAI,GAAG,cAAc;AAC5D,YAAQ,OAAO;AAAA,MACb,mBAAc,SAAS,gBAAgB,SAAS,GAAG,kCAAkC,SAAS;AAAA;AAAA,IAChG;AAAA,EACF,SAAS,KAAc;AACrB,UAAM,OACJ,eAAe,SAAS,UAAU,MAC7B,IAA8B,OAC/B;AACN,QAAI,SAAS,SAAS;AACpB,cAAQ,OAAO,MAAM,YAAY,SAAS;AAAA,CAAqB;AAC/D;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;","names":[]}
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ HOME_DIR,
4
+ listProjects,
5
+ loadConfig
6
+ } from "./chunk-3YHD4SIN.js";
7
+ import "./chunk-LIEW4ULF.js";
8
+
9
+ // src/commands/projects.ts
10
+ import fs from "fs";
11
+ import path from "path";
12
+ import os from "os";
13
+ import { confirm } from "@clack/prompts";
14
+ import pc from "picocolors";
15
+ var PROJECTS_DIR = path.join(HOME_DIR, "projects");
16
+ function projectsList() {
17
+ const names = listProjects();
18
+ if (names.length === 0) {
19
+ process.stdout.write(
20
+ pc.yellow("No projects configured. Run: jiraACP init\n")
21
+ );
22
+ return;
23
+ }
24
+ const COL1 = 20;
25
+ const COL2 = 18;
26
+ const pad = (s, w) => s.padEnd(w);
27
+ process.stdout.write(
28
+ pc.bold(` ${pad("Name", COL1)}${pad("Jira Project", COL2)}Workspace
29
+ `)
30
+ );
31
+ process.stdout.write(
32
+ pc.dim(` ${"-".repeat(COL1)}${"-".repeat(COL2)}${"-".repeat(30)}
33
+ `)
34
+ );
35
+ for (const name of names) {
36
+ try {
37
+ const config = loadConfig(name);
38
+ const projectKey = config.jira.projectKey;
39
+ const rootDir = config.workspace.rootDir.replace(os.homedir(), "~");
40
+ process.stdout.write(
41
+ ` ${pad(pc.cyan(name), COL1 + 9)}${pad(pc.green(projectKey), COL2 + 9)}${rootDir}
42
+ `
43
+ );
44
+ } catch {
45
+ process.stdout.write(
46
+ ` ${pad(pc.red(name), COL1 + 9)}${pad(pc.dim("(invalid)"), COL2 + 9)}${pc.dim("parse error")}
47
+ `
48
+ );
49
+ }
50
+ }
51
+ }
52
+ async function projectsAdd(name) {
53
+ const filePath = path.join(PROJECTS_DIR, `${name}.json`);
54
+ if (fs.existsSync(filePath)) {
55
+ process.stderr.write(
56
+ pc.red(`Error: Project '${name}' already exists at ${filePath}
57
+ `)
58
+ );
59
+ process.exit(1);
60
+ }
61
+ const skeleton = {
62
+ name,
63
+ jira: {
64
+ instance: "default",
65
+ url: "https://your-org.atlassian.net",
66
+ email: "you@example.com",
67
+ token: "",
68
+ projectKey: "PROJ",
69
+ assignees: ["your-jira-accountid"],
70
+ clarityScoreThreshold: 0.7,
71
+ requiredFields: ["description"]
72
+ },
73
+ github: {
74
+ owner: "your-org",
75
+ repo: name,
76
+ token: "",
77
+ defaultBranch: "main",
78
+ branchPattern: "feature/{ticketKey}-{slug}",
79
+ autoMergeStrategy: "squash",
80
+ reviewers: [],
81
+ majorIssueThreshold: 1
82
+ },
83
+ workspace: {
84
+ rootDir: "/path/to/workspace",
85
+ allowedPaths: ["."]
86
+ },
87
+ telegram: {
88
+ botToken: "",
89
+ chatId: ""
90
+ },
91
+ pipeline: {
92
+ maxConcurrentRuns: 2
93
+ }
94
+ };
95
+ fs.mkdirSync(PROJECTS_DIR, { recursive: true });
96
+ fs.writeFileSync(filePath, JSON.stringify(skeleton, null, 2));
97
+ const displayPath = filePath.replace(os.homedir(), "~");
98
+ process.stdout.write(
99
+ pc.green(`\u2713 Created ${displayPath} \u2014 fill in credentials before running
100
+ `)
101
+ );
102
+ }
103
+ async function projectsRemove(name) {
104
+ const filePath = path.join(PROJECTS_DIR, `${name}.json`);
105
+ if (!fs.existsSync(filePath)) {
106
+ process.stderr.write(
107
+ pc.red(`Error: Project '${name}' not found at ${filePath}
108
+ `)
109
+ );
110
+ process.exit(1);
111
+ }
112
+ const confirmed = await confirm({
113
+ message: `Delete project '${name}'? This is irreversible.`,
114
+ initialValue: false
115
+ });
116
+ if (typeof confirmed !== "boolean" || !confirmed) {
117
+ process.stdout.write("Cancelled.\n");
118
+ process.exit(0);
119
+ }
120
+ fs.unlinkSync(filePath);
121
+ process.stdout.write(pc.green(`\u2713 Project '${name}' removed
122
+ `));
123
+ }
124
+ export {
125
+ projectsAdd,
126
+ projectsList,
127
+ projectsRemove
128
+ };
129
+ //# sourceMappingURL=projects-QMIGNW7U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/projects.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { confirm } from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { listProjects, HOME_DIR, loadConfig } from \"../config/loader.js\";\n\nconst PROJECTS_DIR = path.join(HOME_DIR, \"projects\");\n\nexport function projectsList(): void {\n const names = listProjects();\n\n if (names.length === 0) {\n process.stdout.write(\n pc.yellow(\"No projects configured. Run: jiraACP init\\n\"),\n );\n return;\n }\n\n const COL1 = 20;\n const COL2 = 18;\n\n const pad = (s: string, w: number): string => s.padEnd(w);\n\n process.stdout.write(\n pc.bold(` ${pad(\"Name\", COL1)}${pad(\"Jira Project\", COL2)}Workspace\\n`),\n );\n process.stdout.write(\n pc.dim(` ${\"-\".repeat(COL1)}${\"-\".repeat(COL2)}${\"-\".repeat(30)}\\n`),\n );\n\n for (const name of names) {\n try {\n const config = loadConfig(name);\n const projectKey = config.jira.projectKey;\n const rootDir = config.workspace.rootDir.replace(os.homedir(), \"~\");\n process.stdout.write(\n ` ${pad(pc.cyan(name), COL1 + 9)}${pad(pc.green(projectKey), COL2 + 9)}${rootDir}\\n`,\n );\n } catch {\n process.stdout.write(\n ` ${pad(pc.red(name), COL1 + 9)}${pad(pc.dim(\"(invalid)\"), COL2 + 9)}${pc.dim(\"parse error\")}\\n`,\n );\n }\n }\n}\n\nexport async function projectsAdd(name: string): Promise<void> {\n const filePath = path.join(PROJECTS_DIR, `${name}.json`);\n\n if (fs.existsSync(filePath)) {\n process.stderr.write(\n pc.red(`Error: Project '${name}' already exists at ${filePath}\\n`),\n );\n process.exit(1);\n }\n\n const skeleton = {\n name,\n jira: {\n instance: \"default\",\n url: \"https://your-org.atlassian.net\",\n email: \"you@example.com\",\n token: \"\",\n projectKey: \"PROJ\",\n assignees: [\"your-jira-accountid\"],\n clarityScoreThreshold: 0.7,\n requiredFields: [\"description\"],\n },\n github: {\n owner: \"your-org\",\n repo: name,\n token: \"\",\n defaultBranch: \"main\",\n branchPattern: \"feature/{ticketKey}-{slug}\",\n autoMergeStrategy: \"squash\",\n reviewers: [],\n majorIssueThreshold: 1,\n },\n workspace: {\n rootDir: \"/path/to/workspace\",\n allowedPaths: [\".\"],\n },\n telegram: {\n botToken: \"\",\n chatId: \"\",\n },\n pipeline: {\n maxConcurrentRuns: 2,\n },\n };\n\n fs.mkdirSync(PROJECTS_DIR, { recursive: true });\n fs.writeFileSync(filePath, JSON.stringify(skeleton, null, 2));\n\n const displayPath = filePath.replace(os.homedir(), \"~\");\n process.stdout.write(\n pc.green(`✓ Created ${displayPath} — fill in credentials before running\\n`),\n );\n}\n\nexport async function projectsRemove(name: string): Promise<void> {\n const filePath = path.join(PROJECTS_DIR, `${name}.json`);\n\n if (!fs.existsSync(filePath)) {\n process.stderr.write(\n pc.red(`Error: Project '${name}' not found at ${filePath}\\n`),\n );\n process.exit(1);\n }\n\n const confirmed = await confirm({\n message: `Delete project '${name}'? This is irreversible.`,\n initialValue: false,\n });\n\n // @clack/prompts returns symbol when user cancels (Ctrl+C)\n if (typeof confirmed !== \"boolean\" || !confirmed) {\n process.stdout.write(\"Cancelled.\\n\");\n process.exit(0);\n }\n\n fs.unlinkSync(filePath);\n process.stdout.write(pc.green(`✓ Project '${name}' removed\\n`));\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getEvents,
4
+ getRunDir
5
+ } from "./chunk-VWBCDZWQ.js";
6
+ import {
7
+ createLogger
8
+ } from "./chunk-IT74N3UH.js";
9
+
10
+ // src/commands/replay.ts
11
+ import fs from "fs";
12
+ import pc from "picocolors";
13
+ var log = createLogger("replay");
14
+ function formatTime(iso) {
15
+ return iso.slice(11, 19);
16
+ }
17
+ function elapsedSeconds(from, to) {
18
+ const diff = new Date(to).getTime() - new Date(from).getTime();
19
+ return `${(diff / 1e3).toFixed(1)}s`;
20
+ }
21
+ function printEvent(event, startedAt) {
22
+ const ts = pc.gray(`[${formatTime(event.timestamp)}]`);
23
+ switch (event.type) {
24
+ case "STARTED":
25
+ process.stdout.write(`${ts} ${pc.cyan("\u25B6 STARTED")}
26
+ `);
27
+ break;
28
+ case "STAGE_STARTED":
29
+ process.stdout.write(
30
+ `${ts} ${pc.blue(` \u2192 stage:${event.stage} started`)}
31
+ `
32
+ );
33
+ break;
34
+ case "STAGE_COMPLETED": {
35
+ const elapsed = startedAt ? pc.gray(` (${elapsedSeconds(startedAt, event.timestamp)})`) : "";
36
+ process.stdout.write(
37
+ `${ts} ${pc.green(` \u2713 stage:${event.stage}`)}${elapsed}
38
+ `
39
+ );
40
+ break;
41
+ }
42
+ case "STAGE_FAILED":
43
+ process.stdout.write(
44
+ `${ts} ${pc.red(` \u2717 stage:${event.stage} ${event.error}`)}
45
+ `
46
+ );
47
+ break;
48
+ case "STAGE_SKIPPED":
49
+ process.stdout.write(
50
+ `${ts} ${pc.gray(` \u2298 stage:${event.stage} skipped \u2014 ${event.reason}`)}
51
+ `
52
+ );
53
+ break;
54
+ case "CLARIFICATION_REQUESTED": {
55
+ process.stdout.write(
56
+ `${ts} ${pc.yellow(" \u26A0 CLARIFICATION REQUESTED")}
57
+ `
58
+ );
59
+ for (const q of event.questions) {
60
+ process.stdout.write(` ${pc.yellow("\u2022")} ${q}
61
+ `);
62
+ }
63
+ break;
64
+ }
65
+ case "CLARIFICATION_RECEIVED": {
66
+ const preview = event.answers.slice(0, 80);
67
+ process.stdout.write(
68
+ `${ts} ${pc.green(" \u2713 CLARIFICATION RECEIVED")} ${pc.gray(preview)}
69
+ `
70
+ );
71
+ break;
72
+ }
73
+ case "HUMAN_APPROVAL_REQUESTED":
74
+ process.stdout.write(
75
+ `${ts} ${pc.yellow(" \u26A0 HUMAN APPROVAL REQUESTED")}
76
+ `
77
+ );
78
+ break;
79
+ case "HUMAN_APPROVED":
80
+ process.stdout.write(`${ts} ${pc.green(" \u2713 HUMAN APPROVED")}
81
+ `);
82
+ break;
83
+ case "HUMAN_REJECTED":
84
+ process.stdout.write(
85
+ `${ts} ${pc.red(` \u2717 HUMAN REJECTED ${event.reason}`)}
86
+ `
87
+ );
88
+ break;
89
+ case "PIPELINE_COMPLETED": {
90
+ const elapsed = startedAt ? pc.gray(` (${elapsedSeconds(startedAt, event.timestamp)})`) : "";
91
+ process.stdout.write(
92
+ `${ts} ${pc.bold(pc.green("\u2713 PIPELINE COMPLETED"))}${elapsed}
93
+ `
94
+ );
95
+ break;
96
+ }
97
+ case "PIPELINE_ABORTED": {
98
+ const reason = event.reason ? ` \u2014 ${event.reason}` : "";
99
+ process.stdout.write(
100
+ `${ts} ${pc.bold(pc.red(`\u2717 PIPELINE ABORTED${reason}`))}
101
+ `
102
+ );
103
+ break;
104
+ }
105
+ default: {
106
+ const _exhaustive = event;
107
+ const fallback = _exhaustive;
108
+ process.stdout.write(`${ts} ${pc.gray(fallback.type)}
109
+ `);
110
+ break;
111
+ }
112
+ }
113
+ }
114
+ async function replayRun(ticketKey, projectName) {
115
+ log.debug({ ticketKey, projectName }, "replay started");
116
+ const runDir = getRunDir(projectName, ticketKey);
117
+ if (!fs.existsSync(runDir)) {
118
+ process.stderr.write(
119
+ `Error: no run directory found for ${ticketKey} (project: ${projectName})
120
+ `
121
+ );
122
+ process.exitCode = 1;
123
+ return;
124
+ }
125
+ const events = getEvents(runDir);
126
+ if (events.length === 0) {
127
+ process.stderr.write(
128
+ `Error: no events found for ${ticketKey} (project: ${projectName})
129
+ `
130
+ );
131
+ process.exitCode = 1;
132
+ return;
133
+ }
134
+ const startEvent = events.find((e) => e.type === "STARTED");
135
+ const startedAt = startEvent?.timestamp ?? null;
136
+ const headerTimestamp = startedAt ? pc.gray(` started ${startedAt}`) : "";
137
+ process.stdout.write(
138
+ `
139
+ ${pc.bold(pc.cyan(`\u27F3 Replay: ${ticketKey}`))}${headerTimestamp}
140
+
141
+ `
142
+ );
143
+ for (const event of events) {
144
+ printEvent(event, startedAt);
145
+ }
146
+ process.stdout.write("\n");
147
+ }
148
+ export {
149
+ replayRun
150
+ };
151
+ //# sourceMappingURL=replay-M4JEG4Z4.js.map