Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,10 @@ $RECYCLE.BIN/

# Mac crap
.DS_Store

# Nia
/.nia/work
/.nia/context.toml
/.nia/logs
/.nia/.config_lock
/.nia/.config.lock
Empty file added .nia/.context.lock
Empty file.
64 changes: 64 additions & 0 deletions .nia/config/agents.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Generated by: nia config init --agent github_copilot --models balanced
# Generated at: 2026-08-31T12:16:30.307061+00:00
# Agent: github_copilot (GitHub Copilot CLI)
# Profile: balanced - Good performance at reasonable cost
#
# Model Selection Rationale:
# Model Tier Guide:
# - Default (gpt-5.4): Standard tier - balanced performance for most operations
# - issue.draft (gpt-5.5): Heavy/Reasoning tier - premium for user-facing output
# - issue.plan (gpt-5.5): Heavy/Reasoning tier - premium for strategic planning
# - issue.review (gpt-5.5): Heavy/Reasoning tier - premium for review quality
# - pr.review (gpt-5.5): Heavy/Reasoning tier - premium for PR assessment
# - pr.merge (gpt-5.5): Heavy/Reasoning tier - premium for high-risk operations

schema_version = "1.0.0"

[agent]
default = "github_copilot"

[agent.github_copilot]
model = "gpt-5.4"

[agent.github_copilot.operations]
"issue.review" = "gpt-5.5"
"issue.plan" = "gpt-5.5"
"pr.merge" = "gpt-5.5"
"pr.review" = "gpt-5.5"
"issue.draft" = "gpt-5.5"

# ============================================================================
# Commit Configuration (optional)
# ============================================================================
#
# Control which commands include commit instructions in their prompts.
# By default, commands that modify code/docs include commit instructions,
# while review/analysis commands do not.
#
# Commands with commits enabled by default:
# - Code generation and refactoring (create, refactor, fix modes)
# - Documentation generation and build fixes
# - Pull request merge operations
# - Security patching
#
# Commands with commits disabled by default:
# - Review and analysis operations
# - Draft generation tasks
# - Ask/query commands
# - Security audit operations
#
# To override defaults, use the extended target/operation syntax:
#
# [agent.github_copilot.targets]
# code = { model = "gpt-4", commits = "on" } # Enable commits for all code target operations
# issue = { commits = "off" } # Disable commits for all issue target operations
#
# [agent.github_copilot.operations]
# "workflow.execute" = { commits = "on" } # Enable commits for specific operation
# "workflow.plan" = { model = "gpt-4", commits = "off" } # Disable commits with model override
#
# Values:
# - "on": Enable commit instructions for this target/operation
# - "off": Disable commit instructions for this target/operation
#
# Note: project.toml [commit].behavior = "disabled" overrides ALL settings here.
54 changes: 54 additions & 0 deletions .nia/config/project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
schema_version = "1.0.0"

[project]
name = "JustMockLite"
description = "Project description"
language = "Rust" # Change to your primary language
framework = "None" # Update with your framework (e.g., "actix-web", "axum")
testing_framework = "cargo test"
package_manager = "cargo"

[beta_consent]
acknowledged = true
acknowledgement_date = "2026-08-31T12:12:34.189752600+00:00"
acknowledged_by = "nia"
version_at_consent = "4.4.0"
consent_phrase = "i agree"

# Uncomment and configure for monorepo
# [monorepo]
# enabled = true
#
# [[monorepo.services]]
# name = "service-a"
# path = "services/service-a"

# Context files and directories
#
# Files and directories listed here are always included as context for AI prompts.
# This is useful for architecture docs, coding standards, or API specifications.
#
# [[project.context]]
# type = "file"
# path = "docs/architecture.md"
# description = "System architecture overview"
#
# [[project.context]]
# type = "directory"
# path = "docs/standards/"
# description = "Coding standards and guidelines"

