agentsys 5.11.0 → 5.12.0

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agentsys",
3
3
  "description": "20 specialized plugins for AI workflow automation - task orchestration, PR workflow, slop detection, code review, drift detection, enhancement analysis, documentation sync, unified static analysis, perf investigations, topic research, agent config linting, cross-tool AI consultation, structured AI debate, workflow pattern learning, codebase onboarding, contributor guidance, and Zig language support",
4
- "version": "5.11.0",
4
+ "version": "5.12.0",
5
5
  "owner": {
6
6
  "name": "Avi Fenesh",
7
7
  "url": "https://github.com/avifenesh"
@@ -40,11 +40,11 @@
40
40
  "source": {
41
41
  "source": "url",
42
42
  "url": "https://github.com/agent-sh/prepare-delivery.git",
43
- "commit": "693d7649501608da49aea8efe610a7029100b8f2",
44
- "ref": "v0.1.1"
43
+ "commit": "0e9685fe0e93e058af5ca9a0374f4f97e1db878c",
44
+ "ref": "v0.1.2"
45
45
  },
46
46
  "description": "Pre-ship quality gates: deslop, simplify, agnix, enhance, review loop, delivery validation, docs sync",
47
- "version": "0.1.1",
47
+ "version": "0.1.2",
48
48
  "category": "productivity",
49
49
  "homepage": "https://github.com/agent-sh/prepare-delivery"
50
50
  },
@@ -78,7 +78,7 @@
78
78
  "source": {
79
79
  "source": "url",
80
80
  "url": "https://github.com/agent-sh/deslop.git",
81
- "commit": "dc49a5309a104a011439f87b346d1c3b47375db2"
81
+ "commit": "00301b9ce81d12caa38063e4a65b535ba5b011b2"
82
82
  },
83
83
  "description": "3-phase AI slop detection: regex patterns (HIGH), multi-pass analyzers (MEDIUM), CLI tools (LOW)",
84
84
  "version": "1.0.0",
@@ -90,11 +90,11 @@
90
90
  "source": {
91
91
  "source": "url",
92
92
  "url": "https://github.com/agent-sh/audit-project.git",
93
- "commit": "2c961a84ab5945670be44d6c54eb496099effe48",
94
- "ref": "v1.0.1"
93
+ "commit": "f703facec38765b6fd8cb5a2076c98bf14e5998e",
94
+ "ref": "v1.0.2"
95
95
  },
96
96
  "description": "Multi-agent iterative code review until zero issues remain",
97
- "version": "1.0.1",
97
+ "version": "1.0.2",
98
98
  "category": "development",
99
99
  "homepage": "https://github.com/agent-sh/audit-project"
100
100
  },
@@ -103,7 +103,7 @@
103
103
  "source": {
104
104
  "source": "url",
105
105
  "url": "https://github.com/agent-sh/drift-detect.git",
106
- "commit": "e7edd602a0e24ae2bff8e262c58e481aae448944"
106
+ "commit": "576aca37402068aef175c8a6002584e19cb6ea74"
107
107
  },
108
108
  "description": "Deep repository analysis to realign project plans with code reality - detects drift, gaps, and creates prioritized reconstruction plans",
109
109
  "version": "1.0.0",
@@ -115,7 +115,7 @@
115
115
  "source": {
116
116
  "source": "url",
117
117
  "url": "https://github.com/agent-sh/enhance.git",
118
- "commit": "31e7d3861afb20b3d910be957387de23dc3ae854"
118
+ "commit": "93f299e494a3a9ea74e82bd2d15bc1c517ce8f0c"
119
119
  },
120
120
  "description": "Master enhancement orchestrator: parallel analyzer execution for plugins, agents, docs, CLAUDE.md, and prompts with unified reporting",
121
121
  "version": "1.0.0",
@@ -127,7 +127,7 @@
127
127
  "source": {
128
128
  "source": "url",
129
129
  "url": "https://github.com/agent-sh/sync-docs.git",
130
- "commit": "961f5e67b583f70a4e0ad3ad83503ab90decc11d"
130
+ "commit": "410e06739da101583b7238669f4acad7f5aea7ab"
131
131
  },
