@onlooker-community/ecosystem 0.43.0 → 0.43.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ecosystem",
3
- "version": "0.43.0",
3
+ "version": "0.43.2",
4
4
  "description": "Observability substrate for Claude Code. Provides the shared $ONLOOKER_DIR storage root (default $HOME/.onlooker), canonical schema-validated event emission, session and tool tracking hooks, and prompt rules. Required by all other Onlooker plugins.",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -39,17 +39,26 @@ jobs:
39
39
  - run: npm ci
40
40
  if: ${{ contains(fromJSON(steps.release.outputs.paths_released || '[]'), '.') }}
41
41
 
42
- # --provenance is what makes the id-token: write permission above do
43
- # anything. Without it npm never requests an OIDC token and the publish
44
- # authenticates with NPM_TOKEN alone a classic automation token, which
45
- # this package's 2FA policy rejects with a 403. The permission has been
46
- # granted since #175 and inert ever since, so every release from 0.35.0
47
- # on tagged cleanly and never reached npm.
42
+ # Trusted publishing authenticates via OIDC, and the OIDC exchange lives
43
+ # in npm's lib/utils/oidc.js added in npm 11.5.x. Node 22 bundles npm
44
+ # 10.9.8, which has no such module, so `npm publish` never even attempts
45
+ # the exchange and silently falls back to whatever token it finds. That
46
+ # is why every release from 0.35.0 on tagged cleanly and never reached
47
+ # npm: first as a 403 ("2FA is required but an automation token was
48
+ # specified"), then as a bare 404 once trusted publishing was switched on
49
+ # and the registry stopped accepting the automation token at all.
48
50
  #
49
- # --access public is a no-op on an already-public package; it is here for
50
- # parity with onlooker-community/schema's publish-npm.yml, the one
51
+ # a7c7a0e removed this upgrade because npm@latest was broken on hosted
52
+ # runners at the time (missing promise-retry) and provenance alone did
53
+ # work on the bundled npm. Provenance is not the problem — auth is.
54
+ - run: npm install -g npm@latest
55
+ if: ${{ contains(fromJSON(steps.release.outputs.paths_released || '[]'), '.') }}
56
+
57
+ # No NODE_AUTH_TOKEN here on purpose. With trusted publishing the token
58
+ # is the thing being replaced: npm trades the workflow's OIDC identity
59
+ # for a short-lived registry token at publish time. Supplying a static
60
+ # token invites npm to authenticate with it instead and fail closed.
61
+ # This mirrors onlooker-community/schema's publish-npm.yml, the one
51
62
  # configuration in this org that publishes successfully.
52
63
  - run: npm publish --provenance --access public
53
64
  if: ${{ contains(fromJSON(steps.release.outputs.paths_released || '[]'), '.') }}
