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.11

324

dist/index.js
#!/usr/bin/env node
// src/index.ts
import { getPackageInfo, storage as storage10 } from "@offlegacy/git-intent-core";
import { program } from "commander";
// src/utils/storage.ts
import path3 from "node:path";
import fs3 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 fs from "fs-extra";
function getPackageInfo() {
const possiblePaths = [
path.resolve(__dirname, "../../package.json"),
path.resolve(__dirname, "../package.json"),
path.resolve(process.cwd(), "package.json")
];
for (const packageJsonPath of possiblePaths) {
try {
if (fs.existsSync(packageJsonPath)) {
const packageJson = fs.readJSONSync(packageJsonPath);
if (packageJson.name === "git-intent") {
return {
version: packageJson.version || "0.0.0",
description: packageJson.description || "Git Intent CLI"
};
}
}
} catch (error) {
}
}
return {
version: "0.0.0",
description: "Git Intent CLI"
};
}
// src/utils/git.ts
import { spawnSync } from "node:child_process";
import path2 from "node:path";
import fs2 from "fs-extra";
import { simpleGit } from "simple-git";
function execGit(args, options = {}) {
const { input, cwd } = options;
const result = spawnSync("git", args, {
input: input ? Buffer.from(input) : void 0,
cwd,
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"]
});
if (result.status !== 0) {
throw new Error(`Git command failed: git ${args.join(" ")}
${result.stderr}`);
}
return result.stdout ? result.stdout.trim() : "";
}
var createGit = (cwd) => simpleGit(cwd);
async function findGitRoot(startDir = process.cwd()) {
const dir = path2.resolve(startDir);
const gitDir = path2.join(dir, ".git");
if (fs2.existsSync(gitDir) && fs2.statSync(gitDir).isDirectory()) {
return dir;
}
const parentDir = path2.dirname(dir);
if (parentDir === dir) {
throw new Error("Not a git repository (or any of the parent directories)");
}
return findGitRoot(parentDir);
}
async function checkIsRepo(cwd) {
try {
const git = createGit(cwd);
await git.checkIsRepo();
return await findGitRoot(cwd);
} catch {
try {
return await findGitRoot(cwd);
} catch (error) {
throw new Error("Not a git repository (or any of the parent directories)");
}
}
}
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;
}
async function hashObject(content, cwd) {
return execGit(["hash-object", "-w", "--stdin"], { input: content, cwd });
}
async function createTree(treeContent, cwd) {
if (!treeContent || treeContent.trim() === "") {
throw new Error("Invalid tree content: tree content cannot be empty");
}
return execGit(["mktree"], { input: treeContent, cwd });
}
async function createCommitTree(treeHash, message, cwd) {
if (!treeHash || treeHash.trim() === "") {
throw new Error("Invalid tree hash: tree hash cannot be empty");
}
try {
const result = execGit(["commit-tree", treeHash, "-m", message], { cwd });
if (!result || result.trim() === "") {
throw new Error(`Failed to create commit tree from hash: ${treeHash}`);
}
return result;
} catch (error) {
console.error("Error creating commit tree:", error);
throw error;
}
}
async function updateRef(refName, commitHash, cwd) {
if (!commitHash || commitHash.trim() === "") {
throw new Error(`Invalid commit hash: commit hash cannot be empty for ref ${refName}`);
}
const git = createGit(cwd);
await git.raw(["update-ref", refName, commitHash]);
}
async function deleteRef(refName, cwd) {
const git = createGit(cwd);
await git.raw(["update-ref", "-d", refName]);
}
async function checkRefExists(refName, cwd) {
const git = createGit(cwd);
try {
await git.raw(["show-ref", "--verify", refName]);
return true;
} catch {
return false;
}
}
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 path3.join(root, this.GIT_DIR, "intentional-commits");
}
async getCommitsFile() {
const commitsDir = await this.getCommitsDir();
return path3.join(commitsDir, "commits.json");
}
getInitialData() {
return {
version: getPackageInfo().version,
commits: []
};
}
async ensureCommitsDir() {
const commitsDir = await this.getCommitsDir();
const commitsFile = await this.getCommitsFile();
await fs3.ensureDir(commitsDir);
try {
await fs3.access(commitsFile);
} catch {
await fs3.writeJSON(commitsFile, this.getInitialData());
}
}
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));
return data.commits;
} catch {
const commitsFile = await this.getCommitsFile();
const data = this.migrateData(await fs3.readJSON(commitsFile));
return data.commits;
}
}
async saveCommitsData(data) {
const root = await this.getGitRoot();
const commitsFile = await this.getCommitsFile();
const content = JSON.stringify(data, null, 2);
const hash = await hashObject(content, root);
const treeContent = `100644 blob ${hash} ${this.storageFilename}
`;
const treeHash = await createTree(treeContent, root);
const commitHash = await createCommitTree(treeHash, "Update intent commits", root);
await updateRef(`${this.REFS_PREFIX}/commits`, commitHash, root);
await fs3.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 newCommit = { ...commit2, id: newCommitId };
const data = {
version: getPackageInfo().version,
commits: [...currentCommits, newCommit]
};
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 fs3.remove(commitsFile);
await deleteRef(`${this.REFS_PREFIX}/commits`, root);
}
async initializeRefs() {
const root = await this.getGitRoot();
await checkIsRepo(root);
const refExists = await checkRefExists(`${this.REFS_PREFIX}/commits`, root);
if (!refExists) {
const initialData = this.getInitialData();
const content = JSON.stringify(initialData, null, 2);
const hash = await hashObject(content, root);
const treeContent = `100644 blob ${hash} ${this.storageFilename}
`;
const treeHash = await createTree(treeContent, root);
const commitHash = await createCommitTree(treeHash, "Initialize intent commits", root);
if (!commitHash || commitHash.trim() === "") {
throw new Error("Failed to create commit: commit hash is empty");
}
await updateRef(`${this.REFS_PREFIX}/commits`, commitHash, root);
}
}
};
var storage = GitIntentionalCommitStorage.getInstance();
// src/commands/list.ts
import { storage } from "@offlegacy/git-intent-core";
import chalk from "chalk";

