Skip to content

release: 0.1.0-alpha.1 - #149

Closed
stainless-app[bot] wants to merge 28 commits into
mainfrom
release-please--branches--main--changes--next--components--terminal49
Closed

release: 0.1.0-alpha.1#149
stainless-app[bot] wants to merge 28 commits into
mainfrom
release-please--branches--main--changes--next--components--terminal49

Conversation

@stainless-app

@stainless-app stainless-app Bot commented Oct 26, 2025

Copy link
Copy Markdown

Automated Release PR

0.1.0-alpha.1 (2025-11-13)

Full Changelog: v0.0.1-alpha.0...v0.1.0-alpha.1

Features

  • mcp: enable optional code execution tool on http mcp servers (b64c4e9)
  • routing endpoints (#137) (444d73a)
  • Update API documentation with consistent code style (6feca12)

Bug Fixes

  • mcpb: pin @anthropic-ai/mcpb version (b0b95f5)
  • mcp: fix cli argument parsing logic (ede6ca2)
  • mcp: resolve a linting issue in server code (b15b8ce)
  • mcp: return tool execution error on jq failure (fec4eb2)

Performance Improvements

Chores

  • Auto-generate Postman collection from openapi.json [skip ci] (0014457)
  • Auto-generate Postman collection from openapi.json [skip ci] (2de5f6d)
  • Auto-generate Postman collection from openapi.json [skip ci] (b187f8b)
  • Auto-generate Postman collection from openapi.json [skip ci] (ee25375)
  • Auto-generate Postman collection from openapi.json [skip ci] (dfdc873)
  • Auto-generate Postman collection from openapi.json [skip ci] (3c2edec)
  • consistent documentation in define Authorization token (41e65e3)
  • docs: add Kimmie's suggestions (24c8beb)
  • docs: add map styling guide (2d652db)
  • docs: embedding the map (d5ee3c5)
  • docs: remove FAQ (27f7446)
  • docs: remove frontmatter (829a486)
  • docs: tell users to reach out to support for a publishable api key (275c651)
  • extract some types in mcp docs (c401b96)
  • internal: codegen related update (497d3bf)
  • internal: codegen related update (ce47236)
  • internal: codegen related update (f84ecdf)
  • internal: fix incremental formatting in some cases (38dfa5d)
  • internal: grammar fix (it's -> its) (6f50c26)
  • internal: ignore .eslintcache (a3a91d5)
  • internal: remove .eslintcache (4c240a6)
  • internal: remove deprecated compilerOptions.baseUrl from tsconfig.json (2dc6c24)
  • internal: use npm pack for build uploads (9053cb7)
  • jsdoc: fix @link annotations to refer only to parts of the package‘s public interface (30fcefa)
  • mcp code tool explicit error message when missing a run function (e1ee122)
  • mcp: add friendlier MCP code tool errors on incorrect method invocations (eb5b0fb)
  • mcp: add line numbers to code tool errors (338b1a5)
  • mcp: allow pointing docs_search tool at other URLs (7203f41)
  • mcp: clarify http auth error (b2ab851)
  • mcp: upgrade jq-web (b4b3ebc)
  • sync repo (d6d221b)
  • Update authentication header in API documentation (e5a16d8)
  • Update links in documentation to use relative paths (787edf5)
  • update lockfile (8fe064e)
  • update old documentation links to be relatives (b2d37fa)
  • update SDK settings (18778c3)
  • use structured error when code execution tool errors (aadf506)

Documentation

  • fix relative paths removing "/docs" (17234ba)

Refactors

  • docs: rename assets to terminal49-map (a3304fc)

This pull request is managed by Stainless's GitHub App.

The semver version number is based on included commit messages. Alternatively, you can manually set the version number in the title of this pull request.

For a better experience, it is recommended to use either rebase-merge or squash-merge when merging this pull request.

🔗 Stainless website
📚 Read the docs
🙋 Reach out for help or questions

@vercel

vercel Bot commented Oct 26, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
api Error Error Nov 13, 2025 5:49am

@macroscopeapp

macroscopeapp Bot commented Oct 26, 2025

Copy link
Copy Markdown

Release version 0.1.0-alpha.1 and add generated Terminal49 TypeScript SDK resources with MCP server tools and CI workflow

Introduce the initial SDK and MCP server: generated API client and resource modules, MCP tool handlers for core endpoints, server CLI and transports, build/test/release tooling, and CI. Key entrypoints include Terminal49 in src/index.ts, resource wiring in src/resources/index.ts, MCP server setup in packages/mcp-server/src/index.ts, and GitHub Actions in .github/workflows/ci.yml.

📍Where to Start

Start with the SDK client initialization and resource wiring in src/client.ts, then review the MCP server entrypoint and tool registration in packages/mcp-server/src/index.ts and packages/mcp-server/src/tools/index.ts.


📊 Macroscope summarized a350415. 50 files reviewed, 63 issues evaluated, 45 issues filtered, 11 comments posted. View details

result[key] = firstVariant[key];
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removeAnyOf drops anyOf even when the first variant is a primitive or null, leaving the rest of the schema unchanged. This broadens accepted inputs or yields an invalid schema, and contradicts the intent to "use only the first variant" because no replacement is applied for non-object variants.

Consider returning the first variant when it isn’t an object, so the function actually uses the first anyOf member in all cases before continuing recursion.

-    }
-
-    delete result.anyOf;
+    } else {
+      return removeAnyOf(firstVariant as JSONSchema);
+    }
+    delete result.anyOf;

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

