@nac3/forge-cli 0.2.0-alpha.3 → 0.2.0-alpha.31

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 (166) hide show
  1. package/dist/bin/yf.d.ts.map +1 -1
  2. package/dist/bin/yf.js +27 -0
  3. package/dist/bin/yf.js.map +1 -1
  4. package/dist/chat/claude.d.ts +22 -15
  5. package/dist/chat/claude.d.ts.map +1 -1
  6. package/dist/chat/claude.js +75 -22
  7. package/dist/chat/claude.js.map +1 -1
  8. package/dist/chat/panel.d.ts.map +1 -1
  9. package/dist/chat/panel.js +791 -17
  10. package/dist/chat/panel.js.map +1 -1
  11. package/dist/chat/server.js +734 -32
  12. package/dist/chat/server.js.map +1 -1
  13. package/dist/chat/spec_extract.d.ts.map +1 -1
  14. package/dist/chat/spec_extract.js +39 -0
  15. package/dist/chat/spec_extract.js.map +1 -1
  16. package/dist/chat/tools/audit_consumers.d.ts +66 -0
  17. package/dist/chat/tools/audit_consumers.d.ts.map +1 -0
  18. package/dist/chat/tools/audit_consumers.js +231 -0
  19. package/dist/chat/tools/audit_consumers.js.map +1 -0
  20. package/dist/chat/tools/git.js +4 -4
  21. package/dist/chat/tools/github.js +3 -3
  22. package/dist/chat/tools/keys.d.ts +9 -0
  23. package/dist/chat/tools/keys.d.ts.map +1 -0
  24. package/dist/chat/tools/keys.js +194 -0
  25. package/dist/chat/tools/keys.js.map +1 -0
  26. package/dist/chat/tools/lifecycle.js +3 -3
  27. package/dist/chat/tools/manual.js +1 -1
  28. package/dist/chat/tools/reader.js +8 -8
  29. package/dist/chat/tools/workflow.d.ts +45 -0
  30. package/dist/chat/tools/workflow.d.ts.map +1 -0
  31. package/dist/chat/tools/workflow.js +404 -0
  32. package/dist/chat/tools/workflow.js.map +1 -0
  33. package/dist/chat/tools.d.ts.map +1 -1
  34. package/dist/chat/tools.js +31 -4
  35. package/dist/chat/tools.js.map +1 -1
  36. package/dist/commands/approve.d.ts +32 -0
  37. package/dist/commands/approve.d.ts.map +1 -0
  38. package/dist/commands/approve.js +198 -0
  39. package/dist/commands/approve.js.map +1 -0
  40. package/dist/commands/block.d.ts +28 -0
  41. package/dist/commands/block.d.ts.map +1 -0
  42. package/dist/commands/block.js +189 -0
  43. package/dist/commands/block.js.map +1 -0
  44. package/dist/commands/bootstrap.d.ts +35 -0
  45. package/dist/commands/bootstrap.d.ts.map +1 -0
  46. package/dist/commands/bootstrap.js +205 -0
  47. package/dist/commands/bootstrap.js.map +1 -0
  48. package/dist/commands/chat.d.ts +3 -0
  49. package/dist/commands/chat.d.ts.map +1 -1
  50. package/dist/commands/chat.js +46 -1
  51. package/dist/commands/chat.js.map +1 -1
  52. package/dist/commands/clarify.d.ts +30 -0
  53. package/dist/commands/clarify.d.ts.map +1 -0
  54. package/dist/commands/clarify.js +671 -0
  55. package/dist/commands/clarify.js.map +1 -0
  56. package/dist/commands/discover.d.ts +30 -0
  57. package/dist/commands/discover.d.ts.map +1 -0
  58. package/dist/commands/discover.js +178 -0
  59. package/dist/commands/discover.js.map +1 -0
  60. package/dist/commands/doctor.js +94 -42
  61. package/dist/commands/doctor.js.map +1 -1
  62. package/dist/commands/keys_setup.d.ts +53 -0
  63. package/dist/commands/keys_setup.d.ts.map +1 -0
  64. package/dist/commands/keys_setup.js +487 -0
  65. package/dist/commands/keys_setup.js.map +1 -0
  66. package/dist/commands/legacy-audit.d.ts +34 -0
  67. package/dist/commands/legacy-audit.d.ts.map +1 -0
  68. package/dist/commands/legacy-audit.js +270 -0
  69. package/dist/commands/legacy-audit.js.map +1 -0
  70. package/dist/commands/license.d.ts.map +1 -1
  71. package/dist/commands/license.js +41 -0
  72. package/dist/commands/license.js.map +1 -1
  73. package/dist/commands/operate.d.ts +22 -0
  74. package/dist/commands/operate.d.ts.map +1 -0
  75. package/dist/commands/operate.js +523 -0
  76. package/dist/commands/operate.js.map +1 -0
  77. package/dist/commands/spec.d.ts +38 -0
  78. package/dist/commands/spec.d.ts.map +1 -0
  79. package/dist/commands/spec.js +256 -0
  80. package/dist/commands/spec.js.map +1 -0
  81. package/dist/commands/support.d.ts +22 -0
  82. package/dist/commands/support.d.ts.map +1 -0
  83. package/dist/commands/support.js +143 -0
  84. package/dist/commands/support.js.map +1 -0
  85. package/dist/commands/triage.d.ts +34 -0
  86. package/dist/commands/triage.d.ts.map +1 -0
  87. package/dist/commands/triage.js +228 -0
  88. package/dist/commands/triage.js.map +1 -0
  89. package/dist/commands/vault-inventory.d.ts +30 -0
  90. package/dist/commands/vault-inventory.d.ts.map +1 -0
  91. package/dist/commands/vault-inventory.js +214 -0
  92. package/dist/commands/vault-inventory.js.map +1 -0
  93. package/dist/commands/vault.d.ts.map +1 -1
  94. package/dist/commands/vault.js +5 -0
  95. package/dist/commands/vault.js.map +1 -1
  96. package/dist/commands/voice.js +1 -1
  97. package/dist/commands/voice.js.map +1 -1
  98. package/dist/commands/workflow-coverage.d.ts +30 -0
  99. package/dist/commands/workflow-coverage.d.ts.map +1 -0
  100. package/dist/commands/workflow-coverage.js +138 -0
  101. package/dist/commands/workflow-coverage.js.map +1 -0
  102. package/dist/core/keys_envelope.d.ts +13 -0
  103. package/dist/core/keys_envelope.d.ts.map +1 -1
  104. package/dist/core/keys_envelope.js.map +1 -1
  105. package/dist/deploy/adapter.d.ts +93 -0
  106. package/dist/deploy/adapter.d.ts.map +1 -0
  107. package/dist/deploy/adapter.js +42 -0
  108. package/dist/deploy/adapter.js.map +1 -0
  109. package/dist/deploy/aws_adapter.d.ts +28 -0
  110. package/dist/deploy/aws_adapter.d.ts.map +1 -0
  111. package/dist/deploy/aws_adapter.js +98 -0
  112. package/dist/deploy/aws_adapter.js.map +1 -0
  113. package/dist/deploy/cloudflare.d.ts +24 -0
  114. package/dist/deploy/cloudflare.d.ts.map +1 -0
  115. package/dist/deploy/cloudflare.js +169 -0
  116. package/dist/deploy/cloudflare.js.map +1 -0
  117. package/dist/license/hito4_client.d.ts +17 -1
  118. package/dist/license/hito4_client.d.ts.map +1 -1
  119. package/dist/license/hito4_client.js +71 -10
  120. package/dist/license/hito4_client.js.map +1 -1
  121. package/dist/license/index.d.ts.map +1 -1
  122. package/dist/license/index.js +7 -0
  123. package/dist/license/index.js.map +1 -1
  124. package/dist/license/sync.d.ts +54 -0
  125. package/dist/license/sync.d.ts.map +1 -0
  126. package/dist/license/sync.js +131 -0
  127. package/dist/license/sync.js.map +1 -0
  128. package/dist/support/reports.d.ts +31 -0
  129. package/dist/support/reports.d.ts.map +1 -0
  130. package/dist/support/reports.js +162 -0
  131. package/dist/support/reports.js.map +1 -0
  132. package/dist/telemetry/usage.d.ts +67 -0
  133. package/dist/telemetry/usage.d.ts.map +1 -0
  134. package/dist/telemetry/usage.js +208 -0
  135. package/dist/telemetry/usage.js.map +1 -0
  136. package/dist/version.d.ts +1 -1
  137. package/dist/version.d.ts.map +1 -1
  138. package/dist/version.js +1 -1
  139. package/dist/version.js.map +1 -1
  140. package/dist/voice/intents.d.ts +1 -1
  141. package/dist/voice/intents.js +0 -0
  142. package/dist/voice/providers/google.d.ts +9 -0
  143. package/dist/voice/providers/google.d.ts.map +1 -1
  144. package/dist/voice/providers/google.js +204 -28
  145. package/dist/voice/providers/google.js.map +1 -1
  146. package/dist/voice/router.d.ts +10 -0
  147. package/dist/voice/router.d.ts.map +1 -1
  148. package/dist/voice/router.js +39 -20
  149. package/dist/voice/router.js.map +1 -1
  150. package/dist/voice/types.d.ts +5 -2
  151. package/dist/voice/types.d.ts.map +1 -1
  152. package/dist/voice/types.js.map +1 -1
  153. package/dist/workflow/state.d.ts +190 -0
  154. package/dist/workflow/state.d.ts.map +1 -0
  155. package/dist/workflow/state.js +119 -0
  156. package/dist/workflow/state.js.map +1 -0
  157. package/package.json +13 -15
  158. package/templates/nextjs-app/README.md +48 -0
  159. package/templates/nextjs-app/next.config.js +8 -0
  160. package/templates/nextjs-app/package.json +33 -0
  161. package/templates/nextjs-app/src/app/globals.css +43 -0
  162. package/templates/nextjs-app/src/app/layout.tsx +29 -0
  163. package/templates/nextjs-app/src/app/page.tsx +63 -0
  164. package/templates/nextjs-app/src/nac/manifest.ts +36 -0
  165. package/templates/nextjs-app/tsconfig.json +21 -0
  166. package/templates/nextjs-app/yujin.forge.json +11 -0
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Support report sink. Captures runtime errors from the chat
3
+ * panel (window.onerror, unhandled promise rejection, fetch
4
+ * failures) and persists them to a local JSONL log so we have
5
+ * a reproducible trail when a user reports "no me escucha" or
6
+ * "nada anda".
7
+ *
8
+ * Per SQ Sec 15: this surface exists so the user does NOT
9
+ * have to open DevTools + copy logs. Forge sees what the
10
+ * browser saw, from the server side.
11
+ *
12
+ * Where: ~/.yujin-forge/support_reports.jsonl
13
+ *
14
+ * Rotation: when the file exceeds 5 MB, the existing file is
15
+ * renamed to support_reports.jsonl.1 (previous .1 deleted) and
16
+ * a fresh file starts. One generation of history kept.
17
+ *
18
+ * PII scrubbing: emails + bearer tokens + sk-* keys + 32+ hex
19
+ * blobs are replaced with <redacted>.
20
+ *
21
+ * ASCII-only.
22
+ */
23
+ import { promises as fs } from 'node:fs';
24
+ import path from 'node:path';
25
+ import { configDir } from '../license/index.js';
26
+ const MAX_FILE_BYTES = 5 * 1024 * 1024;
27
+ const PII_REGEXES = [
28
+ { re: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, replace: '<redacted-email>' },
29
+ { re: /sk-ant-[A-Za-z0-9_-]{20,}/g, replace: '<redacted-anthropic-key>' },
30
+ { re: /sk-[A-Za-z0-9_-]{20,}/g, replace: '<redacted-api-key>' },
31
+ { re: /Bearer\s+[A-Za-z0-9._-]{20,}/g, replace: 'Bearer <redacted>' },
32
+ { re: /\b[a-f0-9]{40,}\b/g, replace: '<redacted-hex>' },
33
+ ];
34
+ /** Replace PII patterns in any string field of the report. */
35
+ export function scrubPii(report) {
36
+ const out = { ...report };
37
+ const passFields = ['message', 'stack', 'url', 'user_agent', 'view'];
38
+ for (const f of passFields) {
39
+ const v = out[f];
40
+ if (typeof v === 'string') {
41
+ let scrubbed = v;
42
+ for (const { re, replace } of PII_REGEXES) {
43
+ scrubbed = scrubbed.replace(re, replace);
44
+ }
45
+ out[f] = scrubbed;
46
+ }
47
+ }
48
+ /* Also scrub request_trail URLs (could contain tokens in
49
+ * query strings). */
50
+ if (Array.isArray(out.request_trail)) {
51
+ out.request_trail = out.request_trail.map((r) => {
52
+ let u = r.url;
53
+ for (const { re, replace } of PII_REGEXES)
54
+ u = u.replace(re, replace);
55
+ return { ...r, url: u };
56
+ });
57
+ }
58
+ return out;
59
+ }
60
+ function reportsFile() {
61
+ return path.join(configDir(), 'support_reports.jsonl');
62
+ }
63
+ function rotatedFile() {
64
+ return path.join(configDir(), 'support_reports.jsonl.1');
65
+ }
66
+ async function ensureDir() {
67
+ try {
68
+ await fs.mkdir(configDir(), { recursive: true });
69
+ }
70
+ catch { /* ok */ }
71
+ }
72
+ async function rotateIfBig() {
73
+ try {
74
+ const st = await fs.stat(reportsFile());
75
+ if (st.size > MAX_FILE_BYTES) {
76
+ try {
77
+ await fs.unlink(rotatedFile());
78
+ }
79
+ catch { /* ok */ }
80
+ await fs.rename(reportsFile(), rotatedFile());
81
+ }
82
+ }
83
+ catch { /* file does not exist yet, nothing to rotate */ }
84
+ }
85
+ /** Append a single report. Never throws. */
86
+ export async function recordReport(report) {
87
+ try {
88
+ await ensureDir();
89
+ await rotateIfBig();
90
+ const scrubbed = scrubPii(report);
91
+ await fs.appendFile(reportsFile(), JSON.stringify(scrubbed) + '\n', 'utf-8');
92
+ }
93
+ catch {
94
+ /* swallow */
95
+ }
96
+ }
97
+ /** Read all reports (current + rotated). Tolerates malformed lines. */
98
+ export async function readReports() {
99
+ const all = [];
100
+ for (const fp of [rotatedFile(), reportsFile()]) {
101
+ try {
102
+ const raw = await fs.readFile(fp, 'utf-8');
103
+ for (const line of raw.split('\n')) {
104
+ if (line.trim() === '')
105
+ continue;
106
+ try {
107
+ all.push(JSON.parse(line));
108
+ }
109
+ catch { /* skip */ }
110
+ }
111
+ }
112
+ catch { /* file may not exist */ }
113
+ }
114
+ return all;
115
+ }
116
+ /** Validate + normalize an inbound payload from the panel.
117
+ * Returns null when the payload shape is unacceptable. */
118
+ export function validateInbound(body, defaults = {}) {
119
+ if (!body || typeof body !== 'object' || Array.isArray(body))
120
+ return null;
121
+ const b = body;
122
+ const level = b.level;
123
+ if (level !== 'error' && level !== 'warn' && level !== 'info')
124
+ return null;
125
+ const source = typeof b.source === 'string' ? b.source : 'panel';
126
+ const message = typeof b.message === 'string' ? b.message : '';
127
+ if (message === '')
128
+ return null;
129
+ const report = {
130
+ ts: new Date().toISOString(),
131
+ level,
132
+ source,
133
+ message: message.slice(0, 2000),
134
+ };
135
+ if (typeof b.stack === 'string')
136
+ report.stack = b.stack.slice(0, 8000);
137
+ if (typeof b.url === 'string')
138
+ report.url = b.url.slice(0, 500);
139
+ if (typeof b.line === 'number')
140
+ report.line = b.line;
141
+ if (typeof b.col === 'number')
142
+ report.col = b.col;
143
+ if (typeof b.view === 'string')
144
+ report.view = b.view.slice(0, 100);
145
+ if (typeof b.client_ts === 'string')
146
+ report.client_ts = b.client_ts.slice(0, 64);
147
+ if (defaults.user_agent)
148
+ report.user_agent = defaults.user_agent.slice(0, 200);
149
+ if (Array.isArray(b.request_trail)) {
150
+ report.request_trail = b.request_trail
151
+ .slice(-10)
152
+ .filter((r) => r && typeof r === 'object'
153
+ && typeof r.method === 'string' && typeof r.url === 'string')
154
+ .map((r) => ({
155
+ method: String(r.method).slice(0, 10),
156
+ url: String(r.url).slice(0, 500),
157
+ ...(typeof r.status === 'number' ? { status: r.status } : {}),
158
+ }));
159
+ }
160
+ return report;
161
+ }
162
+ //# sourceMappingURL=reports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/support/reports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ export type UsageKind = 'claude.chat' | 'claude.spec' | 'claude.clarify' | 'claude.triage' | 'voice.tts' | 'voice.stt' | 'misc';
2
+ export interface UsageEvent {
3
+ ts: string;
4
+ kind: UsageKind;
5
+ model?: string;
6
+ tokens_in?: number;
7
+ tokens_out?: number;
8
+ units?: number;
9
+ label?: string;
10
+ project_root?: string;
11
+ }
12
+ export interface PricingTable {
13
+ models?: Record<string, {
14
+ in_per_mtok: number;
15
+ out_per_mtok: number;
16
+ }>;
17
+ voice?: {
18
+ tts_per_million_chars?: number;
19
+ stt_per_minute?: number;
20
+ };
21
+ }
22
+ export declare const DEFAULT_PRICING: PricingTable;
23
+ /**
24
+ * Append a usage event. Never throws -- failures swallowed.
25
+ */
26
+ export declare function recordUsage(ev: Omit<UsageEvent, 'ts'> & {
27
+ ts?: string;
28
+ }): Promise<void>;
29
+ /**
30
+ * Load pricing table (defaults overlaid with user overrides).
31
+ */
32
+ export declare function loadPricing(): Promise<PricingTable>;
33
+ /**
34
+ * Read all usage events. Tolerates malformed lines.
35
+ */
36
+ export declare function readUsage(): Promise<UsageEvent[]>;
37
+ export interface CostBreakdown {
38
+ total_usd: number;
39
+ by_kind: Record<string, {
40
+ count: number;
41
+ usd: number;
42
+ }>;
43
+ by_model: Record<string, {
44
+ count: number;
45
+ tokens_in: number;
46
+ tokens_out: number;
47
+ usd: number;
48
+ }>;
49
+ by_day: Record<string, {
50
+ count: number;
51
+ usd: number;
52
+ }>;
53
+ events_total: number;
54
+ events_window: number;
55
+ window_label: string;
56
+ }
57
+ /**
58
+ * Compute cost breakdown over a time window. `sinceDays` defaults
59
+ * to 30. Pass 0 to mean "all-time".
60
+ */
61
+ export declare function computeCosts(sinceDays?: number): Promise<CostBreakdown>;
62
+ /**
63
+ * Pretty-format a CostBreakdown for terminal output. Returns
64
+ * lines; caller does the printing.
65
+ */
66
+ export declare function formatCosts(b: CostBreakdown): string[];
67
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../src/telemetry/usage.ts"],"names":[],"mappings":"AAiCA,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,aAAa,GACb,gBAAgB,GAChB,eAAe,GACf,WAAW,GACX,WAAW,GACX,MAAM,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,EAAE,EAAY,MAAM,CAAC;IACrB,IAAI,EAAU,SAAS,CAAC;IACxB,KAAK,CAAC,EAAQ,MAAM,CAAC;IACrB,SAAS,CAAC,EAAI,MAAM,CAAC;IACrB,UAAU,CAAC,EAAG,MAAM,CAAC;IACrB,KAAK,CAAC,EAAQ,MAAM,CAAC;IACrB,KAAK,CAAC,EAAQ,MAAM,CAAC;IACrB,YAAY,CAAC,EAAC,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,KAAK,CAAC,EAAG;QACP,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,cAAc,CAAC,EAAS,MAAM,CAAC;KAChC,CAAC;CACH;AAID,eAAO,MAAM,eAAe,EAAE,YAe7B,CAAC;AAaF;;GAEG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ7F;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC,CAWzD;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAYvD;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAO,MAAM,CAAC;IACvB,OAAO,EAAS,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,QAAQ,EAAQ,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtG,MAAM,EAAU,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,YAAY,EAAI,MAAM,CAAC;IACvB,aAAa,EAAG,MAAM,CAAC;IACvB,YAAY,EAAI,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,SAAS,SAAK,GAAG,OAAO,CAAC,aAAa,CAAC,CAsDzE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,EAAE,CAiCtD"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Yujin Forge -- usage + cost telemetry.
3
+ *
4
+ * Append-only event log at ~/.yujin-forge/usage.jsonl. Every
5
+ * Claude API call (or other priced operation) records one JSONL
6
+ * line with { ts, kind, model?, tokens_in?, tokens_out?, units?,
7
+ * label?, project_root? }.
8
+ *
9
+ * The reader (`yf operate costs`) aggregates by day + by kind +
10
+ * by model and applies a pricing table to produce a cost report.
11
+ *
12
+ * Append is best-effort: telemetry failures NEVER throw to the
13
+ * caller -- a broken usage file should not break user work.
14
+ *
15
+ * Pricing is hard-coded for the 2026 model lineup. Users can
16
+ * override via ~/.yujin-forge/pricing.json:
17
+ * {
18
+ * "models": {
19
+ * "claude-opus-4-7": { "in_per_mtok": 15, "out_per_mtok": 75 },
20
+ * "claude-sonnet-4-6": { "in_per_mtok": 3, "out_per_mtok": 15 }
21
+ * },
22
+ * "voice": {
23
+ * "tts_per_million_chars": 16,
24
+ * "stt_per_minute": 0.006
25
+ * }
26
+ * }
27
+ *
28
+ * ASCII-only.
29
+ */
30
+ import { promises as fs } from 'node:fs';
31
+ import path from 'node:path';
32
+ import { configDir } from '../license/index.js';
33
+ /* Defaults reflect early-2026 Anthropic + Google Cloud pricing.
34
+ * Users can override via ~/.yujin-forge/pricing.json. */
35
+ export const DEFAULT_PRICING = {
36
+ models: {
37
+ 'claude-opus-4-7': { in_per_mtok: 15, out_per_mtok: 75 },
38
+ 'claude-opus-4': { in_per_mtok: 15, out_per_mtok: 75 },
39
+ 'claude-sonnet-4-6': { in_per_mtok: 3, out_per_mtok: 15 },
40
+ 'claude-sonnet-4': { in_per_mtok: 3, out_per_mtok: 15 },
41
+ 'claude-haiku-4-5': { in_per_mtok: 1, out_per_mtok: 5 },
42
+ /* Older lineup kept for back-compat. */
43
+ 'claude-3-5-sonnet': { in_per_mtok: 3, out_per_mtok: 15 },
44
+ 'claude-3-5-haiku': { in_per_mtok: 0.8, out_per_mtok: 4 },
45
+ },
46
+ voice: {
47
+ tts_per_million_chars: 16, /* Google Cloud TTS Neural2 */
48
+ stt_per_minute: 0.006, /* Google Cloud STT enhanced */
49
+ },
50
+ };
51
+ function usageFile() {
52
+ return path.join(configDir(), 'usage.jsonl');
53
+ }
54
+ function pricingFile() {
55
+ return path.join(configDir(), 'pricing.json');
56
+ }
57
+ async function ensureDir() {
58
+ try {
59
+ await fs.mkdir(configDir(), { recursive: true });
60
+ }
61
+ catch { /* best effort */ }
62
+ }
63
+ /**
64
+ * Append a usage event. Never throws -- failures swallowed.
65
+ */
66
+ export async function recordUsage(ev) {
67
+ try {
68
+ await ensureDir();
69
+ const line = { ts: ev.ts ?? new Date().toISOString(), ...ev };
70
+ await fs.appendFile(usageFile(), JSON.stringify(line) + '\n', 'utf-8');
71
+ }
72
+ catch {
73
+ /* swallow -- telemetry must never break user flow */
74
+ }
75
+ }
76
+ /**
77
+ * Load pricing table (defaults overlaid with user overrides).
78
+ */
79
+ export async function loadPricing() {
80
+ try {
81
+ const raw = await fs.readFile(pricingFile(), 'utf-8');
82
+ const override = JSON.parse(raw);
83
+ return {
84
+ models: { ...(DEFAULT_PRICING.models ?? {}), ...(override.models ?? {}) },
85
+ voice: { ...(DEFAULT_PRICING.voice ?? {}), ...(override.voice ?? {}) },
86
+ };
87
+ }
88
+ catch {
89
+ return DEFAULT_PRICING;
90
+ }
91
+ }
92
+ /**
93
+ * Read all usage events. Tolerates malformed lines.
94
+ */
95
+ export async function readUsage() {
96
+ try {
97
+ const raw = await fs.readFile(usageFile(), 'utf-8');
98
+ return raw.split('\n')
99
+ .filter((l) => l.trim().length > 0)
100
+ .map((l) => {
101
+ try {
102
+ return JSON.parse(l);
103
+ }
104
+ catch {
105
+ return null;
106
+ }
107
+ })
108
+ .filter((x) => x !== null);
109
+ }
110
+ catch {
111
+ return [];
112
+ }
113
+ }
114
+ /**
115
+ * Compute cost breakdown over a time window. `sinceDays` defaults
116
+ * to 30. Pass 0 to mean "all-time".
117
+ */
118
+ export async function computeCosts(sinceDays = 30) {
119
+ const events = await readUsage();
120
+ const pricing = await loadPricing();
121
+ const now = Date.now();
122
+ const cutoffMs = sinceDays > 0 ? now - sinceDays * 24 * 60 * 60 * 1000 : 0;
123
+ const inWindow = events.filter((e) => Date.parse(e.ts) >= cutoffMs);
124
+ const breakdown = {
125
+ total_usd: 0,
126
+ by_kind: {},
127
+ by_model: {},
128
+ by_day: {},
129
+ events_total: events.length,
130
+ events_window: inWindow.length,
131
+ window_label: sinceDays === 0 ? 'all-time' : 'last ' + sinceDays + ' days',
132
+ };
133
+ for (const ev of inWindow) {
134
+ let usd = 0;
135
+ if (ev.kind.startsWith('claude.')) {
136
+ const m = ev.model ?? 'unknown';
137
+ const p = pricing.models?.[m];
138
+ if (p) {
139
+ usd = ((ev.tokens_in ?? 0) / 1_000_000) * p.in_per_mtok
140
+ + ((ev.tokens_out ?? 0) / 1_000_000) * p.out_per_mtok;
141
+ }
142
+ if (!breakdown.by_model[m]) {
143
+ breakdown.by_model[m] = { count: 0, tokens_in: 0, tokens_out: 0, usd: 0 };
144
+ }
145
+ const slot = breakdown.by_model[m];
146
+ slot.count++;
147
+ slot.tokens_in += ev.tokens_in ?? 0;
148
+ slot.tokens_out += ev.tokens_out ?? 0;
149
+ slot.usd += usd;
150
+ }
151
+ else if (ev.kind === 'voice.tts') {
152
+ usd = ((ev.units ?? 0) / 1_000_000) * (pricing.voice?.tts_per_million_chars ?? 0);
153
+ }
154
+ else if (ev.kind === 'voice.stt') {
155
+ usd = (ev.units ?? 0) * (pricing.voice?.stt_per_minute ?? 0);
156
+ }
157
+ breakdown.total_usd += usd;
158
+ if (!breakdown.by_kind[ev.kind])
159
+ breakdown.by_kind[ev.kind] = { count: 0, usd: 0 };
160
+ breakdown.by_kind[ev.kind].count++;
161
+ breakdown.by_kind[ev.kind].usd += usd;
162
+ const day = ev.ts.slice(0, 10);
163
+ if (!breakdown.by_day[day])
164
+ breakdown.by_day[day] = { count: 0, usd: 0 };
165
+ breakdown.by_day[day].count++;
166
+ breakdown.by_day[day].usd += usd;
167
+ }
168
+ return breakdown;
169
+ }
170
+ /**
171
+ * Pretty-format a CostBreakdown for terminal output. Returns
172
+ * lines; caller does the printing.
173
+ */
174
+ export function formatCosts(b) {
175
+ const lines = [];
176
+ lines.push('Window: ' + b.window_label);
177
+ lines.push('Events total: ' + b.events_total);
178
+ lines.push('Events in window:' + b.events_window);
179
+ lines.push('Total USD: $' + b.total_usd.toFixed(4));
180
+ lines.push('');
181
+ lines.push('By kind:');
182
+ const kinds = Object.entries(b.by_kind).sort((a, c) => c[1].usd - a[1].usd);
183
+ for (const [k, v] of kinds) {
184
+ lines.push(' ' + k.padEnd(18) + 'count=' + String(v.count).padStart(5) + ' usd=$' + v.usd.toFixed(4));
185
+ }
186
+ if (Object.keys(b.by_model).length > 0) {
187
+ lines.push('');
188
+ lines.push('By model:');
189
+ const models = Object.entries(b.by_model).sort((a, c) => c[1].usd - a[1].usd);
190
+ for (const [m, v] of models) {
191
+ lines.push(' ' + m.padEnd(24)
192
+ + 'count=' + String(v.count).padStart(5)
193
+ + ' in=' + String(v.tokens_in).padStart(8)
194
+ + ' out=' + String(v.tokens_out).padStart(7)
195
+ + ' usd=$' + v.usd.toFixed(4));
196
+ }
197
+ }
198
+ if (Object.keys(b.by_day).length > 0) {
199
+ lines.push('');
200
+ lines.push('By day:');
201
+ const days = Object.entries(b.by_day).sort((a, c) => (a[0] < c[0] ? 1 : -1)).slice(0, 14);
202
+ for (const [d, v] of days) {
203
+ lines.push(' ' + d + ' count=' + String(v.count).padStart(5) + ' usd=$' + v.usd.toFixed(4));
204
+ }
205
+ }
206
+ return lines;
207
+ }
208
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/telemetry/usage.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -4,5 +4,5 @@
4
4
  * into the npm metadata) so we don't end up with two versions
