myshell-tools 2.0.0-alpha.0 → 2.0.0

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
@@ -11,7 +11,7 @@ and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
11
11
  - Cross-OS CI execution (requires a public remote).
12
12
  - First npm publish.
13
13
 
14
- ## [2.0.0-alpha.0]
14
+ ## [2.0.0]
15
15
 
16
16
  A ground-up rebuild. The architecture is hexagonal (a pure, injected orchestration
17
17
  core behind a `Provider` port), and the first principle is the **Honesty Contract**:
package/dist/cli.js CHANGED
@@ -15,6 +15,10 @@ import { startRepl } from './interface/repl.js';
15
15
  import { buildProviders } from './providers/registry.js';
16
16
  import { runDoctor } from './commands/doctor.js';
17
17
  import { runCost } from './commands/cost.js';
18
+ import { runLogin } from './commands/login.js';
19
+ import { banner } from './ui/banner.js';
20
+ import { createSpinner } from './ui/spinner.js';
21
+ import { dim } from './ui/theme.js';
18
22
  const require = createRequire(import.meta.url);
19
23
  const pkg = require('../package.json');
20
24
  const version = pkg.version;
@@ -28,20 +32,43 @@ Options:
28
32
  -v, --version Print version number
29
33
 
30
34
  Commands:
31
- run <task...> Run a one-shot task and exit
32
- repl Start an interactive REPL session (default when no command given)
33
- doctor Check provider installation, auth, and environment health
34
- cost Show real spend from the ledger with a per-model breakdown
35
+ run <task...> Run a one-shot task and exit
36
+ repl Start an interactive session (default when no command given)
37
+ login [provider] Sign in to a provider (claude or codex) via its own OAuth
38
+ doctor Check provider installation, auth, and environment health
39
+ cost Show real spend from the ledger with a per-model breakdown
35
40
 
36
41
  Examples:
42
+ myshell-tools login
37
43
  myshell-tools run "refactor the auth module"
38
- myshell-tools repl
39
44
  myshell-tools doctor
40
- myshell-tools cost
41
45
  myshell-tools
42
46
 
43
47
  Repository: https://github.com/hey-vera/myshell-tools