# Commit behavior configuration
#
# Controls how nia handles git commits during code generation tasks.
#
# Options:
# - "enabled" (default): Include basic commit instructions in prompts
# - "tagged": Include commit instructions with nia co-author attribution
# - "disabled": Do not include any commit instructions (you handle commits manually)
#
# Note: This is a global override. To configure commit behavior per command,
# use the agents.toml file (see comments in that file for examples).
#
# [commit]
# behavior = "enabled"
9 changes: 9 additions & 0 deletions .nia/config/telemetry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[consent]
notice_shown = true
notice_shown_date = "2026-08-31T12:12:36.494017900+00:00"
notice_shown_by = "nia"
consented = true
opted_out = false
consent_date = "2026-08-31T12:12:36.494019300+00:00"
consent_phrase = "i agree"
consented_by = "nia"
129 changes: 129 additions & 0 deletions .nia/config/toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Nia toolchain configuration
# This file tells AI agents what tools are available and how to access them
#
# To switch access methods for a tool:
# 1. Comment out the current 'description' field (add # prefix to each line)
# 2. Uncomment your preferred method's description block
# 3. Update the 'method' field to match the new method
schema_version = "1.0.0"

# Issue tracker configuration
[issue_tracker]
name = "jira"
type = "built-in"
method = "skill" # Options: "cli", "mcp", "api", "skill" (default)
description = """
When retrieving or reading issues from JIRA, use the "{{issue_tracker_skill_name}}" skill.
This skill provides guidance on JQL queries, field navigation, authentication,
and JIRA-specific best practices including checking comments and attachments.
"""

# [CLI Method]:
# description = """
# JIRA for agile project management and issue tracking.
# Access via Atlassian CLI (`acli jira` command).
# The Atlassian CLI must be installed and configured separately.
# Common operations:
# - View issue: acli jira workitem view {{issue_id}}
# - Edit issue: acli jira workitem edit {{issue_id}}
# """

# [MCP Method]:
# description = """
# JIRA for agile project management and issue tracking.
# Access via JIRA MCP Server (if available).
# The MCP server provides tools for managing JIRA issues, sprints, and boards.
# All authentication is handled by the MCP server configuration.
# """

# [API Method]:
# description = """
# JIRA for agile project management and issue tracking.
# Access via JIRA REST API.
#
# Authentication: API token required
# - Environment variable: NIA_ISSUE_TOKEN
# - Scope: Read and write access to JIRA issues
# - Management: User-managed; set externally before running Nia
# - Security: Nia does not inject tokens into logs, traces, or prompts
#
# The Coding Agent will read this token dynamically when making API calls.
#
# Common operations:
# - List issues: GET /rest/api/2/search?jql=<query>
# - View issue: GET /rest/api/2/issue/{{issue_id}}
# - Create issue: POST /rest/api/2/issue
# - Update issue: PUT /rest/api/2/issue/{{issue_id}}
# """

# Code platform configuration
[code_platform]
name = "github"
type = "built-in"
method = "skill" # Options: "cli", "mcp", "api", "skill" (default)
description = """
When retrieving or reading pull requests from the code platform, use the "{{code_platform_skill_name}}" skill.
This skill provides guidance on PR navigation, review status, diff inspection,
and code platform best practices.
"""

# [CLI Method]:
# description = """
# GitHub for code hosting and collaboration.
# Access via 'gh' CLI commands.
#
# {{#if code_platform_repo_slug}}Repository: {{code_platform_repo_slug}}
#
# Common operations (repository configured — use --repo flag):
# - Create PR: gh pr create --title "..." --body "..." --repo {{code_platform_repo_slug}}
# - View PR: gh pr view {{pr_id}} --repo {{code_platform_repo_slug}}
# - List PRs: gh pr list --repo {{code_platform_repo_slug}}
# - Review PR: gh pr review {{pr_id}} --repo {{code_platform_repo_slug}}
# - Merge PR: gh pr merge {{pr_id}} --repo {{code_platform_repo_slug}}
# - View repo: gh repo view --repo {{code_platform_repo_slug}}
# {{/if}}
# {{#unless code_platform_repo_slug}}Common operations:
# - Create PR: gh pr create --title "..." --body "..."
# - View PR: gh pr view {{pr_id}}
# - List PRs: gh pr list
# - Review PR: gh pr review {{pr_id}}
# - Merge PR: gh pr merge {{pr_id}}
# - View repo: gh repo view
# {{/unless}}
# """

# [MCP Method]:
# description = """
# GitHub for code hosting and collaboration.
# Access via GitHub MCP Server.
# The MCP server provides comprehensive tools for repository operations including pull requests, code reviews, branches, and commits.
# All authentication is handled by the MCP server configuration.
# """

