Teams App Developer
MicrosoftOfficialPublished by Microsoft
- Skill
- Tool integration
- Software development
- MIT
- Medium risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The teams-app-developer skill provides a structured framework for managing the lifecycle of Microsoft 365 agents and Teams applications. It leverages the ATK CLI to handle project scaffolding, local testing via the Agents Playground, cloud provisioning on Azure, and troubleshooting. The skill includes specialized guidance for migrating Slack bots to Teams, including converting Block Kit UI to Adaptive Cards, and provides access to an extensive library of micro-expert documentation for cross-platform development.
What it does
- Scaffolds new Microsoft 365 agents and Teams applications from templates.
- Facilitates local testing using the Agents Playground or Teams-specific environments.
- Automates Azure resource provisioning and cloud deployment workflows.
- Provides diagnostic procedures for common authentication and configuration errors.
- Supports migration of Slack bots to the Teams platform.
- Manages project configuration and environment variables for ATK-based projects.
When to use it
- When starting a new Teams app, bot, or Declarative Agent project.
- When you need to test an agent locally before deploying to the cloud.
- When migrating existing Slack bots to the Microsoft Teams ecosystem.
- When troubleshooting deployment or authentication issues in a Teams project.
- When you need to provision Azure infrastructure for a Teams application.
Advantages
- Streamlines the development lifecycle with standardized CLI commands.
- Reduces development time by offering a local testing playground.
- Provides expert-level guidance for complex cross-platform migrations.
- Ensures consistent configuration management across development environments.
- Includes robust error-handling protocols for common platform-specific pitfalls.
Usage examples
- “Create a new Teams bot project using the default template.”
- The agent will initialize a new project folder, configure the necessary YAML files, and guide you through the initial setup using the ATK CLI.
- “How do I migrate my Slack bot to Microsoft Teams?”
- The agent will initiate the slack-to-teams workflow, providing access to cross-platform bridging experts and guidance on converting UI components.
- “My Teams bot is returning a 401 error, how do I fix it?”
- The agent will trigger the troubleshooting workflow, checking your environment variables, tunnel status, and authentication configuration.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/teams-app-developer/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip teams-app-developer.zip -d .agents/skills
Documentation by Microsoft
Microsoft 365 Agents Toolkit Skill
Build Microsoft 365 agents and Teams apps using the ATK CLI.
AI Behavior Guidelines
Testing Strategy: Recommend Agents Playground first (faster, no M365 needed). Use Teams workflow only if user explicitly requests it.
Environment Variables: NEVER hardcode secrets or make up placeholder values. Always ask users for real values.
Error Handling: Read error messages carefully. Check
env/.env.local,.localConfigs, andatk auth list. Common pitfalls:AADSTS7000229→aadApp/createmissinggenerateServicePrincipal: truein YAML — add it and re-provisionMissing
TENANT_IDin.localConfigs→ SDK uses wrong token authority → 401 from Bot Connector401 persists after auth fix → devtunnel URL may be blacklisted — create a fresh tunnel
See troubleshoot/troubleshoot.md for full diagnostic steps
Long-Running Commands — WAIT for completion:
atk new,atk provision,atk deploycan take several minutesAlways wait for completion before running the next step (timeout 120000ms+)
Local Service Startup — Hangs terminal (expected):
npm run dev,npm start,python app.py,devtunnel host, etc. will hang — the process keeps running indefinitelyALWAYS run as a background process (
isBackground=true) — NEVER useisBackground=falsefor these commandsDo NOT wait for it to "finish" — verify startup by checking output for "listening on port" or tunnel URL
If errors appear, read logs, diagnose, fix, restart
Use a NEW terminal to launch Agents Playground or open Teams sideloading URL
Monitor App Logs: Periodically check background terminal output for runtime errors. If the app crashes, read the error, fix the root cause, and restart.
Telemetry Tagging: Before running any
atkCLI commands, set the session environment variable so all CLI invocations are tagged as skill-initiated:export ATK_CLI_SKILL=trueRun this once at the start of the session. All subsequent
atkcommands in the same terminal will inherit it.
ATK CLI Setup
atk --version # Must be > 1.1.5-betaIf ATK is not found or version is too old:
npm i -g @microsoft/m365agentstoolkit-cli@betaCLI Global Options
| Option | Meaning | Recommendation |
|---|---|---|
-i | Interactive mode | Always use -i false in automation to avoid hanging |
-f | Project folder | Default to be current directory, used when specifying a custom folder. When scaffolding a new project, this is the parent folder where the project folder will be created under. |
-h | Command help | Use atk <command> -h for quick syntax checks |
Sub-Skills
| Sub-Skill | When to Use | Reference |
|---|---|---|
| create-project | Scaffold new project from template, choose template, atk new | create-project/create-project.md |
| test-playground | Test locally with Agents Playground, agentsplayground, quick testing | test-playground/test-playground.md |
| test-teams | Run on Teams, devtunnel, sideload, Teams testing, test in Copilot | test-teams/test-teams.md |
| provision-deploy | Provision Azure resources, deploy to cloud, atk provision, atk deploy | provision-deploy/provision-deploy.md |
| troubleshoot | Fix errors, 401, port conflicts, YAML errors, stale bots | troubleshoot/troubleshoot.md |
| slack-to-teams | Migrate Slack bot to Teams, cross-platform bridging, Block Kit to Adaptive Cards | slack-to-teams/SKILL.md |
MANDATORY: Before executing any workflow, read the corresponding sub-skill document.
Shared References
manifest-and-yaml.md — Project files, YAML config, env vars, .localConfigs flow
commands.md — ATK CLI commands: package, validate, share, collaborate
templates.md — Complete template catalog with language support
experts/ — 100+ micro-expert files: Teams SDK, Slack SDK, cross-platform bridging, deploy, AI models, security, language conversion
docs/ — Platform comparison guides: UI, messaging, identity, infrastructure, feature gaps
Workflow Chains
Match user intent to the smallest valid workflow.
| User Intent | Workflow (read in order) |
|---|---|
| Build new app from scratch | create-project → test-playground |
| Test existing project locally | test-playground (recommended) or test-teams |
| Deploy to Azure | provision-deploy |
| Fix broken bot | troubleshoot → re-test |
| Migrate Slack bot to Teams | slack-to-teams |
MANDATORY: Before executing any slack-to-teams workflow, read slack-to-teams/SKILL.md first. The sub-skill contains a routed expert system with 100+ micro-expert files for cross-platform bot development.
ATK Project Context Resolution
Resolve config values only when missing. If a value is already known in the session, reuse it.
Step 1: Detect ATK Project
If m365agentstoolkit*.yml exists in the current folder, treat it as an ATK project and parse configuration.
Step 2: Resolve Common Configuration
Resolve variables referenced in m365agentstoolkit*.yml. Common variables:
AZURE_OPENAI_API_KEY
AZURE_OPENAI_ENDPOINT
AZURE_OPENAI_DEPLOYMENT_NAME
Step 3: Collect Missing Values
If required values are missing, ask the user for only the missing ones.
Refer to manifest-and-yaml.md for full config-file details.
Files
- ATTRIBUTION.mdAdded by AutoGineer906 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md7.6 KiB
- create-project/create-project.md8.1 KiB
- docs/README.md2.8 KiB
- docs/advanced-features.md7.0 KiB
- docs/feature-gaps.md46.3 KiB
- docs/files-and-links.md4.2 KiB
- docs/identity-and-auth.md4.3 KiB
- docs/infrastructure.md6.7 KiB
- docs/interactive-responses.md4.4 KiB
- docs/messaging-and-commands.md4.5 KiB
- docs/middleware-and-handlers.md4.4 KiB
- docs/ui-components.md6.9 KiB
- docs/workflows.md14.4 KiB
- experts/README.md8.6 KiB
- experts/_expert-ts.md2.2 KiB
- experts/analyzer.md14.0 KiB
- experts/bridge/app-distribution-packaging-ts.md14.2 KiB
- experts/bridge/channel-ops-graph-ts.md15.4 KiB
- experts/bridge/commands-slash-text-ts.md18.5 KiB
- experts/bridge/cross-platform-advisor-ts.md36.4 KiB
- experts/bridge/cross-platform-architecture-ts.md8.3 KiB
- experts/bridge/events-activities-ts.md22.4 KiB
- experts/bridge/files-upload-download-ts.md17.2 KiB
- experts/bridge/identity-oauth-bridge-ts.md19.8 KiB
- experts/bridge/index.md13.0 KiB
- experts/bridge/infra-compute-ts.md14.6 KiB
- experts/bridge/infra-observability-ts.md14.0 KiB
- experts/bridge/infra-secrets-config-ts.md13.2 KiB
- experts/bridge/infra-storage-ts.md14.3 KiB
- experts/bridge/interactive-responses-ts.md19.6 KiB
- experts/bridge/link-unfurl-preview-ts.md17.1 KiB
- experts/bridge/middleware-handlers-ts.md15.4 KiB
- experts/bridge/python-cross-platform.md9.3 KiB
- experts/bridge/rate-limiting-resilience-ts.md17.6 KiB
- experts/bridge/rest-only-integration-ts.md8.4 KiB
- experts/bridge/scheduling-deferred-send-ts.md17.8 KiB
- experts/bridge/shortcuts-extensions-ts.md17.5 KiB
- experts/bridge/transport-socketmode-https-ts.md14.3 KiB
- experts/bridge/ui-app-home-personal-tab-ts.md14.5 KiB
- experts/bridge/ui-block-kit-adaptive-cards-ts.md21.5 KiB
- experts/bridge/ui-legacy-attachments-cards-ts.md11.2 KiB
- experts/bridge/ui-modals-dialogs-ts.md21.4 KiB
- experts/bridge/workflow.composable-platform-ts.md13.7 KiB
- experts/bridge/workflows-automation-ts.md14.3 KiB
- experts/builder.md11.1 KiB
- experts/convert/bulk-conversion-strategy-ts.md12.8 KiB
- experts/convert/dependency-mapping-ts.md8.3 KiB
- experts/convert/index.md3.5 KiB
- experts/convert/java-to-ts-ts.md20.6 KiB
- experts/convert/js-to-ts-ts.md6.2 KiB
- experts/convert/json-serialization-ts.md11.0 KiB
- experts/convert/kotlin-to-ts-ts.md11.2 KiB
- experts/convert/ruby-to-ts-ts.md9.7 KiB
- experts/convert/type-mapping-ts.md10.1 KiB
- experts/deploy/aws-bot-deploy-ts.md14.6 KiB
- experts/deploy/aws-cli-reference-ts.md52.4 KiB
- experts/deploy/azure-bot-deploy-ts.md15.4 KiB
- experts/deploy/azure-cli-reference-ts.md16.9 KiB
- experts/deploy/index.md4.6 KiB
- experts/fallback.md2.1 KiB
- experts/index.md18.9 KiB
- experts/models/anthropic-ts.md7.8 KiB
- experts/models/bedrock-ts.md9.9 KiB
- experts/models/foundry-cloud-ts.md8.1 KiB
- experts/models/foundry-local-ts.md10.6 KiB
- experts/models/index.md5.8 KiB
- experts/models/openai-azure-openai-ts.md8.3 KiB
- experts/models/oss-openai-compatible-ts.md10.7 KiB
- experts/models/transformers-js-ts.md11.6 KiB
- experts/prompt-engineer.md14.7 KiB
- experts/researcher.md2.8 KiB
- experts/security/index.md1.2 KiB
- experts/security/input-validation-ts.md13.8 KiB
- experts/security/secrets-ts.md13.9 KiB
- experts/slack/bolt-assistant-ts.md9.9 KiB
- experts/slack/bolt-events-ts.md9.3 KiB
- experts/slack/bolt-java.md8.9 KiB
- experts/slack/bolt-oauth-distribution-ts.md10.9 KiB
- experts/slack/bolt-python.md9.5 KiB
- experts/slack/cli.app-management.md7.9 KiB
- experts/slack/cli.datastore-env.md8.6 KiB
- experts/slack/cli.getting-started.md8.0 KiB
- experts/slack/cli.local-dev-deploy.md8.4 KiB
- experts/slack/cli.manifest-triggers.md9.9 KiB
- experts/slack/index.md8.9 KiB
- experts/slack/runtime.ack-rules-ts.md9.8 KiB
- experts/slack/runtime.bolt-foundations-ts.md10.7 KiB
- experts/slack/runtime.shortcuts-ts.md11.0 KiB
- experts/slack/runtime.slash-commands-ts.md11.6 KiB
- experts/slack/runtime.socket-mode-ts.md9.5 KiB
- experts/slack/ui.block-kit-ts.md11.5 KiB
- experts/slack/ui.modals-lifecycle-ts.md13.3 KiB
- experts/slack/web-api-proactive-ts.md11.0 KiB
- experts/slack/workflow.slack-automations-ts.md10.2 KiB
- experts/teams/a2a.client-basics-ts.md9.7 KiB
- experts/teams/a2a.orchestrator-patterns-ts.md12.7 KiB
- experts/teams/a2a.server-basics-ts.md11.4 KiB
- experts/teams/ai.chatprompt-basics-ts.md8.1 KiB
- experts/teams/ai.citations-feedback-ts.md6.9 KiB
- experts/teams/ai.conversational-query-ts.md14.2 KiB
- experts/teams/ai.function-calling-design-ts.md9.0 KiB
- experts/teams/ai.function-calling-implementation-ts.md7.7 KiB
- experts/teams/ai.memory-localmemory-ts.md7.3 KiB
- experts/teams/ai.model-setup-ts.md6.6 KiB
- experts/teams/ai.rag-retrieval-ts.md7.4 KiB
- experts/teams/ai.rag-vectorstores-ts.md8.5 KiB
- experts/teams/ai.streaming-ts.md6.9 KiB
- experts/teams/auth.oauth-sso-ts.md10.1 KiB
- experts/teams/compat.botbuilder-interop-ts.md14.6 KiB
- experts/teams/dev.debug-test-ts.md14.1 KiB
- experts/teams/graph.usergraph-appgraph-ts.md9.0 KiB
- experts/teams/index.md9.8 KiB
- experts/teams/mcp.client-basics-ts.md9.5 KiB
- experts/teams/mcp.expose-chatprompt-tools-ts.md9.5 KiB
- experts/teams/mcp.security-ts.md10.4 KiB
- experts/teams/mcp.server-basics-ts.md9.9 KiB
- experts/teams/project.scaffold-files-ts.md12.2 KiB
- experts/teams/runtime.app-init-ts.md10.9 KiB
- experts/teams/runtime.manifest-ts.md12.3 KiB
- experts/teams/runtime.proactive-messaging-ts.md12.6 KiB
- experts/teams/runtime.routing-handlers-ts.md12.3 KiB
- experts/teams/state.storage-patterns-ts.md9.4 KiB
- experts/teams/teams-dotnet.md8.2 KiB
- experts/teams/teams-python.md8.3 KiB
- experts/teams/ui.adaptive-cards-ts.md12.9 KiB
- experts/teams/ui.dialogs-task-modules-ts.md15.1 KiB
- experts/teams/ui.message-extensions-ts.md15.6 KiB
- experts/teams/workflow.approvals-inline-ts.md12.4 KiB
- experts/teams/workflow.message-native-records-ts.md10.6 KiB
- experts/teams/workflow.sharepoint-lists-ts.md9.0 KiB
- experts/teams/workflow.state-driven-events-ts.md12.2 KiB
- experts/teams/workflow.triggers-compose-ts.md10.3 KiB
- experts/update-experts.md10.0 KiB
- provision-deploy/provision-deploy.md4.3 KiB
- test-playground/playground-cli.md4.6 KiB
- test-playground/playground.md4.5 KiB
- test-playground/test-playground.md1.1 KiB
- test-teams/test-teams.md4.9 KiB
- toolkit/README.md4.2 KiB
- toolkit/commands.md2.6 KiB
- toolkit/environments.md12.6 KiB
- toolkit/lifecycle-cli.md17.6 KiB
- toolkit/manifest-and-yaml.md6.0 KiB
- toolkit/playground.md7.6 KiB
- toolkit/publish.md9.3 KiB
- toolkit/templates.md6.7 KiB
- troubleshoot/troubleshoot.md20.2 KiB
experts/convert/bulk-conversion-strategy-ts.md
bulk-conversion-strategy-ts
purpose
Strategy and workflow for large-scale code conversion — converting 100+ source files (Java POJOs, Ruby classes, JS modules) to TypeScript efficiently with prioritized phases, incremental validation, and tooling.
rules
Never attempt a big-bang conversion. Convert in phases, ensuring each phase compiles and passes tests before proceeding. A half-converted project that compiles is infinitely better than a fully-converted project that doesn't.
Phase order: Models → Utilities → Core logic → Handlers → Entry point. Convert bottom-up through the dependency graph. Models have no internal dependencies, so they convert first. Entry points depend on everything, so they convert last.
Prioritize by dependency count. Run a dependency analysis: files imported by many others convert first (high fan-in). Files that import many others convert last (high fan-out). This minimizes the number of temporary
anyshims.Use TypeScript's
allowJs: trueduring transition. This lets.tsfiles coexist with unconverted.jsfiles. SetcheckJs: falseto avoid type-checking JS files. RemoveallowJsonly when 100% of files are converted.Create a
@types/source-projectdeclarations file for unconverted modules. As you convert models first, other unconverted files may still import them. A.d.tsshim keeps the compiler happy during the transition.Batch similar files. Group files by pattern (all Lombok
@DataPOJOs, all event handlers, all middleware) and convert each group in one pass. This builds muscle memory and ensures consistency.Validate each batch immediately. After converting a batch: (1)
tsc --noEmitto check types, (2) run relevant tests, (3) commit. Do not accumulate unconverted batches.Track progress with a conversion manifest. Maintain a simple JSON or markdown file listing every source file, its status (pending/in-progress/done/skipped), target TS file, and notes. This prevents duplicate work and makes progress visible.
Handle the 80/20 rule. ~80% of files in a Java project are simple POJOs/models that convert mechanically. ~20% contain complex logic (middleware, async chains, polymorphic factories) that need careful manual conversion. Identify the 20% early and plan extra time.
Establish naming conventions before starting. Decide once: snake_case API fields stay snake_case or become camelCase? One file per class (Java-style) or group by feature (TS-style)? Barrel exports or direct imports? Document in the conversion manifest.
Write adapter/shim layers for incremental testing. If the source project has integration tests, create thin adapter layers so converted TS modules can be called from unconverted test harnesses (or vice versa) during transition.
Delete source files after conversion, don't keep both. Having
User.javaandUser.tsside by side causes confusion. OnceUser.tscompiles and tests pass, deleteUser.java. The git history preserves the original.
interview
Q1 — Naming Conventions
question: "How should internal field names be cased in the converted TypeScript code?"
header: "Field casing"
options:
- label: "camelCase (Recommended)"
description: "Convert all internal fields to camelCase (standard TS convention). Wire-format fields (API JSON) keep their original casing via serialization mapping."
- label: "Keep original casing"
description: "Preserve snake_case/PascalCase from the source language as-is. Fewer changes but non-idiomatic TS."
- label: "You Decide Everything"
description: "Accept recommended defaults for all decisions and skip remaining questions."
multiSelect: falseQ2 — File Organization
question: "How should converted files be organized?"
header: "File layout"
options:
- label: "Group by feature (Recommended)"
description: "Organize files by feature/module (TS-style). Related types, handlers, and utilities live together."
- label: "One file per class"
description: "Keep the source language's structure (e.g., Java's one-class-per-file). Familiar but can lead to many small files."
multiSelect: falseQ3 — Export Style
question: "How should modules be exported?"
header: "Exports"
options:
- label: "Barrel exports (Recommended)"
description: "Each directory gets an index.ts re-exporting its public API. Cleaner imports for consumers."
- label: "Direct imports only"
description: "Import directly from each file path. No barrel files. Simpler but more verbose import paths."
multiSelect: falseQ4 — Conversion Scope
question: "Should we convert everything, or focus on specific modules first?"
header: "Scope"
options:
- label: "Full project (phased)"
description: "Convert the entire project in dependency order (models -> utils -> core -> handlers -> entry). Recommended for clean breaks."
- label: "Critical path only"
description: "Convert only the modules needed for the current feature/migration. Remaining modules use .d.ts shims."
- label: "Models + utilities only"
description: "Convert data models and shared utilities. Keep handlers/entry points in source language with interop layer."
multiSelect: falsedefaults table
| Question | Default |
|---|---|
| Q1 | camelCase for internal, preserve wire-format |
| Q2 | Group by feature |
| Q3 | Barrel exports |
| Q4 | Full project (phased) |
patterns
Conversion manifest tracking file
# Conversion Manifest — java-slack-sdk
## Conventions
- API wire-format fields: keep snake_case
- Internal fields: camelCase
- One interface per model file (may group related types)
- Barrel exports via index.ts per directory
## Phase 1: Models (200 files)
| Source File | Status | Target File | Notes |
|---|---|---|---|
| model/block/SectionBlock.java | done | src/models/blocks/section-block.ts | |
| model/block/ActionsBlock.java | done | src/models/blocks/actions-block.ts | |
| model/block/DividerBlock.java | done | src/models/blocks/divider-block.ts | |
| model/event/AppMentionEvent.java | in-progress | src/models/events/app-mention-event.ts | Has nested types |
| model/event/MessageEvent.java | pending | src/models/events/message-event.ts | |
| ... | | | |
## Phase 2: Utilities (15 files)
| Source File | Status | Target File | Notes |
|---|---|---|---|
## Phase 3: Core Services (30 files)
| Source File | Status | Target File | Notes |
|---|---|---|---|
## Phase 4: Handlers (40 files)
| Source File | Status | Target File | Notes |
|---|---|---|---|
## Phase 5: Entry Points (5 files)
| Source File | Status | Target File | Notes |
|---|---|---|---|Dependency graph analysis for prioritization
// Script to analyze Java import graph and determine conversion order
import { readFileSync, readdirSync } from 'fs';
import { join, relative } from 'path';
interface FileNode {
path: string;
imports: string[]; // files this file imports
importedBy: string[]; // files that import this file (fan-in)
}
function analyzeJavaImports(srcDir: string): FileNode[] {
const files: Map<string, FileNode> = new Map();
// Scan all .java files
function scan(dir: string) {
for (const entry of readdirSync(dir, { withFileTypes: true })) {
const fullPath = join(dir, entry.name);
if (entry.isDirectory()) {
scan(fullPath);
} else if (entry.name.endsWith('.java')) {
const rel = relative(srcDir, fullPath);
const content = readFileSync(fullPath, 'utf-8');
const imports = [...content.matchAll(/^import\s+([\w.]+);/gm)]
.map((m) => m[1].replace(/\./g, '/') + '.java');
files.set(rel, { path: rel, imports, importedBy: [] });
}
}
}
scan(srcDir);
// Build reverse dependency map (fan-in)
for (const [path, node] of files) {
for (const imp of node.imports) {
const target = files.get(imp);
if (target) {
target.importedBy.push(path);
}
}
}
// Sort: highest fan-in first (most depended-on → convert first)
return [...files.values()].sort(
(a, b) => b.importedBy.length - a.importedBy.length,
);
}
// Usage:
const ordered = analyzeJavaImports('./java-slack-sdk/slack-api-model/src/main/java');
console.log('Convert in this order:');
ordered.slice(0, 20).forEach((f) =>
console.log(` ${f.path} (imported by ${f.importedBy.length} files)`),
);Batch conversion script for Lombok @Data POJOs
// Semi-automated: reads Java @Data class, outputs TS interface stub
function convertDataClass(javaSource: string): string {
const lines = javaSource.split('\n');
const className = lines
.find((l) => l.includes('class '))
?.match(/class\s+(\w+)/)?.[1] ?? 'Unknown';
const fields: { name: string; type: string; serializedName?: string }[] = [];
let serializedName: string | undefined;
for (const line of lines) {
const snMatch = line.match(/@SerializedName\("(\w+)"\)/);
if (snMatch) {
serializedName = snMatch[1];
continue;
}
const fieldMatch = line.match(
/private\s+(?:final\s+)?(\w+(?:<[\w<>,\s]+>)?)\s+(\w+)\s*;/,
);
if (fieldMatch) {
fields.push({
type: mapJavaType(fieldMatch[1]),
name: serializedName ?? fieldMatch[2],
serializedName,
});
serializedName = undefined;
}
}
const fieldLines = fields
.map((f) => ` ${f.name}: ${f.type};`)
.join('\n');
return `export interface ${className} {\n${fieldLines}\n}\n`;
}
function mapJavaType(javaType: string): string {
const map: Record<string, string> = {
String: 'string',
boolean: 'boolean',
Boolean: 'boolean',
int: 'number',
Integer: 'number',
long: 'number',
Long: 'number',
double: 'number',
Double: 'number',
float: 'number',
Float: 'number',
};
if (map[javaType]) return map[javaType];
if (javaType.startsWith('List<')) {
const inner = javaType.slice(5, -1);
return `${mapJavaType(inner)}[]`;
}
if (javaType.startsWith('Map<')) {
const [k, v] = javaType.slice(4, -1).split(',').map((s) => s.trim());
return `Record<${mapJavaType(k)}, ${mapJavaType(v)}>`;
}
return javaType; // Keep as-is for custom types (will need manual mapping)
}pitfalls
Converting everything before testing anything: The biggest risk. Convert 5 model files, compile, test, commit. Then the next 5. Never go more than ~20 files without validating.
Ignoring the dependency graph: Converting a handler before its model types exist forces you to use
anyeverywhere, creating tech debt you'll forget to clean up.Inconsistent naming conventions: If file 1 uses
threadTsand file 50 usesthread_tsfor the same field, you'll have runtime bugs. Establish and document conventions in the manifest BEFORE starting.Keeping source and target files: Having
User.javaanduser.tsin the repo simultaneously leads to confusion about which is authoritative. Delete the source after confirming the target works.Automating too much: Semi-automated scripts (like the POJO converter above) produce ~70% correct output. Always review and adjust. Fully automated conversion produces subtle type errors that are harder to find later.
Not tracking progress: After converting 50 of 200 files, it's easy to lose track of what's done. The manifest file is essential for multi-session conversion work.
Skipping the hard 20%: It's tempting to convert all easy POJOs and declare victory. The complex files (middleware, async chains, polymorphic factories) are where the real conversion effort lives. Plan them explicitly.
Breaking the build for days: Use
allowJs: trueto keep the project buildable throughout. If the project must stay deployable during conversion, maintain a working build at all times.
references
https://www.typescriptlang.org/tsconfig#allowJs -- allowJs for incremental migration
https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html -- official migration guide
https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html -- .d.ts files for shims
instructions
Use this expert when facing a large-scale conversion (50+ source files). Before converting any code, read this expert to establish the phase order, create a conversion manifest, and run dependency analysis. Pair with the appropriate language expert (java-to-ts-ts.md, ruby-to-ts-ts.md, or js-to-ts-ts.md) for per-file conversion rules, and json-serialization-ts.md for serialization-heavy model conversion.
research
Deep Research prompt:
"Write a micro expert for large-scale language conversion strategy (100+ files from Java/Ruby/JS to TypeScript). Cover: phased conversion order (models → utils → core → handlers → entry), dependency graph analysis for prioritization, conversion manifest tracking, batch processing patterns, allowJs incremental migration, naming convention decisions, validation checkpoints, and common failure modes in big conversions."
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an API key, Needs Python, Needs Node.js
Security
What our scanner noticed· Medium risk
- Possible data-exfiltration endpoints
- Instructions that use the network
- Downloads piped into a shell
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills · .github/plugins/microsoft-365-agents-toolkit/skills/teams-app-developer · commit 0696600
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download teams-app-developer.zip