5
5
  * drifting.
6
6
  */
7
- export declare const VERSION = "0.2.0-alpha.3";
7
+ export declare const VERSION = "0.2.0-alpha.31";
8
8
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,OAAO,kBAAkB,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,OAAO,mBAAmB,CAAC"}
package/dist/version.js CHANGED
@@ -4,5 +4,5 @@
4
4
  * into the npm metadata) so we don't end up with two versions
5
5
  * drifting.
6
6
  */
7
- export const VERSION = '0.2.0-alpha.3';
7
+ export const VERSION = '0.2.0-alpha.31';
8
8
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,gBAAgB,CAAC"}
@@ -35,7 +35,7 @@
35
35
  * the contract is the literal string the chat dispatcher
36
36
  * accepts. If a tool is renamed there, this list must follow.
37
37
  */
38
- export type ReaderToolName = 'forge.reader.open' | 'forge.reader.list_documents' | 'forge.reader.read_section' | 'forge.reader.next_block' | 'forge.reader.search' | 'forge.reader.bookmark_set' | 'forge.reader.bookmark_jump' | 'forge.reader.recap' | 'forge.manual.open';
38
+ export type ReaderToolName = 'forge_reader_open' | 'forge_reader_list_documents' | 'forge_reader_read_section' | 'forge_reader_next_block' | 'forge_reader_search' | 'forge_reader_bookmark_set' | 'forge_reader_bookmark_jump' | 'forge_reader_recap' | 'forge_manual_open';
39
39
  export interface MatchedIntent {
40
40
  tool: ReaderToolName;
41
41
  args: Record<string, unknown>;
Binary file
@@ -27,6 +27,15 @@ export interface GoogleProviderOptions {
27
27
  fetchImpl?: typeof fetch;
28
28
  vaultOpener?: () => Promise<Vault>;
29
29
  }
30
+ /** Google STT enhanced models only certify a subset of Spanish
31
+ * locale codes. Map any specifically-regional Latin-Spanish
32
+ * locale (es-AR, es-CL, es-PE, es-CO, es-VE, etc) to es-US
33
+ * (Latin American Spanish neutral). Pass through:
34
+ * es-ES (Spain), es-US (Latin neutral), es-419 (Latin
35
+ * generic) -- all supported directly by latest_long +
36
+ * useEnhanced. Bare 'es' also routes to es-US.
37
+ * Exported for tests. */
38
+ export declare function normaliseSpanishLocale(locale: string): string;
30
39
  /** Map our SttAudioFormat to Google's encoding enum. */
31
40
  declare function sttFormatToGoogleEncoding(format: SttAudioFormat): string;
32
41
  /** Map our TtsAudioFormat to Google's audio encoding enum. */
@@ -1 +1 @@
1
- {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../../src/voice/providers/google.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACf,MAAM,aAAa,CAAC;AAQrB,QAAA,MAAM,UAAU,iBAAiB,CAAC;AAElC,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;CACpC;AAED,wDAAwD;AACxD,iBAAS,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAUjE;AAED,8DAA8D;AAC9D,iBAAS,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAQjE;AAqBD,qBAAa,iBAAkB,YAAW,WAAW;IACnD,QAAQ,CAAC,EAAE,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;gBAEvC,IAAI,GAAE,qBAA0B;IAKtC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAS9B,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAwExD;AAMD,qBAAa,iBAAkB,YAAW,WAAW;IACnD,QAAQ,CAAC,EAAE,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;gBAEvC,IAAI,GAAE,qBAA0B;IAKtC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAS9B,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAiEvD;qDACiD;IACjD,OAAO,CAAC,sBAAsB;IAQ9B,qDAAqD;IACrD,OAAO,CAAC,UAAU;CAMnB;AAGD,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../../src/voice/providers/google.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACf,MAAM,aAAa,CAAC;AAuErB,QAAA,MAAM,UAAU,iBAAiB,CAAC;AAElC,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;CACpC;AAED;;;;;;;0BAO0B;AAC1B,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED,wDAAwD;AACxD,iBAAS,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAUjE;AAED,8DAA8D;AAC9D,iBAAS,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAQjE;AA4ED,qBAAa,iBAAkB,YAAW,WAAW;IACnD,QAAQ,CAAC,EAAE,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;gBAEvC,IAAI,GAAE,qBAA0B;IAKtC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAI9B,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAgGxD;AAMD,qBAAa,iBAAkB,YAAW,WAAW;IACnD,QAAQ,CAAC,EAAE,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;gBAEvC,IAAI,GAAE,qBAA0B;IAKtC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAI9B,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAoGvD;qDACiD;IACjD,OAAO,CAAC,sBAAsB;IAQ9B,qDAAqD;IACrD,OAAO,CAAC,UAAU;CAMnB;AAGD,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,UAAU,EAAE,CAAC"}