@fromsvenwithlove/devops-issues-cli
Version:
AI-powered CLI tool and library for Azure DevOps work item management with Claude agents
136 lines (116 loc) ⢠4.08 kB
JavaScript
import inquirer from "inquirer";
import chalk from "chalk";
import { getConfig } from "../config/index.js";
import { AzureDevOpsClient } from "../api/azure-client.js";
import {
getChildWorkItemType,
canHaveChildren,
} from "../utils/work-item-types.js";
import { TreeSelector } from "./tree-selector.js";
import { stdinStateManager } from "../utils/stdin-state-manager.js";
/**
* Runs the interactive create work item wizard
* @param {Object} options - Command options
* @returns {Object} Created work item details
*/
export async function runCreateWizard(options = {}) {
console.log(chalk.bold.blue("\nš§ Create Work Item Wizard\n"));
try {
// Get configuration and connect to Azure DevOps
const config = getConfig();
const client = new AzureDevOpsClient(config);
await client.connect();
// Step 1: Get all work items for parent selection
console.log(chalk.dim("Loading work items for parent selection..."));
const workItems = await client.getAssignedWorkItems({});
if (workItems.length === 0) {
console.log(
chalk.yellow(
"No work items found. You need existing work items to create child items."
)
);
return;
}
// Step 2: Select parent from available work items using tree selector
const treeSelector = new TreeSelector(workItems);
const parentId = await treeSelector.selectParent();
if (!parentId) {
console.log(chalk.yellow("\nWizard cancelled."));
return;
}
// Step 3: Get parent details and determine child type
const parent = await client.getWorkItem(parentId);
const childType = getChildWorkItemType(parent.type);
console.log(
chalk.dim(
`\nSelected parent: ${parent.type} #${parent.id} - ${parent.title}`
)
);
console.log(chalk.dim(`New work item will be: ${childType}`));
// Full reset
process.stdin.setRawMode?.(false);
process.stdin.removeAllListeners(); // š Verwijdert alle listeners op stdin
process.stdin.pause();
while (process.stdin.read() !== null); // leeg input buffer
process.stdin.resume();
// Step 4: Get title for new work item
const title = await promptForTitle(childType);
if (!title) {
console.log(chalk.yellow("\nWizard cancelled."));
return;
}
// Step 5: Create the work item
const newWorkItem = await client.createWorkItem(parentId, title, childType);
// Step 6: Display success message
displayCreateSuccess(newWorkItem, parent);
return newWorkItem;
} catch (error) {
console.error(chalk.red("Error:"), error.message);
throw error;
}
}
/**
* Prompts user for work item title
* @param {string} workItemType - Type of work item being created
* @returns {string|null} Title or null if cancelled
*/
async function promptForTitle(workItemType) {
const answers = await inquirer.prompt([
{
type: "input",
name: "title",
message: `Enter title for new ${workItemType}:`,
validate: (input) => {
if (!input || input.trim().length === 0) {
return "Title cannot be empty";
}
if (input.trim().length > 255) {
return "Title must be 255 characters or less";
}
return true;
},
filter: (input) => input.trim(),
},
]);
return answers.title || null;
}
/**
* Displays success message after work item creation
* @param {Object} newWorkItem - Created work item
* @param {Object} parent - Parent work item
*/
function displayCreateSuccess(newWorkItem, parent) {
console.log("");
console.log(chalk.green("ā
Work item created successfully!"));
console.log("");
console.log(chalk.bold("Details:"));
console.log(` ID: ${chalk.cyan("#" + newWorkItem.id)}`);
console.log(` Title: ${newWorkItem.title}`);
console.log(` Type: ${newWorkItem.type}`);
console.log(` State: ${newWorkItem.state}`);
console.log(` Parent: #${parent.id} (${parent.title})`);
if (newWorkItem.url) {
console.log(` URL: ${chalk.dim(newWorkItem.url)}`);
}
console.log("");
}