Skip to content

Feature: File Statistics Toggle & File Size fix#332

Open
Mistralys wants to merge 2 commits into
context-hub:mainfrom
Mistralys:feature-file-stat-toggle
Open

Feature: File Statistics Toggle & File Size fix#332
Mistralys wants to merge 2 commits into
context-hub:mainfrom
Mistralys:feature-file-stat-toggle

Conversation

@Mistralys
Copy link
Copy Markdown

Hi, I've looking for a way to turn off the file statistics section in the generated documents, and thought to contribute this when I saw that there was none.

This PR adds a showFileStats boolean flag (default: true) that controls whether the auto-generated File Statistics section is appended to compiled documents. Can be set per-document or globally via settings.showFileStats. The per-document value always takes precedence.

Additionally, a discrepancy was fixed where file statistics were silently omitted on the first ctx generate' run because addFileStatistics() attempted to read stats from the output file before witing it to disk. This also had the effect to always count the previous file size, not the size of the new file being written. Stats are now computed directly from the in-memory content, making them accurate on every run.

Mistralys added 2 commits May 28, 2026 08:28
Introduces a \showFileStats\ boolean (default: true) on Document. Can be set
per-document or globally via \settings.showFileStats\; per-document always
wins. Implemented across the domain model, YAML parser, JSON schema, and
Markdown front-matter transformer. Includes full test coverage and docs.
Rewrites addFileStatistics() to compute byte count and line count directly
from the in-memory content string via strlen/substr_count, removing all disk
I/O. Stats are now accurate on the very first run. Also drops the redundant
post-write files->size() call from the success log.
@butschster butschster self-requested a review May 28, 2026 06:58
@butschster butschster self-assigned this May 28, 2026
@butschster butschster added type:enhancement New feature or request document:compiler Document transformation and output compilation source:file Local filesystem source support labels May 28, 2026
@Mistralys
Copy link
Copy Markdown
Author

Hi @butschster, I checked the CI error and it is unrelated to my changes. I had my agent look at the issue, here's a summary explaining what's going on - hoping it helps.


Issue Report for ctx/mcp-serverPromptConfigFactory::parseRole() silently accepts missing role

Package: ctx/mcp-server v1.7.2
File: src/Prompt/PromptConfigFactory.php
Method: parseRole()


What changed

In v1.7.2 the parseMessage() logic was refactored to extract a dedicated parseRole() helper. In that refactor the behaviour for a missing role key changed:

Before (correct behaviour, previously in the consuming project's local override):

if (!isset($messageConfig['role']) || !\is_string($messageConfig['role'])) {
    throw new PromptParsingException('Message must have a valid role');
}

After (current v1.7.2 behaviour):

private function parseRole(array $messageConfig): Role
{
    if (!isset($messageConfig['role'])) {
        return Role::User;   // ← silently defaults instead of rejecting
    }
    // ...
}

The docblock even documents this as intentional ("defaults to Role::User if not specified"), but it breaks the expected contract.


Why this is a problem

When role is missing, the factory should reject the message so the error bubbles up through PromptParserPlugin to ConfigParser, which catches it and omits the entire prompt from the registry. Silently defaulting to Role::User instead hides a configuration mistake and registers a prompt the user did not properly define.

The inconsistency is also asymmetric: a non-string role already throws (!\is_string check), and an invalid string role also throws (Role::tryFrom(...) ?? throw). Only a missing role is silently swallowed — which is the most common typo/omission.


Ideal fix

In parseRole(), treat a missing role the same as an invalid one:

/**
 * @param array<string, mixed> $messageConfig The message configuration.
 * @return Role The parsed role.
 *
 * @throws PromptParsingException If the role is missing or invalid.
 */
private function parseRole(array $messageConfig): Role
{
    if (!isset($messageConfig['role']) || !\is_string($messageConfig['role'])) {
        throw new PromptParsingException('Message must have a valid role');
    }

    return Role::tryFrom($messageConfig['role'])
        ?? throw new PromptParsingException(
            \sprintf('Invalid role "%s"', $messageConfig['role']),
        );
}

This restores the original behaviour: any message without an explicit role causes the containing prompt to be silently dropped from the registry (with a logged warning), rather than being registered with an assumed role the user never specified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

document:compiler Document transformation and output compilation source:file Local filesystem source support type:enhancement New feature or request

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants