@rmyndharis/aimhooman 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +19 -0
- package/README.md +1 -1
- package/bin/aimhooman.mjs +20 -3
- package/package.json +1 -1
- package/rules/secrets.json +3 -2
- package/src/githooks.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,25 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.4] - 2026-07-18
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Uninstall no longer leaves aimhooman artifacts in `.git`. Every atomic write takes a
|
|
13
|
+
lock whose `<lock>.queue` directory was created but never removed — the release path
|
|
14
|
+
only unlinked its own candidate file — and `--purge-state` cleared just the state
|
|
15
|
+
directory. So `.git` kept the queue directories and the `COMMIT_EDITMSG.aimhooman-bak`
|
|
16
|
+
attribution backup while the command printed "state purged". Uninstall now sweeps this
|
|
17
|
+
residue once the lifecycle lock releases; `rmdirSync` removes only an empty directory,
|
|
18
|
+
so a concurrent contender's queue is never touched, and the lifecycle queue is removable
|
|
19
|
+
precisely because its own lock has already released. A plain uninstall keeps policy
|
|
20
|
+
state and drops the operational residue; `--purge-state` leaves no aimhooman fingerprints.
|
|
21
|
+
- A bare AWS access key ID is now detected. `secret.aws-key-content` fired only when an
|
|
22
|
+
`aws_secret_access_key` or `aws_session_token` name sat beside the value, so an
|
|
23
|
+
`AKIA…`/`ASIA…` access key ID committed on its own passed clean. The rule now matches the
|
|
24
|
+
access-key-ID prefixes directly — the fixed-prefix, highest-confidence AWS indicator. The
|
|
25
|
+
16-character body and word boundaries keep short lookalikes such as `AKIA123` from matching.
|
|
26
|
+
|
|
8
27
|
## [0.1.3] - 2026-07-18
|
|
9
28
|
|
|
10
29
|
### Fixed
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
11
|
<img src="https://img.shields.io/github/actions/workflow/status/rmyndharis/aimhooman/test.yml?branch=main&label=CI" alt="CI">
|
|
12
|
-
<img src="https://img.shields.io/badge/version-v0.1.
|
|
12
|
+
<img src="https://img.shields.io/badge/version-v0.1.4-blue" alt="v0.1.4">
|
|
13
13
|
<img src="https://img.shields.io/badge/node-%E2%89%A522.8-339933?logo=node.js&logoColor=white" alt="Node 22.8+">
|
|
14
14
|
<img src="https://img.shields.io/badge/dependencies-0-brightgreen" alt="Zero dependencies">
|
|
15
15
|
<img src="https://img.shields.io/badge/license-MIT-111111" alt="MIT">
|
package/bin/aimhooman.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execFileSync } from 'node:child_process';
|
|
3
|
-
import { chmodSync, lstatSync, readFileSync, rmSync } from 'node:fs';
|
|
3
|
+
import { chmodSync, lstatSync, readFileSync, rmdirSync, rmSync } from 'node:fs';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { GIT_TIMEOUT_MS } from '../src/git-environment.mjs';
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from '../src/gitx.mjs';
|
|
21
21
|
import { loadConfig, loadOverrides, loadProjectPolicy, normalizeOverrideTarget, saveConfig, saveOverrides } from '../src/state.mjs';
|
|
22
22
|
import { applyExclude, inspectExclude, patternsForRules, removeExclude } from '../src/exclude.mjs';
|
|
23
|
-
import { hookDiagnostics, installHooks, installGlobalHooks, uninstallGlobalHooks, globalHooksDir, installedHooks, remainingDispatchers, uninstallHooks, unrestoredChainedBackups } from '../src/githooks.mjs';
|
|
23
|
+
import { effectiveHooksDir, hookDiagnostics, installHooks, installGlobalHooks, uninstallGlobalHooks, globalHooksDir, installedHooks, remainingDispatchers, uninstallHooks, unrestoredChainedBackups } from '../src/githooks.mjs';
|
|
24
24
|
import { ArgumentError, parseArguments } from '../src/args.mjs';
|
|
25
25
|
import { engineForPolicy, scanGitTarget, scanMessage } from '../src/scan-target.mjs';
|
|
26
26
|
import { resolvePolicy } from '../src/policy-resolver.mjs';
|
|
@@ -1615,7 +1615,8 @@ function cmdUninstall(args) {
|
|
|
1615
1615
|
console.error('aimhooman: not a git repository');
|
|
1616
1616
|
return 30;
|
|
1617
1617
|
}
|
|
1618
|
-
|
|
1618
|
+
const lifecycleLock = join(repo.commonDir, 'aimhooman-lifecycle.lock');
|
|
1619
|
+
const exitStatus = withLock(lifecycleLock, () => {
|
|
1619
1620
|
const rep = uninstallHooks(repo);
|
|
1620
1621
|
// The irreversible work is already done above, and the report is still
|
|
1621
1622
|
// below. A throw from here unwound past all of it, so a damaged marker was
|
|
@@ -1683,6 +1684,22 @@ function cmdUninstall(args) {
|
|
|
1683
1684
|
// the uninstall is genuinely incomplete and 30 is the honest answer.
|
|
1684
1685
|
return remaining.length || rep.failures?.length || unrestored.length || excludeFailure ? 30 : 0;
|
|
1685
1686
|
}, LIFECYCLE_LOCK_OPTIONS);
|
|
1687
|
+
// Sweep the operational residue the guard authored in .git, so uninstall leaves
|
|
1688
|
+
// no aimhooman fingerprints behind — the same tooling residue this tool exists
|
|
1689
|
+
// to remove. rmdirSync deletes only an empty directory, so a live contender's
|
|
1690
|
+
// queue is never touched; the lifecycle queue becomes removable only now, after
|
|
1691
|
+
// its own lock above has released.
|
|
1692
|
+
for (const queue of [
|
|
1693
|
+
`${lifecycleLock}.queue`,
|
|
1694
|
+
`${repo.excludeFile}.aimhooman.lock.queue`,
|
|
1695
|
+
join(effectiveHooksDir(repo), '.aimhooman-hooks.lock.queue'),
|
|
1696
|
+
]) {
|
|
1697
|
+
try { rmdirSync(queue); } catch { /* held by another aimhooman, or already gone */ }
|
|
1698
|
+
}
|
|
1699
|
+
// A one-commit-ago attribution backup that git's next COMMIT_EDITMSG makes stale.
|
|
1700
|
+
try { rmSync(join(repo.commonDir, 'COMMIT_EDITMSG.aimhooman-bak'), { force: true }); }
|
|
1701
|
+
catch { /* nothing to remove */ }
|
|
1702
|
+
return exitStatus;
|
|
1686
1703
|
}
|
|
1687
1704
|
|
|
1688
1705
|
function usage() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rmyndharis/aimhooman",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "AI works. Hoomans ship. Keep AI session files, secrets, and attribution out of your commits.",
|
|
5
5
|
"homepage": "https://github.com/rmyndharis/aimhooman#readme",
|
|
6
6
|
"repository": {
|
package/rules/secrets.json
CHANGED
|
@@ -45,14 +45,15 @@
|
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"id": "secret.aws-key-content",
|
|
48
|
-
"version":
|
|
48
|
+
"version": 2,
|
|
49
49
|
"provider": "aws",
|
|
50
50
|
"category": "secret",
|
|
51
51
|
"confidence": "high",
|
|
52
52
|
"kind": "code",
|
|
53
53
|
"match": {
|
|
54
54
|
"content": [
|
|
55
|
-
"(?i)\\baws_(?:secret_access_key|session_token)\\b\\s*[:=]\\s*[\\\"']?[A-Za-z0-9/+=]{32,}(?![A-Za-z0-9/+=])"
|
|
55
|
+
"(?i)\\baws_(?:secret_access_key|session_token)\\b\\s*[:=]\\s*[\\\"']?[A-Za-z0-9/+=]{32,}(?![A-Za-z0-9/+=])",
|
|
56
|
+
"\\b(?:AKIA|ASIA)[A-Z0-9]{16}\\b"
|
|
56
57
|
]
|
|
57
58
|
},
|
|
58
59
|
"actions": {
|
package/src/githooks.mjs
CHANGED
|
@@ -124,7 +124,7 @@ function canonicalPath(path) {
|
|
|
124
124
|
|
|
125
125
|
// Ask Git for the path it actually uses. In a linked worktree this resolves to
|
|
126
126
|
// the common repository hooks directory, not <gitDir>/hooks.
|
|
127
|
-
function effectiveHooksDir(repo) {
|
|
127
|
+
export function effectiveHooksDir(repo) {
|
|
128
128
|
try {
|
|
129
129
|
return execFileSync(
|
|
130
130
|
'git',
|