wood-fired-tasks 2.1.0 → 2.1.1
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/CHANGELOG.md +18 -1
- package/README.md +1 -1
- package/SECURITY.md +2 -2
- package/dist/cli/commands/self-update.d.ts +16 -3
- package/dist/cli/commands/self-update.js +21 -0
- package/docs/SETUP.md +7 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,21 @@ vulnerabilities, supply-chain pinning) are always called out under `Security`.
|
|
|
13
13
|
|
|
14
14
|
_No changes yet._
|
|
15
15
|
|
|
16
|
+
## [v2.1.1] - 2026-06-09
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **`tasks self-update` now re-syncs bundled skills/agents into `~/.claude`**
|
|
20
|
+
(PR #57, task #934). The command previously only ran
|
|
21
|
+
`npm i -g wood-fired-tasks@latest`, so a release that added or changed a
|
|
22
|
+
skill (first hit: v2.1.0's `/tasks:set-models`) left self-updaters with
|
|
23
|
+
stale `~/.claude/commands/tasks/` while reporting success — violating the
|
|
24
|
+
README's "keep it up to date" contract. After a clean install, self-update
|
|
25
|
+
now runs the same idempotent `copySkills()`/`copyAgents()` sync `tasks
|
|
26
|
+
setup` uses, reports what it refreshed, and exits non-zero with a
|
|
27
|
+
`tasks setup` remediation hint if the sync itself fails. A contract test
|
|
28
|
+
pins the default sync to setup's own implementation so the update and
|
|
29
|
+
onboarding paths cannot drift.
|
|
30
|
+
|
|
16
31
|
## [v2.1.0] - 2026-06-09
|
|
17
32
|
|
|
18
33
|
### Added
|
|
@@ -814,7 +829,9 @@ and the task/project/dependency/comment/subtask domain model.
|
|
|
814
829
|
- Task hierarchy (subtasks), dependency service, comments, time estimates
|
|
815
830
|
(phase 06).
|
|
816
831
|
|
|
817
|
-
[Unreleased]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v2.
|
|
832
|
+
[Unreleased]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v2.1.1...HEAD
|
|
833
|
+
[v2.1.1]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v2.1.0...v2.1.1
|
|
834
|
+
[v2.1.0]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v2.0.6...v2.1.0
|
|
818
835
|
[v2.0.0]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v1.18.2...v2.0.0
|
|
819
836
|
[v1.15]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v1.14...v1.15
|
|
820
837
|
[v1.14]: https://github.com/Wood-Fired-Games/wood-fired-tasks/compare/v1.13...v1.14
|
package/README.md
CHANGED
|
@@ -143,7 +143,7 @@ user scope.
|
|
|
143
143
|
|
|
144
144
|
```bash
|
|
145
145
|
wood-fired-tasks service install # Linux: user-scoped systemd unit (admin-free)
|
|
146
|
-
wood-fired-tasks self-update # npm i -g
|
|
146
|
+
wood-fired-tasks self-update # npm i -g @latest + re-sync skills (no sudo)
|
|
147
147
|
```
|
|
148
148
|
|
|
149
149
|
**Point at a shared remote server** (the *Remote client* mode above) with
|
package/SECURITY.md
CHANGED
|
@@ -14,11 +14,11 @@ security updates. Older tags are provided as-is.
|
|
|
14
14
|
| Version | Supported |
|
|
15
15
|
| ----------------- | ------------------ |
|
|
16
16
|
| `main` (HEAD) | :white_check_mark: |
|
|
17
|
-
| `v2.1.
|
|
17
|
+
| `v2.1.1` (latest) | :white_check_mark: |
|
|
18
18
|
| `v1.0` – `v2.0.6` | :x: |
|
|
19
19
|
|
|
20
20
|
"Latest" tracks whichever tag is most recent on GitHub; at the time of
|
|
21
|
-
writing that is `v2.1.
|
|
21
|
+
writing that is `v2.1.1`. If you are reading this on an older checkout,
|
|
22
22
|
verify the current latest release via
|
|
23
23
|
`git tag --sort=-creatordate | head -1` or the GitHub Releases page.
|
|
24
24
|
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { type ChildProcess, type SpawnOptions } from 'child_process';
|
|
3
|
+
import { type CopySkillsResult, type CopyAgentsResult } from './setup.js';
|
|
3
4
|
/**
|
|
4
5
|
* `tasks self-update` — frictionless self-update for npm-global installs
|
|
5
6
|
* (project #36, task #739).
|
|
6
7
|
*
|
|
7
|
-
* Spawns `npm i -g wood-fired-tasks@latest
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Spawns `npm i -g wood-fired-tasks@latest`, then re-syncs the bundled
|
|
9
|
+
* skills/agents into ~/.claude (task #934): the npm install replaces the
|
|
10
|
+
* files under the global prefix in place, so the post-install copySkills /
|
|
11
|
+
* copyAgents read the NEW version's assets even though this process is still
|
|
12
|
+
* running the old binary. Without this step, any release that adds or
|
|
13
|
+
* changes a skill leaves self-updaters with stale ~/.claude/commands/tasks
|
|
14
|
+
* while self-update reports success — violating the README's "keep it up to
|
|
15
|
+
* date" contract. The DB schema does NOT need touching here —
|
|
16
|
+
* migrate-on-next-serve handles it the next time the service boots against
|
|
17
|
+
* the upgraded binary.
|
|
10
18
|
*
|
|
11
19
|
* EACCES policy: a global npm install under a root-owned prefix fails with
|
|
12
20
|
* EACCES. We DO NOT escalate (no sudo / runas / elevation of ANY kind).
|
|
@@ -17,9 +25,14 @@ import { type ChildProcess, type SpawnOptions } from 'child_process';
|
|
|
17
25
|
*/
|
|
18
26
|
export type SpawnFn = (command: string, args: readonly string[], options: SpawnOptions) => ChildProcess;
|
|
19
27
|
export type NotifyFn = (currentVersion: string) => void | Promise<void>;
|
|
28
|
+
export type SyncAssetsFn = () => {
|
|
29
|
+
skills: CopySkillsResult;
|
|
30
|
+
agents: CopyAgentsResult;
|
|
31
|
+
};
|
|
20
32
|
export interface SelfUpdateDeps {
|
|
21
33
|
spawn?: SpawnFn;
|
|
22
34
|
notify?: NotifyFn;
|
|
35
|
+
syncAssets?: SyncAssetsFn;
|
|
23
36
|
}
|
|
24
37
|
/**
|
|
25
38
|
* True when a spawn error / non-zero exit looks like an EACCES-class
|
|
@@ -3,6 +3,7 @@ import { spawn as nodeSpawn } from 'child_process';
|
|
|
3
3
|
import { colorError, colorInfo, colorSuccess, colorWarn } from '../output/formatters.js';
|
|
4
4
|
import { VERSION } from '../../utils/version.js';
|
|
5
5
|
import { buildNpmInvocation } from '../util/npm-spawn.js';
|
|
6
|
+
import { copySkills, copyAgents } from './setup.js';
|
|
6
7
|
const PACKAGE_NAME = 'wood-fired-tasks';
|
|
7
8
|
/**
|
|
8
9
|
* True when a spawn error / non-zero exit looks like an EACCES-class
|
|
@@ -98,6 +99,7 @@ export const selfUpdateCommand = new Command('self-update')
|
|
|
98
99
|
const deps = selfUpdateCommand._deps ?? {};
|
|
99
100
|
const spawn = deps.spawn ?? nodeSpawn;
|
|
100
101
|
const notify = deps.notify ?? defaultNotify;
|
|
102
|
+
const syncAssets = deps.syncAssets ?? (() => ({ skills: copySkills(), agents: copyAgents() }));
|
|
101
103
|
// update-notifier nudge: surface a "newer version available" hint before
|
|
102
104
|
// we attempt the upgrade. Best-effort and never blocks the update.
|
|
103
105
|
await notify(VERSION);
|
|
@@ -119,6 +121,25 @@ export const selfUpdateCommand = new Command('self-update')
|
|
|
119
121
|
process.exitCode = code ?? 1;
|
|
120
122
|
return;
|
|
121
123
|
}
|
|
124
|
+
// npm replaced the package files under the global prefix in place, so the
|
|
125
|
+
// sync below reads the NEW version's dist/skills even though this process
|
|
126
|
+
// still runs the old binary. A sync failure is loud and non-zero: "update
|
|
127
|
+
// succeeded but your skills are stale" is exactly the silent state this
|
|
128
|
+
// step exists to eliminate (task #934).
|
|
129
|
+
try {
|
|
130
|
+
const { skills, agents } = syncAssets();
|
|
131
|
+
const refreshed = skills.written.length + agents.written.length;
|
|
132
|
+
console.log(refreshed > 0
|
|
133
|
+
? colorInfo(`Refreshed ${skills.written.length} skill(s) in ${skills.destDir} and ${agents.written.length} agent(s) in ${agents.destDir}`)
|
|
134
|
+
: colorInfo(`Skills and agents already up to date in ${skills.destDir}`));
|
|
135
|
+
}
|
|
136
|
+
catch (syncError) {
|
|
137
|
+
const message = syncError instanceof Error ? syncError.message : String(syncError);
|
|
138
|
+
console.error(colorError(`Update installed, but syncing bundled skills/agents into ~/.claude failed: ${message}`));
|
|
139
|
+
console.error(colorWarn(`Run \`${PACKAGE_NAME} setup\` to retry the skills sync.`));
|
|
140
|
+
process.exitCode = 1;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
122
143
|
console.log(colorSuccess(`Updated ${PACKAGE_NAME}. The schema migrates automatically on next serve.`));
|
|
123
144
|
process.exitCode = 0;
|
|
124
145
|
});
|
package/docs/SETUP.md
CHANGED
|
@@ -158,8 +158,13 @@ unless `--port` overrides it. The unauthenticated `GET /health` route returns
|
|
|
158
158
|
wood-fired-tasks self-update
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
-
This runs `npm i -g wood-fired-tasks@latest
|
|
162
|
-
|
|
161
|
+
This runs `npm i -g wood-fired-tasks@latest`, then re-syncs the bundled
|
|
162
|
+
skills into `~/.claude/commands/tasks/` and the subagent definitions into
|
|
163
|
+
`~/.claude/agents/` — the same idempotent copy `setup` performs, so a release
|
|
164
|
+
that adds or changes a skill is fully picked up by `self-update` alone (no
|
|
165
|
+
`setup` re-run needed). If the install succeeds but the skills sync fails, it
|
|
166
|
+
says so and exits non-zero; re-run `wood-fired-tasks setup` to retry the sync.
|
|
167
|
+
It **never escalates**: on an EACCES (root-owned global prefix) it prints the
|
|
163
168
|
writable-prefix remediation (the same `~/.npm-global` fix as `--fix-npm-prefix`)
|
|
164
169
|
and exits non-zero rather than suggesting sudo. The database schema needs no
|
|
165
170
|
special handling — it migrates automatically the next time `serve` (or the
|