BH3D Logo
Inline Intent

Inline Intent: Embedding Specifications Directly in Your Source Files

By Ben Houston, 2025-05-07

Intent-based development has proven valuable for separating what a system should do from how it's implemented. Until now, Declary has focused on standalone .intent.yaml files that live alongside your source code. But what if you could embed those specifications directly in your implementation files—just as React embeds components in JavaScript via JSX?

That's exactly what Inline Intent enables. This new capability lets you weave intent specifications directly into your source files, creating a fluid boundary between declarative intent and imperative code.

Why Embed Intent in Source?

While separate intent files provide clean separation, they create a context switch when working on closely related specifications and implementations. In many cases—particularly for complex algorithms, domain-specific logic, or performance-critical code—we need both:

  • High-level natural language descriptions of purpose and constraints
  • Precise, implementation-specific details that are difficult to capture in pure YAML

Inline Intent addresses this need by allowing you to define intent specifications exactly where the code should be generated, effectively turning pseudocode into actual implementation:

// src/utils/sorting.ts

export function optimizedSort<T>(
  array: T[],
  compareFn?: (a: T, b: T) => number
): T[] {
  /** @intent
   * A stable, adaptive merge sort implementation optimized for
   * partially sorted arrays. Should maintain O(n log n) worst-case
   * performance but approach O(n) for nearly-sorted data.
   *
   * This optimizes for both runtime performance and memory efficiency
   * on modern JavaScript engines.
   */
}

When you run declary generate, the comment block is interpreted as an intent specification, and the function implementation is regenerated.

The JSX Analogy

This approach is conceptually similar to how JSX works in React:

  • JSX lets you embed UI components directly in JavaScript/TypeScript
  • The transpiler converts this specialized syntax into standard function calls
  • This provides a more intuitive mental model where component definitions live with their usage

Similarly, Inline Intent:

  • Lets you embed intent specifications directly where the code should be generated
  • The Declary processor converts these pseudocode-like instructions into real implementations
  • The developer writes what amounts to structured comments that get automatically transformed into working code

Implementation Approaches

Declary supports multiple ways to define inline intent:

Comment-Based Intent

The simplest approach uses specially formatted comments:

/** @intent
 * builder: typescript/class
 * instructions: |
 *   A cache implementation using LRU (least recently used) eviction.
 *   Should support setting max item count and TTL (time to live).
 */
export class Cache<K, V> {
  // Implementation will be generated here
}

This works in any language without requiring special tools—just Declary's processor.

Language Extension (TSI/JSI)

For TypeScript and JavaScript, we've introduced .tsi and .jsi extensions (TypeScript/JavaScript with Intent), providing first-class syntax support:

// user-service.tsi
import { Database } from '../db';

export class UserService {
  constructor(private db: Database) {}

  intent {
    "User management service handling authentication, profiles, and permissions"
    concerns: ["logging", "error-handling", "input-validation"]
  }
}

Similar to how TypeScript/JavaScript handle JSX, this syntax provides better tooling support, syntax highlighting, and validation.

Python Intent (PYI)

For Python codebases, we've created a .pyi extension supporting a similar pattern:

# recommender.pyi
import numpy as np

def recommend(user_id, item_matrix, n_recommendations=5):
    """@intent
    A collaborative filtering recommendation algorithm using matrix factorization.
    Should handle sparse input matrices efficiently and support incremental updates.
    Must maintain sub-quadratic performance characteristics.
    """

This approach is syntactically compatible with standard Python, requiring minimal tooling changes.

When to Use Inline Intent

Inline Intent shines in several scenarios:

Complex Algorithmic Requirements

When algorithms have nuanced requirements difficult to express in pure YAML:

Algorithm as Pseudocode

Here's an example showing how you can write an entire algorithm in pseudocode form using intent comments:

// minimax.ts
export function minimax(
  node: GameNode,
  depth: number,
  isMaximizingPlayer: boolean
): number {
  /** @intent
   * Base case: if we've reached a terminal node or maximum depth
   * return the evaluation score for this node
   */
  /** @intent
   * If maximizing player:
   *   Set maxEval to negative infinity
   *   For each child of the node:
   *     Recursively evaluate child with minimax(child, depth-1, false)
   *     Update maxEval with maximum of current maxEval and the child evaluation
   *   Return maxEval
   */
  /** @intent
   * If minimizing player:
   *   Set minEval to positive infinity
   *   For each child of the node:
   *     Recursively evaluate child with minimax(child, depth-1, true)
   *     Update minEval with minimum of current minEval and the child evaluation
   *   Return minEval
   */
}

When processed by Declary, these intent comments are transformed into a complete, working implementation:

// Generated output:
export function minimax(
  node: GameNode,
  depth: number,
  isMaximizingPlayer: boolean
): number {
  // Base case: if we've reached a terminal node or maximum depth
  if (depth === 0 || node.isTerminal()) {
    return node.evaluate();
  }

  // If maximizing player
  if (isMaximizingPlayer) {
    let maxEval = -Infinity;
    for (const child of node.children) {
      const eval = minimax(child, depth - 1, false);
      maxEval = Math.max(maxEval, eval);
    }
    return maxEval;
  }
  // If minimizing player
  else {
    let minEval = Infinity;
    for (const child of node.children) {
      const eval = minimax(child, depth - 1, true);
      minEval = Math.min(minEval, eval);
    }
    return minEval;
  }
}

Gradual Migration

When incrementally adopting intent-based development in existing codebases:

Another Example: Multi-Step Algorithm Using Line-by-Line Intent

For algorithms that require step-by-step processing, you can use intent comments at each logical step:

# quick_sort.py
def quick_sort(arr, low, high):
    """@intent
    Implementation of the quicksort algorithm with the following characteristics:
    - Uses the Hoare partition scheme
    - Selects pivot using median-of-three method to avoid worst-case on already sorted arrays
    - Falls back to insertion sort for small partitions (less than 10 elements)
    """

    # @intent Check if the partition is small enough for insertion sort

    # @intent Select pivot using median-of-three

    # @intent Partition the array around the pivot

    # @intent Recursively sort the left partition

    # @intent Recursively sort the right partition

This approach provides complete freedom to structure your intent at the appropriate level of abstraction - whether that's describing an entire algorithm, outlining logical blocks, or detailing specific implementation steps.

Mixed Intent/Implementation

When some parts need intent-based generation while others require hand-crafting:

Enhanced Intent Directives: @builder and @concerns

To provide more precise control over code generation, inline intent supports specialized directives that can be included within the comment blocks:

/** @intent
 * @builder react/component
 * @concerns responsive theming accessibility
 * A dropdown menu component that displays a list of options when clicked.
 * Should support keyboard navigation, screen readers, and custom styling.
 */
function Dropdown({ options, defaultValue, onChange }) {
  // [CODEGEN] will be generated here
}

Available Directives

  • @builder - Specifies which code generator to use (e.g., react/component, typescript/validator, sql/query)
  • @concerns - Lists cross-cutting concerns to apply (e.g., responsive, authentication, logging)

These directives can be used with any of the intent styles we've discussed:

With Comment-Based Intent

function calculateTaxes(income: number, location: string): TaxResult {
  /** @intent
   * @builder finance/tax-calculator
   * @concerns logging validation
   * Calculate income taxes based on jurisdiction and income brackets.
   * For US locations, apply federal, state and local tax rates.
   * For international locations, apply country-specific tax treaties.
   */
}

With Tilde Syntax

export function generateReport(data: DataSet, format: ReportFormat): Report {
  ~@builder reporting/generator
  @concerns pagination caching
  Generate a financial report from the dataset with configurable sections.
  Include summary statistics, trend analysis, and visualizations.
  Format according to the specified output type (PDF, Excel, HTML).~
}

In Immediate Mode

// api-endpoints.ts
export async function getUserProfile(userId: string): Promise<UserProfile> {
  /** @intent
   * @builder api/endpoint
   * @concerns authentication rate-limiting
   * Fetch user profile information from the database.
   * Include basic info, preferences, and activity history.
   * Ensure proper access control checks before returning data.
   */

  // [CODEGEN:START] - Generated from @intent above
  const authResult = await checkAuthorization(userId);
  if (!authResult.isAuthorized) {
    throw new UnauthorizedError('Not authorized to view this profile');
  }

  await rateLimiter.check('user-profile', userId);

  const user = await db.users.findOne({ id: userId });
  if (!user) {
    throw new NotFoundError('User not found');
  }

  const activities = await db.activities
    .find({ userId })
    .sort({ date: -1 })
    .limit(10);
  const preferences = await db.preferences.findOne({ userId });

  return {
    id: user.id,
    name: user.name,
    email: user.email,
    profilePicture: user.profilePicture,
    joinDate: user.createdAt,
    preferences: preferences || {},
    recentActivity: activities
  };
  // [CODEGEN:END]
}

Multiple Intents in a Single File

With these directives, you can now include multiple intents within a single file, each with its own builder and concerns:

// user-service.ts

/** @intent
 * @builder typescript/service
 * @concerns logging error-handling
 * Service for managing user accounts and authentication.
 */
export class UserService {
  constructor(private db: Database) {}

  /** @intent
   * @builder typescript/method
   * @concerns validation security
   * Create a new user account with the provided details.
   * Hash password before storage, validate email format,
   * and ensure username uniqueness.
   */
  async createUser(
    username: string,
    email: string,
    password: string
  ): Promise<User> {
    // [CODEGEN] will be generated here
  }

  /** @intent
   * @builder typescript/method
   * @concerns security audit-logging
   * Authenticate a user with email/password and return a session token.
   * Track login attempts and implement lockout after failed attempts.
   */
  async login(email: string, password: string): Promise<AuthResult> {
    // [CODEGEN] will be generated here
  }

