claude-nomad 0.60.0 → 0.62.0
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/.gitleaks.toml +58 -16
- package/CHANGELOG.md +38 -0
- package/README.md +48 -0
- package/dist/nomad.mjs +1141 -441
- package/package.json +2 -2
package/.gitleaks.toml
CHANGED
|
@@ -6,28 +6,53 @@
|
|
|
6
6
|
[extend]
|
|
7
7
|
useDefault = true
|
|
8
8
|
|
|
9
|
-
# Path-scoped:
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
# token-anchored with `\b` on both ends, so
|
|
20
|
-
#
|
|
9
|
+
# Path-scoped: the bare Sonar-issue-key shape (`AY` + 17-22 base64url chars) is
|
|
10
|
+
# a CONTEXT-FREE token pattern. Unlike the three structural noise shapes below
|
|
11
|
+
# it carries no surrounding structure (no `:rule:line`, no `"id":`, no `key=`
|
|
12
|
+
# prefix), so it cannot be distinguished from a real `AY`-prefixed high-entropy
|
|
13
|
+
# credential of the same length. It is therefore scoped to synced session
|
|
14
|
+
# transcripts ONLY (`shared/projects/<logical>/.../*.jsonl`), NOT to
|
|
15
|
+
# `shared/skills/**`: a skill file is executable, curated content a user pastes
|
|
16
|
+
# real values into, so an `AY`-shaped credential dropped into a skill MUST still
|
|
17
|
+
# fire. `condition = "AND"` confines the suppression to transcripts: a real
|
|
18
|
+
# secret in a source file still fires. The regex is length-bounded to the real
|
|
19
|
+
# key shape and token-anchored with `\b` on both ends, so even inside a
|
|
20
|
+
# transcript it cannot suppress a longer or embedded `AY`-prefixed credential as
|
|
21
|
+
# a substring (an unbounded `{20,}` could).
|
|
21
22
|
[[allowlists]]
|
|
22
|
-
description = "claude-nomad:
|
|
23
|
+
description = "claude-nomad: Sonar issue-key token shape (AY-prefixed) in synced session transcripts only, NOT skills"
|
|
23
24
|
regexes = [
|
|
24
25
|
'''\bAY[A-Za-z0-9_-]{17,22}\b''',
|
|
26
|
+
]
|
|
27
|
+
paths = [
|
|
28
|
+
'''^shared/projects/[^/]+/.*\.jsonl$''',
|
|
29
|
+
]
|
|
30
|
+
condition = "AND"
|
|
31
|
+
|
|
32
|
+
# Path-scoped: this tool-output noise (gitleaks fingerprints, coverage
|
|
33
|
+
# line-keys, npm audit JSON id hashes) accumulates in Claude Code session
|
|
34
|
+
# transcripts when a conversation runs those tools. Each of these three regexes
|
|
35
|
+
# carries structural context (`<path>.<ext>:<rule>:<line>`, `"id":"<hex>"`, or
|
|
36
|
+
# `key=<hex> <path>:<line>`) that a bare credential does not, so widening them
|
|
37
|
+
# to skill content cannot mask a context-free secret token. Scoping to
|
|
38
|
+
# `shared/projects/<logical>/.../*.jsonl` with `condition = "AND"` (matching
|
|
39
|
+
# every other block below) confines the suppression to synced transcripts: a
|
|
40
|
+
# real secret in a source file still fires. Also scoped (recursively) to
|
|
41
|
+
# `shared/skills/<name>/**`: curated, portable skill content can legitimately
|
|
42
|
+
# embed the same structured tool-output noise shapes (e.g. a skill doc pasting
|
|
43
|
+
# an example npm-audit or coverage dump), and the structural anchor keeps the
|
|
44
|
+
# false-negative risk low in that tree too. The bare `AY` shape is deliberately
|
|
45
|
+
# NOT in this block (see the transcript-only block above).
|
|
46
|
+
[[allowlists]]
|
|
47
|
+
description = "claude-nomad: structurally-anchored tool-output noise in synced session transcripts and skills"
|
|
48
|
+
regexes = [
|
|
25
49
|
'''[\w./-]+\.[A-Za-z0-9]+:[\w-]+:\d+''',
|
|
26
50
|
'''"id"\s*:\s*"[a-f0-9]{40,64}"''',
|
|
27
51
|
'''key=[a-f0-9]{8,} [\w./-]+\.\w+:\d+''',
|
|
28
52
|
]
|
|
29
53
|
paths = [
|
|
30
54
|
'''^shared/projects/[^/]+/.*\.jsonl$''',
|
|
55
|
+
'''^shared/skills/[^/]+/.*$''',
|
|
31
56
|
]
|
|
32
57
|
condition = "AND"
|
|
33
58
|
|
|
@@ -41,7 +66,11 @@ condition = "AND"
|
|
|
41
66
|
# false-positive handler is a narrow allowlist scoped to synced session
|
|
42
67
|
# paths. `condition = "AND"` requires BOTH a known literal AND a
|
|
43
68
|
# `shared/projects/<logical>/.../*.jsonl` path; a real PAT in the same
|
|
44
|
-
# file (different 36-char body) still fires.
|
|
69
|
+
# file (different 36-char body) still fires. Also scoped to
|
|
70
|
+
# `shared/projects/<logical>/memory/*.md`: these exact literals legitimately
|
|
71
|
+
# appear in curated memory prose that discusses the fixture pattern itself
|
|
72
|
+
# (e.g. a memory note documenting this allowlist), and the exact-literal match
|
|
73
|
+
# carries no false-negative risk there either.
|
|
45
74
|
[[allowlists]]
|
|
46
75
|
description = "claude-nomad: documented test-fixture github-pat literals + scrub placeholders in synced session transcripts"
|
|
47
76
|
regexes = [
|
|
@@ -52,6 +81,7 @@ regexes = [
|
|
|
52
81
|
]
|
|
53
82
|
paths = [
|
|
54
83
|
'''^shared/projects/[^/]+/.*\.jsonl$''',
|
|
84
|
+
'''^shared/projects/[^/]+/memory/[^/]+\.md$''',
|
|
55
85
|
]
|
|
56
86
|
condition = "AND"
|
|
57
87
|
|
|
@@ -64,7 +94,13 @@ condition = "AND"
|
|
|
64
94
|
# regexTarget = "line") keeps this from whitelisting a bare token: a real
|
|
65
95
|
# secret is never preceded by an SSH key-type label and the SHA256: scheme
|
|
66
96
|
# prefix. `condition = "AND"` plus the session-jsonl path scope double-locks
|
|
67
|
-
# it to synced transcripts.
|
|
97
|
+
# it to synced transcripts. Also scoped to `shared/projects/<logical>/memory/*.md`:
|
|
98
|
+
# this is plausible content in a curated memory note documenting a commit
|
|
99
|
+
# signature-verification procedure, and the structural `with <keytype> key
|
|
100
|
+
# SHA256:` anchor keeps the false-negative risk low there too. Also scoped
|
|
101
|
+
# (recursively) to `shared/skills/<name>/**`: a skill documenting a
|
|
102
|
+
# signature-verification procedure can plausibly quote the same fingerprint
|
|
103
|
+
# line shape, with the same low false-negative risk.
|
|
68
104
|
[[allowlists]]
|
|
69
105
|
description = "claude-nomad: SSH public-key fingerprints (with <keytype> key SHA256:<b64>) in git signature output in synced session transcripts"
|
|
70
106
|
regexTarget = "line"
|
|
@@ -73,6 +109,8 @@ regexes = [
|
|
|
73
109
|
]
|
|
74
110
|
paths = [
|
|
75
111
|
'''^shared/projects/[^/]+/.*\.jsonl$''',
|
|
112
|
+
'''^shared/projects/[^/]+/memory/[^/]+\.md$''',
|
|
113
|
+
'''^shared/skills/[^/]+/.*$''',
|
|
76
114
|
]
|
|
77
115
|
condition = "AND"
|
|
78
116
|
|
|
@@ -84,7 +122,10 @@ condition = "AND"
|
|
|
84
122
|
# above keys on. Anchoring on the surrounding `key:`/`rule:` structure (via
|
|
85
123
|
# regexTarget = "line") keeps this from whitelisting a bare token: a real API
|
|
86
124
|
# key is never followed by `\n rule: <lang>:S####`. `condition = "AND"` plus
|
|
87
|
-
# the session-jsonl path scope double-locks it to synced transcripts.
|
|
125
|
+
# the session-jsonl path scope double-locks it to synced transcripts. Also
|
|
126
|
+
# scoped (recursively) to `shared/skills/<name>/**`: a skill documenting a
|
|
127
|
+
# SonarCloud triage procedure can plausibly quote the same issue-listing
|
|
128
|
+
# pair shape, with the same low false-negative risk.
|
|
88
129
|
[[allowlists]]
|
|
89
130
|
description = "claude-nomad: SonarCloud issue-listing output (key: <id> / rule: <lang>:S<n>) in synced session transcripts"
|
|
90
131
|
regexTarget = "line"
|
|
@@ -93,5 +134,6 @@ regexes = [
|
|
|
93
134
|
]
|
|
94
135
|
paths = [
|
|
95
136
|
'''^shared/projects/[^/]+/.*\.jsonl$''',
|
|
137
|
+
'''^shared/skills/[^/]+/.*$''',
|
|
96
138
|
]
|
|
97
139
|
condition = "AND"
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.62.0](https://github.com/funkadelic/claude-nomad/compare/v0.61.0...v0.62.0) (2026-07-18)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
* **crash-handler:** redacted crash reports for unexpected errors ([#433](https://github.com/funkadelic/claude-nomad/issues/433)) ([cb2d23c](https://github.com/funkadelic/claude-nomad/commit/cb2d23c16165b0004a8769a8ab5c60af026c9577))
|
|
9
|
+
* **exit-codes:** documented exit-code contract for scripted callers ([#432](https://github.com/funkadelic/claude-nomad/issues/432)) ([890e6a2](https://github.com/funkadelic/claude-nomad/commit/890e6a2a28d37e6559f7167ae57c695b4d1337f5))
|
|
10
|
+
* **push:** handle shared/skills secrets at parity with sessions and memory ([#431](https://github.com/funkadelic/claude-nomad/issues/431)) ([759262c](https://github.com/funkadelic/claude-nomad/commit/759262c52aeaf4e2913fc1421ccd90260327c882))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Dependencies
|
|
14
|
+
|
|
15
|
+
* bump markdownlint-cli2 from 0.23.0 to 0.23.1 ([#434](https://github.com/funkadelic/claude-nomad/issues/434)) ([68c6402](https://github.com/funkadelic/claude-nomad/commit/68c6402cea2dbc3a8f9c1eb8fd8db0a416005a53))
|
|
16
|
+
|
|
17
|
+
## [0.61.0](https://github.com/funkadelic/claude-nomad/compare/v0.60.0...v0.61.0) (2026-07-17)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
* **push:** handle memory/*.md secrets at parity with session transcripts ([#427](https://github.com/funkadelic/claude-nomad/issues/427)) ([d1e544c](https://github.com/funkadelic/claude-nomad/commit/d1e544c4f402dae80e319c62ed1fae903fef6e4b))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
* **publish:** checkout in smoke-test so setup-node can read .nvmrc ([#424](https://github.com/funkadelic/claude-nomad/issues/424)) ([3d8fd2c](https://github.com/funkadelic/claude-nomad/commit/3d8fd2c66ba7947a9326c46f997c336793786efc))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Documentation
|
|
31
|
+
|
|
32
|
+
* correct release-bump, Stryker HOME, and offboarding details ([#429](https://github.com/funkadelic/claude-nomad/issues/429)) ([bb5f0fe](https://github.com/funkadelic/claude-nomad/commit/bb5f0fede4cafb848609134bbd1581ac62d42f2c))
|
|
33
|
+
* drop redundant overview file tree in how-it-works ([#428](https://github.com/funkadelic/claude-nomad/issues/428)) ([dd795c8](https://github.com/funkadelic/claude-nomad/commit/dd795c831b876be3ed6bfe1b1313c8ce8f108715))
|
|
34
|
+
* **site:** show claude-nomad version badge in the header ([#430](https://github.com/funkadelic/claude-nomad/issues/430)) ([18d5e86](https://github.com/funkadelic/claude-nomad/commit/18d5e864cd5579d79a79fdd8060352afedcc32fe))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Testing
|
|
38
|
+
|
|
39
|
+
* **integration:** cover recovery, sync, dry-run, manifest, and eject flows ([#426](https://github.com/funkadelic/claude-nomad/issues/426)) ([c9c5223](https://github.com/funkadelic/claude-nomad/commit/c9c5223117426439ad57e2442137891c379af1f7))
|
|
40
|
+
|
|
3
41
|
## [0.60.0](https://github.com/funkadelic/claude-nomad/compare/v0.59.0...v0.60.0) (2026-07-15)
|
|
4
42
|
|
|
5
43
|
|
package/README.md
CHANGED
|
@@ -45,6 +45,9 @@ survives different file paths and your secrets never ride along.
|
|
|
45
45
|
entirely and can leak a secret that `nomad push` would have caught. Steady-state pushes scan only
|
|
46
46
|
the transcripts that changed since the last successful push (incremental); a cold start, a
|
|
47
47
|
gitleaks version change, a config file change, or `--full-scan` forces a full rescan.
|
|
48
|
+
`nomad doctor --check-shared` also runs a read-only advisory over memory notes and skill files
|
|
49
|
+
already synced to the repo, flagging (but never blocking on) a secret that already made it through
|
|
50
|
+
in a past push; the fix is the same interactive Redact step `nomad push` offers.
|
|
48
51
|
- **Preview before you trust it.** `nomad diff` shows offline what a pull would change (gsd-owned
|
|
49
52
|
hook churn is filtered the same as on pull, so the preview matches what a real pull writes), and
|
|
50
53
|
`--dry-run` on pull and push prints the plan without writing anything.
|
|
@@ -297,6 +300,51 @@ version-staleness check and `nomad doctor --check-schema`. The CLI works without
|
|
|
297
300
|
curl or wget needed) and verifies that `shared/` and a valid `path-map.json` are present there; it
|
|
298
301
|
skips with a `⚠︎` when the ref is unavailable, and is non-fatal in all cases.
|
|
299
302
|
|
|
303
|
+
## Exit codes
|
|
304
|
+
|
|
305
|
+
Every `nomad` subcommand exits with one of a small set of codes, so a script or cron wrapper can
|
|
306
|
+
branch on `$?` without parsing stderr text.
|
|
307
|
+
|
|
308
|
+
| Code | Name | Meaning |
|
|
309
|
+
| ---- | --------------- | ------------------------------------------------------------------------------------ |
|
|
310
|
+
| 0 | Success | Completed successfully. |
|
|
311
|
+
| 1 | Generic failure | Unclassified failure; the default for any error not covered below. |
|
|
312
|
+
| 2 | Usage | Bad argv: an unknown subcommand, an unknown flag, or a malformed flag value. |
|
|
313
|
+
| 4 | Conflict | The sync repo is wedged (e.g. an unresolved rebase) and needs manual git resolution. |
|
|
314
|
+
| 5 | Leak blocked | gitleaks confirmed a secret in the staged tree and the push was aborted. |
|
|
315
|
+
|
|
316
|
+
A run skipped because another nomad process already holds the lock also exits 0: this is an
|
|
317
|
+
intentional no-op skip, not a failure, so a backgrounded shell-rc or cron invocation never raises a
|
|
318
|
+
false alarm from a concurrent run. Value `3` is reserved for future use.
|
|
319
|
+
|
|
320
|
+
## Crash reports
|
|
321
|
+
|
|
322
|
+
If `nomad` ever hits an unexpected bug, it no longer dumps a raw stack trace at you. Instead it
|
|
323
|
+
prints a short "this looks like a bug" banner (with a link to the issue tracker) and writes a small
|
|
324
|
+
report you can attach to a bug report if you choose. The exit code is unchanged: an unexpected crash
|
|
325
|
+
exits `1`, and a documented failure still exits with its own code from the table above.
|
|
326
|
+
|
|
327
|
+
What this means for you:
|
|
328
|
+
|
|
329
|
+
- **The report stays on your machine.** It is written to `~/.cache/claude-nomad/crash/` and nothing
|
|
330
|
+
is ever uploaded anywhere. The file just sits there until you decide to share it or delete it.
|
|
331
|
+
- **The saved report is scrubbed twice.** First a structural pass rewrites your home directory to
|
|
332
|
+
`~` and your hostname to a placeholder (absolute paths are personal information a secret scanner
|
|
333
|
+
would not catch). Then a best-effort secret scan runs the same gitleaks-based redaction nomad
|
|
334
|
+
already uses for session transcripts. The secret scan works on a temporary, owner-only (`0o600`)
|
|
335
|
+
copy that already has the structural scrub applied; that scratch file is deleted immediately after
|
|
336
|
+
the scan, and only the fully-redacted report is kept.
|
|
337
|
+
- **It degrades safely without gitleaks.** If gitleaks is not installed, the structural scrub still
|
|
338
|
+
runs and the report is still written, with a one-line note that the secret scan did not run, so
|
|
339
|
+
give it a glance before posting it publicly.
|
|
340
|
+
- **It is small and bounded.** The report contains only the nomad version, the command you ran
|
|
341
|
+
(bounded, and including any flag values you typed), the error name and message, a trimmed stack,
|
|
342
|
+
your platform, the Node.js version, and a timestamp. It never includes an environment dump or the
|
|
343
|
+
contents of any file.
|
|
344
|
+
- **The directory manages itself.** Only the most recent reports are kept; older ones are pruned
|
|
345
|
+
automatically on the next crash. There is no `nomad clean` flag for the crash directory, by
|
|
346
|
+
design: it self-manages.
|
|
347
|
+
|
|
300
348
|
## Learn more
|
|
301
349
|
|
|
302
350
|
- [How it works](https://funkadelic.github.io/claude-nomad/how-it-works/) -- path remapping,
|