update-agentic-workspace 0.0.0 → 0.1.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/README.md +91 -0
- package/bin/update-agentic-workspace.mjs +49 -0
- package/package.json +21 -5
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# update-agentic-workspace
|
|
2
|
+
|
|
3
|
+
One command to bring an already-installed [Agentic Foundry](https://github.com/lukasrepublic/agentic-foundry)
|
|
4
|
+
workspace current: refresh the plugin marketplace, migrate a pre-v1.7.0 tag-pinned registration if
|
|
5
|
+
one is found, update the plugin in every scope that enables it, and re-run the workspace and
|
|
6
|
+
permission-floor reconcile.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npx update-agentic-workspace
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Run it **from inside** the workspace directory you scaffolded with `npx create-agentic-workspace`
|
|
13
|
+
(the sibling entry point). This package is a thin wrapper: every shared module is resolved from
|
|
14
|
+
`create-agentic-workspace` at an exact, pinned version — nothing here is a second copy.
|
|
15
|
+
|
|
16
|
+
## Unlike the sibling entry point, this one runs `claude`
|
|
17
|
+
|
|
18
|
+
`create-agentic-workspace` never runs `claude`, never accepts the workspace trust dialog, and never
|
|
19
|
+
pre-grants anything — it only declares. The update entry point necessarily does invoke `claude`, to
|
|
20
|
+
refresh the marketplace and update the plugin. That posture change is bounded, not open-ended:
|
|
21
|
+
every invocation this command makes is drawn from **one frozen, closed allowlist** of six
|
|
22
|
+
non-interactive `plugin` subcommand pairs (`plugin marketplace update`, `plugin marketplace add`,
|
|
23
|
+
`plugin marketplace remove`, `plugin update`, `plugin install`, `plugin list`) — none of which can
|
|
24
|
+
start a session or reach the workspace trust dialog. This command still never accepts the trust
|
|
25
|
+
dialog itself and never grants anything beyond what that dialog decides — put plainly, it never
|
|
26
|
+
grants a capability of its own: it declares and refreshes, and the platform's own trust dialog
|
|
27
|
+
remains the only consent ceremony there is.
|
|
28
|
+
|
|
29
|
+
**One side effect worth stating plainly, because "grants nothing of its own" could be read to rule
|
|
30
|
+
it out.** The migration heals a scope whose registration still carries a pinned `ref`, and healing
|
|
31
|
+
it ends — by design — in `claude plugin install <plugin>@<marketplace> --scope <scope>`, so that
|
|
32
|
+
removing the registration cannot leave the plugin orphaned. If that scope had the plugin *disabled*,
|
|
33
|
+
this re-enables it there. That is the specified behaviour, not an accident: the pinned-`ref` trigger
|
|
34
|
+
is deliberately not conditioned on enablement, because a stale pin is a broken registration whether
|
|
35
|
+
or not the plugin is currently switched on. If you have deliberately disabled the plugin in a scope
|
|
36
|
+
and want it to stay that way, disable it again after the update, or migrate that scope by hand.
|
|
37
|
+
|
|
38
|
+
## What it does
|
|
39
|
+
|
|
40
|
+
1. **Marketplace refresh** — `claude plugin marketplace update <marketplace>`, first migrating a
|
|
41
|
+
registration that is not yet in the tagless steady state (a leftover from before v1.7.0): removed,
|
|
42
|
+
re-added tagless, and the plugin re-installed, once per affected scope, with that scope's other
|
|
43
|
+
settings preserved exactly.
|
|
44
|
+
2. **Plugin update** — `claude plugin update <plugin>@<marketplace>` once for every scope whose
|
|
45
|
+
settings enable it, verified by reading back the refreshed cache manifest rather than trusting
|
|
46
|
+
the invoked CLI's own success line.
|
|
47
|
+
3. **Cleanup, opt-in (`--cleanup`)** — prune superseded plugin-cache versions and remove a stale or
|
|
48
|
+
duplicate marketplace registration. **This is destructive** and off by default: without
|
|
49
|
+
`--cleanup`, every candidate path and registration is still previewed, but nothing is removed and
|
|
50
|
+
no `claude` invocation runs for this phase at all. Pass `--cleanup` to actually delete what was
|
|
51
|
+
previewed.
|
|
52
|
+
4. **Reinitialization** — the same never-clobber managed-file reconcile and additive permission-floor
|
|
53
|
+
reconcile `create-agentic-workspace --existing` already implements: an operator-edited file is
|
|
54
|
+
reported drifted and left byte-identical, never overwritten.
|
|
55
|
+
|
|
56
|
+
Every run previews every `claude` invocation and every path it will touch **before** the first one
|
|
57
|
+
happens, and ends with a per-phase summary (`changed` / `already current` / `skipped: <reason>`).
|
|
58
|
+
|
|
59
|
+
## Flags
|
|
60
|
+
|
|
61
|
+
- `--cleanup` — also perform the destructive cache-prune and stale-registration removal previewed
|
|
62
|
+
above. Off by default; a flagless run removes nothing and prunes nothing.
|
|
63
|
+
- `--help` — print usage and exit.
|
|
64
|
+
|
|
65
|
+
## Exit codes
|
|
66
|
+
|
|
67
|
+
Same convention as the sibling package, and worth reading before you wire this into anything:
|
|
68
|
+
|
|
69
|
+
| code | meaning |
|
|
70
|
+
|------|---------|
|
|
71
|
+
| `0` | the run completed and no managed workspace file was found drifted |
|
|
72
|
+
| `2` | the run completed and at least one managed workspace file was drifted |
|
|
73
|
+
| `1` | the run refused, or an invocation failed |
|
|
74
|
+
|
|
75
|
+
**`2` is a success, not an error.** It reports one specific thing: a managed file in your workspace
|
|
76
|
+
has diverged from what the current template would write. That is a normal finding on a workspace
|
|
77
|
+
that predates a template change, and it is the expected result of a first run against a pre-v1.7.0
|
|
78
|
+
workspace.
|
|
79
|
+
|
|
80
|
+
Read the codes precisely, because `2` is narrower than "something happened": it is computed *only*
|
|
81
|
+
from the managed-file drift check, so a run that migrates a tag-pinned registration and updates the
|
|
82
|
+
plugin in every scope — real, visible changes — still exits `0` if no managed file drifted. Use the
|
|
83
|
+
printed phase summary, not the exit code, to see what the run actually did.
|
|
84
|
+
|
|
85
|
+
Only `1` means something went wrong. A `set -e` script or a CI step that treats any non-zero as
|
|
86
|
+
failure will read a perfectly good update as broken; test for `1` specifically.
|
|
87
|
+
|
|
88
|
+
## No telemetry
|
|
89
|
+
|
|
90
|
+
Same posture as the sibling package: no telemetry, no credential read beyond what your own `claude`
|
|
91
|
+
session already holds, nothing transmitted anywhere this tool does not tell you about.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// update-agentic-workspace — the npx entrypoint for bringing an installed workspace current
|
|
3
|
+
// (AC-UAW-1/-2). This file wires process.argv/stdio/env to the orchestrator and prints its output;
|
|
4
|
+
// EVERY behaviour lives in the shared `create-agentic-workspace` package, resolved at an EXACT
|
|
5
|
+
// version (AC-UAW-2) so this thin wrapper and the wizard entry point can never diverge into
|
|
6
|
+
// different behaviours. No file here vendors a copy of a module under create-agentic-workspace's
|
|
7
|
+
// own src/ — this file spawns no `claude` invocation itself; every one goes through
|
|
8
|
+
// runUpdate -> pluginRefresh.mjs's single, allowlisted (AC-UAW-14) spawn site.
|
|
9
|
+
//
|
|
10
|
+
// `claude`-invoking posture (AC-UAW-14, row d): unlike create-agentic-workspace, THIS entry point
|
|
11
|
+
// runs `claude` — the marketplace refresh and plugin update phases necessarily do. It never
|
|
12
|
+
// accepts the workspace trust dialog and never pre-grants anything: every invocation is drawn from
|
|
13
|
+
// one frozen, closed allowlist (ALLOWED_CLAUDE_SUBCOMMANDS) of non-interactive `plugin` subcommands,
|
|
14
|
+
// none of which can start a session or reach a trust dialog.
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
import os from 'node:os';
|
|
18
|
+
import { runUpdate, parseUpdateArgv } from 'create-agentic-workspace/src/update.mjs';
|
|
19
|
+
|
|
20
|
+
const rawArgv = process.argv.slice(2);
|
|
21
|
+
|
|
22
|
+
// A parse failure here (an unknown flag, including a mistyped --cleanup) is reported the same way
|
|
23
|
+
// runUpdate reports any other refusal, before anything is spawned or written. runUpdate re-parses
|
|
24
|
+
// argv itself (parseUpdateArgv is pure and idempotent); this pre-check exists only so a malformed
|
|
25
|
+
// invocation fails fast with a clean message from the entry point, before pkgDir resolution below.
|
|
26
|
+
try {
|
|
27
|
+
parseUpdateArgv(rawArgv);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
process.stderr.write(`refused: ${e.message}\n`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// `create-agentic-workspace`'s OWN package root, resolved via the dependency (AC-UAW-2) rather than
|
|
34
|
+
// a relative path — the templates/, permission-floor.json and package.json (for the `foundry` pins)
|
|
35
|
+
// Phase 3's reconcile needs all live there, one exact version away, never vendored here.
|
|
36
|
+
const pkgDir = path.dirname(
|
|
37
|
+
fileURLToPath(import.meta.resolve('create-agentic-workspace/package.json')),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const { exitCode } = await runUpdate(rawArgv, {
|
|
41
|
+
cwd: process.cwd(),
|
|
42
|
+
configDir: process.env.CLAUDE_CONFIG_DIR || path.join(process.env.HOME || os.homedir(), '.claude'),
|
|
43
|
+
homeDir: process.env.HOME || os.homedir(),
|
|
44
|
+
pkgDir,
|
|
45
|
+
output: process.stdout,
|
|
46
|
+
spawnEnv: process.env,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
process.exitCode = exitCode;
|
package/package.json
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "update-agentic-workspace",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "One command to bring an installed Agentic Foundry workspace current: refresh the plugin marketplace (migrating a pre-v1.7.0 tag-pinned registration if found), update the plugin in every scope that enables it, and re-run the workspace + permission-floor reconcile. A thin wrapper: every shared module is resolved from create-agentic-workspace at an exact version — no vendored second copy.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
8
9
|
"url": "git+https://github.com/lukasrepublic/agentic-foundry.git",
|
|
9
10
|
"directory": "cli-update"
|
|
10
11
|
},
|
|
11
|
-
"
|
|
12
|
-
"author": "",
|
|
12
|
+
"homepage": "https://github.com/lukasrepublic/agentic-foundry/tree/main/cli-update#readme",
|
|
13
13
|
"bugs": {
|
|
14
14
|
"url": "https://github.com/lukasrepublic/agentic-foundry/issues"
|
|
15
15
|
},
|
|
16
|
-
"
|
|
16
|
+
"bin": {
|
|
17
|
+
"update-agentic-workspace": "bin/update-agentic-workspace.mjs"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=22.0.0"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"bin/update-agentic-workspace.mjs",
|
|
24
|
+
"package.json",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"create-agentic-workspace": "0.9.0"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"test": "echo 'no local tests: every shared module is unit-tested in ../cli/test against create-agentic-workspace'\"'\"'s own src/'"
|
|
32
|
+
}
|
|
17
33
|
}
|