Skip to content

feat(framework): add maintenance and scoped upgrades - #1145

Draft
alexsoyes wants to merge 38 commits into
nextfrom
feat/aidd-maintenance
Draft

alexsoyes wants to merge 38 commits into
nextfrom
feat/aidd-maintenance

Conversation

@alexsoyes

@alexsoyes alexsoyes commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

What & why

Show installed AIDD versions and the latest matching release, then let the user review and update supported project installations. Keep local-source comparisons explicit and preserve the installation method and scope.

Behavior

  • Session notices show the registered marketplace version, release tag and title, verification time and known plugin updates in a compact layout. Official release data is cached; unavailable title metadata is retried independently.

  • Claude's native marketplace and CLI-managed project/global plugins are checked against their own sources and release channels. A shared marketplace left on an older source is labelled separately after its global plugins are updated.

  • aidd framework update --release <tag> previews project plugins, their sources, release notes and repository comparison links, validates the release, and requires confirmation. Shared sources require explicit consent. Comparison links use the current tags and cover the whole repository.

  • Project updates build the target afresh, check collisions including Antigravity hook scripts before changing the marketplace, and remove obsolete files only when their ownership and contents remain verified. Global sync restores missing owned machine files and refuses changed files or symbolic-link paths.

  • aidd framework update --release <tag> --scope user separately updates pinned OpenCode/Kilo machine copies. It shows versions and known dependents, leaves the shared marketplace and native claims alone, and pins subsequent syncs to the selected commit.

  • OpenCode and Kilo show the notice at TUI startup. aidd run opencode -- … and aidd run kilo -- … execute the real CLI with the notice on stderr and the tool output unchanged. Ambiguous or remote configurations are refused.

  • For the tested native Claude, Copilot and Codex GitHub marketplaces pinned to a release, the skill describes an update without removing the marketplace, preserving plugin scopes and enabled states. Codex refresh affects every installed plugin from the marketplace and requires collective approval. Other native sources or managed configurations are reported as unsupported.

  • Machine-scoped maintenance hooks use the ownership model from feat(cli): install the framework for every project with setup --global #1142. Kilo's TUI config retains existing settings, comments and third-party plugins when maintenance is installed or removed.

  • Project release updates show known Claude installations sharing the catalogue before confirmation, then refresh the selected local plugin without changing its enabled state. The effective source and inventory are rechecked before native writes. Historical plugin ownership is not required. Failed native catalogue builds are reported as incomplete updates.

  • The skill defaults to the stable or current prerelease channel; an explicitly chosen newer release may use another channel in either project or global scope. Both CLI previews show the release title or an explicit fallback; the project preview lists AIDD user-scope copies recorded by the machine manifest and labels native inventory incomplete.

  • Project hook directories are checked before updates; a blocked Codex .agents directory stops the update before writes and reports the required access.

  • Git hook gates clear repository-local Git environment variables before running tests, so temporary repositories do not target the worktree being pushed.

  • Authenticated Git clones keep credentials out of remotes, argv and debug output. Automatically resolved AIDD tokens are restricted to github.com; other hosts use Git credential helpers. The test suite no longer sweeps directories in the shared temporary root.

