You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

git-intent

Package Overview
Dependencies
Maintainers
3
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

git-intent - npm Package Compare versions

Comparing version

to
0.0.8

640

dist/index.js
#!/usr/bin/env node
import{Command as xt}from"commander";import H from"node:path";import v from"execa";import I from"fs-extra";import{nanoid as q}from"nanoid";function _(i){return q(i)}import U from"node:path";import V from"fs-extra";function h(){let i=U.join("package.json");return V.readJSONSync(i)}import Y from"simple-git";var x=i=>Y(i);async function k(i){let t=x(i);try{await t.checkIsRepo()}catch{throw new Error("Not a git repository")}}async function M(i){return(await x(i).revparse(["--abbrev-ref","HEAD"])).trim()}async function X(i,t){return(await x(t).commit(i)).commit}var C=x();var D=class i{static instance;REFS_PREFIX="refs/intentional-commits";storageFilename;GIT_DIR=".git";gitRoot;constructor(){this.storageFilename=process.env.VITEST?"test_intents.json":"intents.json"}static getInstance(){return i.instance||(i.instance=new i),i.instance}setGitRoot(t){this.gitRoot=t}async getGitRoot(){return this.gitRoot?this.gitRoot:process.cwd()}async getCommitsDir(){let t=await this.getGitRoot();return H.join(t,this.GIT_DIR,"intentional-commits")}async getCommitsFile(){let t=await this.getCommitsDir();return H.join(t,"commits.json")}getInitialData(){return{version:h().version,commits:[]}}async ensureCommitsDir(){let t=await this.getCommitsDir(),e=await this.getCommitsFile();await I.ensureDir(t);try{await I.access(e)}catch{await I.writeJSON(e,this.getInitialData())}}migrateData(t){return t}async loadCommits(){let t=await this.getGitRoot();await k(t),await this.ensureCommitsDir();try{let e=await C.cwd(t).show(`${this.REFS_PREFIX}/commits:${this.storageFilename}`);return this.migrateData(JSON.parse(e)).commits}catch{let e=await this.getCommitsFile();return this.migrateData(await I.readJSON(e)).commits}}async saveCommitsData(t){let e=await this.getGitRoot(),o=await this.getCommitsFile(),s=JSON.stringify(t,null,2),{stdout:r}=await v("git",["hash-object","-w","--stdin"],{input:s,cwd:e}),c=`100644 blob ${r.trim()} ${this.storageFilename}
`,{stdout:m}=await v("git",["mktree"],{input:c,cwd:e}),{stdout:p}=await v("git",["commit-tree",m.trim(),"-m","Update intent commits"],{cwd:e});await C.cwd(e).raw(["update-ref",`${this.REFS_PREFIX}/commits`,p.trim()]),await I.writeJSON(o,t,{spaces:2})}async saveCommits(t){let e={version:h().version,commits:t};await this.saveCommitsData(e)}async addCommit(t){let e=await this.loadCommits(),o=_(8),s={version:h().version,commits:[...e,{...t,id:o}]};return await this.saveCommitsData(s),o}async updateCommitMessage(t,e){let o=await this.loadCommits(),s=o.find(c=>c.id===t);if(!s)throw new Error("Commit not found");let r={version:h().version,commits:o.map(c=>c.id===t?{...s,message:e}:c)};await this.saveCommitsData(r)}async deleteCommit(t){let o=(await this.loadCommits()).filter(s=>s.id!==t);await this.saveCommits(o)}async clearCommits(){let t=await this.getGitRoot(),e=await this.getCommitsFile();await I.remove(e),await C.cwd(t).raw(["update-ref","-d",`${this.REFS_PREFIX}/commits`])}async initializeRefs(){let t=await this.getGitRoot();await k(t);try{await C.cwd(t).raw(["show-ref","--verify",`${this.REFS_PREFIX}/commits`])}catch{let e=this.getInitialData(),o=JSON.stringify(e,null,2),{stdout:s}=await v("git",["hash-object","-w","--stdin"],{input:o,cwd:t}),r=`100644 blob ${s.trim()} ${this.storageFilename}
`,{stdout:c}=await v("git",["mktree"],{input:r,cwd:t}),{stdout:m}=await v("git",["commit-tree",c.trim(),"-m","Initialize intent commits"],{cwd:t});await C.cwd(t).raw(["update-ref",`${this.REFS_PREFIX}/commits`,m.trim()])}}},a=D.getInstance();import L from"chalk";import{Command as K}from"commander";var Q=new K().command("list").description("List all intentional commits").action(async()=>{let i=await a.loadCommits();if(i.length===0){console.log("No intents found");return}console.log(`
Created:`);let t=i.filter(o=>o.status==="created");for(let o of t)console.log(L.white(` [${o.id}] ${o.message}`));console.log(`
In Progress:`);let e=i.filter(o=>o.status==="in_progress");for(let o of e)console.log(L.blue(` [${o.id}] ${o.message}`))}),S=Q;import z from"chalk";import{Command as Z}from"commander";import tt from"prompts";var et=new Z().command("start").argument("[id]","Intent ID").description("Start working on a planned intent").action(async i=>{let t=await a.loadCommits(),e=i;if(!e){let r=t.filter(m=>m.status==="created");if(r.length===0){console.log("No created intents found");return}e=(await tt({type:"select",name:"id",message:"Select an intent to start:",choices:r.map(m=>({title:`${m.message} (${m.id})`,value:m.id}))})).id}if(!e){console.error("No intent selected");return}let o=t.find(r=>r.id===e);if(!o){console.error("Intent not found");return}if(o.status!=="created"){console.error("Intent is not in created status");return}let s=await M();o.status="in_progress",o.metadata.startedAt=new Date().toISOString(),o.metadata.branch=s,await a.saveCommits(t),console.log(z.green("\u2713 Started working on:")),console.log(`ID: ${z.blue(o.id)}`),console.log(`Message: ${o.message}`)}),$=et;import b from"chalk";import{Command as ot}from"commander";var it=new ot().command("show").description("Show current intention").action(async()=>{let t=(await a.loadCommits()).find(e=>e.status==="in_progress");if(!t){console.log("No active intention");return}console.log(b.blue("Current intention:")),console.log(`ID: ${b.dim(t.id)}`),console.log(`Message: ${t.message}`),console.log(`Status: ${b.yellow(t.status)}`),console.log(`Created at: ${new Date(t.metadata.createdAt).toLocaleString()}`)}),R=it;import st from"chalk";import{Command as nt}from"commander";var at=new nt().command("commit").description("Complete current intention and commit").option("-m, --message <message>","Additional commit message").action(async i=>{let e=(await a.loadCommits()).find(s=>s.status==="in_progress");if(!e){console.log("No active intention");return}let o=i.message?`${e.message}
${i.message}`:e.message;await X(o),await a.deleteCommit(e.id),console.log(st.green("\u2713 Intention completed and committed"))}),P=at;import F from"chalk";import{Command as rt}from"commander";import mt from"prompts";var ct=new rt().command("drop").description("Drop a planned intent").argument("[id]","Intent ID").option("-a, --all","Drop all created intents").action(async(i,t)=>{let e=await a.loadCommits(),o=e.filter(m=>m.status==="created");if(t.all){await a.saveCommits([]),console.log(F.green("\u2713 All created intents removed"));return}let s=i;if(!s){if(o.length===0){console.log("No created intents found. Nothing to remove.");return}s=(await mt({type:"select",name:"id",message:"Select an intent to remove:",choices:o.map(p=>({title:`${p.message} (${p.id})`,value:p.id}))})).id}if(!s){console.error("No intent selected");return}let r=e.find(m=>m.id===s);if(!r){console.error("Intent not found");return}if(r.status!=="created"){console.error("Can only remove intents in created status");return}let c=e.filter(m=>m.id!==s);await a.saveCommits(c),console.log(F.green("\u2713 Intent removed:")),console.log(`ID: ${F.blue(r.id)}`),console.log(`Message: ${r.message}`)}),T=ct;import N from"chalk";import{Command as dt}from"commander";import lt from"prompts";var gt=new dt().command("cancel").description("Cancel current intention").action(async()=>{let i=await a.loadCommits(),t=i.find(s=>s.status==="in_progress");if(!t){console.log("No active intention");return}let{action:e}=await lt({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(!e)return;let o;e==="reset"?(o=i.map(s=>s.id===t.id?{...s,status:"created",metadata:{...s.metadata,startedAt:void 0}}:s),console.log(N.green("\u2713 Intent reset to created status:"))):(o=i.filter(s=>s.id!==t.id),console.log(N.green("\u2713 Intent deleted:"))),await a.saveCommits(o),console.log(`ID: ${N.blue(t.id)}`),console.log(`Message: ${t.message}`),console.log(`
Note: Your staged changes are preserved.`)}),O=gt;import{Command as pt}from"commander";import ft from"prompts";var ut=new pt().command("reset").description("Reset all intents").action(async()=>{(await ft({type:"confirm",name:"reset",message:"Are you sure you want to reset all intents?",initial:!1})).reset&&(await a.clearCommits(),console.log("All intents reset"))}),E=ut;import g from"chalk";import{Command as wt}from"commander";import B from"external-editor";import y from"prompts";var ht=new wt().command("divide").description("Divide an intent into smaller parts").action(async()=>{let i=await a.loadCommits();if(i.length===0){console.log("No intents found to divide");return}let e=(await y({type:"select",name:"id",message:"Select an intent to divide:",choices:i.map(n=>({title:`[${n.status==="created"?"Created":"In Progress"}] ${n.message.split(`
`)[0]} (${n.id})`,value:n.id})),onState:n=>{n.aborted&&process.nextTick(()=>{process.exit(0)})}})).id;if(!e){console.log("No intent selected");return}let o=i.find(n=>n.id===e);if(!o){console.error("Intent not found");return}console.log(g.blue(`
Original commit:`),o.message);let s=[];console.log(g.yellow(`
Dividing commit into two tasks.`)),console.log(g.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(g.blue(`
First task:`));let{taskTitle:r}=await y({type:"text",name:"taskTitle",message:"Task 1 title:",onState:n=>{n.aborted&&process.nextTick(()=>{process.exit(0)})}});if(r&&r.trim()!=="")s.push(r.trim());else{console.log(g.dim("Opening editor for commit message. Save and close the editor when done."));let n=o.message;n=`# Enter commit message for the first task
// src/index.ts
import { program } from "commander";
// src/utils/storage.ts
import path2 from "node:path";
import execa from "execa";
import fs2 from "fs-extra";
// src/utils/generateId.ts
import { nanoid } from "nanoid";
function generateId(size) {
return nanoid(size);
}
// src/utils/get-package-info.ts
import path from "node:path";
import { fileURLToPath } from "node:url";
import fs from "fs-extra";
function getPackageInfo() {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const packageJsonPath = path.join(__dirname, "..", "package.json");
return fs.readJSONSync(packageJsonPath);
}
// src/utils/git.ts
import simpleGit from "simple-git";
var createGit = (cwd) => simpleGit(cwd);
async function checkIsRepo(cwd) {
const git = createGit(cwd);
try {
await git.checkIsRepo();
} catch {
throw new Error("Not a git repository");
}
}
async function getCurrentBranch(cwd) {
const git = createGit(cwd);
const branch = await git.revparse(["--abbrev-ref", "HEAD"]);
return branch.trim();
}
async function createCommit(message, cwd) {
const git = createGit(cwd);
const result = await git.commit(message);
return result.commit;
}
var git_default = createGit();
// src/utils/storage.ts
var GitIntentionalCommitStorage = class _GitIntentionalCommitStorage {
static instance;
REFS_PREFIX = "refs/intentional-commits";
storageFilename;
GIT_DIR = ".git";
gitRoot;
constructor() {
this.storageFilename = process.env.VITEST ? "test_intents.json" : "intents.json";
}
static getInstance() {
if (!_GitIntentionalCommitStorage.instance) {
_GitIntentionalCommitStorage.instance = new _GitIntentionalCommitStorage();
}
return _GitIntentionalCommitStorage.instance;
}
setGitRoot(root) {
this.gitRoot = root;
}
async getGitRoot() {
if (this.gitRoot) return this.gitRoot;
return process.cwd();
}
async getCommitsDir() {
const root = await this.getGitRoot();
return path2.join(root, this.GIT_DIR, "intentional-commits");
}
async getCommitsFile() {
const commitsDir = await this.getCommitsDir();
return path2.join(commitsDir, "commits.json");
}
getInitialData() {
return {
version: getPackageInfo().version,
commits: []
};
}
async ensureCommitsDir() {
const commitsDir = await this.getCommitsDir();
const commitsFile = await this.getCommitsFile();
await fs2.ensureDir(commitsDir);
try {
await fs2.access(commitsFile);
} catch {
await fs2.writeJSON(commitsFile, this.getInitialData());
}
}
// NOTE: Migrate old data
migrateData(data) {
return data;
}
async loadCommits() {
const root = await this.getGitRoot();
await checkIsRepo(root);
await this.ensureCommitsDir();
try {
const result = await git_default.cwd(root).show(`${this.REFS_PREFIX}/commits:${this.storageFilename}`);
const data = this.migrateData(JSON.parse(result));
console.log(data);
return data.commits;
} catch {
const commitsFile = await this.getCommitsFile();
const data = this.migrateData(await fs2.readJSON(commitsFile));
console.log(data);
return data.commits;
}
}
async saveCommitsData(data) {
const root = await this.getGitRoot();
const commitsFile = await this.getCommitsFile();
const content = JSON.stringify(data, null, 2);
const { stdout: hash } = await execa("git", ["hash-object", "-w", "--stdin"], { input: content, cwd: root });
const treeContent = `100644 blob ${hash.trim()} ${this.storageFilename}
`;
const { stdout: treeHash } = await execa("git", ["mktree"], { input: treeContent, cwd: root });
const { stdout: commitHash } = await execa("git", ["commit-tree", treeHash.trim(), "-m", "Update intent commits"], {
cwd: root
});
await git_default.cwd(root).raw(["update-ref", `${this.REFS_PREFIX}/commits`, commitHash.trim()]);
await fs2.writeJSON(commitsFile, data, { spaces: 2 });
}
async saveCommits(commits) {
const data = {
version: getPackageInfo().version,
commits
};
await this.saveCommitsData(data);
}
async addCommit(commit2) {
const currentCommits = await this.loadCommits();
const newCommitId = generateId(8);
const data = {
version: getPackageInfo().version,
commits: [...currentCommits, { ...commit2, id: newCommitId }]
};
await this.saveCommitsData(data);
return newCommitId;
}
async updateCommitMessage(id, message) {
const currentCommits = await this.loadCommits();
const existingCommit = currentCommits.find((c) => c.id === id);
if (!existingCommit) {
throw new Error("Commit not found");
}
const data = {
version: getPackageInfo().version,
commits: currentCommits.map((c) => c.id === id ? { ...existingCommit, message } : c)
};
await this.saveCommitsData(data);
}
async deleteCommit(id) {
const currentCommits = await this.loadCommits();
const newCommits = currentCommits.filter((c) => c.id !== id);
await this.saveCommits(newCommits);
}
async clearCommits() {
const root = await this.getGitRoot();
const commitsFile = await this.getCommitsFile();
await fs2.remove(commitsFile);
await git_default.cwd(root).raw(["update-ref", "-d", `${this.REFS_PREFIX}/commits`]);
}
async initializeRefs() {
const root = await this.getGitRoot();
await checkIsRepo(root);
try {
await git_default.cwd(root).raw(["show-ref", "--verify", `${this.REFS_PREFIX}/commits`]);
} catch {
const initialData = this.getInitialData();
const content = JSON.stringify(initialData, null, 2);
const { stdout: hash } = await execa("git", ["hash-object", "-w", "--stdin"], { input: content, cwd: root });
const treeContent = `100644 blob ${hash.trim()} ${this.storageFilename}
`;
const { stdout: treeHash } = await execa("git", ["mktree"], { input: treeContent, cwd: root });
const { stdout: commitHash } = await execa(
"git",
["commit-tree", treeHash.trim(), "-m", "Initialize intent commits"],
{ cwd: root }
);
await git_default.cwd(root).raw(["update-ref", `${this.REFS_PREFIX}/commits`, commitHash.trim()]);
}
}
};
var storage = GitIntentionalCommitStorage.getInstance();
// src/commands/list.ts
import chalk from "chalk";
import { Command } from "commander";
var list = new Command().command("list").description("List all intentional commits").action(async () => {
const commits = await 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(chalk.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(chalk.blue(` [${commit2.id}] ${commit2.message}`));
}
});
var list_default = list;
// src/commands/start.ts
import chalk2 from "chalk";
import { Command as Command2 } from "commander";
import prompts from "prompts";
var start = new Command2().command("start").argument("[id]", "Intent ID").description("Start working on a planned intent").action(async (id) => {
const commits = await 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 prompts({
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 getCurrentBranch();
targetCommit.status = "in_progress";
targetCommit.metadata.startedAt = (/* @__PURE__ */ new Date()).toISOString();
targetCommit.metadata.branch = currentBranch;
await storage.saveCommits(commits);
console.log(chalk2.green("\u2713 Started working on:"));
console.log(`ID: ${chalk2.blue(targetCommit.id)}`);
console.log(`Message: ${targetCommit.message}`);
});
var start_default = start;
// src/commands/show.ts
import chalk3 from "chalk";
import { Command as Command3 } from "commander";
var show = new Command3().command("show").description("Show current intention").action(async () => {
const commits = await storage.loadCommits();
const currentCommit = commits.find((c) => c.status === "in_progress");
if (!currentCommit) {
console.log("No active intention");
return;
}
console.log(chalk3.blue("Current intention:"));
console.log(`ID: ${chalk3.dim(currentCommit.id)}`);
console.log(`Message: ${currentCommit.message}`);
console.log(`Status: ${chalk3.yellow(currentCommit.status)}`);
console.log(`Created at: ${new Date(currentCommit.metadata.createdAt).toLocaleString()}`);
});
var show_default = show;
// src/commands/commit.ts
import chalk4 from "chalk";
import { Command as Command4 } from "commander";
var commit = new Command4().command("commit").description("Complete current intention and commit").option("-m, --message <message>", "Additional commit message").action(async (options) => {
const commits = await 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 createCommit(message);
await storage.deleteCommit(currentCommit.id);
console.log(chalk4.green("\u2713 Intention completed and committed"));
});
var commit_default = commit;
// src/commands/drop.ts
import chalk5 from "chalk";
import { Command as Command5 } from "commander";
import prompts2 from "prompts";
var drop = new Command5().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 storage.loadCommits();
const createdCommits = commits.filter((c) => c.status === "created");
if (options.all) {
await storage.saveCommits([]);
console.log(chalk5.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 prompts2({
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 storage.saveCommits(updatedCommits);
console.log(chalk5.green("\u2713 Intent removed:"));
console.log(`ID: ${chalk5.blue(targetCommit.id)}`);
console.log(`Message: ${targetCommit.message}`);
});
var drop_default = drop;
// src/commands/cancel.ts
import chalk6 from "chalk";
import { Command as Command6 } from "commander";
import prompts3 from "prompts";
var cancel = new Command6().command("cancel").description("Cancel current intention").action(async () => {
const commits = await storage.loadCommits();
const currentCommit = commits.find((c) => c.status === "in_progress");
if (!currentCommit) {
console.log("No active intention");
return;
}
const { action } = await prompts3({
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(chalk6.green("\u2713 Intent reset to created status:"));
} else {
updatedCommits = commits.filter((c) => c.id !== currentCommit.id);
console.log(chalk6.green("\u2713 Intent deleted:"));
}
await storage.saveCommits(updatedCommits);
console.log(`ID: ${chalk6.blue(currentCommit.id)}`);
console.log(`Message: ${currentCommit.message}`);
console.log("\nNote: Your staged changes are preserved.");
});
var cancel_default = cancel;
// src/commands/reset.ts
import { Command as Command7 } from "commander";
import prompts4 from "prompts";
var reset = new Command7().command("reset").description("Reset all intents").action(async () => {
const response = await prompts4({
type: "confirm",
name: "reset",
message: "Are you sure you want to reset all intents?",
initial: false
});
if (!response.reset) {
return;
}
await storage.clearCommits();
console.log("All intents reset");
});
var reset_default = reset;
// src/commands/divide.ts
import chalk7 from "chalk";
import { Command as Command8 } from "commander";
import edit from "external-editor";
import prompts5 from "prompts";
var divide = new Command8().command("divide").description("Divide an intent into smaller parts").action(async () => {
const commits = await storage.loadCommits();
if (commits.length === 0) {
console.log("No intents found to divide");
return;
}
const response = await prompts5({
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(chalk7.blue("\nOriginal commit:"), targetCommit.message);
const tasks = [];
console.log(chalk7.yellow("\nDividing commit into two tasks."));
console.log(
chalk7.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(chalk7.blue("\nFirst task:"));
const { taskTitle: firstTaskTitle } = await prompts5({
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(chalk7.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
${n}`;let u=B.edit(n,{postfix:".git-intent-divide"}).split(`
`).filter(w=>!w.trim().startsWith("#")).join(`
`).trim();if(!u){console.log("No message provided for the first task. Operation cancelled.");return}s.push(u)}console.log(g.blue(`
Second task:`));let{taskTitle:c}=await y({type:"text",name:"taskTitle",message:"Task 2 title:",onState:n=>{n.aborted&&process.nextTick(()=>{process.exit(0)})}});if(c&&c.trim()!=="")s.push(c.trim());else{console.log(g.dim("Opening editor for commit message. Save and close the editor when done."));let u=B.edit(`# Enter commit message for the second task
# Lines starting with # will be ignored
`,{postfix:".git-intent-divide"}).split(`
`).filter(w=>!w.trim().startsWith("#")).join(`
`).trim();if(!u){console.log("No message provided for the second task. Operation cancelled.");return}s.push(u)}console.log(g.blue(`
Tasks to create:`)),s.forEach((n,f)=>{let u=n.split(`
`)[0];if(console.log(`${f+1}. ${u}`),n.includes(`
`)){let w=n.split(`
`).slice(1).join(" ").trim(),J=w.length>60?`${w.substring(0,57)}...`:w;J&&console.log(` ${g.dim(J)}`)}});let{confirmed:m}=await y({type:"confirm",name:"confirmed",message:"Do you want to divide the commit with these tasks?",initial:!0,onState:n=>{n.aborted&&process.nextTick(()=>{process.exit(0)})}});if(!m){console.log("Operation cancelled.");return}let{shouldRemoveOriginal:p}=await y({type:"confirm",name:"shouldRemoveOriginal",message:"Do you want to remove the original commit?",initial:!1,onState:n=>{n.aborted&&process.nextTick(()=>{process.exit(0)})}}),G=[];for(let n of s){let f=await a.addCommit({message:n,status:"created",metadata:{createdAt:new Date().toISOString()}});G.push(f)}p&&await a.deleteCommit(o.id),console.log(g.green("\u2713 Successfully divided the commit:"));for(let n=0;n<s.length;n++){let f=s[n].split(`
`)[0];console.log(`${n+1}. ${g.blue(f)} (ID: ${G[n]})`)}if(!p){console.log(g.yellow(`
Original commit was kept:`));let n=o.message.split(`
`)[0];console.log(`${g.blue(n)} (ID: ${o.id})`)}}),A=ht;import W from"chalk";import{Command as Ct}from"commander";import vt from"external-editor";var It=new Ct().command("add").description("Add a new intentional commit before starting work").argument("[message]","Intent message").action(async i=>{let t=i;t||(t=vt.edit("",{postfix:".git-intent"}).trim()),t||(console.error("Commit message is required"),process.exit(1));let e=await a.addCommit({message:t,status:"created",metadata:{createdAt:new Date().toISOString()}});console.log(W.green("\u2713 Intent created:")),console.log(`ID: ${W.blue(e)}`),console.log(`Message: ${t}`)}),j=It;(async()=>{let i=new xt;await a.initializeRefs();let t=h();i.name("git-intent").description(t.description).version(t.version),i.addCommand(j).addCommand(S).addCommand($).addCommand(R).addCommand(P).addCommand(O).addCommand(E).addCommand(A).addCommand(T),i.parse()})();
${initialText}`;
const message = edit.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(chalk7.blue("\nSecond task:"));
const { taskTitle: secondTaskTitle } = await prompts5({
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(chalk7.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 = edit.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(chalk7.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(` ${chalk7.dim(shortPreview)}`);
}
}
});
const { confirmed } = await prompts5({
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 prompts5({
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 storage.addCommit({
message: task,
status: "created",
metadata: {
createdAt: (/* @__PURE__ */ new Date()).toISOString()
}
});
newCommitIds.push(newCommitId);
}
if (shouldRemoveOriginal) {
await storage.deleteCommit(targetCommit.id);
}
console.log(chalk7.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}. ${chalk7.blue(title)} (ID: ${newCommitIds[i]})`);
}
if (!shouldRemoveOriginal) {
console.log(chalk7.yellow("\nOriginal commit was kept:"));
const originalTitle = targetCommit.message.split("\n")[0];
console.log(`${chalk7.blue(originalTitle)} (ID: ${targetCommit.id})`);
}
});
var divide_default = divide;
// src/commands/add.ts
import chalk8 from "chalk";
import { Command as Command9 } from "commander";
import edit2 from "external-editor";
var add = new Command9().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 = edit2.edit("", {
postfix: ".git-intent"
});
commitMessage = text.trim();
}
if (!commitMessage) {
console.error("Commit message is required");
process.exit(1);
}
const newCommitId = await storage.addCommit({
message: commitMessage,
status: "created",
metadata: {
createdAt: (/* @__PURE__ */ new Date()).toISOString()
}
});
console.log(chalk8.green("\u2713 Intent created:"));
console.log(`ID: ${chalk8.blue(newCommitId)}`);
console.log(`Message: ${commitMessage}`);
});
var add_default = add;
// src/index.ts
(async () => {
await storage.initializeRefs();
program.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);
program.parse();
})();

7

package.json
{
"name": "git-intent",
"version": "0.0.7",
"version": "0.0.8",
"description": "Git workflow tool for intentional commits — define your commit intentions first for clearer, more atomic changes.",

@@ -35,3 +35,3 @@ "keywords": [

"chalk": "^4.1.2",
"commander": "^11.1.0",
"commander": "^13.1.0",
"execa": "^5.1.1",

@@ -46,3 +46,3 @@ "external-editor": "^3.1.0",

"devDependencies": {
"@biomejs/biome": "1.5.3",
"@biomejs/biome": "^1.9.4",
"@types/fs-extra": "^11.0.4",

@@ -53,2 +53,3 @@ "@types/node": "^20.11.24",

"tsup": "^8.0.2",
"type-fest": "^4.39.1",
"typescript": "^5.3.3",

@@ -55,0 +56,0 @@ "vitest": "^1.3.1"