# [API Method]:
# description = """
# GitHub for code hosting and collaboration.
# Access via GitHub REST API.
#
# Authentication: API token required
# - Environment variable: NIA_CODE_TOKEN
# - Scope: Read and write access to repositories, pull requests, and code
# - Management: User-managed; set externally before running Nia
# - Security: Nia does not inject tokens into logs, traces, or prompts
#
# The Coding Agent will read this token dynamically when making API calls.
#
# Repository placeholders: {{code_platform_repo_owner}}/{{code_platform_repo_name}}
#
# Common operations:
# - List PRs: GET /repos/{{code_platform_repo_owner}}/{{code_platform_repo_name}}/pulls
# - View PR: GET /repos/{{code_platform_repo_owner}}/{{code_platform_repo_name}}/pulls/{{pr_id}}
# - Create PR: POST /repos/{{code_platform_repo_owner}}/{{code_platform_repo_name}}/pulls
# - Update PR: PATCH /repos/{{code_platform_repo_owner}}/{{code_platform_repo_name}}/pulls/{{pr_id}}
# - Merge PR: PUT /repos/{{code_platform_repo_owner}}/{{code_platform_repo_name}}/pulls/{{pr_id}}/merge
# - List commits: GET /repos/{{code_platform_repo_owner}}/{{code_platform_repo_name}}/commits
# - Get repo: GET /repos/{{code_platform_repo_owner}}/{{code_platform_repo_name}}
#
# Note: When repository placeholders are empty (not configured), use auto-detected repository information from Git remote.
# """

36 changes: 36 additions & 0 deletions Telerik.JustMock/Core/MocksRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public sealed class MocksRepository
private readonly int repositoryId;
private readonly Thread creatingThread;
private readonly Dictionary<Type, IMockMixin> staticMixinDatabase = new Dictionary<Type, IMockMixin>();
private readonly Dictionary<Type, IMockMixin> futureMixinDatabase = new Dictionary<Type, IMockMixin>();
private readonly Dictionary<MethodBase, MethodInfoMatcherTreeNode> arrangementTreeRoots = new Dictionary<MethodBase, MethodInfoMatcherTreeNode>();
private readonly Dictionary<MethodBase, MethodInfoMatcherTreeNode> invocationTreeRoots = new Dictionary<MethodBase, MethodInfoMatcherTreeNode>();
private readonly Dictionary<KeyValuePair<object, object>, object> valueStore = new Dictionary<KeyValuePair<object, object>, object>();
Expand Down Expand Up @@ -274,6 +275,17 @@ internal static IMockMixin GetMockMixin(object obj, Type objType)
if (obj != null)
{
asMixin = GetMixinFromExternalDatabase(obj, objType);

// Check future mixin database for instance calls where no explicit mock exists
if (asMixin == null)
{
MocksRepository repo = MockingContext.ResolveRepository(UnresolvedContextBehavior.CreateNewContextual);
if (repo != null)
{
lock (repo.futureMixinDatabase)
repo.futureMixinDatabase.TryGetValue(objType, out asMixin);
}
}
}
else if (objType != null)
{
Expand Down Expand Up @@ -431,6 +443,7 @@ internal void Reset()

this.arrangedTypes.Clear();
this.staticMixinDatabase.Clear();
this.futureMixinDatabase.Clear();

foreach (var method in this.globallyInterceptedMethods)
{
Expand Down Expand Up @@ -798,6 +811,29 @@ internal void InterceptStatics(Type type, MockCreationSettings settings, bool mo
this.EnableInterception(type);
}

internal void InterceptFuture(Type type, MockCreationSettings settings)
{
if (!ProfilerInterceptor.IsProfilerAttached)
ProfilerInterceptor.ThrowElevatedMockingException(type);

if (!settings.FallbackBehaviors.OfType<CallOriginalBehavior>().Any())
ProfilerInterceptor.CheckIfSafeToInterceptWholesale(type);

var mockMixin = (IMockMixin)Create(typeof(ExternalMockMixin),
new MockCreationSettings
{
Mixins = settings.Mixins,
SupplementaryBehaviors = settings.SupplementaryBehaviors,
FallbackBehaviors = settings.FallbackBehaviors,
MustCreateProxy = true,
});

lock (futureMixinDatabase)
futureMixinDatabase[type] = mockMixin;

this.EnableInterception(type);
}

private MockMixin CreateMockMixin(Type declaringType, MockCreationSettings settings)
{
return CreateMockMixin(declaringType, settings, settings.MockConstructorCall);
Expand Down
Loading