@@ -307,2 +31,3 @@ import { Command } from "commander";

// src/commands/start.ts
import { git, storage as storage2 } from "@offlegacy/git-intent-core";
import chalk2 from "chalk";

@@ -312,3 +37,3 @@ import { Command as Command2 } from "commander";

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();
const commits = await storage2.loadCommits();
let selectedId = id;

@@ -345,7 +70,7 @@ if (!selectedId) {

}
const currentBranch = await getCurrentBranch();
const currentBranch = await git.getCurrentBranch();
targetCommit.status = "in_progress";
targetCommit.metadata.startedAt = (/* @__PURE__ */ new Date()).toISOString();
targetCommit.metadata.branch = currentBranch;
await storage.saveCommits(commits);
await storage2.saveCommits(commits);
console.log(chalk2.green("\u2713 Started working on:"));

@@ -358,6 +83,7 @@ console.log(`ID: ${chalk2.blue(targetCommit.id)}`);

// src/commands/show.ts
import { storage as storage3 } from "@offlegacy/git-intent-core";
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 commits = await storage3.loadCommits();
const currentCommit = commits.find((c) => c.status === "in_progress");

@@ -377,6 +103,7 @@ if (!currentCommit) {

// src/commands/commit.ts
import { git as git2, storage as storage4 } from "@offlegacy/git-intent-core";
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 commits = await storage4.loadCommits();
const currentCommit = commits.find((c) => c.status === "in_progress");

@@ -390,4 +117,4 @@ if (!currentCommit) {

${options.message}` : currentCommit.message;
await createCommit(message);
await storage.deleteCommit(currentCommit.id);
await git2.createCommit(message);
await storage4.deleteCommit(currentCommit.id);
console.log(chalk4.green("\u2713 Intention completed and committed"));

@@ -398,2 +125,3 @@ });

// src/commands/drop.ts
import { storage as storage5 } from "@offlegacy/git-intent-core";
import chalk5 from "chalk";

@@ -403,6 +131,6 @@ import { Command as Command5 } from "commander";

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 commits = await storage5.loadCommits();
const createdCommits = commits.filter((c) => c.status === "created");
if (options.all) {
await storage.saveCommits([]);
await storage5.saveCommits([]);
console.log(chalk5.green("\u2713 All created intents removed"));

@@ -442,3 +170,3 @@ return;

const updatedCommits = commits.filter((c) => c.id !== selectedId);
await storage.saveCommits(updatedCommits);
await storage5.saveCommits(updatedCommits);
console.log(chalk5.green("\u2713 Intent removed:"));

@@ -451,2 +179,3 @@ console.log(`ID: ${chalk5.blue(targetCommit.id)}`);

// src/commands/cancel.ts
import { storage as storage6 } from "@offlegacy/git-intent-core";
import chalk6 from "chalk";

@@ -456,3 +185,3 @@ import { Command as Command6 } from "commander";

var cancel = new Command6().command("cancel").description("Cancel current intention").action(async () => {
const commits = await storage.loadCommits();
const commits = await storage6.loadCommits();
const currentCommit = commits.find((c) => c.status === "in_progress");

@@ -485,3 +214,3 @@ if (!currentCommit) {

}
await storage.saveCommits(updatedCommits);
await storage6.saveCommits(updatedCommits);
console.log(`ID: ${chalk6.blue(currentCommit.id)}`);

@@ -494,2 +223,3 @@ console.log(`Message: ${currentCommit.message}`);

// src/commands/reset.ts
import { storage as storage7 } from "@offlegacy/git-intent-core";
import { Command as Command7 } from "commander";

@@ -507,3 +237,3 @@ import prompts4 from "prompts";

}
await storage.clearCommits();
await storage7.clearCommits();
console.log("All intents reset");

@@ -514,2 +244,3 @@ });

// src/commands/divide.ts
import { storage as storage8 } from "@offlegacy/git-intent-core";
import chalk7 from "chalk";

@@ -520,3 +251,3 @@ import { Command as Command8 } from "commander";

var divide = new Command8().command("divide").description("Divide an intent into smaller parts").action(async () => {
const commits = await storage.loadCommits();
const commits = await storage8.loadCommits();
if (commits.length === 0) {

@@ -664,3 +395,3 @@ console.log("No intents found to divide");

for (const task of tasks) {
const newCommitId = await storage.addCommit({
const newCommitId = await storage8.addCommit({
message: task,

@@ -675,3 +406,3 @@ status: "created",

if (shouldRemoveOriginal) {
await storage.deleteCommit(targetCommit.id);
await storage8.deleteCommit(targetCommit.id);
}

@@ -692,2 +423,3 @@ console.log(chalk7.green("\u2713 Successfully divided the commit:"));

// src/commands/add.ts
import { storage as storage9 } from "@offlegacy/git-intent-core";
import chalk8 from "chalk";

@@ -708,3 +440,3 @@ import { Command as Command9 } from "commander";

}
const newCommitId = await storage.addCommit({
const newCommitId = await storage9.addCommit({
message: commitMessage,

@@ -724,3 +456,3 @@ status: "created",

(async () => {
await storage.initializeRefs();
await storage10.initializeRefs();
const { version, description } = getPackageInfo();

@@ -727,0 +459,0 @@ 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);

24

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

@@ -37,18 +37,9 @@ "keywords": [

"external-editor": "^3.1.0",
"fs-extra": "^11.3.0",
"nanoid": "^3.3.7",
"ora": "^5.4.1",
"ora": "^8.2.0",
"prompts": "^2.4.2",
"simple-git": "^3.27.0"
"@offlegacy/git-intent-core": "0.0.11"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@types/fs-extra": "^11.0.4",
"@types/node": "^20.11.24",
"@types/prompts": "^2.4.9",
"pkg": "^5.8.1",
"tsup": "^8.0.2",
"type-fest": "^4.39.1",
"typescript": "^5.3.3",
"vitest": "^1.3.1"
"pkg": "^5.8.1"
},

@@ -58,9 +49,6 @@ "scripts": {

"build": "tsup",
"start": "node dist/index.js",
"start": "node dist/index.cjs",
"format": "biome format",
"format:fix": "biome format --write",
"pkg:build": "pnpm pkg:build:macos && pnpm pkg:build:linux && pnpm pkg:build:win",
"pkg:build:macos": "pkg . --no-bytecode -t node18-macos-arm64 -o build/git-intent-macos",
"pkg:build:linux": "pkg . --no-bytecode -t node18-linux-x64 -o build/git-intent-linux",
"pkg:build:win": "pkg . --no-bytecode -t node18-win-x64 -o build/git-intent-win.exe",
"pkg:build:macos": "pnpm build && pkg . --no-bytecode -t node18-macos-arm64 -o build/git-intent-macos",
"test": "vitest",

@@ -67,0 +55,0 @@ "test:ui": "vitest --ui"

Sorry, the diff of this file is not supported yet