git-intent
Version:
Git workflow tool for intentional commits — define your commit intentions first for clearer, more atomic changes.
464 lines (450 loc) • 18.2 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// src/index.ts
var import_git_intent_core10 = require("@offlegacy/git-intent-core");
var import_commander10 = require("commander");
// src/commands/list.ts
var import_git_intent_core = require("@offlegacy/git-intent-core");
var import_chalk = __toESM(require("chalk"), 1);
var import_commander = require("commander");
var list = new import_commander.Command().command("list").description("List all intentional commits").action(async () => {
const commits = await import_git_intent_core.storage.loadCommits();
if (commits.length === 0) {
console.log("No intents found");
return;
}
console.log("\nCreated:");
const createdCommits = commits.filter((commit2) => commit2.status === "created");
for (const commit2 of createdCommits) {
console.log(import_chalk.default.white(` [${commit2.id}] ${commit2.message}`));
}
console.log("\nIn Progress:");
const inProgressCommits = commits.filter((commit2) => commit2.status === "in_progress");
for (const commit2 of inProgressCommits) {
console.log(import_chalk.default.blue(` [${commit2.id}] ${commit2.message}`));
}
});
var list_default = list;
// src/commands/start.ts
var import_git_intent_core2 = require("@offlegacy/git-intent-core");
var import_chalk2 = __toESM(require("chalk"), 1);
var import_commander2 = require("commander");
var import_prompts = __toESM(require("prompts"), 1);
var start = new import_commander2.Command().command("start").argument("[id]", "Intent ID").description("Start working on a planned intent").action(async (id) => {
const commits = await import_git_intent_core2.storage.loadCommits();
let selectedId = id;
if (!selectedId) {
const createdCommits = commits.filter((c) => c.status === "created");
if (createdCommits.length === 0) {
console.log("No created intents found");
return;
}
const response = await (0, import_prompts.default)({
type: "select",
name: "id",
message: "Select an intent to start:",
choices: createdCommits.map((c) => ({
title: `${c.message} (${c.id})`,
value: c.id
}))
});
selectedId = response.id;
}
if (!selectedId) {
console.error("No intent selected");
return;
}
const targetCommit = commits.find((c) => c.id === selectedId);
if (!targetCommit) {
console.error("Intent not found");
return;
}
if (targetCommit.status !== "created") {
console.error("Intent is not in created status");
return;
}
const currentBranch = await import_git_intent_core2.gitService.getCurrentBranch();
targetCommit.status = "in_progress";
targetCommit.metadata.startedAt = (/* @__PURE__ */ new Date()).toISOString();
targetCommit.metadata.branch = currentBranch;
await import_git_intent_core2.storage.saveCommits(commits);
console.log(import_chalk2.default.green("\u2713 Started working on:"));
console.log(`ID: ${import_chalk2.default.blue(targetCommit.id)}`);
console.log(`Message: ${targetCommit.message}`);
});
var start_default = start;
// src/commands/show.ts
var import_git_intent_core3 = require("@offlegacy/git-intent-core");
var import_chalk3 = __toESM(require("chalk"), 1);
var import_commander3 = require("commander");
var show = new import_commander3.Command().command("show").description("Show current intention").action(async () => {
const commits = await import_git_intent_core3.storage.loadCommits();
const currentCommit = commits.find((c) => c.status === "in_progress");
if (!currentCommit) {
console.log("No active intention");
return;
}
console.log(import_chalk3.default.blue("Current intention:"));
console.log(`ID: ${import_chalk3.default.dim(currentCommit.id)}`);
console.log(`Message: ${currentCommit.message}`);
console.log(`Status: ${import_chalk3.default.yellow(currentCommit.status)}`);
console.log(`Created at: ${new Date(currentCommit.metadata.createdAt).toLocaleString()}`);
});
var show_default = show;
// src/commands/commit.ts
var import_git_intent_core4 = require("@offlegacy/git-intent-core");
var import_chalk4 = __toESM(require("chalk"), 1);
var import_commander4 = require("commander");
var commit = new import_commander4.Command().command("commit").description("Complete current intention and commit").option("-m, --message <message>", "Additional commit message").action(async (options) => {
const commits = await import_git_intent_core4.storage.loadCommits();
const currentCommit = commits.find((c) => c.status === "in_progress");
if (!currentCommit) {
console.log("No active intention");
return;
}
const message = options.message ? `${currentCommit.message}
${options.message}` : currentCommit.message;
await import_git_intent_core4.gitService.createCommit(message);
await import_git_intent_core4.storage.deleteCommit(currentCommit.id);
console.log(import_chalk4.default.green("\u2713 Intention completed and committed"));
});
var commit_default = commit;
// src/commands/drop.ts
var import_git_intent_core5 = require("@offlegacy/git-intent-core");
var import_chalk5 = __toESM(require("chalk"), 1);
var import_commander5 = require("commander");
var import_prompts2 = __toESM(require("prompts"), 1);
var drop = new import_commander5.Command().command("drop").description("Drop a planned intent").argument("[id]", "Intent ID").option("-a, --all", "Drop all created intents").action(async (id, options) => {
const commits = await import_git_intent_core5.storage.loadCommits();
const createdCommits = commits.filter((c) => c.status === "created");
if (options.all) {
await import_git_intent_core5.storage.saveCommits([]);
console.log(import_chalk5.default.green("\u2713 All created intents removed"));
return;
}
let selectedId = id;
if (!selectedId) {
if (createdCommits.length === 0) {
console.log("No created intents found. Nothing to remove.");
return;
}
const response = await (0, import_prompts2.default)({
type: "select",
name: "id",
message: "Select an intent to remove:",
choices: createdCommits.map((c) => ({
title: `${c.message} (${c.id})`,
value: c.id
}))
});
selectedId = response.id;
}
if (!selectedId) {
console.error("No intent selected");
return;
}
const targetCommit = commits.find((c) => c.id === selectedId);
if (!targetCommit) {
console.error("Intent not found");
return;
}
if (targetCommit.status !== "created") {
console.error("Can only remove intents in created status");
return;
}
const updatedCommits = commits.filter((c) => c.id !== selectedId);
await import_git_intent_core5.storage.saveCommits(updatedCommits);
console.log(import_chalk5.default.green("\u2713 Intent removed:"));
console.log(`ID: ${import_chalk5.default.blue(targetCommit.id)}`);
console.log(`Message: ${targetCommit.message}`);
});
var drop_default = drop;
// src/commands/cancel.ts
var import_git_intent_core6 = require("@offlegacy/git-intent-core");
var import_chalk6 = __toESM(require("chalk"), 1);
var import_commander6 = require("commander");
var import_prompts3 = __toESM(require("prompts"), 1);
var cancel = new import_commander6.Command().command("cancel").description("Cancel current intention").action(async () => {
const commits = await import_git_intent_core6.storage.loadCommits();
const currentCommit = commits.find((c) => c.status === "in_progress");
if (!currentCommit) {
console.log("No active intention");
return;
}
const { action } = await (0, import_prompts3.default)({
type: "select",
name: "action",
message: "What would you like to do with the intent?",
choices: [
{ title: "Reset to created status", value: "reset" },
{ title: "Delete the intent", value: "delete" }
]
});
if (!action) {
return;
}
let updatedCommits;
if (action === "reset") {
updatedCommits = commits.map(
(c) => c.id === currentCommit.id ? { ...c, status: "created", metadata: { ...c.metadata, startedAt: void 0 } } : c
);
console.log(import_chalk6.default.green("\u2713 Intent reset to created status:"));
} else {
updatedCommits = commits.filter((c) => c.id !== currentCommit.id);
console.log(import_chalk6.default.green("\u2713 Intent deleted:"));
}
await import_git_intent_core6.storage.saveCommits(updatedCommits);
console.log(`ID: ${import_chalk6.default.blue(currentCommit.id)}`);
console.log(`Message: ${currentCommit.message}`);
console.log("\nNote: Your staged changes are preserved.");
});
var cancel_default = cancel;
// src/commands/reset.ts
var import_git_intent_core7 = require("@offlegacy/git-intent-core");
var import_commander7 = require("commander");
var import_prompts4 = __toESM(require("prompts"), 1);
var reset = new import_commander7.Command().command("reset").description("Reset all intents").action(async () => {
const response = await (0, import_prompts4.default)({
type: "confirm",
name: "reset",
message: "Are you sure you want to reset all intents?",
initial: false
});
if (!response.reset) {
return;
}
await import_git_intent_core7.storage.clearCommits();
console.log("All intents reset");
});
var reset_default = reset;
// src/commands/divide.ts
var import_git_intent_core8 = require("@offlegacy/git-intent-core");
var import_chalk7 = __toESM(require("chalk"), 1);
var import_commander8 = require("commander");
var import_external_editor = __toESM(require("external-editor"), 1);
var import_prompts5 = __toESM(require("prompts"), 1);
var divide = new import_commander8.Command().command("divide").description("Divide an intent into smaller parts").action(async () => {
const commits = await import_git_intent_core8.storage.loadCommits();
if (commits.length === 0) {
console.log("No intents found to divide");
return;
}
const response = await (0, import_prompts5.default)({
type: "select",
name: "id",
message: "Select an intent to divide:",
choices: commits.map((c) => ({
title: `[${c.status === "created" ? "Created" : "In Progress"}] ${c.message.split("\n")[0]} (${c.id})`,
value: c.id
})),
onState: (state) => {
if (state.aborted) {
process.nextTick(() => {
process.exit(0);
});
}
}
});
const selectedId = response.id;
if (!selectedId) {
console.log("No intent selected");
return;
}
const targetCommit = commits.find((c) => c.id === selectedId);
if (!targetCommit) {
console.error("Intent not found");
return;
}
console.log(import_chalk7.default.blue("\nOriginal commit:"), targetCommit.message);
const tasks = [];
console.log(import_chalk7.default.yellow("\nDividing commit into two tasks."));
console.log(
import_chalk7.default.dim(
"Tip: Enter a title directly for a simple task, or leave it empty to open an editor for a detailed commit message."
)
);
console.log(import_chalk7.default.blue("\nFirst task:"));
const { taskTitle: firstTaskTitle } = await (0, import_prompts5.default)({
type: "text",
name: "taskTitle",
message: "Task 1 title:",
onState: (state) => {
if (state.aborted) {
process.nextTick(() => {
process.exit(0);
});
}
}
});
if (firstTaskTitle && firstTaskTitle.trim() !== "") {
tasks.push(firstTaskTitle.trim());
} else {
console.log(import_chalk7.default.dim("Opening editor for commit message. Save and close the editor when done."));
let initialText = targetCommit.message;
initialText = `# Enter commit message for the first task
# Lines starting with # will be ignored
${initialText}`;
const message = import_external_editor.default.edit(initialText, {
postfix: ".git-intent-divide"
});
const fullMessage = message.split("\n").filter((line) => !line.trim().startsWith("#")).join("\n").trim();
if (!fullMessage) {
console.log("No message provided for the first task. Operation cancelled.");
return;
}
tasks.push(fullMessage);
}
console.log(import_chalk7.default.blue("\nSecond task:"));
const { taskTitle: secondTaskTitle } = await (0, import_prompts5.default)({
type: "text",
name: "taskTitle",
message: "Task 2 title:",
onState: (state) => {
if (state.aborted) {
process.nextTick(() => {
process.exit(0);
});
}
}
});
if (secondTaskTitle && secondTaskTitle.trim() !== "") {
tasks.push(secondTaskTitle.trim());
} else {
console.log(import_chalk7.default.dim("Opening editor for commit message. Save and close the editor when done."));
const initialText = "# Enter commit message for the second task\n# Lines starting with # will be ignored\n";
const message = import_external_editor.default.edit(initialText, {
postfix: ".git-intent-divide"
});
const fullMessage = message.split("\n").filter((line) => !line.trim().startsWith("#")).join("\n").trim();
if (!fullMessage) {
console.log("No message provided for the second task. Operation cancelled.");
return;
}
tasks.push(fullMessage);
}
console.log(import_chalk7.default.blue("\nTasks to create:"));
tasks.forEach((task, index) => {
const title = task.split("\n")[0];
console.log(`${index + 1}. ${title}`);
if (task.includes("\n")) {
const preview = task.split("\n").slice(1).join(" ").trim();
const shortPreview = preview.length > 60 ? `${preview.substring(0, 57)}...` : preview;
if (shortPreview) {
console.log(` ${import_chalk7.default.dim(shortPreview)}`);
}
}
});
const { confirmed } = await (0, import_prompts5.default)({
type: "confirm",
name: "confirmed",
message: "Do you want to divide the commit with these tasks?",
initial: true,
onState: (state) => {
if (state.aborted) {
process.nextTick(() => {
process.exit(0);
});
}
}
});
if (!confirmed) {
console.log("Operation cancelled.");
return;
}
const { shouldRemoveOriginal } = await (0, import_prompts5.default)({
type: "confirm",
name: "shouldRemoveOriginal",
message: "Do you want to remove the original commit?",
initial: false,
onState: (state) => {
if (state.aborted) {
process.nextTick(() => {
process.exit(0);
});
}
}
});
const newCommitIds = [];
for (const task of tasks) {
const newCommitId = await import_git_intent_core8.storage.addCommit({
message: task,
status: "created",
metadata: {
createdAt: (/* @__PURE__ */ new Date()).toISOString()
}
});
newCommitIds.push(newCommitId);
}
if (shouldRemoveOriginal) {
await import_git_intent_core8.storage.deleteCommit(targetCommit.id);
}
console.log(import_chalk7.default.green("\u2713 Successfully divided the commit:"));
for (let i = 0; i < tasks.length; i++) {
const title = tasks[i].split("\n")[0];
console.log(`${i + 1}. ${import_chalk7.default.blue(title)} (ID: ${newCommitIds[i]})`);
}
if (!shouldRemoveOriginal) {
console.log(import_chalk7.default.yellow("\nOriginal commit was kept:"));
const originalTitle = targetCommit.message.split("\n")[0];
console.log(`${import_chalk7.default.blue(originalTitle)} (ID: ${targetCommit.id})`);
}
});
var divide_default = divide;
// src/commands/add.ts
var import_git_intent_core9 = require("@offlegacy/git-intent-core");
var import_chalk8 = __toESM(require("chalk"), 1);
var import_commander9 = require("commander");
var import_external_editor2 = __toESM(require("external-editor"), 1);
var add = new import_commander9.Command().command("add").description("Add a new intentional commit before starting work").argument("[message]", "Intent message").action(async (message) => {
let commitMessage = message;
if (!commitMessage) {
const text = import_external_editor2.default.edit("", {
postfix: ".git-intent"
});
commitMessage = text.trim();
}
if (!commitMessage) {
console.error("Commit message is required");
process.exit(1);
}
const newCommitId = await import_git_intent_core9.storage.addCommit({
message: commitMessage,
status: "created",
metadata: {
createdAt: (/* @__PURE__ */ new Date()).toISOString()
}
});
console.log(import_chalk8.default.green("\u2713 Intent created:"));
console.log(`ID: ${import_chalk8.default.blue(newCommitId)}`);
console.log(`Message: ${commitMessage}`);
});
var add_default = add;
// src/index.ts
(async () => {
await import_git_intent_core10.storage.initializeRefs();
const { version, description } = (0, import_git_intent_core10.getPackageInfo)();
import_commander10.program.name("git-intent").description(description).version(version).addCommand(add_default).addCommand(list_default).addCommand(start_default).addCommand(show_default).addCommand(commit_default).addCommand(cancel_default).addCommand(reset_default).addCommand(divide_default).addCommand(drop_default);
import_commander10.program.parse();
})();