Verification

  • Real interactive Claude Code, Codex, Copilot CLI, OpenCode 2.2.5 and Kilo 7.8.18 displayed the notice. OpenCode TUI displayed the full release title after global installation, and no notice after removal.

  • Real Kilo project and global installations were exercised together: after global removal the project still showed its notice; after project removal the notice disappeared. Existing JSONC comments and third-party plugin entries survived both removals.

  • Real OpenCode and Kilo headless runs returned model responses as JSON with the notice on stderr. Conflicting project/global copies were refused.

  • Real isolated OpenCode and Codex projects were updated from v5.12.0 to v5.13.0; their manifests were checked, as were Codex's installed plugin and subsequent session.

  • Real isolated global OpenCode/Kilo copies were updated from v5.12.0 to v5.13.0; plugin update and sync --global retained the new commit, while a Claude native registration and the shared marketplace remained unchanged. A real SIGKILL after journal creation was followed by a successful recovery through sync --global on macOS. With two plugins on two tools, each update or sync used one real Git clone and two builds, with no file drift.

  • Real isolated OpenCode project v5.12.0 → v5.13.0 update removed obsolete files from disk and manifest. An all installation updated all nine plugins, with 465 tracked files matching their hashes and no orphaned old files. A collision refused the update before changing the marketplace or user file.

  • Real isolated OpenCode/Kilo global sync restored deleted owned files; modified files and symbolic links were refused. Real Claude startup and OpenCode TUI tests verified marketplace source selection and global plugin notices.

  • Real Codex skill sessions updated v5.12.0 to v5.13.0 for OpenCode project/global, project-only while leaving global unchanged, and native Claude and Copilot marketplaces. A second interactive Codex run updated project/global OpenCode with 158/158 and 156/156 owned files matching their hashes. Real Kilo --continue displayed the notice.

  • An interactive Codex run with the real v5.12.0 marketplace displayed the new notice, including the v5.13.0 tag, release title and plugin version change.

  • Real CLI previews for project and global OpenCode installations displayed release notes and comparison links before confirmation.

  • The real pre-push hook passed from a linked worktree: 7,432 CLI tests passed, 3 skipped. The hook-isolation regression and 1,031 script tests also passed. A final real Codex preview showed the release title and project/global impact, and left all 312 installed files unchanged after declining confirmation.

  • Local gates: 7,432 CLI tests passed, 3 skipped. After the latest test additions, local runtime mutation scored 90.22% (90% threshold); presentation mutation scored 95.2% (95% threshold) before the subsequent Git security and test-cleanup changes. GitHub CI passed on the final revision, including Windows.

  • A real Codex skill session previewed a shared Claude installation, refused to write without approval, then updated the selected local plugin from 2.9.0 to 2.10.0; the user-scope registry remained 2.9.0 and both enabled states were preserved. A real Claude run also updated a legacy project with no native registration and preserved disabled states without adding claims.

  • Real Codex skill sessions displayed the descriptive release title and a project/global OpenCode inventory, then updated the project and global scopes after separate approvals. After both updates 158 project and 156 global files matched their manifests, with no obsolete files left.

  • A further real Codex skill session ran the authenticated update with Git and Node debug enabled: 158 files matched the manifest, and no raw or encoded token was found in the 1,149 files checked, including logs and Git configs. A local adversarial Git server reflecting an authorization header was tested without a credential in the logs.

  • A real Vitest startup test leaves old user directories intact under a private TMPDIR; the previous sweeper failed the same scenario.

  • An isolated real Claude project updated from v5.12.0 to v5.13.0: aidd-context moved from 2.9.0 to 2.10.0 in Claude's local registry and cache. An earlier isolated run with both scopes confirmed the native update preserves a disabled local plugin and does not update the user-scope registry.

  • OpenCode Desktop 2.2.5 experimental POC displayed the version and release title after a real server session creation, using an isolated profile and the installed hook. The project directory came from the event; the installed script path was fixed in the POC. No GUI integration is included.

  • A real Codex session verified that an unwritable Antigravity .agents directory stops before changing 467 files or manifests; after targeted access, project OpenCode and Antigravity plus global OpenCode updated successfully, preserving a third-party hook.

  • The real aidd run opencode launcher displayed the notice and returned a real model response. One earlier launcher attempt failed for an unknown reason; the launcher now reports safe error codes without exposing hook output.

