@c4roa0/agentpay-user 0.3.2 → 0.3.3
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/README.md +19 -1
- package/doc/README.md +2 -0
- package/doc/TODO.md +9 -2
- package/doc/architecture.md +1 -0
- package/doc/records/local-npm-update-2026-11-08.md +28 -0
- package/doc/runbooks/commands.md +2 -1
- package/doc/runbooks/local-update.md +21 -4
- package/package.json +1 -1
- package/progress.md +38 -0
- package/src/npm-update.mjs +56 -14
- package/update-pair.json +1 -1
package/README.md
CHANGED
|
@@ -33,6 +33,24 @@ normally live in `~/.local/share/agentpay/user`; an existing custom data directo
|
|
|
33
33
|
is retained. Installation checkpoints use `~/.local/state/agentpay/user` (or
|
|
34
34
|
`$XDG_STATE_HOME/agentpay/user`). Upgrading program files does not erase either.
|
|
35
35
|
|
|
36
|
+
## Install in a folder instead
|
|
37
|
+
|
|
38
|
+
For a directory-owned installation, choose a program folder:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
mkdir agentpay-local
|
|
42
|
+
cd agentpay-local
|
|
43
|
+
npm install @c4roa0/agentpay-user
|
|
44
|
+
./node_modules/.bin/agentpay help
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Use `./node_modules/.bin/agentpay` instead of `agentpay` in the commands below.
|
|
48
|
+
`update` updates this installation and its project lockfile; it does not install
|
|
49
|
+
User globally. For an existing Wallet, use `repair` to refresh the background
|
|
50
|
+
services against this installation. Private data stays in its existing directory.
|
|
51
|
+
Before deleting the program folder, run `uninstall` to remove managed services;
|
|
52
|
+
private data is kept unless you explicitly choose `--delete-data`.
|
|
53
|
+
|
|
36
54
|
## After setup
|
|
37
55
|
|
|
38
56
|
```sh
|
|
@@ -44,7 +62,7 @@ agentpay market connect
|
|
|
44
62
|
|
|
45
63
|
Linux background services use your systemd user session. Wallet starts locked after
|
|
46
64
|
a restart. `agentpay service help` explains startup, stop and logs; `agentpay help` lists
|
|
47
|
-
all groups.
|
|
65
|
+
all groups. npm installations use `agentpay update` to review and install a
|
|
48
66
|
new User version with its matching Wallet and official test Skill. Source checkouts
|
|
49
67
|
update their files, run `npm ci`, then `agentpay repair`. [Commands](doc/runbooks/commands.md) · [Updates](doc/runbooks/local-update.md)
|
|
50
68
|
· [Backup and restore](doc/runbooks/wallet-identity.md).
|
package/doc/README.md
CHANGED
package/doc/TODO.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# User TODO
|
|
2
2
|
|
|
3
|
+
## Directory npm update, then HTTPS
|
|
4
|
+
|
|
5
|
+
- [x] Support directory-local npm update without replacing source/link installs.
|
|
6
|
+
- [x] Verify real npm directory upgrade and isolated preflight; nine regression checks passed.
|
|
7
|
+
- [ ] Publish a follow-up version and verify participant directory install/update.
|
|
8
|
+
|
|
3
9
|
## Tag-triggered publication
|
|
4
10
|
|
|
5
11
|
- [x] Use matching `vX.Y.Z` tags for npm publication; retain verification gates.
|
|
6
12
|
- [x] Owner confirmed release tags allowed in the GitHub `npm-publish` environment.
|
|
7
|
-
- [
|
|
13
|
+
- [x] Verify first tag-triggered OIDC run 42491753287 and registry archive integrity.
|
|
8
14
|
|
|
9
15
|
## Official package 1.2.1 — 2026-11-08
|
|
10
16
|
|
|
@@ -13,7 +19,8 @@
|
|
|
13
19
|
- [x] Load the reviewed User source update and run the normal 1.2.1 payment test with explicit user consent; terminal delivery/result/ack completed.
|
|
14
20
|
- [x] Verify website visibility and independently reconcile Settlement/chain outcome; prepare User 0.3.2 candidate.
|
|
15
21
|
- [x] Pin the verified public Wallet 0.3.2; align package/lockfile/update-pair.
|
|
16
|
-
- [
|
|
22
|
+
- [x] Publish User 0.3.2 through tag-triggered OIDC; verify public registry archive.
|
|
23
|
+
- [ ] Accept a real participant npm update/restart.
|
|
17
24
|
|
|
18
25
|
|
|
19
26
|
## Fixed Skill download loop — 2026-11-08
|
package/doc/architecture.md
CHANGED
|
@@ -30,6 +30,7 @@ name change. Independent-version compatibility remains a separate planned featur
|
|
|
30
30
|
| Area | Main files | Responsibility |
|
|
31
31
|
| --- | --- | --- |
|
|
32
32
|
| CLI | `run`, `scripts/agentpay-cli.mjs`, `src/user-cli.mjs` | Node discovery, grouped commands and help |
|
|
33
|
+
| npm update | `npm-update.mjs` | Detect global/direct-project installation, isolate npm preflight, pin the reviewed release and repair services without changing private data |
|
|
33
34
|
| Install / repair | `install-user.mjs`, `install-and-setup.mjs`, `install-preflight.mjs`, `local-update.mjs` | Dependency/build preparation, checkpoints, downloaded settings and safe restart |
|
|
34
35
|
| Setup | `guided-setup.mjs`, `user-setup-guide.mjs`, `anvil-onboarding.mjs` | Terminal sequence and saved-step continuation; explicit signer mode |
|
|
35
36
|
| Permission | `policy-terminal-guide.mjs`, `safe-policy-plan.mjs`, `renew-policy.mjs`, `policy-operations.mjs`, `policy-migration.mjs` | Drafts, approved operations and verified local binding |
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Directory npm update verification — 2026-11-08
|
|
2
|
+
|
|
3
|
+
The updater accepts a direct registry dependency in a project installation as well
|
|
4
|
+
as a global installation. The owning folder comes from the running package, not
|
|
5
|
+
the terminal working directory. Source/link, custom-source and transitive installs
|
|
6
|
+
remain outside automatic updates. Confirmation, exact release pinning, private-data
|
|
7
|
+
retention and the existing service repair flow remain in effect.
|
|
8
|
+
|
|
9
|
+
Nine controlled regression checks passed, covering global/local update, cancellation,
|
|
10
|
+
forced confirmation, failures, concurrent changes and unsupported install layouts.
|
|
11
|
+
A real-npm check installed public User 0.3.1 into a temporary project, ran the changed
|
|
12
|
+
updater against public 0.3.2 and verified program, manifest and lockfile versions.
|
|
13
|
+
Private-record fixture bytes were preserved. Service stop/repair hooks were controlled;
|
|
14
|
+
this is not participant process recovery or paid acceptance.
|
|
15
|
+
|
|
16
|
+
npm 10.9.8 dry-run changed node_modules/.package-lock.json without replacing program
|
|
17
|
+
files. The subsequent install could report up to date while leaving old code.
|
|
18
|
+
Lock-related flags did not reliably prevent this. Preflight now uses a disposable
|
|
19
|
+
prefix with privately copied project npm settings for consistent registry selection,
|
|
20
|
+
removed afterward. The real check confirms the existing hidden lockfile stays on
|
|
21
|
+
the old version after preflight. No participant keys, services or payments were used.
|
|
22
|
+
|
|
23
|
+
Follow-up publication and participant directory-update acceptance remain pending.
|
|
24
|
+
|
|
25
|
+
User 0.3.3 release preparation (2026-11-09): all 383 behavior checks and standalone
|
|
26
|
+
archive installation with isolated Wallet/Runtime process checks passed. Wallet
|
|
27
|
+
0.3.2, Protocol 0.14.3 and official package pin are unchanged. Publication and
|
|
28
|
+
participant acceptance remain separate gates.
|
package/doc/runbooks/commands.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Use `agentpay` after installing the package or linking a source checkout with
|
|
4
4
|
`npm link`. From a source folder, `./run` is the same entry; it uses Node on PATH
|
|
5
|
-
or `AGENTPAY_NODE`.
|
|
5
|
+
or `AGENTPAY_NODE`. For a folder-local npm install, use
|
|
6
|
+
`./node_modules/.bin/agentpay`; its `update` stays in that installation folder.
|
|
6
7
|
|
|
7
8
|
```sh
|
|
8
9
|
agentpay help
|
|
@@ -8,18 +8,35 @@ For a global npm installation:
|
|
|
8
8
|
agentpay update
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
For an npm installation inside a project folder, run its own command:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
./node_modules/.bin/agentpay update
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Directory-local update support starts with User 0.3.3. For an older directory
|
|
18
|
+
installation, run `npm install --save-exact @c4roa0/agentpay-user@0.3.3` in its
|
|
19
|
+
original program folder, then `./node_modules/.bin/agentpay repair`. Future versions
|
|
20
|
+
can be installed with the command above. Keep your private data directory.
|
|
21
|
+
|
|
22
|
+
Both forms update the installation that owns the command, regardless of the
|
|
23
|
+
terminal's working directory. Directory installs update their direct User dependency
|
|
24
|
+
and package lockfile in that folder, with an exact version; global installs keep
|
|
25
|
+
their global prefix. The confirmation shows the target folder. User must be a direct
|
|
26
|
+
registry dependency, not a transitive dependency or a linked/custom-source package.
|
|
27
|
+
|
|
11
28
|
It checks the published User version and shows its exact Wallet dependency. Confirm
|
|
12
29
|
to continue, or cancel without changing services. `agentpay update -f` skips only
|
|
13
|
-
this confirmation. The updater checks requirements, stops configured services,
|
|
30
|
+
this confirmation. The updater checks requirements in a temporary installation directory, stops configured services,
|
|
14
31
|
installs the confirmed version and invokes the new version's repair to refresh
|
|
15
32
|
services and verify its pinned official test Skill. No paid test runs automatically.
|
|
16
33
|
Other installed Skills and original requests are kept. Wallet needs unlocking after
|
|
17
34
|
restart. A current User version still checks the official test Skill.
|
|
18
35
|
|
|
19
|
-
Only genuine
|
|
36
|
+
Only genuine npm installations are updated. A source checkout or `npm link`
|
|
20
37
|
is refused rather than overwritten: update User's files, run `npm ci`, then
|
|
21
|
-
`agentpay repair`.
|
|
22
|
-
|
|
38
|
+
`agentpay repair`. Directory update has controlled real-npm verification; participant upgrade acceptance
|
|
39
|
+
remains separate. The updater uses npm's configured registry, checks
|
|
23
40
|
Node engine requirements and disables package installation hooks; releases must
|
|
24
41
|
ship usable runtime artifacts. It never independently selects the newest Wallet.
|
|
25
42
|
|
package/package.json
CHANGED
package/progress.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# AgentPay User progress
|
|
2
2
|
|
|
3
|
+
## User 0.3.3 release candidate — 2026-11-09
|
|
4
|
+
|
|
5
|
+
Release directory-local npm updates, keeping exact Wallet 0.3.2 and Protocol
|
|
6
|
+
0.14.3 dependencies and the reviewed official test package unchanged. No endpoint
|
|
7
|
+
migration, Policy or saved request rewrite is included. All 383 local behavior tests and independent archive installation/process checks
|
|
8
|
+
passed. Tag-triggered publication and registry verification remain pending.
|
|
9
|
+
|
|
10
|
+
## HTTPS endpoint migration — 2026-11-09
|
|
11
|
+
|
|
12
|
+
HTTPS migration inventory: existing setup rejects URL differences; local service settings, Market receipt origin/session, recovery observations and cancellation intents need coordinated handling. Public configuration publication does not migrate existing users. Keep original requests/Policies and current tunnels until an explicit local migration is implemented and verified.
|
|
13
|
+
|
|
14
|
+
## Directory npm update — 2026-11-08
|
|
15
|
+
|
|
16
|
+
Update now supports a direct registry dependency under a project node_modules as
|
|
17
|
+
well as a global installation. It derives the owning project from the running
|
|
18
|
+
package, pins the confirmed version, preserves the dependency section, updates the
|
|
19
|
+
local lockfile and uses the existing stop/repair/private-data flow. Source/link,
|
|
20
|
+
custom-source and transitive installs are refused before changing services.
|
|
21
|
+
Nine updater regression checks passed. A real public-npm 0.3.1 → 0.3.2 upgrade
|
|
22
|
+
in a disposable project verified program/manifest/lockfile agreement and preserved
|
|
23
|
+
private-record fixtures; service hooks were controlled, not participant processes.
|
|
24
|
+
This exposed npm dry-run rewriting the hidden installed-tree lockfile. Preflight
|
|
25
|
+
now runs in a disposable prefix with private project npm settings, removed afterward.
|
|
26
|
+
See [verification](doc/records/local-npm-update-2026-11-08.md).
|
|
27
|
+
User 0.3.3 is the release candidate for this fix; publication verification is pending.
|
|
28
|
+
|
|
29
|
+
## User 0.3.2 tag publication verified — 2026-11-08
|
|
30
|
+
|
|
31
|
+
Tag `v0.3.2` points to `890171b`; GitHub push-triggered OIDC run
|
|
32
|
+
[42491753287](https://github.com/c4rO-0/agentpay-user/actions/runs/42491753287)
|
|
33
|
+
completed successfully, including registry integrity verification. Public npm latest
|
|
34
|
+
is 0.3.2, pins Wallet 0.3.2 / Protocol 0.14.3 and includes provenance. Independently
|
|
35
|
+
downloaded registry bytes exactly match the locally tested archive (SHA-256
|
|
36
|
+
`e6bb2f1199e510850313c004055afeb3ba45afc07035697c1d37af14ebcf1489`).
|
|
37
|
+
All 380 existing tests and the independent package's real Wallet/Runtime restart
|
|
38
|
+
check passed. Participant npm update/restart acceptance remains the next step;
|
|
39
|
+
publication did not modify any participant services or create a paid Order.
|
|
40
|
+
|
|
3
41
|
## User 0.3.2 release pairing — 2026-11-08
|
|
4
42
|
|
|
5
43
|
Candidate now pins the verified public Wallet 0.3.2 with Protocol 0.14.3; package,
|
package/src/npm-update.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
-
// Update
|
|
2
|
+
// Update real global or project npm installations. Source checkouts/npm links are never
|
|
3
3
|
// overwritten. npm selects User; User's exact dependencies select Wallet/Protocol.
|
|
4
4
|
import { execFile } from 'node:child_process';
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
|
-
import { access, appendFile, lstat, mkdir, open, readFile, realpath, unlink } from 'node:fs/promises';
|
|
6
|
+
import { access, appendFile, copyFile, chmod, lstat, mkdir, mkdtemp, open, readFile, realpath, rm, unlink } from 'node:fs/promises';
|
|
7
7
|
import { constants } from 'node:fs';
|
|
8
|
-
import { dirname, isAbsolute, join } from 'node:path';
|
|
8
|
+
import { basename, dirname, isAbsolute, join, resolve } from 'node:path';
|
|
9
9
|
import { randomUUID } from 'node:crypto';
|
|
10
10
|
import { createInterface } from 'node:readline/promises';
|
|
11
11
|
import { installedUserDir, resolveUserDataDir, rememberUserDataDir } from './local-data-directory.mjs';
|
|
@@ -35,6 +35,35 @@ async function askConfirmation(message) {
|
|
|
35
35
|
const terminal = createInterface({ input:process.stdin, output:process.stdout });
|
|
36
36
|
try { return await terminal.question(message + '\n> '); } finally { terminal.close(); }
|
|
37
37
|
}
|
|
38
|
+
// Resolve the installed package, not the terminal's working directory. A project
|
|
39
|
+
// update must name a direct dependency; never promote a transitive package or
|
|
40
|
+
// replace a linked source checkout as a side effect of updating User.
|
|
41
|
+
async function installationTarget(userDir, npm) {
|
|
42
|
+
const root = await npm(['root', '--global']);
|
|
43
|
+
if (!isAbsolute(root)) throw Error('npm installation paths could not be verified.');
|
|
44
|
+
const globalPath = join(root, name);
|
|
45
|
+
const info = await lstat(globalPath).catch(e => { if (e.code !== 'ENOENT') throw e; return null; });
|
|
46
|
+
if (info?.isDirectory() && !info.isSymbolicLink() && await realpath(globalPath) === await realpath(userDir)) {
|
|
47
|
+
const prefix = await npm(['prefix', '--global']);
|
|
48
|
+
if (!isAbsolute(prefix)) throw Error('npm installation paths could not be verified.');
|
|
49
|
+
return {prefix, flags:['--global'], directory:globalPath};
|
|
50
|
+
}
|
|
51
|
+
const scope = dirname(userDir), modules = dirname(scope), prefix = dirname(modules);
|
|
52
|
+
if (basename(userDir) !== 'agentpay-user' || basename(scope) !== '@c4roa0' || basename(modules) !== 'node_modules' ||
|
|
53
|
+
!(await lstat(userDir)).isDirectory() || (await lstat(userDir)).isSymbolicLink())
|
|
54
|
+
throw Error('This is a source checkout or linked installation. Update its files, run npm ci, then agentpay repair.');
|
|
55
|
+
const project = JSON.parse(await readFile(join(prefix,'package.json'),'utf8'));
|
|
56
|
+
const sections = ['dependencies','devDependencies','optionalDependencies'].filter(key => Object.hasOwn(project[key] || {}, name));
|
|
57
|
+
if (sections.length !== 1 || typeof project[sections[0]][name] !== 'string')
|
|
58
|
+
throw Error('User must be a direct npm dependency of this folder. Install it in a dedicated folder before using update.');
|
|
59
|
+
const spec = project[sections[0]][name];
|
|
60
|
+
if (/[:/\\]/.test(spec) || spec.startsWith('.'))
|
|
61
|
+
throw Error('This dependency uses a custom source. Update that source explicitly, then run agentpay repair.');
|
|
62
|
+
const save = {dependencies:'--save-prod',devDependencies:'--save-dev',optionalDependencies:'--save-optional'}[sections[0]];
|
|
63
|
+
return {prefix, directory:userDir, section:sections[0], spec,
|
|
64
|
+
flags:['--global=false','--workspaces=false','--save-exact',save,'--include=dev','--include=optional']};
|
|
65
|
+
}
|
|
66
|
+
|
|
38
67
|
export async function updateFromNpm({
|
|
39
68
|
userDir = installedUserDir, dataDir, force = false, write = console.log,
|
|
40
69
|
ask = askConfirmation,
|
|
@@ -45,17 +74,13 @@ export async function updateFromNpm({
|
|
|
45
74
|
} = {}) {
|
|
46
75
|
let lock, lockPath, logPath, installing = false;
|
|
47
76
|
try {
|
|
77
|
+
userDir = resolve(userDir);
|
|
48
78
|
const current = JSON.parse(await readFile(join(userDir, 'package.json'), 'utf8'));
|
|
49
79
|
if (current.name !== name || !stable(current.version)) throw Error('Unrecognized User installation.');
|
|
50
80
|
write('Checking for a User update…');
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
const globalInfo = await lstat(globalPath).catch(e => { if(e.code !== 'ENOENT') throw e; return null; });
|
|
55
|
-
if (!globalInfo || globalInfo.isSymbolicLink() || await realpath(globalPath) !== await realpath(userDir))
|
|
56
|
-
throw Error('This is a source checkout or linked installation. Update its files, run npm ci, then agentpay repair.');
|
|
57
|
-
await access(dirname(globalPath), constants.W_OK);
|
|
58
|
-
const metadata = JSON.parse(await npm(['view',name + '@latest','--global','--json']));
|
|
81
|
+
const target = await installationTarget(userDir, npm);
|
|
82
|
+
await access(dirname(target.directory), constants.W_OK);
|
|
83
|
+
const metadata = JSON.parse(await npm(['view',name + '@latest','--json'], {cwd:target.prefix}));
|
|
59
84
|
if (metadata.name !== name || !stable(metadata.version) ||
|
|
60
85
|
!stable(metadata.dependencies?.['@c4roa0/agentpay-wallet']) ||
|
|
61
86
|
!stable(metadata.dependencies?.['@c4roa0/agentpay-protocol']))
|
|
@@ -67,6 +92,7 @@ export async function updateFromNpm({
|
|
|
67
92
|
return 0;
|
|
68
93
|
}
|
|
69
94
|
write(`User ${current.version} → ${metadata.version} · Wallet ${metadata.dependencies['@c4roa0/agentpay-wallet']}`);
|
|
95
|
+
write(`Installation folder: ${target.prefix}`);
|
|
70
96
|
write('Background services will pause. Keys, permissions, Orders and cache are kept.');
|
|
71
97
|
if (!force && (await ask("Type 'confirm' to update, or 'q' to cancel")).trim().toLowerCase() !== 'confirm') {
|
|
72
98
|
write('Update cancelled. Nothing was changed.'); return 0;
|
|
@@ -81,12 +107,28 @@ export async function updateFromNpm({
|
|
|
81
107
|
const rechecked = JSON.parse(await readFile(join(userDir,'package.json'),'utf8'));
|
|
82
108
|
if (rechecked.version !== current.version || rechecked.name !== name)
|
|
83
109
|
throw Error('Program files changed while reviewing the update. Run agentpay update again.');
|
|
110
|
+
if (target.section) {
|
|
111
|
+
const project = JSON.parse(await readFile(join(target.prefix,'package.json'),'utf8'));
|
|
112
|
+
if (project[target.section]?.[name] !== target.spec)
|
|
113
|
+
throw Error('The project dependency changed while reviewing the update. Run agentpay update again.');
|
|
114
|
+
}
|
|
84
115
|
const env = {...process.env,AGENTPAY_USER_DATA_DIR:dataDir};
|
|
85
|
-
const options = {logPath,env,cwd:
|
|
116
|
+
const options = {logPath,env,cwd:target.prefix,timeout:600000};
|
|
86
117
|
const spec = name + '@' + metadata.version;
|
|
87
|
-
const args = ['install','--
|
|
118
|
+
const args = ['install',...target.flags,'--prefix',target.prefix,'--engine-strict','--ignore-scripts','--no-audit','--no-fund',spec];
|
|
88
119
|
write('1/3 Check the update requirements.');
|
|
89
|
-
|
|
120
|
+
// npm dry-run may rewrite its hidden installed-tree lockfile. Preflight in
|
|
121
|
+
// a disposable prefix, never the live installation. Carry project npm settings
|
|
122
|
+
// privately so registry/auth selection remains consistent with the real install.
|
|
123
|
+
const preflight = await mkdtemp(join(stateDir,'update-check-'));
|
|
124
|
+
try {
|
|
125
|
+
await copyFile(join(target.prefix,'.npmrc'),join(preflight,'.npmrc')).then(
|
|
126
|
+
() => chmod(join(preflight,'.npmrc'),0o600),
|
|
127
|
+
error => { if(error.code !== 'ENOENT') throw error; });
|
|
128
|
+
await npm(['install','--global=false','--prefix',preflight,'--engine-strict',
|
|
129
|
+
'--ignore-scripts','--no-audit','--no-fund',spec,'--dry-run'],
|
|
130
|
+
{...options,cwd:preflight});
|
|
131
|
+
} finally { await rm(preflight,{recursive:true,force:true}); }
|
|
90
132
|
let configured = false;
|
|
91
133
|
try { configured = (await lstat(join(dataDir,'runtime/local-services.json'))).isFile(); }
|
|
92
134
|
catch(e) { if(e.code !== 'ENOENT') throw e; }
|