thinkwell 0.5.4 → 0.5.6

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 (44) hide show
  1. package/dist/agent.d.ts.map +1 -1
  2. package/dist/agent.js +207 -279
  3. package/dist/agent.js.map +1 -1
  4. package/dist/build.js +44 -98
  5. package/dist/cli/build.js +92 -227
  6. package/dist/cli/bundle.js +570 -1136
  7. package/dist/cli/check.js +125 -214
  8. package/dist/cli/commands.js +63 -177
  9. package/dist/cli/compiler-host.js +81 -190
  10. package/dist/cli/dependency-check.js +125 -269
  11. package/dist/cli/dependency-errors.js +12 -84
  12. package/dist/cli/fmt.js +1 -13
  13. package/dist/cli/init-command.js +21 -68
  14. package/dist/cli/init.js +90 -220
  15. package/dist/cli/loader.js +95 -361
  16. package/dist/cli/new-command.js +25 -73
  17. package/dist/cli/package-manager.js +50 -117
  18. package/dist/cli/schema.js +89 -245
  19. package/dist/cli/workspace.js +92 -226
  20. package/dist/connectors/index.js +1 -7
  21. package/dist/generated/features.d.ts +5 -0
  22. package/dist/generated/features.d.ts.map +1 -0
  23. package/dist/generated/features.js +4 -0
  24. package/dist/generated/features.js.map +1 -0
  25. package/dist/index.js +0 -5
  26. package/dist/schema.js +3 -36
  27. package/dist/session.js +50 -82
  28. package/dist/think-builder.d.ts.map +1 -1
  29. package/dist/think-builder.js +269 -370
  30. package/dist/think-builder.js.map +1 -1
  31. package/dist/thought-event.d.ts +1 -0
  32. package/dist/thought-event.d.ts.map +1 -1
  33. package/dist/thought-event.js +0 -1
  34. package/dist/thought-stream.js +60 -96
  35. package/dist-pkg/acp.cjs +13385 -1876
  36. package/dist-pkg/cli-build.cjs +171 -369
  37. package/dist-pkg/cli-bundle.cjs +289 -690
  38. package/dist-pkg/cli-check.cjs +202 -415
  39. package/dist-pkg/cli-dependency-check.cjs +39 -82
  40. package/dist-pkg/cli-dependency-errors.cjs +9 -41
  41. package/dist-pkg/cli-loader.cjs +90 -173
  42. package/dist-pkg/protocol.cjs +2 -8
  43. package/dist-pkg/thinkwell.cjs +876 -1842
  44. package/package.json +7 -6
@@ -1,9 +1,3 @@
1
- /**
2
- * CLI command for initializing a new thinkwell project.
3
- *
4
- * This command scaffolds a new project with the necessary configuration
5
- * and example files. It does not require Bun to run.
6
- */
7
1
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
8
2
  import { basename, join, resolve } from "node:path";
9
3
  import { cyan, cyanBold, greenBold, whiteBold, dim } from "./fmt.js";
@@ -19,8 +13,7 @@ const PACKAGE_JSON_TEMPLATE = (name) => `{
19
13
  "thinkwell": "^0.2.0"
20
14
  }
21
15
  }
22
- `;
23
- const MAIN_TS_TEMPLATE = `import { open } from "thinkwell";
16
+ `, MAIN_TS_TEMPLATE = `import { open } from "thinkwell";
24
17
 
25
18
  /**
26
19
  * A greeting response from the agent.
@@ -43,8 +36,7 @@ async function main() {
43
36
  }
44
37
 
45
38
  main().catch(console.error);
46
- `;
47
- const TSCONFIG_TEMPLATE = `{
39
+ `, TSCONFIG_TEMPLATE = `{
48
40
  "compilerOptions": {
49
41
  "target": "ES2022",
50
42
  "module": "NodeNext",
@@ -57,30 +49,20 @@ const TSCONFIG_TEMPLATE = `{
57
49
  },
58
50
  "include": ["src/**/*"]
59
51
  }
60
- `;
61
- const GITIGNORE_TEMPLATE = `node_modules/
52
+ `, GITIGNORE_TEMPLATE = `node_modules/
62
53
  dist/