[ "$(basename "$(dirname "$PWD")")" = 'tmp' ] ||
# The name of the containing directory that 'yarn` uses, which looks like
# $(yarn cache dir)/.tmp/XXXXX
[ "$(basename "$(dirname "$PWD")")" = '.tmp' ]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both the npm cache check (file:scripts/utils/check-is-in-git-install.sh:6) and the yarn cache check (file:scripts/utils/check-is-in-git-install.sh:9) in scripts/utils/check-is-in-git-install.sh currently compare the parent of PWD, but npm’s git clones and yarn’s cache layout place the tmp/.tmp directory one level higher. Update both checks to inspect the grandparent directory name (basename $(dirname $(dirname "$PWD"))) against tmp (npm) or .tmp (yarn) to accurately detect cache-based installations.

-[ "$(basename "$(dirname "$PWD")")" = '.tmp' ]
+[ "$(basename "$(dirname "$(dirname "$PWD")")")" = '.tmp' ]

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

return result;
}

for (const key in result) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a circular $ref causes a property to be deleted under properties, the parent schema’s required (and potentially dependentRequired) is not updated. This yields schemas that require properties that no longer exist, leading to invalid or contradictory validation.

Consider adjusting inlineRefsRecursive to special-case properties: when a property is removed due to a circular ref, also remove its name from required and, if present, clean up related entries in dependentRequired for that property. This keeps the resulting schema consistent and valid.

-  for (const key in result) {
-    if (result[key] && typeof result[key] === 'object') {
-      const processed = inlineRefsRecursive(result[key] as JSONSchema, defs, refPath);
-      if (processed === null) {
-        // Remove properties that would cause circular references
-        delete result[key];
-      } else {
-        result[key] = processed;
-      }
-    }
-  }
+  if (result.properties && typeof result.properties === 'object') {
+    const props = { ...(result.properties as Record<string, JSONSchema>) };
+    for (const propName in props) {
+      const processedProp = inlineRefsRecursive(props[propName] as JSONSchema, defs, refPath);
+      if (processedProp === null) {
+        delete props[propName];
+        if (Array.isArray(result.required)) {
+          result.required = (result.required as string[]).filter((r) => r !== propName);
+        }
+        if (result.dependentRequired && typeof result.dependentRequired === 'object') {
+          delete (result.dependentRequired as Record<string, string[]>)[propName];
+          // Optionally, also remove references to `propName` inside arrays of other dependencies if present.
+          // for (const dep in result.dependentRequired as Record<string, string[]>) {
+          //   (result.dependentRequired as Record<string, string[]>)[dep] = (result.dependentRequired as Record<string, string[]>)[dep].filter((r) => r !== propName);
+          // }
+        }
+      } else {
+        props[propName] = processedProp;
+      }
+    }
+    result.properties = props;
+  }
+
+  for (const key in result) {
+    if (key === 'properties') continue;
+    if (result[key] && typeof result[key] === 'object') {
+      const processed = inlineRefsRecursive(result[key] as JSONSchema, defs, refPath);
+      if (processed === null) {
+        // Remove properties that would cause circular references
+        delete result[key];
+      } else {
+        result[key] = processed;
+      }
+    }
+  }

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

