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
87 changes: 87 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Copilot instructions

This document provides instructions to the copilot AI assistants for dvorka/mindforger project.

## General instructions

- Always write beautiful, readable, and maintainable code.
- Handle errors, exceptions, and corner cases.
- Prefer clarity over cleverness. Optimize only when needed and measured.
- Always KISS - keep changes small and focused.
- Always DRY the code - do not duplicate code; create reusable classes, functions and methods; do not repeat yourself.
- Always add tests alongside code changes.

## Functional architecture instructions

- Contribute to this repository which is the thinking notebook and Markdown IDE desktop.

## Technology stack instructions

- The project is written in C++.
- The code is portable so that it can be compiled on Linux, Windows and macOS.
- The application is written using Qt framework.
- Always use C++ 11 and avoid newer language features.
- Always start code comments with lowercase letter.
- Always use `MF_DEBUG` to write debugging output.
- Always use `_WIN32` to identify Windows specific code.
- Always use `__APPLE__` to identify macOS specific code.

## Code quality instructions

- Use code formatting style as used in mindforger.cpp - comments, indentatation, parenthesis, namespaces, directives, ...

## Repository conventions

- The project is structured to the library which is then used by Qt application.
- Library dependencies are stored in `deps/` - each have its own build style.
- Library code lives under `lib/`.
- Qt application code lives under `app/`.
- Tests code lives under `lib/tests/`.
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Copilot project instructions claim tests live under lib/tests/, but this repo uses lib/test/ (and the design doc also references lib/test/src/...). Update this path to avoid steering contributors/tools to a non-existent directory.

Suggested change
- Tests code lives under `lib/tests/`.
- Tests code lives under `lib/test/`.

Copilot uses AI. Check for mistakes.
- Licenses are stored in `licenses/`.

## Test instructions

- Always use `gtest` (Google test) framework to write the test.
- Each test (function) is structured into 3 sections: `// GIVEN`, `// WHEN`, and `// THEN`. `GIVEN` section prepares the data, `WHEN` section calls the function, and `THEN` section prints results, asserts results and checks results.
- `THEN` section of the test must have at least one assert statement.
- Keep tests deterministic.
- Always use text to indicate success/failure/progress like DONE, ERROR or WIP - never use (unicode) characters like ✓ or ✗.
- Always print or log intermediate values only when they aid debugging.
- Always make sure that tests which test new feature or fix are in green.

## Build instructions

- Qt is used to describe the project structure using `*.pro` files and to build it using `qmake`.
- Makefile to build, test, run and package the project is located in `build/Makefile`.
- Always use `make help` to find out what are the targets.

## Documentation instructions

- Markdown user documentation sources live under `doc/`.
- Doxygen documentation can be build using a target defined in `build/Makefile` - use details from that target.
- Always use `build/Makefile` targets to build the Doxygen documentation.

## Continuous Integration instructions

- GitHub Actions is used as CI for Linux and macOS.
- AppVeyor is used as CI for Windows.
- GitHub Actions CI configuration is stored under `.github/workflows/`.

## Security and secrets instructions

- Always use environment variables and secret stores.
- Always use GitHub actions secrets.
- Never commit secrets, credentials or sensitive data.
- Validate, sanitize and anonymize all external inputs.
- Always run security-focused checks.
- Always add new license to `licenses/` when you add new direct dependency.

## Release versioning instructions

- Always use semantic versioning: MAJOR.MINOR.PATCH.
- Note that releases has Git tag like `vMAJOR.MINOR.PATCH`.
- Note that releases are being developed in `dev-MAJOR.MINOR.PATCH` branches.
- Note that Git branches use naming convention for fix branch (`bug-NUMBER/DESCRIPTION`), features and enhancements (`feat-NUMBER/DESCRIPTION`) and documentation (`doc-NUMBER/DESCRIPTION`).
- Note that Conventional commits (conventionalcommits.org) are used for the commit messages.
- Always update change log stored in `Changelog` whenever you do a fix, change, or enhancement.
- Always make sure that the version is consistent in `app_info.h`, `Makefile`, `debian/debian-make-deb.sh`, `debian/changelog`, `macos/env.h`, `snap/snapcraft.yaml`, `tarball/tarball-build.sh` and `ubuntu/debian/changelog` - `app_info.h.py` is the one and only authoritative version source.
6 changes: 6 additions & 0 deletions app/app.pro
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ HEADERS += \
src/qt/dialogs/rm_library_dialog.h \
src/qt/dialogs/run_tool_dialog.h \
src/qt/dialogs/wingman_dialog.h \
src/qt/dialogs/add_llm_provider_dialog.h \
src/qt/dialogs/openai_config_dialog.h \
src/qt/dialogs/ollama_config_dialog.h \
src/qt/dialogs/sync_library_dialog.h \
src/qt/dialogs/terminal_dialog.h \
src/qt/kanban_column_model.h \
Expand Down Expand Up @@ -407,6 +410,9 @@ SOURCES += \
src/qt/dialogs/rm_library_dialog.cpp \
src/qt/dialogs/run_tool_dialog.cpp \
src/qt/dialogs/wingman_dialog.cpp \
src/qt/dialogs/add_llm_provider_dialog.cpp \
src/qt/dialogs/openai_config_dialog.cpp \
src/qt/dialogs/ollama_config_dialog.cpp \
src/qt/dialogs/sync_library_dialog.cpp \
src/qt/dialogs/terminal_dialog.cpp \
src/qt/kanban_column_model.cpp \
Expand Down
83 changes: 83 additions & 0 deletions app/src/qt/dialogs/add_llm_provider_dialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
add_llm_provider_dialog.cpp MindForger thinking notebook