63
54
  *.thinkwell.d.ts
64
55
  .env
65
- `;
66
- const ENV_EXAMPLE_TEMPLATE = `# Configure your agent command
56
+ `, ENV_EXAMPLE_TEMPLATE = `# Configure your agent command
67
57
  # Example for Claude Code:
68
58
  # THINKWELL_AGENT_CMD=claude --dangerously-skip-permissions
69
59
  `;
70
60
  function createProject(options) {
71
- const { name, targetDir } = options;
72
- // Create directories
73
- mkdirSync(targetDir, { recursive: true });
74
- mkdirSync(join(targetDir, "src"), { recursive: true });
75
- // Write files
76
- writeFileSync(join(targetDir, "package.json"), PACKAGE_JSON_TEMPLATE(name));
77
- writeFileSync(join(targetDir, "src/main.ts"), MAIN_TS_TEMPLATE);
78
- writeFileSync(join(targetDir, "tsconfig.json"), TSCONFIG_TEMPLATE);
79
- writeFileSync(join(targetDir, ".gitignore"), GITIGNORE_TEMPLATE);
80
- writeFileSync(join(targetDir, ".env.example"), ENV_EXAMPLE_TEMPLATE);
61
+ const { name, targetDir } = options;
62
+ mkdirSync(targetDir, { recursive: !0 }), mkdirSync(join(targetDir, "src"), { recursive: !0 }), writeFileSync(join(targetDir, "package.json"), PACKAGE_JSON_TEMPLATE(name)), writeFileSync(join(targetDir, "src/main.ts"), MAIN_TS_TEMPLATE), writeFileSync(join(targetDir, "tsconfig.json"), TSCONFIG_TEMPLATE), writeFileSync(join(targetDir, ".gitignore"), GITIGNORE_TEMPLATE), writeFileSync(join(targetDir, ".env.example"), ENV_EXAMPLE_TEMPLATE);
81
63
  }
82
64
  function showHelp() {
83
- console.log(`
65
+ console.log(`
84
66
  ${cyanBold("thinkwell init")} - ${whiteBold("Initialize a new thinkwell project")}
85
67
 
86
68
  ${greenBold("Usage:")}
@@ -102,48 +84,19 @@ ${greenBold("This command creates:")}
102
84
  `);
103
85
  }
