Commit Graph

306 Commits

Author SHA1 Message Date
Steve Lau
7d0d11860c try to enable microphone access for signed macOS builds 2025-08-01 11:54:06 +08:00
SteveLauC
c30df6cee0 feat: sub extension can set 'platforms' now (#847)
Before this commit, sub extensions were not allowed to set their
"platforms" field, this restriction is lifted in this commit.

By allowing this, a group extension can have sub extensions for
different platforms, here is an example (irrelavent fields are omitted
for the sake of simplicity):

```json
{
  "name": "Suspend my machine",
  "type": "Group",
  "platforms": ["macos", "windows"],
  "commands": [
    {
      "name": "Suspend macOS":
      "platforms": ["macos"],
      "action": {...}
    },
    {
      "name": "Suspend Windows":
      "platforms": ["windows"],
      "action": {...}
    }
  ]
}
```

While loading or installing extensions, incompatible sub extensions will
be filtered out by Coco, e.g., you won't see that "Suspend Windows"
command if you are on macOS.

An extra check is added in this commit to ensure a sub extensions won't
support the platforms that are incompatible with its main extension.

Even though main extensions and sub extensions can both have "platforms"
specified, the semantics of this field, when not set, differs between them.
For main extensions, it means this extension is compatible with all the
platforms supported by Coco (null == all).  For sub extensions, having it
not set implicitly says that this field has the same value as the main
extension's "platforms" field.

The primary reason behind this design is that if we choose the semantics used
by the main extension, treating null as all, all the extensions we currently
have will become invalid, because they are all macOS-only, the main extensions's
"platforms" field is "macos" and sub extensions' "platforms" is not set (null),
they will be equivalent to:

```json
{
  "name": "this is macOS-only",
  "type": "Group",
  "platforms": ["macos"],
  "commands": [
    {
      "name": "How the fxxk can this support all the platforms!"
      "platforms": ["macos", "windows", "linux"],
      "type": "Command",
      "action": {...}
    }
  ]
}
```
This hits exactly the check we mentioned earlier and will be rejected by
Coco.  If we have users installed them, the installed extensions will be
treated invalid and rejected by future Coco release, boom, we break backward
compatibility.

Also, the current design actually makes sense.  Nobody wants to repeatedly
tell Coco that all the sub extensions support macOS if this can be said only
once:

```json
{
  "name": "this is macOS-only",
  "platforms": ["macos"],
  "commands": [
    {
      "name": "This supports macOS"
      "platforms": ["macos"],
    },
    {
      "name": "This supports macOS too"
      "platforms": ["macos"],
    },
    {
      "name": "Guess what! this also supports macOS"
      "platforms": ["macos"],
    },
    {
      "name": "Come on dude, do I really to say this platform=macos so many times"
      "platforms": ["macos"],
    }
  ]
}
```
2025-07-31 21:49:59 +08:00
ayangweb
855fb2a168 feat: support sending files in chat messages (#764)
* feat: support sending files in chat messages

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* docs: update changelog
2025-07-31 15:36:03 +08:00
SteveLauC
d2735ec13b refactor: check Extension/plugin.json from all sources (#846)
Coco App has 4 sources of Extension/plugin.json that should be checked:

1. From the "<data directory>/third_party_extensions" directory
2. Imported via "Import Local Extension"
3. Downloaded from the "store/extension/<extension ID>/_download" API
4. From coco-extensions repository

   Granted, Coco APP won't check these files directly, but we will
   re-use the code and run them in that repository's CI.

Previously, only the Extensions from the first source were checked/validated.
This commit extracts the validation logic to a function and applies it to all
4 sources.

Also, the return value of the Tauri command "list_extensions()" has changed.
We no longer return a boolean indicating if any invalid extensions
are found during loading, which only makes sense when installing
extensions requires users to manually edit data files. Since we now
support extension store and local extension imports, it could be omitted.
2025-07-31 14:27:23 +08:00
SteveLauC
c40fc5818a chore: ignore tauri::AppHandle's generic argument R (#845)
This commit removes the generic argument R from all the AppHandle imports, which
is feasible as it has a default type. This change is made not only for simplicity,
but also **consistency**. Trait SearchSource uses this type:

```rust
pub trait SearchSource {
    async fn search(
        &self,
        tauri_app_handle: AppHandle,
        query: SearchQuery,
    ) -> Result<QueryResponse, SearchError>;
}
```

In order to make trait SearchSource object-safe, the AppHandle used in it cannot
contain generic arguments. So some parts of Coco already omit this generic
argument. This commit cleans up the remaining instances and unifies the usage
project-wide.
2025-07-29 21:55:03 +08:00
SteveLauC
a553ebd593 feat: support Quicklink on Rust side (#760)
This commit implements the support for Quicklink on Rust side. We still
need the frontend part to make this complete.
2025-07-29 16:30:12 +08:00
BiggerRain
232166eb89 chore: delete unused code files and dependencies (#841)
Mainly delete unused webSocket content, and delete other unused code files and dependencies
2025-07-29 13:02:28 +08:00
Medcl
99144950d9 Revert "chore: add macos config for tauri (#837)" (#840)
This reverts commit ee45d21bbe.
2025-07-29 11:04:53 +08:00
SteveLauC
32d4f45144 feat: support installing local extensions (#749)
This commit adds support for installing extensions from a local folder path:

```text
extension-directory/
├── assets/
│   ├── icon.png
│   └── other-assets...
└── plugin.json
```

Useful for testing and development of extensions before publishing.

Co-authored-by: ayang <473033518@qq.com>
2025-07-29 10:26:47 +08:00
SteveLauC
cd54beee04 refactor: split query_coco_fusion() (#836)
This commit splits query_coco_fusion() into 2 functions:

1. query_coco_fusion_single_query_source()
2. query_coco_fusion_multi_query_sources()

query_coco_fusion_single_query_source(), as the name suggests, will only search
1 query source. Due to this simplicity, it does not need the complex re-ranking
procedure used by query_coco_fusion_multi_query_sources(), which is the primary
reason why this commit was made.

Another reason behind the change is that the re-ranking logic makes the
search results of querying single query source incorrect, it removes documents
from the results. I didn't investigate the issue because dropping the complex
logic in single query source search would be the best solution here.
2025-07-28 17:29:17 +08:00
ayangweb
ee45d21bbe chore: add macos config for tauri (#837) 2025-07-28 16:35:11 +08:00
SteveLauC
4696aa1759 test: test extract_build_number() (#835)
This commit adds a test for extract_build_number(), which I forgot to do
in commit 067fb7144f6[1].

[1]: 067fb7144f
2025-07-28 11:42:50 +08:00
BiggerRain
8f992bfa92 chore: bump version number to 0.7.1 (#830) 2025-07-27 17:26:08 +08:00
BiggerRain
e7dd27c744 chore: add toggle_move_to_active_space_attribute (#829)
* chore: add toggle_move_to_active_space_attribute

* chore: pin

* chore: add

* update

---------

Co-authored-by: Steve Lau <stevelauc@outlook.com>
2025-07-27 16:50:11 +08:00
BiggerRain
b37bf1f7c7 chore: bump version number to 0.7.0 (#827) 2025-07-25 19:54:33 +08:00
SteveLauC
286b1be212 fix: panic on Ubuntu (GNOME) when opening apps (#821)
On Ubuntu (the GNOME version), Coco would panic when users open an app due
to the reason that Coco thinks it is running in an unsupported desktop
environment (DE).

We rely on the environment variable XDG_CURRENT_DESKTOP to detect the DE,
Ubuntu sets this variable to "ubuntu:GNOME" instead of just "GNOME",
which was not handled by the previous implementation.

This commit supports this case. Also, when Coco runs in an unsupported DE,
opening apps should not panic the app. After this commit, we would return
an error.
2025-07-25 15:32:48 +08:00
BiggerRain
d664fa7271 chore: handle reply to message (#799)
* chore: add reply to message

* chore: handle rust data

* log

* chore: id

* feat: add

* chore: loading step

* chore: cur id

* feat: add

* accept query parameters

* chore: add message id for cancel

* chore: remove log

* chore: remove log

---------

Co-authored-by: Steve Lau <stevelauc@outlook.com>
2025-07-24 18:06:59 +08:00
SteveLauC
067fb7144f refactor: use custom version comparator to determine if we should update (#810) 2025-07-24 16:05:36 +08:00
SteveLauC
e8f9a4e627 chore: log querysources to search only when querysource is not set (#807) 2025-07-24 09:39:29 +08:00
SteveLauC
ca3b514a65 fix: panic caused by "state() called before manage()" (#806)
This commit fixes the following panic:

```
Time: [2025-07-23-17-03-23]
Location: [/Users/steve/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.5.1/src/lib.rs:742:7]
Message: [state() called before manage() for tauri_plugin_global_shortcut::GlobalShortcut<tauri_runtime_wry::Wry<tauri::EventLoopMessage>>]
```

The root cause is that, in a Tauri application, before you can access a piece of
managed state with the .state() method, you must first register it with Tauri
using .manage(). When a user reigsters hotkey for an extension,
initializing extensions will invoke the .state() method, at that point,
.manage() hasn't been called.

The fix is simple, we simply call .manage() earlies (invoked by our
`shortcut::enable_shortcut(app)` function).
2025-07-23 18:56:16 +08:00
SteveLauC
c694c4eda9 chore: display backtrace in panic log (#805)
Having backtrace in the panic log will help debugging a lot. Under
release builds, we strip our binary so the symbols information is
unavailable, but this information is still useful in debug builds.

Panic log in release builds:

```
Time: [YYYY-MM-DD-HH-MM-SS]
Location: [/Users/foo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.5.1/src/lib.rs:742:7]
Message: [state() called before manage() for tauri_plugin_global_shortcut::GlobalShortcut<tauri_runtime_wry::Wry<tauri::EventLoopMessage>>]
Backtrace:
   0: __mh_execute_header
   1: __mh_execute_header
   2: __mh_execute_header
   3: __mh_execute_header
   4: __mh_execute_header
   5: __mh_execute_header
   6: __mh_execute_header
   7: __mh_execute_header
   8: __mh_execute_header
   9: __mh_execute_header
  10: __mh_execute_header
  11: __mh_execute_header
  12: __mh_execute_header
  13: __mh_execute_header
  14: __mh_execute_header
  15: __mh_execute_header
  16: __mh_execute_header
  17: <unknown>
  18: <unknown>
```
2025-07-23 17:00:48 +08:00
SteveLauC
25bbab7432 refactor: clean up unsupported characters from query string in Win Search (#802)
We found that Windows Search would error out if it encounters a single
quote character, the natural solution would be to escape it. But I couldn't
find out how. The approach mentioned by most posts:

```
~="<Unsupported Char>"
```

won't work in my test. So I decided to replace it with a whitespace.

Single quote is not the first unsupported character I know, the newline
character is not supported as well, so it will be handled in the same
way.
2025-07-23 16:13:15 +08:00
SteveLauC
e78fe4ac89 fix: broken windows search (#801)
This commit fixes the search issue introduced by [commit](5c0a865822). We have no idea why the tauri command `get_app_search_source` won't be invoked after that commit on Windows.

This commit resolves the issue by moving the extension init logic to the Rust side.

Also, update the querysource logs in `quey_coco_fusion()`, the old one won't say anything if the querysource list is empty, the new one will tell us that.
2025-07-23 12:33:18 +08:00
Medcl
60fd79f1fa fix: increase read_timeout for HTTP streaming stability (#798) 2025-07-22 18:44:27 +08:00
BiggerRain
5c0a865822 chore: not request the interface if not logged in (#795)
* chore: not request the interface if not logged in

* chore: res

* chore: res

* chore: common interface

* chore: no login

* chore: login

* chore: login

* chore: add

* dbg print servers

* chore: id

* docs: update notes

---------

Co-authored-by: Steve Lau <stevelauc@outlook.com>
2025-07-22 16:15:58 +08:00
SteveLauC
b97386a827 refactor: avoid GLOBAL_TAURI_APP_HANLE if possible (#796)
This commit fixes the Windows panic issue. 

Coco panicked because it accessed `GLOBAL_TAURI_APP_HANDLE` when this global variable wasn't initialized. I removed all the uses of this variable except for the one use in `src-tauri/src/server/http_client.rs`, which I don't have a good way to refactor.

If you are wondering why this didn't happen in the past, the access was triggered by the frontend code, something there likely changed. Regardless, this global variable is still dangerous and error-prone, so we should avoid it.

Also, this commit fixes the issue that the panic hook does not work on Windows because the log filename contains ":", which is not allowed by the Windows file system.
2025-07-22 14:43:27 +08:00
SteveLauC
29aa26af94 chore: add a panic hook to catch panic msg (#793) 2025-07-22 10:34:27 +08:00
SteveLauC
f26031047c fix: refreshing Coco server should register it to SearchSource (#792) 2025-07-22 08:51:57 +08:00
BiggerRain
f1dfc5c730 fixed: chat message confusion (#782)
* fix: chat

* fix: chat

* chore: add session id

* fix: fixed incorrect taskbar icon display on linux (#783)

* fix: fixed incorrect taskbar icon display on linux

* docs: update changelog

* fix: fix data inconsistency issue on secondary pages (#784)

* chore: chat

* chore: chat

* chore: add logging message

* chore: chat

* chore: chat

* chore: add

* feat: add

* chore: chat end

* style: message width

---------

Co-authored-by: ayangweb <75017711+ayangweb@users.noreply.github.com>
Co-authored-by: medcl <m@medcl.net>
2025-07-21 21:17:20 +08:00
SteveLauC
74ed642a42 refactor: tighten up Coco servers state management (#790)
* refactor: tighten up Coco servers state management

* ignore unused warnings

* log out if the failed request has status 401
2025-07-21 20:39:16 +08:00
SteveLauC
57ab08fb6d chore: remove unused tauri cmd get_server_token (#787)
Found this tauri command while reading the code, then I realized that
token management logic should all be kept in the backend, there is no
need to expose it to the frontend. And indeed, searching for it in the
frontend code showed that it is not used at all.

```sh
$ cd src

$ rg get_server_token
commands/servers.ts
75:export function get_server_token(id: string): Promise<ServerTokenResponse> {
76:  return invokeWithErrorHandler(`get_server_token`, { id });
```

So remove it.
2025-07-20 17:25:32 +08:00
ayangweb
b1e2c6961d fix: fixed incorrect taskbar icon display on linux (#783)
* fix: fixed incorrect taskbar icon display on linux

* docs: update changelog
2025-07-20 10:08:11 +08:00
SteveLauC
7b8b396368 fix: indexing apps does not respect search scope config (#773)
This commit fixes the issue that indexing applications does not
respect the search scope configuration, it always uses the default
values.
2025-07-18 16:26:34 +08:00
SteveLauC
7d0e7cd7dc fix: unregister ext hotkey when it gets deleted (#770)
This commit fixes the bug that when an extension gets uninstalled, its
registered hotkey won't be cleared.
2025-07-18 13:20:41 +08:00
SteveLauC
14fbf2ac5d refactor: do status code check before deserializing response (#767)
* refactor: do status code check before deserializing response

This commit adds a status code check to the following requests, only when
this check passes, we deserialize the response JSON body:

- get_connectors_by_server
- mcp_server_search
- datasource_search

A helper function `status_code_check(response, allowed_status_codes)`
is added to make refactoring easier.

* chore: release notes
2025-07-17 15:08:14 +08:00
SteveLauC
494e2f0d8a chore: Coco app http request headers (#744)
Add the following HTTP headers when making HTTP requests:

- X-OS-NAME
- X-OS-VER
- X-OS-ARCH
- X-APP-NAME
- X-APP-VER
- X-APP-LANG
2025-07-17 11:31:19 +08:00
SteveLauC
0b5e31a476 chore(deps): bump the windows crate (#766)
This commit bumps the windows crate from "0.60.0" to "0.61.3", it should
solve the CI issue happened here[1]:

```text
error[E0277]: `DBOBJECT` doesn't implement `Debug`
     --> C:\Users\runneradmin\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\windows-0.60.0\src\Windows\Win32\System\Search\mod.rs:21828:5
      |
21826 | #[derive(Clone, Debug, PartialEq)]
      |                 ----- in this derive macro expansion
21827 | pub struct SSVARIANT_0_4 {
21828 |     pub dbobj: DBOBJECT,
      |     ^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `DBOBJECT`
      |
      = note: add `#[derive(Debug)]` to `DBOBJECT` or manually `impl Debug for DBOBJECT`
```

[1]: https://github.com/infinilabs/ci/actions/runs/16314479643/job/46076989290
2025-07-16 17:10:32 +08:00
SteveLauC
c8a723ed9d feat: file search for Windows (#762)
This commit implements the file search extension for Windows platforms using the [Windows Search](https://learn.microsoft.com/en-us/windows/win32/search/-search-3x-wds-qryidx-overview) functionality.

Something to note:

1. Searching by file content is not natively supported. Coco would search for all the columns (attributes/fields within the index) with this option:

```rust
        SearchBy::NameAndContents => {
            // Windows File Search does not support searching by file content.
            //
            // `CONTAINS('query_string')` would search all columns for `query_string`,
            // this is the closest solution we have.
            format!("((System.FileName LIKE '%{query_string}%') OR CONTAINS('{query_string}'))")
        }
```

2. Tests have been added, but they failed in our CI for unknown reasons so I disabled them:

```rust
// Skip these tests in our CI, they fail with the following error 
// "SQL is invalid: "0x80041820""
// 
// I have no idea about the underlying root cause
#[cfg(all(test, not(ci)))]
mod test {
```

3. The Windows Search index is not real-time and can return obsolete results. Opening the returned documents could fail if the chosen file has been deleted or moved.
2025-07-16 09:11:53 +08:00
ayangweb
e8bd970cdb refactor: updated the upload endpoint for attachments (#759) 2025-07-10 18:20:32 +08:00
Medcl
5b034c28ac chore: make optional fields optional (#758)
* chore: make optional fields optional

* chore: update docs
2025-07-10 18:06:05 +08:00
ayangweb
b17949fe29 refactor: enabling the upload file component (#755)
* refactor: enabling the upload file component

* update
2025-07-10 17:26:44 +08:00
SteveLauC
5d37420109 feat: tauri command get_file_icon() (#756) 2025-07-10 16:51:34 +08:00
BiggerRain
4d11afe18e chore: assistant params & styles (#753)
* chore: add

* chore: add

* chore: assistant params & styles

* docs: update notes
2025-07-10 11:47:10 +08:00
SteveLauC
0c0291c8c0 chore: rename QuickLink/quick_link to Quicklink/quicklink (#752)
* chore: rename QuickLink/quick_link to Quicklink/quicklink

Standardize varaible naming to match the correct term: "Quicklink" and "quicklink".
This updates all incorrect variants such as "QuickLink" and "quick_link".

* chore: release notes
2025-07-10 10:18:57 +08:00
ayangweb
cca672b2cb feat: text to speech now powered by LLM (#750)
* feat: support text to speech

* chore: receive bytes stream

* chore: update testing code

* feat: mp3 paly

* update

* docs: update changelog

* update

* update

* update

---------

Co-authored-by: medcl <m@medcl.net>
Co-authored-by: rain9 <15911122312@163.com>
2025-07-10 10:16:51 +08:00
SteveLauC
c1c4e0db7b chore: bump dep applications-rs (#751)
* chore: bump dep applications-rs

Currently Coco depends on atty v0.2.14, a crate that has
[vulnerability](https://github.com/infinilabs/coco-app/security/dependabot/25),
here is the dependency chain:

```
coco -> applications-rs -> freedesktop-file-parser 0.1.0 -> atty 0.2.14
```

I bumped the [`freedesktop-file-parser`](7bdb070e45)
crate in our applications-rs crate, which would eliminate the `atty` crate
from the chain to fix the vulnerability.

This commit bumps the applications-rs crate to include the above change.

* chore: release notes
2025-07-09 18:52:17 +08:00
ayangweb
074a7c8b0a fix: prevent window from hiding when moved on Windows (#748)
* fix: prevent window from hiding when moved on Windows

* docs: update changelog

* update
2025-07-09 16:30:41 +08:00
SteveLauC
bc524e19db refactor: adjust extension code hierarchy (#747)
* refactor: adjust extension code hierarchy

In this commit, I refactored the extension code structure.

* We can only install third-party extensions so the `store.rs` file should
  belong to the `third_party` directory.

* Move tauri command `uninstall_extension()` to `extension/mod.rs` from
  `third_party.rs` since one can uninstall an extension regardless of
  how you installed it.

* Refactor the `install_extension_from_store()` function, add more
  descriptive code comments.

Also, a trivial change, bump Rust toolchain and edition to use the
[let-chains](https://blog.rust-lang.org/2025/06/26/Rust-1.88.0/#let-chains) syntax.

* chore: release notes
2025-07-09 16:28:59 +08:00
SteveLauC
05f70d26d9 chore: replace meval-rs with our fork to clear dep warning (#745)
* chore: replace meval-rs with our fork to clear dep warning

This commit replaces the meval-rs dependency with our
[fork](https://github.com/infinilabs/meval-rs). The original meval-rs
crate has not been maintained for a long time and uses nom 1.0, a crate
that was released 9 years ago, which would be rejected by future Rust
compiler because it contains outdated Rust syntaxes. This is the reason
why we are seeing the following warning:

```
warning: the following packages contain code that will be rejected by a future version of Rust: nom v1.2.4
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 1
```

Switching to our fork would solve this warning.

* chore: release notes
2025-07-08 15:39:58 +08:00
SteveLauC
ab26dc7c6a fix(file search): searching by name&content does not search file name (#743)
* fix(file search): searching by name&content does not search file name

* release note
2025-07-08 09:21:43 +08:00