update-agentic-workspace 0.0.0 → 0.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/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.0.0",
4
- "description": "Placeholder - reserved for the Agentic Foundry workspace update command.",
3
+ "version": "0.1.1",
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
- "keywords": [],
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
- "homepage": "https://github.com/lukasrepublic/agentic-foundry#readme"
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.1"
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
  }