Copyright (C) 2016-2026 Martin Dvorak <martin.dvorak@mindforger.com>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "add_llm_provider_dialog.h"

namespace m8r {

using namespace std;

AddLlmProviderDialog::AddLlmProviderDialog(QWidget* parent)
: QDialog(parent),
selectedProviderType(WINGMAN_PROVIDER_NONE)
{
questionLabel = new QLabel(tr("Which provider do you want to configure?"), this);

providerTypeCombo = new QComboBox(this);
providerTypeCombo->addItem(tr("OpenAI"), WINGMAN_PROVIDER_OPENAI);
providerTypeCombo->addItem(tr("ollama"), WINGMAN_PROVIDER_OLLAMA);

nextButton = new QPushButton(tr("Next >"), this);
nextButton->setDefault(true);

cancelButton = new QPushButton(tr("Cancel"), this);

// layout
QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(questionLabel);
mainLayout->addWidget(providerTypeCombo);

QHBoxLayout* buttonLayout = new QHBoxLayout();
buttonLayout->addStretch();
buttonLayout->addWidget(cancelButton);
buttonLayout->addWidget(nextButton);

mainLayout->addLayout(buttonLayout);
setLayout(mainLayout);

// signals
QObject::connect(nextButton, &QPushButton::clicked, this, &AddLlmProviderDialog::handleNext);
QObject::connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject);

// dialog
setWindowTitle(tr("New LLM Provider"));
resize(fontMetrics().averageCharWidth()*55, height());
setModal(true);
}

AddLlmProviderDialog::~AddLlmProviderDialog()
{
}

void AddLlmProviderDialog::show()
{
providerTypeCombo->setCurrentIndex(0);
selectedProviderType = WINGMAN_PROVIDER_NONE;

QDialog::show();
}

void AddLlmProviderDialog::handleNext()
{
selectedProviderType = static_cast<WingmanLlmProviders>(
providerTypeCombo->itemData(providerTypeCombo->currentIndex()).toInt());

accept();
}

}
57 changes: 57 additions & 0 deletions app/src/qt/dialogs/add_llm_provider_dialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
add_llm_provider_dialog.h MindForger thinking notebook

Copyright (C) 2016-2026 Martin Dvorak <martin.dvorak@mindforger.com>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef M8RUI_ADD_LLM_PROVIDER_DIALOG_H
#define M8RUI_ADD_LLM_PROVIDER_DIALOG_H

#include <QtWidgets>

#include "../../lib/src/config/configuration.h"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relative include ../../lib/src/config/configuration.h resolves to app/src/lib/... from this header, which doesn’t exist in the repo, so these new dialogs likely won’t compile. Same issue also appears in the OpenAI/ollama config dialog headers.

Severity: high

Other Locations
  • app/src/qt/dialogs/openai_config_dialog.h:25
  • app/src/qt/dialogs/openai_config_dialog.h:26
  • app/src/qt/dialogs/ollama_config_dialog.h:25
  • app/src/qt/dialogs/ollama_config_dialog.h:26

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


namespace m8r {

class AddLlmProviderDialog : public QDialog
{
Q_OBJECT

private:
QLabel* questionLabel;
QComboBox* providerTypeCombo;
QPushButton* nextButton;
QPushButton* cancelButton;

WingmanLlmProviders selectedProviderType;

public:
explicit AddLlmProviderDialog(QWidget* parent);
AddLlmProviderDialog(const AddLlmProviderDialog&) = delete;
AddLlmProviderDialog(const AddLlmProviderDialog&&) = delete;
AddLlmProviderDialog& operator=(const AddLlmProviderDialog&) = delete;
AddLlmProviderDialog& operator=(const AddLlmProviderDialog&&) = delete;
Comment on lines +43 to +45
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AddLlmProviderDialog also declares deleted move operations as const AddLlmProviderDialog&& / operator=(const AddLlmProviderDialog&&). This isn’t the normal move signature and can be misleading; use AddLlmProviderDialog&& (or omit move deletions if not needed).

Suggested change
AddLlmProviderDialog(const AddLlmProviderDialog&&) = delete;
AddLlmProviderDialog& operator=(const AddLlmProviderDialog&) = delete;
AddLlmProviderDialog& operator=(const AddLlmProviderDialog&&) = delete;
AddLlmProviderDialog(AddLlmProviderDialog&&) = delete;
AddLlmProviderDialog& operator=(const AddLlmProviderDialog&) = delete;
AddLlmProviderDialog& operator=(AddLlmProviderDialog&&) = delete;

Copilot uses AI. Check for mistakes.
~AddLlmProviderDialog();

WingmanLlmProviders getSelectedProviderType() const { return selectedProviderType; }

void show();

private slots:
void handleNext();
};

}
#endif // M8RUI_ADD_LLM_PROVIDER_DIALOG_H
Loading
Loading