@trading-boy/cli 0.1.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.
Files changed (106) hide show
  1. package/README.md +8 -0
  2. package/dist/api-client.d.ts +20 -0
  3. package/dist/api-client.d.ts.map +1 -0
  4. package/dist/api-client.js +81 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/cli.d.ts +5 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +71 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/commands/audit.d.ts +33 -0
  11. package/dist/commands/audit.d.ts.map +1 -0
  12. package/dist/commands/audit.js +135 -0
  13. package/dist/commands/audit.js.map +1 -0
  14. package/dist/commands/behavioral.d.ts +40 -0
  15. package/dist/commands/behavioral.d.ts.map +1 -0
  16. package/dist/commands/behavioral.js +369 -0
  17. package/dist/commands/behavioral.js.map +1 -0
  18. package/dist/commands/billing.d.ts +12 -0
  19. package/dist/commands/billing.d.ts.map +1 -0
  20. package/dist/commands/billing.js +111 -0
  21. package/dist/commands/billing.js.map +1 -0
  22. package/dist/commands/catalysts.d.ts +8 -0
  23. package/dist/commands/catalysts.d.ts.map +1 -0
  24. package/dist/commands/catalysts.js +192 -0
  25. package/dist/commands/catalysts.js.map +1 -0
  26. package/dist/commands/config-cmd.d.ts +30 -0
  27. package/dist/commands/config-cmd.d.ts.map +1 -0
  28. package/dist/commands/config-cmd.js +265 -0
  29. package/dist/commands/config-cmd.js.map +1 -0
  30. package/dist/commands/context.d.ts +40 -0
  31. package/dist/commands/context.d.ts.map +1 -0
  32. package/dist/commands/context.js +385 -0
  33. package/dist/commands/context.js.map +1 -0
  34. package/dist/commands/decisions.d.ts +21 -0
  35. package/dist/commands/decisions.d.ts.map +1 -0
  36. package/dist/commands/decisions.js +327 -0
  37. package/dist/commands/decisions.js.map +1 -0
  38. package/dist/commands/events.d.ts +3 -0
  39. package/dist/commands/events.d.ts.map +1 -0
  40. package/dist/commands/events.js +201 -0
  41. package/dist/commands/events.js.map +1 -0
  42. package/dist/commands/infra.d.ts +22 -0
  43. package/dist/commands/infra.d.ts.map +1 -0
  44. package/dist/commands/infra.js +228 -0
  45. package/dist/commands/infra.js.map +1 -0
  46. package/dist/commands/journal.d.ts +3 -0
  47. package/dist/commands/journal.d.ts.map +1 -0
  48. package/dist/commands/journal.js +616 -0
  49. package/dist/commands/journal.js.map +1 -0
  50. package/dist/commands/login.d.ts +18 -0
  51. package/dist/commands/login.d.ts.map +1 -0
  52. package/dist/commands/login.js +121 -0
  53. package/dist/commands/login.js.map +1 -0
  54. package/dist/commands/logout.d.ts +7 -0
  55. package/dist/commands/logout.d.ts.map +1 -0
  56. package/dist/commands/logout.js +39 -0
  57. package/dist/commands/logout.js.map +1 -0
  58. package/dist/commands/narratives.d.ts +3 -0
  59. package/dist/commands/narratives.d.ts.map +1 -0
  60. package/dist/commands/narratives.js +336 -0
  61. package/dist/commands/narratives.js.map +1 -0
  62. package/dist/commands/query.d.ts +39 -0
  63. package/dist/commands/query.d.ts.map +1 -0
  64. package/dist/commands/query.js +212 -0
  65. package/dist/commands/query.js.map +1 -0
  66. package/dist/commands/review.d.ts +3 -0
  67. package/dist/commands/review.d.ts.map +1 -0
  68. package/dist/commands/review.js +481 -0
  69. package/dist/commands/review.js.map +1 -0
  70. package/dist/commands/risk.d.ts +19 -0
  71. package/dist/commands/risk.d.ts.map +1 -0
  72. package/dist/commands/risk.js +190 -0
  73. package/dist/commands/risk.js.map +1 -0
  74. package/dist/commands/social.d.ts +9 -0
  75. package/dist/commands/social.d.ts.map +1 -0
  76. package/dist/commands/social.js +386 -0
  77. package/dist/commands/social.js.map +1 -0
  78. package/dist/commands/subscribe.d.ts +45 -0
  79. package/dist/commands/subscribe.d.ts.map +1 -0
  80. package/dist/commands/subscribe.js +259 -0
  81. package/dist/commands/subscribe.js.map +1 -0
  82. package/dist/commands/trader.d.ts +12 -0
  83. package/dist/commands/trader.d.ts.map +1 -0
  84. package/dist/commands/trader.js +265 -0
  85. package/dist/commands/trader.js.map +1 -0
  86. package/dist/commands/watch.d.ts +26 -0
  87. package/dist/commands/watch.d.ts.map +1 -0
  88. package/dist/commands/watch.js +121 -0
  89. package/dist/commands/watch.js.map +1 -0
  90. package/dist/commands/whoami.d.ts +14 -0
  91. package/dist/commands/whoami.d.ts.map +1 -0
  92. package/dist/commands/whoami.js +73 -0
  93. package/dist/commands/whoami.js.map +1 -0
  94. package/dist/credentials.d.ts +18 -0
  95. package/dist/credentials.d.ts.map +1 -0
  96. package/dist/credentials.js +164 -0
  97. package/dist/credentials.js.map +1 -0
  98. package/dist/index.d.ts +33 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +28 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/utils.d.ts +6 -0
  103. package/dist/utils.d.ts.map +1 -0
  104. package/dist/utils.js +21 -0
  105. package/dist/utils.js.map +1 -0
  106. package/package.json +40 -0
