Non-breaking work that can ship without waiting for v3. For breaking changes, see NEXT-MAJOR.md.
Refs: GH = caffeinelabs/mops, LIN = Linear ticket title.
Trust / lockfile / registry
mops verifyas an explicit on-disk integrity command. The breaking half (removing the implicit re-hash frominstall) waits for v3. (GH #517)--lockedwith strict-lockfile semantics (fail ifmops.lockis missing or would change; never write it), oninstalland every implicitly-resolving command. Oldmops installunchanged. Decided 2026-07 against a separatemops cicommand — cargo/pnpm/yarn all use a flag; seeNEXT-MAJOR.md. The breaking half (droppingCIenv-var auto-detection incli/integrity.ts:50-59, dropping--lock) waits for v3. (GH #516)- Resolve dependency tree on the backend — additive query method. (GH #19)
yank/deprecate/unpublish. (GH #291)- Downloadable package index (cargo/purescript style), additive endpoint. (GH #291)
Security / dependency hygiene
ReplaceDone:decompress(critical, no fix available).downloadFromGithubextracts withfflateplus explicit path containment (cli/helpers/extract-github-zip.ts); thedecompressdependency is removed andnpm auditis clean.
Bundling / runtime
MOPS_PASSWORD/--passwordfor non-interactive identity (todaygetIdentity()blocks on stdin for encrypted PEMs —cli/mops.ts:59-82).- Standalone binary distribution alongside npm — additive third channel. (LIN: standalone binary)
- Narrow
filesincli/package.json(currently["*"]with a few exclusions). The published npm tarball ships both distributions: the unbundleddist/tree thatbinactually points at and the 5.9 MB bunbundle/cli.jsthat only thecli.mops.oneinstaller uses (that installer downloadsbundle/cli.tgzfrom the releases canister instead —cli-releases/install.sh→cli/release-cli.ts:33-41). Excludingbundle/would roughly halve the npm download. Pre-existing; found while investigating the@dfinity/picpostinstall (seeNEXT-MAJOR.md).
Backend additions
- File blobs in stable memory (storage canisters). Invisible to clients. (GH #18)
- Tarball storage. Invisible if per-file API stays for one cycle. (GH #291)
- Expose replica/PocketIC canister id to test harnesses. (GH #274)
benchinternal canister →core. (GH #354 partial)semver.mo: pre-release tag support. (backend/main/utils/semver.mo:70)
- Cargo-style version syntax — phased to avoid breaking old CLIs (
Semver.validateis strictxx.xx.xxtoday — old CLIs would crash on^1.2.3in a fetchedmops.toml):- 2.x CLI-only: parse
=/^/~/>=,<and respect them only in the consuming app'smops.toml(root + local-path deps).mops publishkeeps rejecting non-bare versions client-side. Zero risk for old CLIs. - Coordinated CLI + backend with
apiVersionmajor bump: backendSemver.validateaccepts new syntax (backend/main/utils/semver.mo:71);mops publishallows it in published[dependencies]. Old CLIs hit the existing major-mismatch path (cli/mops.ts:289-300) and refuse with "upgrade required" instead of crashing. - v3+: deprecation warning when a bare pin is silently overridden by max-wins; flip bare
1.2.3to mean^1.2.3. (seeNEXT-MAJOR.md)
- 2.x CLI-only: parse
- Install-as alias: new
foo = { name = "core", … }form, plain string still works. (GH #266) - Packages can declare exported
.didfiles inmops.toml; CLI auto-injects matching--actor-id-aliasmoc flags (mirrors how lintoko rules are exported). Ship a separateic-didpackage for the management canister, auto-published with major bumps on Motoko-incompatible changes. Replaces the broken-today manual download/commit workflow. (LANG-1280, GH #492) - Multi-version: schema can land before moc
--override; resolver rejects until then. (GH #283) - Local-path transitives: relax remaining edge-cases (today
installLocalDeprecurses but resolver edges still misbehave). (GH #289)
MOPS_*env-var overrides (MOPS_NETWORK,MOPS_REGISTRY_HOST,MOPS_REGISTRY_CANISTER_ID,MOPS_VERIFY_QUERY_SIGNATURES,MOPS_CWD,MOPS_ENV): document, log when active, add proper flag equivalents. Today they silently change registry/network/cwd. (cli/api/network.ts,cli/api/actors.ts,cli/cli.ts:72)dfx-bundled moc fallback: warn on every fallback today (cli/commands/toolchain/index.ts:359,387,cli/commands/docs.ts:44-54); drop in v3.- WASI
wasmtimePATH fallback already labelled "legacy" — already warns (cli/commands/test/test.ts:270-280); remove in v3. // compatibility with older versionsre-exports (cli/mops.ts:324-325): mark@deprecated, document successors.--legacy-persistencedefault inbench(cli/commands/bench.ts:253): one-line deprecation when used.
mops watch --format: gate behind[watch] format = truein 2.x; flip default in v3.- Test reporter:
[test] reporter = "verbose"opt-in; flip default in v3. - Lintoko on
check: already runs when pinned (2.6) — fine. The "always-on" flip waits for v3.
- HTTP layer: respect
HTTP_PROXY/HTTPS_PROXY, raise TCP timeouts, fix Docker-on-mac hangs. (GH #228, #256, #304) - Reduce bundle size:
glob→tinyglobby,tar→tar-fs + node:zlib,decomp-tarxz→xz-decompress. (GH #296) - Remove transitive deprecation warnings on
npm i -g ic-mops(@dfinity/*→@icp-sdk/core/*, oldglob, etc.). (LIN: remove deprecation warnings) - Update
benchinternal canister tocore. (GH #354, LIN) - Drop
--legacy-persistencedefault inbench(cli/commands/bench.ts:253). - Switch
@iarna/toml→smol-toml(cli/mops.ts:5). Active maintenance, ~5x faster parse, smaller bundle, better TOML 1.0 compliance. Round-trip reformat behavior ofwriteConfig(cli/mops.ts:229-257) is unchanged — both are value-only parsers; comments and key ordering are still lost onadd/remove/bump/toolchain use/init. Format preservation is a separate, harder problem (would need@taplo/libor surgical string edits).
Cargo/npm has these, mops doesn't, and that's been fine. Pull individual items up if a user asks.
Cargo-style command parity
mops tree— resolved graph + duplicates.mops why <pkg>— inverse tree, "who pulled this in?".mops doctor— environment + cache + lockfile health.mops metadata— JSON dump of resolved graph + manifest (unblocks IDE integrations).--jsonoutput foroutdated,search,info.mops add foo bar baz— accept multiple packages.--dry-runforadd,install,update,sync(today onlyremovehas it).--manifest-path/-C <dir>global flag.- Global
-q/--quietconsistency. mops uninstallas alias forremove.
Publish ergonomics
mops publish --dry-run— rehearse upload, validate the packed tree.mops publish --allow-dirty— matchcargo publishsemantics around VCS state.- Pack preview on disk — write the tarball that would be uploaded.