sandoichi 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -1,25 +1,19 @@
1
1
  # sandoichi
2
2
 
3
- Cuts what Claude Code and Codex charge you to re-read their own output. Redacts secrets, caps oversized tool results, and, if you turn it on, trims request history before it's sent — all without calling an LLM itself.
3
+ `sandoichi` is Sando's optional JavaScript library. The full Sando plugin is the main product. Install it through the Claude Code or Codex marketplace.
4
4
 
5
- This is the core library (`@sando/core` renamed `sandoichi` for npm). For the Claude Code plugin, Codex plugin, and provider proxy, see the [main repo](https://github.com/yuzushi-dev/Sando).
6
-
7
- ## Install
8
-
9
- ```sh
5
+ ```bash
10
6
  npm install sandoichi
11
7
  ```
12
8
 
13
- Requires Node.js `22.22.x`.
14
-
15
- ## Usage
16
-
17
9
  ```js
18
10
  import { optimizeToolOutput, createProviderProxy } from 'sandoichi';
19
11
  ```
20
12
 
21
- See [index.mjs](./index.mjs) for the full list of exports (tool-output optimization, provider request transforms, semantic compaction, metrics, status line rendering).
13
+ The library requires Node.js `>=22.22.0 <23` and has no runtime dependencies. Installing it does not install or enable the plugin.
14
+
15
+ For plugin installation, see the [main project README](https://github.com/yuzushi-dev/Sando#readme).
22
16
 
23
- ## License
17
+ Telemetry is off by default. An interactive npm install asks once for consent; see the [full disclosure](https://github.com/yuzushi-dev/Sando/blob/main/TELEMETRY.md).
24
18
 
25
- MIT
19
+ MIT.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sandoichi",
3
- "version": "0.1.2",
4
- "description": "Cuts what Claude Code and Codex charge you to re-read their own output.",
3
+ "version": "0.1.4",
4
+ "description": "Reduce repeated tool-output context in Claude Code and Codex.",
5
5
  "license": "MIT",
6
6
  "author": "yuzushi",
7
7
  "repository": {
@@ -7,9 +7,11 @@ import path from 'node:path';
7
7
  import readline from 'node:readline/promises';
8
8
  import { pathToFileURL } from 'node:url';
9
9
 
10
- import { CONSENT_VERSION, defaultTelemetryConfigPath, enableTelemetry, readTelemetryConfig } from './telemetry.mjs';
10
+ import {
11
+ CONSENT_VERSION, defaultTelemetryConfigPath, enableTelemetry, readTelemetryConfig, TELEMETRY_DETAILS_URL,
12
+ } from './telemetry.mjs';
11
13
 
12
- const CONSENT_PROMPT = 'Enable anonymous telemetry? Full details at: TELEMETRY.md [y/N] ';
14
+ const CONSENT_PROMPT = `Enable anonymous telemetry? Full details at: ${TELEMETRY_DETAILS_URL} [y/N] `;
13
15
 
14
16
  export async function runPostinstall({
15
17
  env = process.env, stdin = process.stdin, stdout = process.stdout,
@@ -0,0 +1,28 @@
1
+ import path from 'node:path';
2
+
3
+ import { defaultTelemetryConfigPath, readTelemetryConfig, TELEMETRY_DETAILS_URL } from './telemetry.mjs';
4
+
5
+ export function runSessionStart({
6
+ env = process.env,
7
+ stdout = process.stdout,
8
+ rootEnv = 'PLUGIN_ROOT',
9
+ } = {}) {
10
+ try {
11
+ const config = readTelemetryConfig(defaultTelemetryConfigPath(env));
12
+ if (config.prompted_consent_version > 0) {
13
+ stdout.write('{}\n');
14
+ return;
15
+ }
16
+ const pluginRoot = env[rootEnv] || path.resolve(import.meta.dirname, '..');
17
+ const cli = path.join(pluginRoot, 'lib', 'telemetry-cli.mjs');
18
+ stdout.write(`${JSON.stringify({
19
+ hookSpecificOutput: {
20
+ hookEventName: 'SessionStart',
21
+ systemMessage: 'Sando can send anonymous aggregate telemetry (opt-in, off by default). '
22
+ + `Run \`node "${cli}" enable\` to turn it on. Details: ${TELEMETRY_DETAILS_URL}`,
23
+ },
24
+ })}\n`);
25
+ } catch {
26
+ stdout.write('{}\n');
27
+ }
28
+ }
@@ -95,6 +95,6 @@ export function renderStatusLine({ metrics, providerUsage, totalCostUsd } = {},
95
95
  const effectiveRate = Number.isFinite(totalCostUsd) && totalCostUsd > 0
96
96
  && Number.isSafeInteger(providerUsage?.totalTokens) && providerUsage.totalTokens > 0
97
97
  ? totalCostUsd / providerUsage.totalTokens : undefined;
98
- const cost = effectiveRate === undefined ? undefined : compactCost(metrics.savedTokens, effectiveRate);
99
- return `🥪 ${[savings, cost && `(-${cost})`].filter(Boolean).join(' ')}`;
98
+ void effectiveRate; // computed for downstream cost tracking, intentionally not shown in the status bar
99
+ return `🥪 ${savings}`;
100
100
  }
@@ -6,11 +6,11 @@ import { pathToFileURL } from 'node:url';
6
6
 
7
7
  import {
8
8
  defaultTelemetryConfigPath, defaultTelemetryStatePaths,
9
- disableTelemetry, enableTelemetry, flushQueue, previewNextUpload, statusTelemetry,
9
+ disableTelemetry, enableTelemetry, flushQueue, previewNextUpload, statusTelemetry, TELEMETRY_DETAILS_URL,
10
10
  } from './telemetry.mjs';
11
11
 
12
12
  const USAGE = 'Usage: sando telemetry <status|enable|disable [--purge]|preview|flush>\n';
13
- const CONSENT_PROMPT = 'Enable anonymous telemetry? Full details at: TELEMETRY.md [y/N] ';
13
+ const CONSENT_PROMPT = `Enable anonymous telemetry? Full details at: ${TELEMETRY_DETAILS_URL} [y/N] `;
14
14
 
15
15
  async function defaultPrompt(message) {
16
16
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
package/src/telemetry.mjs CHANGED
@@ -84,6 +84,7 @@ export function serializeEvent(payload) {
84
84
 
85
85
  export const TELEMETRY_CONFIG_VERSION = 1;
86
86
  export const CONSENT_VERSION = 1;
87
+ export const TELEMETRY_DETAILS_URL = 'https://github.com/yuzushi-dev/Sando/blob/main/TELEMETRY.md';
87
88
  // Canary phase: shared backend, fronted by a Cloudflare Tunnel so it's
88
89
  // reachable from any of the owner's machines (see
89
90
  // session-handoff/deploy/telemetry/). Rate-limited at nginx (30 req/min/IP).