postPath = true;
}
const value = params[index];
let encoded = (postPath ? encodeURIComponent : pathEncoder)('' + value);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coercing params with '' + value will throw a TypeError when value is a Symbol, causing the tag function to crash before it can raise a Terminal49Error. This affects both the initial encoding and the invalid-parameter branch.

Consider using String(value) for coercion in both places. This safely handles Symbol (and other primitives) and preserves the intended behavior of emitting a controlled Terminal49Error for invalid segments.

-       let encoded = (postPath ? encodeURIComponent : pathEncoder)('' + value);
+       let encoded = (postPath ? encodeURIComponent : pathEncoder)(String(value));
-         encoded = value + '';
+         encoded = String(value);

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

Comment thread eslint.config.mjs
{
patterns: [
{
regex: '^terminal49(/.*)?',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-restricted-imports uses an unsupported regex property inside patterns, which doesn’t match the rule schema. This can cause a runtime config error or the rule to be ignored.

Consider switching to the supported object form with group: ['^terminal49(/.*)?'] and keep the message to enforce the restriction as intended.

-              regex: '^terminal49(/.*)?',
+              group: ['^terminal49(/.*)?'],

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

variantSchema['description'] = tool.description;
}

const usedDefs = findUsedDefs(variant, defs);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removeTopLevelUnions computes $defs using findUsedDefs(variant, defs), but the final variantSchema is a merge of inputSchema and variant. $refs from inputSchema won’t be discovered and can be omitted, leaving variantSchema with $refs pointing to missing definitions.

Consider computing used defs from the fully merged variantSchema (instead of just the variant) before assigning $defs so all referenced definitions are included.

-    const usedDefs = findUsedDefs(variant, defs);
+    const usedDefs = findUsedDefs(variantSchema, defs);

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

return values.flatMap((v) => v.split(','));
},
})
.option('no-capability', {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--no-capability uses choices: CAPABILITY_CHOICES while also trying to support comma-separated values via coerce. Yargs validates choices before coerce, so inputs like --no-capability=refs,formats are rejected as the raw string "refs,formats" is not in CAPABILITY_CHOICES.

Consider removing choices from --no-capability and validating after splitting (e.g., mirroring the --capability path), so comma-separated values work as intended.

-    .option('no-capability', {
-      type: 'string',
-      array: true,
-      description: 'Unset client capabilities',
-      choices: CAPABILITY_CHOICES,
-      coerce: (values: string[]) => {
-        return values.flatMap((v) => v.split(','));
-      },
-    })
+    .option('no-capability', {
+      type: 'string',
+      array: true,
+      description: 'Unset client capabilities',
+      coerce: (values: string[]) => {
+        return values.flatMap((v) => v.split(','));
+      },
+    })

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.


const renameMap = new Map<string, string>();
const usedNames = new Set<string>();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider initializing usedNames in truncateToolNames (in applyCompatibilityTransformations) with all existing tool names before generating truncated or suffixed names, so that both the non-collide truncation path (truncateToolNames) and the suffix-based collision loop (truncateToolNames) avoid creating duplicates with original names.

+   // Track existing names (those not exceeding maxLength) to avoid collisions with originals
+   for (const name of names) {
+     if (name.length <= maxLength) {
+       usedNames.add(name);
+     }
+   }
-   if (!willCollide) {
-     for (const name of toTruncate) {
-       const truncatedName = name.slice(0, maxLength);
-       renameMap.set(name, truncatedName);
-     }
+   if (!willCollide) {
+     for (const name of toTruncate) {
+       const truncatedName = name.slice(0, maxLength);
+       if (usedNames.has(truncatedName)) {
+         const baseName = name.slice(0, maxLength - 1);
+         let counter = 1;
+         while (usedNames.has(baseName + counter)) {
+           counter++;
+         }
+         const finalName = baseName + counter;
+         renameMap.set(name, finalName);
+         usedNames.add(finalName);
+       } else {
+         renameMap.set(name, truncatedName);
+         usedNames.add(truncatedName);
+       }
+     }
   } else {
     const baseLength = maxLength - 1;
 
     for (const name of toTruncate) {
       const baseName = name.slice(0, baseLength);
       let counter = 1;
 
       while (usedNames.has(baseName + counter)) {
         counter++;
       }
 
       const finalName = baseName + counter;
       renameMap.set(name, finalName);
       usedNames.add(finalName);
     }
   }

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

const baseLength = maxLength - 1;

for (const name of toTruncate) {
const baseName = name.slice(0, baseLength);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Numeric suffixes can push finalName over maxLength in the collision path. When counter >= 10, baseName.length remains maxLength - 1, so baseName + counter exceeds the limit.

Consider computing the suffix length first and truncating the base accordingly (e.g., derive allowedBaseLength = maxLength - String(counter).length) inside the uniqueness loop so the final name never exceeds maxLength.

-       const baseName = name.slice(0, baseLength);
-       let counter = 1;
-
-       while (usedNames.has(baseName + counter)) {
-         counter++;
-       }
-
-       const finalName = baseName + counter;
+       let counter = 1;
+       let finalName = "";
+       while (true) {
+         const suffix = String(counter);
+         const allowedBaseLength = Math.max(0, maxLength - suffix.length);
+         const baseName = name.slice(0, allowedBaseLength);
+         finalName = baseName + suffix;
+         if (!usedNames.has(finalName)) {
+           break;
+         }
+         counter++;
+       }

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.


async function postprocess() {
for await (const file of walk(distDir)) {
if (!/(\.d)?[cm]?ts$/.test(file)) continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file filter regex /(\.d)?[cm]?ts$/ doesn’t match *.d.mts or *.d.cts because it expects .d directly before mts/cts with no dot. This means .d.mts and .d.cts files are skipped and their /// <reference ...> lines aren’t stripped.

Consider updating the pattern to allow an extra dot after .d, e.g., /(?:\.d\.)?[cm]?ts$/, so .ts, .cts, .mts, .d.ts, .d.cts, and .d.mts are all covered consistently.

-    if (!/(\.d)?[cm]?ts$/.test(file)) continue;
+    if (!/(?:\.d\.)?[cm]?ts$/.test(file)) continue;

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

@stainless-app

stainless-app Bot commented Oct 31, 2025

Copy link
Copy Markdown
Author

🧪 Testing

    To try out this version of the SDK, run:
    ```
    npm install 'https://pkg.stainless.com/s/terminal49-typescript/b4b3ebc63037fa340491805a0191f0677fe23870/dist.tar.gz'
    ```

    _Expires: Sat, 13 Dec 2025 05:49:15 GMT_

@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from a350415 to 19b0c56 Compare October 31, 2025 04:27
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from 19b0c56 to 491dde8 Compare November 4, 2025 06:24
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from 491dde8 to a65ff68 Compare November 4, 2025 06:29
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from a65ff68 to 742c8d3 Compare November 5, 2025 05:55
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from 742c8d3 to adc7c47 Compare November 5, 2025 05:58
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch 2 times, most recently from 21f6a0f to 5cf111f Compare November 6, 2025 06:15
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from 5cf111f to 366f934 Compare November 6, 2025 06:19
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from 366f934 to 9b8108d Compare November 8, 2025 11:37
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from 9b8108d to 446da42 Compare November 11, 2025 06:17
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from 446da42 to e663b58 Compare November 13, 2025 05:45
@stainless-app
stainless-app Bot force-pushed the release-please--branches--main--changes--next--components--terminal49 branch from e663b58 to b96186f Compare November 13, 2025 05:48
@dodeja dodeja closed this Nov 23, 2025
@dodeja
dodeja deleted the release-please--branches--main--changes--next--components--terminal49 branch November 23, 2025 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant