@onlooker-community/ecosystem 0.43.1 → 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.1",
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",
@@ -1,5 +1,5 @@
1
1
  {
2
- ".": "0.43.1",
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,12 @@
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
+
3
10
  ## [0.43.1](https://github.com/onlooker-community/ecosystem/compare/ecosystem-v0.43.0...ecosystem-v0.43.1) (2026-08-20)
4
11
 
5
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlooker-community/ecosystem",
3
- "version": "0.43.1",
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
+ });