Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8fca370
fix(changelog): improve cache serialization and require app parameter
Quorafind Oct 12, 2025
37c9769
feat(quick-capture): add file name template dropdown and enhance sett…
Quorafind Oct 12, 2025
cf5334f
fix(editor-extensions): resolve transaction conflicts between workflo…
Quorafind Oct 13, 2025
09ed881
feat(workspace): add module visibility control with performance impro…
Quorafind Oct 16, 2025
a0b9891
fix(workspace): improve async handling and error recovery in module v…
Quorafind Oct 16, 2025
fa35b82
docs: add FSL-1.1-ALv2 license and contributor license agreement
Quorafind Oct 16, 2025
853c9ef
docs: update documentation with CLA and license information
Quorafind Oct 16, 2025
0d3c6fa
chore: add GitHub pull request template with CLA reference
Quorafind Oct 16, 2025
b475615
refactor(workspace): clean up settings and improve module visibility
Quorafind Oct 16, 2025
dee9541
feat(workspace): add color customization support
Quorafind Oct 18, 2025
852f527
feat(task): add multi-task selection and bulk operations
Quorafind Oct 19, 2025
add61b7
refactor(fluent): rename V2 to fluent and improve code quality
Quorafind Oct 19, 2025
fc7600c
feat(bulk-operations): optimize view updates to prevent list flashing
Quorafind Oct 19, 2025
2f2f59a
refactor(fluent): improve view mode persistence and configuration
Quorafind Oct 19, 2025
99884ea
refactor(quick-capture): consolidate modal imports and improve code q…
Quorafind Oct 20, 2025
8fdfc39
feat(bulk-operations): add keyboard shortcuts for selection management
Quorafind Oct 20, 2025
9aaabe7
feat(fluent): implement dual-mode projects view
Quorafind Oct 20, 2025
7d41359
refactor: remove void keywords and standardize code formatting
Quorafind Oct 20, 2025
422fdf0
refactor(workspace): improve state management and persistence reliabi…
Quorafind Oct 20, 2025
9dedada
refactor(workspace): remove deprecated feature hiding functionality
Quorafind Oct 21, 2025
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
17 changes: 17 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Description
<!-- Describe your changes -->

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Documentation update
- [ ] Code refactoring

## Checklist
- [ ] I have read and agree to the [CLA](./CLA.md)
- [ ] My code follows the project's style guidelines
- [ ] I have tested my changes
- [ ] I have updated the documentation

## Related Issues
Closes #(issue number)
22 changes: 22 additions & 0 deletions .github/workflows/cla.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: "Obsidian Task Genius CLA Assistant"
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened, closed, synchronize]

jobs:
CLAssistant:
runs-on: ubuntu-latest
steps:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
uses: contributor-assistant/github-action@v2.3.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
with:
path-to-signatures: "signatures/cla.json"
path-to-document: "https://github.com/quorafind/obsidian-task-genius/blob/master/CLA.md"
branch: "main"
allowlist: bot*
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ translation-templates
CLAUDE.md
.kiro
.claude
.codex