54
- env:
55
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1,5 +1,5 @@
1
1
  {
2
- ".": "0.43.0",
2
+ ".": "0.43.2",
3
3
  "plugins/archivist": "0.3.1",
4
4
  "plugins/tribunal": "1.2.7",
5
5
  "plugins/echo": "0.3.1",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.43.2](https://github.com/onlooker-community/ecosystem/compare/ecosystem-v0.43.1...ecosystem-v0.43.2) (2026-08-21)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **ci:** shellcheck every tracked script, not a stale list :broom: ([#190](https://github.com/onlooker-community/ecosystem/issues/190)) ([841a37c](https://github.com/onlooker-community/ecosystem/commit/841a37cfa2c8a0eb2ff540f67b4b5a10eb4ed161))
9
+
10
+ ## [0.43.1](https://github.com/onlooker-community/ecosystem/compare/ecosystem-v0.43.0...ecosystem-v0.43.1) (2026-08-20)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **release:** upgrade npm so trusted publishing runs :relieved: ([#188](https://github.com/onlooker-community/ecosystem/issues/188)) ([caf6dfd](https://github.com/onlooker-community/ecosystem/commit/caf6dfddc3d906708538c258755d9bd8297970c1))
16
+
3
17
  ## [0.43.0](https://github.com/onlooker-community/ecosystem/compare/ecosystem-v0.42.2...ecosystem-v0.43.0) (2026-08-19)
4
18
 
5
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlooker-community/ecosystem",
3
- "version": "0.43.0",
3
+ "version": "0.43.2",
4
4
  "description": "Agents, skills, hooks, commands, rules, and MCP configurations that power [Onlooker](https://onlooker.dev)",
5
5
  "author": {
6
6
  "name": "Onlooker Community",
@@ -22,7 +22,7 @@
22
22
  "test": "npm run test:bats && npm run test:schema",
23
23
  "test:bats": "bats test/bats",
24
24
  "test:schema": "node --test test/node/*.test.mjs",
25
- "test:shellcheck": "shellcheck -S error -x install.sh scripts/common.sh scripts/hooks/*.sh scripts/lib/*.sh plugins/archivist/scripts/hooks/*.sh plugins/archivist/scripts/lib/*.sh plugins/tribunal/scripts/hooks/*.sh plugins/tribunal/scripts/lib/*.sh plugins/echo/scripts/hooks/*.sh plugins/echo/scripts/lib/*.sh plugins/governor/scripts/hooks/*.sh plugins/governor/scripts/lib/*.sh plugins/compass/scripts/hooks/*.sh plugins/compass/scripts/lib/*.sh plugins/scribe/scripts/hooks/*.sh plugins/scribe/scripts/lib/*.sh plugins/counsel/scripts/hooks/*.sh plugins/counsel/scripts/lib/*.sh plugins/warden/scripts/hooks/*.sh plugins/warden/scripts/lib/*.sh plugins/librarian/scripts/hooks/*.sh plugins/librarian/scripts/lib/*.sh plugins/curator/scripts/hooks/*.sh plugins/curator/scripts/lib/*.sh plugins/historian/scripts/hooks/*.sh plugins/historian/scripts/lib/*.sh plugins/assayer/scripts/hooks/*.sh plugins/assayer/scripts/lib/*.sh plugins/cartographer/scripts/hooks/*.sh plugins/cartographer/scripts/lib/*.sh plugins/bursar/scripts/hooks/*.sh plugins/bursar/scripts/lib/*.sh plugins/lineage/scripts/hooks/*.sh plugins/lineage/scripts/lib/*.sh plugins/inspector/scripts/hooks/*.sh plugins/inspector/scripts/lib/*.sh",
25
+ "test:shellcheck": "git ls-files -z '*.sh' | xargs -0 shellcheck -S error -x",
26
26
  "lint:references": "node scripts/lint/check-references.mjs",
27
27
  "lint:manifests": "node scripts/lint/check-manifests.mjs",
28
28
  "lint:lesson-schema": "node scripts/lint/check-lesson-schema-drift.mjs",
@@ -0,0 +1,67 @@
1
+ import assert from 'node:assert/strict';
2
+ import { spawnSync } from 'node:child_process';
3
+ import { chmodSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { dirname, join, resolve } from 'node:path';
6
+ import { describe, it } from 'node:test';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const HERE = dirname(fileURLToPath(import.meta.url));
10
+ const REPO_ROOT = resolve(HERE, '..', '..');
11
+
12
+ // Every shell script git tracks. This is the set that must be linted; anything
13
+ // test:shellcheck does not hand to shellcheck is silently unlinted.
14
+ function trackedShellScripts() {
15
+ const r = spawnSync('git', ['ls-files', '-z', '*.sh'], {
16
+ cwd: REPO_ROOT,
17
+ encoding: 'utf8',
18
+ });
19
+ assert.equal(r.status, 0, `git ls-files failed: ${r.stderr}`);
20
+ return new Set(r.stdout.split('\0').filter(Boolean));
21
+ }
22
+
23
+ // Run the real test:shellcheck command with a shellcheck that reports its
24
+ // arguments instead of linting. Shimming rather than parsing the command keeps
25
+ // this test agnostic to how the file list is produced -- an enumerated list, a
26
+ // glob, or git ls-files all answer the same question: what gets linted?
27
+ function filesHandedToShellcheck() {
28
+ const stubDir = mkdtempSync(join(tmpdir(), 'shellcheck-stub-'));
29
+ const stub = join(stubDir, 'shellcheck');
30
+ writeFileSync(
31
+ stub,
32
+ '#!/bin/sh\nfor a in "$@"; do\n case "$a" in\n *.sh) printf \'%s\\n\' "$a" ;;\n esac\ndone\nexit 0\n',
33
+ );
34
+ chmodSync(stub, 0o755);
35
+
36
+ const pkg = JSON.parse(readFileSync(join(REPO_ROOT, 'package.json'), 'utf8'));
37
+ const command = pkg.scripts['test:shellcheck'];
38
+ assert.ok(command, 'package.json has no test:shellcheck script');
39
+
40
+ const r = spawnSync('sh', ['-c', command], {
41
+ cwd: REPO_ROOT,
42
+ encoding: 'utf8',
43
+ env: { ...process.env, PATH: `${stubDir}:${process.env.PATH}` },
44
+ });
45
+ assert.equal(r.status, 0, `test:shellcheck command failed: ${r.stderr}`);
46
+ return new Set(r.stdout.split('\n').filter(Boolean));
47
+ }
48
+
49
+ describe('test:shellcheck coverage', () => {
50
+ it('lints every shell script in the repository', () => {
51
+ const tracked = trackedShellScripts();
52
+ const linted = filesHandedToShellcheck();
53
+
54
+ assert.ok(tracked.size > 0, 'expected git to track at least one .sh file');
55
+
56
+ const orphaned = [...tracked].filter((f) => !linted.has(f)).sort();
57
+ assert.deepEqual(orphaned, [], `these tracked scripts are never shellchecked:\n ${orphaned.join('\n ')}`);
58
+ });
59
+
60
+ it('does not reference scripts that no longer exist', () => {
61
+ const tracked = trackedShellScripts();
62
+ const linted = filesHandedToShellcheck();
63
+
64
+ const stale = [...linted].filter((f) => !tracked.has(f)).sort();
65
+ assert.deepEqual(stale, [], `test:shellcheck names paths git does not track:\n ${stale.join('\n ')}`);
66
+ });
67
+ });