@pencil-agent/nano-pencil 2.0.0-beta.2 → 2.0.0-beta.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.
Files changed (179) hide show
  1. package/dist/build-meta.json +3 -3
  2. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-continuations.d.ts +17 -0
  3. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-continuations.js +60 -0
  4. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-stream-events.d.ts +19 -0
  5. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-stream-events.js +55 -0
  6. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-results.d.ts +10 -0
  7. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-results.js +137 -0
  8. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-summaries.d.ts +22 -0
  9. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop-tool-summaries.js +64 -0
  10. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop.d.ts +26 -0
  11. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-loop.js +913 -0
  12. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-run-result.d.ts +9 -0
  13. package/dist/node_modules/@pencil-agent/agent-core/dist/agent-run-result.js +32 -0
  14. package/dist/node_modules/@pencil-agent/agent-core/dist/agent.d.ts +215 -0
  15. package/dist/node_modules/@pencil-agent/agent-core/dist/agent.js +522 -0
  16. package/dist/node_modules/@pencil-agent/agent-core/dist/errors.d.ts +62 -0
  17. package/dist/node_modules/@pencil-agent/agent-core/dist/errors.js +146 -0
  18. package/dist/node_modules/@pencil-agent/agent-core/dist/index.d.ts +14 -0
  19. package/dist/node_modules/@pencil-agent/agent-core/dist/index.js +19 -0
  20. package/dist/node_modules/@pencil-agent/agent-core/dist/proxy.d.ts +91 -0
  21. package/dist/node_modules/@pencil-agent/agent-core/dist/proxy.js +279 -0
  22. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-agent-loop.d.ts +15 -0
  23. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-agent-loop.js +625 -0
  24. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-streaming-tool-executor.d.ts +33 -0
  25. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-streaming-tool-executor.js +189 -0
  26. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-tool-orchestration.d.ts +35 -0
  27. package/dist/node_modules/@pencil-agent/agent-core/dist/structured-adaptive-tool-orchestration.js +319 -0
  28. package/dist/node_modules/@pencil-agent/agent-core/dist/types.d.ts +417 -0
  29. package/dist/node_modules/@pencil-agent/agent-core/dist/types.js +13 -0
  30. package/dist/node_modules/@pencil-agent/agent-core/package.json +28 -0
  31. package/dist/node_modules/@pencil-agent/ai/dist/api-registry.d.ts +27 -0
  32. package/dist/node_modules/@pencil-agent/ai/dist/api-registry.js +152 -0
  33. package/dist/node_modules/@pencil-agent/ai/dist/cli.d.ts +2 -0
  34. package/dist/node_modules/@pencil-agent/ai/dist/cli.js +121 -0
  35. package/dist/node_modules/@pencil-agent/ai/dist/config-path.d.ts +1 -0
  36. package/dist/node_modules/@pencil-agent/ai/dist/config-path.js +17 -0
  37. package/dist/node_modules/@pencil-agent/ai/dist/debug-logger.d.ts +94 -0
  38. package/dist/node_modules/@pencil-agent/ai/dist/debug-logger.js +218 -0
  39. package/dist/node_modules/@pencil-agent/ai/dist/env-api-keys.d.ts +8 -0
  40. package/dist/node_modules/@pencil-agent/ai/dist/env-api-keys.js +107 -0
  41. package/dist/node_modules/@pencil-agent/ai/dist/env.d.ts +7 -0
  42. package/dist/node_modules/@pencil-agent/ai/dist/env.js +7 -0
  43. package/dist/node_modules/@pencil-agent/ai/dist/events.d.ts +8 -0
  44. package/dist/node_modules/@pencil-agent/ai/dist/events.js +7 -0
  45. package/dist/node_modules/@pencil-agent/ai/dist/index.d.ts +27 -0
  46. package/dist/node_modules/@pencil-agent/ai/dist/index.js +20 -0
  47. package/dist/node_modules/@pencil-agent/ai/dist/json.d.ts +7 -0
  48. package/dist/node_modules/@pencil-agent/ai/dist/json.js +7 -0
  49. package/dist/node_modules/@pencil-agent/ai/dist/models.d.ts +31 -0
  50. package/dist/node_modules/@pencil-agent/ai/dist/models.generated.d.ts +15159 -0
  51. package/dist/node_modules/@pencil-agent/ai/dist/models.generated.js +14928 -0
  52. package/dist/node_modules/@pencil-agent/ai/dist/models.js +60 -0
  53. package/dist/node_modules/@pencil-agent/ai/dist/overflow.d.ts +7 -0
  54. package/dist/node_modules/@pencil-agent/ai/dist/overflow.js +7 -0
  55. package/dist/node_modules/@pencil-agent/ai/dist/providers/amazon-bedrock.d.ts +20 -0
  56. package/dist/node_modules/@pencil-agent/ai/dist/providers/amazon-bedrock.js +606 -0
  57. package/dist/node_modules/@pencil-agent/ai/dist/providers/anthropic.d.ts +38 -0
  58. package/dist/node_modules/@pencil-agent/ai/dist/providers/anthropic.js +737 -0
  59. package/dist/node_modules/@pencil-agent/ai/dist/providers/azure-openai-responses.d.ts +21 -0
  60. package/dist/node_modules/@pencil-agent/ai/dist/providers/azure-openai-responses.js +193 -0
  61. package/dist/node_modules/@pencil-agent/ai/dist/providers/github-copilot-headers.d.ts +13 -0
  62. package/dist/node_modules/@pencil-agent/ai/dist/providers/github-copilot-headers.js +34 -0
  63. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-gemini-cli.d.ts +79 -0
  64. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-gemini-cli.js +753 -0
  65. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-shared.d.ts +70 -0
  66. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-shared.js +311 -0
  67. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-vertex.d.ts +20 -0
  68. package/dist/node_modules/@pencil-agent/ai/dist/providers/google-vertex.js +380 -0
  69. package/dist/node_modules/@pencil-agent/ai/dist/providers/google.d.ts +18 -0
  70. package/dist/node_modules/@pencil-agent/ai/dist/providers/google.js +360 -0
  71. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-codex-responses.d.ts +8 -0
  72. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-codex-responses.js +704 -0
  73. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-completions.d.ts +20 -0
  74. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-completions.js +870 -0
  75. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses-shared.d.ts +22 -0
  76. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses-shared.js +432 -0
  77. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses.d.ts +19 -0
  78. package/dist/node_modules/@pencil-agent/ai/dist/providers/openai-responses.js +207 -0
  79. package/dist/node_modules/@pencil-agent/ai/dist/providers/register-builtins.d.ts +8 -0
  80. package/dist/node_modules/@pencil-agent/ai/dist/providers/register-builtins.js +86 -0
  81. package/dist/node_modules/@pencil-agent/ai/dist/providers/simple-options.d.ts +13 -0
  82. package/dist/node_modules/@pencil-agent/ai/dist/providers/simple-options.js +40 -0
  83. package/dist/node_modules/@pencil-agent/ai/dist/providers/transform-messages.d.ts +13 -0
  84. package/dist/node_modules/@pencil-agent/ai/dist/providers/transform-messages.js +175 -0
  85. package/dist/node_modules/@pencil-agent/ai/dist/registry.d.ts +8 -0
  86. package/dist/node_modules/@pencil-agent/ai/dist/registry.js +8 -0
  87. package/dist/node_modules/@pencil-agent/ai/dist/schema.d.ts +10 -0
  88. package/dist/node_modules/@pencil-agent/ai/dist/schema.js +9 -0
  89. package/dist/node_modules/@pencil-agent/ai/dist/stream.d.ts +25 -0
  90. package/dist/node_modules/@pencil-agent/ai/dist/stream.js +324 -0
  91. package/dist/node_modules/@pencil-agent/ai/dist/types.d.ts +306 -0
  92. package/dist/node_modules/@pencil-agent/ai/dist/types.js +7 -0
  93. package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream-types.d.ts +12 -0
  94. package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream-types.js +7 -0
  95. package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream.d.ts +31 -0
  96. package/dist/node_modules/@pencil-agent/ai/dist/utils/event-stream.js +98 -0
  97. package/dist/node_modules/@pencil-agent/ai/dist/utils/http-proxy.d.ts +13 -0
  98. package/dist/node_modules/@pencil-agent/ai/dist/utils/http-proxy.js +20 -0
  99. package/dist/node_modules/@pencil-agent/ai/dist/utils/json-parse.d.ts +14 -0
  100. package/dist/node_modules/@pencil-agent/ai/dist/utils/json-parse.js +34 -0
  101. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/anthropic.d.ts +22 -0
  102. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/anthropic.js +109 -0
  103. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/decode-credential.d.ts +12 -0
  104. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/decode-credential.js +25 -0
  105. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/github-copilot.d.ts +35 -0
  106. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/github-copilot.js +286 -0
  107. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-antigravity.d.ts +31 -0
  108. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-antigravity.js +378 -0
  109. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-gemini-cli.d.ts +31 -0
  110. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/google-gemini-cli.js +483 -0
  111. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/index.d.ts +60 -0
  112. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/index.js +131 -0
  113. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/openai-codex.d.ts +39 -0
  114. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/openai-codex.js +385 -0
  115. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/pkce.d.ts +18 -0
  116. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/pkce.js +36 -0
  117. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/types.d.ts +52 -0
  118. package/dist/node_modules/@pencil-agent/ai/dist/utils/oauth/types.js +7 -0
  119. package/dist/node_modules/@pencil-agent/ai/dist/utils/overflow.d.ts +57 -0
  120. package/dist/node_modules/@pencil-agent/ai/dist/utils/overflow.js +120 -0
  121. package/dist/node_modules/@pencil-agent/ai/dist/utils/sanitize-unicode.d.ts +16 -0
  122. package/dist/node_modules/@pencil-agent/ai/dist/utils/sanitize-unicode.js +20 -0
  123. package/dist/node_modules/@pencil-agent/ai/dist/utils/typebox-helpers.d.ts +22 -0
  124. package/dist/node_modules/@pencil-agent/ai/dist/utils/typebox-helpers.js +26 -0
  125. package/dist/node_modules/@pencil-agent/ai/dist/utils/validation.d.ts +23 -0
  126. package/dist/node_modules/@pencil-agent/ai/dist/utils/validation.js +78 -0
  127. package/dist/node_modules/@pencil-agent/ai/package.json +94 -0
  128. package/dist/node_modules/@pencil-agent/tui/dist/autocomplete.d.ts +62 -0
  129. package/dist/node_modules/@pencil-agent/tui/dist/autocomplete.js +624 -0
  130. package/dist/node_modules/@pencil-agent/tui/dist/components/box.d.ts +27 -0
  131. package/dist/node_modules/@pencil-agent/tui/dist/components/box.js +109 -0
  132. package/dist/node_modules/@pencil-agent/tui/dist/components/cancellable-loader.d.ts +27 -0
  133. package/dist/node_modules/@pencil-agent/tui/dist/components/cancellable-loader.js +40 -0
  134. package/dist/node_modules/@pencil-agent/tui/dist/components/editor.d.ts +218 -0
  135. package/dist/node_modules/@pencil-agent/tui/dist/components/editor.js +1697 -0
  136. package/dist/node_modules/@pencil-agent/tui/dist/components/image.d.ts +33 -0
  137. package/dist/node_modules/@pencil-agent/tui/dist/components/image.js +74 -0
  138. package/dist/node_modules/@pencil-agent/tui/dist/components/input.d.ts +42 -0
  139. package/dist/node_modules/@pencil-agent/tui/dist/components/input.js +438 -0
  140. package/dist/node_modules/@pencil-agent/tui/dist/components/loader.d.ts +26 -0
  141. package/dist/node_modules/@pencil-agent/tui/dist/components/loader.js +54 -0
  142. package/dist/node_modules/@pencil-agent/tui/dist/components/markdown.d.ts +100 -0
  143. package/dist/node_modules/@pencil-agent/tui/dist/components/markdown.js +634 -0
  144. package/dist/node_modules/@pencil-agent/tui/dist/components/select-list.d.ts +37 -0
  145. package/dist/node_modules/@pencil-agent/tui/dist/components/select-list.js +157 -0
  146. package/dist/node_modules/@pencil-agent/tui/dist/components/settings-list.d.ts +55 -0
  147. package/dist/node_modules/@pencil-agent/tui/dist/components/settings-list.js +190 -0
  148. package/dist/node_modules/@pencil-agent/tui/dist/components/spacer.d.ts +17 -0
  149. package/dist/node_modules/@pencil-agent/tui/dist/components/spacer.js +28 -0
  150. package/dist/node_modules/@pencil-agent/tui/dist/components/text.d.ts +24 -0
  151. package/dist/node_modules/@pencil-agent/tui/dist/components/text.js +94 -0
  152. package/dist/node_modules/@pencil-agent/tui/dist/components/truncated-text.d.ts +18 -0
  153. package/dist/node_modules/@pencil-agent/tui/dist/components/truncated-text.js +56 -0
  154. package/dist/node_modules/@pencil-agent/tui/dist/editor-component.d.ts +51 -0
  155. package/dist/node_modules/@pencil-agent/tui/dist/editor-component.js +7 -0
  156. package/dist/node_modules/@pencil-agent/tui/dist/fuzzy.d.ts +32 -0
  157. package/dist/node_modules/@pencil-agent/tui/dist/fuzzy.js +152 -0
  158. package/dist/node_modules/@pencil-agent/tui/dist/index.d.ts +28 -0
  159. package/dist/node_modules/@pencil-agent/tui/dist/index.js +37 -0
  160. package/dist/node_modules/@pencil-agent/tui/dist/keybindings.d.ts +44 -0
  161. package/dist/node_modules/@pencil-agent/tui/dist/keybindings.js +119 -0
  162. package/dist/node_modules/@pencil-agent/tui/dist/keys.d.ts +149 -0
  163. package/dist/node_modules/@pencil-agent/tui/dist/keys.js +948 -0
  164. package/dist/node_modules/@pencil-agent/tui/dist/kill-ring.d.ts +33 -0
  165. package/dist/node_modules/@pencil-agent/tui/dist/kill-ring.js +49 -0
  166. package/dist/node_modules/@pencil-agent/tui/dist/stdin-buffer.d.ts +38 -0
  167. package/dist/node_modules/@pencil-agent/tui/dist/stdin-buffer.js +307 -0
  168. package/dist/node_modules/@pencil-agent/tui/dist/terminal-image.d.ts +73 -0
  169. package/dist/node_modules/@pencil-agent/tui/dist/terminal-image.js +287 -0
  170. package/dist/node_modules/@pencil-agent/tui/dist/terminal.d.ts +86 -0
  171. package/dist/node_modules/@pencil-agent/tui/dist/terminal.js +266 -0
  172. package/dist/node_modules/@pencil-agent/tui/dist/tui.d.ts +219 -0
  173. package/dist/node_modules/@pencil-agent/tui/dist/tui.js +1001 -0
  174. package/dist/node_modules/@pencil-agent/tui/dist/undo-stack.d.ts +22 -0
  175. package/dist/node_modules/@pencil-agent/tui/dist/undo-stack.js +30 -0
  176. package/dist/node_modules/@pencil-agent/tui/dist/utils.d.ts +83 -0
  177. package/dist/node_modules/@pencil-agent/tui/dist/utils.js +811 -0
  178. package/dist/node_modules/@pencil-agent/tui/package.json +37 -0
  179. package/package.json +3 -2
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * [WHO]: OAuth CLI tool for managing AI provider credentials
4
+ * [FROM]: Depends on node:fs, readline, oauth utils
5
+ * [TO]: Consumed by core/lib/ai/src/index.ts
6
+ * [HERE]: core/lib/ai/src/cli.ts - AI package CLI
7
+ */
8
+ import { existsSync, readFileSync, writeFileSync } from "fs";
9
+ import { createInterface } from "readline";
10
+ import { getOAuthProvider, getOAuthProviders } from "./utils/oauth/index.js";
11
+ const AUTH_FILE = "auth.json";
12
+ const PROVIDERS = getOAuthProviders();
13
+ function prompt(rl, question) {
14
+ return new Promise((resolve) => rl.question(question, resolve));
15
+ }
16
+ function loadAuth() {
17
+ if (!existsSync(AUTH_FILE))
18
+ return {};
19
+ try {
20
+ return JSON.parse(readFileSync(AUTH_FILE, "utf-8"));
21
+ }
22
+ catch {
23
+ return {};
24
+ }
25
+ }
26
+ function saveAuth(auth) {
27
+ writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), "utf-8");
28
+ }
29
+ async function login(providerId) {
30
+ const provider = getOAuthProvider(providerId);
31
+ if (!provider) {
32
+ console.error(`Unknown provider: ${providerId}`);
33
+ process.exit(1);
34
+ }
35
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
36
+ const promptFn = (msg) => prompt(rl, `${msg} `);
37
+ try {
38
+ const credentials = await provider.login({
39
+ onAuth: (info) => {
40
+ console.log(`\nOpen this URL in your browser:\n${info.url}`);
41
+ if (info.instructions)
42
+ console.log(info.instructions);
43
+ console.log();
44
+ },
45
+ onPrompt: async (p) => {
46
+ return await promptFn(`${p.message}${p.placeholder ? ` (${p.placeholder})` : ""}:`);
47
+ },
48
+ onProgress: (msg) => console.log(msg),
49
+ });
50
+ const auth = loadAuth();
51
+ auth[providerId] = { type: "oauth", ...credentials };
52
+ saveAuth(auth);
53
+ console.log(`\nCredentials saved to ${AUTH_FILE}`);
54
+ }
55
+ finally {
56
+ rl.close();
57
+ }
58
+ }
59
+ async function main() {
60
+ const args = process.argv.slice(2);
61
+ const command = args[0];
62
+ if (!command || command === "help" || command === "--help" || command === "-h") {
63
+ const providerList = PROVIDERS.map((p) => ` ${p.id.padEnd(20)} ${p.name}`).join("\n");
64
+ console.log(`Usage: npx @pencil-agent/ai <command> [provider]
65
+
66
+ Commands:
67
+ login [provider] Login to an OAuth provider
68
+ list List available providers
69
+
70
+ Providers:
71
+ ${providerList}
72
+
73
+ Examples:
74
+ npx @pencil-agent/ai login # interactive provider selection
75
+ npx @pencil-agent/ai login anthropic # login to specific provider
76
+ npx @pencil-agent/ai list # list providers
77
+ `);
78
+ return;
79
+ }
80
+ if (command === "list") {
81
+ console.log("Available OAuth providers:\n");
82
+ for (const p of PROVIDERS) {
83
+ console.log(` ${p.id.padEnd(20)} ${p.name}`);
84
+ }
85
+ return;
86
+ }
87
+ if (command === "login") {
88
+ let provider = args[1];
89
+ if (!provider) {
90
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
91
+ console.log("Select a provider:\n");
92
+ for (let i = 0; i < PROVIDERS.length; i++) {
93
+ console.log(` ${i + 1}. ${PROVIDERS[i].name}`);
94
+ }
95
+ console.log();
96
+ const choice = await prompt(rl, `Enter number (1-${PROVIDERS.length}): `);
97
+ rl.close();
98
+ const index = parseInt(choice, 10) - 1;
99
+ if (index < 0 || index >= PROVIDERS.length) {
100
+ console.error("Invalid selection");
101
+ process.exit(1);
102
+ }
103
+ provider = PROVIDERS[index].id;
104
+ }
105
+ if (!PROVIDERS.some((p) => p.id === provider)) {
106
+ console.error(`Unknown provider: ${provider}`);
107
+ console.error(`Use 'npx @pencil-agent/ai list' to see available providers`);
108
+ process.exit(1);
109
+ }
110
+ console.log(`Logging in to ${provider}...`);
111
+ await login(provider);
112
+ return;
113
+ }
114
+ console.error(`Unknown command: ${command}`);
115
+ console.error(`Use 'npx @pencil-agent/ai --help' for usage`);
116
+ process.exit(1);
117
+ }
118
+ main().catch((err) => {
119
+ console.error("Error:", err.message);
120
+ process.exit(1);
121
+ });
@@ -0,0 +1 @@
1
+ export declare function getDebugLogPath(): string;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * [WHO]: getDebugLogPath function - returns path to debug log file
3
+ * [FROM]: Depends on node:os, node:path
4
+ * [TO]: Consumed by ./debug-logger.ts, ai package internals
5
+ * [HERE]: core/lib/ai/src/config-path.ts - debug log path utility
6
+ */
7
+ import { homedir } from "os";
8
+ import { join } from "path";
9
+ export function getDebugLogPath() {
10
+ // Check for environment variable override
11
+ const envDir = process.env.NANOPENCIL_CODING_AGENT_DIR;
12
+ if (envDir) {
13
+ const dir = envDir === "~" ? homedir() : envDir.startsWith("~/") ? homedir() + envDir.slice(1) : envDir;
14
+ return join(dir, "nanopencil-debug.log");
15
+ }
16
+ return join(homedir(), ".nanopencil", "agent", "nanopencil-debug.log");
17
+ }
@@ -0,0 +1,94 @@
1
+ export type DebugLogLevel = "error" | "warn" | "info" | "debug" | "trace";
2
+ interface DebugLoggerOptions {
3
+ enabled?: boolean;
4
+ level?: DebugLogLevel;
5
+ maxFileSize?: number;
6
+ }
7
+ declare class DebugLogger {
8
+ private enabled;
9
+ private level;
10
+ private maxFileSize;
11
+ private logPath;
12
+ constructor(options?: DebugLoggerOptions);
13
+ /**
14
+ * Detect if debug logging is enabled from environment
15
+ */
16
+ private detectEnabled;
17
+ /**
18
+ * Detect log level from environment
19
+ */
20
+ private detectLevel;
21
+ /**
22
+ * Enable or disable logging at runtime
23
+ */
24
+ setEnabled(enabled: boolean): void;
25
+ /**
26
+ * Set log level at runtime
27
+ */
28
+ setLevel(level: DebugLogLevel): void;
29
+ /**
30
+ * Re-check environment variables (for when they change after initialization)
31
+ */
32
+ refreshFromEnv(): void;
33
+ /**
34
+ * Check if a specific level is enabled
35
+ */
36
+ private isLevelEnabled;
37
+ /**
38
+ * Write a log entry to file
39
+ */
40
+ private writeLog;
41
+ /**
42
+ * Rotate log file if it exceeds max size
43
+ */
44
+ private rotateIfNeeded;
45
+ error(category: string, message: string, data?: unknown): void;
46
+ warn(category: string, message: string, data?: unknown): void;
47
+ info(category: string, message: string, data?: unknown): void;
48
+ debug(category: string, message: string, data?: unknown): void;
49
+ trace(category: string, message: string, data?: unknown): void;
50
+ /**
51
+ * Log AI provider request
52
+ */
53
+ logProviderRequest(provider: string, model: string, request: unknown): void;
54
+ /**
55
+ * Log AI provider response chunk (for streaming)
56
+ */
57
+ logProviderChunk(provider: string, model: string, chunk: unknown): void;
58
+ /**
59
+ * Log AI provider response (non-streaming)
60
+ */
61
+ logProviderResponse(provider: string, model: string, response: unknown): void;
62
+ /**
63
+ * Log content parsing events
64
+ */
65
+ logContentParse(operation: string, input: unknown, output?: unknown): void;
66
+ /**
67
+ * Log TUI rendering events
68
+ */
69
+ logTUI(operation: string, details?: unknown): void;
70
+ /**
71
+ * Get the log file path
72
+ */
73
+ getLogPath(): string;
74
+ /**
75
+ * Clear the log file
76
+ */
77
+ clear(): void;
78
+ }
79
+ export declare function getDebugLogger(): DebugLogger;
80
+ export declare function createDebugLogger(options: DebugLoggerOptions): DebugLogger;
81
+ export declare const debug: {
82
+ error: (category: string, message: string, data?: unknown) => void;
83
+ warn: (category: string, message: string, data?: unknown) => void;
84
+ info: (category: string, message: string, data?: unknown) => void;
85
+ debug: (category: string, message: string, data?: unknown) => void;
86
+ trace: (category: string, message: string, data?: unknown) => void;
87
+ logProviderRequest: (provider: string, model: string, request: unknown) => void;
88
+ logProviderChunk: (provider: string, model: string, chunk: unknown) => void;
89
+ logProviderResponse: (provider: string, model: string, response: unknown) => void;
90
+ logContentParse: (operation: string, input: unknown, output?: unknown) => void;
91
+ getLogPath: () => string;
92
+ clear: () => void;
93
+ };
94
+ export {};
@@ -0,0 +1,218 @@
1
+ /**
2
+ * [WHO]: DebugLogger class, debug logging system for AI provider troubleshooting
3
+ * [FROM]: Depends on node:fs, node:path, ./config-path
4
+ * [TO]: Consumed by ai package providers for logging
5
+ * [HERE]: core/lib/ai/src/debug-logger.ts - debug logging for nanopencil AI providers
6
+ */
7
+ import { appendFileSync, existsSync, mkdirSync } from "fs";
8
+ import { dirname } from "path";
9
+ import { getDebugLogPath } from "./config-path.js";
10
+ const LOG_LEVELS = {
11
+ error: 0,
12
+ warn: 1,
13
+ info: 2,
14
+ debug: 3,
15
+ trace: 4,
16
+ };
17
+ class DebugLogger {
18
+ enabled;
19
+ level;
20
+ maxFileSize;
21
+ logPath;
22
+ constructor(options = {}) {
23
+ this.enabled = options.enabled ?? this.detectEnabled();
24
+ this.level = LOG_LEVELS[options.level ?? this.detectLevel()];
25
+ this.maxFileSize = options.maxFileSize ?? 10 * 1024 * 1024; // 10MB
26
+ this.logPath = getDebugLogPath();
27
+ }
28
+ /**
29
+ * Detect if debug logging is enabled from environment
30
+ */
31
+ detectEnabled() {
32
+ return (process.env.NANOPENCIL_DEBUG === "1" ||
33
+ process.env.DEBUG?.includes("nanopencil") ||
34
+ false);
35
+ }
36
+ /**
37
+ * Detect log level from environment
38
+ */
39
+ detectLevel() {
40
+ const level = process.env.NANOPENCIL_DEBUG_LEVEL;
41
+ if (level && level in LOG_LEVELS) {
42
+ return level;
43
+ }
44
+ return "info";
45
+ }
46
+ /**
47
+ * Enable or disable logging at runtime
48
+ */
49
+ setEnabled(enabled) {
50
+ this.enabled = enabled;
51
+ }
52
+ /**
53
+ * Set log level at runtime
54
+ */
55
+ setLevel(level) {
56
+ this.level = LOG_LEVELS[level];
57
+ }
58
+ /**
59
+ * Re-check environment variables (for when they change after initialization)
60
+ */
61
+ refreshFromEnv() {
62
+ this.enabled = this.detectEnabled();
63
+ this.level = LOG_LEVELS[this.detectLevel()];
64
+ }
65
+ /**
66
+ * Check if a specific level is enabled
67
+ */
68
+ isLevelEnabled(level) {
69
+ // Re-check environment on each log call to handle late-set env vars
70
+ if (!this.enabled && process.env.NANOPENCIL_DEBUG === "1") {
71
+ this.refreshFromEnv();
72
+ }
73
+ return this.enabled && LOG_LEVELS[level] <= this.level;
74
+ }
75
+ /**
76
+ * Write a log entry to file
77
+ */
78
+ writeLog(level, category, message, data) {
79
+ if (!this.isLevelEnabled(level))
80
+ return;
81
+ const timestamp = new Date().toISOString();
82
+ const levelStr = level.toUpperCase().padStart(5);
83
+ let logLine = `[${timestamp}] [${levelStr}] [${category}] ${message}`;
84
+ if (data !== undefined) {
85
+ try {
86
+ const dataStr = typeof data === "string" ? data : JSON.stringify(data, null, 2);
87
+ logLine += `\n${dataStr}`;
88
+ }
89
+ catch {
90
+ logLine += `\n[Unable to serialize data]`;
91
+ }
92
+ }
93
+ logLine += "\n";
94
+ try {
95
+ // Ensure directory exists
96
+ const dir = dirname(this.logPath);
97
+ if (!existsSync(dir)) {
98
+ mkdirSync(dir, { recursive: true });
99
+ }
100
+ // Check file size and rotate if needed
101
+ this.rotateIfNeeded();
102
+ appendFileSync(this.logPath, logLine);
103
+ }
104
+ catch {
105
+ // Silently fail - debug logging should never break the app
106
+ }
107
+ }
108
+ /**
109
+ * Rotate log file if it exceeds max size
110
+ */
111
+ rotateIfNeeded() {
112
+ try {
113
+ const { statSync, renameSync, existsSync } = require("fs");
114
+ if (existsSync(this.logPath)) {
115
+ const stats = statSync(this.logPath);
116
+ if (stats.size > this.maxFileSize) {
117
+ const backupPath = `${this.logPath}.old`;
118
+ if (existsSync(backupPath)) {
119
+ require("fs").unlinkSync(backupPath);
120
+ }
121
+ renameSync(this.logPath, backupPath);
122
+ }
123
+ }
124
+ }
125
+ catch {
126
+ // Ignore rotation errors
127
+ }
128
+ }
129
+ // Public logging methods
130
+ error(category, message, data) {
131
+ this.writeLog("error", category, message, data);
132
+ }
133
+ warn(category, message, data) {
134
+ this.writeLog("warn", category, message, data);
135
+ }
136
+ info(category, message, data) {
137
+ this.writeLog("info", category, message, data);
138
+ }
139
+ debug(category, message, data) {
140
+ this.writeLog("debug", category, message, data);
141
+ }
142
+ trace(category, message, data) {
143
+ this.writeLog("trace", category, message, data);
144
+ }
145
+ /**
146
+ * Log AI provider request
147
+ */
148
+ logProviderRequest(provider, model, request) {
149
+ this.debug("AI", `Request to ${provider}/${model}`, request);
150
+ }
151
+ /**
152
+ * Log AI provider response chunk (for streaming)
153
+ */
154
+ logProviderChunk(provider, model, chunk) {
155
+ this.trace("AI", `Chunk from ${provider}/${model}`, chunk);
156
+ }
157
+ /**
158
+ * Log AI provider response (non-streaming)
159
+ */
160
+ logProviderResponse(provider, model, response) {
161
+ this.debug("AI", `Response from ${provider}/${model}`, response);
162
+ }
163
+ /**
164
+ * Log content parsing events
165
+ */
166
+ logContentParse(operation, input, output) {
167
+ this.trace("PARSE", operation, { input, output });
168
+ }
169
+ /**
170
+ * Log TUI rendering events
171
+ */
172
+ logTUI(operation, details) {
173
+ this.trace("TUI", operation, details);
174
+ }
175
+ /**
176
+ * Get the log file path
177
+ */
178
+ getLogPath() {
179
+ return this.logPath;
180
+ }
181
+ /**
182
+ * Clear the log file
183
+ */
184
+ clear() {
185
+ try {
186
+ const { writeFileSync } = require("fs");
187
+ writeFileSync(this.logPath, "");
188
+ }
189
+ catch {
190
+ // Ignore clear errors
191
+ }
192
+ }
193
+ }
194
+ // Singleton instance
195
+ let globalLogger = null;
196
+ export function getDebugLogger() {
197
+ if (!globalLogger) {
198
+ globalLogger = new DebugLogger();
199
+ }
200
+ return globalLogger;
201
+ }
202
+ export function createDebugLogger(options) {
203
+ return new DebugLogger(options);
204
+ }
205
+ // Export singleton methods for convenience
206
+ export const debug = {
207
+ error: (category, message, data) => getDebugLogger().error(category, message, data),
208
+ warn: (category, message, data) => getDebugLogger().warn(category, message, data),
209
+ info: (category, message, data) => getDebugLogger().info(category, message, data),
210
+ debug: (category, message, data) => getDebugLogger().debug(category, message, data),
211
+ trace: (category, message, data) => getDebugLogger().trace(category, message, data),
212
+ logProviderRequest: (provider, model, request) => getDebugLogger().logProviderRequest(provider, model, request),
213
+ logProviderChunk: (provider, model, chunk) => getDebugLogger().logProviderChunk(provider, model, chunk),
214
+ logProviderResponse: (provider, model, response) => getDebugLogger().logProviderResponse(provider, model, response),
215
+ logContentParse: (operation, input, output) => getDebugLogger().logContentParse(operation, input, output),
216
+ getLogPath: () => getDebugLogger().getLogPath(),
217
+ clear: () => getDebugLogger().clear(),
218
+ };
@@ -0,0 +1,8 @@
1
+ import type { KnownProvider } from "./types.js";
2
+ /**
3
+ * Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.
4
+ *
5
+ * Will not return API keys for providers that require OAuth tokens.
6
+ */
7
+ export declare function getEnvApiKey(provider: KnownProvider): string | undefined;
8
+ export declare function getEnvApiKey(provider: string): string | undefined;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * [WHO]: Environment-based API key utilities
3
+ * [FROM]: Depends on node:fs, node:os, node:path (lazy loaded)
4
+ * [TO]: Consumed by core/lib/ai/src/index.ts
5
+ * [HERE]: core/lib/ai/src/env-api-keys.ts - environment variable key access
6
+ */
7
+ // NEVER convert to top-level imports - breaks browser/Vite builds (web-ui)
8
+ let _existsSync = null;
9
+ let _homedir = null;
10
+ let _join = null;
11
+ // Eagerly load in Node.js/Bun environment only
12
+ if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
13
+ import("node:fs").then((m) => {
14
+ _existsSync = m.existsSync;
15
+ });
16
+ import("node:os").then((m) => {
17
+ _homedir = m.homedir;
18
+ });
19
+ import("node:path").then((m) => {
20
+ _join = m.join;
21
+ });
22
+ }
23
+ let cachedVertexAdcCredentialsExists = null;
24
+ function hasVertexAdcCredentials() {
25
+ if (cachedVertexAdcCredentialsExists === null) {
26
+ // If node modules haven't loaded yet (async import race at startup),
27
+ // return false WITHOUT caching so the next call retries once they're ready.
28
+ // Only cache false permanently in a browser environment where fs is never available.
29
+ if (!_existsSync || !_homedir || !_join) {
30
+ const isNode = typeof process !== "undefined" && (process.versions?.node || process.versions?.bun);
31
+ if (!isNode) {
32
+ // Definitively in a browser — safe to cache false permanently
33
+ cachedVertexAdcCredentialsExists = false;
34
+ }
35
+ return false;
36
+ }
37
+ // Check GOOGLE_APPLICATION_CREDENTIALS env var first (standard way)
38
+ const gacPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
39
+ if (gacPath) {
40
+ cachedVertexAdcCredentialsExists = _existsSync(gacPath);
41
+ }
42
+ else {
43
+ // Fall back to default ADC path (lazy evaluation)
44
+ cachedVertexAdcCredentialsExists = _existsSync(_join(_homedir(), ".config", "gcloud", "application_default_credentials.json"));
45
+ }
46
+ }
47
+ return cachedVertexAdcCredentialsExists;
48
+ }
49
+ export function getEnvApiKey(provider) {
50
+ // Fall back to environment variables
51
+ if (provider === "github-copilot") {
52
+ return process.env.COPILOT_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
53
+ }
54
+ // ANTHROPIC_OAUTH_TOKEN takes precedence over ANTHROPIC_API_KEY
55
+ if (provider === "anthropic") {
56
+ return process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY;
57
+ }
58
+ // Vertex AI uses Application Default Credentials, not API keys.
59
+ // Auth is configured via `gcloud auth application-default login`.
60
+ if (provider === "google-vertex") {
61
+ const hasCredentials = hasVertexAdcCredentials();
62
+ const hasProject = !!(process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT);
63
+ const hasLocation = !!process.env.GOOGLE_CLOUD_LOCATION;
64
+ if (hasCredentials && hasProject && hasLocation) {
65
+ return "<authenticated>";
66
+ }
67
+ }
68
+ if (provider === "amazon-bedrock") {
69
+ // Amazon Bedrock supports multiple credential sources:
70
+ // 1. AWS_PROFILE - named profile from ~/.aws/credentials
71
+ // 2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY - standard IAM keys
72
+ // 3. AWS_BEARER_TOKEN_BEDROCK - Bedrock API keys (bearer token)
73
+ // 4. AWS_CONTAINER_CREDENTIALS_RELATIVE_URI - ECS task roles
74
+ // 5. AWS_CONTAINER_CREDENTIALS_FULL_URI - ECS task roles (full URI)
75
+ // 6. AWS_WEB_IDENTITY_TOKEN_FILE - IRSA (IAM Roles for Service Accounts)
76
+ if (process.env.AWS_PROFILE ||
77
+ (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||
78
+ process.env.AWS_BEARER_TOKEN_BEDROCK ||
79
+ process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ||
80
+ process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI ||
81
+ process.env.AWS_WEB_IDENTITY_TOKEN_FILE) {
82
+ return "<authenticated>";
83
+ }
84
+ }
85
+ const envMap = {
86
+ openai: "OPENAI_API_KEY",
87
+ "azure-openai-responses": "AZURE_OPENAI_API_KEY",
88
+ google: "GEMINI_API_KEY",
89
+ groq: "GROQ_API_KEY",
90
+ cerebras: "CEREBRAS_API_KEY",
91
+ xai: "XAI_API_KEY",
92
+ openrouter: "OPENROUTER_API_KEY",
93
+ "vercel-ai-gateway": "AI_GATEWAY_API_KEY",
94
+ zai: "ZAI_API_KEY",
95
+ mistral: "MISTRAL_API_KEY",
96
+ minimax: "MINIMAX_API_KEY",
97
+ "minimax-cn": "MINIMAX_CN_API_KEY",
98
+ huggingface: "HF_TOKEN",
99
+ opencode: "OPENCODE_API_KEY",
100
+ "opencode-go": "OPENCODE_API_KEY",
101
+ "kimi-coding": "KIMI_API_KEY",
102
+ "ali-token-plan-openai": "ALI_TOKEN_PLAN_API_KEY",
103
+ "ali-token-plan-anthropic": "ALI_TOKEN_PLAN_API_KEY",
104
+ };
105
+ const envVar = envMap[provider];
106
+ return envVar ? process.env[envVar] : undefined;
107
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * [WHO]: getEnvApiKey
3
+ * [FROM]: Depends on env-api-keys for environment/provider API key lookup
4
+ * [TO]: Consumed by @pencil-agent/ai/env subpath consumers
5
+ * [HERE]: core/lib/ai/src/env.ts - additive env helper subpath entry for AI package
6
+ */
7
+ export { getEnvApiKey } from "./env-api-keys.js";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * [WHO]: getEnvApiKey
3
+ * [FROM]: Depends on env-api-keys for environment/provider API key lookup
4
+ * [TO]: Consumed by @pencil-agent/ai/env subpath consumers
5
+ * [HERE]: core/lib/ai/src/env.ts - additive env helper subpath entry for AI package
6
+ */
7
+ export { getEnvApiKey } from "./env-api-keys.js";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * [WHO]: EventStream, AssistantMessageEventStream, createAssistantMessageEventStream, AsyncEventStream
3
+ * [FROM]: Depends on AI event stream implementation and structural event stream types
4
+ * [TO]: Consumed by @pencil-agent/ai/events subpath consumers
5
+ * [HERE]: core/lib/ai/src/events.ts - additive events subpath entry for AI package
6
+ */
7
+ export * from "./utils/event-stream.js";
8
+ export type * from "./utils/event-stream-types.js";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * [WHO]: EventStream, AssistantMessageEventStream, createAssistantMessageEventStream, AsyncEventStream
3
+ * [FROM]: Depends on AI event stream implementation and structural event stream types
4
+ * [TO]: Consumed by @pencil-agent/ai/events subpath consumers
5
+ * [HERE]: core/lib/ai/src/events.ts - additive events subpath entry for AI package
6
+ */
7
+ export * from "./utils/event-stream.js";
@@ -0,0 +1,27 @@
1
+ /**
2
+ * [WHO]: AI package barrel exports
3
+ * [FROM]: Depends on typebox, all providers
4
+ * [TO]: Consumed by core/lib/ai/src/index.ts
5
+ * [HERE]: core/lib/ai/src/index.ts - AI package entry point
6
+ */
7
+ export type { Static, TSchema } from "@sinclair/typebox";
8
+ export { Type } from "@sinclair/typebox";
9
+ export * from "./api-registry.js";
10
+ export * from "./env-api-keys.js";
11
+ export * from "./models.js";
12
+ export * from "./providers/anthropic.js";
13
+ export * from "./providers/azure-openai-responses.js";
14
+ export * from "./providers/google.js";
15
+ export * from "./providers/google-gemini-cli.js";
16
+ export * from "./providers/google-vertex.js";
17
+ export * from "./providers/openai-completions.js";
18
+ export * from "./providers/openai-responses.js";
19
+ export * from "./providers/register-builtins.js";
20
+ export * from "./stream.js";
21
+ export * from "./types.js";
22
+ export * from "./utils/event-stream.js";
23
+ export * from "./utils/json-parse.js";
24
+ export * from "./utils/oauth/index.js";
25
+ export * from "./utils/overflow.js";
26
+ export * from "./utils/typebox-helpers.js";
27
+ export * from "./utils/validation.js";
@@ -0,0 +1,20 @@
1
+ export { Type } from "@sinclair/typebox";
2
+ export * from "./api-registry.js";
3
+ export * from "./env-api-keys.js";
4
+ export * from "./models.js";
5
+ export * from "./providers/anthropic.js";
6
+ export * from "./providers/azure-openai-responses.js";
7
+ export * from "./providers/google.js";
8
+ export * from "./providers/google-gemini-cli.js";
9
+ export * from "./providers/google-vertex.js";
10
+ export * from "./providers/openai-completions.js";
11
+ export * from "./providers/openai-responses.js";
12
+ export * from "./providers/register-builtins.js";
13
+ export * from "./stream.js";
14
+ export * from "./types.js";
15
+ export * from "./utils/event-stream.js";
16
+ export * from "./utils/json-parse.js";
17
+ export * from "./utils/oauth/index.js";
18
+ export * from "./utils/overflow.js";
19
+ export * from "./utils/typebox-helpers.js";
20
+ export * from "./utils/validation.js";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * [WHO]: parseStreamingJson
3
+ * [FROM]: Depends on streaming JSON parser utility
4
+ * [TO]: Consumed by @pencil-agent/ai/json subpath consumers
5
+ * [HERE]: core/lib/ai/src/json.ts - additive JSON helper subpath entry for AI package
6
+ */
7
+ export * from "./utils/json-parse.js";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * [WHO]: parseStreamingJson
3
+ * [FROM]: Depends on streaming JSON parser utility
4
+ * [TO]: Consumed by @pencil-agent/ai/json subpath consumers
5
+ * [HERE]: core/lib/ai/src/json.ts - additive JSON helper subpath entry for AI package
6
+ */
7
+ export * from "./utils/json-parse.js";