Limitations

  • Claude project refresh currently refuses custom CLAUDE_CONFIG_DIR. Shared catalogue previews report installations known to the host and note that other dependents may exist. Source and inventory are rechecked before native writes, but a concurrent external Claude change after the recheck is not locked out.
  • Credentials explicitly embedded in source URLs can still be persisted in manifests; the Git clone fix does not prevent or remove that. The test suite no longer automatically cleans abandoned temporary directories.
  • Depends on feat(cli): install the framework for every project with setup --global #1142; retarget to next after it merges.
  • Direct local plugin install for Codex is a pre-existing CLI limitation: it materializes plugin files without activating them. Cursor display remains unverified because the test account reached its usage limit. Copilot VS Code remains unverified; its Legacy Local and Copilot harnesses can send indistinguishable startup payloads but document different output shapes. OpenCode Desktop has no GUI entry in this plugin and its GUI API is experimental. Kilo VS Code 7.4.1 backend was tested and does not run the startup notice; no documented GUI notification path was confirmed. Codex native update commands succeeded in isolation, but a skill-driven refresh timed out in the protected test session; it reported the partial state and the skill-driven success path remains unverified.
  • The CLI global release command covers pinned OpenCode/Kilo copies and reports native claims as skipped; the skill handles the tested pinned Claude/Copilot GitHub marketplaces separately and describes the tested Codex native commands. Cursor's pinned source remains unsupported. Maintenance is not yet in a published release, so its own update between public releases cannot yet be tested. A marketplace refresh alone does not verify installed plugins.
  • Automatic stale-lock recovery is limited to identifiable processes in the same boot on macOS/Linux; Windows and orphaned auxiliary guards require manual verification and cleanup. The journal handles process interruption, not power loss or concurrent external writes between checks.
  • Existing pinned caches with noncanonical line endings can be refused for manual inspection instead of being silently rewritten.
  • A late network or host failure after a project update has started can leave a reported partial update. The skill instructs the user to inspect the marketplace and plugin manifests before any retry.
  • Direct opencode run / kilo run do not expose the startup notice; use the explicit AIDD launcher. The launcher refuses remote servers, overridden config directories and ambiguous project/global copies.

Refs #1114
Refs #980

✅ I certify

  • I DO CERTIFY I READ EACH LINE OF THE PULL REQUEST BECAUSE I AM A SOFTWARE ENGINEER, NOT A AI PUPPY.

@alexsoyes alexsoyes left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je me demande aussi si tout est bien déterministe et si tout est suffisamment généraliste pour accueillir les nouveaux prochains IDEs ? faisons la même chose avec Codex

