@logicseek/hello-cc 1.1.4 → 1.1.5

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 CHANGED
@@ -7,6 +7,7 @@ Before publishing, run:
7
7
 
8
8
  ```bash
9
9
  npm run release:check
10
+ npm run release:artifact:check
10
11
  npm run release:notes
11
12
  npm run release:github:dry-run
12
13
  ```
@@ -16,6 +17,27 @@ the release description from the current changelog section. Use
16
17
  `npm run release:github` with `GH_TOKEN` or `GITHUB_TOKEN` only for local
17
18
  backfills.
18
19
 
20
+ ## 1.1.5
21
+
22
+ ### Summary
23
+
24
+ Require a verified immutable package before npm publication or GitHub Release
25
+ creation so a missing release manifest fails before publication.
26
+
27
+ ### Highlights
28
+
29
+ - Check the versioned frozen manifest, archive digest, packaged files and modes
30
+ before publishing. Reject a requested version that differs from the package.
31
+ - Include the frozen npm archive and file manifest used by release-mode
32
+ DeepSeek Harness acceptance; preserve all previously published tags and files.
33
+ - Keep the 1.1.4 runtime behavior, including opted-in App inbox listener recovery.
34
+
35
+ ### Validation
36
+
37
+ Release preflight tests cover a matching immutable package, missing manifests,
38
+ source drift and version mismatches. DeepSeek Harness 0.2.0-rc.2 and 0.2.1-rc.3
39
+ are checked on Linux and macOS alongside repository, Web and native workflows.
40
+
19
41
  ## 1.1.4
20
42
 
21
43
  ### Summary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logicseek/hello-cc",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "Local control plane for coordinating Claude Code, Codex, and other coding CLI sessions.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,6 +27,7 @@
27
27
  "scripts": {
28
28
  "release:notes": "node ./scripts/release-notes.mjs",
29
29
  "release:check": "node ./scripts/release-notes.mjs --check",
30
+ "release:artifact:check": "node ./scripts/dsh-package-provenance.mjs --check-release",
30
31
  "release:github": "node ./scripts/github-release.mjs",
31
32
  "release:github:dry-run": "node ./scripts/github-release.mjs --dry-run",
32
33
  "smoke": "node ./bin/hcc.mjs --help",
@@ -41,7 +42,7 @@
41
42
  "build:native:cwd-handoff": "node ./scripts/build-cwd-handoff.mjs",
42
43
  "release:native:verify": "node ./scripts/verify-cwd-handoff-package.mjs",
43
44
  "release:native:pack": "node ./scripts/pack-cwd-handoff.mjs",
44
- "prepublishOnly": "npm run release:native:verify"
45
+ "prepublishOnly": "npm run release:check && npm run release:artifact:check && npm run release:native:verify"
45
46
  },
