@astudioplus/compressor 0.1.0 → 0.1.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 CHANGED
@@ -5,9 +5,32 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.2] - 2026-06-10
9
+
10
+ ### Changed
11
+
12
+ - `compressor status` is clearer: it now names the scope it reports on
13
+ (`project: <cwd>` or `user-level (machine-wide)`), so a global package install
14
+ in an unconfigured directory no longer reads as "broken". Redundant
15
+ "not installed — not installed" lines collapse to "not installed", and a
16
+ cross-scope install renders as "not installed (global); installed at project
17
+ level" instead of the contradictory "installed — not installed (global)".
18
+ When nothing is configured, status prints the `init` command to run.
19
+
20
+ ## [0.1.1] - 2026-06-10
21
+
22
+ ### Fixed
23
+
24
+ - Package-root discovery keyed on the literal name `compressor`, so after the
25
+ rename to `@astudioplus/compressor` every CLI command threw "could not locate
26
+ the compressor package root" when installed from npm. Discovery now keys on the
27
+ `compressor` bin entry, which survives any scope/name change. Regression test
28
+ added. (0.1.0 was unusable when installed; 0.1.1 is the first working release.)
29
+ - `compressor --version` now reports the package version.
30
+
8
31
  ## [0.1.0] - 2026-06-10
9
32
 
10
- Initial release.
33
+ Initial release. (Broken when installed from npm — see 0.1.1.)
11
34
 
12
35
  ### Added
13
36
 
@@ -49,4 +72,6 @@ Initial release.
49
72
  - `stats` command: actual usage aggregated from local Claude Code transcripts.
50
73
  - `count` command: estimated token counts per file, `--exact` via the Anthropic `count_tokens` endpoint.
51
74
 
75
+ [0.1.2]: https://github.com/anvanster/compressor/releases/tag/v0.1.2
76
+ [0.1.1]: https://github.com/anvanster/compressor/releases/tag/v0.1.1
52
77
  [0.1.0]: https://github.com/anvanster/compressor/releases/tag/v0.1.0
@@ -1,11 +1,37 @@
1
+ import process from 'node:process';
1
2
  import { adapters } from "../../adapters/index.js";
2
3
  import { buildContext } from "./init.js";
3
4
  export async function runStatus(global = false) {
4
5
  const ctx = buildContext(global, 'optimized', false);
6
+ // status reports whether compressor is CONFIGURED INTO each agent at this
7
+ // scope — not whether the compressor CLI itself is installed. Name the scope
8
+ // so a global package install + empty project doesn't read as "broken".
9
+ const scope = global ? 'user-level (machine-wide)' : `project: ${process.cwd()}`;
10
+ console.log(`compressor status — ${scope}`);
11
+ let anyInstalled = false;
5
12
  for (const adapter of adapters) {
6
13
  const status = await adapter.status(ctx);
7
- const installed = status.installed ? 'installed' : 'not installed';
8
- const mode = status.mode === undefined ? '' : ` (mode=${status.mode})`;
9
- console.log(`${status.agent}: ${installed}${mode} ${status.detail}`);
14
+ const detail = status.detail.trim();
15
+ // The adapter's `installed` flag is true if installed at EITHER scope; the
16
+ // detail is scope-faithful. When the detail leads with "not installed", it
17
+ // is authoritative for THIS scope (avoids "installed — not installed").
18
+ const installedHere = status.installed && !detail.startsWith('not installed');
19
+ if (installedHere) {
20
+ anyInstalled = true;
21
+ const mode = status.mode === undefined ? '' : ` (mode=${status.mode})`;
22
+ console.log(` ${status.agent}: installed${mode} — ${detail}`);
23
+ }
24
+ else if (detail === '' || detail === 'not installed') {
25
+ console.log(` ${status.agent}: not installed`);
26
+ }
27
+ else {
28
+ // self-complete detail, e.g. "not installed (global); installed at project level"
29
+ console.log(` ${status.agent}: ${detail}`);
30
+ }
31
+ }
32
+ if (!anyInstalled) {
33
+ console.log(global
34
+ ? "\nNothing configured at user level. Run `compressor init --agent copilot --global` for a machine-wide Copilot hook."
35
+ : "\nNothing configured in this project. Run `compressor init` (Claude Code) or add `--agent copilot --agent cursor --agent agents-md`; `--global` installs a machine-wide Copilot hook.");
10
36
  }
11
37
  }
package/dist/cli/index.js CHANGED
@@ -5,7 +5,7 @@ const program = new Command();
5
5
  program
6
6
  .name('compressor')
7
7
  .description('Token optimization for AI coding agents: instruction packs, tool-output compression, measured savings')
8
- .version('0.1.0');
8
+ .version('0.1.2');
9
9
  program
10
10
  .command('init')
11
11
  .description('install the instruction pack + PostToolUse hook for the given agents')
package/dist/paths.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { PackMode } from './packs/types.ts';
2
+ export declare function isCompressorRoot(dir: string): boolean;
2
3
  export declare function packageRoot(): string;
3
4
  /**
4
5
  * Hook command for ownership matching in status/uninstall — must work even
package/dist/paths.js CHANGED
@@ -1,16 +1,26 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- function isCompressorRoot(dir) {
4
+ export function isCompressorRoot(dir) {
5
5
  const pkgPath = path.join(dir, 'package.json');
6
6
  if (!existsSync(pkgPath)) {
7
7
  return false;
8
8
  }
9
9
  try {
10
10
  const parsed = JSON.parse(readFileSync(pkgPath, 'utf8'));
11
- return (typeof parsed === 'object' &&
12
- parsed !== null &&
13
- parsed['name'] === 'compressor');
11
+ if (typeof parsed !== 'object' || parsed === null) {
12
+ return false;
13
+ }
14
+ const pkg = parsed;
15
+ // Identify our package by the `compressor` bin, not its name — survives the
16
+ // unscoped→@astudioplus/compressor rename and any future scope change. The
17
+ // name check is a belt-and-suspenders fallback.
18
+ const bin = pkg['bin'];
19
+ if (typeof bin === 'object' && bin !== null && 'compressor' in bin) {
20
+ return true;
21
+ }
22
+ const name = pkg['name'];
23
+ return name === 'compressor' || name === '@astudioplus/compressor';
14
24
  }
15
25
  catch {
16
26
  return false;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@astudioplus/compressor",
3
- "version": "0.1.0",
4
- "description": "Reduce token usage in AI coding agents (Claude Code, Copilot, Cursor) with instruction packs and tool-output compression hooks savings you can measure.",
3
+ "version": "0.1.2",
4
+ "description": "Reduce token usage in AI coding agents (Claude Code, Copilot, Cursor) with instruction packs and tool-output compression hooks \u2014 savings you can measure.",
5
5
  "type": "module",
6
6
  "author": "Andrey Vasilevsky <anvanster@gmail.com>",
7
7
  "license": "MIT",