"hooks": [
{
"type": "command",
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.cjs\"",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c'est que pour claude ça ? a terme on aura tous les IDEs hein oublie pas + rajoute tableau de comptabilité dans le readme

@alexsoyes alexsoyes left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revue Alex, y'a beaucoup de texte, que ce soit du code ou des instructions dans les actions / skills, allons à l'essentiel sans perdre d'info.

- Claude Code: `claude plugin marketplace update aidd-framework`, then `claude plugin update <plugin>@aidd-framework` for each selected installed reference and its actual scope. Updating a plugin requires a new session. [Claude Code plugin reference](https://code.claude.com/docs/en/cli-reference)
- Copilot CLI: `copilot plugin marketplace update aidd-framework`, then `copilot plugin update <plugin>@aidd-framework` for each selected installed reference. A directory-source marketplace loads its local files, not a remote release. [Copilot CLI plugin reference](https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-plugin-reference)
- Codex: `codex plugin marketplace upgrade aidd-framework` refreshes a configured Git marketplace; it does not itself establish that every installed plugin changed. [Codex plugin documentation](https://developers.openai.com/plugins/build/plugins)
- Cursor, OpenCode and Kilo: an equivalent direct native release upgrade is unverified. Use their installed tool's own documented flow or report the limitation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est à toi de faire cette regarde on veut un support de 100% et etre sur, ensuite fais un tableau.

@alexsoyes
alexsoyes force-pushed the feat/aidd-maintenance branch from ff247fa to 31932ab Compare November 5, 2026 00:56
@alexsoyes
alexsoyes changed the base branch from next to feat/global-install November 5, 2026 00:56
@alexsoyes
alexsoyes force-pushed the feat/aidd-maintenance branch 2 times, most recently from 497b3d6 to 8124d15 Compare November 5, 2026 02:02
alexsoyes and others added 16 commits November 6, 2026 05:34
Until now `setup --scope user` only registered the framework source: it refused --plugins, refused
OpenCode, and installed nothing, so every machine-wide install lived in make reload's own copies.

`aidd setup --global --ide claude,codex,opencode --plugins all|recommended|<names>` now installs:
Claude Code, Codex and Copilot enable the plugins through their own CLI at user scope; OpenCode,
which has no plugin system, gets each plugin's skills and agents copied into ~/.config/opencode,
and Codex, whose plugins cannot carry agents, its agents into ~/.codex/agents. A profile declares
those copies as `machineFiles`; they are recorded in the machine manifest as user-scope plugins
and written by the existing user-scope plugin writer, so `sync --global` rebuilds them from the
framework source and `clean --global` removes them without touching files aidd did not write.

`--global` is the spelling of `--scope user` on setup, sync, doctor and clean, and `--ide` names
every tool, AI assistants included (`--ai` stays as a hidden former spelling).
… setup --global

The reload hands this checkout to aidd setup --global --source local --plugins all, the way a user installs machine-wide, instead of copying skills and agents by hand. Claude and Codex get their plugins afresh each run, since an edited plugin keeps its version. Copilot and Cursor are unchanged.
…nymore

Since the generic sub-agents shipped, every profile declares its agent frontmatter in agent-format.ts; agent-frontmatter-strip.ts and its test were left with no caller.
…o too

- Kilo copies skills and agents into ~/.config/kilo, as OpenCode does.
- Cursor copies plugins into ~/.cursor/plugins/local.
- Copilot 1.0.98 answers marketplace list --json: its local source is now proven,
  so setup --global enables the plugins through its CLI.
- Plan user-scope plugin updates one at a time: plans for one tool share its built tree.
- Copilot and Cursor leave the script's own build and copy: setup --global installs them,
  with Kilo now detected too. Copilot is released afresh each reload, like Claude and Codex.
- Kilo documents no global AGENTS.md, so the reload writes it no instructions.
- Docs: INSTALL.md shows the machine-wide install, update and removal; the CLI README,
  memory and smoke-real tool list follow every tool now supporting --global.
…gins in place

- setup --global runs from HOME: the checkout's own .claude/settings.json enables the plugins
  at project scope, which the hosts report and the CLI refuses as refs it does not own.
- Copilot is no longer uninstalled each reload: its uninstall leaves every plugin disabled
  rather than gone, which the next setup --global refuses the same way.
- doctor --global stops asking a project to declare the marketplace, which a machine-wide
  install never writes there, and its messages name setup --global.
…ilot

- Claude 2.1.312's marketplace remove --scope user drops the settings declaration and keeps
  the registration: a user-scope remove now names no scope, from the home directory
  (NativeActivation.userRemoveArgs), so clean deletes it and the next setup declares it again.
- Copilot's uninstall leaves each ref disabled rather than gone: a disabled ref there is no
  longer taken for a plugin in use (NativeActivation.uninstallLeavesRefDisabled), so setup
  after clean enables the plugins again. Claude keeps refusing a ref the person disabled.
- make reload removes Claude's marketplace from every scope, from HOME, for the same reason.
…of the plugins

Plugins enabled, global instructions, skills and agents, per installed tool: asked of the tool
where it can answer, read from the files its documentation names where it cannot. Exits 1 when
an installed tool misses something.
- Claude's plugins, skills and agents come from its session's init event, compared by name; the
  session runs without hooks or a saved transcript.
- A listed skill counts only under the tool's config directory and while its file exists.
- Cursor reads names from the frontmatter alone; global instructions need the managed block.
- No plugin to expect, or a tool answering no config directory, is a failure, not 0/0.
- OpenCode's service is read again while it starts cold, until it lists every skill.
- A test per tool, and one per false positive.
Removing Claude's marketplace from every scope also uninstalls what a project installed from it,
with its saved options. clean --global and make reload now do that only when no project uses the
marketplace, and stay at user scope otherwise, or when the list cannot be read.
The README's clean --global example names --force, without which it previews or asks.
…hing later

Every plugin's plan is checked before the first write, the manifest is saved
after each plugin, and a rerun takes over identical files on Cursor as it
already did on the flat tools.
…touch only what it names

sync --global writes back a recorded file that was deleted. A remote source's
clone and plugin fetches live in the user's cache, never the current directory.
Only the tools a run names get the chosen plugins. A rerun takes the source it
resolved. Without the shared source, global files are refused rather than rebuilt
in a project's layout. make reload shows what setup skipped.
--global is the word people know. The names already on next stay for their own change.
Keep successful native plugin selections recoverable, protect unowned files, and complete global cleanup without removing other marketplace sources. Restore managed OpenCode reload compatibility.

Refs: #1142
@alexsoyes
alexsoyes force-pushed the feat/aidd-maintenance branch from caaeedf to 9458178 Compare November 6, 2026 08:21
Base automatically changed from feat/global-install to next November 7, 2026 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants