File tagging — annotate project files and inject them into a chat

Overview

A user can attach tags to files inside a project. When a chat is sent, every tagged file is included in the upstream request as a synthetic message carrying the file's content (or a path/line-range excerpt) and the tags that pulled it in. Tags live in <projectDir>/.mouaif.json so the user can commit them with the project and edit them by hand. The picker is mobile-first: a list of files, a per-file tag chip strip, and an "Include in chat" toggle.

Usage

Tagging a file

From the project card's options menu or Settings → This project → File tags, the user opens File tags and sees every scanned project file. Each row shows the file name prominently and its project-relative folder underneath; root files show Project root. Binary files are labeled and cannot be newly tagged.

In a chat

When the user sends a message, the server pre-appends the tagged files to the upstream messages array, before the user's history. The shape of each injected message is:

{
  role: 'system',                     // or 'user' if the user explicitly @-referenced the file
  content:
    '# File: src/api/users.js\n' +
    '# Tags: api, auth\n' +
    '# Excerpt: 1-120\n' +
    '\n' +
    '<file contents or excerpt>'
}

The leading header block lets the model reason about provenance. The role is system by default (the tagged files are project context); when the user types @src/api/users.js in the composer, the role is user so the model treats it as a direct reference.

A bare basename mention — @users.js instead of the full path — is also accepted. parseReferences resolves it against the tagged map first and the on-disk scan second, so @users.js promotes src/api/users.js when that basename is unambiguous (an ambiguous basename resolves to the shortest path rather than being dropped, and a mention with no match at all is silently ignored).

Behavior