@dopemarkets/agent 0.1.1 → 0.1.3

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/dist/index.js CHANGED
@@ -15,7 +15,7 @@ const markets_js_1 = require("./commands/markets.js");
15
15
  const stack_js_1 = require("./commands/stack.js");
16
16
  const agent_key_js_1 = require("./commands/agent_key.js");
17
17
  const mcp_js_1 = require("./commands/mcp.js");
18
- const VERSION = '0.1.0';
18
+ const VERSION = '0.1.3';
19
19
  const HELP = `dope — DOPE Agent Mode CLI (v${VERSION})
20
20
 
21
21
  Usage:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dopemarkets/agent",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "DOPE Agent Mode CLI. Run agentic Stack trades on DOPE from the terminal.",
5
5
  "bin": {
6
6
  "dope": "bin/dope.js"
@@ -1,24 +1,40 @@
1
1
  #!/usr/bin/env node
2
- // Banner printed once after `npm install -g @dopemarkets/agent`.
2
+ // Banner printed after `npm install [-g] @dopemarkets/agent`.
3
3
  //
4
4
  // Goal: replace npm's opaque "changed N packages in Ns" with an
5
5
  // unambiguous "the install succeeded — here's what to do next" line.
6
6
  // Non-developers won't otherwise know the install worked.
7
7
  //
8
+ // Two non-obvious things make this trickier than it looks:
9
+ //
10
+ // 1. npm 9+ runs postinstall scripts in background mode by default
11
+ // (the `--foreground-scripts` flag is opt-in). In background
12
+ // mode npm captures the child's stdout/stderr and only surfaces
13
+ // them on failure. Writing to `process.stderr` is therefore
14
+ // invisible to the user on a normal `npm install -g` run. To
15
+ // reach the user's terminal we open `/dev/tty` for writing and
16
+ // print there, bypassing npm's stream capture entirely. This
17
+ // requires a controlling terminal (so e.g. CI shows nothing,
18
+ // which is the right outcome — no human to read the banner).
19
+ //
20
+ // 2. We previously tried gating this on `npm_config_global` so the
21
+ // banner would only print on `-g` installs. npm 11 does not
22
+ // reliably set that env var for postinstall scripts, so the
23
+ // gate silently no-op'd on the install path that actually
24
+ // matters. `@dopemarkets/agent` is a CLI; the global install
25
+ // is overwhelmingly the intended use. We always print.
26
+ //
8
27
  // Rules:
9
- // - Only print on global installs (`npm install -g @dopemarkets/agent`).
10
- // Skipping local installs keeps this quiet when the package is pulled
11
- // in as a transitive dep, which is the npm convention.
12
- // - Print to stderr so it sits alongside npm's own install chatter.
13
- // - Never throw. Postinstall failures bubble up as install failures,
14
- // and a banner is not worth breaking somebody's machine over.
28
+ // - Try the controlling TTY first (works on the common case).
29
+ // - Fall back to stderr (covers Windows, `--foreground-scripts`,
30
+ // and any environment without a usable /dev/tty).
31
+ // - Never throw. Postinstall failures bubble up as install
32
+ // failures, and a banner is never worth breaking somebody's
33
+ // machine over.
15
34
 
16
35
  'use strict';
17
36
 
18
37
  try {
19
- const isGlobal = process.env.npm_config_global === 'true';
20
- if (!isGlobal) return;
21
-
22
38
  const lines = [
23
39
  '',
24
40
  'DOPE Agent Mode installed.',
@@ -29,7 +45,24 @@ try {
29
45
  'Run `dope --help` to see every command.',
30
46
  '',
31
47
  ];
32
- process.stderr.write(lines.join('\n'));
48
+ const message = lines.join('\n');
49
+
50
+ let wroteToTty = false;
51
+ if (process.platform !== 'win32') {
52
+ try {
53
+ // Synchronous open + write so we don't leak across npm's
54
+ // postinstall lifecycle boundary.
55
+ const fs = require('fs');
56
+ fs.writeFileSync('/dev/tty', message);
57
+ wroteToTty = true;
58
+ } catch {
59
+ // No controlling TTY (e.g. CI). Fall through to stderr.
60
+ }
61
+ }
62
+
63
+ if (!wroteToTty) {
64
+ process.stderr.write(message);
65
+ }
33
66
  } catch {
34
67
  // Intentionally swallow. A banner is never worth a failed install.
35
68
  }