@@ -0,0 +1,121 @@
1
+ import chalk from 'chalk';
2
+ import { createLogger } from '@trading-boy/core';
3
+ import { executeQuery, formatQueryOutput } from './query.js';
4
+ import { executeContext, formatContextOutput } from './context.js';
5
+ import { formatConnectionError } from '../utils.js';
6
+ // ─── Logger ───
7
+ const logger = createLogger('cli-watch');
8
+ // ─── Default intervals ───
9
+ const DEFAULT_INTERVAL_SECONDS = 10;
10
+ const DEFAULT_CONTEXT_INTERVAL_SECONDS = 60;
11
+ /**
12
+ * Render a single query cycle — clears screen, runs query, prints output.
13
+ */
14
+ export async function renderCycle(symbol) {
15
+ try {
16
+ const result = await executeQuery(symbol);
17
+ // Clear terminal
18
+ process.stdout.write('\x1B[2J\x1B[0f');
19
+ console.log(formatQueryOutput(result));
20
+ console.log(chalk.dim(` Watching ${symbol.toUpperCase()} — refreshing every few seconds. Press Ctrl+C to stop.`));
21
+ console.log(chalk.dim(` Last updated: ${new Date().toLocaleString()}`));
22
+ console.log('');
23
+ return result;
24
+ }
25
+ catch (error) {
26
+ const message = error instanceof Error ? error.message : String(error);
27
+ logger.error({ error: message }, 'Watch cycle failed');
28
+ console.error(chalk.red(`Error: ${message}`));
29
+ const guidance = formatConnectionError(message);
30
+ if (guidance)
31
+ console.error(guidance);
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * Render a single context cycle — clears screen, assembles full ContextPackage, prints output.
37
+ */
38
+ export async function renderContextCycle(symbol, intervalSeconds) {
39
+ try {
40
+ const pkg = await executeContext(symbol);
41
+ // Clear terminal
42
+ process.stdout.write('\x1B[2J\x1B[0f');
43
+ console.log(formatContextOutput(pkg));
44
+ const intervalStr = intervalSeconds ? `${intervalSeconds}s` : '60s';
45
+ console.log(chalk.dim(` Watching ${symbol.toUpperCase()} [context] — refreshing every ${intervalStr}. Press Ctrl+C to stop.`));
46
+ console.log(chalk.dim(` Last updated: ${new Date().toLocaleString()}`));
47
+ console.log('');
48
+ return pkg;
49
+ }
50
+ catch (error) {
51
+ const message = error instanceof Error ? error.message : String(error);
52
+ logger.error({ error: message }, 'Watch context cycle failed');
53
+ console.error(chalk.red(`Error: ${message}`));
54
+ const guidance = formatConnectionError(message);
55
+ if (guidance)
56
+ console.error(guidance);
57
+ return null;
58
+ }
59
+ }
60
+ /**
61
+ * Start a watch loop that polls and re-renders at the given interval.
62
+ * Returns a WatchState with a cleanup handle.
63
+ */
64
+ export function startWatchLoop(symbol, intervalSeconds, renderFn) {
65
+ const state = { timer: null, running: true };
66
+ const render = renderFn ?? renderCycle;
67
+ // Initial render
68
+ void render(symbol);
69
+ // Set up polling interval
70
+ state.timer = setInterval(() => {
71
+ if (state.running) {
72
+ void render(symbol);
73
+ }
74
+ }, intervalSeconds * 1000);
75
+ return state;
76
+ }
77
+ /**
78
+ * Stop the watch loop and clean up resources.
79
+ */
80
+ export function stopWatchLoop(state) {
81
+ state.running = false;
82
+ if (state.timer) {
83
+ clearInterval(state.timer);
84
+ state.timer = null;
85
+ }
86
+ }
87
+ // ─── Command Registration ───
88
+ export function registerWatchCommand(program) {
89
+ program
90
+ .command('watch <symbol>')
91
+ .description('Watch token data with periodic refresh')
92
+ .option('-i, --interval <seconds>', 'Refresh interval in seconds', (v) => parseInt(v, 10))
93
+ .option('-c, --context', 'Watch full ContextPackage (default interval: 60s)')
94
+ .action(async (symbol, options) => {
95
+ const useContext = options.context === true;
96
+ const defaultInterval = useContext ? DEFAULT_CONTEXT_INTERVAL_SECONDS : DEFAULT_INTERVAL_SECONDS;
97
+ const intervalSeconds = options.interval ?? defaultInterval;
98
+ if (intervalSeconds < 1) {
99
+ console.error(chalk.red('Error: Interval must be at least 1 second'));
100
+ process.exitCode = 1;
101
+ return;
102
+ }
103
+ const mode = useContext ? 'context' : 'query';
104
+ logger.info({ symbol, intervalSeconds, mode }, 'Starting watch mode');
105
+ const renderFn = useContext
106
+ ? (sym) => renderContextCycle(sym, intervalSeconds)
107
+ : renderCycle;
108
+ const state = startWatchLoop(symbol, intervalSeconds, renderFn);
109
+ // Clean exit on SIGINT (Ctrl+C)
110
+ const cleanup = () => {
111
+ logger.info('Watch mode stopped by user');
112
+ stopWatchLoop(state);
113
+ console.log('');
114
+ console.log(chalk.dim(' Watch mode stopped.'));
115
+ process.exit(0);
116
+ };
117
+ process.on('SIGINT', cleanup);
118
+ process.on('SIGTERM', cleanup);
119
+ });
120
+ }
121
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Command } from 'commander';
2
+ export interface WhoamiResult {
3
+ authenticated: boolean;
4
+ email?: string;
5
+ plan?: string;
6
+ keyId?: string;
7
+ redactedKey?: string;
8
+ storageMethod?: string;
9
+ storedAt?: string;
10
+ }
11
+ export declare function executeWhoami(): Promise<WhoamiResult>;
12
+ export declare function formatWhoamiOutput(result: WhoamiResult): string;
13
+ export declare function registerWhoamiCommand(program: Command): void;
14
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,wBAAsB,aAAa,IAAI,OAAO,CAAC,YAAY,CAAC,CAgB3D;AAID,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAoC/D;AAID,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAe5D"}
@@ -0,0 +1,73 @@
1
+ import chalk from 'chalk';
2
+ import { createLogger } from '@trading-boy/core';
3
+ import { loadCredentials, redactApiKey } from '../credentials.js';
4
+ const logger = createLogger('cli-whoami');
5
+ // ─── Whoami Logic ───
6
+ export async function executeWhoami() {
7
+ const creds = await loadCredentials();
8
+ if (!creds) {
9
+ return { authenticated: false };
10
+ }
11
+ return {
12
+ authenticated: true,
13
+ email: creds.email,
14
+ plan: creds.plan,
15
+ keyId: creds.keyId,
16
+ redactedKey: redactApiKey(creds.apiKey),
17
+ storageMethod: creds.storageMethod,
18
+ storedAt: creds.storedAt,
19
+ };
20
+ }
21
+ // ─── Formatter ───
22
+ export function formatWhoamiOutput(result) {
23
+ const lines = [];
24
+ lines.push('');
25
+ if (!result.authenticated) {
26
+ lines.push(chalk.dim(' Not authenticated. Run `trading-boy login` to get started.'));
27
+ lines.push('');
28
+ return lines.join('\n');
29
+ }
30
+ lines.push(chalk.bold.cyan(' Authenticated'));
31
+ lines.push(chalk.gray(' ' + '─'.repeat(40)));
32
+ lines.push('');
33
+ if (result.email) {
34
+ lines.push(` ${chalk.gray('Account:')} ${result.email}`);
35
+ }
36
+ if (result.plan) {
37
+ lines.push(` ${chalk.gray('Plan:')} ${result.plan}`);
38
+ }
39
+ if (result.keyId) {
40
+ lines.push(` ${chalk.gray('Key ID:')} ${result.keyId}`);
41
+ }
42
+ if (result.redactedKey) {
43
+ lines.push(` ${chalk.gray('Key:')} ${result.redactedKey}`);
44
+ }
45
+ if (result.storageMethod) {
46
+ lines.push(` ${chalk.gray('Storage:')} ${result.storageMethod}`);
47
+ }
48
+ if (result.storedAt) {
49
+ const date = new Date(result.storedAt).toLocaleString();
50
+ lines.push(` ${chalk.gray('Since:')} ${date}`);
51
+ }
52
+ lines.push('');
53
+ return lines.join('\n');
54
+ }
55
+ // ─── Command Registration ───
56
+ export function registerWhoamiCommand(program) {
57
+ program
58
+ .command('whoami')
59
+ .description('Show current authentication status')
60
+ .action(async () => {
61
+ try {
62
+ const result = await executeWhoami();
63
+ console.log(formatWhoamiOutput(result));
64
+ }
65
+ catch (error) {
66
+ const message = error instanceof Error ? error.message : String(error);
67
+ logger.error({ error: message }, 'Whoami failed');
68
+ console.error(chalk.red(` Error: ${message}`));
69
+ process.exitCode = 1;
70
+ }
71
+ });
72
+ }
73
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface StoredCredentials {
2
+ apiKey: string;
3
+ keyId?: string;
4
+ email?: string;
5
+ plan?: string;
6
+ storedAt: string;
7
+ storageMethod: 'keychain' | 'file';
8
+ }
9
+ export declare function storeCredentials(apiKey: string, metadata?: {
10
+ keyId?: string;
11
+ email?: string;
12
+ plan?: string;
13
+ }): Promise<void>;
14
+ export declare function loadCredentials(): Promise<StoredCredentials | null>;
15
+ export declare function clearCredentials(): Promise<void>;
16
+ export declare function redactApiKey(key: string): string;
17
+ export declare function getCredentialsFilePath(): string;
18
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,UAAU,GAAG,MAAM,CAAC;CACpC;AAkGD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3D,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA2BzE;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAGtD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C"}
@@ -0,0 +1,164 @@
1
+ import { homedir } from 'node:os';
2
+ import { join } from 'node:path';
3
+ import { mkdirSync, readFileSync, writeFileSync, unlinkSync, existsSync } from 'node:fs';
4
+ import { createLogger } from '@trading-boy/core';
5
+ const logger = createLogger('cli-credentials');
6
+ // ─── Constants ───
7
+ const SERVICE_NAME = 'trading-boy';
8
+ const ACCOUNT_NAME = 'api-key';
9
+ function getConfigDir() {
10
+ return join(homedir(), '.config', 'trading-boy');
11
+ }
12
+ function getCredentialsFile() {
13
+ return join(getConfigDir(), 'credentials.json');
14
+ }
15
+ // ─── Keychain Operations ───
16
+ async function loadKeyring() {
17
+ try {
18
+ return await import('@napi-rs/keyring');
19
+ }
20
+ catch {
21
+ logger.debug('Keychain not available, using file fallback');
22
+ return null;
23
+ }
24
+ }
25
+ async function storeInKeychain(apiKey) {
26
+ const keyring = await loadKeyring();
27
+ if (!keyring)
28
+ return false;
29
+ try {
30
+ const entry = new keyring.Entry(SERVICE_NAME, ACCOUNT_NAME);
31
+ entry.setPassword(apiKey);
32
+ return true;
33
+ }
34
+ catch (err) {
35
+ logger.debug({ error: String(err) }, 'Keychain store failed');
36
+ return false;
37
+ }
38
+ }
39
+ async function loadFromKeychain() {
40
+ const keyring = await loadKeyring();
41
+ if (!keyring)
42
+ return null;
43
+ try {
44
+ const entry = new keyring.Entry(SERVICE_NAME, ACCOUNT_NAME);
45
+ return entry.getPassword();
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ async function deleteFromKeychain() {
52
+ const keyring = await loadKeyring();
53
+ if (!keyring)
54
+ return false;
55
+ try {
56
+ const entry = new keyring.Entry(SERVICE_NAME, ACCOUNT_NAME);
57
+ entry.deletePassword();
58
+ return true;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ }
64
+ // ─── File Operations ───
65
+ function ensureConfigDir() {
66
+ const configDir = getConfigDir();
67
+ if (!existsSync(configDir)) {
68
+ mkdirSync(configDir, { recursive: true, mode: 0o700 });
69
+ }
70
+ }
71
+ function writeCredentialsFile(data) {
72
+ ensureConfigDir();
73
+ writeFileSync(getCredentialsFile(), JSON.stringify(data, null, 2), { mode: 0o600 });
74
+ }
75
+ function readCredentialsFile() {
76
+ const credFile = getCredentialsFile();
77
+ if (!existsSync(credFile))
78
+ return null;
79
+ try {
80
+ const content = readFileSync(credFile, 'utf-8');
81
+ return JSON.parse(content);
82
+ }
83
+ catch {
84
+ return null;
85
+ }
86
+ }
87
+ function deleteCredentialsFile() {
88
+ const credFile = getCredentialsFile();
89
+ if (existsSync(credFile)) {
90
+ // Overwrite before unlinking for secure deletion
91
+ writeFileSync(credFile, '0'.repeat(1024));
92
+ unlinkSync(credFile);
93
+ }
94
+ }
95
+ // ─── Public API ───
96
+ export async function storeCredentials(apiKey, metadata) {
97
+ const storedAt = new Date().toISOString();
98
+ // Try keychain first
99
+ const keychainOk = await storeInKeychain(apiKey);
100
+ if (keychainOk) {
101
+ // Store metadata in file, key in keychain
102
+ writeCredentialsFile({
103
+ keyId: metadata?.keyId,
104
+ email: metadata?.email,
105
+ plan: metadata?.plan,
106
+ storedAt,
107
+ storageMethod: 'keychain',
108
+ });
109
+ }
110
+ else {
111
+ // Fallback: store everything in file
112
+ writeCredentialsFile({
113
+ apiKey,
114
+ keyId: metadata?.keyId,
115
+ email: metadata?.email,
116
+ plan: metadata?.plan,
117
+ storedAt,
118
+ storageMethod: 'file',
119
+ });
120
+ }
121
+ }
122
+ export async function loadCredentials() {
123
+ const fileData = readCredentialsFile();
124
+ if (!fileData)
125
+ return null;
126
+ let apiKey;
127
+ if (fileData.storageMethod === 'keychain') {
128
+ apiKey = (await loadFromKeychain()) ?? undefined;
129
+ if (!apiKey) {
130
+ // Keychain entry was deleted externally
131
+ logger.warn('Keychain entry missing — credentials may need to be re-entered');
132
+ return null;
133
+ }
134
+ }
135
+ else {
136
+ apiKey = fileData.apiKey;
137
+ }
138
+ if (!apiKey)
139
+ return null;
140
+ return {
141
+ apiKey,
142
+ keyId: fileData.keyId,
143
+ email: fileData.email,
144
+ plan: fileData.plan,
145
+ storedAt: fileData.storedAt,
146
+ storageMethod: fileData.storageMethod,
147
+ };
148
+ }
149
+ export async function clearCredentials() {
150
+ await deleteFromKeychain();
151
+ deleteCredentialsFile();
152
+ }
153
+ export function redactApiKey(key) {
154
+ if (key.length <= 12)
155
+ return '****';
156
+ // Show prefix + last 4 chars: tb_live_****abcd
157
+ const prefix = key.slice(0, 8);
158
+ const suffix = key.slice(-4);
159
+ return `${prefix}****${suffix}`;
160
+ }
161
+ export function getCredentialsFilePath() {
162
+ return getCredentialsFile();
163
+ }
164
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export { createCli, main } from './cli.js';
2
+ export { formatConnectionError } from './utils.js';
3
+ export { registerJournalCommand } from './commands/journal.js';
4
+ export { registerQueryCommand, executeQuery, formatQueryOutput } from './commands/query.js';
5
+ export type { QueryResult } from './commands/query.js';
6
+ export { registerWatchCommand, startWatchLoop, stopWatchLoop, renderCycle, renderContextCycle } from './commands/watch.js';
7
+ export type { WatchState } from './commands/watch.js';
8
+ export { registerAuditCommand, toVerifiableDecision, buildAuditResult, formatAuditVerifyOutput } from './commands/audit.js';
9
+ export type { AuditVerifyResult } from './commands/audit.js';
10
+ export { registerEventsCommand } from './commands/events.js';
11
+ export { registerRiskCommand, formatRiskOutput, formatContagionOutput, formatRiskScore } from './commands/risk.js';
12
+ export { registerCatalystsCommand, formatCatalystsOutput } from './commands/catalysts.js';
13
+ export { registerDecisionsCommand, formatDecisionsOutput, formatStatsOutput, formatSetupTypeStats, parsePeriod } from './commands/decisions.js';
14
+ export { registerSocialCommand, formatTokenSocial } from './commands/social.js';
15
+ export { registerNarrativeCommand } from './commands/narratives.js';
16
+ export { registerTraderCommand, formatTraderOutput, formatTraderListOutput } from './commands/trader.js';
17
+ export { registerBehavioralCommand, formatBehavioralProfile, formatBehavioralFlags, parsePeriodDays, colorScore, colorHonorRate, scoreLabel, } from './commands/behavioral.js';
18
+ export { registerContextCommand, executeContext, formatContextOutput, formatMarketSection, formatOnchainSection, formatRiskSection, formatCatalystsSection, formatSocialSection, formatSynthesisSection, formatMetaSection, } from './commands/context.js';
19
+ export { registerConfigCommand, formatConfigOutput, redactValue, resolveEnvPath, parseEnvFile, writeEnvValue, } from './commands/config-cmd.js';
20
+ export { registerInfraCommand, checkInfraStatus, formatInfraStatus, } from './commands/infra.js';
21
+ export type { InfraStatusResult } from './commands/infra.js';
22
+ export { registerLoginCommand, validateApiKeyFormat, verifyApiKey, executeLogin } from './commands/login.js';
23
+ export { registerLogoutCommand, executeLogout } from './commands/logout.js';
24
+ export { registerWhoamiCommand, executeWhoami, formatWhoamiOutput } from './commands/whoami.js';
25
+ export type { WhoamiResult } from './commands/whoami.js';
26
+ export { registerBillingCommand, formatBillingStatus } from './commands/billing.js';
27
+ export type { BillingStatusResponse } from './commands/billing.js';
28
+ export { registerSubscribeCommand, createCheckoutSession, pollProvisioningToken, pollForApiKey, saveApiKey, formatSubscribeSuccess, } from './commands/subscribe.js';
29
+ export type { CheckoutResponse, ProvisionResponse, PollResult, } from './commands/subscribe.js';
30
+ export { storeCredentials, loadCredentials, clearCredentials, redactApiKey, getCredentialsFilePath } from './credentials.js';
31
+ export type { StoredCredentials } from './credentials.js';
32
+ export { apiRequest, resolveApiKey, getApiBase, ApiError } from './api-client.js';
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ // CLI entry point
2
+ export { createCli, main } from './cli.js';
3
+ export { formatConnectionError } from './utils.js';
4
+ export { registerJournalCommand } from './commands/journal.js';
5
+ export { registerQueryCommand, executeQuery, formatQueryOutput } from './commands/query.js';
6
+ export { registerWatchCommand, startWatchLoop, stopWatchLoop, renderCycle, renderContextCycle } from './commands/watch.js';
7
+ export { registerAuditCommand, toVerifiableDecision, buildAuditResult, formatAuditVerifyOutput } from './commands/audit.js';
8
+ export { registerEventsCommand } from './commands/events.js';
9
+ export { registerRiskCommand, formatRiskOutput, formatContagionOutput, formatRiskScore } from './commands/risk.js';
10
+ export { registerCatalystsCommand, formatCatalystsOutput } from './commands/catalysts.js';
11
+ export { registerDecisionsCommand, formatDecisionsOutput, formatStatsOutput, formatSetupTypeStats, parsePeriod } from './commands/decisions.js';
12
+ export { registerSocialCommand, formatTokenSocial } from './commands/social.js';
13
+ export { registerNarrativeCommand } from './commands/narratives.js';
14
+ export { registerTraderCommand, formatTraderOutput, formatTraderListOutput } from './commands/trader.js';
15
+ export { registerBehavioralCommand, formatBehavioralProfile, formatBehavioralFlags, parsePeriodDays, colorScore, colorHonorRate, scoreLabel, } from './commands/behavioral.js';
16
+ export { registerContextCommand, executeContext, formatContextOutput, formatMarketSection, formatOnchainSection, formatRiskSection, formatCatalystsSection, formatSocialSection, formatSynthesisSection, formatMetaSection, } from './commands/context.js';
17
+ export { registerConfigCommand, formatConfigOutput, redactValue, resolveEnvPath, parseEnvFile, writeEnvValue, } from './commands/config-cmd.js';
18
+ export { registerInfraCommand, checkInfraStatus, formatInfraStatus, } from './commands/infra.js';
19
+ // Authentication
20
+ export { registerLoginCommand, validateApiKeyFormat, verifyApiKey, executeLogin } from './commands/login.js';
21
+ export { registerLogoutCommand, executeLogout } from './commands/logout.js';
22
+ export { registerWhoamiCommand, executeWhoami, formatWhoamiOutput } from './commands/whoami.js';
23
+ export { registerBillingCommand, formatBillingStatus } from './commands/billing.js';
24
+ export { registerSubscribeCommand, createCheckoutSession, pollProvisioningToken, pollForApiKey, saveApiKey, formatSubscribeSuccess, } from './commands/subscribe.js';
25
+ // Credentials & API client
26
+ export { storeCredentials, loadCredentials, clearCredentials, redactApiKey, getCredentialsFilePath } from './credentials.js';
27
+ export { apiRequest, resolveApiKey, getApiBase, ApiError } from './api-client.js';
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAClB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE5F,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE3H,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE5H,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACnH,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAChJ,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACzG,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,cAAc,EACd,UAAU,GACX,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAE7B,iBAAiB;AACjB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC7G,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAEhG,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEpF,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,UAAU,EACV,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAMjC,2BAA2B;AAC3B,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE7H,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Detect connection failure patterns in error messages and return
3
+ * actionable guidance lines. Returns null for non-connection errors.
4
+ */
5
+ export declare function formatConnectionError(message: string): string | null;
6
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBpE"}
package/dist/utils.js ADDED
@@ -0,0 +1,21 @@
1
+ import chalk from 'chalk';
2
+ /**
3
+ * Detect connection failure patterns in error messages and return
4
+ * actionable guidance lines. Returns null for non-connection errors.
5
+ */
6
+ export function formatConnectionError(message) {
7
+ const lower = message.toLowerCase();
8
+ const isConnectionError = lower.includes('econnrefused') ||
9
+ lower.includes('serviceunavailable') ||
10
+ lower.includes('failed to connect') ||
11
+ lower.includes('connection refused') ||
12
+ lower.includes('max retries per request limit exceeded') ||
13
+ lower.includes('enotfound');
14
+ if (!isConnectionError)
15
+ return null;
16
+ return [
17
+ chalk.dim(' → Is the infrastructure running? Try: trading-boy infra status'),
18
+ chalk.dim(' → To start: pnpm infra:up'),
19
+ ].join('\n');
20
+ }
21
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAEpC,MAAM,iBAAiB,GACrB,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC9B,KAAK,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QACpC,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QACnC,KAAK,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QACpC,KAAK,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACxD,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAE9B,IAAI,CAAC,iBAAiB;QAAE,OAAO,IAAI,CAAC;IAEpC,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,kEAAkE,CAAC;QAC7E,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC;KACzC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@trading-boy/cli",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "trading-boy": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "!dist/**/*.test.*"
13
+ ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "dependencies": {
18
+ "@inquirer/prompts": "^7.0.0",
19
+ "@napi-rs/keyring": "^1.1.3",
20
+ "chalk": "^5.4.0",
21
+ "commander": "^13.0.0",
22
+ "ioredis": "^5.4.0",
23
+ "open": "^10.1.0",
24
+ "ora": "^9.3.0",
25
+ "@trading-boy/context-engine": "0.1.0",
26
+ "@trading-boy/graph-db": "0.1.0",
27
+ "@trading-boy/timeseries-db": "0.1.0",
28
+ "@trading-boy/core": "0.1.0"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "^5.7.0"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "typecheck": "tsc --noEmit",
36
+ "test": "vitest run",
37
+ "lint": "eslint src/",
38
+ "clean": "rm -rf dist .turbo"
39
+ }
40
+ }