46
47
  "repository": {
47
48
  "type": "git",
@@ -2,11 +2,13 @@
2
2
  // Harness, calling a model, changing an archive, or publishing a package.
3
3
  import assert from 'node:assert/strict';
4
4
  import fs from 'node:fs';
5
+ import os from 'node:os';
5
6
  import path from 'node:path';
6
7
  import { createHash } from 'node:crypto';
7
8
  import { execFileSync } from 'node:child_process';
8
9
  import { fileURLToPath, pathToFileURL } from 'node:url';
9
10
  import { DSH_BASELINE_VERSION, DSH_SUPPORTED_VERSIONS } from '../lib/integrations/dsh-versions.mjs';
11
+ import { normalizeVersion } from '../lib/release/release-notes.mjs';
10
12
 
11
13
  const ARCHIVED_BASELINE = 'docs/verification/dsh-1.0.3-package.json';
12
14
  const hash = file => createHash('sha256').update(fs.readFileSync(file)).digest('hex');
@@ -69,7 +71,9 @@ export function freezeAcceptancePackage({ root, repo = fileURLToPath(new URL('..
69
71
  const run = (command, args) => execFileSync(command, args, { cwd: repo, env: childEnv, encoding: 'utf8', maxBuffer: 8 * 1024 * 1024 });
70
72
  const npm = args => env.npm_execpath
71
73
  ? run(process.execPath, [env.npm_execpath, ...args]) : run('npm', args);
72
- const metadata = JSON.parse(npm(['pack', '--ignore-scripts', '--json', '--pack-destination', path.join(root, 'candidate')]))[0];
74
+ // A parent npm publish --dry-run exports npm_config_dry_run. The preflight
75
+ // still needs real local archive bytes in order to verify the package.
76
+ const metadata = JSON.parse(npm(['pack', '--ignore-scripts', '--dry-run=false', '--json', '--pack-destination', path.join(root, 'candidate')]))[0];
73
77
  if (env.GITHUB_REF?.startsWith('refs/tags/v')) {
74
78
  assert.equal(mode, 'release', 'Version tags require immutable release acceptance');
75
79
  assert.equal(env.GITHUB_REF.slice('refs/tags/v'.length), metadata.version, 'Version tag must match the package version');
@@ -103,17 +107,40 @@ export function freezeAcceptancePackage({ root, repo = fileURLToPath(new URL('..
103
107
  return receipt;
104
108
  }
105
109
 
110
+ export function checkReleaseArtifact({ repo, env = process.env, version } = {}) {
111
+ const expectedVersion = version ? normalizeVersion(version) : null;
112
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'hcc-release-artifact-check-'));
113
+ try {
114
+ const receipt = freezeAcceptancePackage({ repo, root, mode: 'release',
115
+ env: { ...env, GITHUB_OUTPUT: '' } });
116
+ if (expectedVersion) assert.equal(receipt.package.version, expectedVersion,
117
+ 'Requested release must match the checked package version');
118
+ return receipt;
119
+ } finally {
120
+ fs.rmSync(root, { recursive: true, force: true });
121
+ }
122
+ }
123
+
106
124
  if (process.argv[1] && pathToFileURL(path.resolve(process.argv[1])).href === import.meta.url) {
107
125
  try {
108
126
  const options = new Map();
109
- for (let index = 2; index < process.argv.length; index += 2) {
110
- const key = process.argv[index], value = process.argv[index + 1];
111
- assert.ok(['--mode', '--output-dir'].includes(key) && value && !value.startsWith('--'), `Invalid option: ${key}`);
127
+ for (let index = 2; index < process.argv.length; index += 1) {
128
+ const key = process.argv[index];
129
+ if (key === '--check-release') { options.set(key, true); continue; }
130
+ const value = process.argv[++index];
131
+ assert.ok(['--mode', '--output-dir', '--version'].includes(key) && value && !value.startsWith('--'), `Invalid option: ${key}`);
112
132
  options.set(key, value);
113
133
  }
114
- const mode = options.get('--mode') || resolveAcceptanceMode({ eventName: process.env.GITHUB_EVENT_NAME,
115
- ref: process.env.GITHUB_REF, dispatchMode: process.env.HCC_DSH_DISPATCH_MODE });
116
- console.log(JSON.stringify(freezeAcceptancePackage({ root: options.get('--output-dir') || process.env.HCC_DSH_ACCEPTANCE_ROOT, mode }), null, 2));
134
+ if (options.get('--check-release')) {
135
+ assert.ok(!options.has('--mode') && !options.has('--output-dir'),
136
+ '--check-release uses release mode and its own temporary directory');
137
+ console.log(JSON.stringify(checkReleaseArtifact({ version: options.get('--version') }), null, 2));
138
+ } else {
139
+ assert.ok(!options.has('--version'), '--version requires --check-release');
140
+ const mode = options.get('--mode') || resolveAcceptanceMode({ eventName: process.env.GITHUB_EVENT_NAME,
141
+ ref: process.env.GITHUB_REF, dispatchMode: process.env.HCC_DSH_DISPATCH_MODE });
142
+ console.log(JSON.stringify(freezeAcceptancePackage({ root: options.get('--output-dir') || process.env.HCC_DSH_ACCEPTANCE_ROOT, mode }), null, 2));
143
+ }
117
144
  } catch (error) {
118
145
  const details = String(error.stack || error.message || error).replaceAll('%', '%25').replaceAll('\r', '%0D').replaceAll('\n', '%0A');
119
146
  console.error(`::error::${details}`); process.exitCode = 1;