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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Public browser configuration. Use a same-origin path, never a credential.
VITE_KEEPSIDE_API_URL=/api
60 changes: 60 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Bug report
description: Report a reproducible problem in Keepside
title: "[Bug]: "
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report this. Do not attach a real workspace export. Reproduce the issue with sample data.
- type: input
id: browser
attributes:
label: Browser and version
placeholder: Safari 19.0, Chrome 140, Firefox 142
validations:
required: true
- type: input
id: revision
attributes:
label: Keepside version or commit
placeholder: v0.1.0 or a commit SHA
validations:
required: true
- type: textarea
id: steps
attributes:
label: Reproduction steps
description: Start from a fresh workspace or the built-in sample workspace.
placeholder: |
1. Load the sample workspace
2. Open ...
3. Choose ...
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected result
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual result
validations:
required: true
- type: dropdown
id: mode
attributes:
label: Storage mode
options:
- Local mode
- Connected-mode client or custom server
- Not sure
validations:
required: true
- type: textarea
id: notes
attributes:
label: Safe supporting material
description: Add console errors or screenshots only after removing client data and credentials.
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/conduct.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Conduct report
description: Flag a public project interaction for maintainer review.
title: "[Conduct] "
body:
- type: markdown
attributes:
value: |
This form creates a public issue. Link to the interaction, but do not include private client information, contact details, or other sensitive material. For threats, doxxing, or private evidence, use GitHub's abuse reporting route instead.
- type: input
id: location
attributes:
label: Interaction
description: Link to the issue, pull request, comment, or other public project interaction.
placeholder: https://github.com/SebastianSteele/keepside-web/...
validations:
required: true
- type: textarea
id: concern
attributes:
label: What needs review?
description: Give the maintainer enough context to locate the concern without repeating harmful or private content.
validations:
required: true
- type: checkboxes
id: privacy
attributes:
label: Public report
options:
- label: I understand this report is public and contains no private client data or sensitive evidence.
required: true
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Private security report
url: https://github.com/SebastianSteele/keepside-web/security/advisories/new
about: Report a vulnerability without publishing sensitive details.
38 changes: 38 additions & 0 deletions .github/ISSUE_TEMPLATE/feature.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Feature proposal
description: Suggest a focused improvement to client work
title: "[Proposal]: "
body:
- type: markdown
attributes:
value: Do not attach a real workspace export or include client data. Use the sample workspace for examples.
- type: textarea
id: problem
attributes:
label: What client-work problem are you trying to solve?
description: Describe the real workflow before describing a screen or implementation.
validations:
required: true
- type: textarea
id: current
attributes:
label: How do you handle it today?
validations:
required: true
- type: textarea
id: change
attributes:
label: Smallest useful change
description: Explain the outcome, including what Keepside can leave out.
validations:
required: true
- type: dropdown
id: data
attributes:
label: Does this change stored or transmitted data?
options:
- No
- Yes, local workspace data
- Yes, connected-mode data
- Not sure
validations:
required: true
21 changes: 21 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## What changed


## Why


## Visual proof

Add before and after screenshots for interface changes. Use the sample workspace only.

## Checks

- [ ] `npm run typecheck`
- [ ] `npm test`
- [ ] `npm run build`
- [ ] `npm audit --audit-level=high`

## Data boundary

- [ ] I described any workspace schema, persistence, privacy, or network impact.
- [ ] I did not include real client data, workspace exports, or credentials.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
node-version: 20.19.0
cache: npm
- run: npm ci
- run: npm run typecheck
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ dist
.DS_Store
*.local
*.log
.env
.env.*
!.env.example
coverage
*.tsbuildinfo
vite.config.js
Expand Down
17 changes: 15 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,24 @@ Keepside uses a single workspace document as its source of truth.
- `src/App.tsx` owns the current workspace instance and presentation state.
- Screens render derived data and open editors. They do not write browser storage directly.
- Editors return complete typed records to the application. They do not implement persistence rules.
- `src/infrastructure/serverClients.ts` owns the optional connected-service transport. It does not redefine domain records.