104
86
  export async function runInit(args) {
105
- // Check for help flag
106
- if (args.includes("--help") || args.includes("-h")) {
107
- showHelp();
108
- return;
109
- }
110
- // Get project name from args or use current directory
111
- const projectArg = args.find((arg) => !arg.startsWith("-"));
112
- const targetDir = projectArg ? resolve(projectArg) : process.cwd();
113
- const name = projectArg || basename(process.cwd());
114
- // Check if directory exists and is not empty
115
- if (existsSync(targetDir)) {
116
- const files = ["package.json", "tsconfig.json", "src/main.ts"];
117
- const existingFiles = files.filter((f) => existsSync(join(targetDir, f)));
118
- if (existingFiles.length > 0) {
119
- console.error(`Error: Directory already contains project files:`);
120
- for (const file of existingFiles) {
121
- console.error(` - ${file}`);
122
- }
123
- console.error("");
124
- console.error("Use a different directory or remove existing files.");
125
- process.exit(1);
126
- }
127
- }
128
- console.log(`Creating thinkwell project in ${targetDir}...`);
129
- console.log("");
130
- createProject({ name, targetDir });
131
- console.log("Created files:");
132
- console.log(" - package.json");
133
- console.log(" - tsconfig.json");
134
- console.log(" - src/main.ts");
135
- console.log(" - .gitignore");
136
- console.log(" - .env.example");
137
- console.log("");
138
- console.log("Next steps:");
139
- console.log("");
140
- if (projectArg) {
141
- console.log(` cd ${projectArg}`);
87
+ if (args.includes("--help") || args.includes("-h")) {
88
+ showHelp();
89
+ return;
90
+ }
91
+ const projectArg = args.find((arg) => !arg.startsWith("-")), targetDir = projectArg ? resolve(projectArg) : process.cwd(), name = projectArg || basename(process.cwd());
92
+ if (existsSync(targetDir)) {
93
+ const existingFiles = ["package.json", "tsconfig.json", "src/main.ts"].filter((f) => existsSync(join(targetDir, f)));
94
+ if (existingFiles.length > 0) {
95
+ console.error("Error: Directory already contains project files:");
96
+ for (const file of existingFiles)
97
+ console.error(` - ${file}`);
98
+ console.error(""), console.error("Use a different directory or remove existing files."), process.exit(1);
142
99
  }
143
- console.log(" npm install # or: bun install");
144
- console.log(" cp .env.example .env");
145
- console.log(" # Edit .env to configure your agent");
146
- console.log(" thinkwell src/main.ts");
147
- console.log("");
100
+ }
101
+ console.log(`Creating thinkwell project in ${targetDir}...`), console.log(""), createProject({ name, targetDir }), console.log("Created files:"), console.log(" - package.json"), console.log(" - tsconfig.json"), console.log(" - src/main.ts"), console.log(" - .gitignore"), console.log(" - .env.example"), console.log(""), console.log("Next steps:"), console.log(""), projectArg && console.log(` cd ${projectArg}`), console.log(" npm install # or: bun install"), console.log(" cp .env.example .env"), console.log(" # Edit .env to configure your agent"), console.log(" thinkwell src/main.ts"), console.log("");
148
102
  }
149
- //# sourceMappingURL=init-command.js.map
package/dist/cli/init.js CHANGED
@@ -1,250 +1,120 @@
1
- /**
2
- * CLI command for initializing thinkwell in the current directory.
3
- *
4
- * This command initializes a project for thinkwell development:
5
- * - Creates package.json if none exists
6
- * - Adds missing dependencies (thinkwell, typescript)
7
- *
8
- * Following Cargo's design: "init" modifies existing state in the current
9
- * directory, while "new" creates a new directory.
10
- *
11
- * @see doc/rfd/explicit-config.md for the design
12
- */
13
1
  import { createInterface } from "node:readline";
14
2
  import { spawn } from "node:child_process";
15
3
  import { basename, dirname, join } from "node:path";
16
4
  import { fileURLToPath } from "node:url";
17
5
  import { readFileSync, writeFileSync } from "node:fs";
18
- import { checkDependencies, hasPackageJson, } from "./dependency-check.js";
6
+ import { checkDependencies, hasPackageJson } from "./dependency-check.js";
19
7
  import { detectPackageManager } from "./package-manager.js";
20
8
  import { cyan, cyanBold, greenBold, whiteBold, dim, redBold } from "./fmt.js";
21
- // ============================================================================
22
- // Version Detection
23
- // ============================================================================
24
- /**
25
- * Get the version of the thinkwell CLI.
26
- * Used to set default dependency versions that match the CLI.
27
- */
28
9
  function getCliVersion() {
29
- try {
30
- // Resolve path relative to this module
31
- const __dirname = dirname(fileURLToPath(import.meta.url));
32
- const pkgPath = join(__dirname, "../../package.json");
33
- const content = readFileSync(pkgPath, "utf-8");
34
- const pkg = JSON.parse(content);
35
- return pkg.version || "0.5.0";
36
- }
37
- catch {
38
- return "0.5.0";
39
- }
10
+ try {
11
+ const __dirname = dirname(fileURLToPath(import.meta.url)), pkgPath = join(__dirname, "../../package.json"), content = readFileSync(pkgPath, "utf-8");
12
+ return JSON.parse(content).version || "0.5.0";
13
+ } catch {
14
+ return "0.5.0";
15
+ }
40
16
  }
41
- /**
42
- * Get the TypeScript version bundled with thinkwell.
43
- * Used to set a compatible default version.
44
- */
45
17
  function getTypescriptVersion() {
46
- try {
47
- const __dirname = dirname(fileURLToPath(import.meta.url));
48
- const pkgPath = join(__dirname, "../../package.json");
49
- const content = readFileSync(pkgPath, "utf-8");
50
- const pkg = JSON.parse(content);
51
- // Extract major.minor from the dependency spec (e.g., "^5.7.2" -> "5.7")
52
- const tsSpec = pkg.dependencies?.typescript || "^5.7.0";
53
- const match = tsSpec.match(/(\d+\.\d+)/);
54
- return match ? `^${match[1]}.0` : "^5.7.0";
55
- }
56
- catch {
57
- return "^5.7.0";
58
- }
18
+ try {
19
+ const __dirname = dirname(fileURLToPath(import.meta.url)), pkgPath = join(__dirname, "../../package.json"), content = readFileSync(pkgPath, "utf-8"), match = (JSON.parse(content).dependencies?.typescript || "^5.7.0").match(/(\d+\.\d+)/);
20
+ return match ? `^${match[1]}.0` : "^5.7.0";
21
+ } catch {
22
+ return "^5.7.0";
23
+ }
59
24
  }
60
- // ============================================================================
61
- // Interactive Prompts
62
- // ============================================================================
63
- /**
64
- * Prompt the user for confirmation.
65
- * Returns true if the user accepts (Y/y or Enter), false otherwise.
66
- */
67
25
  async function confirm(message) {
68
- const rl = createInterface({
69
- input: process.stdin,
70
- output: process.stdout,
71
- });
72
- return new Promise((resolve) => {
73
- rl.question(message, (answer) => {
74
- rl.close();
75
- const normalized = answer.trim().toLowerCase();
76
- // Accept empty (Enter), 'y', or 'yes'
77
- resolve(normalized === "" || normalized === "y" || normalized === "yes");
78
- });
26
+ const rl = createInterface({
27
+ input: process.stdin,
28
+ output: process.stdout
29
+ });
30
+ return new Promise((resolve) => {
31
+ rl.question(message, (answer) => {
32
+ rl.close();
33
+ const normalized = answer.trim().toLowerCase();
34
+ resolve(normalized === "" || normalized === "y" || normalized === "yes");
79
35
  });
36
+ });
80
37
  }
81
- // ============================================================================
82
- // Package Installation
83
- // ============================================================================
84
- /**
85
- * Run a shell command and stream output to stdout/stderr.
86
- */
87
38
  function runCommand(cmd, cwd) {
88
- return new Promise((resolve, reject) => {
89
- const [command, ...args] = cmd;
90
- const proc = spawn(command, args, {
91
- cwd,
92
- stdio: "inherit",
93
- });
94
- proc.on("error", reject);
95
- proc.on("close", (code) => {
96
- if (code === 0) {
97
- resolve();
98
- }
99
- else {
100
- reject(new Error(`Command failed with exit code ${code}`));
101
- }
102
- });
39
+ return new Promise((resolve, reject) => {
40
+ const [command, ...args] = cmd, proc = spawn(command, args, {
41
+ cwd,
42
+ stdio: "inherit"
43
+ });
44
+ proc.on("error", reject), proc.on("close", (code) => {
45
+ code === 0 ? resolve() : reject(new Error(`Command failed with exit code ${code}`));
103
46
  });
47
+ });
104
48
  }
105
- /**
106
- * Install a package using the detected package manager.
107
- */
108
49
  async function installPackage(pm, pkg, version, dev, cwd) {
109
- const spec = `${pkg}@${version}`;
110
- // Build the command based on package manager
111
- let cmd;
112
- switch (pm.name) {
113
- case "pnpm":
114
- cmd = dev ? ["pnpm", "add", "-D", spec] : ["pnpm", "add", spec];
115
- break;
116
- case "yarn":
117
- cmd = dev ? ["yarn", "add", "-D", spec] : ["yarn", "add", spec];
118
- break;
119
- case "npm":
120
- cmd = dev ? ["npm", "install", "-D", spec] : ["npm", "install", spec];
121
- break;
122
- }
123
- console.log(`Running: ${cmd.join(" ")}`);
124
- await runCommand(cmd, cwd);
50
+ const spec = `${pkg}@${version}`;
51
+ let cmd;
52
+ switch (pm.name) {
53
+ case "pnpm":
54
+ cmd = dev ? ["pnpm", "add", "-D", spec] : ["pnpm", "add", spec];
55
+ break;
56
+ case "yarn":
57
+ cmd = dev ? ["yarn", "add", "-D", spec] : ["yarn", "add", spec];
58
+ break;
59
+ case "npm":
60
+ cmd = dev ? ["npm", "install", "-D", spec] : ["npm", "install", spec];
61
+ break;
62
+ }
63
+ console.log(`Running: ${cmd.join(" ")}`), await runCommand(cmd, cwd);
125
64
  }
126
- // ============================================================================
127
- // Package.json Creation
128
- // ============================================================================
129
- /**
130
- * Create a minimal package.json for a new project.
131
- */
132
65
  function createPackageJson(projectDir) {
133
- const name = basename(projectDir);
134
- const content = {
135
- name,
136
- version: "0.1.0",
137
- type: "module",
138
- };
139
- const pkgPath = join(projectDir, "package.json");
140
- writeFileSync(pkgPath, JSON.stringify(content, null, 2) + "\n");
66
+ const content = {
67
+ name: basename(projectDir),
68
+ version: "0.1.0",
69
+ type: "module"
70
+ }, pkgPath = join(projectDir, "package.json");
71
+ writeFileSync(pkgPath, JSON.stringify(content, null, 2) + `
72
+ `);
141
73
  }
142
- // ============================================================================
143
- // Main Init Logic
144
- // ============================================================================
145
- /**
146
- * Determine which dependencies are missing and need to be installed.
147
- */
148
74
  function getMissingDependencies(result) {
149
- const missing = [];
150
- if (!result.thinkwell.found) {
151
- const cliVersion = getCliVersion();
152
- // Use caret range for thinkwell (e.g., "^0.5.0")
153
- const version = cliVersion.startsWith("^") ? cliVersion : `^${cliVersion}`;
154
- missing.push({ name: "thinkwell", version, dev: false });
155
- }
156
- if (!result.typescript.found) {
157
- missing.push({ name: "typescript", version: getTypescriptVersion(), dev: true });
158
- }
159
- return missing;
75
+ const missing = [];
76
+ if (!result.thinkwell.found) {
77
+ const cliVersion = getCliVersion(), version = cliVersion.startsWith("^") ? cliVersion : `^${cliVersion}`;
78
+ missing.push({ name: "thinkwell", version, dev: !1 });
79
+ }
80
+ return result.typescript.found || missing.push({ name: "typescript", version: getTypescriptVersion(), dev: !0 }), missing;
160
81
  }
161
- /**
162
- * Run the init command.
163
- */
164
82
  export async function runInit(options) {
165
- const { yes, projectDir } = options;
166
- // Create package.json if it doesn't exist
167
- if (!hasPackageJson(projectDir)) {
168
- console.log("No package.json found. Creating one...");
169
- createPackageJson(projectDir);
170
- console.log(`Created ${cyanBold("package.json")}`);
171
- console.log("");
172
- }
173
- // Detect package manager
174
- const pm = detectPackageManager(projectDir);
175
- console.log(`Detected package manager: ${cyanBold(pm.name)}`);
176
- console.log("");
177
- // Check dependencies
178
- const result = await checkDependencies(projectDir);
179
- const missing = getMissingDependencies(result);
180
- if (missing.length === 0) {
181
- console.log(`${greenBold("✓")} All required dependencies are already installed.`);
182
- return;
183
- }
184
- // Show what will be installed
185
- console.log("Missing dependencies:");
186
- for (const dep of missing) {
187
- const devTag = dep.dev ? dim(" (devDependency)") : "";
188
- console.log(` • ${cyanBold(dep.name)} ${dim(`(will add ${dep.version})`)}${devTag}`);
189
- }
190
- console.log("");
191
- // Prompt for confirmation in interactive mode
192
- if (!yes) {
193
- const isTTY = process.stdin.isTTY && process.stdout.isTTY;
194
- if (isTTY) {
195
- const proceed = await confirm("Proceed? [Y/n] ");
196
- if (!proceed) {
197
- console.log("Aborted.");
198
- process.exit(0);
199
- }
200
- console.log("");
201
- }
202
- else {
203
- // Non-TTY without --yes flag: fail with guidance
204
- console.error(`${redBold("Error:")} Cannot prompt for confirmation in non-interactive mode.`);
205
- console.error("");
206
- console.error("Run with --yes to proceed without confirmation:");
207
- console.error(` ${cyanBold("thinkwell init --yes")}`);
208
- process.exit(2);
209
- }
210
- }
211
- // Install missing dependencies
212
- for (const dep of missing) {
213
- await installPackage(pm, dep.name, dep.version, dep.dev, projectDir);
214
- }
215
- console.log("");
216
- console.log(`${greenBold("✓")} Dependencies added successfully.`);
83
+ const { yes, projectDir } = options;
84
+ hasPackageJson(projectDir) || (console.log("No package.json found. Creating one..."), createPackageJson(projectDir), console.log(`Created ${cyanBold("package.json")}`), console.log(""));
85
+ const pm = detectPackageManager(projectDir);
86
+ console.log(`Detected package manager: ${cyanBold(pm.name)}`), console.log("");
87
+ const result = await checkDependencies(projectDir), missing = getMissingDependencies(result);
88
+ if (missing.length === 0) {
89
+ console.log(`${greenBold("\u2713")} All required dependencies are already installed.`);
90
+ return;
91
+ }
92
+ console.log("Missing dependencies:");
93
+ for (const dep of missing) {
94
+ const devTag = dep.dev ? dim(" (devDependency)") : "";
95
+ console.log(` \u2022 ${cyanBold(dep.name)} ${dim(`(will add ${dep.version})`)}${devTag}`);
96
+ }
97
+ console.log(""), yes || (process.stdin.isTTY && process.stdout.isTTY ? (await confirm("Proceed? [Y/n] ") || (console.log("Aborted."), process.exit(0)), console.log("")) : (console.error(`${redBold("Error:")} Cannot prompt for confirmation in non-interactive mode.`), console.error(""), console.error("Run with --yes to proceed without confirmation:"), console.error(` ${cyanBold("thinkwell init --yes")}`), process.exit(2)));
98
+ for (const dep of missing)
99
+ await installPackage(pm, dep.name, dep.version, dep.dev, projectDir);
100
+ console.log(""), console.log(`${greenBold("\u2713")} Dependencies added successfully.`);
217
101
  }
218
- // ============================================================================
219
- // Argument Parsing
220
- // ============================================================================
221
- /**
222
- * Parse command-line arguments for the init command.
223
- */
224
102
  export function parseInitArgs(args) {
225
- let yes = false;
226
- let projectDir = process.cwd();
227
- for (let i = 0; i < args.length; i++) {
228
- const arg = args[i];
229
- if (arg === "--yes" || arg === "-y") {
230
- yes = true;
231
- }
232
- else if (arg === "--help" || arg === "-h") {
233
- // Handled by caller
234
- continue;
235
- }
236
- else if (!arg.startsWith("-")) {
237
- // Treat as project directory
238
- projectDir = arg.startsWith("/") ? arg : join(process.cwd(), arg);
239
- }
103
+ let yes = !1, projectDir = process.cwd();
104
+ for (let i = 0; i < args.length; i++) {
105
+ const arg = args[i];
106
+ if (arg === "--yes" || arg === "-y")
107
+ yes = !0;
108
+ else {
109
+ if (arg === "--help" || arg === "-h")
110
+ continue;
111
+ arg.startsWith("-") || (projectDir = arg.startsWith("/") ? arg : join(process.cwd(), arg));
240
112
  }
241
- return { yes, projectDir };
113
+ }
114
+ return { yes, projectDir };
242
115
  }
243
- /**
244
- * Show help for the init command.
245
- */
246
116
  export function showInitHelp() {
247
- console.log(`
117
+ console.log(`
248
118
  ${cyanBold("thinkwell init")} - ${whiteBold("Initialize thinkwell in the current directory")}
249
119
 
250
120
  ${greenBold("Usage:")}
@@ -269,6 +139,6 @@ ${greenBold("Examples:")}
269
139
 
270
140
  ${greenBold("To create a new project in a new directory:")}
271
141
  ${cyanBold("thinkwell new")} ${cyan("<project-name>")}
272
- `.trim() + "\n");
142
+ `.trim() + `
143
+ `);
273
144
  }
274
- //# sourceMappingURL=init.js.map