132
132
  "description": "Standalone documentation sync: find outdated refs, update CHANGELOG, flag stale examples based on code changes",
133
133
  "version": "1.0.0",
@@ -165,7 +165,7 @@
165
165
  "source": {
166
166
  "source": "url",
167
167
  "url": "https://github.com/agent-sh/learn.git",
168
- "commit": "e28ea11f4622509d1ae7425fa97f7dd719d43716"
168
+ "commit": "b3025d376a83841078f3ab5cf53b62c6960e46c3"
169
169
  },
170
170
  "description": "Research topics online and create comprehensive learning guides with RAG-optimized indexes",
171
171
  "version": "1.0.0",
@@ -190,7 +190,7 @@
190
190
  "source": {
191
191
  "source": "url",
192
192
  "url": "https://github.com/agent-sh/consult.git",
193
- "commit": "3115688a7c6079a04e8caa0183c1ca020e3d413d"
193
+ "commit": "8ce96f86c0ae67f732383a8b45c9994a7cd64d2a"
194
194
  },
195
195
  "description": "Cross-tool AI consultation: get second opinions from Gemini CLI, Codex CLI, Claude Code, OpenCode, or Copilot CLI with model and thinking effort control",
196
196
  "version": "1.0.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentsys",
3
- "version": "5.11.0",
3
+ "version": "5.12.0",
4
4
  "description": "Professional-grade slash commands for Claude Code with cross-platform support",