## Storage
## Local mode

The whole workspace is validated before it is read, saved, imported, or exported. Invalid stored data falls back to an empty workspace. Deleting a client also removes records owned by that client. Deleting a contact clears its references from meetings and email records.

Local mode persists that document in one browser `localStorage` entry. It makes no workspace or mail network request.

## Connected-mode seam

Connected mode is an experimental integration boundary, not a second active data model. `WorkspaceApiClient` loads and saves the same `WorkspaceData` document through the contract in `docs/openapi.yaml`. Every response is passed through the existing domain validator. Conditional writes use the last server `ETag`, so a stale client cannot overwrite a newer revision silently.

A product that activates connected storage must choose it explicitly. It should upload once or open the existing server workspace, then use one store only. Automatic merges and local-plus-server dual writes are intentionally absent.

`MailRelayClient` submits one outgoing draft after an explicit user action. It marks nothing sent by itself. When **Send through relay** is used, the editor changes the record to sent only after the relay returns an accepted receipt. A person can still log an already-sent message manually.

The reference PostgreSQL shape stores one JSON document per authenticated owner. Delivery metadata lives in a separate table because it describes the transport, not the client record.

## Product boundary

Keepside is a manual client manager. Hosted sync, AI features, analytics, inbox access, automations, credential storage, and third-party integrations are outside this repository.
Keepside is a manual client manager. AI features, analytics, inbox ingestion, automations, browser-side credential storage, automatic conflict merging, and public mail-service infrastructure are outside this repository.
21 changes: 21 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Code of conduct

Keepside should be a useful place to do careful work together.

## Expected conduct

- Treat people and their time with respect.
- Critique the work without belittling the person behind it.
- Make room for different levels of experience and different kinds of client work.
- Keep private client information, credentials, and workspace exports out of public issues.
- Accept a clear boundary when someone asks to end an interaction.

Harassment, discrimination, threats, sexual attention, doxxing, and deliberate disruption are not welcome in project spaces.

## Scope and enforcement

This applies in the repository, issue tracker, pull requests, and public conversations where someone represents Keepside.

For project moderation, open a short issue that links to the interaction without repeating private details. The maintainer may edit or remove content, close participation, or ban an account when needed to protect the community.

For a private or platform-level report, use [GitHub's abuse reporting route](https://support.github.com/contact/report-abuse).
24 changes: 22 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
# Contributing

Small, focused pull requests are welcome.
Small, focused pull requests are welcome. Start with the workflow problem and keep the implementation as narrow as the fix allows.

Before opening one, run:

```bash
npm run typecheck
npm test
npm run build
npm audit
npm audit --audit-level=high
```

Keep domain rules in `src/domain/workspace.ts`. Do not introduce a second persistence path or duplicate entity logic inside a screen. New dependencies should solve a demonstrated problem that browser APIs and the existing code cannot cover simply.

The interface should remain calm, readable, and specific to client work. Avoid generic dashboard cards, decorative statistics, chat assistants, automation builders, gradients used as filler, or placeholder business metrics.

## Data and screenshots

- Use the built-in sample workspace for reproduction steps and screenshots.
- Never commit a real workspace export, client address, inbox message, API key, or `.env` file.
- Call out changes to `WorkspaceData`, import compatibility, storage, network requests, and deletion behavior in the pull request.
- For connected-mode work, keep `src/domain` canonical and update `docs/openapi.yaml` when the public transport changes.

## Interface work

Check desktop and mobile widths, keyboard focus, reduced motion, empty states, long names, and destructive confirmations. Visual changes need before and after screenshots in the pull request.

For a reproducible production build with the sample workspace preloaded:

```bash
VITE_KEEPSIDE_DEMO=true VITE_KEEPSIDE_API_URL=/api npm run build
npm exec vite -- preview
```

In that build only, `?section=clients&client=client-studio` opens the sample client and `?section=mail&compose=email-studio-review-draft` opens the sample draft. Default builds ignore those query values.
Loading
Loading