Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 65 additions & 39 deletions dist/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var __toESM = (mod, isNodeMode, target) => {
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
var __require = /* @__PURE__ */ createRequire(import.meta.url);

// ../../node_modules/commander/lib/error.js
// node_modules/commander/lib/error.js
var require_error = __commonJS((exports) => {
class CommanderError extends Error {
constructor(exitCode, code, message) {
Expand All @@ -57,7 +57,7 @@ var require_error = __commonJS((exports) => {
exports.InvalidArgumentError = InvalidArgumentError;
});

// ../../node_modules/commander/lib/argument.js
// node_modules/commander/lib/argument.js
var require_argument = __commonJS((exports) => {
var { InvalidArgumentError } = require_error();

Expand Down Expand Up @@ -136,7 +136,7 @@ var require_argument = __commonJS((exports) => {
exports.humanReadableArgName = humanReadableArgName;
});

// ../../node_modules/commander/lib/help.js
// node_modules/commander/lib/help.js
var require_help = __commonJS((exports) => {
var { humanReadableArgName } = require_argument();

Expand Down Expand Up @@ -385,7 +385,7 @@ var require_help = __commonJS((exports) => {
exports.Help = Help;
});

// ../../node_modules/commander/lib/option.js
// node_modules/commander/lib/option.js
var require_option = __commonJS((exports) => {
var { InvalidArgumentError } = require_error();

Expand Down Expand Up @@ -536,7 +536,7 @@ var require_option = __commonJS((exports) => {
exports.DualOptions = DualOptions;
});

// ../../node_modules/commander/lib/suggestSimilar.js
// node_modules/commander/lib/suggestSimilar.js
var require_suggestSimilar = __commonJS((exports) => {
var maxDistance = 3;
function editDistance(a, b) {
Expand Down Expand Up @@ -609,7 +609,7 @@ var require_suggestSimilar = __commonJS((exports) => {
exports.suggestSimilar = suggestSimilar;
});

// ../../node_modules/commander/lib/command.js
// node_modules/commander/lib/command.js
var require_command = __commonJS((exports) => {
var EventEmitter = __require("node:events").EventEmitter;
var childProcess = __require("node:child_process");
Expand Down Expand Up @@ -1852,7 +1852,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
exports.Command = Command;
});

// ../../node_modules/commander/index.js
// node_modules/commander/index.js
var require_commander = __commonJS((exports) => {
var { Argument } = require_argument();
var { Command } = require_command();
Expand All @@ -1878,7 +1878,7 @@ import { fileURLToPath } from "url";
import { dirname, join } from "path";
import { createInterface } from "readline/promises";

// ../../node_modules/commander/esm.mjs
// node_modules/commander/esm.mjs
var import__ = __toESM(require_commander(), 1);
var {
program,
Expand All @@ -1895,7 +1895,7 @@ var {
} = import__.default;

// src/install.ts
import fs from "fs/promises";
import fs2 from "fs/promises";

// src/utils/logger.ts
var c = {
Expand Down Expand Up @@ -1965,6 +1965,7 @@ var logger = new Logger;
// src/utils/paths.ts
import path from "path";
import os from "os";
import fs from "fs/promises";
function getHomeDir() {
if (process.env.HOME) {
return process.env.HOME;
Expand All @@ -1990,13 +1991,28 @@ function getConfig() {
function toGitPath(filePath) {
return filePath.replace(/\\/g, "/");
}
async function pathExists(filePath) {
try {
await fs.access(filePath);
return true;
} catch {
return false;
}
}

// src/pattern-catalog.json
var pattern_catalog_default = [
{
id: "claude",
signatureAliases: ["Claude", "Anthropic"],
authorTokens: ["claude", "claude code", "claude opus", "claude sonnet", "claude haiku", "anthropic"],
authorTokens: [
"claude",
"claude code",
"claude opus",
"claude sonnet",
"claude haiku",
"anthropic"
],
emails: ["noreply@anthropic.com", "claude@anthropic.com"]
},
{
Expand Down Expand Up @@ -2101,10 +2117,7 @@ function buildNamePattern(aliases) {
return `${CO_AUTHORED_BY_PREFIX}(?:${aliases.map(escapeRegex).join("|")}).*`;
}
function buildEmailPattern(emails, emailPatterns) {
const emailAlternatives = [
...emails.map(escapeRegex),
...emailPatterns
];
const emailAlternatives = [...emails.map(escapeRegex), ...emailPatterns];
return `${CO_AUTHORED_BY_PREFIX}.*\\b(?:${emailAlternatives.join("|")})\\b.*`;
}
var AI_SIGNATURE_CATALOG = pattern_catalog_default;
Expand Down Expand Up @@ -2280,6 +2293,11 @@ function createHookInstallPlan(options) {
]
};
}
var NOCO_HOOK_MARKERS = ["Generated by noco", "nococli:"];
var HOOK_BACKUP_EXT = ".bak";
function isNococliHook(content) {
return NOCO_HOOK_MARKERS.some((marker) => content.includes(marker));
}
function getPatternNames() {
return DEFAULT_AI_PATTERNS.map((pattern) => pattern.name);
}
Expand Down Expand Up @@ -2380,7 +2398,7 @@ async function install(options = {}) {
const platform = options.platform ?? process.platform;
try {
logger2.info("Creating git templates directory...");
await fs.mkdir(config.hooksDir, { recursive: true });
await fs2.mkdir(config.hooksDir, { recursive: true });
const powerShellRuntime = detectPowerShellRuntime(platform);
if (platform === "win32" && !powerShellRuntime) {
return {
Expand All @@ -2393,8 +2411,20 @@ async function install(options = {}) {
platform,
powerShellCommand: powerShellRuntime ?? undefined
});
if (!options.force) {
for (const file of installPlan.files) {
try {
const existingContent = await fs2.readFile(file.path, "utf8");
if (!isNococliHook(existingContent)) {
const backupPath = `${file.path}${HOOK_BACKUP_EXT}`;
await fs2.copyFile(file.path, backupPath);
logger2.warning(`Existing hook backed up to ${backupPath}`);
}
} catch {}
}
}
for (const file of installPlan.files) {
await fs.writeFile(file.path, file.content, {
await fs2.writeFile(file.path, file.content, {
mode: file.mode
});
logger2.success(`Hook file created at ${file.path}`);
Expand Down Expand Up @@ -2444,7 +2474,7 @@ async function install(options = {}) {
}

// src/uninstall.ts
import fs2 from "fs/promises";
import fs3 from "fs/promises";
async function uninstall(options = {}) {
const logger2 = new Logger(options.silent);
const config = getConfig();
Expand All @@ -2453,32 +2483,37 @@ async function uninstall(options = {}) {
try {
logger2.info("Removing hook file...");
try {
await fs2.unlink(config.hookFile);
await fs3.unlink(config.hookFile);
logger2.success(`Removed ${config.hookFile}`);
} catch {
logger2.info("Hook file not found (already removed?)");
}
try {
await fs2.unlink(config.powerShellHookFile);
await fs3.unlink(config.powerShellHookFile);
removedPowerShellHook = true;
logger2.success(`Removed ${config.powerShellHookFile}`);
} catch {
logger2.info("PowerShell hook file not found (already removed?)");
}
for (const hookPath of [config.hookFile, config.powerShellHookFile]) {
const backupPath = `${hookPath}${HOOK_BACKUP_EXT}`;
try {
await fs3.rename(backupPath, hookPath);
logger2.success(`Restored previous hook from ${backupPath}`);
} catch {}
}
try {
const hooksExists = await fs2.access(config.hooksDir).then(() => true).catch(() => false);
if (hooksExists) {
const files = await fs2.readdir(config.hooksDir);
if (await pathExists(config.hooksDir)) {
const files = await fs3.readdir(config.hooksDir);
if (files.length === 0) {
await fs2.rmdir(config.hooksDir);
await fs3.rmdir(config.hooksDir);
logger2.info("Removed empty hooks directory");
}
}
const templateExists = await fs2.access(config.templateDir).then(() => true).catch(() => false);
if (templateExists) {
const files = await fs2.readdir(config.templateDir);
if (await pathExists(config.templateDir)) {
const files = await fs3.readdir(config.templateDir);
if (files.length === 0) {
await fs2.rmdir(config.templateDir);
await fs3.rmdir(config.templateDir);
logger2.info("Removed empty templates directory");
}
}
Expand Down Expand Up @@ -2515,7 +2550,6 @@ async function uninstall(options = {}) {
}

// src/cli.ts
import { access } from "fs/promises";
var logger2 = new Logger;
var __dirname2 = dirname(fileURLToPath(import.meta.url));
var version = "0.0.0";
Expand All @@ -2536,14 +2570,6 @@ async function promptConfirm(message) {
rl.close();
return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
}
async function fileExists(filePath) {
try {
await access(filePath);
return true;
} catch {
return false;
}
}
async function runInstallCommand(options) {
const currentName = getGitUserName();
if (currentName.exists && currentName.value && isAIAuthor(currentName.value)) {
Expand Down Expand Up @@ -2574,7 +2600,7 @@ async function runInstallCommand(options) {
} else {
logger2.info("No existing template directory found");
}
const result = await install({ silent: options.silent });
const result = await install({ silent: options.silent, force: options.force });
if (!result.success) {
logger2.blank();
logger2.error(result.message);
Expand Down Expand Up @@ -2630,8 +2656,8 @@ program2.command("status").description("Check if noco is properly installed and
} else {
logger2.warning("Not installed");
}
const hookExists = await fileExists(config.hookFile);
const powerShellHookExists = await fileExists(config.powerShellHookFile);
const hookExists = await pathExists(config.hookFile);
const powerShellHookExists = await pathExists(config.powerShellHookFile);
if (hookExists) {
logger2.success("Hook entrypoint exists");
} else {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "nococli",
"version": "1.1.0",
"description": "Keep your code yours remove AI co-author signatures from git commits",
"description": "Keep your code yours -- remove AI co-author signatures from git commits",
"type": "module",
"bin": {
"noco": "./dist/cli.js"
Expand Down
Loading
Loading