44
48
  `;
49
+ /** Build the orchestration dependencies (includes provider detection). */
50
+ async function buildDeps(cwd) {
51
+ return {
52
+ clock: systemClock,
53
+ session: createSessionWriter({ cwd, id: systemClock.uuid() }),
54
+ ledger: createLedger({ cwd }),
55
+ policy: DEFAULT_POLICY,
56
+ providers: await buildProviders(cwd),
57
+ cwd,
58
+ sandbox: 'workspace-write',
59
+ timeoutMs: 120000,
60
+ };
61
+ }
62
+ /** Honest one-line welcome: which providers were actually detected. */
63
+ function welcome(deps, color) {
64
+ const ready = Object.keys(deps.providers);
65
+ if (ready.length > 0) {
66
+ return dim(`Providers: ${ready.join(', ')}. Type a task and press Enter, or /help. ` +
67
+ `Not signed in? run: myshell-tools login`, color);
68
+ }
69
+ return dim('No providers detected. Install Claude Code or Codex, then run: myshell-tools login ' +
70
+ '(diagnose: myshell-tools doctor)', color);
71
+ }
45
72
  async function main() {
46
73
  const args = process.argv.slice(2);
47
74
  if (args.includes('--help') || args.includes('-h')) {
@@ -52,50 +79,47 @@ async function main() {
52
79
  process.stdout.write(`${version}\n`);
53
80
  process.exit(0);
54
81
  }
55
- // ---------------------------------------------------------------------------
56
- // Build shared infrastructure
57
- // ---------------------------------------------------------------------------
58
82
  const cwd = process.cwd();
59
83
  const out = {
60
- write: (s) => { process.stdout.write(s); },
84
+ write: (s) => {
85
+ process.stdout.write(s);
86
+ },
61
87
  color: process.stdout.isTTY === true && !process.env['NO_COLOR'],
62
88
  isTty: process.stdout.isTTY === true,
63
89
  };
64
- const deps = {
65
- clock: systemClock,
66
- session: createSessionWriter({ cwd, id: systemClock.uuid() }),
67
- ledger: createLedger({ cwd }),
68
- policy: DEFAULT_POLICY,
69
- providers: await buildProviders(cwd),
70
- cwd,
71
- sandbox: 'workspace-write',
72
- timeoutMs: 120000,
73
- };
74
- // ---------------------------------------------------------------------------
75
- // Dispatch
76
- // ---------------------------------------------------------------------------
90
+ // ---- Commands that do NOT need provider detection --------------------------
91
+ if (args[0] === 'login') {
92
+ process.exit(await runLogin(out, args[1]));
93
+ }
77
94
  if (args[0] === 'doctor') {
78
95
  process.exit(await runDoctor(out));
79
96
  }
80
97
  if (args[0] === 'cost') {
81
98
  process.exit(await runCost(cwd, out));
82
99
  }
100
+ // ---- One-shot run ----------------------------------------------------------
83
101
  if (args[0] === 'run') {
84
102
  const taskParts = args.slice(1);
85
103
  if (taskParts.length === 0) {
86
104
  process.stderr.write('myshell-tools run: expected a task description\n');
87
105
  process.exit(1);
88
106
  }
89
- const task = taskParts.join(' ');
90
- const ac = new AbortController();
91
- const code = await runTask(task, deps, out, ac.signal);
107
+ const deps = await buildDeps(cwd);
108
+ const code = await runTask(taskParts.join(' '), deps, out, new AbortController().signal);
92
109
  process.exit(code);
93
110
  }
111
+ // ---- Interactive REPL (default) --------------------------------------------
94
112
  if (args.length === 0 || args[0] === 'repl') {
113
+ out.write(banner(version, out.color) + '\n');
114
+ const spinner = createSpinner(out);
115
+ spinner.start('Detecting providers…');
116
+ const deps = await buildDeps(cwd);
117
+ spinner.stop();
118
+ out.write(welcome(deps, out.color) + '\n\n');
95
119
  await startRepl(deps, out);
96
120
  process.exit(0);
97
121
  }
98
- // Unknown command
122
+ // ---- Unknown command -------------------------------------------------------
99
123
  process.stderr.write(`myshell-tools: unknown command "${args[0] ?? ''}"\nRun myshell-tools --help for usage.\n`);
100
124
  process.exit(1);
101
125
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * src/commands/login.ts — `myshell-tools login [claude|codex]`.
3
+ *
4
+ * Frictionless authentication: rather than make the user remember each vendor's
5
+ * CLI auth command, we delegate to the provider's OWN OAuth flow and inherit the
6
+ * terminal so the browser/device sign-in works in place.
7
+ *
8
+ * Security: myshell-tools never sees, handles, or stores raw credentials. Each
9
+ * CLI manages its own tokens; we only trigger its login. (This is what keeps the
10
+ * "use your subscription, no API keys" model honest.)
11
+ */
12
+ import type { OutputSink } from '../interface/render.js';
13
+ import type { ProviderId } from '../providers/port.js';
14
+ export declare function isProviderId(value: string): value is ProviderId;
15
+ /**
16
+ * Run the interactive sign-in flow for one provider (or all installed providers
17
+ * when no argument is given). Returns 0 on success, 1 only for an invalid
18
+ * argument — individual sign-in failures are reported but do not fail the command.
19
+ */
20
+ export declare function runLogin(out: OutputSink, providerArg?: string): Promise<number>;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * src/commands/login.ts — `myshell-tools login [claude|codex]`.
3
+ *
4
+ * Frictionless authentication: rather than make the user remember each vendor's
5
+ * CLI auth command, we delegate to the provider's OWN OAuth flow and inherit the
6
+ * terminal so the browser/device sign-in works in place.
7
+ *
8
+ * Security: myshell-tools never sees, handles, or stores raw credentials. Each
9
+ * CLI manages its own tokens; we only trigger its login. (This is what keeps the
10
+ * "use your subscription, no API keys" model honest.)
11
+ */
12
+ import { execa } from 'execa';
13
+ import { detectProvider, getInstallCommand } from '../providers/detect.js';
14
+ import { bold, dim, green, red } from '../ui/theme.js';
15
+ /** Each provider's interactive sign-in command. */
16
+ const LOGIN_COMMAND = {
17
+ claude: { bin: 'claude', args: ['auth', 'login'] },
18
+ codex: { bin: 'codex', args: ['login'] },
19
+ };
20
+ export function isProviderId(value) {
21
+ return value === 'claude' || value === 'codex';
22
+ }
23
+ /**
24
+ * Run the interactive sign-in flow for one provider (or all installed providers
25
+ * when no argument is given). Returns 0 on success, 1 only for an invalid
26
+ * argument — individual sign-in failures are reported but do not fail the command.
27
+ */
28
+ export async function runLogin(out, providerArg) {
29
+ let targets;
30
+ if (providerArg !== undefined) {
31
+ if (!isProviderId(providerArg)) {
32
+ out.write(red(`Unknown provider "${providerArg}". Use: claude or codex.\n`, out.color));
33
+ return 1;
34
+ }
35
+ targets = [providerArg];
36
+ }
37
+ else {
38
+ targets = ['claude', 'codex'];
39
+ }
40
+ for (const id of targets) {
41
+ const status = await detectProvider(id);
42
+ if (!status.installed) {
43
+ out.write(dim(`${id}: not installed — skipping. Install with: ${getInstallCommand(id)}\n`, out.color));
44
+ continue;
45
+ }
46
+ out.write(bold(`\nSigning in to ${id} — a browser window may open…\n`, out.color));
47
+ const { bin, args } = LOGIN_COMMAND[id];
48
+ // stdio:'inherit' hands the terminal to the provider CLI so its OAuth/device
49
+ // flow runs in place. reject:false so we report rather than throw.
50
+ const result = await execa(bin, [...args], { stdio: 'inherit', reject: false });
51
+ if (result.exitCode === 0) {
52
+ out.write(green(`✓ ${id} sign-in complete.\n`, out.color));
53
+ }
54
+ else {
55
+ out.write(red(`✗ ${id} sign-in did not complete (exit ${result.exitCode ?? 'unknown'}).\n`, out.color));
56
+ }
57
+ }
58
+ return 0;
59
+ }
60
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAG9B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAEvD,mDAAmD;AACnD,MAAM,aAAa,GAAmF;IACpG,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;IAClD,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE;CACzC,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAe,EAAE,WAAoB;IAClE,IAAI,OAAqB,CAAC;IAC1B,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,WAAW,4BAA4B,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YACxF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,GAAG,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,GAAG,CAAC,KAAK,CACP,GAAG,CAAC,GAAG,EAAE,6CAA6C,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAC5F,CAAC;YACF,SAAS;QACX,CAAC;QAED,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,iCAAiC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QACnF,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;QACxC,6EAA6E;QAC7E,mEAAmE;QACnE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAEhF,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,sBAAsB,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,KAAK,CACP,GAAG,CAAC,KAAK,EAAE,mCAAmC,MAAM,CAAC,QAAQ,IAAI,SAAS,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAC7F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myshell-tools",
3
- "version": "2.0.0-alpha.0",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "myshell-tools": "dist/cli.js",