5
5
  "keywords": [
6
6
  "workflow",
package/CHANGELOG.md CHANGED
@@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [5.12.0] - 2026-04-26
13
+
14
+ ### Propagated upstream releases
15
+ - agent-core v0.4.4 (fixer.js symlink + TOCTOU) -> v0.4.5 (client-side SLSA verification + sync allowlist) synced into all 13 consumers.
16
+ - agent-analyzer v0.8.0 -> v0.8.1 (cargo-deny CI).
17
+ - prepare-delivery v0.1.2, audit-project v1.0.2 (reviewer-contract markers + orchestrator blocked handling).
18
+
12
19
  ## [5.11.0] - 2026-04-26
13
20
 
14
21
  ### Changed
@@ -19,6 +19,22 @@
19
19
  * script validates every zip entry before extracting it and rejects
20
20
  * absolute, UNC, and parent-traversal entries.
21
21
  *
22
+ * Verification chain (in order, each gate must pass to proceed):
23
+ * 1. TLS - https.get() pins the GitHub CA chain at the OS level.
24
+ * 2. SHA-256 sidecar - `<asset>.sha256` fetched from the same release and
25
+ * verified against the downloaded bytes. Closes basic tampering.
26
+ * 3. SLSA build provenance (optional / required) - `gh attestation verify`
27
+ * checks the Sigstore-signed attestation that agent-analyzer's release
28
+ * workflow publishes via `actions/attest-build-provenance`. This closes
29
+ * the "stolen release token uploads attacker binary + attacker sha256"
30
+ * hole that steps 1 and 2 cannot see.
31
+ *
32
+ * SLSA verification is SOFT by default: if `gh` is not on PATH we log
33
+ * a warning and proceed with just SHA-256. Set env var
34
+ * `AGENT_ANALYZER_REQUIRE_ATTESTATION=1` to make a missing `gh` a hard
35
+ * failure (recommended for CI). A present `gh` that reports a failed
36
+ * verification is ALWAYS a hard failure regardless of the env var.
37
+ *
22
38
  * @module lib/binary
23
39
  */
24
40
 
@@ -572,6 +588,117 @@ function findBinaryInScratch(scratch, binaryBaseName) {
572
588
  return null;
573
589
  }
574
590
 
591
+ // ---------------------------------------------------------------------------
592
+ // SLSA build provenance verification
593
+ // ---------------------------------------------------------------------------
594
+
595
+ /**
596
+ * Result of an attempted SLSA attestation verification.
597
+ * @typedef {Object} SlsaResult
598
+ * @property {'verified'|'skipped'|'failed'} status
599
+ * @property {string} [reason] human-readable detail (for skipped/failed)
600
+ * @property {string} [stderr] captured stderr from `gh` (failed only)
601
+ */
602
+
603
+ /**
604
+ * Default runner: spawn `gh attestation verify` and return the captured
605
+ * exit code, stdout, and stderr. Injectable for tests.
606
+ * @param {string} filePath
607
+ * @param {string} repo e.g. `agent-sh/agent-analyzer`
608
+ * @returns {{ status: number|null, stdout: string, stderr: string }}
609
+ */
610
+ function defaultGhRunner(filePath, repo) {
611
+ try {
612
+ const stdout = cp.execFileSync(
613
+ 'gh',
614
+ ['attestation', 'verify', filePath, '--repo', repo, '--format', 'json'],
615
+ {
616
+ encoding: 'utf8',
617
+ stdio: ['ignore', 'pipe', 'pipe'],
618
+ timeout: 60000,
619
+ windowsHide: true
620
+ }
621
+ );
622
+ return { status: 0, stdout: stdout || '', stderr: '' };
623
+ } catch (err) {
624
+ return {
625
+ status: typeof err.status === 'number' ? err.status : null,
626
+ stdout: err.stdout ? String(err.stdout) : '',
627
+ stderr: err.stderr ? String(err.stderr) : (err.message || '')
628
+ };
629
+ }
630
+ }
631
+
632
+ /**
633
+ * Returns true if the `gh` CLI is on PATH. Uses a short, non-privileged probe.
634
+ * @param {function} [runner] optional probe; defaults to real `gh --version`
635
+ * @returns {boolean}
636
+ */
637
+ function isGhAvailable(runner) {
638
+ if (typeof runner === 'function') {
639
+ try { return !!runner(); } catch (e) { return false; }
640
+ }
641
+ try {
642
+ cp.execFileSync('gh', ['--version'], {
643
+ stdio: 'ignore',
644
+ timeout: 5000,
645
+ windowsHide: true
646
+ });
647
+ return true;
648
+ } catch (e) {
649
+ return false;
650
+ }
651
+ }
652
+
653
+ /**
654
+ * Verify a downloaded asset's SLSA build provenance attestation via the
655
+ * GitHub CLI. The check is SOFT by default: if `gh` is not installed the
656
+ * function returns { status: 'skipped' } and the caller logs a warning. Set
657
+ * `requireAttestation` (or the env var) to make a missing `gh` a failure.
658
+ *
659
+ * A present `gh` that reports verification failure ALWAYS returns
660
+ * { status: 'failed' } regardless of `requireAttestation`; the caller is
661
+ * expected to abort in that case.
662
+ *
663
+ * @param {string} filePath absolute path to the downloaded archive
664
+ * @param {Object} [options]
665
+ * @param {string} [options.repo] e.g. `agent-sh/agent-analyzer`
666
+ * @param {boolean} [options.requireAttestation] defaults to env
667
+ * `AGENT_ANALYZER_REQUIRE_ATTESTATION === '1'`
668
+ * @param {function} [options.ghRunner] injectable runner for tests. Receives
669
+ * (filePath, repo), returns { status, stdout, stderr }.
670
+ * @param {function} [options.ghProbe] injectable gh-on-PATH probe for tests.
671
+ * @returns {SlsaResult}
672
+ */
673
+ function verifySlsaAttestation(filePath, options) {
674
+ const opts = options || {};
675
+ const repo = opts.repo || GITHUB_REPO;
676
+ const runner = typeof opts.ghRunner === 'function' ? opts.ghRunner : defaultGhRunner;
677
+ const require_ = typeof opts.requireAttestation === 'boolean'
678
+ ? opts.requireAttestation
679
+ : process.env.AGENT_ANALYZER_REQUIRE_ATTESTATION === '1';
680
+
681
+ const ghPresent = isGhAvailable(opts.ghProbe);
682
+ if (!ghPresent) {
683
+ const reason = '`gh` CLI not found on PATH';
684
+ if (require_) {
685
+ return { status: 'failed', reason: reason + ' (AGENT_ANALYZER_REQUIRE_ATTESTATION=1)' };
686
+ }
687
+ return { status: 'skipped', reason: reason };
688
+ }
689
+
690
+ const result = runner(filePath, repo);
691
+ if (result && result.status === 0) {
692
+ return { status: 'verified' };
693
+ }
694
+ return {
695
+ status: 'failed',
696
+ reason: 'gh attestation verify exited with status ' +
697
+ (result && result.status !== null ? result.status : 'unknown'),
698
+ stderr: (result && result.stderr) || ''
699
+ };
700
+ }
701
+
575
702
  // ---------------------------------------------------------------------------
576
703
  // Download + install
577
704
  // ---------------------------------------------------------------------------
@@ -582,11 +709,19 @@ function findBinaryInScratch(scratch, binaryBaseName) {
582
709
  * @param {Object} [options]
583
710
  * @param {boolean} [options.skipChecksum=false] LOCAL DEV ONLY. Skips the
584
711
  * `.sha256` sidecar fetch and verification. NEVER set this in production.
712
+ * @param {boolean} [options.skipAttestation=false] LOCAL DEV ONLY. Skips the
713
+ * SLSA attestation check entirely.
714
+ * @param {boolean} [options.requireAttestation] when true, a missing `gh`
715
+ * CLI becomes a hard failure. Defaults to
716
+ * `process.env.AGENT_ANALYZER_REQUIRE_ATTESTATION === '1'`.
717
+ * @param {function} [options.ghRunner] injectable runner for tests.
718
+ * @param {function} [options.ghProbe] injectable gh-on-PATH probe for tests.
585
719
  * @returns {Promise<string>} path to the installed binary
586
720
  */
587
721
  async function downloadBinary(ver, options) {
588
722
  const opts = options || {};
589
723
  const skipChecksum = opts.skipChecksum === true;
724
+ const skipAttestation = opts.skipAttestation === true;
590
725
 
591
726
  const platformKey = getPlatformKey();
592
727
  if (!platformKey) {
@@ -643,6 +778,47 @@ async function downloadBinary(ver, options) {
643
778
  verifySha256(buf, expected, filename);
644
779
  }
645
780
 
781
+ // --- 2b. Verify SLSA build provenance (optional / required) ------------
782
+ if (skipAttestation) {
783
+ process.stderr.write(
784
+ '[WARN] skipAttestation=true - SLSA verification disabled. ' +
785
+ 'This is LOCAL DEV ONLY and MUST NOT be used in production.\n'
786
+ );
787
+ } else {
788
+ // `gh attestation verify` needs a real file. Persist buf to a tmp path,
789
+ // verify, then drop it. Extraction continues from the in-memory buf so
790
+ // we don't need the tmp file beyond the verify call.
791
+ const attestDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-analyzer-slsa-'));
792
+ const attestFile = path.join(attestDir, filename);
793
+ try {
794
+ fs.writeFileSync(attestFile, buf);
795
+ const result = verifySlsaAttestation(attestFile, {
796
+ repo: GITHUB_REPO,
797
+ requireAttestation: opts.requireAttestation,
798
+ ghRunner: opts.ghRunner,
799
+ ghProbe: opts.ghProbe
800
+ });
801
+ if (result.status === 'verified') {
802
+ process.stderr.write('[OK] SLSA attestation verified for ' + filename + '\n');
803
+ } else if (result.status === 'skipped') {
804
+ process.stderr.write(
805
+ '[WARN] SLSA attestation check skipped: ' + result.reason + '. ' +
806
+ 'Install the GitHub CLI (`gh`) to enable provenance verification. ' +
807
+ 'Set AGENT_ANALYZER_REQUIRE_ATTESTATION=1 to require it.\n'
808
+ );
809
+ } else {
810
+ // 'failed'
811
+ throw new Error(
812
+ 'SLSA attestation verification failed for ' + filename + ': ' +
813
+ result.reason + '. Refusing to execute binary.' +
814
+ (result.stderr ? '\n--- gh stderr ---\n' + result.stderr : '')
815
+ );
816
+ }
817
+ } finally {
818
+ rmrf(attestDir);
819
+ }
820
+ }
821
+
646
822
  // --- 3. Extract to isolated scratch dir + validate entries -------------
647
823
  const binaryBaseName = path.basename(binPath);
648
824
  let scratch;
@@ -707,7 +883,13 @@ async function ensureBinary(options) {
707
883
  }
708
884
  }
709
885
 
710
- return downloadBinary(targetVer, { skipChecksum: opts.skipChecksum === true });
886
+ return downloadBinary(targetVer, {
887
+ skipChecksum: opts.skipChecksum === true,
888
+ skipAttestation: opts.skipAttestation === true,
889
+ requireAttestation: opts.requireAttestation,
890
+ ghRunner: opts.ghRunner,
891
+ ghProbe: opts.ghProbe
892
+ });
711
893
  }
712
894
 
713
895
  /**
@@ -730,11 +912,27 @@ function ensureBinarySync(options) {
730
912
 
731
913
  const targetVer = (options && options.version) || ANALYZER_MIN_VERSION;
732
914
  const skipChecksum = !!(options && options.skipChecksum);
915
+ const skipAttestation = !!(options && options.skipAttestation);
916
+ // Forward requireAttestation when explicitly set (tri-state: undefined
917
+ // lets the child fall back to the AGENT_ANALYZER_REQUIRE_ATTESTATION
918
+ // env var, matching ensureBinary()). Without this forwarding, a sync
919
+ // caller with requireAttestation:true would silently lose the hard-fail
920
+ // intent when gh is missing.
921
+ const requireAttestation = options && typeof options.requireAttestation === 'boolean'
922
+ ? options.requireAttestation
923
+ : undefined;
733
924
  const selfPath = __filename;
925
+ const ensureOpts = {
926
+ version: targetVer,
927
+ skipChecksum: skipChecksum,
928
+ skipAttestation: skipAttestation
929
+ };
930
+ if (requireAttestation !== undefined) {
931
+ ensureOpts.requireAttestation = requireAttestation;
932
+ }
734
933
  const helperLines = [
735
934
  'var b = require(' + JSON.stringify(selfPath) + ');',
736
- 'b.ensureBinary({ version: ' + JSON.stringify(targetVer) +
737
- ', skipChecksum: ' + JSON.stringify(skipChecksum) + ' })',
935
+ 'b.ensureBinary(' + JSON.stringify(ensureOpts) + ')',
738
936
  ' .then(function(p) { process.stdout.write(p); })',
739
937
  ' .catch(function(e) { process.stderr.write(e.message); process.exit(1); });'
740
938
  ];
@@ -798,6 +996,8 @@ module.exports = {
798
996
  assertSafeArchiveEntry,
799
997
  assertInsideRoot,
800
998
  downloadBinary,
999
+ verifySlsaAttestation,
1000
+ isGhAvailable,
801
1001
  // Exported for tests only
802
1002
  extractTarGzToScratch,
803
1003
  extractZipToScratch,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentsys",
3
- "version": "5.11.0",
3
+ "version": "5.12.0",
4
4
  "description": "A modular runtime and orchestration system for AI agents - works with Claude Code, OpenCode, and Codex CLI",
5
5
  "main": "lib/platform/detect-platform.js",
6
6
  "type": "commonjs",
package/site/content.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://agent-sh.github.io/agentsys",
6
6
  "repo": "https://github.com/agent-sh/agentsys",
7
7
  "npm": "https://www.npmjs.com/package/agentsys",
8
- "version": "5.11.0",
8
+ "version": "5.12.0",
9
9
  "author": "Avi Fenesh",
10
10
  "author_url": "https://github.com/avifenesh"
11
11
  },