  /** @intent
   * @builder typescript/method
   * @concerns caching pagination
   * Retrieve a list of users matching the search criteria.
   * Support filtering, sorting, and pagination options.
   */
  async findUsers(
    criteria: UserSearchCriteria
  ): Promise<PaginatedResult<User>> {
    // [CODEGEN] will be generated here
  }
}

This enables a highly modular approach where each function, method, or component can have its own specialized intent, while still maintaining the overall cohesion of the file.

SQL Generation Example

Intent-based generation works particularly well for database queries:

function getUserAnalytics(userId: string, startDate: Date, endDate: Date) {
  const sql =
    /* @intent
    @builder sql/query
    @concerns performance security
    Generate a SQL query that retrieves user analytics data.
    Include total sessions, average session duration, pages viewed,
    and conversion events. Group by date for the specified date range.
    Ensure proper parameter sanitization and index usage.
  */

    // [CODEGEN:START]
    `
  SELECT 
    DATE(session_start) as date,
    COUNT(DISTINCT session_id) as total_sessions,
    AVG(TIMESTAMPDIFF(SECOND, session_start, session_end)) as avg_duration,
    SUM(pages_viewed) as total_pages,
    SUM(CASE WHEN event_type = 'conversion' THEN 1 ELSE 0 END) as conversions
  FROM 
    user_analytics
  WHERE 
    user_id = ? 
    AND session_start >= ?
    AND session_start <= ?
  GROUP BY 
    DATE(session_start)
  ORDER BY 
    DATE(session_start) ASC
  `;
  // [CODEGEN:END]

  return db.query(sql, [userId, startDate, endDate]);
}

API Route Generation

Similarly, framework-specific route handlers can be generated:

// routes.ts

/** @intent
 * @builder express/route
 * @concerns validation authentication
 * POST endpoint to create a new order.
 * Validate product availability and user payment details.
 * Return the created order with status and tracking information.
 */
app.post('/api/orders', async (req, res) => {
  // [CODEGEN] will be generated here
});

By combining multiple specialized intents in a single file, each with its own builder and concerns, Declary can now support a much more flexible and granular approach to intent-based development.

Processing and Generation Flow

The workflow with Inline Intent is straightforward:

  1. Write or modify intent specifications directly in source files
  2. Run declary generate to process the codebase
  3. Declary identifies inline intent blocks and passes them to appropriate builders
  4. Generated code replaces placeholder implementations or previous generations
  5. Version control tracks both the intent specifications and the resulting implementations

For .tsi/.jsi/.pyi files, an additional transpilation step generates standard .ts/.js/.py files, similar to how JSX processing works.

Benefits of Inline Intent

This approach offers several advantages:

Reduced Context Switching

Developers can define both what and how in a single file, reducing the cognitive load of switching between separate specification and implementation files.

Finer-Grained Control

You can apply intent-based generation selectively—just the parts that benefit from it—while keeping hand-crafted code where needed.

Easier Collaboration

Code reviews capture both intent changes and implementation changes in a single diff, making it easier to understand and validate modifications.

Familiar Mental Model

Developers already familiar with JSX/TSX will find the syntax patterns intuitive, flattening the learning curve.

Stronger Implementation/Intent Coupling

The physical proximity of intent to code encourages keeping them in sync, reducing the risk of drift over time.

Real-World Example: API Endpoint

Here's a practical example showing how Inline Intent works for an API endpoint:

// user-controller.tsi
import { Request, Response } from 'express';
import { UserService } from '../services';

export class UserController {
  constructor(private userService: UserService) {
    /** @intent
     * Controller handling user account operations
     * concerns: ["auth", "rate-limiting", "validation"]
     */
  }

  async createUser(req: Request, res: Response) {
    /** @intent
     * method: POST
     * route: "/users"
     * Creates a new user account
     * validation: {
     *   email: "required|email",
     *   password: "required|min:8",
     *   name: "required|string"
     * }
     * responses: {
     *   201: "User created successfully",
     *   400: "Invalid input",
     *   409: "Email already exists"
     * }
     */
  }

  // More endpoints...
}

When processed, this generates fully implemented controller methods with appropriate validation, error handling, and service calls.

Conclusion: Intent Everywhere

Inline Intent represents an evolution in Declary's approach to intent-based development. Rather than forcing an all-or-nothing choice between separate intent files and traditional code, it enables a flexible spectrum where you can apply intent-based principles precisely where they add the most value.

By bringing intent specifications directly into your source files, Declary becomes even more adaptable to your existing workflows and codebases. The result is a development model that truly fits how real teams work: pragmatically, incrementally, and with an eye toward both immediate productivity and long-term maintainability.

Whether you're building new features or gradually refactoring legacy code, Inline Intent gives you a powerful new tool for expressing not just what your code does, but why it exists.