contract-driven-delivery 2.0.1 → 2.0.2
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/CHANGELOG.md +21 -0
- package/bin/postinstall.js +20 -0
- package/dist/cli/index.js +62 -33
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.2] - 2026-04-30
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `npm postinstall` hook: after `npm install -g` or `npm update -g`, skills and
|
|
8
|
+
agents in `~/.claude/` are automatically synced to the newly installed version.
|
|
9
|
+
The sync is a no-op when `cdd-kit init` has never been run (safe for CI and
|
|
10
|
+
local dev installs of the package itself). A backup of any locally modified
|
|
11
|
+
files is created in `~/.claude/.cdd-kit-backup/<timestamp>/` before overwriting,
|
|
12
|
+
matching the existing `cdd-kit update --yes` behaviour.
|
|
13
|
+
- `cdd-kit update --postinstall` flag (internal): quiet mode that implies
|
|
14
|
+
`--yes`, locks provider to `claude`, and silently exits when the skill
|
|
15
|
+
directory is absent. Not intended for direct user invocation.
|
|
16
|
+
|
|
17
|
+
### Migration note
|
|
18
|
+
|
|
19
|
+
The first `npm update -g contract-driven-delivery` that brings in this version
|
|
20
|
+
will **not** auto-sync (the postinstall hook did not exist in the previously
|
|
21
|
+
installed version). Run `cdd-kit update --yes` once after this upgrade; all
|
|
22
|
+
subsequent upgrades will auto-sync.
|
|
23
|
+
|
|
3
24
|
## [2.0.1] - 2026-04-30
|
|
4
25
|
|
|
5
26
|
### Fixed
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { join, dirname } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
const cliPath = join(__dirname, '..', 'dist', 'cli', 'index.js');
|
|
11
|
+
if (!existsSync(cliPath)) process.exit(0);
|
|
12
|
+
|
|
13
|
+
spawnSync(process.execPath, [cliPath, 'update', '--postinstall'], {
|
|
14
|
+
stdio: 'inherit',
|
|
15
|
+
timeout: 30_000,
|
|
16
|
+
});
|
|
17
|
+
process.exit(0);
|
|
18
|
+
} catch {
|
|
19
|
+
process.exit(0);
|
|
20
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -11673,7 +11673,16 @@ function backupDir(dir, backupDest) {
|
|
|
11673
11673
|
walk(dir, backupDest);
|
|
11674
11674
|
}
|
|
11675
11675
|
async function update(opts) {
|
|
11676
|
-
|
|
11676
|
+
if (opts.postinstall) {
|
|
11677
|
+
if (!existsSync5(join6(SKILLS_HOME, "contract-driven-delivery"))) {
|
|
11678
|
+
return;
|
|
11679
|
+
}
|
|
11680
|
+
opts.yes = true;
|
|
11681
|
+
opts.provider = "claude";
|
|
11682
|
+
}
|
|
11683
|
+
const quiet = !!opts.postinstall;
|
|
11684
|
+
if (!quiet)
|
|
11685
|
+
log.blank();
|
|
11677
11686
|
const cwd = process.cwd();
|
|
11678
11687
|
const requestedProvider = opts.provider ?? "auto";
|
|
11679
11688
|
if (!validateProviderOption(requestedProvider)) {
|
|
@@ -11689,28 +11698,32 @@ async function update(opts) {
|
|
|
11689
11698
|
const toAdd = toWrite.filter((e) => e.action === "add");
|
|
11690
11699
|
const toOver = toWrite.filter((e) => e.action === "overwrite");
|
|
11691
11700
|
const toSkip = [...agentDiff, ...skillDiff].filter((e) => e.action === "skip");
|
|
11692
|
-
|
|
11693
|
-
|
|
11694
|
-
|
|
11695
|
-
|
|
11696
|
-
|
|
11697
|
-
|
|
11698
|
-
|
|
11701
|
+
if (!quiet) {
|
|
11702
|
+
log.info(`Provider: ${provider}`);
|
|
11703
|
+
if (updateClaudeAssets) {
|
|
11704
|
+
log.info(`Dry-run diff \u2014 agents: ${AGENTS_HOME}`);
|
|
11705
|
+
log.info(`Dry-run diff \u2014 skill: ${skillDest}`);
|
|
11706
|
+
} else {
|
|
11707
|
+
log.info("Codex provider has no global cdd-kit assets to update.");
|
|
11708
|
+
log.info("Project files are preserved; run cdd-kit init --local-only --provider codex to add missing local guidance.");
|
|
11709
|
+
}
|
|
11710
|
+
log.blank();
|
|
11711
|
+
if (toAdd.length)
|
|
11712
|
+
log.info(` + ${toAdd.length} file(s) would be added`);
|
|
11713
|
+
if (toOver.length)
|
|
11714
|
+
log.warn(` ~ ${toOver.length} file(s) would be overwritten (user edits lost without backup)`);
|
|
11715
|
+
if (toSkip.length)
|
|
11716
|
+
log.dim(` ${toSkip.length} file(s) unchanged (skipped)`);
|
|
11699
11717
|
}
|
|
11700
|
-
log.blank();
|
|
11701
|
-
if (toAdd.length)
|
|
11702
|
-
log.info(` + ${toAdd.length} file(s) would be added`);
|
|
11703
|
-
if (toOver.length)
|
|
11704
|
-
log.warn(` ~ ${toOver.length} file(s) would be overwritten (user edits lost without backup)`);
|
|
11705
|
-
if (toSkip.length)
|
|
11706
|
-
log.dim(` ${toSkip.length} file(s) unchanged (skipped)`);
|
|
11707
11718
|
if (toWrite.length === 0) {
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
|
|
11719
|
+
if (!quiet) {
|
|
11720
|
+
log.blank();
|
|
11721
|
+
log.ok("Already up to date \u2014 nothing to write.");
|
|
11722
|
+
log.blank();
|
|
11723
|
+
}
|
|
11711
11724
|
return;
|
|
11712
11725
|
}
|
|
11713
|
-
if (!opts.yes) {
|
|
11726
|
+
if (!quiet && !opts.yes) {
|
|
11714
11727
|
log.blank();
|
|
11715
11728
|
log.info("Run with --yes to apply changes. Example:");
|
|
11716
11729
|
log.dim(" cdd-kit update --yes");
|
|
@@ -11719,25 +11732,41 @@ async function update(opts) {
|
|
|
11719
11732
|
}
|
|
11720
11733
|
const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11721
11734
|
const backupRoot = join6(homedir2(), ".claude", ".cdd-kit-backup", timestamp2);
|
|
11722
|
-
|
|
11723
|
-
|
|
11735
|
+
if (!quiet) {
|
|
11736
|
+
log.blank();
|
|
11737
|
+
log.info(`Backing up to ${backupRoot} \u2026`);
|
|
11738
|
+
}
|
|
11724
11739
|
backupDir(AGENTS_HOME, join6(backupRoot, "agents"));
|
|
11725
11740
|
backupDir(skillDest, join6(backupRoot, "skill"));
|
|
11726
|
-
|
|
11727
|
-
|
|
11741
|
+
if (!quiet)
|
|
11742
|
+
log.ok(`Backup complete: ${backupRoot}`);
|
|
11743
|
+
if (!quiet)
|
|
11744
|
+
log.blank();
|
|
11745
|
+
let totalSynced = 0;
|
|
11728
11746
|
if (updateClaudeAssets) {
|
|
11729
|
-
|
|
11747
|
+
if (!quiet)
|
|
11748
|
+
log.info(`Updating agents \u2192 ${AGENTS_HOME}`);
|
|
11730
11749
|
const agentCount = applyDir(agentDiff);
|
|
11731
|
-
|
|
11732
|
-
|
|
11750
|
+
if (!quiet)
|
|
11751
|
+
log.ok(`${agentCount} agent file(s) updated.`);
|
|
11752
|
+
totalSynced += agentCount;
|
|
11753
|
+
if (!quiet)
|
|
11754
|
+
log.info(`Updating skill \u2192 ${skillDest}`);
|
|
11733
11755
|
const skillCount = applyDir(skillDiff);
|
|
11734
|
-
|
|
11756
|
+
if (!quiet)
|
|
11757
|
+
log.ok(`${skillCount} skill file(s) updated.`);
|
|
11758
|
+
totalSynced += skillCount;
|
|
11759
|
+
}
|
|
11760
|
+
if (quiet) {
|
|
11761
|
+
if (totalSynced > 0)
|
|
11762
|
+
log.ok(`cdd-kit: synced ${totalSynced} file(s) to ~/.claude/`);
|
|
11763
|
+
} else {
|
|
11764
|
+
log.blank();
|
|
11765
|
+
log.info("Project files (contracts/, specs/, tests/, ci/) were not changed.");
|
|
11766
|
+
log.ok("Update complete.");
|
|
11767
|
+
log.info(`Backup saved to: ${backupRoot}`);
|
|
11768
|
+
log.blank();
|
|
11735
11769
|
}
|
|
11736
|
-
log.blank();
|
|
11737
|
-
log.info("Project files (contracts/, specs/, tests/, ci/) were not changed.");
|
|
11738
|
-
log.ok("Update complete.");
|
|
11739
|
-
log.info(`Backup saved to: ${backupRoot}`);
|
|
11740
|
-
log.blank();
|
|
11741
11770
|
}
|
|
11742
11771
|
|
|
11743
11772
|
// src/commands/new-change.ts
|
|
@@ -12657,7 +12686,7 @@ program.command("init").description(
|
|
|
12657
12686
|
provider: opts.provider
|
|
12658
12687
|
})
|
|
12659
12688
|
);
|
|
12660
|
-
program.command("update").description("Update provider assets for the current project (does not overwrite project guidance files)").option("--yes", "Apply changes (default is dry-run)", false).option("--provider <provider>", "Provider adapter to update: auto, claude, codex, or both", "auto").action((opts) => update({ yes: opts.yes, provider: opts.provider }));
|
|
12689
|
+
program.command("update").description("Update provider assets for the current project (does not overwrite project guidance files)").option("--yes", "Apply changes (default is dry-run)", false).option("--provider <provider>", "Provider adapter to update: auto, claude, codex, or both", "auto").option("--postinstall", "Internal: invoked by npm postinstall; no-op if cdd has not been init-ed", false).action((opts) => update({ yes: opts.yes, provider: opts.provider, postinstall: opts.postinstall }));
|
|
12661
12690
|
program.command("doctor").description("Inspect cdd-kit repo health, provider guidance, and context index freshness").option("--strict", "Treat warnings as errors", false).option("--json", "Print a machine-readable health report", false).option("--provider <provider>", "Provider adapter to inspect: auto, claude, codex, or both", "auto").option("--fix", "Auto-resolve safe warnings (stale context indexes, missing role bindings)", false).action(async (opts) => {
|
|
12662
12691
|
const { doctor: doctor2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
|
|
12663
12692
|
await doctor2({ strict: opts.strict, json: opts.json, provider: opts.provider, fix: opts.fix });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "contract-driven-delivery",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Contract-driven delivery kit for AI coding agents with deterministic context indexes, manifest-backed read-scope governance, and orchestrated contracts-first delivery.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contract-driven",
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"build": "node build.js",
|
|
41
41
|
"test": "vitest run",
|
|
42
42
|
"test:watch": "vitest",
|
|
43
|
-
"prepublishOnly": "node build.js && vitest run"
|
|
43
|
+
"prepublishOnly": "node build.js && vitest run",
|
|
44
|
+
"postinstall": "node bin/postinstall.js"
|
|
44
45
|
},
|
|
45
46
|
"engines": {
|
|
46
47
|
"node": ">=18.0.0"
|