codemuster 0.1.0 → 0.2.8
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/LICENSE +74 -0
- package/README.md +147 -20
- package/lib/launcher.js +73 -10
- package/package.json +10 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
CodeMuster Personal and Internal Business Use License
|
|
2
|
+
Version 1.0 - September 14, 2026
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 Tim Carter. All rights reserved.
|
|
5
|
+
|
|
6
|
+
1. Scope
|
|
7
|
+
|
|
8
|
+
"Software" means CodeMuster's source code, binaries, launcher, skill files,
|
|
9
|
+
and associated documentation supplied under this license. "You" means the
|
|
10
|
+
individual or legal entity exercising the permissions below.
|
|
11
|
+
|
|
12
|
+
2. Permitted use
|
|
13
|
+
|
|
14
|
+
Subject to these terms, you may download, install, run, and copy the Software
|
|
15
|
+
free of charge for your own personal use or your organization's internal
|
|
16
|
+
business use. You may inspect and modify the Software solely for those uses.
|
|
17
|
+
Employees and contractors may use it on your behalf subject to these terms.
|
|
18
|
+
Keep this license and the copyright notice with all copies and modifications.
|
|
19
|
+
|
|
20
|
+
You may use the Software to analyze and improve code that you or your
|
|
21
|
+
organization owns or is authorized to work on, including code for commercial
|
|
22
|
+
products and client projects. You may sell that code and those products and
|
|
23
|
+
use the resulting reports and fixes in your work. Merely using the Software
|
|
24
|
+
does not subject your code, products, reports, or fixes to this license.
|
|
25
|
+
These permissions do not authorize including the Software itself in a
|
|
26
|
+
product or providing its functionality to third parties.
|
|
27
|
+
|
|
28
|
+
3. Restrictions
|
|
29
|
+
|
|
30
|
+
Without separate written permission from Tim Carter, you may not:
|
|
31
|
+
|
|
32
|
+
(a) Sell, resell, rent, lease, sublicense, or charge for the Software or any
|
|
33
|
+
modified version, in whole or in part.
|
|
34
|
+
(b) Modify, rebrand, bundle, or incorporate the Software into a product or
|
|
35
|
+
service for sale or other commercial distribution.
|
|
36
|
+
(c) Offer the Software or a modified version as a hosted service, API,
|
|
37
|
+
subscription, paid auditing service, or other offering that sells access
|
|
38
|
+
to or the functionality of the Software, including through bundled fees.
|
|
39
|
+
(d) Distribute the Software or modified versions outside your organization,
|
|
40
|
+
except to contractors solely for the permitted use on your behalf.
|
|
41
|
+
You may share links to the copyright holder's official distributions.
|
|
42
|
+
(e) Market or offer for sale any of the Software's code, skill files, or
|
|
43
|
+
documentation as your own product or implementation.
|
|
44
|
+
|
|
45
|
+
4. Ownership and limits
|
|
46
|
+
|
|
47
|
+
The Software is licensed, not sold. All rights not expressly granted are
|
|
48
|
+
reserved. This license grants no right to use CodeMuster's name or branding
|
|
49
|
+
to imply ownership, endorsement, or affiliation.
|
|
50
|
+
|
|
51
|
+
This license restricts use of the Software and its modified versions. It
|
|
52
|
+
does not claim ownership of abstract ideas, concepts, or methods, or impose
|
|
53
|
+
restrictions on independently developed software that does not copy protected
|
|
54
|
+
material from the Software. Rights provided by applicable law that cannot
|
|
55
|
+
be restricted by a license remain unaffected.
|
|
56
|
+
|
|
57
|
+
Third-party components remain subject to their own licenses. This license
|
|
58
|
+
does not replace those licenses or revoke rights already granted for copies
|
|
59
|
+
previously distributed under another license.
|
|
60
|
+
|
|
61
|
+
5. Termination
|
|
62
|
+
|
|
63
|
+
Your permissions under this license terminate automatically if you violate
|
|
64
|
+
its terms. Upon termination, stop using and distributing the Software and
|
|
65
|
+
delete your copies, except where retention is required by applicable law.
|
|
66
|
+
|
|
67
|
+
6. Disclaimer
|
|
68
|
+
|
|
69
|
+
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED
|
|
70
|
+
"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
|
71
|
+
LIMITED TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
|
72
|
+
NONINFRINGEMENT. THE AUTHORS AND COPYRIGHT HOLDERS SHALL NOT BE LIABLE FOR
|
|
73
|
+
ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING FROM OR IN CONNECTION WITH
|
|
74
|
+
THE SOFTWARE OR ITS USE, WHETHER IN CONTRACT, TORT, OR OTHERWISE.
|
package/README.md
CHANGED
|
@@ -1,37 +1,164 @@
|
|
|
1
|
-
#
|
|
1
|
+
# CodeMuster
|
|
2
2
|
|
|
3
|
-
Audit
|
|
4
|
-
|
|
5
|
-
hands your agent one unit of work at a time in a fresh context, tracks every unit in a local
|
|
6
|
-
ledger, and tries to refute each finding before it reaches the report.
|
|
3
|
+
Audit a codebase with Claude Code, Codex, or the standalone CLI, and see exactly which work
|
|
4
|
+
has been completed.
|
|
7
5
|
|
|
8
|
-
|
|
6
|
+
CodeMuster maps C# with Roslyn and TypeScript with the TypeScript compiler, groups code into
|
|
7
|
+
work units, and tracks each unit in a local SQLite ledger. Your agent analyzes each unit in a
|
|
8
|
+
fresh context. A verification pass tries to refute reported findings. Fix mode groups confirmed
|
|
9
|
+
findings by file, runs independent file workers, and creates local commits.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
Coverage tells you what was analyzed. It does not prove that every defect was found or that a
|
|
12
|
+
fix passes your tests.
|
|
13
|
+
|
|
14
|
+
## Install and set up
|
|
15
|
+
|
|
16
|
+
### Use through your coding agent (recommended)
|
|
17
|
+
|
|
18
|
+
Install the CodeMuster plugin from this repository's marketplace. It bundles the same skill
|
|
19
|
+
for Claude Code and Codex. Run the commands for your agent:
|
|
20
|
+
|
|
21
|
+
**Claude Code**
|
|
11
22
|
|
|
12
23
|
```sh
|
|
13
|
-
|
|
24
|
+
claude plugin marketplace add TSCarterJr/CodeMuster
|
|
25
|
+
claude plugin install codemuster@codemuster
|
|
14
26
|
```
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
|
|
28
|
+
**Codex**
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
codex plugin marketplace add TSCarterJr/CodeMuster
|
|
32
|
+
codex plugin add codemuster@codemuster
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Start a new agent session in your repository. The plugin directs the agent to use CodeMuster
|
|
36
|
+
during coding according to `automation` in `.codemuster/config.json`: `off`, `update`
|
|
37
|
+
(default), `review`, or `review_and_fix`. You can also ask for a full audit:
|
|
38
|
+
|
|
39
|
+
> Audit this repository with CodeMuster.
|
|
18
40
|
|
|
19
|
-
|
|
41
|
+
The skill checks for the CLI, attempts `npm i -g codemuster` if missing, and verifies the
|
|
42
|
+
result. This skill requires stable CLI 0.2.7 or later, checks recovery/validation capabilities, and attempts an explicit update once for an older installation. A version pin is respected. If installation is blocked or fails, it explains the problem and gives the manual
|
|
43
|
+
command. Plugin use runs `init --yes --no-skills` without `--for` to avoid duplicate project skills; this also
|
|
44
|
+
skips project hooks. The plugin supplies its own session/edit context hooks. Review and fix
|
|
45
|
+
mode authorizes scoped repairs and local commits; configure `test_command` for validation.
|
|
46
|
+
See [automatic use](https://github.com/TSCarterJr/CodeMuster/blob/main/docs/usage.md#automatic-use-during-coding)
|
|
47
|
+
for settings, scope, and how existing work is preserved.
|
|
48
|
+
|
|
49
|
+
This is a repository marketplace; installation does not depend on an official directory
|
|
50
|
+
listing. For local-checkout installation, updates, standalone skill downloads, and publication
|
|
51
|
+
status, see the [distribution guide](https://github.com/TSCarterJr/CodeMuster/blob/main/docs/distribution.md).
|
|
52
|
+
|
|
53
|
+
### Use the standalone CLI
|
|
54
|
+
|
|
55
|
+
You need Node.js 22 or later and Git. The CLI ships as a self-contained platform build.
|
|
56
|
+
C# mapping also needs a suitable .NET SDK; TypeScript mapping needs the target repository's
|
|
57
|
+
`typescript` dependency installed. These requirements also apply to plugin use, which needs
|
|
58
|
+
terminal access to your repository. Install and authenticate your chosen coding agent separately.
|
|
20
59
|
|
|
21
60
|
```sh
|
|
61
|
+
npm install -g codemuster
|
|
22
62
|
cd your-repo
|
|
23
|
-
codemuster init --yes
|
|
63
|
+
codemuster init --for codex --yes
|
|
24
64
|
codemuster doctor
|
|
25
|
-
codemuster skill install --for claude
|
|
26
65
|
```
|
|
27
66
|
|
|
28
|
-
|
|
29
|
-
|
|
67
|
+
Commit `.codemuster/config.json`. Keep `.codemuster/ledger.db` local and ignored.
|
|
68
|
+
`doctor` checks the mappers and suggests setup commands; it does not install dependencies.
|
|
69
|
+
`init` installs project skills and change hooks for your selected agents. Choose a comma-separated
|
|
70
|
+
`--for claude,codex,gemini`, or choose interactively with plain `init`. `--yes` selects all unless
|
|
71
|
+
`--for` or `--no-skills` is given. Use `--no-gitignore`, `--no-hooks`, or `--no-skills` to opt out.
|
|
72
|
+
Reload the agent and approve its hook trust prompt when needed. Hooks track changes without
|
|
73
|
+
running an audit. Standalone `skill install` also supports `opencode` and global installation.
|
|
74
|
+
|
|
75
|
+
### Use the skill without a plugin
|
|
76
|
+
|
|
77
|
+
With the CLI installed, run `codemuster skill install --for codex`. The installer supports
|
|
78
|
+
`claude`, `codex`, `gemini`, and `opencode`; add `--global` for all repositories. Use either
|
|
79
|
+
the plugin or a standalone skill copy in a given agent scope to avoid duplicate entries.
|
|
80
|
+
|
|
81
|
+
## Drive an audit yourself
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
codemuster scan
|
|
85
|
+
codemuster estimate
|
|
86
|
+
codemuster run --agent codex -j 4
|
|
87
|
+
codemuster status
|
|
88
|
+
codemuster report --out audit.md
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`scan` maps entry-point call paths and unreached code by default. Use `scan --mode file` for one
|
|
92
|
+
unit per included file. `estimate` approximates pending input tokens. `run` analyzes pending
|
|
93
|
+
units and processes verification work when enabled. Repeat `run` to resume unfinished work.
|
|
94
|
+
|
|
95
|
+
Use `--path src` with `next`, `estimate`, `run`, `verify`, or `fix` to work on one part of a repository.
|
|
96
|
+
A lens's globs select where its instructions apply; `exclude` removes files from the scan.
|
|
97
|
+
The report includes verification verdicts and recorded fix outcomes. Refuted findings are
|
|
98
|
+
hidden unless you use `--include-refuted`.
|
|
99
|
+
|
|
100
|
+
## Fix confirmed findings
|
|
101
|
+
|
|
102
|
+
First configure the repository's validation command. For example, add this property to the
|
|
103
|
+
existing `.codemuster/config.json`:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
"test_command": ["dotnet", "test", "YourSolution.sln"]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Then run:
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
codemuster fix --agent codex -j 4
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`-j` is an upper limit, with a default of one. Four files with `-j 10` use at most four workers.
|
|
116
|
+
Each file's confirmed findings go to one worker. All workers, including the default single worker, use isolated Git worktrees;
|
|
117
|
+
the coordinator applies their completed patches, runs the configured tests, commits each changed
|
|
118
|
+
file, and records outcomes in sequence. CodeMuster never pushes the commits.
|
|
119
|
+
|
|
120
|
+
If tracked files have local edits, the terminal offers to stash them and restore them afterward,
|
|
121
|
+
including their staging state. Use `--stash` for unattended consent. Untracked files stay in
|
|
122
|
+
place, and recovery stashes are retained. Avoid editing the checkout during a fix run.
|
|
123
|
+
|
|
124
|
+
A failed attempt is retried up to `--attempts N` times in total (default three). Extra file edits
|
|
125
|
+
are rejected and reported with a retained worker path. The untracked Impeccable hook cache is
|
|
126
|
+
excluded from the patch and does not block it. Without `test_command`, CodeMuster warns that
|
|
127
|
+
it is accepting fixes without running your tests.
|
|
128
|
+
|
|
129
|
+
Retry declines through `fix --retry-declined`. For a repair spanning related files, select an
|
|
130
|
+
exact primary `--path` and `--include-related path/to/caller,path/to/catalog -j 1`; all paths
|
|
131
|
+
must be existing tracked files. The worker stays inside that explicit scope.
|
|
132
|
+
|
|
133
|
+
After repairs, run `codemuster verify --agent codex --force` to recheck the known findings against
|
|
134
|
+
current code. A `resolved` verdict records the fixed outcome and evidence; a confirmed regression
|
|
135
|
+
reopens it. Then run `codemuster validate` to execute your configured build/test command against
|
|
136
|
+
the final state, even when no fixes remain. Missing validation configuration is a failure.
|
|
137
|
+
Use `scan` and `run` afterward when you need a refreshed audit of all changed code.
|
|
138
|
+
|
|
139
|
+
## Help and documentation
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
codemuster --help
|
|
143
|
+
codemuster fix --help
|
|
144
|
+
codemuster --version
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- [User guide and command reference](https://github.com/TSCarterJr/CodeMuster/blob/main/docs/usage.md): configuration, scope, parallelism, retries, and recovery.
|
|
148
|
+
- [Contributor guide](https://github.com/TSCarterJr/CodeMuster/blob/main/docs/development.md): build, test, and project layout.
|
|
149
|
+
- [Decisions](https://github.com/TSCarterJr/CodeMuster/blob/main/DECISIONS.md) and [implementation checklist](https://github.com/TSCarterJr/CodeMuster/blob/main/MVP-Checklist.md).
|
|
30
150
|
|
|
31
|
-
|
|
151
|
+
These documents describe the repository source; an older installed release may have fewer
|
|
152
|
+
options. The npm launcher checks for updates at most once a day and uses a downloaded update on
|
|
153
|
+
a later invocation. Set `CI` or `CODEMUSTER_NO_UPDATE` to disable automatic checks.
|
|
154
|
+
`codemuster update --check` checks availability without installing; `codemuster update` installs
|
|
155
|
+
an available update. The 0.2.7 launcher supports `CODEMUSTER_VERSION=0.2.0` to select that exact binary, including when a newer build is cached. Unset the variable to resume normal selection; explicit updates are refused while pinned. Install the current launcher first to obtain pin support. Run `skill install` again to refresh an installed skill copy. See the user guide for rollback and ledger precautions.
|
|
32
156
|
|
|
33
|
-
|
|
34
|
-
checks its integrity, and uses it from the next run on. It never updates when the `CI` or
|
|
35
|
-
`CODEMUSTER_NO_UPDATE` environment variable is set.
|
|
157
|
+
## License
|
|
36
158
|
|
|
37
|
-
|
|
159
|
+
CodeMuster uses the [Personal and Internal Business Use License](LICENSE).
|
|
160
|
+
You may use and privately modify it for personal work and internal company work,
|
|
161
|
+
including work on commercial products and client code. You may sell your own
|
|
162
|
+
products; you may not sell CodeMuster, commercialize a modified version, or offer
|
|
163
|
+
its functionality as a paid service. Redistribution requires written permission.
|
|
164
|
+
This is a source-available license with use restrictions. See LICENSE for the full terms.
|
package/lib/launcher.js
CHANGED
|
@@ -12,6 +12,10 @@ const KEEP_VERSIONS = 2;
|
|
|
12
12
|
const PLATFORMS = new Set(['win32-x64', 'win32-arm64', 'darwin-x64', 'darwin-arm64', 'linux-x64', 'linux-arm64']);
|
|
13
13
|
const VERSION = /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;
|
|
14
14
|
|
|
15
|
+
function versionsDirectory(stateDir, platform, arch) {
|
|
16
|
+
return path.join(stateDir, `${platform}-${arch}`, 'versions');
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
function platformPackage(platform, arch) {
|
|
16
20
|
const name = `${platform}-${arch}`;
|
|
17
21
|
if (!PLATFORMS.has(name)) {
|
|
@@ -70,13 +74,13 @@ function splitVersion(version) {
|
|
|
70
74
|
return [core.split('.'), dash < 0 ? null : version.slice(dash + 1)];
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
function newestBuild({ versionsDir, bundled, platform }) {
|
|
77
|
+
function newestBuild({ versionsDir, bundled, platform, pinnedVersion }) {
|
|
74
78
|
const candidates = bundled ? [{ version: bundled.version, binary: path.join(bundled.dir, 'bin', binaryName(platform)) }] : [];
|
|
75
79
|
for (const version of installedVersions(versionsDir)) {
|
|
76
80
|
candidates.push({ version, binary: path.join(versionsDir, version, 'bin', binaryName(platform)) });
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
const complete = candidates.filter((candidate) => fs.existsSync(candidate.binary));
|
|
83
|
+
const complete = candidates.filter((candidate) => (!pinnedVersion || candidate.version === pinnedVersion) && fs.existsSync(candidate.binary));
|
|
80
84
|
complete.sort((x, y) => compareVersions(y.version, x.version));
|
|
81
85
|
return complete[0] ?? null;
|
|
82
86
|
}
|
|
@@ -90,7 +94,7 @@ function installedVersions(versionsDir) {
|
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
function shouldCheckForUpdate({ env, now, lastCheck }) {
|
|
93
|
-
return !env.CI && !env.CODEMUSTER_NO_UPDATE && (lastCheck === null || now - lastCheck >= DAY);
|
|
97
|
+
return !env.CI && !env.CODEMUSTER_NO_UPDATE && !env.CODEMUSTER_VERSION && (lastCheck === null || now - lastCheck >= DAY);
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
function readLastCheck(stateDir) {
|
|
@@ -109,7 +113,7 @@ function tar(args) {
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
async function getJson(url) {
|
|
112
|
-
const response = await fetch(url, { headers: { accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8' } });
|
|
116
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(60000), headers: { accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8' } });
|
|
113
117
|
if (!response.ok) {
|
|
114
118
|
throw new Error(`GET ${url} returned ${response.status}`);
|
|
115
119
|
}
|
|
@@ -118,6 +122,7 @@ async function getJson(url) {
|
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
async function installVersion({ registry, version, versionsDir, platform, arch }) {
|
|
125
|
+
if (!VERSION.test(version)) throw new Error(`invalid version: ${version}`);
|
|
121
126
|
const pkg = platformPackage(platform, arch);
|
|
122
127
|
fs.mkdirSync(versionsDir, { recursive: true });
|
|
123
128
|
const packument = await getJson(`${registry}/${pkg.replace('/', '%2f')}`);
|
|
@@ -126,7 +131,7 @@ async function installVersion({ registry, version, versionsDir, platform, arch }
|
|
|
126
131
|
throw new Error(`${pkg}@${version} is not in the registry`);
|
|
127
132
|
}
|
|
128
133
|
|
|
129
|
-
const response = await fetch(dist.tarball);
|
|
134
|
+
const response = await fetch(dist.tarball, { signal: AbortSignal.timeout(60000) });
|
|
130
135
|
if (!response.ok) {
|
|
131
136
|
throw new Error(`GET ${dist.tarball} returned ${response.status}`);
|
|
132
137
|
}
|
|
@@ -185,7 +190,7 @@ async function update({ registry, stateDir, platform, arch, currentVersion, now
|
|
|
185
190
|
return { latest, installed: null };
|
|
186
191
|
}
|
|
187
192
|
|
|
188
|
-
const versionsDir =
|
|
193
|
+
const versionsDir = versionsDirectory(stateDir, platform, arch);
|
|
189
194
|
await installVersion({ registry, version: latest, versionsDir, platform, arch });
|
|
190
195
|
pruneVersions(versionsDir);
|
|
191
196
|
return { latest, installed: latest };
|
|
@@ -218,17 +223,73 @@ function bundledBuild(pkg) {
|
|
|
218
223
|
}
|
|
219
224
|
}
|
|
220
225
|
|
|
226
|
+
async function updateNow({ args, stateDir, platform, arch, currentVersion, registry = REGISTRY, out = process.stdout }) {
|
|
227
|
+
const checkOnly = args.includes('--check');
|
|
228
|
+
let packument;
|
|
229
|
+
try {
|
|
230
|
+
packument = await getJson(`${registry}/codemuster`);
|
|
231
|
+
} catch (error) {
|
|
232
|
+
out.write(`codemuster: could not reach the npm registry: ${error.message}\n`);
|
|
233
|
+
return 1;
|
|
234
|
+
}
|
|
235
|
+
const latest = (packument['dist-tags'] && packument['dist-tags'].latest) || null;
|
|
236
|
+
if (latest === null) {
|
|
237
|
+
out.write('codemuster: the registry named no latest version\n');
|
|
238
|
+
return 1;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (compareVersions(latest, currentVersion) <= 0) {
|
|
242
|
+
out.write(`codemuster ${currentVersion} is already the newest\n`);
|
|
243
|
+
return 0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (checkOnly) {
|
|
247
|
+
out.write(`codemuster ${latest} is available; you are on ${currentVersion}. Run codemuster update to install it.\n`);
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
out.write(`updating codemuster ${currentVersion} to ${latest}\n`);
|
|
252
|
+
const versionsDir = versionsDirectory(stateDir, platform, arch);
|
|
253
|
+
try {
|
|
254
|
+
await installVersion({ registry, version: latest, versionsDir, platform, arch });
|
|
255
|
+
} catch (error) {
|
|
256
|
+
out.write(`codemuster: ${latest} could not be installed: ${error.message}\n`);
|
|
257
|
+
return 1;
|
|
258
|
+
}
|
|
259
|
+
pruneVersions(versionsDir);
|
|
260
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
261
|
+
fs.writeFileSync(path.join(stateDir, 'last-update-check'), String(Date.now()));
|
|
262
|
+
out.write(`codemuster ${latest} is ready; the next command uses it\n`);
|
|
263
|
+
return 0;
|
|
264
|
+
}
|
|
265
|
+
|
|
221
266
|
async function main(args, env = process.env) {
|
|
267
|
+
if ((args[0] === 'update' && args.slice(1).some((arg) => arg === '--help' || arg === '-h'))
|
|
268
|
+
|| (args.length === 2 && args[0] === 'help' && args[1] === 'update')) {
|
|
269
|
+
process.stdout.write('usage: codemuster update [--check]\n\nUpdate CodeMuster itself through the npm launcher.\n --check Show the available version without installing it\n\nAutomatic background checks can be disabled with CI or CODEMUSTER_NO_UPDATE.\n');
|
|
270
|
+
return 0;
|
|
271
|
+
}
|
|
272
|
+
|
|
222
273
|
const platform = process.platform;
|
|
223
274
|
const arch = process.arch;
|
|
224
275
|
const stateDir = path.join(os.homedir(), '.codemuster');
|
|
225
|
-
const versionsDir =
|
|
226
|
-
|
|
276
|
+
const versionsDir = versionsDirectory(stateDir, platform, arch);
|
|
277
|
+
const pinnedVersion = env.CODEMUSTER_VERSION;
|
|
278
|
+
if (pinnedVersion && !VERSION.test(pinnedVersion)) throw new Error(`invalid version pin: ${pinnedVersion}`);
|
|
279
|
+
let build = newestBuild({ versionsDir, pinnedVersion, bundled: bundledBuild(platformPackage(platform, arch)), platform });
|
|
227
280
|
if (build === null) {
|
|
228
|
-
const version = require('../package.json').version;
|
|
281
|
+
const version = pinnedVersion || require('../package.json').version;
|
|
229
282
|
process.stderr.write(`codemuster: downloading CodeMuster ${version} for ${platform}-${arch}\n`);
|
|
230
283
|
await installVersion({ registry: REGISTRY, version, versionsDir, platform, arch });
|
|
231
|
-
build = newestBuild({ versionsDir, bundled: null, platform });
|
|
284
|
+
build = newestBuild({ versionsDir, pinnedVersion, bundled: null, platform });
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (args[0] === 'update') {
|
|
288
|
+
if (pinnedVersion) {
|
|
289
|
+
process.stderr.write(`codemuster is pinned to ${pinnedVersion}; unset CODEMUSTER_VERSION before updating\n`);
|
|
290
|
+
return 1;
|
|
291
|
+
}
|
|
292
|
+
return updateNow({ args: args.slice(1), stateDir, platform, arch, currentVersion: build.version });
|
|
232
293
|
}
|
|
233
294
|
|
|
234
295
|
if (shouldCheckForUpdate({ env, now: Date.now(), lastCheck: readLastCheck(stateDir) })) {
|
|
@@ -242,6 +303,7 @@ async function main(args, env = process.env) {
|
|
|
242
303
|
|
|
243
304
|
module.exports = {
|
|
244
305
|
REGISTRY,
|
|
306
|
+
versionsDirectory,
|
|
245
307
|
binaryName,
|
|
246
308
|
compareVersions,
|
|
247
309
|
installVersion,
|
|
@@ -253,4 +315,5 @@ module.exports = {
|
|
|
253
315
|
shouldCheckForUpdate,
|
|
254
316
|
tar,
|
|
255
317
|
update,
|
|
318
|
+
updateNow,
|
|
256
319
|
};
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codemuster",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "CodeMuster: full-coverage codebase audits with a coverage number, driven by your coding agent through one skill.",
|
|
5
|
-
"license": "
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Tim Carter",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/TSCarterJr/CodeMuster.git"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://
|
|
11
|
+
"homepage": "https://github.com/TSCarterJr/CodeMuster",
|
|
12
12
|
"keywords": [
|
|
13
13
|
"code-audit",
|
|
14
14
|
"code-review",
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
"node": ">=22"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
|
-
"test": "node --test test/launcher.test.js"
|
|
36
|
+
"test": "node --test test/launcher.test.js test/plugin.test.js test/release.test.js"
|
|
37
37
|
},
|
|
38
38
|
"optionalDependencies": {
|
|
39
|
-
"@codemuster/darwin-arm64": "0.
|
|
40
|
-
"@codemuster/darwin-x64": "0.
|
|
41
|
-
"@codemuster/linux-arm64": "0.
|
|
42
|
-
"@codemuster/linux-x64": "0.
|
|
43
|
-
"@codemuster/win32-arm64": "0.
|
|
44
|
-
"@codemuster/win32-x64": "0.
|
|
39
|
+
"@codemuster/darwin-arm64": "0.2.8",
|
|
40
|
+
"@codemuster/darwin-x64": "0.2.8",
|
|
41
|
+
"@codemuster/linux-arm64": "0.2.8",
|
|
42
|
+
"@codemuster/linux-x64": "0.2.8",
|
|
43
|
+
"@codemuster/win32-arm64": "0.2.8",
|
|
44
|
+
"@codemuster/win32-x64": "0.2.8"
|
|
45
45
|
}
|
|
46
46
|
}
|