Rename app from oAI to Confab
"oAI" reads as easily confused with OpenAI, both visually and in casual conversation. Renamed to "Confab" throughout: Xcode target/scheme/bundle ID (com.oai.Confab), Info.plist and Help Book identity, all user-facing UI text, internal Log subsystem and color identifiers, localization catalogs (6 languages, including a proper reworded/retranslated Intel-deprecation notice), Help Book HTML content, and docs (README/DEVELOPMENT/PRIVACY/SECURITY). Deliberately cosmetic-only: the on-disk data folder (~/Library/Application Support/oAI/), database/backup filenames, Keychain service identifiers, and EncryptionService's key-derivation inputs are all left untouched so existing conversations, settings, and stored API keys survive the update with zero migration and no re-entering credentials. Verified live: a real signed build successfully decrypted a stored API key and loaded an existing conversation database after the bundle ID change. Also includes a small already-completed, previously uncommitted model-release-date feature (ModelInfo/OpenRouterModels/ OpenRouterProvider/ModelInfoView) that happened to share several files with this rename. Gitignored on this branch and updated on disk but not part of this commit: CLAUDE.md, RELEASE_NOTES.md, and the build*.sh scripts.
This commit is contained in:
+7
-7
@@ -1,4 +1,4 @@
|
||||
# oAI — Development Guide
|
||||
# Confab — Development Guide
|
||||
|
||||
## Project Structure
|
||||
|
||||
@@ -47,7 +47,7 @@ oAI/
|
||||
│ └── EmailHandlerService.swift # Email AI responder
|
||||
│
|
||||
└── Resources/
|
||||
└── oAI.help/ # macOS Help Book
|
||||
└── Confab.help/ # macOS Help Book
|
||||
```
|
||||
|
||||
## Key Technologies
|
||||
@@ -76,16 +76,16 @@ oAI/
|
||||
|
||||
```bash
|
||||
# Clean build
|
||||
xcodebuild clean -scheme oAI
|
||||
xcodebuild clean -scheme Confab
|
||||
|
||||
# Debug build
|
||||
xcodebuild -scheme oAI -configuration Debug
|
||||
xcodebuild -scheme Confab -configuration Debug
|
||||
|
||||
# Run tests
|
||||
xcodebuild test -scheme oAI
|
||||
xcodebuild test -scheme Confab
|
||||
```
|
||||
|
||||
**Output:** `~/Library/Developer/Xcode/DerivedData/oAI-*/Build/Products/Debug/oAI.app`
|
||||
**Output:** `~/Library/Developer/Xcode/DerivedData/oAI-*/Build/Products/Debug/Confab.app`
|
||||
|
||||
In Xcode: `⌘B` build, `⌘R` run, `⌘⇧K` clean, `⌘.` stop.
|
||||
|
||||
@@ -96,7 +96,7 @@ XProtect 5331 flags Debug builds (bash + IMAP + file access = RAT signature matc
|
||||
## Logs
|
||||
|
||||
```
|
||||
~/Library/Logs/oAI.log
|
||||
~/Library/Logs/Confab.log
|
||||
```
|
||||
|
||||
## Performance Notes
|
||||
|
||||
+15
-15
@@ -2,38 +2,38 @@
|
||||
|
||||
**Last updated:** 2026-07-27
|
||||
|
||||
oAI is a native macOS app. This document describes what data it handles, where it goes, and what control you have over it.
|
||||
Confab is a native macOS app. This document describes what data it handles, where it goes, and what control you have over it.
|
||||
|
||||
## Summary
|
||||
|
||||
- oAI does not collect analytics, telemetry, crash reports, or usage data of any kind. There is no tracking SDK in the app, and the developer has no visibility into how you use it.
|
||||
- Everything oAI stores — conversations, settings, command history — stays in a local SQLite database on your Mac, unless you explicitly enable a sync or backup feature.
|
||||
- Confab does not collect analytics, telemetry, crash reports, or usage data of any kind. There is no tracking SDK in the app, and the developer has no visibility into how you use it.
|
||||
- Everything Confab stores — conversations, settings, command history — stays in a local SQLite database on your Mac, unless you explicitly enable a sync or backup feature.
|
||||
- The only data that leaves your Mac is data you choose to send: messages sent to the AI provider/model you've selected, and, for optional integrations you turn on yourself (email, Anytype, Paperless-NGX, external MCP servers), whatever those specific features are configured to talk to.
|
||||
- oAI is free and open source. You can read exactly what it does at **https://gitlab.pm/rune/oai-swift**.
|
||||
- Confab is free and open source. You can read exactly what it does at **https://gitlab.pm/rune/oai-swift**.
|
||||
|
||||
## Data stored locally
|
||||
|
||||
oAI keeps its data in a SQLite database at `~/Library/Application Support/oAI/oai_conversations.db`:
|
||||
Confab keeps its data in a SQLite database at `~/Library/Application Support/oAI/oai_conversations.db`:
|
||||
- Saved conversations and messages
|
||||
- App settings and feature toggles
|
||||
- Command history (last 5,000 entries, auto-pruned)
|
||||
- Email processing logs, if the email assistant feature is used
|
||||
|
||||
Log files (no message content, no credentials) are written to `~/Library/Logs/oAI.log` for troubleshooting.
|
||||
Log files (no message content, no credentials) are written to `~/Library/Logs/Confab.log` for troubleshooting.
|
||||
|
||||
None of this is sent anywhere by oAI itself. Deleting the database file (or uninstalling the app) removes it.
|
||||
None of this is sent anywhere by Confab itself. Deleting the database file (or uninstalling the app) removes it.
|
||||
|
||||
## API keys and credentials
|
||||
|
||||
- Provider API keys (OpenRouter, Anthropic, OpenAI, Google) are stored in the macOS **Keychain**, not the database, and not in plaintext anywhere on disk.
|
||||
- A small number of other credentials that can't use Keychain directly (e.g. email account password, if you set up the email assistant) are stored **encrypted at rest** in the local database, using a key derived from your Mac's hardware identifier — this key never leaves your device and isn't transmitted anywhere.
|
||||
- oAI never transmits your API keys or credentials to anyone other than the service they belong to (e.g. your OpenRouter key is only ever sent to OpenRouter's API).
|
||||
- Confab never transmits your API keys or credentials to anyone other than the service they belong to (e.g. your OpenRouter key is only ever sent to OpenRouter's API).
|
||||
|
||||
## AI providers — where your messages actually go
|
||||
|
||||
oAI is a client for AI providers you choose and configure yourself: OpenRouter, Anthropic, OpenAI, Google, Ollama (self-hosted, stays local), and Apple's on-device Foundation Models (macOS 26+, never leaves your Mac). When you send a message, its content — plus whatever conversation history and system prompt context oAI includes — is sent to whichever provider and model you have selected for that conversation.
|
||||
Confab is a client for AI providers you choose and configure yourself: OpenRouter, Anthropic, OpenAI, Google, Ollama (self-hosted, stays local), and Apple's on-device Foundation Models (macOS 26+, never leaves your Mac). When you send a message, its content — plus whatever conversation history and system prompt context Confab includes — is sent to whichever provider and model you have selected for that conversation.
|
||||
|
||||
Each provider handles that data under its own privacy policy, over which oAI has no control:
|
||||
Each provider handles that data under its own privacy policy, over which Confab has no control:
|
||||
- OpenRouter: https://openrouter.ai/privacy
|
||||
- Anthropic: https://www.anthropic.com/privacy
|
||||
- OpenAI: https://openai.com/privacy
|
||||
@@ -50,14 +50,14 @@ The following are **off by default** and require you to explicitly enable them i
|
||||
- **Bash command execution** — lets the AI run shell commands on your Mac. Off by default; when on, can optionally require your approval before each command runs.
|
||||
- **MCP file access** — lets the AI read/write files in folders you explicitly allow. Includes PDF text extraction. Folder access is scoped to what you approve, nothing outside it.
|
||||
- **Email assistant (IMAP/SMTP)** — polls a mailbox you configure and can send AI-generated replies. Your mail server credentials and the email content it processes are stored locally as described above; email content is sent to your selected AI provider to generate a response.
|
||||
- **Anytype / Paperless-NGX integrations** — connect to instances you run yourself (typically on your own network or self-hosted server). Data flows directly between oAI and your own instance.
|
||||
- **External MCP servers** — you can connect any third-party MCP server of your choosing; oAI has no visibility into or control over what that server does with data passed to it.
|
||||
- **Anytype / Paperless-NGX integrations** — connect to instances you run yourself (typically on your own network or self-hosted server). Data flows directly between Confab and your own instance.
|
||||
- **External MCP servers** — you can connect any third-party MCP server of your choosing; Confab has no visibility into or control over what that server does with data passed to it.
|
||||
- **Semantic search / embeddings** — if enabled, message text is sent to your selected embedding provider (OpenAI, OpenRouter, or Google) to generate vector embeddings, which are then stored locally.
|
||||
- **Web search** — when online mode is enabled, your query may be sent to DuckDuckGo, Google Search, or included as `:online` context to OpenRouter, depending on configuration.
|
||||
|
||||
## Crash reports
|
||||
|
||||
oAI does not include any crash reporting or analytics SDK, and does not automatically collect or transmit crash data. If oAI crashes, macOS writes a local crash log to your own Mac (viewable in Console.app), but it is not sent to the developer automatically — Apple's automatic crash-sharing pipeline for Developer ID–distributed apps like oAI (i.e. not sold through the Mac App Store) does not route reports back to the developer. If you'd like to help fix a crash, you're welcome to attach that log when reporting an issue — see `SECURITY.md` / the contact link below for how.
|
||||
Confab does not include any crash reporting or analytics SDK, and does not automatically collect or transmit crash data. If Confab crashes, macOS writes a local crash log to your own Mac (viewable in Console.app), but it is not sent to the developer automatically — Apple's automatic crash-sharing pipeline for Developer ID–distributed apps like Confab (i.e. not sold through the Mac App Store) does not route reports back to the developer. If you'd like to help fix a crash, you're welcome to attach that log when reporting an issue — see `SECURITY.md` / the contact link below for how.
|
||||
|
||||
## iCloud backup
|
||||
|
||||
@@ -73,11 +73,11 @@ Since everything is local, you're always in full control:
|
||||
|
||||
## Children's privacy
|
||||
|
||||
oAI is not directed at children and does not knowingly collect data from children.
|
||||
Confab is not directed at children and does not knowingly collect data from children.
|
||||
|
||||
## Changes to this policy
|
||||
|
||||
If oAI's data handling changes in a meaningful way, this document will be updated and the date at the top revised. Given the app's local-first design, we don't expect that to happen often.
|
||||
If Confab's data handling changes in a meaningful way, this document will be updated and the date at the top revised. Given the app's local-first design, we don't expect that to happen often.
|
||||
|
||||
## Contact
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# oAI
|
||||
# Confab
|
||||
|
||||
A powerful native macOS AI chat application with support for multiple providers (including on-device Apple Intelligence), MCP-powered tool access, advanced memory management, and seamless Git synchronization.
|
||||
|
||||

|
||||

|
||||
|
||||
## Features
|
||||
|
||||
@@ -16,7 +16,7 @@ A powerful native macOS AI chat application with support for multiple providers
|
||||
### 💬 Core Chat Capabilities
|
||||
- **Streaming Responses** - Real-time token streaming for faster interactions
|
||||
- **Conversation Management** - Save, load, export, and search conversations, organized into folders
|
||||
- **Unsaved Changes & Crash Recovery** - Standard Mac-style save prompt on New Chat/Clear/Load/Quit with unsaved messages; the in-progress conversation (and selected model) is also mirrored to disk periodically and offered back on next launch if oAI crashes or is force-quit
|
||||
- **Unsaved Changes & Crash Recovery** - Standard Mac-style save prompt on New Chat/Clear/Load/Quit with unsaved messages; the in-progress conversation (and selected model) is also mirrored to disk periodically and offered back on next launch if Confab crashes or is force-quit
|
||||
- **Combine Conversations** - Merge 2+ saved conversations, either by chronological concatenation or AI-assisted synthesis
|
||||
- **File Attachments** - Support for text files, images, and PDFs
|
||||
- **Image Generation** - Create images with supported models (DALL-E, Flux, etc.) - renders inline in chat
|
||||
@@ -75,7 +75,7 @@ Seamless conversation backup and sync across devices:
|
||||

|
||||
|
||||
### 📚 Anytype Integration
|
||||
Connect oAI to your local [Anytype](https://anytype.io) knowledge base:
|
||||
Connect Confab to your local [Anytype](https://anytype.io) knowledge base:
|
||||
- **Search** - find objects by keyword across all spaces or within a specific one
|
||||
- **Read** - open any object and read its full markdown content
|
||||
- **Append** - add content to the end of an existing object without touching existing text or internal links (preferred over full update)
|
||||
@@ -84,7 +84,7 @@ Connect oAI to your local [Anytype](https://anytype.io) knowledge base:
|
||||
- All data stays on your machine (local API, no cloud)
|
||||
|
||||
### 🛰️ Jarvis Integration
|
||||
Connect oAI to a self-hosted [Jarvis](https://jarvis.pm) agent-automation server:
|
||||
Connect Confab to a self-hosted [Jarvis](https://jarvis.pm) agent-automation server:
|
||||
- **Agent Management** - List, create, edit, enable/disable, run, and stop agents
|
||||
- **Run History** - Expandable per-run output with status and timing
|
||||
- **Usage & Credits** - Per-agent usage stats and credits balance
|
||||
@@ -129,17 +129,17 @@ Automated email responses powered by AI:
|
||||
|
||||
Download the latest release from the [Releases page](https://gitlab.pm/rune/oai-swift/releases). Two builds are available:
|
||||
|
||||
- **oAI-x.x.x-AppleSilicon.dmg** - for Macs with an Apple Silicon chip (M1 and later)
|
||||
- **oAI-x.x.x-Universal.dmg** - runs natively on both Apple Silicon and Intel Macs
|
||||
- **Confab-x.x.x-AppleSilicon.dmg** - for Macs with an Apple Silicon chip (M1 and later)
|
||||
- **Confab-x.x.x-Universal.dmg** - runs natively on both Apple Silicon and Intel Macs
|
||||
|
||||
### Installing from DMG
|
||||
|
||||
1. Open the downloaded `.dmg` file
|
||||
2. Drag **oAI.app** into the **Applications** folder
|
||||
2. Drag **Confab.app** into the **Applications** folder
|
||||
3. Eject the DMG
|
||||
4. Launch oAI from Applications or Spotlight
|
||||
4. Launch Confab from Applications or Spotlight
|
||||
|
||||
Release DMGs are signed and notarized by Apple, so oAI opens normally on first launch with no Gatekeeper warning.
|
||||
Release DMGs are signed and notarized by Apple, so Confab opens normally on first launch with no Gatekeeper warning.
|
||||
|
||||
### Requirements
|
||||
- macOS 26.2 or later
|
||||
@@ -329,16 +329,16 @@ AI-powered email auto-responder:
|
||||
|
||||
## License
|
||||
|
||||
oAI is source-available under the **PolyForm Noncommercial License 1.0.0**.
|
||||
Confab is source-available under the **PolyForm Noncommercial License 1.0.0**.
|
||||
|
||||
This means you are free to use, study, modify, and share oAI for any noncommercial purpose. Commercial use — including selling oAI or any part of it, standalone or bundled into another product or service — requires a separate commercial license.
|
||||
This means you are free to use, study, modify, and share Confab for any noncommercial purpose. Commercial use — including selling Confab or any part of it, standalone or bundled into another product or service — requires a separate commercial license.
|
||||
|
||||
See [LICENSE](LICENSE) for the full license text, or visit [polyformproject.org/licenses/noncommercial/1.0.0](https://polyformproject.org/licenses/noncommercial/1.0.0). For commercial licensing inquiries, contact Rune Olsen via [oai.pm](https://oai.pm).
|
||||
|
||||
|
||||
## Privacy & Security
|
||||
|
||||
- [Privacy Policy](PRIVACY.md) - what oAI stores, what it sends to AI providers, and what stays local
|
||||
- [Privacy Policy](PRIVACY.md) - what Confab stores, what it sends to AI providers, and what stays local
|
||||
- [Security Policy](SECURITY.md) - supported versions and how to report a vulnerability
|
||||
|
||||
|
||||
@@ -355,7 +355,7 @@ See [LICENSE](LICENSE) for the full license text, or visit [polyformproject.org/
|
||||
|
||||
## Disclaimer
|
||||
|
||||
oAI can take real actions on your behalf when you enable optional features - it can run shell commands, read/write files, send emails, and create calendar events or reminders. Write actions are gated behind explicit opt-in settings and, for bash/calendar/reminders, an on-screen approval prompt before they run. Review your permission settings carefully before use. Content you send is processed by whichever AI provider and model you have selected - see [PRIVACY.md](PRIVACY.md) for details on what goes where. oAI is provided "as is" without warranty of any kind - the author accepts no responsibility for actions taken by the agent or any consequences thereof. See [LICENSE](LICENSE) for full terms.
|
||||
Confab can take real actions on your behalf when you enable optional features - it can run shell commands, read/write files, send emails, and create calendar events or reminders. Write actions are gated behind explicit opt-in settings and, for bash/calendar/reminders, an on-screen approval prompt before they run. Review your permission settings carefully before use. Content you send is processed by whichever AI provider and model you have selected - see [PRIVACY.md](PRIVACY.md) for details on what goes where. Confab is provided "as is" without warranty of any kind - the author accepts no responsibility for actions taken by the agent or any consequences thereof. See [LICENSE](LICENSE) for full terms.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+5
-5
@@ -2,23 +2,23 @@
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Only the latest publicly released version of oAI is supported with security fixes. Please update to the latest version before reporting an issue, and confirm it still reproduces there.
|
||||
Only the latest publicly released version of Confab is supported with security fixes. Please update to the latest version before reporting an issue, and confirm it still reproduces there.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a security vulnerability in oAI, please report it privately rather than opening a public GitHub issue.
|
||||
If you discover a security vulnerability in Confab, please report it privately rather than opening a public GitHub issue.
|
||||
|
||||
To report a security concern, use the contact form at **[https://oai.pm/#contact](https://oai.pm/#contact)**.
|
||||
|
||||
Please include as much detail as possible:
|
||||
- A description of the vulnerability and its potential impact
|
||||
- Steps to reproduce the issue
|
||||
- The oAI version and macOS version you're using
|
||||
- Any relevant logs (`~/Library/Logs/oAI.log`), with sensitive data redacted
|
||||
- The Confab version and macOS version you're using
|
||||
- Any relevant logs (`~/Library/Logs/Confab.log`), with sensitive data redacted
|
||||
|
||||
## Scope
|
||||
|
||||
oAI is a native macOS app that stores conversations, settings, and API keys locally (SQLite database and Keychain). Areas of particular interest for security reports include:
|
||||
Confab is a native macOS app that stores conversations, settings, and API keys locally (SQLite database and Keychain). Areas of particular interest for security reports include:
|
||||
- API key handling and Keychain storage
|
||||
- MCP file access permission checks
|
||||
- Bash execution approval flow
|
||||
|
||||
@@ -22,17 +22,17 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
A550A6622F3B72EA00136F2B /* oAI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = oAI.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A586FF5130122589002CFF95 /* oAITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = oAITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A550A6622F3B72EA00136F2B /* Confab.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Confab.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A586FF5130122589002CFF95 /* ConfabTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ConfabTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
911C4D0E69E11B84C61453DC /* Exceptions for "oAI" folder in "oAI" target */ = {
|
||||
911C4D0E69E11B84C61453DC /* Exceptions for "oAI" folder in "Confab" target */ = {
|
||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||
membershipExceptions = (
|
||||
Info.plist,
|
||||
);
|
||||
target = A550A6612F3B72EA00136F2B /* oAI */;
|
||||
target = A550A6612F3B72EA00136F2B /* Confab */;
|
||||
};
|
||||
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
A550A6642F3B72EA00136F2B /* oAI */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
exceptions = (
|
||||
911C4D0E69E11B84C61453DC /* Exceptions for "oAI" folder in "oAI" target */,
|
||||
911C4D0E69E11B84C61453DC /* Exceptions for "oAI" folder in "Confab" target */,
|
||||
);
|
||||
path = oAI;
|
||||
sourceTree = "<group>";
|
||||
@@ -84,8 +84,8 @@
|
||||
A550A6632F3B72EA00136F2B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A550A6622F3B72EA00136F2B /* oAI.app */,
|
||||
A586FF5130122589002CFF95 /* oAITests.xctest */,
|
||||
A550A6622F3B72EA00136F2B /* Confab.app */,
|
||||
A586FF5130122589002CFF95 /* ConfabTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -93,9 +93,9 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
A550A6612F3B72EA00136F2B /* oAI */ = {
|
||||
A550A6612F3B72EA00136F2B /* Confab */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A550A66D2F3B72EC00136F2B /* Build configuration list for PBXNativeTarget "oAI" */;
|
||||
buildConfigurationList = A550A66D2F3B72EC00136F2B /* Build configuration list for PBXNativeTarget "Confab" */;
|
||||
buildPhases = (
|
||||
A550A65E2F3B72EA00136F2B /* Sources */,
|
||||
A550A65F2F3B72EA00136F2B /* Frameworks */,
|
||||
@@ -108,18 +108,18 @@
|
||||
fileSystemSynchronizedGroups = (
|
||||
A550A6642F3B72EA00136F2B /* oAI */,
|
||||
);
|
||||
name = oAI;
|
||||
name = Confab;
|
||||
packageProductDependencies = (
|
||||
A550A6812F3B730000136F2B /* GRDB */,
|
||||
A52B47512F3E45BA004200E2 /* MarkdownUI */,
|
||||
);
|
||||
productName = oAI;
|
||||
productReference = A550A6622F3B72EA00136F2B /* oAI.app */;
|
||||
productName = Confab;
|
||||
productReference = A550A6622F3B72EA00136F2B /* Confab.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
A586FF5030122589002CFF95 /* oAITests */ = {
|
||||
A586FF5030122589002CFF95 /* ConfabTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A586FF5930122589002CFF95 /* Build configuration list for PBXNativeTarget "oAITests" */;
|
||||
buildConfigurationList = A586FF5930122589002CFF95 /* Build configuration list for PBXNativeTarget "ConfabTests" */;
|
||||
buildPhases = (
|
||||
A586FF4D30122589002CFF95 /* Sources */,
|
||||
A586FF4E30122589002CFF95 /* Frameworks */,
|
||||
@@ -133,11 +133,11 @@
|
||||
fileSystemSynchronizedGroups = (
|
||||
A586FF5230122589002CFF95 /* oAITests */,
|
||||
);
|
||||
name = oAITests;
|
||||
name = ConfabTests;
|
||||
packageProductDependencies = (
|
||||
);
|
||||
productName = oAITests;
|
||||
productReference = A586FF5130122589002CFF95 /* oAITests.xctest */;
|
||||
productName = ConfabTests;
|
||||
productReference = A586FF5130122589002CFF95 /* ConfabTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
@@ -182,8 +182,8 @@
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
A550A6612F3B72EA00136F2B /* oAI */,
|
||||
A586FF5030122589002CFF95 /* oAITests */,
|
||||
A550A6612F3B72EA00136F2B /* Confab */,
|
||||
A586FF5030122589002CFF95 /* ConfabTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -225,7 +225,7 @@
|
||||
/* Begin PBXTargetDependency section */
|
||||
A586FF5630122589002CFF95 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = A550A6612F3B72EA00136F2B /* oAI */;
|
||||
target = A550A6612F3B72EA00136F2B /* Confab */;
|
||||
targetProxy = A586FF5530122589002CFF95 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
@@ -358,7 +358,8 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = oAI/oAI.entitlements;
|
||||
CODE_SIGN_ENTITLEMENTS = oAI/Confab.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
@@ -367,11 +368,12 @@
|
||||
ENABLE_USER_SELECTED_FILES = readonly;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = oAI/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Confab;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
INFOPLIST_KEY_NSCalendarsFullAccessUsageDescription = "oAI can read and create calendar events when you ask it to, if you enable Calendar access in Settings.";
|
||||
INFOPLIST_KEY_NSContactsUsageDescription = "oAI can search your contacts when you ask it to, if you enable Contacts access in Settings.";
|
||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "oAI can use your current location to answer questions, if you enable Location & Maps access in Settings.";
|
||||
INFOPLIST_KEY_NSRemindersFullAccessUsageDescription = "oAI can read and create reminders when you ask it to, if you enable Reminders access in Settings.";
|
||||
INFOPLIST_KEY_NSCalendarsFullAccessUsageDescription = "Confab can read and create calendar events when you ask it to, if you enable Calendar access in Settings.";
|
||||
INFOPLIST_KEY_NSContactsUsageDescription = "Confab can search your contacts when you ask it to, if you enable Contacts access in Settings.";
|
||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Confab can use your current location to answer questions, if you enable Location & Maps access in Settings.";
|
||||
INFOPLIST_KEY_NSRemindersFullAccessUsageDescription = "Confab can read and create reminders when you ask it to, if you enable Reminders access in Settings.";
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
|
||||
@@ -387,7 +389,7 @@
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 26.2;
|
||||
MARKETING_VERSION = 2.4.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.oai.oAI;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.oai.Confab;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
REGISTER_APP_GROUPS = YES;
|
||||
SDKROOT = auto;
|
||||
@@ -408,7 +410,8 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = oAI/oAI.entitlements;
|
||||
CODE_SIGN_ENTITLEMENTS = oAI/Confab.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
@@ -417,11 +420,12 @@
|
||||
ENABLE_USER_SELECTED_FILES = readonly;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = oAI/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Confab;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
INFOPLIST_KEY_NSCalendarsFullAccessUsageDescription = "oAI can read and create calendar events when you ask it to, if you enable Calendar access in Settings.";
|
||||
INFOPLIST_KEY_NSContactsUsageDescription = "oAI can search your contacts when you ask it to, if you enable Contacts access in Settings.";
|
||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "oAI can use your current location to answer questions, if you enable Location & Maps access in Settings.";
|
||||
INFOPLIST_KEY_NSRemindersFullAccessUsageDescription = "oAI can read and create reminders when you ask it to, if you enable Reminders access in Settings.";
|
||||
INFOPLIST_KEY_NSCalendarsFullAccessUsageDescription = "Confab can read and create calendar events when you ask it to, if you enable Calendar access in Settings.";
|
||||
INFOPLIST_KEY_NSContactsUsageDescription = "Confab can search your contacts when you ask it to, if you enable Contacts access in Settings.";
|
||||
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Confab can use your current location to answer questions, if you enable Location & Maps access in Settings.";
|
||||
INFOPLIST_KEY_NSRemindersFullAccessUsageDescription = "Confab can read and create reminders when you ask it to, if you enable Reminders access in Settings.";
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
|
||||
@@ -437,7 +441,7 @@
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 26.2;
|
||||
MARKETING_VERSION = 2.4.4;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.oai.oAI;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.oai.Confab;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
REGISTER_APP_GROUPS = YES;
|
||||
SDKROOT = auto;
|
||||
@@ -463,7 +467,7 @@
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 27.0;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.oai.oAITests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.oai.ConfabTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = NO;
|
||||
@@ -471,7 +475,7 @@
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/oAI.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/oAI";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Confab.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Confab";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -485,7 +489,7 @@
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 27.0;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.oai.oAITests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.oai.ConfabTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = NO;
|
||||
@@ -493,7 +497,7 @@
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/oAI.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/oAI";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Confab.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Confab";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -509,7 +513,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A550A66D2F3B72EC00136F2B /* Build configuration list for PBXNativeTarget "oAI" */ = {
|
||||
A550A66D2F3B72EC00136F2B /* Build configuration list for PBXNativeTarget "Confab" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A550A66E2F3B72EC00136F2B /* Debug */,
|
||||
@@ -518,7 +522,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A586FF5930122589002CFF95 /* Build configuration list for PBXNativeTarget "oAITests" */ = {
|
||||
A586FF5930122589002CFF95 /* Build configuration list for PBXNativeTarget "ConfabTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A586FF5730122589002CFF95 /* Debug */,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<false/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<false/>
|
||||
<key>com.apple.security.personal-information.calendars</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.reminders</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.addressbook</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.location</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
+2
-2
@@ -3,9 +3,9 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleHelpBookFolder</key>
|
||||
<string>oAI.help</string>
|
||||
<string>Confab.help</string>
|
||||
<key>CFBundleHelpBookName</key>
|
||||
<string>oAI Help</string>
|
||||
<string>Confab Help</string>
|
||||
<key>CFBundleLocalizations</key>
|
||||
<array>
|
||||
<string>en</string>
|
||||
|
||||
+45
-45
@@ -523,36 +523,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"• No credentials needed in oAI" : {
|
||||
"• No credentials needed in Confab" : {
|
||||
"localizations" : {
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "• Ingen legitimationsoplysninger nødvendige i oAI"
|
||||
"value" : "• Ingen legitimationsoplysninger nødvendige i Confab"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "• Keine Zugangsdaten in oAI erforderlich"
|
||||
"value" : "• Keine Zugangsdaten in Confab erforderlich"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "• Aucun identifiant requis dans oAI"
|
||||
"value" : "• Aucun identifiant requis dans Confab"
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "• Ingen legitimasjon nødvendig i oAI"
|
||||
"value" : "• Ingen legitimasjon nødvendig i Confab"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "• Inga inloggningsuppgifter behövs i oAI"
|
||||
"value" : "• Inga inloggningsuppgifter behövs i Confab"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1878,36 +1878,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"About oAI" : {
|
||||
"About Confab" : {
|
||||
"localizations" : {
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Om oAI"
|
||||
"value" : "Om Confab"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Über oAI"
|
||||
"value" : "Über Confab"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "À propos d'oAI"
|
||||
"value" : "À propos de Confab"
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Om oAI"
|
||||
"value" : "Om Confab"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Om oAI"
|
||||
"value" : "Om Confab"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4666,36 +4666,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Controls which messages are written to ~/Library/Logs/oAI.log" : {
|
||||
"Controls which messages are written to ~/Library/Logs/Confab.log" : {
|
||||
"localizations" : {
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Styrer hvilke beskeder der skrives til ~/Library/Logs/oAI.log"
|
||||
"value" : "Styrer hvilke beskeder der skrives til ~/Library/Logs/Confab.log"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Steuert, welche Nachrichten in ~/Library/Logs/oAI.log geschrieben werden"
|
||||
"value" : "Steuert, welche Nachrichten in ~/Library/Logs/Confab.log geschrieben werden"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Contrôle quels messages sont écrits dans ~/Library/Logs/oAI.log"
|
||||
"value" : "Contrôle quels messages sont écrits dans ~/Library/Logs/Confab.log"
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Styrer hvilke meldinger som skrives til ~/Library/Logs/oAI.log"
|
||||
"value" : "Styrer hvilke meldinger som skrives til ~/Library/Logs/Confab.log"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Styr vilka meddelanden som skrivs till ~/Library/Logs/oAI.log"
|
||||
"value" : "Styr vilka meddelanden som skrivs till ~/Library/Logs/Confab.log"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6795,36 +6795,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Example: oai-bot-x7k2m9p3@gmail.com" : {
|
||||
"Example: confab-bot-x7k2m9p3@gmail.com" : {
|
||||
"localizations" : {
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Example: oai-bot-x7k2m9p3@gmail.com"
|
||||
"value" : "Example: confab-bot-x7k2m9p3@gmail.com"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Example: oai-bot-x7k2m9p3@gmail.com"
|
||||
"value" : "Example: confab-bot-x7k2m9p3@gmail.com"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Exemple : oai-bot-x7k2m9p3@gmail.com"
|
||||
"value" : "Exemple : confab-bot-x7k2m9p3@gmail.com"
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Example: oai-bot-x7k2m9p3@gmail.com"
|
||||
"value" : "Example: confab-bot-x7k2m9p3@gmail.com"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Example: oai-bot-x7k2m9p3@gmail.com"
|
||||
"value" : "Example: confab-bot-x7k2m9p3@gmail.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9805,7 +9805,7 @@
|
||||
}
|
||||
},
|
||||
"Multi-provider AI chat client" : {
|
||||
"comment" : "A description of oAI.",
|
||||
"comment" : "A description of Confab.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
"da" : {
|
||||
@@ -10576,108 +10576,108 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"oAI" : {
|
||||
"Confab" : {
|
||||
"comment" : "The name of the app.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"oAI Help" : {
|
||||
"Confab Help" : {
|
||||
"localizations" : {
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI-hjælp"
|
||||
"value" : "Confab-hjælp"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI-Hilfe"
|
||||
"value" : "Confab-Hilfe"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Aide oAI"
|
||||
"value" : "Aide Confab"
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI-hjelp"
|
||||
"value" : "Confab-hjelp"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI-hjälp"
|
||||
"value" : "Confab-hjälp"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"oAI v2.4 is the last version to support Intel Macs and Rosetta. Starting with macOS 28, oAI will require Apple Silicon. Consider upgrading your Mac to continue receiving updates." : {
|
||||
"Confab (formerly oAI) v2.4 was the last version to support Intel Macs and Rosetta. Starting with macOS 28, Confab will require Apple Silicon. Consider upgrading your Mac to continue receiving updates." : {
|
||||
"comment" : "A warning that Intel Macs are no longer supported.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI v2.4 er den sidste version, der understøtter Intel-Mac og Rosetta. Fra macOS 28 vil oAI kræve Apple Silicon. Overvej at opgradere din Mac for at fortsætte med at få opdateringer."
|
||||
"value" : "Confab (tidligere oAI) v2.4 var den sidste version, der understøttede Intel-Mac og Rosetta. Fra macOS 28 vil Confab kræve Apple Silicon. Overvej at opgradere din Mac for at fortsætte med at få opdateringer."
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI v2.4 ist die letzte Version, die Intel-Macs und Rosetta unterstützt. Ab macOS 28 benötigt oAI Apple Silicon. Erwäge ein Upgrade deines Mac, um weiterhin Updates zu erhalten."
|
||||
"value" : "Confab (früher oAI) v2.4 war die letzte Version, die Intel-Macs und Rosetta unterstützte. Ab macOS 28 benötigt Confab Apple Silicon. Erwäge ein Upgrade deines Mac, um weiterhin Updates zu erhalten."
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI v2.4 est la dernière version à prendre en charge les Mac Intel et Rosetta. À partir de macOS 28, oAI nécessitera Apple Silicon. Envisage de mettre à niveau ton Mac pour continuer à recevoir des mises à jour."
|
||||
"value" : "Confab (anciennement oAI) v2.4 était la dernière version à prendre en charge les Mac Intel et Rosetta. À partir de macOS 28, Confab nécessitera Apple Silicon. Envisage de mettre à niveau ton Mac pour continuer à recevoir des mises à jour."
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI v2.4 er den siste versjonen som støtter Intel-Mac og Rosetta. Fra macOS 28 vil oAI kreve Apple Silicon. Vurder å oppgradere Mac-en din for å fortsette å få oppdateringer."
|
||||
"value" : "Confab (tidligere oAI) v2.4 var den siste versjonen som støttet Intel-Mac og Rosetta. Fra macOS 28 vil Confab kreve Apple Silicon. Vurder å oppgradere Mac-en din for å fortsette å få oppdateringer."
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI v2.4 är den sista versionen som stöder Intel-Mac och Rosetta. Från macOS 28 kommer oAI att kräva Apple Silicon. Överväg att uppgradera din Mac för att fortsätta få uppdateringar."
|
||||
"value" : "Confab (tidigare oAI) v2.4 var den sista versionen som stödde Intel-Mac och Rosetta. Från macOS 28 kommer Confab att kräva Apple Silicon. Överväg att uppgradera din Mac för att fortsätta få uppdateringar."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15616,7 +15616,7 @@
|
||||
}
|
||||
},
|
||||
"Update Available%@" : {
|
||||
"comment" : "A button that opens a website with information about a new version of oAI. The argument is the version number of the new version.",
|
||||
"comment" : "A button that opens a website with information about a new version of Confab. The argument is the version number of the new version.",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
"da" : {
|
||||
@@ -15998,7 +15998,7 @@
|
||||
}
|
||||
},
|
||||
"v%@" : {
|
||||
"comment" : "A label showing the current version of oAI.",
|
||||
"comment" : "A label showing the current version of Confab.",
|
||||
"extractionState" : "stale",
|
||||
"isCommentAutoGenerated" : true,
|
||||
"localizations" : {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AgentSkill.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// SKILL.md-style behavioral skills — markdown instruction files injected into the system prompt
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// Conversation.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Model for saved conversations
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// EmailLog.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Email processing log entry model
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// Folder.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Model for grouping saved conversations
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// HistoryEntry.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Command history entry model
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// JarvisModels.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Data models for the Jarvis (oAI-Web) API integration.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// Message.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Core message model for chat conversations
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// MockData.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Mock data for Phase 1 testing
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ModelCategory.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Category tags for AI models, inferred from model name/id/description.
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ModelInfo.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Model information and capabilities
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -33,6 +33,7 @@ struct ModelInfo: Identifiable, Codable, Hashable {
|
||||
var architecture: Architecture? = nil
|
||||
var topProvider: String? = nil
|
||||
var categories: [ModelCategory] = []
|
||||
var releaseDate: Date? = nil
|
||||
|
||||
struct Pricing: Codable, Hashable {
|
||||
let prompt: Double // per 1M tokens
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// SessionStats.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Session statistics tracking
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// Settings.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Application settings and configuration
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// Shortcut.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// User-defined slash command templates (prompt shortcuts/macros)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -3,11 +3,11 @@ import Foundation
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// UsageStats.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// All-time usage statistics (aggregated from the messages table)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AIProvider.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Protocol for AI provider implementations
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AnthropicProvider.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Anthropic Messages API provider with SSE streaming and tool support
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AppleFoundationProvider.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Apple Foundation Models provider (on-device Apple Intelligence)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// OllamaProvider.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Ollama local AI provider with JSON-lines streaming
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// OpenAIProvider.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// OpenAI API provider with SSE streaming and tool support
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// OpenRouterModels.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// OpenRouter API request and response models
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -330,6 +330,7 @@ struct OpenRouterModelsResponse: Codable {
|
||||
let architecture: Architecture?
|
||||
let supportedParameters: [String]?
|
||||
let outputModalities: [String]?
|
||||
let created: Int?
|
||||
|
||||
struct PricingData: Codable {
|
||||
let prompt: String
|
||||
@@ -357,6 +358,7 @@ struct OpenRouterModelsResponse: Codable {
|
||||
case architecture
|
||||
case supportedParameters = "supported_parameters"
|
||||
case outputModalities = "output_modalities"
|
||||
case created
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// OpenRouterProvider.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// OpenRouter AI provider implementation with SSE streaming
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -106,6 +106,7 @@ class OpenRouterProvider: AIProvider {
|
||||
},
|
||||
topProvider: modelData.id.components(separatedBy: "/").first
|
||||
)
|
||||
info.releaseDate = modelData.created.map { Date(timeIntervalSince1970: TimeInterval($0)) }
|
||||
info.categories = ModelCategory.infer(
|
||||
name: modelData.name,
|
||||
id: modelData.id,
|
||||
@@ -171,8 +172,8 @@ class OpenRouterProvider: AIProvider {
|
||||
urlRequest.httpMethod = "POST"
|
||||
urlRequest.addValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
|
||||
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
urlRequest.addValue("https://github.com/yourusername/oAI", forHTTPHeaderField: "HTTP-Referer")
|
||||
urlRequest.addValue("oAI-Swift", forHTTPHeaderField: "X-Title")
|
||||
urlRequest.addValue("https://github.com/yourusername/Confab", forHTTPHeaderField: "HTTP-Referer")
|
||||
urlRequest.addValue("Confab-Swift", forHTTPHeaderField: "X-Title")
|
||||
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: ["model": model, "prompt": prompt])
|
||||
|
||||
let (data, response) = try await session.data(for: urlRequest)
|
||||
@@ -233,8 +234,8 @@ class OpenRouterProvider: AIProvider {
|
||||
urlRequest.httpMethod = "POST"
|
||||
urlRequest.addValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
|
||||
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
urlRequest.addValue("https://github.com/yourusername/oAI", forHTTPHeaderField: "HTTP-Referer")
|
||||
urlRequest.addValue("oAI-Swift", forHTTPHeaderField: "X-Title")
|
||||
urlRequest.addValue("https://github.com/yourusername/Confab", forHTTPHeaderField: "HTTP-Referer")
|
||||
urlRequest.addValue("Confab-Swift", forHTTPHeaderField: "X-Title")
|
||||
urlRequest.httpBody = try JSONEncoder().encode(apiRequest)
|
||||
|
||||
let (data, response) = try await session.data(for: urlRequest)
|
||||
@@ -294,8 +295,8 @@ class OpenRouterProvider: AIProvider {
|
||||
urlRequest.httpMethod = "POST"
|
||||
urlRequest.addValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
|
||||
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
urlRequest.addValue("https://github.com/yourusername/oAI", forHTTPHeaderField: "HTTP-Referer")
|
||||
urlRequest.addValue("oAI-Swift", forHTTPHeaderField: "X-Title")
|
||||
urlRequest.addValue("https://github.com/yourusername/Confab", forHTTPHeaderField: "HTTP-Referer")
|
||||
urlRequest.addValue("Confab-Swift", forHTTPHeaderField: "X-Title")
|
||||
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: body)
|
||||
|
||||
let (data, response) = try await session.data(for: urlRequest)
|
||||
@@ -333,8 +334,8 @@ class OpenRouterProvider: AIProvider {
|
||||
urlRequest.addValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
|
||||
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
urlRequest.addValue("text/event-stream", forHTTPHeaderField: "Accept")
|
||||
urlRequest.addValue("https://github.com/yourusername/oAI", forHTTPHeaderField: "HTTP-Referer")
|
||||
urlRequest.addValue("oAI-Swift", forHTTPHeaderField: "X-Title")
|
||||
urlRequest.addValue("https://github.com/yourusername/Confab", forHTTPHeaderField: "HTTP-Referer")
|
||||
urlRequest.addValue("Confab-Swift", forHTTPHeaderField: "X-Title")
|
||||
urlRequest.httpBody = try JSONEncoder().encode(apiRequest)
|
||||
|
||||
let (bytes, response) = try await session.bytes(for: urlRequest)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ProviderRegistry.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Registry for managing multiple AI providers
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
+3
-3
@@ -5,11 +5,11 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.rune.oAI.help</string>
|
||||
<string>com.rune.Confab.help</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>oAI Help</string>
|
||||
<string>Confab Help</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
@@ -23,7 +23,7 @@
|
||||
<key>HPDBookIconPath</key>
|
||||
<string>images/icon.png</string>
|
||||
<key>HPDBookTitle</key>
|
||||
<string>oAI Help</string>
|
||||
<string>Confab Help</string>
|
||||
<key>HPDBookType</key>
|
||||
<string>3</string>
|
||||
</dict>
|
||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
+39
-39
@@ -3,18 +3,18 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="AppleTitle" content="oAI Help">
|
||||
<meta name="AppleTitle" content="Confab Help">
|
||||
<meta name="AppleIcon" content="images/icon.png">
|
||||
<meta name="description" content="oAI - AI Chat Assistant for macOS">
|
||||
<meta name="keywords" content="oAI, AI, chat, assistant, OpenAI, Anthropic, Claude, GPT, commands, help">
|
||||
<title>oAI Help</title>
|
||||
<meta name="description" content="Confab - AI Chat Assistant for macOS">
|
||||
<meta name="keywords" content="Confab, AI, chat, assistant, OpenAI, Anthropic, Claude, GPT, commands, help">
|
||||
<title>Confab Help</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<img src="images/icon.png" alt="oAI Icon" class="app-icon">
|
||||
<h1>oAI Help</h1>
|
||||
<img src="images/icon.png" alt="Confab Icon" class="app-icon">
|
||||
<h1>Confab Help</h1>
|
||||
<p class="subtitle">AI Chat Assistant for macOS</p>
|
||||
</header>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<!-- Getting Started -->
|
||||
<section id="getting-started">
|
||||
<h2>Getting Started</h2>
|
||||
<p>oAI is a powerful AI chat assistant that connects to multiple AI providers including OpenAI, Anthropic, OpenRouter, and local models via Ollama. The app is available in English, Norwegian Bokmål, Swedish, Danish, German, and French — it follows your macOS language preference automatically.</p>
|
||||
<p>Confab is a powerful AI chat assistant that connects to multiple AI providers including OpenAI, Anthropic, OpenRouter, and local models via Ollama. The app is available in English, Norwegian Bokmål, Swedish, Danish, German, and French — it follows your macOS language preference automatically.</p>
|
||||
|
||||
<div class="steps">
|
||||
<h3>Quick Start</h3>
|
||||
@@ -75,7 +75,7 @@
|
||||
<!-- Providers -->
|
||||
<section id="providers">
|
||||
<h2>AI Providers & API Keys</h2>
|
||||
<p>oAI supports multiple AI providers. You'll need an API key from at least one provider to use the app.</p>
|
||||
<p>Confab supports multiple AI providers. You'll need an API key from at least one provider to use the app.</p>
|
||||
|
||||
<h3>Supported Providers</h3>
|
||||
<ul class="provider-list">
|
||||
@@ -153,7 +153,7 @@
|
||||
<p>Use <kbd>↑</kbd> / <kbd>↓</kbd> to move through the list, <kbd>Return</kbd> to select the highlighted model.</p>
|
||||
|
||||
<h3>Default Model</h3>
|
||||
<p>Set a model that oAI always opens with in <strong>Settings → General → Model Settings → Default Model</strong>. Click <strong>Choose…</strong> to pick from the full model list, or <strong>Clear</strong> to remove the default. Switching models during a chat session does <em>not</em> change your saved default — it only changes the current session.</p>
|
||||
<p>Set a model that Confab always opens with in <strong>Settings → General → Model Settings → Default Model</strong>. Click <strong>Choose…</strong> to pick from the full model list, or <strong>Clear</strong> to remove the default. Switching models during a chat session does <em>not</em> change your saved default — it only changes the current session.</p>
|
||||
</section>
|
||||
|
||||
<!-- Sending Messages -->
|
||||
@@ -310,7 +310,7 @@
|
||||
<!-- Memory -->
|
||||
<section id="memory">
|
||||
<h2>Memory & Context</h2>
|
||||
<p>oAI features an enhanced memory and context system with intelligent message selection, semantic search, and automatic summarization.</p>
|
||||
<p>Confab features an enhanced memory and context system with intelligent message selection, semantic search, and automatic summarization.</p>
|
||||
|
||||
<h3>Basic Memory Control</h3>
|
||||
<p>Control whether the AI remembers previous messages:</p>
|
||||
@@ -322,7 +322,7 @@
|
||||
</div>
|
||||
|
||||
<h3>Smart Context Selection</h3>
|
||||
<p>When enabled, oAI intelligently selects which messages to send instead of sending all history. This reduces token usage by 50-80% while maintaining context quality.</p>
|
||||
<p>When enabled, Confab intelligently selects which messages to send instead of sending all history. This reduces token usage by 50-80% while maintaining context quality.</p>
|
||||
|
||||
<h4>How It Works</h4>
|
||||
<ul>
|
||||
@@ -380,7 +380,7 @@
|
||||
</div>
|
||||
|
||||
<h3>Progressive Summarization</h3>
|
||||
<p>For very long conversations, oAI automatically summarizes older messages to save tokens while preserving context.</p>
|
||||
<p>For very long conversations, Confab automatically summarizes older messages to save tokens while preserving context.</p>
|
||||
|
||||
<h4>How It Works</h4>
|
||||
<ul>
|
||||
@@ -517,7 +517,7 @@
|
||||
<p class="note">The Save dialog includes a folder picker — choose an existing folder or pick <strong>New Folder…</strong> to create one on the spot.</p>
|
||||
|
||||
<h3 id="unsaved-changes">Unsaved Changes & Crash Recovery</h3>
|
||||
<p>oAI tracks unsaved changes like a standard Mac document. Starting a New Chat, clearing the chat, loading a different conversation, or quitting the app while there are unsaved messages shows the standard save prompt:</p>
|
||||
<p>Confab tracks unsaved changes like a standard Mac document. Starting a New Chat, clearing the chat, loading a different conversation, or quitting the app while there are unsaved messages shows the standard save prompt:</p>
|
||||
<ul>
|
||||
<li><strong>Save</strong> — saves the conversation (prompting for a name and folder if it hasn't been saved yet), then proceeds</li>
|
||||
<li><strong>Don't Save</strong> (<kbd>⌘D</kbd> in the prompt) — discards the changes and proceeds</li>
|
||||
@@ -525,7 +525,7 @@
|
||||
</ul>
|
||||
|
||||
<div class="tip">
|
||||
<strong>💡 Crash Recovery:</strong> While you're chatting, oAI periodically mirrors the in-progress conversation to disk (every 10 seconds by default — adjustable or turned off in Settings → General). If oAI crashes or is force-quit, the next launch offers to restore the conversation you were working on, including the model you had selected. This mirror is invisible and separate from your saved conversations — it's cleared automatically as soon as you save, discard, or restore it.
|
||||
<strong>💡 Crash Recovery:</strong> While you're chatting, Confab periodically mirrors the in-progress conversation to disk (every 10 seconds by default — adjustable or turned off in Settings → General). If Confab crashes or is force-quit, the next launch offers to restore the conversation you were working on, including the model you had selected. This mirror is invisible and separate from your saved conversations — it's cleared automatically as soon as you save, discard, or restore it.
|
||||
</div>
|
||||
|
||||
<h3>Renaming Conversations</h3>
|
||||
@@ -618,7 +618,7 @@
|
||||
<li>Click <strong>Clone Repository</strong> to initialize</li>
|
||||
</ol>
|
||||
|
||||
<p>Saving to Git is explicit rather than automatic — see <a href="#unsaved-changes">Unsaved Changes & Crash Recovery</a> for how oAI tracks and prompts you to save. Every explicit save (<kbd>⌘S</kbd>, Save Chat As…, or the unsaved-changes prompt) triggers a background sync (export + commit + push) automatically when Git Sync is configured.</p>
|
||||
<p>Saving to Git is explicit rather than automatic — see <a href="#unsaved-changes">Unsaved Changes & Crash Recovery</a> for how Confab tracks and prompts you to save. Every explicit save (<kbd>⌘S</kbd>, Save Chat As…, or the unsaved-changes prompt) triggers a background sync (export + commit + push) automatically when Git Sync is configured.</p>
|
||||
|
||||
<div class="warning">
|
||||
<strong>⚠️ Multi-Machine Warning:</strong> Syncing on multiple machines simultaneously can cause merge conflicts. Pull before you start working on a different machine.
|
||||
@@ -645,7 +645,7 @@
|
||||
</dl>
|
||||
|
||||
<h3>Sync Status Indicators</h3>
|
||||
<p>oAI shows sync status in two places:</p>
|
||||
<p>Confab shows sync status in two places:</p>
|
||||
|
||||
<h4>Header Indicator (Green/Orange/Red Pill)</h4>
|
||||
<ul>
|
||||
@@ -713,7 +713,7 @@ The weather is sunny today!
|
||||
<h3>Restoring on a New Machine</h3>
|
||||
<p>To restore your conversations on a new Mac:</p>
|
||||
<ol>
|
||||
<li>Install oAI on the new machine</li>
|
||||
<li>Install Confab on the new machine</li>
|
||||
<li>Open Settings → Sync tab</li>
|
||||
<li>Enter your repository URL and credentials</li>
|
||||
<li>Click <strong>Clone Repository</strong></li>
|
||||
@@ -726,9 +726,9 @@ The weather is sunny today!
|
||||
<h4>SSH Key (Recommended)</h4>
|
||||
<p>Most secure option. Generate an SSH key and add it to your Git service:</p>
|
||||
<ol>
|
||||
<li>Generate key: <code>ssh-keygen -t ed25519 -C "oai@yourmac"</code></li>
|
||||
<li>Generate key: <code>ssh-keygen -t ed25519 -C "confab@yourmac"</code></li>
|
||||
<li>Add to git service (GitHub Settings → SSH Keys)</li>
|
||||
<li>Use SSH URL in oAI: <code>git@github.com:username/repo.git</code></li>
|
||||
<li>Use SSH URL in Confab: <code>git@github.com:username/repo.git</code></li>
|
||||
</ol>
|
||||
|
||||
<h4>Access Token</h4>
|
||||
@@ -748,7 +748,7 @@ The weather is sunny today!
|
||||
<li><strong>Enable Auto-Sync on One Machine</strong> - Avoid conflicts by syncing automatically on your primary Mac only</li>
|
||||
<li><strong>Manual Sync on Others</strong> - Use Pull/Push buttons on secondary machines</li>
|
||||
<li><strong>Regular Backups</strong> - Git history preserves all versions of your conversations</li>
|
||||
<li><strong>Don't Edit Manually</strong> - The README warns against manual edits; always use oAI's sync features</li>
|
||||
<li><strong>Don't Edit Manually</strong> - The README warns against manual edits; always use Confab's sync features</li>
|
||||
</ul>
|
||||
|
||||
<h3>Troubleshooting</h3>
|
||||
@@ -776,7 +776,7 @@ The weather is sunny today!
|
||||
<!-- Email Handler -->
|
||||
<section id="email-handler">
|
||||
<h2>Email Handler (AI Assistant)</h2>
|
||||
<p>Turn oAI into an AI-powered email auto-responder. Monitor an inbox and automatically reply to emails with intelligent, context-aware responses.</p>
|
||||
<p>Turn Confab into an AI-powered email auto-responder. Monitor an inbox and automatically reply to emails with intelligent, context-aware responses.</p>
|
||||
|
||||
<div class="tip">
|
||||
<strong>💡 Use Cases:</strong> Customer support automation, personal assistant emails, automated FAQ responses, email-based task management.
|
||||
@@ -784,7 +784,7 @@ The weather is sunny today!
|
||||
|
||||
<h3>How It Works</h3>
|
||||
<ol>
|
||||
<li><strong>IMAP Monitoring</strong> - oAI polls your inbox every 30 seconds for new emails</li>
|
||||
<li><strong>IMAP Monitoring</strong> - Confab polls your inbox every 30 seconds for new emails</li>
|
||||
<li><strong>Subject Filter</strong> - Only emails with your identifier (e.g., <code>[Jarvis]</code>) are processed</li>
|
||||
<li><strong>AI Processing</strong> - Email content is sent to your configured AI model</li>
|
||||
<li><strong>Auto-Reply</strong> - AI-generated response is sent via SMTP</li>
|
||||
@@ -812,7 +812,7 @@ The weather is sunny today!
|
||||
<li>Click <strong>Test Connection</strong> to verify settings</li>
|
||||
<li>Set <strong>Subject Identifier</strong> (e.g., <code>[Jarvis]</code>)</li>
|
||||
<li>Select <strong>AI Provider</strong> and <strong>Model</strong> for responses</li>
|
||||
<li>Save settings and restart oAI</li>
|
||||
<li>Save settings and restart Confab</li>
|
||||
</ol>
|
||||
|
||||
<div class="note">
|
||||
@@ -927,8 +927,8 @@ The weather is sunny today!
|
||||
<li>Verify subject identifier matches exactly (case-sensitive)</li>
|
||||
<li>Check email is in INBOX (not Spam/Junk)</li>
|
||||
<li>Ensure email handler is enabled in Settings</li>
|
||||
<li>Restart oAI to reinitialize monitoring</li>
|
||||
<li>Check logs: <code>~/Library/Logs/oAI.log</code></li>
|
||||
<li>Restart Confab to reinitialize monitoring</li>
|
||||
<li>Check logs: <code>~/Library/Logs/Confab.log</code></li>
|
||||
</ul>
|
||||
|
||||
<h4>Connection Errors</h4>
|
||||
@@ -943,7 +943,7 @@ The weather is sunny today!
|
||||
<h4>SMTP TLS Errors</h4>
|
||||
<ul>
|
||||
<li>Use port 465 (direct TLS) instead of 587 (STARTTLS)</li>
|
||||
<li>Port 465 is more reliable with oAI's implementation</li>
|
||||
<li>Port 465 is more reliable with Confab's implementation</li>
|
||||
<li>If only 587 available, contact support</li>
|
||||
</ul>
|
||||
|
||||
@@ -959,7 +959,7 @@ The weather is sunny today!
|
||||
<ul>
|
||||
<li>Check Email Log for duplicate entries</li>
|
||||
<li>Emails should be marked as read after processing</li>
|
||||
<li>Restart oAI if duplicates persist</li>
|
||||
<li>Restart Confab if duplicates persist</li>
|
||||
</ul>
|
||||
|
||||
<h3>Best Practices</h3>
|
||||
@@ -1290,7 +1290,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
<!-- iCloud Backup -->
|
||||
<section id="icloud-backup">
|
||||
<h2>iCloud Backup</h2>
|
||||
<p>Back up and restore all your oAI settings with one click. Backups are saved to iCloud Drive so they're available on any Mac where you're signed in.</p>
|
||||
<p>Back up and restore all your Confab settings with one click. Backups are saved to iCloud Drive so they're available on any Mac where you're signed in.</p>
|
||||
|
||||
<div class="note">
|
||||
<strong>What is included:</strong> All settings and preferences — providers, model defaults, MCP configuration, appearance, advanced options, shortcuts, skills, and more.<br><br>
|
||||
@@ -1315,7 +1315,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
</ol>
|
||||
|
||||
<div class="tip">
|
||||
<strong>💡 New Mac Setup:</strong> Back up on your old Mac, sign in to iCloud on your new Mac, open oAI, restore from the backup file — and all your settings are restored in seconds. You only need to re-enter API keys.
|
||||
<strong>💡 New Mac Setup:</strong> Back up on your old Mac, sign in to iCloud on your new Mac, open Confab, restore from the backup file — and all your settings are restored in seconds. You only need to re-enter API keys.
|
||||
</div>
|
||||
|
||||
<h3>Backup Format</h3>
|
||||
@@ -1325,7 +1325,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
<!-- Reasoning / Thinking Tokens -->
|
||||
<section id="reasoning">
|
||||
<h2>Reasoning / Thinking Tokens</h2>
|
||||
<p>Some AI models can "think out loud" before giving their final answer — reasoning through the problem step by step. oAI streams this thinking content live and displays it in a collapsible block above the response.</p>
|
||||
<p>Some AI models can "think out loud" before giving their final answer — reasoning through the problem step by step. Confab streams this thinking content live and displays it in a collapsible block above the response.</p>
|
||||
|
||||
<h3>Supported Models</h3>
|
||||
<p>Reasoning is available on models that support extended thinking, including:</p>
|
||||
@@ -1382,7 +1382,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
<!-- Anytype Integration -->
|
||||
<section id="anytype">
|
||||
<h2>Anytype Integration</h2>
|
||||
<p>oAI can connect to your local <a href="https://anytype.io" target="_blank">Anytype</a> desktop app, giving the AI read and write access to your personal knowledge base. All data stays on your machine — the API is local-only.</p>
|
||||
<p>Confab can connect to your local <a href="https://anytype.io" target="_blank">Anytype</a> desktop app, giving the AI read and write access to your personal knowledge base. All data stays on your machine — the API is local-only.</p>
|
||||
|
||||
<h3>Requirements</h3>
|
||||
<ul>
|
||||
@@ -1392,7 +1392,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
|
||||
<h3>Setup</h3>
|
||||
<ol>
|
||||
<li>Open oAI Settings → Anytype tab</li>
|
||||
<li>Open Confab Settings → Anytype tab</li>
|
||||
<li>Enable the toggle</li>
|
||||
<li>Enter your API key (leave the URL as the default unless your setup is unusual)</li>
|
||||
<li>Click <strong>Test Connection</strong> — a success message will show how many spaces were found</li>
|
||||
@@ -1450,7 +1450,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
<p>Toggle a server off/on or delete it entirely with the trash icon. Crashed servers automatically restart up to 3 times with increasing delay (5s, 15s, 30s) before giving up.</p>
|
||||
|
||||
<div class="note">
|
||||
<strong>Note:</strong> Tool names from every external server are prefixed with that server's slug (derived from its Name) so they never collide with oAI's built-in tools or each other.
|
||||
<strong>Note:</strong> Tool names from every external server are prefixed with that server's slug (derived from its Name) so they never collide with Confab's built-in tools or each other.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1578,7 +1578,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
<!-- Settings -->
|
||||
<section id="settings">
|
||||
<h2>Settings</h2>
|
||||
<p>Customize oAI to your preferences. Press <kbd>⌘,</kbd> to open Settings.</p>
|
||||
<p>Customize Confab to your preferences. Press <kbd>⌘,</kbd> to open Settings.</p>
|
||||
|
||||
<h3>General Tab</h3>
|
||||
<ul>
|
||||
@@ -1669,7 +1669,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
</div>
|
||||
|
||||
<h3>Paperless Tab <span style="font-size: 0.75em; background: #f90; color: #fff; border-radius: 4px; padding: 1px 5px; vertical-align: middle;">Beta</span></h3>
|
||||
<p>Connect oAI to a self-hosted <a href="https://docs.paperless-ngx.com" target="_blank">Paperless-NGX</a> instance so the AI can search and read your document archive.</p>
|
||||
<p>Connect Confab to a self-hosted <a href="https://docs.paperless-ngx.com" target="_blank">Paperless-NGX</a> instance so the AI can search and read your document archive.</p>
|
||||
<ul>
|
||||
<li><strong>URL</strong> — Base URL of your Paperless instance (e.g. <code>https://paperless.yourdomain.com</code>)</li>
|
||||
<li><strong>API Token</strong> — Found in Paperless → Settings → API Tokens</li>
|
||||
@@ -1710,7 +1710,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
</ul>
|
||||
|
||||
<h3>Anytype Tab</h3>
|
||||
<p>Connect oAI to your local <a href="https://anytype.io" target="_blank">Anytype</a> desktop app so the AI can search, read, and add content to your knowledge base.</p>
|
||||
<p>Connect Confab to your local <a href="https://anytype.io" target="_blank">Anytype</a> desktop app so the AI can search, read, and add content to your knowledge base.</p>
|
||||
<ul>
|
||||
<li><strong>Enable Anytype</strong> — toggle to activate the integration</li>
|
||||
<li><strong>API URL</strong> — local Anytype API endpoint (default: <code>http://127.0.0.1:31009</code>)</li>
|
||||
@@ -1751,7 +1751,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
</ul>
|
||||
|
||||
<h3>Default System Prompt</h3>
|
||||
<p>oAI includes a carefully crafted default system prompt that emphasizes:</p>
|
||||
<p>Confab includes a carefully crafted default system prompt that emphasizes:</p>
|
||||
<ul>
|
||||
<li><strong>Accuracy First</strong> - Never invent information or make assumptions</li>
|
||||
<li><strong>Ask for Clarification</strong> - Request details when requests are ambiguous</li>
|
||||
@@ -1773,7 +1773,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
</ul>
|
||||
|
||||
<h3>How Prompts Are Combined</h3>
|
||||
<p>When you send a message, oAI constructs the complete system prompt like this:</p>
|
||||
<p>When you send a message, Confab constructs the complete system prompt like this:</p>
|
||||
|
||||
<div class="example">
|
||||
<p><strong>Complete System Prompt =</strong></p>
|
||||
@@ -1812,7 +1812,7 @@ Whenever the user asks you to translate something, translate it to Norwegian Bok
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2026 oAI - Rune Olsen. For support or feedback, visit <a href="https://gitlab.pm/rune/oai-swift">gitlab.pm</a> or <a href="mailto:support@fubar.pm?subject=oAI Support&body=What can I help you with?">Contact Us</a>.</p>
|
||||
<p>© 2026 Confab - Rune Olsen. For support or feedback, visit <a href="https://gitlab.pm/rune/oai-swift">gitlab.pm</a> or <a href="mailto:support@fubar.pm?subject=Confab Support&body=What can I help you with?">Contact Us</a>.</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* oAI Help Stylesheet - Apple Human Interface Guidelines */
|
||||
/* Confab Help Stylesheet - Apple Human Interface Guidelines */
|
||||
|
||||
:root {
|
||||
--primary-color: #007AFF;
|
||||
@@ -1,31 +1,31 @@
|
||||
# oAI Help Book
|
||||
# Confab Help Book
|
||||
|
||||
This folder contains the Apple Help Book for oAI.
|
||||
This folder contains the Apple Help Book for Confab.
|
||||
|
||||
## Adding to Xcode Project
|
||||
|
||||
1. **Add the help folder to your project:**
|
||||
- In Xcode, right-click on the `Resources` folder in the Project Navigator
|
||||
- Select "Add Files to 'oAI'..."
|
||||
- Select the `oAI.help` folder
|
||||
- Select "Add Files to 'Confab'..."
|
||||
- Select the `Confab.help` folder
|
||||
- **Important:** Check "Create folder references" (NOT "Create groups")
|
||||
- Click "Add"
|
||||
|
||||
2. **Configure the help book in build settings:**
|
||||
- Select your oAI target in Xcode
|
||||
- Select your Confab target in Xcode
|
||||
- Go to the "Info" tab
|
||||
- Add a new key: `CFBundleHelpBookName` with value: `oAI Help`
|
||||
- Add another key: `CFBundleHelpBookFolder` with value: `oAI.help`
|
||||
- Add a new key: `CFBundleHelpBookName` with value: `Confab Help`
|
||||
- Add another key: `CFBundleHelpBookFolder` with value: `Confab.help`
|
||||
|
||||
3. **Build and test:**
|
||||
- Build the app (⌘B)
|
||||
- Run the app (⌘R)
|
||||
- Press ⌘? or select Help → oAI Help to open the help
|
||||
- Press ⌘? or select Help → Confab Help to open the help
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
oAI.help/
|
||||
Confab.help/
|
||||
├── Contents/
|
||||
│ ├── Info.plist # Help book metadata
|
||||
│ └── Resources/
|
||||
@@ -37,7 +37,7 @@ oAI.help/
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ Comprehensive coverage of all oAI features
|
||||
- ✅ Comprehensive coverage of all Confab features
|
||||
- ✅ Searchable via macOS Help menu search
|
||||
- ✅ Dark mode support
|
||||
- ✅ Organized by topic with table of contents
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AgentSkillFilesService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Manages per-skill file directories in Application Support/oAI/skills/<uuid>/
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AnthropicOAuthService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// OAuth 2.0 PKCE flow for Anthropic Pro/Max subscription login
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AnytypeMCPService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Anytype MCP integration via local HTTP API at http://127.0.0.1:31009
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -29,7 +29,7 @@ class AnytypeMCPService {
|
||||
static let shared = AnytypeMCPService()
|
||||
|
||||
private let settings = SettingsService.shared
|
||||
private let log = Logger(subsystem: "com.oai.oAI", category: "mcp")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "mcp")
|
||||
private let apiVersion = "2025-11-08"
|
||||
private let timeout: TimeInterval = 10
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// BackupService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// iCloud Drive backup of non-encrypted settings (Option C, v1)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -49,7 +49,7 @@ struct FavoritesPayload: Codable {
|
||||
final class BackupService {
|
||||
static let shared = BackupService()
|
||||
|
||||
private let log = Logger(subsystem: "oAI", category: "backup")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "backup")
|
||||
|
||||
/// Whether iCloud Drive is available on this machine
|
||||
var iCloudAvailable: Bool = false
|
||||
@@ -332,7 +332,7 @@ enum BackupError: LocalizedError {
|
||||
case .invalidFormat(let detail):
|
||||
return "The backup file is not valid: \(detail)"
|
||||
case .unsupportedVersion(let v):
|
||||
return "Backup version \(v) is not supported by this version of oAI."
|
||||
return "Backup version \(v) is not supported by this version of Confab."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ContactsService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Read-only Contacts integration: search and "my card" lookup
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// ContextSelectionService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Smart context selection for AI conversations
|
||||
// Selects relevant messages instead of sending entire history
|
||||
@@ -8,11 +8,11 @@
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ConversationExportService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Shared conversation export: Markdown, HTML, and PDF
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ConversationMergeService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Combine multiple saved conversations into one (simple concatenation or AI-assisted merge)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// DatabaseService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// SQLite persistence layer for conversations using GRDB
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// DraftRecoveryService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Crash-recovery draft for the in-progress conversation — a lightweight,
|
||||
// invisible mirror of the current chat, distinct from named saved conversations.
|
||||
@@ -8,11 +8,11 @@
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// EmailHandlerService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// AI-powered email auto-responder service
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -32,7 +32,7 @@ final class EmailHandlerService {
|
||||
private let emailService = EmailService.shared
|
||||
private let emailLog = EmailLogService.shared
|
||||
private let mcp = MCPService.shared
|
||||
private let log = Logger(subsystem: "com.oai.oAI", category: "email-handler")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "email-handler")
|
||||
|
||||
// Rate limiting
|
||||
private var emailsProcessedThisHour: Int = 0
|
||||
@@ -403,7 +403,7 @@ final class EmailHandlerService {
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<p>🤖 This response was generated by AI using oAI Email Handler</p>
|
||||
<p>🤖 This response was generated by AI using Confab Email Handler</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// EmailLogService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Service for managing email handler activity logs
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -29,7 +29,7 @@ final class EmailLogService {
|
||||
static let shared = EmailLogService()
|
||||
|
||||
private let db = DatabaseService.shared
|
||||
private let log = Logger(subsystem: "com.oai.oAI", category: "email-log")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "email-log")
|
||||
|
||||
private init() {}
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// EmailService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// IMAP IDLE email monitoring service for AI email handler
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -71,7 +71,7 @@ final class EmailService {
|
||||
static let shared = EmailService()
|
||||
|
||||
private let settings = SettingsService.shared
|
||||
private let log = Logger(subsystem: "com.oai.oAI", category: "email")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "email")
|
||||
|
||||
// IMAP IDLE state
|
||||
private var isConnected = false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// EmbeddingService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Embedding generation and semantic search
|
||||
// Supports multiple providers: OpenAI, OpenRouter, Google
|
||||
@@ -8,11 +8,11 @@
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -205,7 +205,7 @@ final class EmbeddingService {
|
||||
request.httpMethod = "POST"
|
||||
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
|
||||
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
request.setValue("https://github.com/yourusername/oAI", forHTTPHeaderField: "HTTP-Referer")
|
||||
request.setValue("https://github.com/yourusername/Confab", forHTTPHeaderField: "HTTP-Referer")
|
||||
|
||||
let body: [String: Any] = [
|
||||
"input": text,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// EncryptionService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Secure encryption for sensitive data (API keys)
|
||||
// Uses CryptoKit with machine-specific key derivation
|
||||
@@ -8,11 +8,11 @@
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -72,7 +72,10 @@ class EncryptionService {
|
||||
/// Derive encryption key from machine-specific data
|
||||
private static func deriveEncryptionKey() -> SymmetricKey {
|
||||
let machineUUID = getMachineUUID()
|
||||
let bundleID = Bundle.main.bundleIdentifier ?? "com.oai.oAI"
|
||||
// Pinned, not read from Bundle.main.bundleIdentifier: the app's bundle ID changed
|
||||
// (oAI -> Confab rename) but this key material must not, or every already-encrypted
|
||||
// setting (provider API keys, sync/email credentials) becomes undecryptable.
|
||||
let bundleID = "com.oai.oAI"
|
||||
let salt = "oAI-secure-storage-v1"
|
||||
let keyMaterial = "\(machineUUID)-\(bundleID)-\(salt)"
|
||||
let hash = SHA256.hash(data: Data(keyMaterial.utf8))
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// EventKitService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Calendar and Reminders integration via EventKit
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -75,7 +75,7 @@ final class ExternalMCPClient {
|
||||
let _: MCPInitializeResult = try await timedRequest(seconds: 15, method: "initialize", params: [
|
||||
"protocolVersion": "2024-11-05",
|
||||
"capabilities": [:] as [String: Any],
|
||||
"clientInfo": ["name": "oAI", "version": "1.0"] as [String: Any]
|
||||
"clientInfo": ["name": "Confab", "version": "1.0"] as [String: Any]
|
||||
])
|
||||
try sendNotification(method: "notifications/initialized")
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ import Foundation
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -24,7 +24,7 @@ class GitSyncService {
|
||||
|
||||
private let settings = SettingsService.shared
|
||||
private let db = DatabaseService.shared
|
||||
private let log = Logger(subsystem: "com.oai.oAI", category: "sync")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "sync")
|
||||
|
||||
private(set) var syncStatus = SyncStatus()
|
||||
private(set) var isSyncing = false
|
||||
@@ -90,7 +90,7 @@ class GitSyncService {
|
||||
}
|
||||
|
||||
/// Push local changes to remote
|
||||
func push(message: String = "Sync from oAI") async throws {
|
||||
func push(message: String = "Sync from Confab") async throws {
|
||||
try ensureCloned()
|
||||
|
||||
let localPath = expandPath(settings.syncLocalPath)
|
||||
@@ -314,20 +314,20 @@ class GitSyncService {
|
||||
}
|
||||
|
||||
let readme = """
|
||||
# oAI Conversation Sync
|
||||
# Confab Conversation Sync
|
||||
|
||||
This repository contains your oAI conversations in markdown format.
|
||||
This repository contains your Confab conversations in markdown format.
|
||||
|
||||
## ⚠️ WARNING - DO NOT MANUALLY EDIT
|
||||
|
||||
**This repository is automatically managed by oAI.**
|
||||
**This repository is automatically managed by Confab.**
|
||||
|
||||
- ❌ **DO NOT manually edit** these files
|
||||
- ❌ **DO NOT add** files to this repository
|
||||
- ❌ **DO NOT delete** files from this repository
|
||||
- ❌ **DO NOT merge conflicts** manually (let oAI handle it)
|
||||
- ❌ **DO NOT merge conflicts** manually (let Confab handle it)
|
||||
|
||||
**Why?** oAI rebuilds its internal database from these files. Manual edits will be:
|
||||
**Why?** Confab rebuilds its internal database from these files. Manual edits will be:
|
||||
- Overwritten on next sync
|
||||
- May cause data corruption
|
||||
- May prevent proper import/restore
|
||||
@@ -335,13 +335,13 @@ class GitSyncService {
|
||||
## How It Works
|
||||
|
||||
### Export (Automatic)
|
||||
- oAI saves conversations to its local database
|
||||
- Confab saves conversations to its local database
|
||||
- Auto-sync exports conversations to `conversations/*.md`
|
||||
- Files are committed and pushed to this git repository
|
||||
|
||||
### Import (On New Machine)
|
||||
- Clone this repository on a new machine
|
||||
- oAI imports markdown files into its database
|
||||
- Confab imports markdown files into its database
|
||||
- Your conversation history is restored
|
||||
|
||||
### Sync Across Machines
|
||||
@@ -399,28 +399,28 @@ class GitSyncService {
|
||||
## Troubleshooting
|
||||
|
||||
**Problem:** Files not syncing?
|
||||
- Check Settings → Sync in oAI
|
||||
- Check Settings → Sync in Confab
|
||||
- Verify git credentials are correct
|
||||
- Check network connection
|
||||
|
||||
**Problem:** Conflicts after editing?
|
||||
- Restore from git: `git reset --hard origin/main`
|
||||
- Re-export from oAI: Manual Sync → Export All → Push
|
||||
- Re-export from Confab: Manual Sync → Export All → Push
|
||||
|
||||
**Problem:** Lost conversations?
|
||||
- Conversations are in your local oAI database
|
||||
- Conversations are in your local Confab database
|
||||
- Export manually: Settings → Sync → Export All
|
||||
- Check git history for deleted files
|
||||
|
||||
## Support
|
||||
|
||||
For help with oAI, see:
|
||||
- Settings → Help in oAI app
|
||||
For help with Confab, see:
|
||||
- Settings → Help in Confab app
|
||||
- GitHub issues (if open source)
|
||||
|
||||
---
|
||||
|
||||
**Generated by oAI v1.0**
|
||||
**Generated by Confab v1.0**
|
||||
**Last updated:** \(ISO8601DateFormatter().string(from: Date()))
|
||||
"""
|
||||
|
||||
@@ -504,7 +504,7 @@ class GitSyncService {
|
||||
try await exportAllConversations()
|
||||
|
||||
// Push to git
|
||||
try await push(message: "Auto-sync from oAI")
|
||||
try await push(message: "Auto-sync from Confab")
|
||||
|
||||
// Success
|
||||
await MainActor.run {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// IMAPClient.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Swift-native IMAP client for email monitoring
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -26,7 +26,7 @@ import Network
|
||||
import os
|
||||
|
||||
class IMAPClient {
|
||||
private let log = Logger(subsystem: "com.oai.oAI", category: "imap")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "imap")
|
||||
|
||||
private var connection: NWConnection?
|
||||
private var host: String
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// JarvisService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// HTTP client for the Jarvis (oAI-Web) REST API.
|
||||
// Auth: Authorization: Bearer <api-key>
|
||||
@@ -15,7 +15,7 @@ final class JarvisService: Sendable {
|
||||
static let shared = JarvisService()
|
||||
private init() {}
|
||||
|
||||
private let log = Logger(subsystem: "com.oai.oAI", category: "jarvis")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "jarvis")
|
||||
|
||||
private var baseURL: String { SettingsService.shared.jarvisURL }
|
||||
private var apiKey: String? { SettingsService.shared.jarvisAPIKey }
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// LocationMapsService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Read-only Location and Maps integration via CoreLocation and MapKit
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// MCPService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// MCP (Model Context Protocol) service for filesystem tool execution
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -100,7 +100,7 @@ class MCPService {
|
||||
// Always allow the system temp directory — external MCP servers and tools write
|
||||
// intermediate data there (e.g. Safari MCP page-content files, generated images).
|
||||
// Check both NSTemporaryDirectory() (per-user Darwin temp dir) and /tmp (what this
|
||||
// codebase's own temp files actually use, e.g. ChatViewModel's /tmp/oai_generated_*
|
||||
// codebase's own temp files actually use, e.g. ChatViewModel's /tmp/confab_generated_*
|
||||
// and ExternalMCPClient's /tmp/oai_mcp_* — they resolve to different directories.
|
||||
let tmpCandidates = [
|
||||
(NSTemporaryDirectory() as NSString).standardizingPath,
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// PaperlessService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Paperless-NGX integration: search, read, and upload documents via REST API
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -29,7 +29,7 @@ class PaperlessService {
|
||||
static let shared = PaperlessService()
|
||||
|
||||
private let settings = SettingsService.shared
|
||||
private let log = Logger(subsystem: "com.oai.oAI", category: "mcp")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "mcp")
|
||||
private let readTimeout: TimeInterval = 15
|
||||
private let uploadTimeout: TimeInterval = 60
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// SMTPClient.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Swift-native SMTP client for sending emails
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -26,7 +26,7 @@ import Network
|
||||
import os
|
||||
|
||||
class SMTPClient {
|
||||
private let log = Logger(subsystem: "com.oai.oAI", category: "smtp")
|
||||
private let log = Logger(subsystem: Log.subsystem, category: "smtp")
|
||||
|
||||
private var connection: NWConnection?
|
||||
private var host: String
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// SettingsService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Settings persistence: SQLite for preferences, Keychain for API keys
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ThinkingVerbs.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Fun random verbs for AI thinking/processing states
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// UpdateCheckService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Checks for new releases on GitLab and surfaces an update badge in the footer
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// WebSearchService.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// DuckDuckGo web search for non-OpenRouter providers
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// Color+Extensions.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Color scheme matching Python TUI dark theme
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -26,30 +26,30 @@ import SwiftUI
|
||||
extension Color {
|
||||
// MARK: - oAI Color Palette (Matching Python TUI)
|
||||
|
||||
static let oaiBackground = Color(hex: "#1e1e1e") // Main background
|
||||
static let oaiSurface = Color(hex: "#2d2d2d") // Cards, surfaces
|
||||
static let oaiPrimary = Color(hex: "#cccccc") // Primary text
|
||||
static let oaiSecondary = Color(hex: "#888888") // Secondary text
|
||||
static let oaiAccent = Color(hex: "#0a7aca") // Blue accent (assistant)
|
||||
static let oaiSuccess = Color(hex: "#90ee90") // Green (user messages)
|
||||
static let oaiError = Color(hex: "#ff6b6b") // Red (errors)
|
||||
static let oaiWarning = Color(hex: "#ffaa00") // Orange (warnings)
|
||||
static let oaiBorder = Color(hex: "#555555") // Borders, dividers
|
||||
static let confabBackground = Color(hex: "#1e1e1e") // Main background
|
||||
static let confabSurface = Color(hex: "#2d2d2d") // Cards, surfaces
|
||||
static let confabPrimary = Color(hex: "#cccccc") // Primary text
|
||||
static let confabSecondary = Color(hex: "#888888") // Secondary text
|
||||
static let confabAccent = Color(hex: "#0a7aca") // Blue accent (assistant)
|
||||
static let confabSuccess = Color(hex: "#90ee90") // Green (user messages)
|
||||
static let confabError = Color(hex: "#ff6b6b") // Red (errors)
|
||||
static let confabWarning = Color(hex: "#ffaa00") // Orange (warnings)
|
||||
static let confabBorder = Color(hex: "#555555") // Borders, dividers
|
||||
|
||||
// MARK: - Message Role Colors
|
||||
|
||||
static func messageColor(for role: MessageRole) -> Color {
|
||||
switch role {
|
||||
case .user: return .oaiSuccess
|
||||
case .assistant: return .oaiAccent
|
||||
case .system: return .oaiSecondary
|
||||
case .user: return .confabSuccess
|
||||
case .assistant: return .confabAccent
|
||||
case .system: return .confabSecondary
|
||||
}
|
||||
}
|
||||
|
||||
static func messageBackground(for role: MessageRole) -> Color {
|
||||
switch role {
|
||||
case .user: return .oaiSurface
|
||||
case .assistant: return .oaiBackground
|
||||
case .user: return .confabSurface
|
||||
case .assistant: return .confabBackground
|
||||
case .system: return Color(hex: "#2a2a2a")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// String+Extensions.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// String utility extensions
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// View+Extensions.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// SwiftUI view helpers and modifiers
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -57,33 +57,33 @@ extension View {
|
||||
|
||||
// MARK: - Common Styling
|
||||
|
||||
func oaiCardStyle() -> some View {
|
||||
func confabCardStyle() -> some View {
|
||||
self
|
||||
.background(Color.oaiSurface)
|
||||
.background(Color.confabSurface)
|
||||
.cornerRadius(8)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.stroke(Color.oaiBorder, lineWidth: 1)
|
||||
.stroke(Color.confabBorder, lineWidth: 1)
|
||||
)
|
||||
}
|
||||
|
||||
func oaiButton() -> some View {
|
||||
func confabButton() -> some View {
|
||||
self
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 6)
|
||||
.background(Color.oaiSurface)
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.background(Color.confabSurface)
|
||||
.foregroundColor(.confabPrimary)
|
||||
.cornerRadius(6)
|
||||
}
|
||||
|
||||
func oaiTextField() -> some View {
|
||||
func confabTextField() -> some View {
|
||||
self
|
||||
.padding(8)
|
||||
.background(Color.oaiBackground)
|
||||
.background(Color.confabBackground)
|
||||
.cornerRadius(6)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.stroke(Color.oaiBorder, lineWidth: 1)
|
||||
.stroke(Color.confabBorder, lineWidth: 1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// Logging.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Dual logging: os.Logger (unified log) + file (~Library/Logs/oAI.log)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -82,7 +82,7 @@ final class FileLogger: @unchecked Sendable {
|
||||
private init() {
|
||||
let logsDir = FileManager.default.homeDirectoryForCurrentUser
|
||||
.appendingPathComponent("Library/Logs")
|
||||
let logFile = logsDir.appendingPathComponent("oAI.log")
|
||||
let logFile = logsDir.appendingPathComponent("Confab.log")
|
||||
|
||||
// Ensure file exists
|
||||
if !FileManager.default.fileExists(atPath: logFile.path) {
|
||||
@@ -142,7 +142,7 @@ struct AppLogger: Sendable {
|
||||
// MARK: - Log Namespace
|
||||
|
||||
enum Log {
|
||||
private nonisolated static let subsystem = "com.oai.oAI"
|
||||
nonisolated static let subsystem = "com.oai.Confab"
|
||||
|
||||
nonisolated static let api = AppLogger(subsystem: subsystem, category: "api")
|
||||
nonisolated static let db = AppLogger(subsystem: subsystem, category: "database")
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// SyntaxHighlighter.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Keyword-based syntax highlighting using AttributedString
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ChatViewModel.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Main chat view model
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -1563,7 +1563,7 @@ Don't narrate future actions ("Let me...") - just use the tools.
|
||||
didContinueAfterImages = true
|
||||
let timestamp = Int(Date().timeIntervalSince1970)
|
||||
let tempPaths: [String] = finalImages.enumerated().compactMap { i, imgData in
|
||||
let path = "/tmp/oai_generated_\(timestamp)_\(i).png"
|
||||
let path = "/tmp/confab_generated_\(timestamp)_\(i).png"
|
||||
let ok = FileManager.default.createFile(atPath: path, contents: imgData)
|
||||
Log.ui.debug("Saved generated image to temp: \(path) ok=\(ok)")
|
||||
return ok ? path : nil
|
||||
@@ -2138,7 +2138,7 @@ Don't narrate future actions ("Let me...") - just use the tools.
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .informational
|
||||
alert.messageText = "Restore unsaved conversation?"
|
||||
alert.informativeText = "oAI didn't close properly last time. Would you like to restore the conversation you were working on?"
|
||||
alert.informativeText = "Confab didn't close properly last time. Would you like to restore the conversation you were working on?"
|
||||
alert.addButton(withTitle: "Restore")
|
||||
alert.addButton(withTitle: "Discard")
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ChatView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Main chat interface
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -64,7 +64,7 @@ struct ChatView: View {
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.background(Color.oaiBackground)
|
||||
.background(Color.confabBackground)
|
||||
.onChange(of: viewModel.messages.count) {
|
||||
withAnimation {
|
||||
proxy.scrollTo("bottom", anchor: .bottom)
|
||||
@@ -101,7 +101,7 @@ struct ChatView: View {
|
||||
mcpEnabled: viewModel.mcpEnabled
|
||||
)
|
||||
}
|
||||
.background(Color.oaiBackground)
|
||||
.background(Color.confabBackground)
|
||||
.sheet(isPresented: $viewModel.showShortcuts) {
|
||||
ShortcutsView()
|
||||
}
|
||||
@@ -142,12 +142,12 @@ struct ProcessingIndicator: View {
|
||||
HStack(spacing: 8) {
|
||||
Text(thinkingText)
|
||||
.font(.system(size: 14, weight: .medium))
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
|
||||
HStack(spacing: 4) {
|
||||
ForEach(0..<3) { index in
|
||||
Circle()
|
||||
.fill(Color.oaiSecondary)
|
||||
.fill(Color.confabSecondary)
|
||||
.frame(width: 6, height: 6)
|
||||
.scaleEffect(animating ? 1.0 : 0.5)
|
||||
.animation(
|
||||
@@ -161,7 +161,7 @@ struct ProcessingIndicator: View {
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.vertical, 12)
|
||||
.background(Color.oaiSecondary.opacity(0.05))
|
||||
.background(Color.confabSecondary.opacity(0.05))
|
||||
.cornerRadius(8)
|
||||
.onAppear {
|
||||
animating = true
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ContentView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Root navigation container — NavigationSplitView with collapsible sidebar
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -134,7 +134,7 @@ struct ContentView: View {
|
||||
UserDefaults.standard.set(true, forKey: "hasShownIntelWarning")
|
||||
}
|
||||
} message: {
|
||||
Text("oAI v2.4 is the last version to support Intel Macs and Rosetta. Starting with macOS 28, oAI will require Apple Silicon. Consider upgrading your Mac to continue receiving updates.")
|
||||
Text("Confab (formerly oAI) v2.4 was the last version to support Intel Macs and Rosetta. Starting with macOS 28, Confab will require Apple Silicon. Consider upgrading your Mac to continue receiving updates.")
|
||||
}
|
||||
.alert("Software Update", isPresented: Binding(
|
||||
get: { updateService.manualCheckMessage != nil },
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// FooterView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Footer bar with session summary
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -102,7 +102,7 @@ struct FooterView: View {
|
||||
.background(.ultraThinMaterial)
|
||||
.overlay(
|
||||
Rectangle()
|
||||
.fill(Color.oaiBorder.opacity(0.5))
|
||||
.fill(Color.confabBorder.opacity(0.5))
|
||||
.frame(height: 1),
|
||||
alignment: .top
|
||||
)
|
||||
@@ -153,7 +153,7 @@ struct SaveIndicator: View {
|
||||
.foregroundColor(color)
|
||||
Text(label)
|
||||
.font(.system(size: guiSize - 2))
|
||||
.foregroundColor(isUnsaved ? .secondary : .oaiPrimary)
|
||||
.foregroundColor(isUnsaved ? .secondary : .confabPrimary)
|
||||
}
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
@@ -175,15 +175,15 @@ struct FooterItem: View {
|
||||
HStack(spacing: 6) {
|
||||
Image(systemName: icon)
|
||||
.font(.system(size: guiSize - 2))
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
|
||||
Text(label)
|
||||
.font(.system(size: guiSize - 2))
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
|
||||
Text(value)
|
||||
.font(.system(size: guiSize - 2, weight: .medium))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,5 +279,5 @@ struct UpdateBadge: View {
|
||||
FooterView(stats: stats, conversationName: "My Project", hasUnsavedChanges: true)
|
||||
FooterView(stats: stats, conversationName: "My Project", hasUnsavedChanges: false)
|
||||
}
|
||||
.background(Color.oaiBackground)
|
||||
.background(Color.confabBackground)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// HeaderView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Slim header — provider, model name, star only.
|
||||
// Status pills and stats live in SidebarView and FooterView respectively.
|
||||
@@ -8,11 +8,11 @@
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -53,7 +53,7 @@ struct HeaderView: View {
|
||||
.background(.ultraThinMaterial)
|
||||
.overlay(
|
||||
Rectangle()
|
||||
.fill(Color.oaiBorder.opacity(0.5))
|
||||
.fill(Color.confabBorder.opacity(0.5))
|
||||
.frame(height: 1),
|
||||
alignment: .bottom
|
||||
)
|
||||
@@ -73,7 +73,7 @@ struct HeaderView: View {
|
||||
}
|
||||
Text(name)
|
||||
.font(.system(size: settings.guiTextSize - 1, weight: .medium))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
.lineLimit(1)
|
||||
.frame(maxWidth: 300)
|
||||
}
|
||||
@@ -128,29 +128,29 @@ struct HeaderView: View {
|
||||
HStack(spacing: 6) {
|
||||
Text(model.name)
|
||||
.font(.system(size: settings.guiTextSize, weight: .medium))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
HStack(spacing: 3) {
|
||||
if model.capabilities.vision {
|
||||
Image(systemName: "eye").font(.system(size: 9)).foregroundColor(.oaiSecondary)
|
||||
Image(systemName: "eye").font(.system(size: 9)).foregroundColor(.confabSecondary)
|
||||
}
|
||||
if model.capabilities.tools {
|
||||
Image(systemName: "wrench").font(.system(size: 9)).foregroundColor(.oaiSecondary)
|
||||
Image(systemName: "wrench").font(.system(size: 9)).foregroundColor(.confabSecondary)
|
||||
}
|
||||
if model.capabilities.online {
|
||||
Image(systemName: "globe").font(.system(size: 9)).foregroundColor(.oaiSecondary)
|
||||
Image(systemName: "globe").font(.system(size: 9)).foregroundColor(.confabSecondary)
|
||||
}
|
||||
if model.capabilities.imageGeneration {
|
||||
Image(systemName: "paintbrush").font(.system(size: 9)).foregroundColor(.oaiSecondary)
|
||||
Image(systemName: "paintbrush").font(.system(size: 9)).foregroundColor(.confabSecondary)
|
||||
}
|
||||
}
|
||||
Image(systemName: "chevron.down").font(.caption2).foregroundColor(.oaiSecondary)
|
||||
Image(systemName: "chevron.down").font(.caption2).foregroundColor(.confabSecondary)
|
||||
}
|
||||
} else {
|
||||
HStack(spacing: 4) {
|
||||
Text("No model selected")
|
||||
.font(.system(size: settings.guiTextSize))
|
||||
.foregroundColor(.oaiSecondary)
|
||||
Image(systemName: "chevron.down").font(.caption2).foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
Image(systemName: "chevron.down").font(.caption2).foregroundColor(.confabSecondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,7 +165,7 @@ struct HeaderView: View {
|
||||
Button(action: { settings.toggleFavoriteModel(model.id) }) {
|
||||
Image(systemName: isFav ? "star.fill" : "star")
|
||||
.font(.system(size: settings.guiTextSize - 3))
|
||||
.foregroundColor(isFav ? .yellow : .oaiSecondary)
|
||||
.foregroundColor(isFav ? .yellow : .confabSecondary)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help(isFav ? "Remove from favorites" : "Add to favorites")
|
||||
@@ -187,7 +187,7 @@ struct StatusPill: View {
|
||||
.frame(width: 6, height: 6)
|
||||
Text(label)
|
||||
.font(.system(size: 10, weight: .medium))
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
}
|
||||
.padding(.horizontal, 6)
|
||||
.padding(.vertical, 2)
|
||||
@@ -230,7 +230,7 @@ struct SyncStatusPill: View {
|
||||
.frame(width: 6, height: 6)
|
||||
Text(syncLabel)
|
||||
.font(.system(size: 10, weight: .medium))
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
}
|
||||
.padding(.horizontal, 6)
|
||||
.padding(.vertical, 2)
|
||||
@@ -265,5 +265,5 @@ struct SyncStatusPill: View {
|
||||
)
|
||||
Spacer()
|
||||
}
|
||||
.background(Color.oaiBackground)
|
||||
.background(Color.confabBackground)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// InputBar.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Message input bar with resizable height and online toggle
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -86,7 +86,7 @@ struct InputBar: View {
|
||||
if text.isEmpty {
|
||||
Text("Type a message or / for commands...")
|
||||
.font(.system(size: settings.inputTextSize))
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.top, 10)
|
||||
.allowsHitTesting(false)
|
||||
@@ -96,7 +96,7 @@ struct InputBar: View {
|
||||
NativeTextEditor(
|
||||
text: $text,
|
||||
font: .systemFont(ofSize: settings.inputTextSize),
|
||||
textColor: NSColor(Color.oaiPrimary),
|
||||
textColor: NSColor(Color.confabPrimary),
|
||||
isFocused: isInputFocused,
|
||||
onReturn: {
|
||||
if showCommandDropdown {
|
||||
@@ -157,11 +157,11 @@ struct InputBar: View {
|
||||
}
|
||||
}
|
||||
.frame(height: inputHeight)
|
||||
.background(Color.oaiSurface)
|
||||
.background(Color.confabSurface)
|
||||
.cornerRadius(8)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.stroke(isInputFocused ? Color.oaiAccent : Color.oaiBorder, lineWidth: 1)
|
||||
.stroke(isInputFocused ? Color.confabAccent : Color.confabBorder, lineWidth: 1)
|
||||
)
|
||||
|
||||
// Send / stop + attach buttons
|
||||
@@ -170,7 +170,7 @@ struct InputBar: View {
|
||||
Button(action: pickFile) {
|
||||
Image(systemName: "paperclip")
|
||||
.font(.title2)
|
||||
.foregroundColor(.oaiPrimary.opacity(0.7))
|
||||
.foregroundColor(.confabPrimary.opacity(0.7))
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help("Attach file")
|
||||
@@ -180,7 +180,7 @@ struct InputBar: View {
|
||||
Button(action: onCancel) {
|
||||
Image(systemName: "stop.circle.fill")
|
||||
.font(.title)
|
||||
.foregroundColor(.oaiError.opacity(0.9))
|
||||
.foregroundColor(.confabError.opacity(0.9))
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help("Stop generation")
|
||||
@@ -188,7 +188,7 @@ struct InputBar: View {
|
||||
Button(action: onSend) {
|
||||
Image(systemName: "arrow.up.circle.fill")
|
||||
.font(.title)
|
||||
.foregroundColor(text.isEmpty ? .oaiPrimary.opacity(0.4) : .oaiAccent.opacity(0.9))
|
||||
.foregroundColor(text.isEmpty ? .confabPrimary.opacity(0.4) : .confabAccent.opacity(0.9))
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.disabled(text.isEmpty)
|
||||
@@ -198,7 +198,7 @@ struct InputBar: View {
|
||||
.frame(width: 40)
|
||||
}
|
||||
.padding()
|
||||
.background(Color.oaiSurface)
|
||||
.background(Color.confabSurface)
|
||||
}
|
||||
.onAppear {
|
||||
isInputFocused = true
|
||||
@@ -330,22 +330,22 @@ struct CommandSuggestionsView: View {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(suggestion.command)
|
||||
.font(.body)
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
Text(suggestion.description)
|
||||
.font(.caption)
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 8)
|
||||
.background(index == selectedIndex ? Color.oaiAccent.opacity(0.2) : Color.oaiSurface)
|
||||
.background(index == selectedIndex ? Color.confabAccent.opacity(0.2) : Color.confabSurface)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.id(suggestion.command)
|
||||
|
||||
if index < suggestions.count - 1 {
|
||||
Divider().background(Color.oaiBorder)
|
||||
Divider().background(Color.confabBorder)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -356,9 +356,9 @@ struct CommandSuggestionsView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.background(Color.oaiSurface)
|
||||
.background(Color.confabSurface)
|
||||
.cornerRadius(8)
|
||||
.overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.oaiBorder, lineWidth: 1))
|
||||
.overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.confabBorder, lineWidth: 1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,5 +374,5 @@ struct CommandSuggestionsView: View {
|
||||
onToggleOnline: {}
|
||||
)
|
||||
}
|
||||
.background(Color.oaiBackground)
|
||||
.background(Color.confabBackground)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// MarkdownContentView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Renders markdown content with syntax-highlighted code blocks
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -196,12 +196,12 @@ struct TableView: View {
|
||||
if index < data.headers.count {
|
||||
Text(data.headers[index].trimmingCharacters(in: .whitespaces))
|
||||
.font(.system(size: fontSize, weight: .semibold))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
.frame(maxWidth: .infinity, alignment: alignmentFor(
|
||||
index < data.alignments.count ? data.alignments[index] : .leading
|
||||
))
|
||||
.padding(8)
|
||||
.background(Color.oaiSecondary.opacity(0.1))
|
||||
.background(Color.confabSecondary.opacity(0.1))
|
||||
|
||||
if index < data.headers.count - 1 {
|
||||
Divider()
|
||||
@@ -211,7 +211,7 @@ struct TableView: View {
|
||||
}
|
||||
.overlay(
|
||||
Rectangle()
|
||||
.stroke(Color.oaiSecondary.opacity(0.3), lineWidth: 1)
|
||||
.stroke(Color.confabSecondary.opacity(0.3), lineWidth: 1)
|
||||
)
|
||||
|
||||
// Rows
|
||||
@@ -224,7 +224,7 @@ struct TableView: View {
|
||||
|
||||
Text(cellContent.trimmingCharacters(in: .whitespaces))
|
||||
.font(.system(size: fontSize))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
.frame(maxWidth: .infinity, alignment: alignmentFor(alignment))
|
||||
.padding(8)
|
||||
|
||||
@@ -233,10 +233,10 @@ struct TableView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.background(rowIndex % 2 == 0 ? Color.clear : Color.oaiSecondary.opacity(0.05))
|
||||
.background(rowIndex % 2 == 0 ? Color.clear : Color.confabSecondary.opacity(0.05))
|
||||
.overlay(
|
||||
Rectangle()
|
||||
.stroke(Color.oaiSecondary.opacity(0.3), lineWidth: 1)
|
||||
.stroke(Color.confabSecondary.opacity(0.3), lineWidth: 1)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -244,7 +244,7 @@ struct TableView: View {
|
||||
.cornerRadius(8)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.strokeBorder(Color.oaiSecondary.opacity(0.3), lineWidth: 1)
|
||||
.strokeBorder(Color.confabSecondary.opacity(0.3), lineWidth: 1)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// MessageRow.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Individual message display
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -76,7 +76,7 @@ struct MessageRow: View {
|
||||
Button(action: toggleStar) {
|
||||
Image(systemName: isStarred ? "star.fill" : "star")
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(isStarred ? .yellow : .oaiSecondary)
|
||||
.foregroundColor(isStarred ? .yellow : .confabSecondary)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.transition(.opacity)
|
||||
@@ -94,7 +94,7 @@ struct MessageRow: View {
|
||||
.font(.system(size: 11))
|
||||
}
|
||||
}
|
||||
.foregroundColor(showCopied ? .green : .oaiSecondary)
|
||||
.foregroundColor(showCopied ? .green : .confabSecondary)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.transition(.opacity)
|
||||
@@ -103,7 +103,7 @@ struct MessageRow: View {
|
||||
|
||||
Text(message.timestamp, style: .time)
|
||||
.font(.caption2)
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
}
|
||||
|
||||
// Thinking / reasoning block (collapsible)
|
||||
@@ -146,7 +146,7 @@ struct MessageRow: View {
|
||||
.font(.caption)
|
||||
Text(attachments[index].path)
|
||||
.font(.caption)
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -180,7 +180,7 @@ struct MessageRow: View {
|
||||
}
|
||||
}
|
||||
.font(.caption2)
|
||||
.foregroundColor(.oaiSecondary)
|
||||
.foregroundColor(.confabSecondary)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
@@ -400,18 +400,18 @@ struct MessageRow: View {
|
||||
if isErrorMessage {
|
||||
HStack(alignment: .top, spacing: 8) {
|
||||
Image(systemName: "exclamationmark.triangle.fill")
|
||||
.foregroundColor(.oaiError)
|
||||
.foregroundColor(.confabError)
|
||||
.font(.system(size: settings.dialogTextSize))
|
||||
Text(message.content)
|
||||
.font(.system(size: settings.dialogTextSize))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
} else {
|
||||
Text(message.content)
|
||||
.font(.system(size: settings.dialogTextSize))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
@@ -419,7 +419,7 @@ struct MessageRow: View {
|
||||
// User messages: preserve line breaks as-is (plain text, not markdown)
|
||||
Text(message.content)
|
||||
.font(.system(size: settings.dialogTextSize))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
.lineSpacing(4)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.textSelection(.enabled)
|
||||
@@ -434,7 +434,7 @@ struct MessageRow: View {
|
||||
|
||||
private var messageBorderColor: Color {
|
||||
if isErrorMessage {
|
||||
return .oaiError.opacity(0.5)
|
||||
return .confabError.opacity(0.5)
|
||||
}
|
||||
return Color.messageColor(for: message.role).opacity(0.3)
|
||||
}
|
||||
@@ -571,5 +571,5 @@ struct GeneratedImagesView: View {
|
||||
MessageRow(message: Message.mockSystem)
|
||||
}
|
||||
.padding()
|
||||
.background(Color.oaiBackground)
|
||||
.background(Color.confabBackground)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// SidebarView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Collapsible sidebar: new chat, conversation list, status pills
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -53,7 +53,7 @@ struct SidebarView: View {
|
||||
Text("New Chat")
|
||||
.font(.system(size: 14, weight: .medium))
|
||||
}
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
@@ -63,7 +63,7 @@ struct SidebarView: View {
|
||||
Button(action: { createFolderPrompt() }) {
|
||||
Image(systemName: "folder.badge.plus")
|
||||
.font(.system(size: 14))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.foregroundColor(.confabPrimary)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
@@ -236,7 +236,7 @@ struct SidebarView: View {
|
||||
}
|
||||
.listRowBackground(
|
||||
chatViewModel.currentConversationName == conversation.name
|
||||
? Color.oaiAccent.opacity(0.15)
|
||||
? Color.confabAccent.opacity(0.15)
|
||||
: Color.clear
|
||||
)
|
||||
.draggable(conversation.id.uuidString) {
|
||||
@@ -245,7 +245,7 @@ struct SidebarView: View {
|
||||
.foregroundStyle(.white)
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.vertical, 6)
|
||||
.background(Color.oaiAccent, in: RoundedRectangle(cornerRadius: 6))
|
||||
.background(Color.confabAccent, in: RoundedRectangle(cornerRadius: 6))
|
||||
}
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
||||
Button(role: .destructive) {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// SyncStatusIndicator.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Git sync status indicator (bottom-right corner)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AboutView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// About modal with app icon and version info
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -45,7 +45,7 @@ struct AboutView: View {
|
||||
.clipShape(RoundedRectangle(cornerRadius: 24))
|
||||
.shadow(color: .cyan.opacity(0.3), radius: 12)
|
||||
|
||||
Text("oAI")
|
||||
Text("Confab")
|
||||
.font(.system(size: 28, weight: .bold))
|
||||
|
||||
Text("Version \(appVersion) (\(buildNumber))")
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AgentSkillEditorSheet.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Create or edit a SKILL.md-style agent skill, with optional support files
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// AgentSkillsView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Modal for managing SKILL.md-style agent skills (opened via /skills command)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// BashApprovalSheet.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Approval UI for AI-requested bash commands
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// CombineConversationsSheet.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Combine 2+ saved conversations into one, optionally using AI to merge content
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ConversationListView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Saved conversations list
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -345,7 +345,7 @@ struct ConversationListView: View {
|
||||
}
|
||||
.listRowBackground(
|
||||
!isSelecting && index == selectedIndex
|
||||
? Color.oaiAccent.opacity(0.15)
|
||||
? Color.confabAccent.opacity(0.15)
|
||||
: Color.clear
|
||||
)
|
||||
.id(conversation.id)
|
||||
@@ -355,7 +355,7 @@ struct ConversationListView: View {
|
||||
.foregroundStyle(.white)
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.vertical, 6)
|
||||
.background(Color.oaiAccent, in: RoundedRectangle(cornerRadius: 6))
|
||||
.background(Color.confabAccent, in: RoundedRectangle(cornerRadius: 6))
|
||||
}
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
||||
Button(role: .destructive) {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// CreditsView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Account credits and balance
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// EmailLogView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Email handler activity log viewer
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// HelpView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Help and commands reference with expandable detail and search
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// HistoryView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Command history viewer with search
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -149,7 +149,7 @@ struct HistoryView: View {
|
||||
}
|
||||
}
|
||||
.frame(minWidth: 600, minHeight: 400)
|
||||
.background(Color.oaiBackground)
|
||||
.background(Color.confabBackground)
|
||||
.task {
|
||||
loadHistory()
|
||||
isListFocused = true
|
||||
@@ -191,7 +191,7 @@ struct HistoryRow: View {
|
||||
}
|
||||
.padding(.vertical, 8)
|
||||
.padding(.horizontal, 4)
|
||||
.listRowBackground(isSelected ? Color.oaiAccent.opacity(0.2) : Color.clear)
|
||||
.listRowBackground(isSelected ? Color.confabAccent.opacity(0.2) : Color.clear)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// JarvisView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Main modal for managing Jarvis (oAI-Web) agents and usage.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ModelInfoView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Rich model information modal
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -69,6 +69,9 @@ struct ModelInfoView: View {
|
||||
if let provider = model.topProvider {
|
||||
infoRow("Provider", provider)
|
||||
}
|
||||
if let releaseDate = model.releaseDate {
|
||||
infoRow("Released", releaseDate.formatted(date: .abbreviated, time: .omitted))
|
||||
}
|
||||
if let desc = model.description {
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
Text("Description")
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ModelSelectorView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Model selection screen
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// PersonalDataApprovalSheet.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Approval UI for AI-requested Calendar/Reminders write actions
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// SettingsView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Settings and configuration screen
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -514,7 +514,7 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
|
||||
}
|
||||
}
|
||||
}
|
||||
Text("Controls which messages are written to ~/Library/Logs/oAI.log")
|
||||
Text("Controls which messages are written to ~/Library/Logs/Confab.log")
|
||||
.font(.system(size: 13))
|
||||
.foregroundStyle(.secondary)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
@@ -1605,7 +1605,7 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
|
||||
.font(.system(size: 13))
|
||||
Text("• Add public key to your git provider")
|
||||
.font(.system(size: 13))
|
||||
Text("• No credentials needed in oAI")
|
||||
Text("• No credentials needed in Confab")
|
||||
.font(.system(size: 13))
|
||||
}
|
||||
.foregroundStyle(.secondary)
|
||||
@@ -1822,7 +1822,7 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
|
||||
.font(.system(size: settingsService.guiTextSize))
|
||||
.foregroundColor(.secondary)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
Text("Example: oai-bot-x7k2m9p3@gmail.com")
|
||||
Text("Example: confab-bot-x7k2m9p3@gmail.com")
|
||||
.font(.system(size: settingsService.guiTextSize - 1, design: .monospaced))
|
||||
.foregroundColor(.blue)
|
||||
.padding(.vertical, 4)
|
||||
@@ -2483,7 +2483,7 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("Jarvis is oAI-Web, a self-hosted companion server that lets oAI sync and connect remotely.")
|
||||
Text("Jarvis is oAI-Web, a self-hosted companion server that lets Confab sync and connect remotely.")
|
||||
.foregroundStyle(.secondary)
|
||||
Link("→ Jarvis / oAI-Web on Gitea", destination: URL(string: "https://gitlab.pm/rune/oai-web")!)
|
||||
}
|
||||
@@ -2585,7 +2585,7 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
|
||||
.frame(width: 220)
|
||||
}
|
||||
}
|
||||
Text("When enabled, oAI backs up automatically in the background (checked at launch and hourly while running) — no need to press \"Back Up Now\" yourself.")
|
||||
Text("When enabled, Confab backs up automatically in the background (checked at launch and hourly while running) — no need to press \"Back Up Now\" yourself.")
|
||||
.font(.system(size: 13))
|
||||
.foregroundStyle(.secondary)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
@@ -2706,7 +2706,7 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
|
||||
defer { url.stopAccessingSecurityScopedResource() }
|
||||
try await backupService.importSettings(from: url)
|
||||
await MainActor.run {
|
||||
backupMessage = "Settings restored. Re-enter your API keys to resume using oAI."
|
||||
backupMessage = "Settings restored. Re-enter your API keys to resume using Confab."
|
||||
backupMessageIsError = false
|
||||
isImporting = false
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ShortcutEditorSheet.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Create or edit a user-defined shortcut (prompt template)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// ShortcutsView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Modal for managing user-defined shortcuts (opened via /shortcuts command)
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// StatsView.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Session statistics screen
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
|
||||
@@ -8,31 +8,31 @@
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "oAI"
|
||||
"value" : "Confab"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "oAI can read and create calendar events when you ask it to, if you enable Calendar access in Settings."
|
||||
"value" : "Confab can read and create calendar events when you ask it to, if you enable Calendar access in Settings."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "oAI can search your contacts when you ask it to, if you enable Contacts access in Settings."
|
||||
"value" : "Confab can search your contacts when you ask it to, if you enable Contacts access in Settings."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "oAI can use your current location to answer questions, if you enable Location & Maps access in Settings."
|
||||
"value" : "Confab can use your current location to answer questions, if you enable Location & Maps access in Settings."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "oAI can read and create reminders when you ask it to, if you enable Reminders access in Settings."
|
||||
"value" : "Confab can read and create reminders when you ask it to, if you enable Reminders access in Settings."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -1,17 +1,17 @@
|
||||
//
|
||||
// oAIApp.swift
|
||||
// oAI
|
||||
// Confab
|
||||
//
|
||||
// Main app entry point
|
||||
//
|
||||
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
||||
// Copyright (C) 2026 Rune Olsen
|
||||
//
|
||||
// This file is part of oAI.
|
||||
// This file is part of Confab.
|
||||
//
|
||||
// oAI is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
|
||||
// You may use, study, modify, and share it for any noncommercial
|
||||
// purpose. Commercial use — including selling oAI or any part of
|
||||
// purpose. Commercial use — including selling Confab or any part of
|
||||
// it, standalone or bundled into another product or service —
|
||||
// requires a separate commercial license from the copyright holder.
|
||||
//
|
||||
@@ -117,7 +117,7 @@ struct oAIApp: App {
|
||||
.commands {
|
||||
// ── Apple menu ────────────────────────────────────────────────
|
||||
CommandGroup(replacing: .appInfo) {
|
||||
Button("About oAI") { showAbout = true }
|
||||
Button("About Confab") { showAbout = true }
|
||||
}
|
||||
|
||||
CommandGroup(replacing: .appSettings) {
|
||||
@@ -206,7 +206,7 @@ struct oAIApp: App {
|
||||
|
||||
// ── Help menu ─────────────────────────────────────────────────
|
||||
CommandGroup(replacing: .help) {
|
||||
Button("oAI Help") { openHelp() }
|
||||
Button("Confab Help") { openHelp() }
|
||||
.keyboardShortcut("?", modifiers: .command)
|
||||
Divider()
|
||||
Button(UpdateCheckService.shared.isCheckingManually ? "Checking…" : "Check for Updates…") {
|
||||
@@ -224,7 +224,7 @@ struct oAIApp: App {
|
||||
// through NSHelpManager/Help Viewer — see CLAUDE.md's macOS 27 beta note for why
|
||||
// (Apple's Tips.app replacement for Help Viewer can't resolve anchors on this beta).
|
||||
// Revisit once macOS 27 reaches RC.
|
||||
if let helpBookURL = Bundle.main.url(forResource: "oAI.help", withExtension: nil) {
|
||||
if let helpBookURL = Bundle.main.url(forResource: "Confab.help", withExtension: nil) {
|
||||
NSWorkspace.shared.open(helpBookURL.appendingPathComponent("Contents/Resources/en.lproj/index.html"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import Testing
|
||||
import Foundation
|
||||
@testable import oAI
|
||||
@testable import Confab
|
||||
|
||||
@Suite("ChatResponse / Usage decoding")
|
||||
struct AIProviderTests {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user