tidewave 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,55 +1,9 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this project will be documented in this file.
3
+ ## [0.5.1] - 2025-11-11
4
4
 
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
+ * Add `npx tidewave install` and trim down dependency list.
7
6
 
8
- ## [0.1.0] - 2024-08-29
7
+ ## [0.5.0] - 2025-11-10
9
8
 
10
- ### Added
11
-
12
- #### Core Features
13
- - **MCP Server Support**: STDIO-based Model Context Protocol server for integration with AI coding assistants
14
- - **Documentation Extraction**: Extract TypeScript/JavaScript documentation and type information for symbols, classes, functions, and methods
15
- - **Source Location Resolution**: Get source file paths for modules, symbols, and members
16
- - **Multi-format Support**: Support for local files, npm dependencies, and Node.js builtin modules
17
-
18
- #### Module Reference Formats
19
- - `module:symbol` - Extract documentation for top-level symbols
20
- - `module:Class#method` - Extract documentation for instance methods
21
- - `module:Class.method` - Extract documentation for static methods
22
- - `node:Class#method` - Extract documentation for Node.js builtin instance methods
23
- - `node:Class.method` - Extract documentation for Node.js builtin static methods
24
-
25
- #### CLI Commands
26
- - `tidewave mcp` - Start the MCP server via STDIO
27
- - `tidewave docs <module-path>` - Extract documentation for a symbol
28
- - `tidewave source <module>` - Get the source file path for a module
29
-
30
- #### Runtime Support
31
- - Full support for Node.js with npm/npx
32
- - Native support for Bun with bunx
33
- - Support for Deno via npm: protocol
34
-
35
- ### Fixed
36
- - Handle source location of symbols and members correctly (#7)
37
- - Handle prefix option only on CLI layer, not in core extraction (#6)
38
- - Correctly extract JavaScript/TypeScript symbols, instances, and methods
39
- - Show interface types correctly
40
- - Handle falsy values and improve error handling (#1)
41
-
42
- ### Changed
43
- - Refactored codebase into modular structure for better maintainability
44
- - Simplified module resolution and extraction logic
45
- - Improved TypeScript and Node.js module resolution
46
- - Changed config flag for project path handling (#3)
47
-
48
- ### Technical Details
49
- - Built with TypeScript for type safety
50
- - Uses TypeScript Compiler API for accurate code analysis
51
- - Supports ESM modules
52
- - Includes comprehensive error handling and user-friendly error messages
53
- - Optimized for use with AI coding assistants through MCP protocol
54
-
55
- [0.1.0]: https://github.com/dashbit/tidewave_javascript/releases/tag/v0.1.0
9
+ * Initial release.
package/README.md CHANGED
@@ -1,13 +1,16 @@
1
1
  # Tidewave
2
2
 
3
- > Tidewave Web for Next.js and React+Vite is currently in alpha testing!
3
+ Tidewave is the coding agent for full-stack web app development. Integrate
4
+ Claude Code, OpenAI Codex, and other agents with your web app and web framework
5
+ at every layer, from UI to database. [See our website](https://tidewave.ai) for
6
+ more information.
4
7
 
5
- Tidewave is the coding agent for full-stack web app development.
6
- [See our website](https://tidewave.ai) for more information.
8
+ This project supports:
7
9
 
8
- If you are using Next.js or you have a React + Vite frontend, talking either to
9
- a backend as a service (such as Supabase) or a third-party framework, you are in
10
- the right place!
10
+ - Next.js 15/16
11
+
12
+ - React + Vite frontends, with either a backend as a service (such as Supabase)
13
+ or a third-party framework
11
14
 
12
15
  If you are using React with Django, FastAPI, Flask, Phoenix, or Rails,
13
16
  [follow the steps here instead](http://hexdocs.pm/tidewave/react.html).
@@ -187,8 +190,9 @@ database calls, etc) won't be available.
187
190
  Next.js' `tidewaveHandler` and Vite's `tidewave` accept the configuration
188
191
  options below:
189
192
 
190
- - `allow_remote_access:` allow remote connections when true (default false)
191
- - `allowed_origins:` defaults to the current host/port
193
+ - `allow_remote_access:` allow remote connections when true (default false).
194
+ Enable this only if you trust your network and you want Tidewave MCP to be
195
+ accessed from another trusted machine
192
196
  - `team`: enable Tidewave Web for teams
193
197
 
194
198
  ## CLI
package/dist/cli/index.js CHANGED
@@ -4924,7 +4924,7 @@ var init_src = __esm(() => {
4924
4924
  });
4925
4925
 
4926
4926
  // package.json
4927
- var name = "tidewave", version = "0.5.0", package_default;
4927
+ var name = "tidewave", version = "0.5.1", package_default;
4928
4928
  var init_package = __esm(() => {
4929
4929
  package_default = {
4930
4930
  name,
@@ -4995,23 +4995,14 @@ var init_package = __esm(() => {
4995
4995
  },
4996
4996
  dependencies: {
4997
4997
  "@modelcontextprotocol/sdk": "^1.17.4",
4998
- "@opentelemetry/api": "^1.9.0",
4999
- "@opentelemetry/api-logs": "^0.206.0",
5000
- "@opentelemetry/core": "^2.1.0",
5001
- "@opentelemetry/resources": "^2.1.0",
5002
- "@opentelemetry/sdk-logs": "^0.206.0",
5003
- "@opentelemetry/sdk-trace-base": "^2.1.0",
5004
- "@opentelemetry/sdk-trace-node": "^2.1.0",
5005
- "@opentelemetry/semantic-conventions": "^1.37.0",
5006
4998
  "body-parser": "^2.2.0",
5007
- chalk: "^5.3.0",
5008
- commander: "^12.1.0",
5009
4999
  connect: "^3.7.0",
5010
5000
  typescript: "^5",
5011
5001
  zod: "3.25.76"
5012
5002
  },
5013
5003
  devDependencies: {
5014
5004
  "@eslint/js": "^9.16.0",
5005
+ "@opentelemetry/sdk-trace-node": "^2.1.0",
5015
5006
  "@types/body-parser": "^1.19.6",
5016
5007
  "@types/bun": "latest",
5017
5008
  "@types/connect": "^3.4.38",
@@ -5021,6 +5012,8 @@ var init_package = __esm(() => {
5021
5012
  "@vercel/otel": "^2.0.1",
5022
5013
  "@vitest/ui": "^3.2.4",
5023
5014
  "bun-types": "latest",
5015
+ commander: "^12.1.0",
5016
+ chalk: "^5.3.0",
5024
5017
  eslint: "^9.16.0",
5025
5018
  globals: "^15.14.0",
5026
5019
  next: "^15.5.3",
@@ -14525,7 +14518,7 @@ init_tools();
14525
14518
  init_src();
14526
14519
  init_package();
14527
14520
  import { program } from "commander";
14528
- import chalk from "chalk";
14521
+ import chalk2 from "chalk";
14529
14522
 
14530
14523
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
14531
14524
  import process2 from "node:process";
@@ -14625,11 +14618,345 @@ class StdioServerTransport {
14625
14618
 
14626
14619
  // src/cli/index.ts
14627
14620
  init_mcp2();
14628
- function chdir(path4) {
14621
+
14622
+ // src/cli/install.ts
14623
+ import * as fs from "fs";
14624
+ import * as path4 from "path";
14625
+ import * as child_process from "child_process";
14626
+ import * as readline from "readline";
14627
+ import chalk from "chalk";
14628
+ async function handleInstall(options) {
14629
+ const targetDir = options.prefix || process.cwd();
14630
+ const dryRun = options.dryRun || false;
14631
+ const skipDeps = options.skipDeps || false;
14632
+ console.log(chalk.blue(`
14633
+ \uD83C\uDF0A Tidewave Installer
14634
+ `));
14635
+ console.log(chalk.gray(`Target directory: ${targetDir}`));
14636
+ if (dryRun) {
14637
+ console.log(chalk.yellow(`
14638
+ ⚠️ DRY RUN MODE - No files will be created
14639
+ `));
14640
+ }
14641
+ const nextVersion = await detectNextJsVersion(targetDir);
14642
+ if (!nextVersion) {
14643
+ console.error(chalk.red(`
14644
+ ❌ Could not find Next.js in node_modules.`));
14645
+ console.log(chalk.gray(`
14646
+ The installer only works for Next.js projects
14647
+ `));
14648
+ process.exit(1);
14649
+ }
14650
+ console.log(chalk.green(`✅ Detected Next.js ${nextVersion.raw} (v${nextVersion.major})`));
14651
+ if (!skipDeps) {
14652
+ await installDependencies(targetDir, dryRun);
14653
+ } else {
14654
+ console.log(chalk.gray("⏭️ Skipping dependency installation"));
14655
+ }
14656
+ const steps = [
14657
+ () => createApiHandler(targetDir, dryRun),
14658
+ () => createMiddleware(targetDir, nextVersion, dryRun),
14659
+ () => createInstrumentation(targetDir, dryRun)
14660
+ ];
14661
+ for (const step of steps) {
14662
+ await step();
14663
+ }
14664
+ console.log(chalk.green(`
14665
+ ✅ Tidewave setup complete!
14666
+ `));
14667
+ console.log(chalk.blue("Next steps:"));
14668
+ console.log(" 1. Start your Next.js dev server: npm run dev");
14669
+ console.log(" 2. Install the Tidewave app: https://hexdocs.pm/tidewave/");
14670
+ console.log(` 3. Connect to your app through Tidewave
14671
+ `);
14672
+ }
14673
+ async function detectNextJsVersion(dir) {
14674
+ try {
14675
+ const nextPackageJsonPath = path4.join(dir, "node_modules", "next", "package.json");
14676
+ if (!fs.existsSync(nextPackageJsonPath)) {
14677
+ return null;
14678
+ }
14679
+ const nextPackageJson = JSON.parse(fs.readFileSync(nextPackageJsonPath, "utf-8"));
14680
+ const { version: version2 } = nextPackageJson;
14681
+ const match = version2.match(/^(\d+)\.(\d+)\.(\d+)/);
14682
+ if (match) {
14683
+ return {
14684
+ major: parseInt(match[1]),
14685
+ minor: parseInt(match[2]),
14686
+ raw: version2
14687
+ };
14688
+ }
14689
+ return null;
14690
+ } catch {
14691
+ return null;
14692
+ }
14693
+ }
14694
+ function detectPackageManager(dir) {
14695
+ if (fs.existsSync(path4.join(dir, "bun.lockb")))
14696
+ return "bun";
14697
+ if (fs.existsSync(path4.join(dir, "pnpm-lock.yaml")))
14698
+ return "pnpm";
14699
+ if (fs.existsSync(path4.join(dir, "yarn.lock")))
14700
+ return "yarn";
14701
+ if (fs.existsSync(path4.join(dir, "package-lock.json")))
14702
+ return "npm";
14703
+ return "npm";
14704
+ }
14705
+ async function promptUser(question) {
14706
+ const rl = readline.createInterface({
14707
+ input: process.stdin,
14708
+ output: process.stdout
14709
+ });
14710
+ return new Promise((resolve) => {
14711
+ rl.question(question, (answer) => {
14712
+ rl.close();
14713
+ const normalized = answer.trim().toLowerCase();
14714
+ resolve(normalized === "" || normalized === "y" || normalized === "yes");
14715
+ });
14716
+ });
14717
+ }
14718
+ async function installDependencies(dir, dryRun) {
14719
+ console.log(chalk.yellow("\uD83D\uDCE6 Installing dependencies..."));
14720
+ if (dryRun) {
14721
+ console.log(chalk.gray("[DRY RUN] Would install: tidewave, @opentelemetry/sdk-node"));
14722
+ return;
14723
+ }
14724
+ const pm = detectPackageManager(dir);
14725
+ const devDepCommands = {
14726
+ npm: ["install", "-D", "tidewave"],
14727
+ yarn: ["add", "-D", "tidewave"],
14728
+ pnpm: ["add", "--save-dev", "tidewave"],
14729
+ bun: ["add", "--dev", "tidewave"]
14730
+ };
14731
+ const depCommands = {
14732
+ npm: ["install", "@opentelemetry/sdk-node"],
14733
+ yarn: ["add", "@opentelemetry/sdk-node"],
14734
+ pnpm: ["add", "@opentelemetry/sdk-node"],
14735
+ bun: ["add", "@opentelemetry/sdk-node"]
14736
+ };
14737
+ const devCmds = devDepCommands[pm];
14738
+ const depCmds = depCommands[pm];
14739
+ if (!devCmds || !depCmds) {
14740
+ console.error(chalk.red(`
14741
+ ❌ Unknown package manager: ${pm}`));
14742
+ process.exit(1);
14743
+ }
14744
+ try {
14745
+ child_process.execSync(`${pm} ${devCmds.join(" ")}`, {
14746
+ cwd: dir,
14747
+ stdio: "inherit"
14748
+ });
14749
+ child_process.execSync(`${pm} ${depCmds.join(" ")}`, {
14750
+ cwd: dir,
14751
+ stdio: "inherit"
14752
+ });
14753
+ console.log(chalk.green("✅ Dependencies installed"));
14754
+ } catch (_error) {
14755
+ console.error(chalk.red(`
14756
+ ❌ Failed to install dependencies`));
14757
+ console.log(chalk.gray(`
14758
+ Please install manually:
14759
+ ${pm} ${devCmds.join(" ")}
14760
+ ${pm} ${depCmds.join(" ")}
14761
+ `));
14762
+ process.exit(1);
14763
+ }
14764
+ }
14765
+ async function createApiHandler(dir, dryRun) {
14766
+ const apiDir = path4.join(dir, "pages", "api");
14767
+ const handlerPath = path4.join(apiDir, "tidewave.ts");
14768
+ const handlerContent = `import type { NextApiRequest, NextApiResponse } from 'next';
14769
+
14770
+ export default async function handler(
14771
+ req: NextApiRequest,
14772
+ res: NextApiResponse,
14773
+ ) {
14774
+ if (process.env.NODE_ENV === 'development') {
14775
+ const { tidewaveHandler } = await import('tidewave/next-js/handler');
14776
+ const handler = await tidewaveHandler();
14777
+ return handler(req, res);
14778
+ } else {
14779
+ res.status(404).end();
14780
+ }
14781
+ }
14782
+
14783
+ export const config = {
14784
+ runtime: 'nodejs',
14785
+ api: {
14786
+ bodyParser: false, // Tidewave already parses the body internally
14787
+ },
14788
+ };
14789
+ `;
14790
+ if (fs.existsSync(handlerPath)) {
14791
+ if (dryRun) {
14792
+ console.log(chalk.gray(`[DRY RUN] Would ask to overwrite: ${path4.relative(dir, handlerPath)}`));
14793
+ return;
14794
+ }
14795
+ const shouldOverwrite = await promptUser(chalk.yellow(`
14796
+ ⚠️ ${path4.relative(dir, handlerPath)} already exists. Overwrite? (Y/n): `));
14797
+ if (!shouldOverwrite) {
14798
+ console.log(chalk.gray(`⏭️ Skipping: ${path4.relative(dir, handlerPath)}`));
14799
+ return;
14800
+ }
14801
+ }
14802
+ if (dryRun) {
14803
+ console.log(chalk.gray(`[DRY RUN] Would create: ${path4.relative(dir, handlerPath)}`));
14804
+ return;
14805
+ }
14806
+ fs.mkdirSync(apiDir, { recursive: true });
14807
+ fs.writeFileSync(handlerPath, handlerContent, "utf-8");
14808
+ console.log(chalk.green(`✅ Created: ${path4.relative(dir, handlerPath)}`));
14809
+ }
14810
+ async function createMiddleware(dir, nextVersion, dryRun) {
14811
+ const isNext16Plus = nextVersion.major >= 16;
14812
+ const fileName = isNext16Plus ? "proxy.ts" : "middleware.ts";
14813
+ const filePath = path4.join(dir, fileName);
14814
+ if (fs.existsSync(filePath)) {
14815
+ console.log(chalk.yellow(`⏭️ ${fileName} already exists`));
14816
+ const content = fs.readFileSync(filePath, "utf-8");
14817
+ if (content.includes("/tidewave") && content.includes("/api/tidewave")) {
14818
+ console.log(chalk.green(`✅ ${fileName} already configured for Tidewave`));
14819
+ return;
14820
+ }
14821
+ console.log(chalk.gray(`
14822
+ Please manually add the following to your ${fileName}:
14823
+ `));
14824
+ printMiddlewareInstructions(isNext16Plus);
14825
+ return;
14826
+ }
14827
+ const middlewareContent = isNext16Plus ? `import { NextRequest, NextResponse } from 'next/server';
14828
+
14829
+ export function proxy(req: NextRequest): NextResponse {
14830
+ if (req.nextUrl.pathname.startsWith('/tidewave')) {
14831
+ return NextResponse.rewrite(new URL('/api/tidewave', req.url));
14832
+ }
14833
+
14834
+ // Here you could add your own logic or different middlewares.
14835
+ return NextResponse.next();
14836
+ }
14837
+ ` : `import { NextRequest, NextResponse } from 'next/server';
14838
+
14839
+ export function middleware(req: NextRequest): NextResponse {
14840
+ if (req.nextUrl.pathname.startsWith('/tidewave')) {
14841
+ return NextResponse.rewrite(new URL('/api/tidewave', req.url));
14842
+ }
14843
+
14844
+ // Here you could add your own logic or different middlewares.
14845
+ return NextResponse.next();
14846
+ }
14847
+
14848
+ export const config = {
14849
+ matcher: ['/tidewave/:path*'],
14850
+ };
14851
+ `;
14852
+ if (dryRun) {
14853
+ console.log(chalk.gray(`[DRY RUN] Would create: ${fileName}`));
14854
+ return;
14855
+ }
14856
+ fs.writeFileSync(filePath, middlewareContent, "utf-8");
14857
+ console.log(chalk.green(`✅ Created: ${fileName}`));
14858
+ }
14859
+ function printMiddlewareInstructions(isNext16Plus) {
14860
+ if (isNext16Plus) {
14861
+ console.log(chalk.cyan(` if (req.nextUrl.pathname.startsWith('/tidewave')) {
14862
+ return NextResponse.rewrite(new URL('/api/tidewave', req.url));
14863
+ }`));
14864
+ } else {
14865
+ console.log(chalk.cyan(` if (req.nextUrl.pathname.startsWith('/tidewave')) {
14866
+ return NextResponse.rewrite(new URL('/api/tidewave', req.url));
14867
+ }
14868
+
14869
+ // Also add to config.matcher:
14870
+ export const config = {
14871
+ matcher: ['/tidewave/:path*'],
14872
+ };`));
14873
+ }
14874
+ console.log();
14875
+ }
14876
+ async function createInstrumentation(dir, dryRun) {
14877
+ const rootPath = path4.join(dir, "instrumentation.ts");
14878
+ const srcPath = path4.join(dir, "src", "instrumentation.ts");
14879
+ const hasSrcDir = fs.existsSync(path4.join(dir, "src"));
14880
+ const instrumentationPath = hasSrcDir ? srcPath : rootPath;
14881
+ if (fs.existsSync(rootPath) || fs.existsSync(srcPath)) {
14882
+ const existingPath = fs.existsSync(rootPath) ? rootPath : srcPath;
14883
+ const existingFile = fs.existsSync(rootPath) ? "instrumentation.ts" : "src/instrumentation.ts";
14884
+ console.log(chalk.yellow(`⏭️ ${existingFile} already exists`));
14885
+ const content = fs.readFileSync(existingPath, "utf-8");
14886
+ if (content.includes("TidewaveSpanProcessor") && content.includes("TidewaveLogRecordProcessor")) {
14887
+ console.log(chalk.green(`✅ ${existingFile} already configured for Tidewave`));
14888
+ return;
14889
+ }
14890
+ console.log(chalk.gray(`
14891
+ Please manually add the following to your instrumentation.ts:
14892
+ `));
14893
+ printInstrumentationInstructions();
14894
+ return;
14895
+ }
14896
+ const instrumentationContent = `// instrumentation.ts
14897
+ import { NodeSDK } from '@opentelemetry/sdk-node';
14898
+ import type { SpanProcessor } from '@opentelemetry/sdk-trace-base';
14899
+ import type { LogRecordProcessor } from '@opentelemetry/sdk-logs';
14900
+
14901
+ export async function register() {
14902
+ const runtime = process.env.NEXT_RUNTIME;
14903
+ const env = process.env.NODE_ENV;
14904
+
14905
+ // Add your app own processes here existing configuration
14906
+ const sdkConfig: {
14907
+ spanProcessors: SpanProcessor[];
14908
+ logRecordProcessors: LogRecordProcessor[];
14909
+ } = {
14910
+ spanProcessors: [],
14911
+ logRecordProcessors: [],
14912
+ };
14913
+
14914
+ // Conditionally add Tidewave processors in development
14915
+ if (runtime === 'nodejs' && env === 'development') {
14916
+ const { TidewaveSpanProcessor, TidewaveLogRecordProcessor } = await import(
14917
+ 'tidewave/next-js/instrumentation'
14918
+ );
14919
+
14920
+ sdkConfig.spanProcessors.push(new TidewaveSpanProcessor());
14921
+ sdkConfig.logRecordProcessors.push(new TidewaveLogRecordProcessor());
14922
+ }
14923
+
14924
+ const sdk = new NodeSDK(sdkConfig);
14925
+ sdk.start();
14926
+ }
14927
+ `;
14928
+ if (dryRun) {
14929
+ console.log(chalk.gray(`[DRY RUN] Would create: ${path4.relative(dir, instrumentationPath)}`));
14930
+ return;
14931
+ }
14932
+ if (hasSrcDir) {
14933
+ fs.mkdirSync(path4.dirname(instrumentationPath), { recursive: true });
14934
+ }
14935
+ fs.writeFileSync(instrumentationPath, instrumentationContent, "utf-8");
14936
+ console.log(chalk.green(`✅ Created: ${path4.relative(dir, instrumentationPath)}`));
14937
+ }
14938
+ function printInstrumentationInstructions() {
14939
+ console.log(chalk.cyan(` // Inside your register() function:
14940
+ const runtime = process.env.NEXT_RUNTIME;
14941
+ const env = process.env.NODE_ENV;
14942
+
14943
+ if (runtime === 'nodejs' && env === 'development') {
14944
+ const { TidewaveSpanProcessor, TidewaveLogRecordProcessor } = await import(
14945
+ 'tidewave/next-js/instrumentation'
14946
+ );
14947
+
14948
+ sdkConfig.spanProcessors.push(new TidewaveSpanProcessor());
14949
+ sdkConfig.logRecordProcessors.push(new TidewaveLogRecordProcessor());
14950
+ }`));
14951
+ console.log();
14952
+ }
14953
+
14954
+ // src/cli/index.ts
14955
+ function chdir(path5) {
14629
14956
  try {
14630
- process.chdir(path4);
14957
+ process.chdir(path5);
14631
14958
  } catch (e) {
14632
- console.error(chalk.red(`Failed to apply given prefix: ${e}`));
14959
+ console.error(chalk2.red(`Failed to apply given prefix: ${e}`));
14633
14960
  }
14634
14961
  }
14635
14962
  program.name(name).description("Universal documentation and source extraction tool for TypeScript and JavaScript").version(version);
@@ -14638,7 +14965,7 @@ async function handleGetDocs2(modulePath, options) {
14638
14965
  chdir(options.prefix);
14639
14966
  const docsResult = await Tidewave.extractDocs(modulePath);
14640
14967
  if (isExtractError(docsResult)) {
14641
- console.error(chalk.red(`Error: ${docsResult.error.message}`));
14968
+ console.error(chalk2.red(`Error: ${docsResult.error.message}`));
14642
14969
  process.exit(1);
14643
14970
  }
14644
14971
  if (options.json) {
@@ -14652,7 +14979,7 @@ async function handleGetSourcePath2(moduleName, options) {
14652
14979
  chdir(options.prefix);
14653
14980
  const sourceResult = await Tidewave.getSourceLocation(moduleName);
14654
14981
  if (isResolveError(sourceResult)) {
14655
- console.error(chalk.red(`Error: ${sourceResult.error.message}`));
14982
+ console.error(chalk2.red(`Error: ${sourceResult.error.message}`));
14656
14983
  process.exit(1);
14657
14984
  }
14658
14985
  console.log(sourceResult.path);
@@ -14668,6 +14995,7 @@ var {
14668
14995
  docs: { cli: docsCli },
14669
14996
  source: { cli: sourceCli }
14670
14997
  } = tools;
14998
+ program.command("install").description("Install Tidewave in a Next.js project").option("--prefix <path>", "Specify the directory containing package.json").option("--dry-run", "Preview changes without creating files").action(handleInstall);
14671
14999
  program.command("mcp").description("Starts a MCP server for tidewave (stdio)").option(docsCli.options.prefix.flag, docsCli.options.prefix.desc).action(handleMcp);
14672
15000
  program.command(docsCli.command).description(docsCli.description).argument(docsCli.argument, docsCli.argumentDescription).option(docsCli.options.prefix.flag, docsCli.options.prefix.desc).option(docsCli.options.json.flag, docsCli.options.json.desc).action(handleGetDocs2);
14673
15001
  program.command(sourceCli.command).description(sourceCli.description).argument(sourceCli.argument, sourceCli.argumentDescription).option(sourceCli.options.prefix.flag, sourceCli.options.prefix.desc).action(handleGetSourcePath2);
@@ -0,0 +1,7 @@
1
+ interface InstallOptions {
2
+ prefix?: string;
3
+ dryRun?: boolean;
4
+ skipDeps?: boolean;
5
+ }
6
+ export declare function handleInstall(options: InstallOptions): Promise<void>;
7
+ export {};