dist
dist/*

# Documentation site (separate repository)
docs-site

8 changes: 4 additions & 4 deletions CHANGELOG-BETA.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ All notable changes to beta releases will be documented in this file.

* **setting:** manage workspace setting should jump to workspace setting tab ([f282bff](https://github.com/Quorafind/Obsidian-Task-Progress-Bar/commit/f282bffbf84d2b8fdde21521620342e1f47f6a58))
* **task-mover:** prevent archive markers on non-task lines and preserve folded content ([f20c5eb](https://github.com/Quorafind/Obsidian-Task-Progress-Bar/commit/f20c5ebee3b999fe69a902afee1b0d12e28fcfbe))
* **v2:** hide top navigation for two-column views ([2c24068](https://github.com/Quorafind/Obsidian-Task-Progress-Bar/commit/2c24068c69f314d7ccc63212c243e11abaaa6262))
* **fluent:** hide top navigation for two-column views ([2c24068](https://github.com/Quorafind/Obsidian-Task-Progress-Bar/commit/2c24068c69f314d7ccc63212c243e11abaaa6262))

### Chores

Expand All @@ -35,7 +35,7 @@ All notable changes to beta releases will be documented in this file.

* **setting:** manage workspace setting should jump to workspace setting tab ([f282bff](https://github.com/Quorafind/Obsidian-Task-Progress-Bar/commit/f282bffbf84d2b8fdde21521620342e1f47f6a58))
* **task-mover:** prevent archive markers on non-task lines and preserve folded content ([f20c5eb](https://github.com/Quorafind/Obsidian-Task-Progress-Bar/commit/f20c5ebee3b999fe69a902afee1b0d12e28fcfbe))
* **v2:** hide top navigation for two-column views ([2c24068](https://github.com/Quorafind/Obsidian-Task-Progress-Bar/commit/2c24068c69f314d7ccc63212c243e11abaaa6262))
* **fluent:** hide top navigation for two-column views ([2c24068](https://github.com/Quorafind/Obsidian-Task-Progress-Bar/commit/2c24068c69f314d7ccc63212c243e11abaaa6262))

## [9.9.0-beta.4](https://github.com/Quorafind/Obsidian-Task-Genius/compare/9.9.0-beta.3...9.9.0-beta.4) (2025-09-24)

Expand All @@ -45,7 +45,7 @@ All notable changes to beta releases will be documented in this file.

### Bug Fixes

* **v2:** resolve filter state management issues ([6c282f9](https://github.com/Quorafind/Obsidian-Task-Genius/commit/6c282f976cdaa0da7361a8599ea6b1f092cf1418))
* **fluent:** resolve filter state management issues ([6c282f9](https://github.com/Quorafind/Obsidian-Task-Genius/commit/6c282f976cdaa0da7361a8599ea6b1f092cf1418))

### Chores

Expand All @@ -62,7 +62,7 @@ All notable changes to beta releases will be documented in this file.

### Refactors

* **v2:** rename V2 interface to Fluent and simplify command names ([c096c6c](https://github.com/Quorafind/Obsidian-Task-Genius/commit/c096c6c9527ff0659b991e82f4bbca439e7430d7))
* **fluent:** rename fluent interface to Fluent and simplify command names ([c096c6c](https://github.com/Quorafind/Obsidian-Task-Genius/commit/c096c6c9527ff0659b991e82f4bbca439e7430d7))

## [9.9.0-beta.1](https://github.com/Quorafind/Obsidian-Task-Genius/compare/9.9.0-beta.0...9.9.0-beta.1) (2025-09-24)

Expand Down
19 changes: 19 additions & 0 deletions CLA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Contributor License Agreement (CLA) for Task Genius

Important: Please read this carefully before contributing.

By submitting a contribution (pull request, issue, comment, or any other form of contribution) to this project, you agree to the following terms:

### License Grant

1. **Grant of Rights**: You grant Quorafind the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, reproduce, modify, and distribute your contributions under one or more licenses, including but not limited to:
* (a) The Project's Public License: The project's primary public-facing license, which is currently the **Functional Source License 1.1 (FSL 1.1)**, and the subsequent **Apache License 2.0** it is converted to.
* (b) Proprietary Commercial Licenses: Any other proprietary license of Quorafind's choosing. This allows us to offer the software to commercial customers under terms different from the public license if needed in the future.

2. **Original Work**: You confirm that:
* You are the original author of the contribution.
* You have the legal right to grant the above license.
* Your contribution does not violate any third-party rights.
* Your contribution is submitted voluntarily.

3. **No Warranty**: Contributions are provided "as-is" without warranty of any kind.
36 changes: 34 additions & 2 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [Project Architecture](#project-architecture)
- [Code Style Guide](#code-style-guide)
- [Testing Strategy](#testing-strategy)
- [CLA](#cla)
- [Getting Help](#getting-help)
- [Questions?](#questions)

Expand Down Expand Up @@ -374,6 +375,39 @@ jest.mock('obsidian', () => ({
}));
```

## CLA

Contributor License Agreement (CLA) for Task Genius

Important: Please read this carefully before contributing.

By submitting a contribution (pull request, issue, comment, or any other form of contribution) to this project, you agree to the following terms:

### License Grant

1. **Grant of Rights**: You grant Quorafind the perpetual, worldwide, non-exclusive, royalty-free, irrevocable right to use, reproduce, modify, and distribute your contributions under one or more licenses, including but not limited to:
* (a) The Project's Public License: The project's primary public-facing license, which is currently the **Functional Source License 1.1 (FSL 1.1)**, and the subsequent **Apache License 2.0** it is converted to.
* (b) Proprietary Commercial Licenses: Any other proprietary license of Quorafind's choosing. This allows us to offer the software to commercial customers under terms different from the public license if needed in the future.

2. **Original Work**: You confirm that:
* You are the original author of the contribution.
* You have the legal right to grant the above license.
* Your contribution does not violate any third-party rights.
* Your contribution is submitted voluntarily.

3. **No Warranty**: Contributions are provided "as-is" without warranty of any kind.

### Why We Need This

Our mission is to build the best task management tool for Obsidian and keep it free for everyone. To achieve this sustainably, our project operates under a specific licensing model, and your agreement is essential.

* **Commitment to Free Use:** The compiled, ready-to-use Task Genius plugin is and will remain **free for all users**, including for commercial purposes. We want everyone to benefit from it without a paywall.
* **Protecting the Source Code:** To ensure the project's long-term health and fund its development, we release the **source code** under the Functional Source License 1.1 (FSL 1.1). This prevents others from simply taking our code, rebranding it, and selling it as a competing product.

* **Your Role as a Contributor:** This CLA is the bridge between your contribution and our project. It grants us the legal clarity to incorporate your code into our BSL-licensed project. This single agreement allows us to continue developing, maintaining, and distributing the plugin for the benefit of the entire community.

By signing, you help us protect the project's future while keeping the plugin itself free for all. Thank you for your contribution!

## Getting Help

1. Check existing issues on GitHub
Expand All @@ -384,8 +418,6 @@ jest.mock('obsidian', () => ({
- Expected vs actual behavior
- Console logs

---

## Questions?

If you have questions not covered here:
Expand Down
101 changes: 101 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
Functional Source License, Version 1.1, ALv2 Future License

Abbreviation: FSL-1.1-ALv2

Notice: Copyright 2025 Quorafind

## Terms and Conditions

### Licensor ("We")

The party offering the Software under these Terms and Conditions.

### The Software

The "Software" is each version of the software that we make available under
these Terms and Conditions, as indicated by our inclusion of these Terms and
Conditions with the Software.

### License Grant

Subject to your compliance with this License Grant and the Patents,
Redistribution and Trademark clauses below, we hereby grant you the right to
use, copy, modify, create derivative works, publicly perform, publicly display
and redistribute the Software for any Permitted Purpose identified below.

### Permitted Purpose

A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
means making the Software available to others in a commercial product or
service that:

1. substitutes for the Software;

2. substitutes for any other product or service we offer using the Software
that exists as of the date we make the Software available; or

3. offers the same or substantially similar functionality as the Software.

Permitted Purposes specifically include using the Software:

1. for your internal use and access;

2. for non-commercial education;

3. for non-commercial research; and

4. in connection with professional services that you provide to a licensee
using the Software in accordance with these Terms and Conditions.

### Patents

To the extent your use for a Permitted Purpose would necessarily infringe our
patents, the license grant above includes a license under our patents. If you
make a claim against any party that the Software infringes or contributes to
the infringement of any patent, then your patent license to the Software ends
immediately.

### Redistribution

The Terms and Conditions apply to all copies, modifications and derivatives of
the Software.

If you redistribute any copies, modifications or derivatives of the Software,
you must include a copy of or a link to these Terms and Conditions and not
remove any copyright notices provided in or with the Software.

### Disclaimer

THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.

IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.

### Trademarks

Except for displaying the License Details and identifying us as the origin of
the Software, you have no right under these Terms and Conditions to use our
trademarks, trade names, service marks or product names.

## Grant of Future License

We hereby irrevocably grant you an additional license to use the Software under
the Apache License, Version 2.0 that is effective on the second anniversary of
the date we make the Software available. On or after that date, you may use the
Software under the Apache License, Version 2.0, in which case the following
will apply:

Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

**The Ultimate Task Management Plugin for Obsidian**

[![Version](https://img.shields.io/badge/version-9.0.0-blue.svg)](https://github.com/Quorafind/Obsidian-Task-Genius)
[![Version](https://img.shields.io/badge/version-8.9.0-blue.svg)](https://github.com/Quorafind/Obsidian-Task-Genius)
[![Discord](https://img.shields.io/discord/1382008288706695229?color=7289da&label=Discord&logo=discord&logoColor=white)](https://discord.gg/ARR2rHHX6b)

[Documentation](https://taskgenius.md) • [Installation](#installation) • [Discord Community](https://discord.gg/ARR2rHHX6b)
Expand Down Expand Up @@ -81,4 +81,10 @@ Task Genius is developed with passion and dedication. If you find it valuable, c
</a>
</div>

Your support enables faster development, better documentation, and priority feature implementation.
Your support enables faster development, better documentation, and priority feature implementation.

## License

[FSL-1.1-ALv2](./LICENSE)

Feel free to use any part in the `src/components`, such as the Inline Markdown Editor or the Kanban component.
13 changes: 13 additions & 0 deletions src/__mocks__/codemirror-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,19 @@ export class EditorState {
};
},
};

// Add transactionExtender mock for tests
static transactionExtender = {
of: (
f: (
tr: Transaction
) => TransactionSpec | readonly TransactionSpec[] | null
) => {
return {
extend: f,
};
},
};
}

export class Annotation<T> {
Expand Down
28 changes: 20 additions & 8 deletions src/__tests__/QuickCaptureModal.integration.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { QuickCaptureModal } from "../components/features/quick-capture/modals/QuickCaptureModal";
import { DEFAULT_TIME_PARSING_CONFIG } from '@/services/time-parsing-service';
import { DEFAULT_TIME_PARSING_CONFIG } from "@/services/time-parsing-service";
import { App } from "obsidian";

// Mock dependencies
Expand Down Expand Up @@ -52,17 +52,21 @@ jest.mock("obsidian", () => ({
moment: () => ({ format: jest.fn(() => "2025-01-04") }),
EditorSuggest: class {
constructor() {}
getSuggestions() { return []; }
getSuggestions() {
return [];
}
renderSuggestion() {}
selectSuggestion() {}
onTrigger() { return null; }
onTrigger() {
return null;
}
close() {}
},
}));

// Mock moment module
jest.mock("moment", () => {
const moment = function(input?: any) {
const moment = function (input?: any) {
return {
format: () => "2024-01-01",
diff: () => 0,
Expand All @@ -87,7 +91,15 @@ jest.mock("moment", () => {
moment.locale = jest.fn(() => "en");
moment.utc = () => ({ format: () => "00:00:00" });
moment.duration = () => ({ asMilliseconds: () => 0 });
moment.weekdaysShort = () => ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
moment.weekdaysShort = () => [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
];
moment.weekdaysMin = () => ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
return moment;
});
Expand Down Expand Up @@ -166,7 +178,7 @@ describe("QuickCaptureModal Time Parsing Integration", () => {
test("should initialize with plugin settings", () => {
expect(modal.timeParsingService).toBeDefined();
expect(modal.timeParsingService.getConfig()).toEqual(
mockPlugin.settings.timeParsing
mockPlugin.settings.timeParsing,
);
});

Expand All @@ -183,11 +195,11 @@ describe("QuickCaptureModal Time Parsing Integration", () => {
mockApp,
pluginWithoutTimeParsing,
undefined,
true
true,
);
expect(modalWithoutConfig.timeParsingService).toBeDefined();
expect(modalWithoutConfig.timeParsingService.getConfig()).toEqual(
DEFAULT_TIME_PARSING_CONFIG
DEFAULT_TIME_PARSING_CONFIG,
);
});
});
Expand Down
6 changes: 6 additions & 0 deletions src/__tests__/mockUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,12 @@ const createMockPlugin = (

const mockWriteAPI = {
updateTask: jest.fn(async () => ({ success: true })),
updateTasksSequentially: jest.fn(async (args: any[]) => ({
successCount: args?.length ?? 0,
failCount: 0,
errors: [],
totalCount: args?.length ?? 0,
})),
createTask: jest.fn(async () => ({ success: true })),
deleteTask: jest.fn(async () => ({ success: true })),
};
Expand Down
Loading