Compare commits

..
5109 Commits
Author SHA1 Message Date
Juan Fernando Castro 24fb679dd3 fix: charge stat's return_shares against the share-listing budget (#3870)
* fix: charge stat's return_shares against the share-listing budget

`return_shares` on /fs/stat and the legacy /stat runs the same work as
GET /share/shares, but was only metered under fs:stat's far more
generous limit — and the two scopes stacked instead of sharing one
counter.

Adds consumeRouteRateLimit(req, spec), an imperative charge that
resolves the key and per-subscription limit exactly as rateLimitGate
does, so a handler can conditionally spend a second scope when a
request flag makes the route expensive. Both stat handlers now charge
share:list before doing the listing work; SHARE_LIST_LIMIT moves to a
shared share/limits.ts so all callers pin the same spec.

Closes PUT-1597.

* feat: consumeRouteRateLimit takes the array spec form too

Review follow-up on #3870: a multi-window spec passed whole would have
read an undefined window and silently never pruned. Charge each window
in order instead, refusing on the first refusal, matching the gate.
2026-09-19 14:11:29 -07:00
Daniel Salazar eb9f03e984 fix: misc hardening + other fixes (#3906) 2026-09-19 12:57:57 -07:00
Daniel Salazar 9292771554 fix: hardening (#3904) 2026-09-18 11:22:39 -07:00
Reynaldi Chernando f4974581d0 Add auth message for external apps using puterjs (#3893) 2026-09-18 08:56:02 +07:00
Daniel Salazar b39bb771d9 feat: sortby for recursive readdir (#3900) 2026-09-17 17:29:55 -07:00
Nariman Jelveh 766379ae9f feat(puterjs): add defensive profile picture lookup (#3899) 2026-09-17 17:16:54 -07:00
Daniel Salazar 0be3bc55c2 feat(metering): AI cost multiplier hook for AI drivers (#3898)
Emits ai.cost.multiplier.<driver>.<provider>:<model> before recording AI
usage, so what a model costs to charge is policy an extension owns rather
than a number in core. Nothing listening records the provider cost.

MeteringService.withAiCostMultiplier(driver) returns a view of the service
whose recording paths scale costOverride by the hook's answer; every AI
driver hands that view to its providers, so all of them are covered without
touching provider code.
2026-09-17 15:18:38 -07:00
Nariman Jelveh d1484af754 One recipient field in the sharing dialogs, with suggestions (#3897)
* feat: one recipient field in the sharing dialogs, with suggestions

Both sharing dialogs asked twice: a text field for a person, and a
separate select, label, note and button for a team. Which control to use
was a fact about the API — a bare string is read as an email or a
username, so a team could not be typed — not something a user should
have to know.

Now there is one field. Clicking it offers who this account shared with
before, the teams it belongs to, and the people in them; typing narrows
the list. Choosing an offer locks the field to that recipient, so a team
picked by name still goes out by uid, and the note about a team grant
reaching everyone in it appears at the moment it applies. Anyone already
on the access list is left out of the offers, and a typed address still
works untouched.

Past recipients are kept in the account's key-value store, so they
follow the user between browsers; a typed address that turned out to
belong to an account is filed under the username the backend resolved.
Colleagues are read one page per team, cached for five minutes, and only
looked up once the field is actually used.

The picker is one helper shared by both dialogs so the two can't drift,
styled through `share-suggest-*` tokens each host restates in its own
palette. It opens in the flow rather than floating, which a scrolling
modal body and a mobile bottom sheet would otherwise clip.

* fix: float the recipient suggestions instead of resizing the dialog

The list opened in the flow, which pushed the Share button and everything
under it down and back up as it opened and closed — a dialog that resizes
under the cursor. It now hangs off the recipient row, out of the flow, and
floats over what follows it.

It goes inside the row rather than after it, so the row is its containing
block; as a sibling it resolved against whatever was positioned further up
and landed at the bottom of the scrolling body. Being out of flow it can
be cut off by that scroll container rather than scrolling itself, so on
open it measures the room between the row and the nearest clipping
ancestor, caps the list to it, and opens upwards where below is too tight.

* fix: keep the recipient field focused when the picker is wired onto it

Both sharing dialogs focus the recipient field as they open, and the
picker then moves that field into its wrapper. Moving an element takes
it out of the document for an instant, which drops its focus, so every
dialog opened with the caret in the field opened with the caret on
<body> instead.

* fix: keep the recipient suggestions inside the screen

The list sized itself against the nearest clipping ancestor alone. That
ancestor is the dialog's own scrolling body, which reaches past the
bottom of a short screen — or of any screen once the dialog has been
dragged low — so the list was placed below the fold and the user saw
nothing at all. The viewport bounds it too.

* fix: stop the suggestions flashing a loading box over the dialog

Clicking the recipient field put up a panel saying it was loading before
it knew there was anything to load. For the many accounts with no teams
and nobody shared with before, that panel covered the Share button for
as long as the round trip took and then vanished again. It now waits a
beat before saying anything, and leaves whatever is already listed in
place while a reload is in flight. A list still on its way also no
longer swallows the Escape that closes the dialog.

* fix: do not double-encode the recipient field's placeholder

`i18n()` encodes what it returns, which is right for a string dropped
into markup and wrong for one handed to `.attr()` — the entities show up
as themselves. Nothing is lost today because only English carries the
key, but the next translation with an apostrophe in it would read
`l&apos;équipe`.

* chore: drop the styles for the team picker the field replaced

The desktop dialog's separate team control went with the one recipient
field; its rules stayed behind. The dashboard's equivalents were already
removed with its own markup.

* fix: let Enter share from the desktop dialog's recipient field

Typing a name and pressing Enter did nothing there: the field is in no
form, so the only way to send was to reach the button. The Dashboard's
dialog has always submitted on Enter, and the field now takes Enter to
choose a suggestion, which makes a second press that does nothing read
as a dead key. The picker still gets the press first while it is
choosing a row.
2026-09-17 13:54:03 -07:00
Daniel Salazar 51ce868d1e fix: shared kv handles also allow value opt in (#3895) 2026-09-17 10:34:35 -07:00
Daniel Salazar bb97660ad7 feat: kv events value opt in (#3894) 2026-09-17 00:17:12 -07:00
Neal Shah b2fef45fd6 email read api (#3869)
* email read api

* address docs changes

* remove playground examples
2026-09-16 18:38:58 -04:00
Juan Fernando Castro ff333d05e8 Merge pull request #3890 from HeyPuter/juancastro/put-1819-keep-plan-console
feat: tell the plan picker when a seat's plan is on the way out
2026-09-16 18:05:12 -04:00
Daniel Salazar 194ca7c789 fix: list a link share only while the owner's plan covers it (#3891)
* fix: list a link share only while the owner's plan covers it

* chore: types + jsdoc cleanup
2026-09-16 14:42:52 -07:00
Juan Castro 0b85203edb feat: tell the plan picker when a seat's plan is on the way out
The billing view now names each seat's status; the console passes it
through to the picker so a cancel-pending plan can be kept, plus the
two strings that flow renders.
2026-09-16 15:55:52 -04:00
Daniel Salazar 1b6334c02c feat: a paid plan counts as a verified card for the sharing gate (#3886)
* fix: list a link share only while the owner's plan covers it

* fix: fs limits for signed urls

* feat: a paid plan counts as a verified card for the sharing gate
2026-09-16 10:18:47 -07:00
Juan Fernando Castro 05cbd33211 Merge pull request #3888 from HeyPuter/juancastro/bump-sqlite-schema-version-80
test: schema version is 80 since 0084
2026-09-16 13:04:15 -04:00
Juan Castro 5c8f02384c test: schema version is 80 since 0084
#3874 added 0084_share-anyone-with-link.sql, taking the sqlite chain's
target user_version to 80, but CURRENT_SCHEMA_VERSION stayed at 79 —
and the test workflow only runs on PRs, so main broke silently and every
open PR's 'test (base)' job now fails on it.
2026-09-16 12:48:07 -04:00
Reynaldi Chernando 79c856386f document model variants (#3875) 2026-09-16 19:31:28 +07:00
Daniel Salazar 59f73528cb feat: share with anyone with the link (PUT-1580) (#3874)
* feat(email): inline cid attachments and Puter mailbox delivery for sendTransactional

EmailAttachment gains cid/contentDisposition so the transactional driver can send inline images. The SDK's EmailAttachment typedef now comes from types.js, which already carried cid. Docs describe delivery to <username>@puter.email recipients and the not_found code.

* feat: share with anyone with the link (PUT-1580); gate sharing on a verified phone or card
2026-09-15 21:06:12 -07:00
Daniel Salazar 45aff36f0c fix: auto create folders for fs perms (#3873) 2026-09-15 15:11:13 -07:00
Nariman Jelveh a1f7577acb fix: warn before closing the tab while an upload is in flight
Uploads stream from the page, so closing the tab loses a nearly-finished
one with no warning. The beforeunload handler only existed behind
prompt_user_when_navigation_away_from_puter, which is off by default.

Install it unconditionally and have it consult window.active_uploads,
the registry the progress code already maintains. The feature flag keeps
its open-window behavior.

Uploads now register in active_uploads before the first await in the
init callback: an upload failing while the progress window was still
opening used to run its delete ahead of the insert, leaving a phantom
entry that would have made the tab unclosable.
2026-09-15 13:07:43 -07:00
Juan Fernando Castro b136c56cb5 Merge pull request #3846 from HeyPuter/juancastro/put-1792-optional-seat-email
feat: the team seat experience — no email required, forced password change, team label, and plan-based limits (PUT-1792)

Note: Bypassing the code owners rule, since there are couple approvals in place for this.
2026-09-15 14:53:06 -04:00
Juan Castro f428797a79 feat: render the teams UI for allowlisted users without the global switch
`gui_params.teams_ui` stays the deployment-wide switch; with it off, the
tab now also renders for a signed-in user who passes the email-domain
allowlist (membership included, so seats see their roster). Anonymous
renders hide it, and the API keeps deciding real access either way.
2026-09-15 14:48:11 -04:00
Juan Castro ad3d15e7e2 feat: stage the teams rollout behind an email-domain allowlist
`teams_allowed_email_domains` limits who may enter the teams surface;
unset keeps today's behavior. Gated on the two routes that constitute
entry — creating a team, and the listing that shows the tab — with the
same 404 a teams-off deployment answers, so the GUI needs no change and
a staged rollout is indistinguishable from the feature being off.
Members of an existing team always pass, whatever their domain: an
allowed owner brought them in, and the surface follows the team.
2026-09-15 14:23:49 -04:00
dependabot[bot] 07bf0be9c7 chore(deps): bump peter-evans/create-pull-request from 6 to 8 (#3865)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6 to 8.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v8)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-15 10:39:50 -07:00
dependabot[bot] d116f49669 chore(deps): bump dorny/paths-filter from 3 to 4 (#3866)
Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from 3 to 4.
- [Release notes](https://github.com/dorny/paths-filter/releases)
- [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dorny/paths-filter/compare/v3...v4)

---
updated-dependencies:
- dependency-name: dorny/paths-filter
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-15 10:35:19 -07:00
dependabot[bot] a5f267c2d4 chore(deps): bump docker/setup-qemu-action from 3 to 4 (#3864)
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-15 10:35:07 -07:00
Daniel Salazar 2fdd67c72e fix: tighten up fs perm strings (#3860) 2026-09-15 10:33:47 -07:00
dependabot[bot] 92dfe4019e chore(deps): bump compression from 1.8.1 to 1.8.2 (#3861)
Bumps [compression](https://github.com/expressjs/compression) from 1.8.1 to 1.8.2.
- [Release notes](https://github.com/expressjs/compression/releases)
- [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/compression/compare/v1.8.1...v1.8.2)

---
updated-dependencies:
- dependency-name: compression
  dependency-version: 1.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-15 10:30:41 -07:00
dependabot[bot] 61a6820767 chore(deps-dev): bump @types/node from 24.13.3 to 24.13.4 (#3862)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.13.3 to 24.13.4.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.13.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-15 10:29:37 -07:00
dependabot[bot] 38b131e5e8 chore(deps): bump libphonenumber-js from 1.13.12 to 1.13.13 (#3863)
Bumps [libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js) from 1.13.12 to 1.13.13.
- [Changelog](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/catamphetamine/libphonenumber-js/compare/v1.13.12...v1.13.13)

---
updated-dependencies:
- dependency-name: libphonenumber-js
  dependency-version: 1.13.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-15 10:29:09 -07:00
Juan Castro 230241d6d2 fix: let an owner retire the seats of a deleted team, and only those
Deleting a team suspends every provisioned seat, but every member route
resolved live teams only — so the suspended seats could never be
deleted afterwards, stranding the accounts and, on the billing side,
their paused subscriptions. deleteMember now resolves the team
soft-deleted or not, matching the audit reader.

It also gains the guard enableMember always had: only the team's own
suspension qualifies. A platform-suspended seat could previously be
cascade-deleted by the owner, destroying an account Puter had frozen.
2026-09-15 13:22:13 -04:00
Juan Castro 27dd0f8ce6 docs: publish only the team surface an app can actually call
Every team route except the directory refuses app and API-token callers —
administration belongs to the account console. Publishing provisioning,
credentials, suspension and audit in the app-developer docs invited
integrations that would 403 on their first request, so those thirteen
pages are gone and the overview is rewritten around what an app can do:
detect team context with list(), look up colleagues with listDirectory(),
and share with a whole team.

listDirectory — the one app-callable method — was also the only one with
no page; it has one now, leading with its consent gate. The team
recipient joins the share() docs, where the integration actually happens.
2026-09-15 09:34:17 -04:00
Daniel Salazar 50d3794283 feat: handle sub required endpoints better (#3859) 2026-09-14 21:39:01 -07:00
Daniel Salazar 7fdbc0247f fix: bug bounty dupes (#3858) 2026-09-14 16:04:00 -07:00
Juan Castro 3bf5ba3525 feat: i18n keys for the seat cancel flow 2026-09-14 18:40:37 -04:00
Juan Castro 018196f8b4 feat: i18n keys for the team billing surfaces
The private billing extensions render user-facing strings; their keys
live here with every other translation.
2026-09-14 17:22:04 -04:00
Juan Castro c3e2717e8e fix: close the review findings on the seat experience
From the adversarial review of this PR.

The forced password-change gate could deadlock: it POSTed to the
cookie-only route with a bare fetch, and both initgui call sites open it
before update_auth_data mints the session cookie — a fresh browser with a
token URL 401'd every submit inside a non-dismissible loop. It uses the
session-cookie retry wrapper now, taking the caller's token because
window.auth_token does not exist yet on that path. It also gains the
logout footer its sibling gates have; a lost temporary password was a
hard lock with devtools as the only exit.

Password recovery refused for seats: the address is admin-supplied and
never verified, so whoever holds that inbox could take the seat over at
any later time. A seat's recovery channel is its admin's reset.

change-email gets the same seat guard as change-username and deletion —
the address is where admin-issued credentials go.

The login response now carries `team` alongside requires_password_change:
no-reload logins store that payload as window.user verbatim, and every
seat restriction keys on it.

Smaller: the team-badge tooltip no longer double-encodes; the create-token
hint for an emailless account stops pointing at a verification it can
never perform; the quotas doc records the halved org_seat_free allowance;
the config template tells upgrading operators how to keep the old flat
cap; the SDK suite covers emailless provisioning and the owner-only uuid.
2026-09-14 17:00:18 -04:00
Juan Castro 15527eac4c fix: hold a team seat to the free caps it was meant to have
Review catch by @Salazareo: `org_seat_free` reached `FREE_SUBSCRIPTION_IDS`
and so the `requireSubscription` gate, but two other surfaces decide on
plan and neither consults that set.

`bySubscription` maps name `user_free` and `temp_free`. A plan that
matches no key fell through to the top-level `limit` -- the paid cap --
so a seat outranked an ordinary free account: 240 event listings a minute
against their 120, and the same shape across the kv, notification,
subdomain and worker drivers. Both resolvers now fall back to the
`user_free` entry for anything in the free set, which covers every driver
at once and any free plan added later.

`subscriberOnly` compared against the two named ids, so a seat could
reach a paid-only model. It asks the set now.

A paid plan that names no cap of its own still takes the base, and an
unresolved plan still takes the base; there are tests for both so the
fallback cannot widen into "free by default".
2026-09-14 09:44:32 -04:00
Nariman Jelveh 4a23c296f0 Fix/dashboard apps files audit (#3857)
* Dashboard Files: keep rows in sorted order when icons resolve late

renderDirectory appended each row as soon as its icon resolved. Icons for
weblinks and .app files are read from the file itself, so those rows always
landed at the end of the listing regardless of the sort column or direction.
Resolve every icon first, then append the rows in sorted order; renderItem
takes the pre-resolved icon and still looks it up itself for single-row
callers (socket adds, instant folder creation).

* Rename: store the new item name raw in data attributes and the editor

rename_file wrote html_encode(new_name) into data-name, title and the
name editor's value. jQuery's attr()/val() store strings literally, so a
file renamed to "a&b.txt" carried data-name "a&amp;b.txt": the dashboard
Files tab, which re-reads data-name for column truncation, then showed the
entity on screen, type-to-select and sorting compared the encoded string,
and the editor reopened on the encoded name. The initial render already
stores these raw; make the rename path match.

* Dashboard Files: Enter with several folders selected enters only the first

The Enter handler called pushNavHistory + renderDirectory for every selected
folder. Only the first render runs (renderDirectory drops calls while one is
in flight), but every folder was pushed onto the navigation history, so after
selecting two folders and pressing Enter, Back led to the folder already on
screen and Forward to one that was never opened. Enter now navigates into the
first selected folder only; selected files still open in their apps.

* Dashboard Files: don't offer to move items the user can't move

Trashing or cutting sends an item to its owner's trash or a new folder, which
a shared root or a read-only share can't do — the server answers Forbidden and
the user gets an error alert for an action that should not have been offered.
The single-item context menu already leaves Delete out for such rows; the
Delete key, Ctrl/Cmd+X, the multi-selection menu and the mobile selection bar
did not check. Route all of them through can_restructure, skipping rows that
can't move and hiding Cut/Delete when the whole selection can't.

* Dashboard Files: hide New Folder and Upload in the Shared view

Shared is a query over other people's items, not a directory. Both buttons
stayed visible there: New Folder did nothing, and Upload opened the OS file
picker and then silently dropped whatever the user picked. Hide them the same
way Trash already does.

* Dashboard Files: let the same file be picked again after a failed upload

The upload input was only cleared in the success callback, so after an upload
that failed, was cancelled, or was blocked (Shared view), choosing the same
file again fired no change event and nothing happened. Snapshot the picked
files and clear the input as soon as the change fires. This also drops the
document.querySelector('form').reset() that reset whichever form came first
in the document rather than this one.

* Dashboard Files: read saved preferences in parallel and re-sort immediately

init awaited four independent kv reads one after another before the first
listing could start, and handleSort awaited two kv writes before re-rendering,
so a sort click cost two round-trips before anything moved. Issue the reads
together and let the writes settle in the background. While here, set
$el_window before the first await (renderDirectory reached through a route
change or socket event during init threw and left renderingDirectory stuck),
and tolerate a corrupt saved column_widths value instead of failing init.

* Dashboard Files: show the loading spinner on the first directory load

showSpinner keyed off a loading flag, but clearing the listing at the start of
a navigation removed the overlay without resetting it: init's spinner was
wiped by the first render's clear, and the render's own showSpinner call then
no-oped, so the initial load ran with no indicator. Guard on the overlay's
presence instead.
2026-09-13 11:31:16 -07:00
Ayoub Ait ChikhandDaniel Salazar 790db87e13 Fix/node signed batch upload (#3816)
* puter_signed_upload_error_correction

* docs: update signed upload behavior

* fix(puter-js): complete a bodiless response in the XHR shim

A response with no body at all (`fetch` gives `null`) threw inside the
shim's own `then`, the same way a missing content-type did: no 'load',
no 'error', the request hangs forever. Signed storage PUTs answer in
exactly that shape.

Adds the regression tests the content-type fix was missing — all three
hang against the shim as it was.

* refactor(puter-js): drop the signed batch-write env allowlist

With `nodejs`, `service-worker` and `web-worker` added, the list held
every value `puter.env` can take, so the gate decided nothing — and a
new env would have been silently routed to the legacy path.

The backend capability check (`signedBatchWriteSupported`, set from a
404/405/501 on `startBatchWrite`) is the one that still does work.

* test: run the directory-upload suite on node and workers

Both were pinned to browser because the legacy `/batch` fallback cannot
create a directory tree. Now that every platform takes the signed path
they are the regression test for it, and the stale comment goes with
them.

---------

Co-authored-by: Daniel Salazar <[email protected]>
2026-09-12 16:32:36 -07:00
dependabot[bot] b901040c14 chore(deps): bump nodemailer from 9.0.6 to 9.1.1 (#3832)
Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 9.0.6 to 9.1.1.
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v9.0.6...v9.1.1)

---
updated-dependencies:
- dependency-name: nodemailer
  dependency-version: 9.1.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-12 00:32:34 -07:00
Daniel Salazar ed7e0b9cc4 fix: sharing, events and worker-credential authorization hardening (#3855)
- PUT-1800: gate `createWorkerSessionToken` on actor type, so an app or an
  access token can no longer mint an app-less, root-shaped worker session;
  `WorkerDriver` binds on `effectiveApp` instead of `app`.
- PUT-1799: add `isAccountContext` and read it where "no app" was being read
  as "the account" — handler publish, events-worker listing, kv handle
  mint/revoke/list. A scoped API token is no longer an account session.
- PUT-1802: re-authorize a durable row before its backlog drains, settling it
  permanently when the grant is gone. Covers an ancestor-level unshare, which
  the revoke settle deliberately leaves to the delivery re-check.
- PUT-1803: mask the owner's absolute path out of deliveries and subscription
  anchors on a foreign node, the way every FS surface already does.
- PUT-1804: let a revoke reach rows already suspended for a resumable reason,
  re-stamping them so a resume cannot hand over the held backlog.
- PUT-1805: apply the subscribe path's audience gate to `/events/fetch` before
  the query, so a cursor can no longer count and name invisible notifications.
- PUT-1807: refuse `mode: 'manage'` from any actor holding an app — inside its
  own AppData the ACL short-circuit would otherwise supply the reach.
- PUT-1808: take the sending peer from the verified signature header rather
  than the request body.
- PUT-1810: re-base a kv share-handle row's stored match filter on the handle,
  so the owner's absolute key prefix stays hidden.
- PUT-1814: escape LIKE wildcards and anchor the issuer-prefix queries on a
  segment; anchor `manage:` stripping; reject a backslash in a share prefix;
  assert a resolved actor in `subscribeDurable`.
- PUT-1815: bound the char/varchar columns behind `event_subscriptions` and
  `kv_share_handles` at the store layer.
2026-09-11 21:18:49 -07:00
Neal Shah 883072d144 add email composer api (puter.email.send) (#3854)
* add email composer

* fix imports

* add import for fetchUrl

* add import for compose

* add API origin to fetchUrl

* CI related fixes

* types fix

* address leaf function nitpick

* tests and validation checks

* Fix lockfile
2026-09-12 01:20:41 +00:00
Juan Castro 8d90418c9e fix: don't offer a seat a plan link it cannot use
The Usage card's Upgrade link relabels to "Manage →" for anyone on a
plan, including a seat whose plan is its team's. Following it only
reaches a dialog saying so. Hidden for a seat, unchanged for everyone
else.
2026-09-11 18:00:53 -04:00
Juan Castro de74b0c488 fix: name the plan a team bought, not its policy id
`i18n()` echoes a key it has no translation for, and a team tier has
none — so a seat's dashboard read "team-basic" where a personal plan
reads "Basic". The offering already travels with the subscription, so
its display name is right there; `i18n` stays the fallback for the
personal tiers that do have keys.
2026-09-11 17:44:30 -04:00
404oops 967b974fe9 Merge pull request #3852 from HeyPuter/404oops/infron-fix-tiers
fix: quote and pin Infron service tiers
2026-09-11 23:14:52 +02:00
Daniel Salazar 93885dfc54 fix: email driver rename (#3853) 2026-09-11 13:58:53 -07:00
Filip KujundžićandClaude Opus 5 ab077f047b Revert "docs: document Infron service tiers"
This reverts commit 5fbdc7cac5. Docs will land
in a separate PR.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-11 21:32:42 +02:00
Juan Castro 63f857ce3c fix: make the seat cap the owner's plan decides actually apply
`config.default.json` shipped `max_seats_per_team: 50`, and that flat
override wins over the plan, so the free/paid caps were dead code on
every deployment that did not delete the key. A free owner got 50 seats.
The defaults now carry the two per-plan numbers and leave the flat
override unset; a deployment that wants one number for everyone still
sets it and still wins.

`#ownerPays` asked metering about an `{id, uuid}` stub, so a resolver
keyed on any other field missed and the answer came down to whether
something else had cached that user's plan first — the same team, at the
same seat count, was refused or allowed depending on nothing.

Running out of seats now says what raises the limit and offers the plan
picker, rather than reporting the number and stopping there. The record
table pages at ten rows instead of running off the bottom, and the team
card no longer labels the absence of a handle nothing here can set.
2026-09-11 14:51:54 -04:00
Juan Castro 480d6bc3b5 feat: give a team seat the account surface that is actually its own
A provisioned account could rename itself, delete itself, and see a
Billing tab for a subscription it does not hold — all of it the team's,
not the account's. Each is now refused server-side and dropped from the
UI, keyed on one predicate: whoami reports a team only for an org-owned
seat, and the owner joined their own team.

The Teams tab showed a seat nothing but its own audit rows, so a member
could not see who else was on the team they were told they shared it
with. It now lists them; listMembers was already membership-gated and
already withholds from a member what is not theirs.

The dashboard share modal had no way to reach a team, though the desktop
dialog has had one since team sharing shipped and the SDK has always
taken `{ team }`. Same control, same copy, same helper. The access list
needed a team bucket to go with it: a team share names no holder, so the
aggregate dropped it and a team you had just shared with vanished.
2026-09-11 14:09:07 -04:00
Juan Castro 1efe086565 fix: give the owner the seat uuid the plan action is keyed on
The per-account subscription button did nothing. `listMembers` never
returned a member's uuid, the SDK's `toMember` dropped it, and the Plan
column read `seatTiers[undefined]`, so every seat rendered as Free and
the action dispatched with no seat.

The uuid is owner-only: it is what billing keys a seat's plan on, and one
member has no business identifying another.
2026-09-11 13:14:09 -04:00
Juan Castro 06bdc26efd refactor: let the billing extension own the plan picker
The Teams tab was asking which tier with a UIAlert, which looked nothing like
the personal plan modal. It now dispatches the seat and lets the extension
render the grid, so the two match and OSS stays free of prices.

Carries `username` and `currentTier` so the picker can title itself and mark
the plan the account is already on.
2026-09-11 10:51:57 -04:00
Juan Castro c2a975b3f7 refactor: drop the team plan card
It described a team-wide tier, which stopped existing when plans moved to the
account. What it still showed -- what each tier costs -- is in the Change plan
picker, next to the account it applies to, so nothing is lost by removing it.

`teamPlan.js` and its tests go with it, along with twelve i18n keys nothing
reads any more. `state.plan` stays: the Plan column and the picker both need
the catalogue and the seat assignments.
2026-09-11 10:20:09 -04:00
Juan Castro b8b0650990 feat: list the uuids of the seats a team is billed for
Per-tier quantities need to know *which* seats are active, not just how many:
the count has to be split by the tier each one is on. `countActiveSeats` answers
the old question and stays for the cap and the console copy.

Keyed by `uid` rather than the numeric id, because the billing side holds uids
and would otherwise have to look the team up twice. Same suspension filter, and
a test asserts the two agree so they cannot drift apart.

Falsified: dropping the suspension clause fails "leaves out a suspended seat,
matching countActiveSeats".
2026-09-11 10:11:34 -04:00
Juan Castro bafe8af71b feat: icon buttons for the per-account actions
A row now carries up to five actions -- change plan, reissue, suspend or enable,
delete -- and five labelled buttons do not fit the cell. Each becomes a 30px
icon button.

The label is not dropped, only hidden: it stays as `title`, as `aria-label`, and
as visually-hidden text, so a screen reader and a hover both still get it. The
glyphs are `aria-hidden`, since the button already carries the name.

Inline SVG rather than files under `icons/`: these are one-place 24px line
glyphs, and the dashboard already inlines its sidebar chevron the same way. An
`edit` glyph is defined but unused, ready for the account-edit action.

Falsified: removing the visually-hidden label fails "keeps the label reachable
without showing it".
2026-09-11 10:09:39 -04:00
Juan Castro 187e4c8a2f feat: set a plan per account, not one tier for the whole team
Reverses PUT-1788 D1 at the UI. A team keeps one subscription; each account sits
on its own tier within it.

The plan card stops being the chooser and becomes a summary: what each tier
costs per account, and how many accounts are on it. Choosing happens on the
account, with a Change plan action per row, because that is the thing the tier
now belongs to.

`memberPlanLabel` reads the seat's own assignment rather than the team's single
tier, so two accounts can honestly show different plans. The other three states
are unchanged and still matter: the owner is the payer, a suspended seat is not
billed whatever it was on, and a seat nobody bought a tier for is free.

The action only appears where a billing extension is present and a catalogue
came back, so a deployment that sells nothing shows prices and no dead buttons.
2026-09-11 10:04:40 -04:00
Juan Castro f2c9737bd8 feat: show each account's plan in the team's accounts table
Per-seat billing context without per-seat subscriptions. PUT-1788 D1 stands: one
tier per team, one Stripe subscription, quantity = seat count. The tier is still
changed once, in the plan card.

Four states, because "on Team Basic" is not true of every row. The owner is the
payer and keeps their own personal plan, so they show as such rather than
inheriting the team's. A suspended seat reads "not billed" -- it stops costing a
per-account charge, which is the same rule the billing summary and the plan
card's seat count already use. A seat of a team that bought nothing reads free,
which is the reduced org-seat allowance. Everyone else shows the tier.

The rule is a helper in teamsConsole so it is testable, like the rest of that
file.

Falsified: dropping the payer branch fails "says the owner is the payer, not a
seat"; dropping the suspended branch fails "says a suspended seat is not
billed".
2026-09-11 09:37:34 -04:00
Filip KujundžićandClaude Opus 5 5fbdc7cac5 docs: document Infron service tiers
Tiers beyond a model's default are reachable as `<model>:<tier>` ids, so
the chat docs gain a Service tiers section covering what the suffixes
mean, that the tier named is the tier billed, and that a tier can carry
a smaller context window than its siblings.

The listModels return value described a `cost` object with `input` and
`output` keys. No such field is returned — pricing comes back as `costs`
alongside `costs_currency`, keyed per vendor and named by the model's
own `input_cost_key` / `output_cost_key`. Correct the prose and replace
the example with a real entry.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-11 14:52:28 +02:00
Filip KujundžićandClaude Opus 5 3d2bdfceef fix: quote and pin Infron service tiers
Infron sells the same model at several service tiers. `min_prompt_price`
and `min_completion_price` are the floor across all of them, so every
model with a flex tier was advertised at a batch-job price nobody gets
by default: 25 of 286 chat models, among them gpt-6-astra at $5/$25
against the $7.5/$37.5 a default request actually bills.

Price each tier from its own row in `providers[]` and pin that tier on
the request, so the price quoted is the price charged. Tiers beyond the
default are listed under their own `<model>:<tier>` ids, letting callers
opt into flex or priority by model name:

    puter.ai.chat(prompt, { model: 'infron:openai/gpt-6-astra:flex' })

Suffix parsing matches the catalog exactly before reading a trailing
segment as a tier, since catalog ids can carry a colon of their own
(`deepseek/deepseek-v4-flash:free`). Tier variants take the context
window of their own offering, which differs from the model-level figure
for 11 of them.

Billing was never wrong — it bills Infron's reported `cost` — but the
understated prices fed the credit gate's output cap, which let a request
run roughly 50% past the balance it was gated against, and the fallback
path that prices per token when a response carries no cost.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-11 14:47:41 +02:00
Juan Castro 2083ef47c0 fix: the plan card counted no seats
It filtered on `org_owned`, but the GUI annotates members to `orgOwned` --
so the count was always zero and the card read "billed for 0 accounts" beside
an accounts table saying two.

Uses `membersBillingSummary` now, the same count the table shows, which also
excludes suspended seats: they stop costing a per-account charge, which the
naive filter would have billed for.
2026-09-10 18:32:31 -04:00
Daniel Salazar 9940beb4bb fix: card verification missing email (#3850) 2026-09-10 15:32:01 -07:00
Juan Castro fa36f2e3cf fix: run the forced password change on the login path, not only token-in-URL
`initgui` runs the verification gates in two places: the token-in-URL branch and
the session-restore/login branch. The password gate went into the first only, so
it never fired for the case it exists for -- a seat signing in through the login
form with the credential its administrator issued. The account reached the
desktop and then failed at every gated call with no prompt, which is the state
the gate was written to prevent.

Caught by manual testing, not by any test: both chains looked right in
isolation. Added an invariant test over initgui's source asserting each gate
appears on both paths and each loops until cleared, which is the shape of the
mistake rather than the instance of it.

Falsified: removing the login-path gate fails "runs the forced password change
on both paths" with `expected 1 to be 2`.
2026-09-10 18:27:01 -04:00
Juan Castro efe6ef09bd feat: show a team's plan in the Teams tab, and let the owner change it
PUT-1796's UI half. The owner already manages accounts here, so the plan they
are billed for belongs on the same page rather than a tab away.

Pricing stays out of OSS. The card is drawn from whatever catalogue the server
returns, so this code knows no tier, no price and no payment provider -- a
deployment that sells nothing serves no catalogue and the card does not render.
`TabHome` already reads `/marketplace/subscriptions/current` the same way, so
OSS reading a prod-served endpoint is not a new idea here.

Two things are deliberately not offered rather than offered and broken. A tier
the server marks unavailable gets no button, because no Stripe price is
configured for it and buying would 422. And no button appears at all unless a
billing extension has set `window.team_billing_ui` -- the prices still render,
which is useful on its own, but nothing invites a click nobody can handle.
Checkout is Stripe's, so the button only dispatches `team-plan-purchase` with
the team and item id and lets the extension take it from there.

The markup is a helper rather than another branch in TabTeams, matching
teamBadge/credits/usageBudget, so it can be tested without the window stack.

Falsified: offering an unavailable tier fails "offers no button for a tier with
no configured price"; rendering buttons regardless of the extension fails
"offers no button without a billing extension to act on it".

342 GUI/SDK tests, 136 team backend tests, typecheck clean.
2026-09-10 17:42:51 -04:00
Daniel Salazar 367d20a55c test: kv tests (#3844)
* test: kv tests

* chore: bump deps
2026-09-10 14:35:46 -07:00
Juan Castro e886e86cb5 feat: size a team by whether its owner pays, and halve a free seat's allowance
Three related limits.

Seats per team now depend on the owner's plan: 4 free, 40 paid, decided by
`subscriptionSatisfies(id, true)` -- which is `!FREE_SUBSCRIPTION_IDS.has(id)`,
so a plan an extension adds counts as paid without core knowing its name. The
existing `max_seats_per_team` still overrides both, so a deployment that already
set it keeps what it asked for, and `max_seats_per_team_free` / `_paid` tune
each. An unreadable plan takes the smaller cap: over-provisioning a free team is
the worse failure.

A seat of a team that pays for nothing resolves `org_seat_free`, half the
registered free plan. Without it a team is a way to mint free tiers -- provision
four seats and each arrives with a full free allowance nobody paid for. The
figures are derived from `REGISTERED_USER_FREE` rather than restated, so the two
cannot drift, and the id joins `FREE_SUBSCRIPTION_IDS` because nobody paid for
it either and it must not satisfy a plan gate.

It is a *default* resolver, so a paid team tier -- which only prod knows about,
through `registerSubscriptionResolver` -- still outranks it. The lookup is
`getOrgSeat`, already cached with its negatives, because almost nothing is a
seat.

Found while testing: the suite was reading `max_seats_per_team` out of the
developer's own config.json, so the cap under test was whatever that file said.
It would have passed here and failed in CI, which has no such file. The suite
now pins the value and the cap tests set their own.

Falsified three ways, each breaking only its own test: equal caps fails "lets a
paid owner past four"; a resolver returning null, and an unhalved allowance,
both fail "resolves half the free plan".

186 team/whoami tests, 159 metering tests, typecheck clean.
2026-09-10 17:04:43 -04:00
Juan Castro 106978e714 feat: tell a seat which team its account belongs to
A provisioned account had no way to know it was one. That matters: the team can
reset its password and close it, which is exactly what the account-created email
already warns about, and nothing in the product repeated it afterwards.

`whoami` now carries `team: { uid, name }`. Two gates on it. Only user actors --
a seat's employer is no more an app's business than its phone number, which the
same handler already withholds. And only where `teams_enabled` is on, so a
deployment without teams is byte-identical.

It rides whoami rather than a route of its own because the sidebar needs it at
first paint. A `/teams/whoami` would add a request to every page load for every
user, and almost none of them are seats. The lookup costs nothing either way:
`getOrgSeat` is already cached, negative results included, precisely because
almost nothing is a seat. `team_name` comes off a join the query already made.

In the sidebar it sits under the Puter wordmark -- the conventional slot for
workspace context -- as a muted second line, hidden when the sidebar collapses.
Owners see nothing: they already know, and one may own several teams, so there
would be no single name to show.

The markup is a helper rather than another branch inside UIDashboard, matching
how appGroups/credits/usageBudget were pulled out, so it can be tested without
mocking the window stack.

Falsified: dropping the `isUser` gate fails "withholds it from an app actor" and
nothing else.

181 backend tests, 331 GUI/SDK tests, typecheck clean.
2026-09-10 16:52:10 -04:00
Juan Castro fb74789de1 feat: email a seat its username and temporary password, when an address is given
Follows the previous commit. Dropping the email field entirely went one step too
far: without an address the temporary password shown once in the panel is the
only copy, and an admin who closes that panel has to issue a new one. The field
is back, marked optional, and now it buys something concrete.

`team_account_created` carried no credential -- it said the team "will send you
a temporary password separately". It now carries the username and the temporary
password, so an admin who supplies an address hands nothing over by side channel.

`#notifyUser` takes extra template variables, and both credential-issuing paths
pass the one they just minted: provisioning and re-issue. Re-issue passing the
fresh credential rather than the stale one is the case worth checking, and there
is a test that asserts the old password is absent from that mail.

With no address nothing is sent, which was already true -- `#notifyUser` returns
early without one -- and is now covered.

The docs said the notice carries no credential in two places. Both corrected.

Falsified: dropping the credential from the re-issue call fails "emails the fresh
credential on re-issue, not the old one" and nothing else.

178 backend tests, 326 GUI/SDK tests, typecheck clean.
2026-09-10 16:41:03 -04:00
Juan Castro a983969f32 feat: prompt a team seat to choose its own password on first sign-in
The backend already refused every route with `password_change_required` until a
provisioned account replaced the password its administrator chose, and
`/user-protected/change-password` was already exempt so the account could act.
The client half was missing entirely: nothing in the GUI referenced that code,
so a seat signed in and then failed at everything with no prompt and no way out.

Two gaps, both closed here.

The flag never reached the client. Neither the login response nor `/whoami`
carried `requires_password_change`, so the GUI could not have known even if it
wanted to. It ships from both now, alongside the other three verification flags
the whoami extension already describes as "the flags the GUI acts on".

There was no window to show. `UIWindowChangePassword` is a settings dialog --
closable, and it never resolves on success -- so it cannot act as a gate.
`UIWindowPasswordChangeRequired` mirrors the existing `*Required` windows: it
resolves true only once the change lands, and `initgui` loops on it. It runs
last in the boot chain, matching the server order in assertVerifiedAccount.

It refuses a new password equal to the current one. Without that the account
stays on the credential its administrator still holds, which is the entire thing
the gate exists to end.

Falsified twice: dropping the same-password guard fails "refuses to reuse the
password the admin handed over", and resolving on a rejected response fails
"stays open on a rejected change, so the gate cannot be escaped" -- each
breaking only its own test.

175 backend tests, 326 GUI/SDK tests, typecheck clean.
2026-09-10 16:35:05 -04:00
Juan Castro b19b312e30 feat: a team seat needs no email address, and is never asked to confirm one
PUT-1792. Two separate problems, both from treating a provisioned account like
a self-registered one.

`email` was required, so an admin creating ten seats had to invent ten addresses
and then keep track of ten uniqueness constraints -- for accounts that sign in
by username and never use the address. It is now optional at every layer, and
the add-account form does not ask for it at all: username is the only thing a
seat needs.

`requires_email_confirmation` was set to true, with the reasoning that an
admin-supplied address is unverified. True, but `requireVerifiedAccount` turns
away on exactly `requires_email_confirmation && !email_confirmed`, so a
freshly created seat was asked to confirm an address it may not hold and could
not use the product until it did. The team creating the account is the trust
anchor, not the mailbox, so this is now false either way.

An address is still accepted and still stored when given, because the notices
are worth delivering. `#notifyUser` already returned early on a missing
address, so `team_account_created`, `team_account_disabled`,
`team_password_reset` and `team_closed` degrade quietly with no new branching --
the temporary password is in the API response, which is the documented delivery.

`idx_user_owned_email` is partial and skips password-null rows, so omitting the
address sidesteps it rather than creating a collision surface. Two seats with no
address do not conflict, and there is a test for it.

Docs now say an emailless seat is recoverable only through its team's owner.
That falls out of the design rather than being a limitation of this change, but
it should be written down rather than discovered.

Falsified: putting `requires_email_confirmation: true` back fails
"never demands confirmation, with or without an address" with
`expected true to be false`, and nothing else.

164 team tests, 40 SDK tests, typecheck clean.
2026-09-10 15:55:50 -04:00
Daniel Salazar a8a78736bb feat: kv list ordering toggle + addressable path improvements (#3843)
* fix: put-1787

* feat: kv list reverse
2026-09-09 17:24:03 -07:00
Juan Fernando Castro 9b465aba9f Merge pull request #3837 from HeyPuter/juancastro/team-count-active-seats
feat: add TeamStore.countActiveSeats for the billable seat count
2026-09-09 19:33:55 -04:00
Daniel Salazar 0edee23dd9 Update CODEOWNERS (#3842) 2026-09-09 15:55:19 -07:00
Daniel Salazar 99f3037110 Update CODEOWNERS (#3841) 2026-09-09 15:53:36 -07:00
Juan Castro 7ab48c590e feat: add TeamStore.countActiveSeats for the billable seat count
Per-account billing needs "how many accounts is this team getting the
benefit of", and neither existing count answers it. `countSeats` includes
suspended seats, because it bounds the seat cap and a suspended seat still
holds its username. `countPayers` counts the owner. Billing off `countSeats`
overcharges for suspended accounts, contradicting what the admin console
tells the owner: "0 suspended accounts cost nothing per account."

So this is a third, separate count rather than a change to either — the cap
must keep counting suspended seats.

An unactivated seat is deliberately still counted: it holds a temporary
password, not a suspension, and it is paid for. That is why the filter is
narrower than `listDirectory`'s, which also excludes
`requires_password_change`.

Falsified: dropping the suspended clause fails exactly one test
("drops a suspended seat from the active count but not from the cap",
expected 3 to be 2) and leaves the other 34 green.
2026-09-09 18:13:04 -04:00
404oopsandClaude Fable 5.1 6146ab9dd3 feat(ai): refresh txt2vid catalogs, retire Sora, default to Veo 3.1 Lite (#3828)
OpenAI shuts the Sora Videos API down on 2026-09-24 and sora-2 was the
default txt2vid model, so the default moves to Veo 3.1 Lite on Gemini
and the OpenAI video provider goes. While there, the video catalogs are
brought in line with what each vendor serves today, the request options
are unified across providers, and the txt2vid docs are rewritten.

- driver: default provider gemini-video-generation with
  veo-3.1-lite-generate-preview; a request under the generic `ai-video`
  driver name lands on the default instead of the first-registered
  provider; `WIDTHxHEIGHT` sizes map onto tier catalogs by the shorter
  side and fill width/height
- openai video provider, the `openai-video-generation` alias, its
  config template and migration entries, and Together's openai/sora-2*
  rows removed
- gemini: Veo 3.1 Fast rates 10/12/30 cents per second for
  720p/1080p/4K, Veo 3.1 Lite accepts reference images, URL image
  inputs are fetched server-side through the SSRF-guarded fetch
- together: drop nine models retired upstream, add eighteen from the
  live listing; per-second models are estimated from the catalog rate,
  clamped to remaining credit and billed at the cost Together reports
  on the job; tier-sized models take resolution/ratio;
  input_reference/last_frame map onto keyframes; generate_audio is
  forwarded
- byteplus: Seedance 2.5 (dreamina-seedance-2-5-260628) with per-model
  reference-image caps
- util/imageInput: string-level image helpers shared by the image and
  video drivers; ai-image/inputImage re-exports them unchanged
- puter.js types: provider and generate_audio options; docs: txt2vid
  page rewritten with per-provider model tables, unified options and
  four new playground examples

Known follow-up: Veo returns a key-protected Google file URL, so the
default clip cannot be played directly by a browser until the provider
fetches it server-side.

Co-authored-by: Claude Fable 5.1 <[email protected]>
2026-09-09 14:56:17 -07:00
404oopsandClaude Fable 5.1 c8f4906af4 fix(ai): keep per-provider failures when every chat route fails (#3836)
When the chat fallback chain is exhausted, the driver already records
each attempt (model, provider, status, code, message, timeout) in the
error's `fields.attempts`, but the alarm keyed on the classified message
alone and the alarm client printed the error at inspect depth 2, so the
log and Slack line read `internal_error:All providers failed` with
nothing about which providers failed or why. Deduped repeats printed
only a count.

- The HTTP alarm gate now attaches an HttpError's `fields` to the alarm
  under a single `details` key. One key can't shadow the gate's own
  request fields, and a repeat from another thrower on a shared id
  replaces it instead of merging into it.
- The chat driver logs one warn line per exhausted chain with the
  completion id, the resolved route, the classified code and the
  attempts as JSON, so every occurrence is greppable by trace even when
  the alarm dedupes it. Chains marked `noAlarm` don't log.
- Docs: `fields` reaches both the client and the alarm, so it has to be
  safe to show the caller.

Co-authored-by: Claude Fable 5.1 <[email protected]>
2026-09-09 14:56:11 -07:00
Reynaldi Chernando 435629afc5 Add gpt 2.5 image (#3839) 2026-09-09 14:29:41 -07:00
Juan Fernando Castro e132f765d6 Merge pull request #3745 from HeyPuter/juancastro/put-1736-team-directory
🏗️ PUT-1736: a team directory apps can read, once the team opens it
2026-09-09 16:09:03 -04:00
Juan Castro 4e45fdc172 feat: a team directory apps can read, once the team opens it
Members can already enumerate each other: `/teams/:uid/members` needs a user
actor and nothing more. The only thing this adds is admitting an app actor to
the same names, so an app can offer colleagues without the member driving it.

That is the whole risk, so it is off until the team owner turns it on.
`group.directory_enabled` defaults to 0, and a team that has not opted in
answers 404 rather than 403 -- whether a team has this on is not something an
app should be able to probe for either.

Three things bound what an app sees. The membership tested is always the
person's, never the app's, so an app installed by a member of one team can
never read another's. The page carries username and uuid and nothing else --
no email, activation state, usage or role. And suspended accounts and ones
that never took up their credential are left out, since offering someone who
cannot sign in is noise and their existence is not this list's to disclose.

Activation is the forced-change flag clearing, not the password existing: a
provisioned seat holds its temporary password from birth, so testing
`password IS NOT NULL` would have leaked exactly the accounts meant to be
excluded. A test covers that distinction.

Turning the directory on or off writes an audit row, because it changes who
can read the member list and that is not something a team should be able to
alter silently. Setting it to the value it already has records nothing.

The toggle lives in TabTeams, and turning it on asks for confirmation while
turning it off does not -- one grants access, the other only takes it away.

Closes PUT-1736.
2026-09-09 14:51:05 -04:00
Juan Fernando Castro f6b519874e Merge pull request #3742 from HeyPuter/juancastro/put-1740-1762-workspace-gui
🏗️ PUT-1740 + PUT-1762: the workspace surfaces in the GUI
2026-09-09 14:50:56 -04:00
Reynaldi ChernandoandCopilot Autofix powered by AI 59be4ad237 more recipes (#3819)
* more recipes

* addition

* final

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

* styling fix

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-09-10 01:07:26 +07:00
Juan Castro 9121e66c3f feat: the team surfaces in the GUI
Two places a team becomes visible to a person rather than an API: the
Dashboard tab that administers it, and the share dialog that shares with it.

Squashed because they are one change to a reviewer. Both are the first GUI
consumers of `puter.teams`, both add strings to the same `en.js`, and both had
to answer the same question -- what a team looks like to someone who has
never seen one. Splitting them would mean reviewing that answer twice and
resolving the same translation conflict twice.

TabTeams (PUT-1740)

  Registered in `builtinTabs` after `TabFiles`, as a plain object with
  `html()` and `init($el_window)` like every other tab. The member table
  carries the operations the API allows and nothing it does not: provision,
  resend an activation, disable, restore, delete.

  Deleting asks for confirmation naming the account, because the API deletes
  on a single call -- PUT-1732 places the reversible step at disable, not in
  front of the request, so the client is where a confirmation belongs.

  The wording says plainly that disabling stops the per-account charge and
  keeps the storage one, and that deleting is the only thing that ends it.
  This is the one place a person decides between the two, so leaving them to
  infer the difference costs them money.

  Rendering and the billing arithmetic are pure functions in
  `teamsConsole.js`, with tests beside them; the tab file is the DOM.

Share dialog (PUT-1762)

  `UIWindowShare` gains the teams the caller owns as recipients. A
  team is one entry in the list, not its members expanded -- sharing
  reaches every member, and the per-person wording would understate what the
  grant does.

  `shareWorkspaces.js` holds the resolution and the deduplication, so the
  dialog does not gain a second source of truth about who a recipient is.

Closes PUT-1740 and PUT-1762.
2026-09-09 11:51:44 -04:00
Juan Castro afb5b0d82a feat: add the puter.teams SDK module
Team administration reaches the backend through the `/teams` routes
rather than a driver interface, because the gates it needs are route-level:
a user actor, a verified account, and a dual-window rate limit.

The module follows `apps/` and `perms/` in layout -- one file per method,
a thin `index.js`, a JSDoc-only `types.js`, and the `METHODS` rebinding so a
destructured method keeps its `this`. It does not follow `perms/lib/req.js`:
those endpoints resolve `{ error: true }` for backward compatibility, and
nothing here has callers to keep compatible, so this throws `PuterJSError`
with the backend's own code.

Every method takes a team `uid`. A handle is a mutable label that
deleting the team releases, so a stored handle can later resolve to a
different team.

The list methods offer the three forms `puter.apps.list()` does -- an array
by default, the page envelope under `cursor`/`includeTotal`, an async
iterator under `stream`. They refuse `offset`: these routes are keyset-only
and would otherwise return page one however far you asked to skip.

The surface covers the routes that exist today. Usage totals and member-email
correction have no backend route yet and are deliberately absent rather than
shipped as methods that 404. `deleteMember()` is here because the route it
needs lands in the commit below this one.
2026-09-09 11:51:44 -04:00
Juan Castro a60a4a98b4 feat: delete a team seat for good, once it is disabled
A disabled account persists indefinitely. Removing it is an explicit request,
never a timer, and it is refused on a live account with
`account_must_be_disabled_first` — which puts a reversible step in front of the
only irreversible operation in the feature.

The audit row is written before `cascadeDelete` runs. The FKs are ON DELETE SET
NULL and the `_keep` columns carry the identifiers, so the record of what was
done survives the account it names.

No second billing emit here: `cascadeDelete` already captures the seat and
fires `team.account.deleted` through UserAccountService, and emitting again
would close the storage charge twice. Disabling closed the per-account charge;
this closes the storage one, and it is the only thing that does.

There is no restore window, and none was wanted: the reversible step already
exists earlier at disable, a disabled account costs only the bytes it holds so
nothing pressures a hasty delete, and a restore promise means retaining data
the team explicitly asked to be rid of.

Published in rate-limits-and-quotas.md alongside the team-deletion note,
since the two are easy to confuse and only one of them frees a seat.

Closes PUT-1732.
2026-09-09 11:51:44 -04:00
Juan Castro 81d15f412b feat: tell a team member what was done to their account
Two halves of the same question -- what did the team do to me, and how do
I find out. One is pull, the other push.

The activity view (PUT-1746) was already user-scoped and already 404'd a
non-member; what was missing is the load-bearing half. A member is told a reset
happened, but a reset only matters alongside who signed in afterwards, so
`SessionStore.listSignIns` merges their own sign-ins into the same stream,
newest first, with a per-stream cursor. Without that row the audit says a
credential was issued and never says whether it was used.

The notices (PUT-1733) cover the two things a member cannot discover for
themselves: their account being disabled, and their team being closed.
Deliberately one each -- closing a team disables every account in it, so
sending both would tell one person twice about one event. Both say plainly that
nothing was deleted; the accounts persist, suspended, holding their files.

Squashed because they are one change to a reviewer: same audience, same
purpose, seven files, overlapping only in TeamService. Neither touches shared
platform code.
2026-09-09 11:51:44 -04:00
Juan Castro f5b2365e83 feat: enforce the forced password change on team seats
`user.requires_password_change` shipped with the team columns but nothing
enforced it and nothing ever cleared it, so a provisioned seat kept its
administrator-issued password indefinitely and `reissueCredential`'s
"already activated" 409 was unreachable.

Adds the fourth clause to `assertVerifiedAccount`, the only place a
verification gate may live -- WebDAV builds its own actor and calls that
function directly, so a second implementation would bypass it the way the
phone and card gates once were bypassed.

A gate that refuses everything also refuses the endpoint that clears it,
so `/user-protected/change-password` opts out with `allowUnconfirmed`.
That widens the route: an account pending email, phone or card
verification can now change its password, which it could not before. The
caller is authenticated and proves the current password, so this is
benign, but it is a behaviour change to a shared route.

Also here, because the gate is worthless without them:

- change-password and the recovery-token path clear the flag, and record
  an `activate` entry when the account is a seat.
- Reset takes a live account back with a fresh credential, capped at 20
  per day and audited as `reset_member_password` with no credential in
  the row. Re-issue is audited the same way; it stays closed once a seat
  has chosen its own password.
- An issued credential expires after 24h (new `temp_password_expires_at`
  column, three dialects) and login refuses it after that, so an unused
  reset dies instead of becoming a standing credential.
- 2FA is untouched by a reset, so a reset alone is not takeover.
2026-09-09 11:51:44 -04:00
Juan Fernando Castro f3943f6a55 Merge pull request #3729 from HeyPuter/juancastro/put-1726-put-1727-put-1729-team-share-recipient
🏗️ PUT-1726 + PUT-1727 + PUT-1729: share with a workspace
2026-09-09 10:41:21 -04:00
Juan Castro 7a02fa7741 feat: tell every team member when something is shared with them
`notifyShared` keyed every map off `ResolvedShare.holderId`. A team share
has no individual holder -- the grant is one row against the group and
`holder_user_id` is NULL -- so it was skipped everywhere and the call returned
having told nobody. Nothing errored: the share was created, resolved and listed
correctly. The failure mode was silence.

`#recipientsOf` now expands a team share to its live members at
announcement time, so the grant stays one row and only the telling fans out.
`#announce` and `#emailHolder` are both inside the per-recipient loop, so
members get the in-app notification and the email digest.

Bounded by `NOTIFY_FANOUT_CAP`, which logs when it bites rather than truncating
silently -- a shortened fan-out otherwise reads as "everyone knows". The
existing per-recipient budgets absorb the volume from there.

Wording is unchanged: "shared N items with you", not the team name.

A member who joins later resolves the grant through the scan but is not
retroactively told; announcements describe a moment, not a state.
2026-09-09 10:22:56 -04:00
Juan Castro da68074401 feat: share with a team
Covers PUT-1726, PUT-1727 and PUT-1729. Together because a recipient without
the listing work produces a share that is created correctly, resolves
correctly, and never appears in "Shared with me" — a state nobody would ship.

The recipient. `ShareRecipient` gains `team` (uid) and `teamHandle`, resolved
before the email and username branches and never falling through to them.
Passing both is an error rather than a precedence rule, so a call site always
shows which was chosen: handles are released on soft delete and can be
reclaimed by an unrelated team, and a scripted share to a handle would
silently retarget. There is no bare-string spelling, since that would change
how existing strings are interpreted.

ACLService.setUserGroup mirrors setUserUser: same read-modify-write, same
one-mode-per-node rule, under a node lock keyed on the group.

One grant against the team, not one per member, so membership changes
apply without touching the grant and a share spends one unit of the daily
quota however many members there are. A member who joins afterwards gets
access, which is asserted.

The index row carries `holder_group_id` and leaves `holder_user_id` NULL, so
`0077`'s group index constrains it rather than the user-holder one.

Listing. `listByHolder` and `countByHolder` union the caller's teams into
the same keyset page — `ORDER BY id` still holds — and `#grantEvidence` gains
group grants as a third source. Without that third source the share is
filtered out of every listing as dead: nothing errors, the share simply is not
there, which is the one place a user would look for it.

Unsharing revokes the grant as well as deleting the index row. Deleting the
row alone would hide the share while leaving every member holding real access.

Closes PUT-1726, PUT-1727 and PUT-1729.
2026-09-09 10:22:56 -04:00
Juan Castro 9f615cc632 feat: add the two-team fixture and group permission grants
Two tickets, together because the fixture has no behaviour of its own — the
grant tests are its first real use, and "a grant to team A must not
resolve for B's members" is exactly a two-team assertion.

PUT-1719. Every query resolving team-scoped data has to take the
team as a parameter rather than infer it. One that forgets returns the
right rows against a database holding a single team, so a one-team
fixture does not give weaker coverage — it gives false confidence.

The fixture provides two teams, each with its own master and two
activated seats, plus a user in neither. Each team having its own master
is also what the shipped `max_teams_per_user: 1` requires, so it runs
against the real cap rather than lifting it the way the existing team suites
have to. Seats are activated before use: provisioning leaves
`requires_email_confirmation` set and `requireVerified` rejects them outright,
so an unactivated seat cannot call anything and every authorization assertion
built on one would be vacuous.

PUT-1725. The write half of group grants; the read half already worked, since
`#scanUserGroup` joins `jct_user_group` itself and resolves for whoever is a
member at scan time.

  PermissionStore   resolveGroupId, listGroupMemberUuids,
                    upsertUserGroupPerm, deleteUserGroupPerm,
                    auditUserGroupPerm
  PermissionService grantUserGroupPermission, revokeUserGroupPermission

Both rewrite the permission first, so `fs:/path:mode` collapses to
`fs:<uuid>:mode` and a revoke names the same string the grant wrote; both gate
on `canManagePermission`; both audit into the existing
`audit_user_to_group_permissions`.

The delete is scoped to the issuer, so one issuer's revoke cannot drop
another's identical grant — the PK is (user_id, group_id, permission) and
user_id is the issuer.

Cache invalidation goes through `bumpCacheGenerations` with every member uuid
at once. That already announces to peer regions in a single event, so the
fan-out costs one broadcast rather than one per member.

There is no flat-KV equivalent for group grants, so unlike the user-to-user
path there is no second write to keep consistent and no second invalidation
surface.

Closes PUT-1719 and PUT-1725.
2026-09-09 10:22:56 -04:00
Daniel Salazar 8a70fa2e5c fix: CODEOWNERS + perm dialogs outside puter dashboard/desktop (#3833) 2026-09-08 22:56:03 -07:00
Felix-Ayush 9bb5bffd01 fix(puter-js): account for base64 padding in estimateDataUrlSize (#3805)
Math.ceil(len * 3 / 4) over-counts by 1-2 bytes on padded payloads, so thumbnails at the size limit were wrongly rejected. Subtract padding like ai dataUriByteLength.
2026-09-08 22:33:33 -07:00
Felix-Ayush d7877359d4 fix(puter-js): return key_undefined for missing kv keys (#3803)
get/del/incr/decr/add/expire/expireAt only checked size, so undefined keys threw TypeError. Add assertKeyPresent first, matching set/update/remove.
2026-09-08 22:32:53 -07:00
Felix-Ayush cdc524f504 fix(puter-js): preserve zero amount in kv incr/decr (#3802)
parseCounterArgs used a falsy check, so incr(key, 0) sent amount 1. Only default when amount is undefined/null.
2026-09-08 22:30:02 -07:00
dependabot[bot] 8b872545dc chore(deps): bump docker/setup-buildx-action from 3 to 4 (#3823)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-08 22:27:06 -07:00
dependabot[bot] 52f9fa57a6 chore(deps): bump docker/metadata-action from 5 to 6 (#3822)
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-08 22:26:49 -07:00
dependabot[bot] eb28012897 chore(deps): bump peter-evans/dockerhub-description from 4 to 5 (#3826)
Bumps [peter-evans/dockerhub-description](https://github.com/peter-evans/dockerhub-description) from 4 to 5.
- [Release notes](https://github.com/peter-evans/dockerhub-description/releases)
- [Commits](https://github.com/peter-evans/dockerhub-description/compare/v4...v5)

---
updated-dependencies:
- dependency-name: peter-evans/dockerhub-description
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-08 22:26:27 -07:00
Daniel Salazar e5f322f68c fix: misc event hardening + perm fixes (#3831) 2026-09-08 19:16:21 -07:00
Neal Shah ab3bba5525 add file query param (#3829) 2026-09-08 21:39:19 -04:00
Juan Fernando Castro 9f3c658975 Merge pull request #3830 from HeyPuter/juancastro/phase3-land-on-main
Teams phase 3: land the remaining three PRs on main (#3733, #3724, #3725)
2026-09-08 18:27:11 -04:00
Juan Castro bd19fd18ec feat: cap teams per user and seats per team
A seat is a real Puter account: it takes a name from the global username pool
and gets a home directory. Nothing charges for one — that is prod's job — so
until it does, the only bound on creation is the request rate limit, which
bounds the rate and not the total.

  max_teams_per_user   default 1
  max_seats_per_team   default 50

Ordering is the substance of both checks. The team cap is tested before
the handle, so a capped user is told they are capped rather than that the name
they picked was unusable. The seat cap is tested before any account state
exists, so a refused provision does not burn a global username.

Soft-deleted teams do not count toward the owner's cap, so deleting frees
the slot — which does mean create, provision, delete, repeat still consumes
usernames over time, bounded by the daily rate limit. The caps raise the cost
and make the cycle audited; they do not close it.

Lowering the seat limit blocks new provisioning and disables nobody.

Both limits are published in rate-limits-and-quotas.md, and both keys are
documented in config.template.jsonc and config.default.json.

Closes PUT-1758.
2026-09-08 16:59:29 -04:00
Juan Castro 41a05b68fd feat: announce credit-state transitions so billing can act on them
A seat that exhausts its allowance is refused and cannot fix it itself — only
the team owner can add capacity. Something has to tell the owner, and that
something lives in prod, so OSS's job is to say when it happened.

`MeteringService` emits `metering.credit-state` from `rememberRemainingCredits`,
the single point where the verdict is computed, at 90% of the allowance and
again on exhaustion.

Emitted on a transition, never per request. A blocked account keeps trying and
every retry recomputes the verdict, so without that a retry loop would announce
hundreds of times. The state is tracked per uuid in process, under the same FIFO
bound as the credit cache, and dropped in `#dropCachedCredits` — so added
capacity re-arms the alert for the rest of the month.

The dedup that turns this into exactly one notice per member per month belongs
with whoever sends the mail, and needs a cross-region marker rather than a
per-cluster one.

Part of PUT-1750; the notification half is prod's.
2026-09-08 16:59:29 -04:00
Juan Castro 0c6045ed90 feat: emit team billing events for the payment integration
The charge lives outside this repo, the way the marketplace extension cancels
Stripe subscriptions off `user.delete`. This is the trigger, and it is the
whole of what OSS owes billing.

  team.account.created    a seat exists and can be used
  team.account.disabled   it stopped, and still holds its bytes
  team.account.enabled    it resumed
  team.account.deleted    it is gone
  team.deleted            the team is gone; its accounts are not

Each carries the team uid, the affected account, and the owner's
`stripe_customer_id`. That column ships in the mysql and postgres schemas but
not sqlite, so the read is guarded and degrades to null, as `cascadeDelete`
already does.

Deleting a team emits one `team.account.disabled` per seat plus the
team event, rather than one bulk event: the accounts persist, suspended,
holding their files and their usernames. Deleting a team is not a way to
stop paying for the accounts in it.

`team.account.deleted` is captured before the row is deleted.
`jct_user_group.user_id` is ON DELETE CASCADE, so by the time a listener on
`user.delete` runs, nothing can say which team paid for the account.

`getOrgSeat` deliberately admits soft-deleted teams: their accounts still
exist, so the charge is still running.

Closes PUT-1712.
2026-09-08 16:59:28 -04:00
Juan Fernando Castro 00afea1285 feat: a seat is created, never adopted (#3720)
`addMember` refuses to turn an account that already has a password into a
team seat. No service path did this — `provisionAccount` always creates —
but the store permitted it, and the design rules out existing accounts joining
a team.

Provisioning passes the guard because it admits the account before setting its
temporary password.

There is no bypass parameter. Both HTTP suites now provision a real seat and
authenticate as it, using the same token-minting the harness uses for
`POST /login`. That surfaced something worth knowing: an unactivated seat
cannot call the API at all. Provisioning leaves `requires_email_confirmation`
set and `requireVerified` rejects it, so the suites activate the seat first —
which is the state a member is actually in when making requests.

`listMembers` and `getMembership` also return `u.uuid`, which the billing
events need in order to name the account without a second lookup.
2026-09-08 16:45:16 -04:00
dependabot[bot] 84368f8d02 chore(deps): bump otpauth from 9.5.1 to 9.5.2 (#3820)
Bumps [otpauth](https://github.com/hectorm/otpauth) from 9.5.1 to 9.5.2.
- [Release notes](https://github.com/hectorm/otpauth/releases)
- [Commits](https://github.com/hectorm/otpauth/compare/v9.5.1...v9.5.2)

---
updated-dependencies:
- dependency-name: otpauth
  dependency-version: 9.5.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-08 13:26:41 -04:00
Daniel Salazar 86050f131b fix: hardening events for shared kv (#3827) 2026-09-08 09:04:50 -07:00
dependabot[bot] e50f2911b6 chore(deps): bump actions/upload-artifact from 4 to 7 (#3824)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-08 08:58:37 -07:00
dependabot[bot] 414c121ae4 chore(deps): bump actions/setup-node from 4 to 7 (#3825)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 7.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-08 08:58:24 -07:00
Toshit ChawdaandClaude Opus 5 1d6d0da950 feat(puter.js): transferables in AppConnection.postMessage (#3776)
`postMessage(message, transfer)` (or `{ transfer }`) moves ArrayBuffers,
MessagePorts, streams and the rest to the target app instead of copying
them. The second argument is optional, so existing callers are unchanged.

The transfer list rides in the message body as well as the real transfer
list: structured clone's memory map keeps those objects identical to the
ones inside `contents`, which is how the desktop picks them out mid-relay
and keeps transferring them onward rather than leaving copies behind. Both
`messageToApp` paths carry it — the direct iframe relay and the connection
path that `launchApp()` between apps actually uses.

The desktop forwards the list as-is and lets postMessage judge it. A list
that arrived through the SDK was already validated by the browser on the
first hop, and validating again here would mean an allowlist of
transferable types that silently downgrades an unrecognised one to a copy.
A bad list only reaches us from an app that hand-wrote the envelope; that
throws without detaching anything, and is caught so it cannot escape
`ipc_listener` as an unhandled rejection.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-09-08 08:57:52 -07:00
dependabot[bot] 72889d72c8 chore(deps): bump undici from 7.29.0 to 7.29.1 (#3821)
Bumps [undici](https://github.com/nodejs/undici) from 7.29.0 to 7.29.1.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v7.29.0...v7.29.1)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 7.29.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-08 08:52:50 -07:00
Nariman Jelveh 8a6daee9ab feat: let extensions customize recommended apps 2026-09-07 16:44:41 -07:00
404oops e980b131a0 Merge pull request #3815 from HeyPuter/filipkujundzic/ai-vision-canonical-media-parts 2026-09-08 00:54:41 +02:00
404oopsandClaude Fable 5.1 1cb5472c4c fix(ai): canonicalize image parts once and translate them per provider
The SDK shorthand sends `{ image_url: { url } }` with no type. Claude
forwarded it untouched (Anthropic: "content.1.type: Field required"),
the OpenAI/Azure Responses providers sent a Chat Completions part the
Responses API rejects, and Mistral emitted snake_case `image_url` where
its SDK validates `imageUrl`. All three only appeared to work because
the fallback loop re-served them through OpenRouter.

- utils/mediaParts: canonicalise every inbound media part (untyped
  shorthand, bare string URLs, Responses input_image, Anthropic image
  blocks, Gemini inline_data) to the Chat Completions form in the
  driver, so providers translate from one shape
- Claude → Anthropic image blocks (url / base64 sources), copy-on-write
- Responses processor → input_image with a string URL and detail, and
  copies messages instead of mutating the caller's objects
- Mistral → camelCase imageUrl; the test that asserted the old shape
  is corrected
- driver: 400 up front when the catalog says the model has no image or
  video input; resolve puter_path parts per attempt for providers
  without their own upload path (Claude keeps the Files API)
- move the Moonshot http→data-URL inliner to utils/inlineImages and
  apply it to Grok-via-Azure and Gemini, whose upstreams cannot fetch
  http image URLs

Fixes #3409

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-07 15:23:40 +02:00
Daniel Salazar 927317bc4e fix: events hardening (#3814) 2026-09-06 22:44:07 -07:00
Daniel Salazar a441e7f748 fix: harden events (#3813)
* fix(events): rename carries from, one retry on deploy-timeout, forward-path counters

- FSService.rename passes the pre-rename path so a folder subscription
  sees op move with from, like a real move does
- deploy-timeout from the dispatcher gets one retry with the deployed
  header and no second upload (ALREADY_DEPLOYED_MISS_REASONS)
- OTel counters events.forward.sent/received and events.single.attempt
- cross-app KV subscribe error hints at the three-segment parse
- docs: lease is 60 s, kv prefix example is fully qualified, move covers
  rename

* feat(events): forward session subscriptions across regions, fast bumps, worker session cleanup

- session (onLocal) subscriptions now receive writes committed in other
  regions: a transition-maintained remote-watch index (ev:sc / ev:rw),
  watch/event forward items, replay through dispatchForwarded against
  session rows only; events.forwardSession=false is the kill switch
- subscription and presence generation bumps also ride the addressed
  forward channel (kind bump) so a peer sees a new durable row within
  a queue window; the webhook fan stays as backstop
- workers.destroy revokes every holder's events:handlers session; app
  deletion reaps the app's rows, backlog and handlers and revokes the
  sessions; an hourly sweep revokes sessions whose app is gone
- docs: cross-region latency, per-region caps footnote, session
  lifecycle
2026-09-06 16:44:07 -07:00
dependabot[bot] 2784feb47d chore(deps): bump fast-uri from 3.1.5 to 3.1.7 (#3810)
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.5 to 3.1.7.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.5...v3.1.7)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-06 16:43:02 -07:00
Daniel Salazar 2f70cd1a14 feat(email): sendTransactional alias and streaming file inputs (#3812)
- puter.email.sendTransactional is the new name; send stays as a
  deprecated alias with the same arguments and result
- fileInput: openFileInputStream / resolveFileInputEntry expose the
  ACL-checked FS read as a stream; loadFileInput wraps them
- EmailAttachment accepts a `path` the transport streams on its own
2026-09-06 16:41:02 -07:00
Felix-Ayush b1d3a7c191 fix(puter-js): require prompt in ai.txt2img (#3804)
txt2vid rejects missing prompts client-side with prompt_required, but txt2img sent the request to the backend. Add the same guard before the driver call.
2026-09-06 16:39:35 -07:00
Nariman Jelveh 092a9245ff Fix PDF thumbnail worker loading from CDN bundles 2026-09-06 14:31:42 -07:00
Nariman Jelveh e6cedde732 Add resilient PDF thumbnails to GUI uploads (#3809)
* Add resilient PDF thumbnails to GUI uploads

* Keep GUI image thumbnails working with SDKs lacking the callback context

The desktop loads puter.js from js.puter.com by default, and the SDK
there predates the thumbnail callback context, so passing the PDF
generator made every image upload lose its thumbnail until the SDK
deploys. Fall back to the SDK's bundled image generator whenever the
running SDK passes no usable context, and cover both paths in the unit
and browser tests.

* Ignore preparation failures that land after an upload is cancelled

Cancelling during preparation already rejects the upload and fires the
abort callback. If the step that was in flight then fails, such as a
dropped directory that cannot be read, the error callback also fired and
the GUI showed an upload error for an upload the user had just
cancelled. Skip error reporting once preparation has been aborted.

* Give each PDF thumbnail worker four seconds

The per-PDF budget covers downloading PDF.js as well as rendering, and
the first PDF of a session on a slower connection ran out of time
before its assets had even loaded. Four seconds fits that first load on
ordinary connections while staying under the five-second batch cap, so
one stuck PDF still leaves the rest of the batch a chance.
2026-09-06 13:51:02 -07:00
404oops 9b4d8f11d4 Merge pull request #3801 from HeyPuter/filipkujundzic/remove-retired-imagen-moonshot-models
fix(ai): remove retired Imagen 4 and legacy Moonshot models
2026-09-06 13:26:14 +02:00
dependabot[bot] bf4e810f9c chore(deps-dev): bump browserstack-local (#3808)
Bumps [browserstack-local](https://github.com/browserstack/browserstack-local-nodejs) from 1.5.5 to 1.5.9.
- [Release notes](https://github.com/browserstack/browserstack-local-nodejs/releases)
- [Commits](https://github.com/browserstack/browserstack-local-nodejs/compare/v1.5.5...v1.5.9)

---
updated-dependencies:
- dependency-name: browserstack-local
  dependency-version: 1.5.9
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 15:43:42 -07:00
dependabot[bot] 89a4947f68 chore(deps): bump webpack from 5.101.3 to 5.110.3 in /src/puter-js (#3800)
Bumps [webpack](https://github.com/webpack/webpack) from 5.101.3 to 5.110.3.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack/compare/v5.101.3...v5.110.3)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.110.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 15:40:47 -07:00
dependabot[bot] 9ebe1092f1 chore(deps): bump dependabot/fetch-metadata from 2 to 3 (#3763)
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2 to 3.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v2...v3)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 15:40:22 -07:00
dependabot[bot] 1caf3e121f chore(deps): bump actions/checkout from 3 to 7 (#3764)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 15:40:13 -07:00
dependabot[bot] 3620f7bd85 chore(deps): bump docker/build-push-action from 5 to 7 (#3765)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 15:39:57 -07:00
dependabot[bot] e48802252e chore(deps): bump actions/download-artifact from 4 to 8 (#3767)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 15:39:21 -07:00
Daniel Salazar da65b7f569 feat: the invoking backend deploys an events worker the dispatcher cannot find (#3807)
The dispatcher's rehydrate callback reaches whichever backend answers the
API's public hostname. A backend with the runtime flag on that is not behind
that hostname, or the only one in the fleet with it on, could never get its
scripts deployed that way — the callback answered "disabled". The invoking
backend already knows the app and script, so on a dispatcher miss it deploys
the set itself and retries once, telling the dispatcher to skip its callback
and negative cache. The callback stays the path for evicted scripts.
2026-09-05 14:40:44 -07:00
404oopsandClaude Fable 5.1 ded3d3695b fix(ai): remove retired Imagen 4 and legacy Moonshot models
Google shut down imagen-4.0-fast/standard/ultra in the Gemini API on
2026-08-17; live calls now return 404 "not found ... or is not supported
for predict". Drop the three entries, the generateImages code path that
only they used, and their tests; the integration test moves to
gemini-2.5-flash-image.

Moonshot's live /models listing and the Kimi pricing docs now carry only
kimi-k3, kimi-k2.7-code(-highspeed) and kimi-k2.6. Drop kimi-k2.5 and the
whole moonshot-v1-* family and repoint the unit and integration tests at
current models. kimi-k2.5 still resolves through OpenRouter.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-05 22:22:16 +02:00
dependabot[bot] e451d507ad chore(deps): bump lodash from 4.17.21 to 4.18.1 in /src/puter-js (#3797)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.18.1.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.18.1)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.18.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 12:21:36 -07:00
dependabot[bot] 7099cadc6f chore(deps): bump shell-quote from 1.8.1 to 1.10.0 in /src/puter-js (#3774)
Bumps [shell-quote](https://github.com/ljharb/shell-quote) from 1.8.1 to 1.10.0.
- [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/shell-quote/compare/v1.8.1...v1.10.0)

---
updated-dependencies:
- dependency-name: shell-quote
  dependency-version: 1.10.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 12:19:35 -07:00
dependabot[bot] 73cb60f5ae chore(deps): bump docker/login-action from 3 to 4 (#3762)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 23:58:57 -07:00
Daniel Salazar e478087260 fix: keep matrix legs of test/coverage jobs always instantiated (#3799)
Skipping the whole matrix job via a job-level `if` collapses it to a
single check with the unevaluated name template ("test (\${{
matrix.artifact }})") instead of expanding to "test (base)"/"test (pr)",
since there's no matrix context to fill in when the job never runs. That
check never matches a required-status-check pinned to "test (pr)", so
PRs that skip backend/puterjs testing block forever waiting on a check
that will never be reported. Gate the steps instead so the matrix always
expands with stable names, doing no real work when irrelevant.
2026-09-04 23:58:12 -07:00
dependabot[bot] b6fb4f3cae chore(deps-dev): bump @eslint/js from 9.39.4 to 9.39.5 (#3791)
Bumps [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) from 9.39.4 to 9.39.5.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/commits/v9.39.5/packages/js)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-version: 9.39.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 23:56:03 -07:00
dependabot[bot] 61566431cc chore(deps): bump fs-extra from 11.3.5 to 11.3.6 (#3785)
Bumps [fs-extra](https://github.com/jprichardson/node-fs-extra) from 11.3.5 to 11.3.6.
- [Changelog](https://github.com/jprichardson/node-fs-extra/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jprichardson/node-fs-extra/compare/11.3.5...11.3.6)

---
updated-dependencies:
- dependency-name: fs-extra
  dependency-version: 11.3.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 23:55:31 -07:00
dependabot[bot] d3baf0ef7e chore(deps): bump js-yaml from 4.3.1 to 4.3.2 (#3792)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.3.1 to 4.3.2.
- [Changelog](https://github.com/nodeca/js-yaml/blob/4.3.2/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.3.1...4.3.2)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 23:54:54 -07:00
dependabot[bot] 4c3fe8ef7b chore(deps-dev): bump @vitest/coverage-v8 from 4.1.10 to 4.1.11 (#3793)
Bumps [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) from 4.1.10 to 4.1.11.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.11/packages/coverage-v8)

---
updated-dependencies:
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.1.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 23:53:49 -07:00
dependabot[bot] c164b5724f chore(deps): bump nodemailer from 9.0.3 to 9.0.6 (#3795)
Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 9.0.3 to 9.0.6.
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v9.0.3...v9.0.6)

---
updated-dependencies:
- dependency-name: nodemailer
  dependency-version: 9.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 23:52:48 -07:00
Daniel Salazar bc9cb2d7e7 fix: withdrawing background consent revokes the app's events session (#3777)
* fix: withdrawing background consent revokes the app's events session

A background handler runs as a worker session for the subscriber and app.
Revoking `events:background` or uninstalling the app suspended the
subscriptions but left that session valid, so a token a handler had copied
out kept working until the user found the row in the sessions list. The
revocation settle now revokes the session too; the next consented delivery
mints a fresh one.

* fix: cleanup docs
2026-09-04 21:10:27 -07:00
dependabot[bot] 5669a2d960 chore(deps): bump fastify from 5.10.0 to 5.12.3 (#3749)
Bumps [fastify](https://github.com/fastify/fastify) from 5.10.0 to 5.12.3.
- [Release notes](https://github.com/fastify/fastify/releases)
- [Commits](https://github.com/fastify/fastify/commits)

---
updated-dependencies:
- dependency-name: fastify
  dependency-version: 5.12.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 21:01:11 -07:00
dependabot[bot] 50aea0cc64 chore(deps-dev): bump vite from 8.1.3 to 8.1.5 (#3790)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.1.3 to 8.1.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.1.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.1.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:53:36 +00:00
dependabot[bot] c67f1c3653 chore(deps): bump uuid from 14.0.1 to 14.0.2 (#3789)
Bumps [uuid](https://github.com/uuidjs/uuid) from 14.0.1 to 14.0.2.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v14.0.1...v14.0.2)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 14.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:53:13 +00:00
dependabot[bot] 78f44c8f8c chore(deps-dev): bump vitest from 4.1.10 to 4.1.11 (#3788)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.10 to 4.1.11.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.11/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-version: 4.1.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:53:03 +00:00
dependabot[bot] 45ee0ef102 chore(deps-dev): bump @types/node from 24.13.2 to 24.13.3 (#3787)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.13.2 to 24.13.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.13.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:52:45 +00:00
dependabot[bot] c4da663533 chore(deps): bump sharp from 0.35.3 to 0.35.4 (#3786)
Bumps [sharp](https://github.com/lovell/sharp) from 0.35.3 to 0.35.4.
- [Release notes](https://github.com/lovell/sharp/releases)
- [Commits](https://github.com/lovell/sharp/compare/v0.35.3...v0.35.4)

---
updated-dependencies:
- dependency-name: sharp
  dependency-version: 0.35.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:52:31 +00:00
dependabot[bot] 69b5901278 chore(deps): bump mysql2 from 3.22.5 to 3.22.6 (#3784)
Bumps [mysql2](https://github.com/sidorares/node-mysql2) from 3.22.5 to 3.22.6.
- [Release notes](https://github.com/sidorares/node-mysql2/releases)
- [Changelog](https://github.com/sidorares/node-mysql2/blob/master/Changelog.md)
- [Commits](https://github.com/sidorares/node-mysql2/compare/v3.22.5...v3.22.6)

---
updated-dependencies:
- dependency-name: mysql2
  dependency-version: 3.22.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:51:54 +00:00
dependabot[bot] 99fb4c2dad chore(deps-dev): bump prettier from 3.9.4 to 3.9.6 (#3783)
Bumps [prettier](https://github.com/prettier/prettier) from 3.9.4 to 3.9.6.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.9.4...3.9.6)

---
updated-dependencies:
- dependency-name: prettier
  dependency-version: 3.9.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:51:41 +00:00
dependabot[bot] 25b6a80cb5 chore(deps): bump libphonenumber-js from 1.13.6 to 1.13.12 (#3782)
Bumps [libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js) from 1.13.6 to 1.13.12.
- [Changelog](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/catamphetamine/libphonenumber-js/commits/v1.13.12)

---
updated-dependencies:
- dependency-name: libphonenumber-js
  dependency-version: 1.13.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:51:34 +00:00
dependabot[bot] b334961f75 chore(deps): bump @esbuild/linux-x64 from 0.25.11 to 0.25.12 (#3781)
Bumps [@esbuild/linux-x64](https://github.com/evanw/esbuild) from 0.25.11 to 0.25.12.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2025.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.25.11...v0.25.12)

---
updated-dependencies:
- dependency-name: "@esbuild/linux-x64"
  dependency-version: 0.25.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:51:10 +00:00
dependabot[bot] aa95a76253 chore(deps): bump @prelude.so/js-sdk from 0.12.0 to 0.12.1 (#3780)
Bumps [@prelude.so/js-sdk](https://github.com/prelude-so/web/tree/HEAD/packages/js-sdk) from 0.12.0 to 0.12.1.
- [Changelog](https://github.com/prelude-so/web/blob/main/packages/js-sdk/CHANGELOG.md)
- [Commits](https://github.com/prelude-so/web/commits/HEAD/packages/js-sdk)

---
updated-dependencies:
- dependency-name: "@prelude.so/js-sdk"
  dependency-version: 0.12.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:50:51 +00:00
dependabot[bot] 85bf595d2d chore(deps): bump highlight.js from 11.11.1 to 11.11.2 (#3779)
Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 11.11.1 to 11.11.2.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/main/CHANGES.md)
- [Commits](https://github.com/highlightjs/highlight.js/compare/11.11.1...11.11.2)

---
updated-dependencies:
- dependency-name: highlight.js
  dependency-version: 11.11.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-05 03:50:38 +00:00
Daniel Salazar 2f15e40a77 ci: add CODEOWNERS, restrict Dependabot to patch bumps, make test workflows always-run (#3778)
- CODEOWNERS: default owners @Salazareo @ProgrammerIn-wonderland @jelveh
  @jfcastro92, plus @reynaldichernando for src/docs.
- dependabot.yml: ignore semver-minor/major npm updates, patch only.
- backend-tests.yaml / puterjs-tests.yaml: trigger unconditionally and gate
  the real work behind a dorny/paths-filter job instead of a workflow-level
  path filter, so the checks always report (skipped when irrelevant) and
  can be marked required. Also pins matrix job names to the artifact label
  instead of the branch ref, which previously made the check name change
  per PR and unusable as a required check.
2026-09-04 20:49:14 -07:00
Daniel Salazar b784b51cf3 fix: harden the events stack for flag-on (#3752)
* fix: harden events dispatch, single delivery and KV share handles

Dispatch: a filtered subscription used the anchor path stored at subscribe
time, so renaming or moving the anchor folder silently ended its deliveries;
dispatch now resolves the anchor's live path from the event's own ancestor
chain. A move out of a watched folder now reaches that folder's subscribers,
with `from` only for rows that watched the source side. Gap markers are
authorized like deliveries and coalesced per subscription and subject instead
of fanning per lost event. Session subscriptions: the per-socket cap decides
on the write, not before it; an orphaned watched-set token heals on refresh;
durable rows keep their watch window when a session subscribe touches the
same keys. `self` is false when the acting user is unknown.

Single delivery: a subscription in backoff or suspended with a backlog pinned
the sweeper's head and starved everyone behind it — the sweep now defers it.
Only a settled handler run bills a delivery. A socket-only account row no
longer wedges after two attempts nobody received. The lease is twice the
handler timeout; remote candidates have their own attempt counter; the region
depth reconcile runs once a minute region-wide with a bounded scan.

KV share handles: a grantee no longer sees the owner's namespace and absolute
prefix on the subscribe answer or listing, nor in the delivery token; revoking
a wider handle retires the handles it covers; minting the same handle twice
returns the existing one, after the delegation check; a row whose event
cannot be re-based onto its handle is dropped rather than delivered raw.

* fix: presence survives replication, long sessions and region churn

One presence item per (user, app) with per-region map fields lost a region
whenever two regions joined inside the replication window, and nothing ever
put it back. Presence is now one item per (user, app, region): each region
writes only its own, a leave or repair retires it conditionally on its own
write stamp, and a read is a prefix query. Items carry a 48 h ttl refreshed by
a claim-gated write off the existing socket renew path, at most once per
12 h, so a tab that stays connected keeps its region in the row. A region
that answered "no socket" or completed a leave releases a shared pin, so a
reconnect on another node rejoins and a flapping client cannot force a
replicated write per cycle. Cached rows expire after a minute; unaddressable
region names are filtered and pruned; relayed acks settle under a bounded
concurrency; the forward queue is bounded in bytes as well as items.

* feat: indexes for the event_subscriptions hot queries

Handler publish, remove and listing, and the hourly expiry and suspension
sweeps, all scanned `event_subscriptions`. Adds (app_uid, handler_name),
(expires_at) and (suspended_at, id), guarded on every engine. Existing
migrations: the postgres widens are now guarded so a boot does not take an
exclusive lock for a no-op, the kv_share_handles grantee FK gets an index,
the sqlite notification rebuild is transactional and idempotent.

* fix: notification writes go through the registry

The driver's `create` bypassed the type registry, producing uncatalogued
rows with no size bound; it now requires a registered type, caps the payload,
and answers 400 rather than 500 for a bad one. `mark_acknowledged` emits the
ack other tabs listen for, and only when a row was actually changed.

* fix: the handler scanner, unsubscribe, and the in-tab handler environment

The free-variable scanner skipped arrows inside a declaration's initializer,
so `const ids = event.items.map(x => x.id)` was refused, and treated a name
after a comma in a nested initializer as bound, so a real free variable slipped
through to fail on first delivery. `unsubscribe()` now drops the durable
routing entry so the events socket can close. A broadcast handler running in
the tab gets `user` and `fetch` like the worker gives it. `single` without
a handler name is refused before the round trip.

* docs: events limits, error codes and the background-workers section

Retention is deployment-configured rather than a fixed 14 days, and the
template no longer ships it armed. Documents `events_terminal`, the two
per-event gap reasons, the subject length and listing caps, the `from` field
on moves, and the handle-relative anchor. The sessions manager hides the
background-workers section when the server has none to show.

* feat: a background handler acts as the app does for its user

A handler's `user` was a five-minute access token scoped to the subscription's
`list` grant, which could stat the changed file but not read it, and could
not reach the app's KV or AppData — so an app told that a file was written
could do nothing with it. It now runs with the same authority the app has for
that user in a tab: an app-under-user worker session, one row per (user, app)
named `events:handlers`, visible and revocable in the sessions list. The
`events:background` consent is what authorizes running it unattended, and is
re-checked before every mint.

The wider token exposed two things: puter.js opens a filesystem socket the
moment it has a token, which would have parked the isolate in the app's own
delivery room and steered deliveries at it; the events client now opts out of
sockets (and the per-open bookkeeping) before construction, and is memoized
per token in the isolate. And four filesystem operations assumed a socket
exists; they no longer do.
2026-09-04 17:32:57 -07:00
Daniel Salazar f30baa2a1c feat: the per-app events worker runtime (#3697)
* feat: bake published handlers into a generated events worker

* feat: deploy and address the per-app events worker behind a flag

* test: single delivery end to end through a real local worker

* feat: events workers run their own runtime, in their own namespace

An events worker was being deployed as an ordinary worker: default dispatch
namespace, a `subdomains` row, the router preamble, and an app-scoped worker
token baked in. The public dispatcher resolves any script in that namespace
straight off the hostname, so the worker answered at `<name>.puter.work`, and
the only thing in front of it was an unguessable name plus a check that a
`puter-auth` header was present — which the router never validates. Anyone who
learned the hostname could run an app's handlers with a body of their choosing,
in an isolate holding the owner's token as `me`.

Instead:

- Handlers run on their own runtime (`src/worker/src/events-runtime.js`), which
  provides no `router` and no `me`, owns the single invoke route, and hands a
  handler only `{ event, ctx, user, fetch, ack }`. `user` is built from the
  invocation's delivery token, so a handler acts as the subscriber whose
  delivery it is and nothing wider. The preamble build emits one bundle per
  runtime; the shared half of the template is now included by both.
- The deploy target carries the runtime to prepend, the source to deploy, and
  whether to mint a worker token at all, so an events worker deploys into the
  `events` dispatch namespace from generated source with no token binding, no
  `subdomains` row, and no claim on the owner's worker quota or worker list.
- An invocation carries a key derived from the deployment secret and the script
  name, bound as a secret and checked in constant time inside the isolate,
  which reads it once and drops it before handler code runs.
- Scripts are named after the handler set they contain, so publishing writes
  rows and deploys nothing: a set is deployed the first time a delivery needs
  it, and a changed set is a new script rather than an overwrite of a running
  one. Publish responses keep the shape they had before the runtime existed.
- Invocations reach a worker only through the events dispatcher, which has no
  zone route and requires the internal secret; the backend's own deploy path is
  the rehydrate route the dispatcher calls on a namespace miss. Locally there is
  no dispatcher, so the controller hands the service an in-process transport
  that deploys on miss itself.

The SDK stops allowlisting `puter` as a handler global — a handler that reaches
for an ambient SDK is now refused at publish time, naming `user` instead, rather
than passing the scan and failing on its first delivery.

Requires `events.workerNamespace`, `events.dispatcherUrl` and
`events.internalSecret`; without them nothing is addressable and background
deliveries stay retriable, as they did with the runtime off.

* fix: a handler's delivery token gets through the read routes

An events handler acts as the subscriber through the access token its
invocation carried, but every FS read route refused scoped access tokens
outright, so `user.fs.stat(event.path)` — the design's own example — answered
403 inside the worker. The read-side routes now admit them; the ACL each
handler already runs intersects the token's grant with its issuer's, which is
the check that keeps a token to what it was minted for. The end-to-end suite
asserts the stat from inside the isolate.

* fix: shorthand-method handlers publish as functions

`{ ingest({ event }) { … } }` stringifies without the `function` keyword, so
its source is not an expression and the events worker baked it as a broken
stub — every delivery a retriable 500 until the subscription suspended, with
nothing at publish time to say why. The SDK now gives a shorthand method the
keyword before hashing and sending; getters, setters and computed names are
left for the server-side check to refuse.

* feat: an app's events worker is listable and destroyable

An app with published handlers has an events worker, and hosted deployments
bill it monthly per app, so its owner needs to see it and be able to take it
down. The core announces the lifecycle on the bus — `events.worker.create`
when an app's first handler is published, `events.worker.destroy` when its last
one goes — with the owner as the actor, so pricing can plug in from outside.
`GET /events/workers` lists the caller's workers (paginated, with the script
each set deploys as) and `POST /events/workers/destroy` removes every handler
of an app under the same owner scoping as the handler routes, suspending the
subscriptions bound to them. `puter.events.workers.list/destroy` in the SDK,
a docs page, and a 5 MB cap on an app's combined handler source
(`events_worker_too_large`) so a set that publishes can always deploy.

* fix: harden the events worker runtime for production

- A 4xx is terminal only when it carries the handled marker the runtime (and
  the dispatcher) stamp on every answer that came from a script; an unmarked
  4xx — an edge 404 for a wrong dispatcher hostname, a WAF page — stays
  retriable and is logged, once per script per minute, with the runtime's
  reason header.
- Script names are scoped to this backend's exposed API origin, so two
  backends sharing a namespace never resolve one script with the wrong
  endpoint binding or key. Shape unchanged.
- Each handler is validated in the exact context it is emitted into and the
  whole generated file is compiled once; a source that would break the script
  marks every handler broken instead of deploying a SyntaxError.
- Locally, events scripts live under their own registry key: the public local
  worker host cannot reach them and an ordinary worker cannot take their name.
- A suspended or deleted app owner stops invocations; deploys are throttled
  per app per hour; in-flight deploys are keyed by app and script; the
  upstream deploy call times out; the generated source is size-capped with a
  margin over the publish cap; boot fails when the runtime is on but its
  preamble is not built. Byte-length secret compare, appUid shape check,
  dispatcher URL prefix preserved, wider connection pool.

* feat: background workers are listed in the sessions manager

A user paying for an app's events worker needs somewhere to see it and take it
down. The sessions manager gets a section listing the apps that run event
handlers in the background, with a Destroy action that removes their published
handlers.
2026-09-04 17:32:57 -07:00
dependabot[bot] dfab3d50cd chore(deps-dev): bump browserslist from 4.28.5 to 4.28.9 (#3759)
Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.28.5 to 4.28.9.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.28.5...4.28.9)

---
updated-dependencies:
- dependency-name: browserslist
  dependency-version: 4.28.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 23:20:29 +00:00
dependabot[bot] 9daaec4ec4 chore(deps): bump qs from 6.15.3 to 6.16.0 (#3757)
Bumps [qs](https://github.com/ljharb/qs) from 6.15.3 to 6.16.0.
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.15.3...v6.16.0)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.16.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 16:17:36 -07:00
dependabot[bot] b7effe1e01 chore(deps): bump fast-uri from 3.1.0 to 3.1.7 in /src/puter-js (#3756)
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.0 to 3.1.7.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.7)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 16:17:08 -07:00
Daniel Salazar 2a68e7aafb ci: add Dependabot config and patch auto-merge workflow (#3760)
Weekly npm/docker/github-actions updates plus vulnerability PRs;
patch-level Dependabot PRs auto-merge, minor/major stay manual.
2026-09-04 16:16:04 -07:00
Daniel Salazar 3355190a17 feat: add astra to models (#3755) 2026-09-04 15:56:53 -07:00
Nariman Jelveh 6ebbc6ae0c feat(gui): let users reposition and zoom a new profile picture (#3754)
* feat(gui): let users reposition and zoom a new profile picture

Picking a photo in the dashboard's Account tab used to stretch the whole
image into a 150x150 square, so anything that was not already square came
out distorted and off-center. The pick now opens an adjust step: a
dashboard-style modal (centered card on desktop, bottom sheet on phones)
where the user drags to reposition and zooms with the slider, pinch, or
wheel before saving. The saved result is the same 150x150 PNG as before.

Geometry lives in profilePictureCrop.js with unit tests; the modal owns the
DOM and pointer handling.

* fix(gui): stop double-encoding the crop modal's hint and frame label

i18n() already HTML-encodes its output, so wrapping it in html_encode()
again turned any apostrophe or ampersand in a translation into a literal
"&apos;" / "&amp;" on screen. Also puts the new profile_picture_* keys
in alphabetical order.

* fix(gui): let the crop frame take focus on click so arrow keys work after a drag

pointerdown's preventDefault() also cancels the click-to-focus that a
mousedown would have done, so after dragging the photo the arrow keys and
+/- went to the dialog container and did nothing. The frame now focuses
itself on pointerdown. Focus that arrives by pointer draws no ring; the
first key press lifts that so keyboard users still see where they are.

Also ignores secondary mouse buttons and treats a lost pointer capture as
a release so a pointer can't stay stuck in the gesture map.

* fix(gui): return focus to the avatar when the crop modal closes

The modal remembered document.activeElement to restore focus later, but
at that moment focus sits inside the file picker, which closes right
after -- so on Save, Cancel or Escape focus fell to <body>. The Account
tab now names its avatar as the place focus returns to, and the avatar
becomes a real button (role, tabindex, label, Enter/Space) so it can
hold that focus and be reached from the keyboard at all.

* fix(gui): announce the crop zoom as a magnification, not a 0-100 slider value

Screen readers read the range input's raw value, which maps to nothing a
user can picture. aria-valuetext now carries the zoom factor (1.0x-4.0x)
and follows every zoom source: slider, buttons, keys, wheel, pinch.
2026-09-04 14:38:55 -07:00
404oopsandClaude Opus 5 7248951410 fix(ai): make chat fallback reach streamed Claude calls and rank Azure explicitly (#3743)
* fix(ai): make chat fallback reach streamed Claude calls and rank Azure explicitly

- ClaudeProvider opens the upstream stream and awaits its connection
  before returning the populator, so an overloaded or rate-limited route
  throws from complete() and reaches the driver's fallback loop instead
  of surfacing as an error frame on a 200
- the OpenAI-compatible chat and completions routes only pin a provider
  when the caller sent one, so they get the same preferred healthy route
  puter.js callers do and unhealthy-route skipping applies to their
  first attempt
- Azure is ranked ahead of the vendors it fronts by an explicit tier in
  modelRouting rather than a price tie plus registration order
- drop Together's synthetic always-failing model-fallback-test-1 entry
- test that a 4xx leaves a route in rotation while a 503 marks it

Co-Authored-By: Claude Fable 5.1 <[email protected]>

* fix(ai): surface swallowed Claude stream errors, keep compat-route defaults

Review follow-ups on the fallback work.

- The pre-created event iterator only receives an error if a reader is
  already waiting on it, so a failure landing between the connect and the
  populator's first pull ended the stream cleanly — truncated content
  billed and reported as a success. Rethrow when the stream is errored.
- A refused stream deleted its Anthropic uploads but left the caller's
  message parts pointing at those file ids, so the fallback route was
  handed handles it cannot resolve. processPuterPathUploads now returns a
  restore() that both failure paths call.
- The OpenAI-compat routes keep pinning OpenAI when the caller sends no
  model at all, so the default model stays put instead of moving to
  Azure's.
- Say why /openai/v1/responses and /anthropic/v1/messages stay pinned:
  each translates one provider's native shape by hand.
- PREFERRED_PROVIDERS is unexported and its doc now states the rank is
  unconditional; the duplicated hidden-model list is one constant.

Co-Authored-By: Claude Opus 5 <[email protected]>

* fix(ai): undo the puter_path rewrite by field instead of snapshotting the part

Copying the content part kept whatever the caller sent on it — a large
inline `source` or `text` alongside `puter_path` — reachable until the
request ended, where overwriting the field used to make it garbage right
away. The only fields this function writes are `type`/`source` on success
and `type`/`text` on failure, and the fallback uploader keys off
`puter_path` alone, so restore undoes those three by name.

Co-Authored-By: Claude Opus 5 <[email protected]>

---------

Co-authored-by: Claude Fable 5.1 <[email protected]>
2026-09-04 11:10:05 -07:00
Reynaldi Chernando 2966cee6b0 explicit mention of kv and fs being user scope and workers for backend (#3751) 2026-09-05 01:02:22 +07:00
Reynaldi Chernando d8735d950e fix kv set value type (#3750) 2026-09-05 00:30:17 +07:00
Reynaldi Chernando 48abf73d1a kv add array example (#3748) 2026-09-05 00:22:46 +07:00
Reynaldi ChernandoandCopilot Autofix powered by AI 11c5a7ce52 dynamic workers docs (#3747)
* dynamic workers docs

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-09-04 22:57:11 +07:00
Reynaldi ChernandoandCopilot Autofix powered by AI b6876c50bf PUT-1477 Add fs commands to cli (#3746)
* Add fs commands to cli

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-09-04 21:31:33 +07:00
Daniel Salazar 6d7be8bd6a docs: kv key layout is the ACL boundary (PUT-1689) (#3693) 2026-09-03 19:43:28 -07:00
Daniel Salazar b451d05d10 feat: app-minted kv share handles (PUT-1688) (#3692) 2026-09-03 19:43:27 -07:00
Daniel Salazar f139588f89 feat: revocation settles kv handles (PUT-1687) (#3691) 2026-09-03 19:43:27 -07:00
Daniel Salazar ac5446f877 feat: cross-user KV share grants and handles (PUT-1686) (#3690) 2026-09-03 19:43:27 -07:00
Daniel Salazar adde6c3a29 feat: notification GUI rides the events surface (PUT-1685) (#3689)
Widen the notif: match filter and fetch scope for a session's own
generic developer/app-user subscribe: today it pins ref to the
session's own uuid, so a row naming an app (handler-suspension
notices, app-bound worker deploys) never matches live and never
replays on reconnect, even though the audience predicate already
grants the holder every such row it owns. The predicate is the
authority and already reruns per row/page after the match, so
widening the filter to it (account is unaffected — it never names an
app) adds no exposure.
2026-09-03 15:39:22 -07:00
Daniel Salazar fe5f81e52e feat: scoped app access to notifications (PUT-1684) (#3688)
An actor holding an app reads the `app-user` rows naming that app, plus its
`developer` rows when the holder owns it. `account` rows reach no app, and a
slice an actor may not see comes back empty rather than refused. The audience
predicate becomes the enforced read path in the same change that lifts the
blanket app-actor 403, layered behind an audience/app_uid SQL scope; two-segment
`notif:` subjects expand server-side from the actor's own app, so an app can
never name another app's uid.

No feature flag: `audience` defaults to 'account', so every pre-registry row is
default-denied to app actors and the backfill can only narrow.
2026-09-03 15:39:22 -07:00
Daniel Salazar 796683a133 feat: missed-event fetch and notification fold-in (PUT-1681) (#3687) 2026-09-03 15:39:22 -07:00
Daniel Salazar eb8f497e9f feat: presence and cross-region event forwarding (PUT-1679) (#3686)
* feat: presence and cross-region event forwarding (PUT-1679)

* fix: fan cache bumps to sibling nodes and stop the forward shed cascading (PUT-1679)

`outer.events.generationBumped` and `outer.events.presenceBumped` rode
`outer.*`, which the broadcast service only webhooks to peer regions;
only `outer.pubsub.*` also fans over Redis to a region's other nodes.
Both caches are per-process maps with no expiry, so a bump landing on
one node left its siblings stale until that user's next transition.
Renamed onto `outer.pubsub.events.*`; the listeners already accept the
`from_outside` copy the Redis re-emit carries.

`PeerForwardQueue.push` called `onOverflow` synchronously and the
handler pushed markers straight back, each of which re-tripped the
bound and shed the next item: one item over a 5000 bound recursed ~2200
deep, threw a RangeError, and turned ~2200 queued deliveries into gap
markers. It also re-summed `bytes` over the whole queue per drop. The
handler now returns its markers and the queue appends them past the
bound check, sheds deliveries before markers, keeps one pending marker
per (peer, subscription), and subtracts bytes per dropped item.
2026-09-03 15:39:21 -07:00
Daniel Salazar 32a838d2e2 fix: one ** per match pattern and one * per segment (#3736)
`compileMatch` turned every `*` into an unbounded `[^/]*`, so a subject
like `fs:~/x/*a*a*a*a*a*a*a*a*a*a*z` tested against a 24-char filename
with no `z` — both named by the same subscriber — cost the regex engine
C(34,10) splits before failing: 1.0 s per event at ten stars, 3.7 s at
eleven, on the fs-write dispatch path, inside the 256-character cap.

With one `*` per segment the delimiters pin each star and a wrong split
dies in one step; the single `**` is the only choice point left, so the
worst allowed shape is O(depth × length): 0.4 ms at depth 60 of 200-char
segments. Every documented pattern (`*.png`, `**/build.log`, `**/*.png`,
`dir/**`, `report-?.csv`) stays valid; `*a*`, `a**b` and `**/x/**` are
refused with `invalid_subject_pattern`. The rule is stated where the
syntax is introduced, on the limits page, and in onLocal's error table.
2026-09-03 15:08:49 -07:00
404oops 1b777cd760 Merge pull request #3730 from HeyPuter/filipkujundzic/put-1620-video-generation-timeouts-return-500-and-page-on-call
fix: stop video generation timeouts and failures from paging (PUT-1620)
2026-09-03 22:54:58 +02:00
Daniel Salazar 799fc4ac3c feat: send app icons as a subdomain URL plus an API fallback (#3734)
App payloads carried only the /app-icon endpoint URL, which 302s to the
icons hosting subdomain. Networks that mangle that redirect render no icon
at all, and every icon load pays a round trip for the hop.

Ship the direct subdomain URL as `iconCdnUrl` alongside it (taskbar items,
installedApps, recent/recommended launch apps, suggested apps), and have the
GUI load that first with the endpoint URL as a one-shot retry - desktop
taskbar, start menu, dashboard app grid and recents. Only rows whose `icon`
column is already an http(s) URL get one: a data: column means the resize
pipeline has not written anything to the subdomain yet.

Also folds the four copies of the generated-size list into one exported
APP_ICON_SIZES.
2026-09-03 13:32:55 -07:00
Juan Fernando Castro d855315db8 Merge pull request #3714 from HeyPuter/juancastro/put-1708-26-teamcontroller-and-audit-writes
🏗️ PUT-1708 + PUT-1709 + PUT-1743: TeamController, teams_enabled, and the isolation suite
2026-09-03 16:21:02 -04:00
Juan Castro 9bc2cd741c feat: add TeamController, the teams_enabled flag, and the isolation suite
Covers PUT-1708, PUT-1709 and PUT-1743.

Twelve routes, every one setting requireUserActor -- that option is what
installs requireAuthGate, requireVerifiedAccount and requireNonAccessTokenGate,
because server.ts derives `needsAuth` from the route options. Reads need it as
much as writes: without an auth option a route gets no suspension check and
admits access tokens, so a just-disabled member could still read the roster and
a scoped third-party token could read the audit log.

Authority is checked before anything observable. Validating the body first made
POST /members answer 400 before 403, and resolving :username first turned the
member routes into a global username-existence oracle.

Provisioning applies the same username and email rules as signup rather than
its own -- USERNAME_REGEX, USERNAME_MAX_LENGTH, RESERVED_USERNAMES and
validator.isEmail, now exported from AuthController. Without them a workspace
could mint accounts signup would refuse, claim unregistered reserved names, and
mail arbitrary unvalidated addresses.

Handle problems are 400 or 409 rather than a bare Error, which the server turns
into a 500 and a deduped critical alarm -- an uppercase handle should not page
on-call.

Disable drops sessions through SessionStore.removeByUuid rather than a raw
DELETE. The store invalidates every composite cache key; without that a
disabled member kept authenticating from cache for the session TTL, which is
exactly the "takes effect on the next request, not after a cache TTL" property
disable is supposed to have. Revoking also preserves last_ip/last_user_agent,
which the member-facing audit view reads.

Audit writes live in TeamService at the point of each action rather than in the
route, so a caller reaching the service directly cannot skip them, and the SQL
lives in TeamStore. Audit reads map internal user ids to usernames, and remain
readable by the owner after the workspace is soft-deleted -- otherwise the
delete_team entry was written and immediately unreachable.

teams_enabled gates route registration through an optional isEnabled() the
server honours, so with it off the paths do not exist rather than existing and
refusing. It does not gate DDL.

TeamIsolation.http.test.ts asserts the negative the feature rests on: the
workspace manages accounts and cannot read them, including through a
full-access token and after the member is disabled. It asserts outcomes rather
than the absence of an implicator.
2026-09-03 15:57:23 -04:00
Juan Castro 673f7fe75f feat: provision org accounts from a workspace
Covers PUT-1705. The master account supplies { username, email }; the account
is created with no password, gets the default filesystem tree, joins with
org_owned = 1, and receives a one-shot activation link.

Activation reuses password recovery rather than new token machinery: the same
pass_recovery_token, the same one-hour purpose-scoped JWT, the same
/action/set-new-password link. No team_activation table, no new token type,
and no unauthenticated endpoint on the team surface. Activation state needs no
column either -- an unactivated account is one with no password.

Applies the same username and email rules as signup rather than its own:
USERNAME_REGEX, USERNAME_MAX_LENGTH, RESERVED_USERNAMES and validator.isEmail,
now exported from AuthController. Without them a workspace could mint accounts
signup would refuse -- the username becomes the /username home-directory
segment -- claim unregistered reserved names, and send activation mail to
arbitrary unvalidated addresses at the route's daily limit.

Usernames come from Puter's global pool, so a taken one is refused with free
alternatives rather than silently modified: a suffixed name would appear in
every share dialog that person ever sees, and they never agreed to it. The
check runs before any write, so a rejected provision leaves no orphaned user
row -- asserted by a test on the workspace's member count.

The new account carries requires_email_confirmation, since the address came
from the administrator rather than its holder.

Adds a team_account_activation email template stating what the workspace can
and cannot do -- including that it can reset the password, which the design
requires be said rather than only claiming files are private.

free_storage stamping and the billing event are phase 3.
2026-09-03 15:57:23 -04:00
Juan Castro da2b42d7fe feat: add TeamService workspace lifecycle and disable/re-enable
Covers PUT-1704 and PUT-1707: creating a workspace, admitting the master
account, and the whole of offboarding.

`createWorkspace` admits the creator with org_owned = 0, which is what makes
the master pay for itself and stay an invalid target of every member route.
`checkOwnerInvariant` asserts the rule no dialect can express -- the owner is
a member with org_owned = 0 and the only such member -- and a test breaks it
deliberately, since the schema cannot refuse a second one.

Three authority checks: 404 to a stranger so the endpoint is not an existence
oracle, 403 to a member who is not the master, and the master refused as a
target of member routes.

Handle problems surface as 400 (unusable) or 409 (taken), including the
unique-index race. `TeamStore` throws a bare Error, which the server would turn
into a 500 and a deduped critical alarm -- an uppercase handle should not page
on-call.

Disable writes `user.suspended` as well as suspended_at and suspended_reason.
PUT-1707 named only the latter two, but those are siblings added by 0061 and
0063 -- `userProtected` rejects on `if (user.suspended)` and reads neither.
Setting only the timestamp and reason would have recorded a disable that never
took effect, and disable is the whole of offboarding here.

Sessions are dropped through SessionStore.removeByUuid rather than a raw
DELETE. The store invalidates every composite cache key with its double-delete
pattern; without that a disabled member keeps authenticating from cache for the
session TTL, which is exactly the "next request, not after a cache TTL"
property disable is supposed to have. Revoking also preserves last_ip and
last_user_agent, which the member-facing audit view reads.

Files are untouched and re-enable restores the account.

Adds team_not_found, not_the_master_account and not_an_org_account to the
HttpError legacy codes, which the controller also needs.

Billing events, invalidateActorSubscription, audit rows and the GUI push are
deliberately not here -- they belong to phase 3 and PUT-1708.
2026-09-03 15:57:23 -04:00
Juan Castro 8b4e259421 feat: add team membership reads and writes to TeamStore
Membership management for workspaces: addMember, removeMember,
getMembership, isMember, listMembers and listTeamsForUser. The permission
scan is untouched -- readUserGroupPerms already joins jct_user_group and
resolves group grants; this is the management side.

Resolves the ticket's "do not leave two writers" by splitting domains and
enforcing the split in SQL rather than by convention. Every existing caller
of GroupStore targets a seeded system group -- ADMIN_GROUP_UID,
default_user_group, default_temp_group -- never a team, so the two stores
were already disjoint in practice. GroupStore.addUsers/removeUsers now carry
`AND kind IS NULL`, making a team uid a no-op there, which costs no extra
query because it folds into the existing subquery and matches how addUsers
already treats an unknown username. TeamStore's writes select group_id from
a kind-filtered subquery, so neither store can reach the other's rows.

org_owned is written here but never accepted from a request; TeamService
sets it at provisioning and workspace creation only.

listMembers is keyset-paginated on id per doc/pagination.md, using the
shared cursor and limit helpers and fetching one row past the limit to
decide whether a cursor is warranted.

Passes 1/0 for org_owned rather than db.booleanValue, which yields a real
boolean on postgres and is rejected by the smallint column there -- sqlite
accepted it silently.
2026-09-03 15:57:16 -04:00
Juan Castro 37cb11df8c feat: add TeamStore for workspace CRUD
`GroupStore` has only addUsers/removeUsers; nothing creates, reads back or
lists a group at runtime. `TeamStore` is that missing half, scoped to rows
with `kind = 'team'`.

A workspace is addressed by `uid`, which `group` has carried as NOT NULL
UNIQUE since 0015. `handle` is a mutable display label with no addressing
role, so a rename invalidates nothing and a stale reference can never
resolve to a different workspace.

Soft delete releases the handle and keeps `name`. Nothing points at a
handle, so the name returns to the pool instead of being reserved forever
by a global unique index that cannot exclude dead rows -- mysql has no
partial indexes, so that exclusion was never available.

Handles validate to ^[a-z0-9]+(-[a-z0-9]+)*$, 3-64 chars, against a
reserved list. The charset is deliberately narrower than the column so the
engines' collations cannot disagree: mysql's utf8mb4_unicode_ci also folds
accents and eszett, which sqlite's NOCASE and postgres's lower() do not.

Every read filters `kind = 'team' AND deleted_at IS NULL`, which is what
makes the seeded admin/system groups unreachable rather than merely absent.
Handle lookups compare lower(handle) on postgres, where the index is on
that expression rather than the column.
2026-09-03 15:20:07 -04:00
Juan Fernando Castro ad70e8763b Merge pull request #3708 from HeyPuter/juancastro/put-1701-13-add-audit_team_membership-and-shareholder_group_id
🏗️ PUT-1701: Add audit_team_membership and share.holder_group_id
2026-09-03 15:17:34 -04:00
Juan Castro 64db3fa050 feat: add audit_team_membership and share.holder_group_id
Insert-only record of what a workspace administrator did to an account,
shaped like \`audit_user_to_group_permissions\` after 0019: nullable FK
beside a NOT NULL \`_keep\` column. The FKs are ON DELETE SET NULL, never
CASCADE, so hard-deleting an account cannot erase the record of the
resets performed on it.

Two indexes rather than one. The member's own view is the only place a
reset becomes visible to the account it was performed on, so
(user_id_keep, id) is a read path, not an optimisation.

\`share.holder_group_id\` mirrors \`holder_user_id\` from 0067. The existing
unique index does not constrain team shares at all -- it leads with
\`holder_user_id\`, which is NULL on every team share, and NULLs are
distinct -- so the group-scoped unique index is what prevents duplicates.

Drops the \`role\` column from the specified DDL: it contradicted the
settled single-administrator model.
2026-09-03 15:07:53 -04:00
Juan Fernando Castro 43f62cf7d0 Merge pull request #3705 from HeyPuter/juancastro/put-1700-12-deduplicate-jct_user_group-before-adding-the-unique-pair
🏗️  PUT-1700: Deduplicate jct_user_group and make membership writes unique
2026-09-03 15:07:49 -04:00
Juan Castro dc7b456afa fix: run the membership dedup once instead of on every boot
Review follow-ups on the dedup migration.

mysql and postgres track no per-file applied state and re-execute every
migration on each boot, so the unguarded DELETE self-joined the whole table at
every process start, forever. Both now sit behind the same index-existence
check that guards the ALTER, which also stops a rolling deploy deleting on one
instance while another adds the index.

The dedup test was a false green. `targetVersion: 67` never applies 0071 -- the
loop breaks on `threshold + 1 >= targetVersion` but stamps the target anyway --
so the fixture asserted the current schema version on a database missing a
migration. It now replays the real 0072 file against a fully migrated database,
and a second test pins the off-by-one so nobody builds a fixture on it again.
2026-09-03 14:33:46 -04:00
Juan Castro c1c1588939 fix: deduplicate jct_user_group and make membership writes unique
\`jct_user_group\` had no unique constraint on (user_id, group_id) and
\`GroupStore.addUsers\` had no conflict clause, so re-adding a member
inserted a second row. \`readUserGroupPerms\` joins the junction table on
group_id alone, so each duplicate returned another copy of every group
permission the user holds.

Deduplicate keeping the lowest id, add the unique pair index, and make
\`addUsers\` ignore conflicts via the existing \`insertIgnoreInto\` helpers --
without that last part the index turns a re-add into a raised error, which
five call sites would log as a failed signup step.

mysql cannot delete from a table it reads in a subquery (error 1093), so
it uses a self-join with the same lowest-id-wins semantics.
2026-09-03 14:32:30 -04:00
Juan Fernando Castro abb426a717 Merge pull request #3704 from HeyPuter/juancastro/put-1699-11-add-team-columns-to-group-and-jct_user_group-three
🏗️ PUT-1699: Add team columns to group and jct_user_group
2026-09-03 14:26:58 -04:00
Juan Castro eae25459f4 fix: make handle lookups case-insensitive and pin the reset flag
Review follow-ups on the team columns.

NOCASE moves onto the `handle` column itself, not just the index. Index-only
NOCASE makes uniqueness case-insensitive while leaving `WHERE handle = ?`
case-sensitive, so the same lookup would match on mysql (utf8mb4_unicode_ci)
and miss on sqlite. Postgres still needs lower(handle) at the call site.

`requires_password_change` becomes NOT NULL DEFAULT 0 on all three dialects,
matching the three sibling `requires_*` flags. Left nullable, any query written
as `= 0` would silently exclude every pre-existing user.
2026-09-03 12:10:48 -04:00
Juan Castro 2a5c089dbe feat: add team columns to group and jct_user_group
Schema foundations for teams. Ships dark — nothing reads these columns yet.

group:          kind, name, handle, plan_id, deleted_at
jct_user_group: org_owned
user:           requires_password_change

`kind = 'team'` marks a workspace; the seeded system groups keep it NULL so a
team query can never surface them. `org_owned` distinguishes accounts the
workspace created from the master account, deciding who pays rather than who
may read. `requires_password_change` is a fourth `requires_*` flag for
assertVerifiedAccount, needed by the phase 5 reset flow but shipped here to
avoid a second three-dialect migration.

`handle` uniqueness is case-insensitive, and the dialects disagree by default:
mysql gets it from utf8mb4_unicode_ci, sqlite needs COLLATE NOCASE (as
0055 does for usernames), and postgres indexes lower(handle). Without this the
same migration would accept `Design-Team` next to `design-team` on sqlite and
postgres while mysql rejected it. Postgres handle lookups must therefore
compare lower(handle) to use the index.

idx_group_owner is sqlite-only: mysql and postgres already index that column.
idx_jct_user_group_group is composite, unlike the existing single-column keys.
2026-09-03 12:10:40 -04:00
404oops 55fa5cadcb Merge pull request #3732 from HeyPuter/gemini-38-flash
gemini 3.8 flash direct integration
2026-09-03 17:35:22 +02:00
Reynaldi Chernando 644f59f9dd gemini 3.8 flash direct integration 2026-09-03 22:18:02 +07:00
404oopsandClaude Fable 5.1 8b01077d44 docs: describe the real txt2vid error body and per-provider wait windows
The Errors section claimed a `{ message, code }` body and a single
ten-minute wait. The body also carries `error`, `errorCode`, `provider`,
`upstreamCode` and, for pre-job rejections, `upstreamStatus`, and the
Sora provider still waits five minutes and folds refusals into
`upstream_failed`. Document the fields and the exceptions.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-03 16:57:36 +02:00
404oopsandClaude Fable 5.1 627a5b2d5e fix: stop video generation timeouts and failures from paging (PUT-1620)
A video job that outlived its poll window, an SDK request that timed out,
or a Veo operation that finished with an error all reached the HTTP error
handler as plain Errors. Each became an unhandled 500 with critical
severity and paged on-call for what is the provider's pace or the
provider's fault.

Video providers now share one poll loop that gives up with a 504
`upstream_timeout`, treats a transient poll failure (timeout, dropped
connection, 408/429/5xx) as a missed poll rather than a failed job, and
stops polling with a 400 `client_aborted` when the caller disconnects, so
nothing is metered for a clip nobody will receive. The driver controller
exposes the disconnect as an `abortSignal` on the request context. The
window is ten minutes for every provider; Together and BytePlus move up
from five.

Failed jobs are classified: content-filter refusals become a 400
`bad_request` with `errorCode: moderation_flagged`, rejected parameters a
400 `upstream_bad_request`, and anything else a 502 `upstream_failed`,
each carrying the provider's own code. Veo's filtered output keeps
`disallowed_value` and gains the same `errorCode`. The sanitizer and
content-filter pattern move from the Replicate provider into a shared
util so image and video agree.

Status-less SDK connection timeouts are translated to a 504
`upstream_timeout` at the driver boundary, and the chat driver records
them per attempt so an all-timeout chain is a 504 and a mixed chain is
`upstream_failed` instead of an `internal_error` 500. The Together chat
client gets the same ten-minute request timeout as the other providers.

The OpenAI video provider is left alone beyond an import path: its API is
scheduled to shut down on 2026-09-24.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-03 16:47:16 +02:00
Daniel Salazar 72011fa6ed feat: events metering and quotas (PUT-1683) (#3685)
* feat: events metering and quotas (PUT-1683)

* fix: drop the standing subscription charge and price single deliveries at 100 µ¢

An idle durable row costs nothing worth billing; the plan quotas bound how
many an account holds. Removing the daily line also removes the global
day-claim, the whole-table scan and the timer it rode on.

* test: stop asserting on documentation pages

The limits test read rate-limits-and-quotas.md and grepped it for numbers,
so every rewording of the page failed the backend suite. Docs are kept in
step by the PR and checked in review; AGENTS.md now says so.
2026-09-03 01:39:07 -07:00
Daniel Salazar 41b837b398 feat: background delivery seam, retries, and consent (PUT-1682) (#3684) 2026-09-03 01:39:06 -07:00
Daniel Salazar 04c00385b9 feat: event handlers, context, and suspension machine (PUT-1680) (#3683) 2026-09-03 01:39:06 -07:00
Daniel Salazar 9626ab9c71 feat: KV change events and KV subjects (PUT-1678) (#3682) 2026-09-03 01:39:06 -07:00
Reynaldi Chernando 3de6eeb474 init docs recipes (#3728) 2026-09-03 10:04:01 +07:00
Neal Shah af27115f68 Attempt 1: Fix PUT-1625 (#3727) 2026-09-02 21:36:04 -04:00
Daniel Salazar d8ebfc8023 feat: delivery re-check cache, revocation and anchor settle (PUT-1677) (#3681)
* feat: delivery re-check cache, revocation and anchor settle (PUT-1677)

* fix: authorize re-anchors, settle each row once, purge revoked backlog (PUT-1677)

- A path-form row whose anchor is deleted only climbs to an ancestor its
  holder may still watch under the mode it subscribed with; otherwise it ends
  with `anchor_deleted`. It used to land on any surviving ancestor (a guest's
  row on the owner's home), where the re-check denied every delivery but the
  row still held an anchor slot and a filter evaluation there.
- After a climb the new anchor is re-verified and the climb repeated if a
  recursive delete took that level too, instead of leaving the row on a dead uid.
- suspend() is one conditional write per row and reports which rows it was the
  one to suspend; concurrent settles of the same grant (an unshare revokes
  several strings) no longer each purge, forget and notify the same rows.
- One "subscriptions ended" notification per holder and app, carrying the count
  and subjects, instead of one per row.
- A revoke that removed nothing no longer announces; the sweeper purges (not
  defers) the backlog of a permission_revoked row; the reap purges pending
  entries with the row.
- The delivery auth cache indexes entries by subscription so forget() is not a
  scan of the whole cache.
2026-09-02 16:00:14 -07:00
Daniel Salazar 41d4850ab4 feat: pending event deliveries and delivery-class invariants (PUT-1676) (#3680)
* feat: pending event deliveries and delivery-class invariants (PUT-1676)

* fix: make pending delivery claims and drains atomic, keep the region under its ceiling (PUT-1676)

- claim() and the drain-time reindex run as Lua over the subscription's own
  {subId}-tagged keys. Two claimers can no longer both lease the head, and a
  drain that finds the queue empty deletes it in the same step it checks, so a
  concurrent enqueue is never wiped between the two.
- An append writes the entry and its queue position in one MULTI (same slot),
  with the index seeded before it and corrected after, so an entry is never
  visible without its position and never left out of the sweeper's index.
- Pipelines no longer mix slots (index/counter vs. per-subscription keys), so
  the store works on a multi-shard cluster, not only a single-shard one.
- Region shedding counts the marker it leaves behind; it used to stop one over
  the ceiling and convert a real event into a marker on every enqueue after.
- A claimed or suspended subscription moves to the back of the sweeper's index,
  so a delivery nobody settles cannot hold the head against every other backlog.
- `single` rows must carry a `worker` target: with sockets exhausted and no
  handler, an unacknowledged delivery would sit at the head forever.
- A gap marker for a row with no socket target is dropped rather than counted
  as a delivery of nothing.
- Backlog keys carry a 7-day TTL, refreshed by every claim, as a backstop for
  keys a purge/enqueue race left unindexed.
2026-09-02 16:00:14 -07:00
Daniel Salazar 0dfbceb047 feat: durable event subscriptions store, cache, and routes (PUT-1673) (#3679)
* feat: durable event subscriptions store, cache, and routes (PUT-1673)

* fix: durable subscription hardening (PUT-1673)

- Expired rows stop delivering at dispatch time and no longer count toward
  the per-account cap, instead of waiting for the sweep.
- The expiry sweep runs hourly with a jittered first pass shortly after boot;
  a 24 h interval never fired on a fleet that redeploys more often than that.
- Only a durable generation bump marks peer regions cold. A session
  subscribe/unsubscribe in one region used to force a primary read in every
  other region on its next dispatch.
- `subject`/`anchor_path` widen to varchar(4096) to match `fsentries.path`,
  and subjects longer than that are refused with `invalid_subject` rather than
  failing the insert on MySQL/Postgres.
- The dispatch and durable integration suites wait for the specific delivery
  they expect and assert only within their own folder; the old any-delivery
  `settle()` let a late event from a previous test satisfy or pollute the
  next one under CI load.
2026-09-02 16:00:13 -07:00
Daniel Salazar cab5253923 feat: puter.events SDK module (PUT-1675) (#3678)
* feat: puter.events SDK module (PUT-1675)

* fix: end event subscriptions on a server-side disconnect and retry budget refusals (PUT-1675)

- A disconnect socket.io will not retry (`io server disconnect`) now fails
  every subscription with `events_connection_failed` and drops the socket, so
  the next onLocal() starts a fresh connection instead of reusing a dead one.
- The connection closes when the last subscription lapses on re-subscribe.
- A re-subscribe refused with `too_many_requests` is retried after 10 s
  rather than ended for good.
- The API suite no longer passes when it cannot connect; every runtime it
  runs on (node, browser, workerd) carries the socket.
2026-09-02 16:00:12 -07:00
404oopsandClaude Fable 5.1 d89dc347a2 fix: keep the credit-bounded max_tokens on the context-length retry (PUT-1628) (#3718)
OpenRouter and Together reject a request whose prompt plus max_tokens
overflows the model's context window. Both providers retried by deleting
max_tokens, which threw away the output cap the credit gate had sized to
the caller's remaining balance and let the retry run to the model's full
output limit with no second gate and no new hold.

The retry now goes through a shared helper that sizes a new cap from the
window and input count the rejection reports, falling back to the model's
declared context and a doubled prompt estimate, and never exceeds the cap
the gate set. When no window can be determined or no output fits, the
original rejection is rethrown instead of retrying uncapped. The rejected
params are copied rather than mutated, so the first attempt's record is
not rewritten after the fact.

Also corrects the estimator's own comment, which described the mean of
two approximations as a deliberate halving.

Co-authored-by: Claude Fable 5.1 <[email protected]>
2026-09-02 13:28:36 -07:00
Daniel Salazar 66dc0a6396 feat: subscribe ACL and app scoping for event subscriptions (PUT-1672) (#3677) 2026-09-02 13:08:23 -07:00
Daniel Salazar fb8e2976dc fix: don't redirect puter.com (#3723) 2026-09-02 11:57:30 -07:00
404oopsandClaude Fable 5.1 fd7b517448 fix: classify Replicate prediction failures instead of 500ing (PUT-1608) (#3719)
A Replicate prediction that ran and ended `failed` reaches the provider as a
plain Error with no HTTP status, so the driver-boundary translator could not
classify it and it surfaced as an unhandled 500, a critical alarm, and an
on-call page. Most of these are the model's content filter refusing the
user's prompt.

Wrap the run call and classify the failure: content-filter refusals become
a 400 with `errorCode: moderation_flagged` (the code chat refusals already
use); anything else becomes a 502 `upstream_failed`, which the alarm gate
skips. Status-bearing SDK errors pass through untouched so the boundary
translator keeps handling them. Upstream messages are stripped of markup and
bounded so an HTML error page can no longer ride into a response body or an
alarm signature.

Documents the codes callers can now act on in the txt2img reference.

Co-authored-by: Claude Fable 5.1 <[email protected]>
2026-09-02 11:51:08 -07:00
Neal Shah 262f1dc5c5 allow concept of "home regions" (#3699)
* allow concept of "home regions"

* remove extraneous config value not applicable to repo
2026-09-02 14:11:55 -04:00
Daniel Salazar 7ec674d33b feat: app sockets join their own events room (PUT-1671) (#3676) 2026-09-02 09:01:22 -07:00
Daniel Salazar b07d2e109f feat: session event subscriptions and dispatch hot path (PUT-1666) (#3675) 2026-09-02 09:01:22 -07:00
Daniel Salazar 92e1b40361 feat: events subject registry, parser, anchors, filters (PUT-1660) (#3674) 2026-09-02 09:01:21 -07:00
Daniel Salazar d0ee19a2c2 chore: remove dead notification surfaces (PUT-1669) (#3673) 2026-09-01 22:04:33 -07:00
Daniel Salazar 82076ea767 feat: notification retention sweep (PUT-1668) (#3672) 2026-09-01 22:04:32 -07:00
Daniel Salazar 5f37817a5c feat: notification type registry and audience rules (PUT-1665) (#3671) 2026-09-01 22:04:32 -07:00
Daniel Salazar 148b930182 feat: notification scope columns and backfill (PUT-1659) (#3670) 2026-09-01 22:04:31 -07:00
Daniel Salazar 0385072e06 feat: better verification step handling (#3717) 2026-09-01 21:17:19 -07:00
Daniel Salazar 1736d23ee7 Ds/put 1674 (#3715)
* feat: app-scoped share listing and revoke surface (PUT-1670)

* fix: address review on app-scoped share surface

- Scope the uid-addressed revoke to the named row: only that row's
  issuer's grant is withdrawn, and only that one invite cancelled —
  an app or owner addressing one row no longer takes another issuer's
  grant on the same (item, recipient) pair with it.
- Delete a pending row directly on uid-addressed revoke, so an invite
  whose address registered but never claimed can still be withdrawn.
- Read the legacy `issuerAppUid` data key in the SQL app filter and
  grouping, alongside the unified `issuedByApp`.
- Refuse malformed `appUid` input (duplicated param, empty string)
  instead of silently listing everything, and refuse app-listing
  cursors that decode but name no appUid.
- Derive the acting app from `effectiveApp` alone, per the actor
  contract; drop the second derivation site.
- Pin the attribution semantics with tests: one row records one
  issuance, so re-sharing the same pair re-attributes it to whoever
  issued last, in both directions.
- Soften the uniform-404 docblocks to what the gates actually answer.

* feat: readable grant audit trail (PUT-1674)

* fix: cover the apps summary's no-app-group first page (PUT-1670)

listOutboundApps sorts the no-app group first via an empty-string
sentinel. Add a regression test pinning that a first page (no cursor)
actually returns it, and that the cursor it hands back resumes past it
into the app-keyed groups rather than skipping or repeating.
2026-09-01 14:07:15 -07:00
Daniel Salazar 66a975f659 feat: global outbound share listing (PUT-1664) (#3694)
* feat: global outbound share listing (PUT-1664)

* fix: address review on outbound share listing

- Check share-row liveness per (holder, entry, issuer) so a grant
  withdrawn outside unshare doesn't stay listed while another issuer
  still reaches the same holder; batch the permission reads across the
  whole page instead of per holder.
- Retire a revoked issuer's unclaimed invites in the revoke cascade,
  and hide invites whose issuer lost their authority at read time.
- Unify the pending/active app-attribution key on `issuedByApp` and
  dual-read the legacy `issuerAppUid` spelling.
- Add the missing share issuer index (sqlite, postgres) and correct
  the listOutbound plan comment.
- Refuse cursors that decode but name no id instead of silently
  restarting from page one.
- Consolidate the five hand-built ResolvedShare literals and the two
  listing endpoints' parse/shape code.
- Ship the SDK surface: puter.fs.listSharedByMe() with docs, types,
  suite coverage, and the rate-limit page entry.
2026-09-01 13:52:37 -07:00
404oopsandClaude Fable 5.1 6478a8f47d Add Claude Fable 5.1 (#3711)
Register claude-fable-5-1 in the Claude catalog and gate it in the
provider the same way as Fable 5: no sampling params, effort via
output_config, adaptive thinking with summarized display. The bare
claude-fable / claude-fable-latest aliases move to 5.1, matching how
the Opus aliases moved when Opus 5 landed.

Fable 5.1 keeps Fable 5's $10/$50 per MTok, 1M context and 128K output,
but bills cache reads at 0.025x input instead of the 0.1x every other
Claude model uses, so the catalog row carries its own rate and a test
pins it.

Co-authored-by: Claude Fable 5.1 <[email protected]>
2026-09-01 15:34:49 -04:00
Nariman Jelveh fdd86ceb03 Stop server-rendered landings flashing for signed-in users (#3707)
The shell renders its anonymous markup — the marketing homepage, an
`/app/<name>` landing — off the session cookie alone, and that cookie is
set with no maxAge, so a browser drops it on quit while the GUI's
localStorage token lives on. A returning user is served the anonymous
page and the GUI only tears it down once `whoami` answers, a network
round-trip after first paint. That teardown is the flash.

Gate it before the paint instead. The shell now emits, as the first thing
in <head>, a rule hiding `.hide-if-logged-in` under an <html> class that
an inline script adds iff `auth_token_v2` is in localStorage. The rule is
already in the cascade when the markup is parsed, so a browser holding a
token never paints it at all.

`initgui` settles the guess the token represents: `whoami` confirming the
session removes the nodes outright (replacing the old `#appLanding`
removal), and no session — none stored, or one `whoami` rejected — drops
the class so the markup comes back. The gate carries its own 12s failsafe
so a bundle that never boots can't strand a blank page.

SEO is unaffected: the HTML is byte-identical for every client, nothing
branches on user-agent, and a crawler has no stored token so it never
adds the class. Unreadable storage fails open the same way.

Anonymous markup opts in with `class="hide-if-logged-in"`, which
`home.html` already carried.
2026-09-01 09:19:00 -07:00
Daniel Salazar 7584dffc4b fix: metering for ai (#3703) 2026-09-01 09:11:04 -07:00
jelveh b400e06473 Remove login landing fade-out overlay
Drop the delayed fade-out when a logged-in user reaches the GUI and remove the landing overlay immediately instead. This avoids the overlay sitting above the email/phone/card verification gates because of its z-index.
2026-08-31 20:13:58 -07:00
jelveh 22c3316109 Hide app landing after session restore
Remove the /app landing overlay once `whoami` confirms the user is authenticated, even if the server rendered the page as anonymous because the session cookie was missing. This prevents the overlay from covering the email, phone, and card verification gates during localStorage-based session restores.
2026-08-31 20:07:47 -07:00
404oops a27852de0a Merge pull request #3655 from HeyPuter/FK/normalize-openai-format
Comprehensive Normalization.
2026-08-31 22:24:34 +02:00
jelveh f80a0d72b3 fix: dashboard 'Add Existing Account' dialog buried on phones/tablets
On device-phone/device-tablet, style.css pins every .window to
z-index 9999999 !important — including the fullpage dashboard window.
The Add Existing Account login dialog opens with backdrop: true, and
the .window-backdrop wrapper is not a .window, so it kept its small
inline z-index and rendered entirely behind the dashboard.

Pass stay_on_top: true like every other backdropped dashboard dialog,
and make the Forgot-password child dialog inherit the flag so it does
not open buried under the now stay-on-top login window's backdrop.

Verified with Playwright on iPhone 13 emulation and a desktop
viewport: login and recover-password dialogs stack above the
dashboard in both.
2026-08-30 21:45:43 -07:00
Nariman JelvehandClaude Fable 5 3e8b2735bb Cap /app/<name> meta descriptions at 150 characters (#3698)
The app shell fed the row's full description into <meta name=
"description">, og:description and twitter:description. Long
descriptions now collapse whitespace and cut at a word boundary with an
ellipsis, never exceeding 150 characters.

Co-authored-by: Claude Fable 5 <[email protected]>
2026-08-30 20:17:04 -07:00
Daniel Salazar 5065bcbf0a fix: document allowedAppIdsGate's real non-app-gate behavior (PUT-1667) (#3669)
The JSDoc claimed non-app actors are rejected; they are passed through, and
the check reads `actor.app` rather than `effectiveApp`, so an app in the
token chain is invisible to it. Callers depend on the pass-through — routes
combining `adminOnly` + `allowedAppIds` are reached with an admin's browser
session, and the dev-account surface is called from the desktop's own
session — so the docs are corrected instead of the behavior, on the gate and
on the `allowedAppIds` route option. Tests cover the gate per actor shape
(user session, worker, full-access token, app-issued access token,
app-under-user allowed/disallowed) and the admin composition.
2026-08-30 12:55:39 -07:00
404oopsandClaude Fable 5 7e1cdefd98 feat(ai): backfill provider catalogs from live /models listings
A live audit of every keyed provider's /models endpoint against the hardcoded
catalogs found no stale entries but large gaps. This backfills them under four
rules: nothing vendor-deprecated, nothing without a price confirmed on the
vendor's official pricing page (each entry's source was recorded during
review), nothing absent from the live /models listing, and nothing that fails
a live routing probe.

Added: 46 Alibaba entries (qwen3/3.5/3.7/3.8 families, VL/omni/MT lines, and
Model Studio's hosted GLM/DeepSeek/Kimi third-party models) plus 9 dated
aliases; OpenAI chat-latest and gpt-4o-2024-11-20 plus 16 snapshot aliases;
Gemini gemma-4-31b-it and gemma-4-26b-a4b-it (vendor-documented free tier)
plus rolling -latest aliases; Mistral-hosted zai-glm-5-2 and a
mistral-medium-3.5 alias; deepseek-v4-flash-vision-exp; glm-5.3-flash.

Culled by the rules: 15 vendor-deprecated OpenAI entries (the 3.5/4/4-turbo
legacy line, gpt-4o-2024-05-13, o1-pro, four chat-latest predecessors, the
5.x codex line — deprecations page, most shut down 2026-10-23) and dated
aliases onto the deprecated o1/o3-mini/o4-mini; qwen3-vl-flash-2025-10-15
(live routing probe returned upstream 400 twice). Tiered Alibaba prices are
encoded at the base tier and busy-hour rates where time-of-day priced, noted
in comments.

Every surviving addition was verified end-to-end through a local deployment:
58/58 answered a live prompt, including all 46 Alibaba entries and every
spot-checked alias.

Not changed, flagged for maintainers: pre-existing o1, o3-mini and o4-mini
entries are now vendor-deprecated (shutdown 2026-10-23); the pre-existing
deepseek-v4-flash/-pro prices no longer match DeepSeek's current pricing
page; gemma-4 emits its own <thought> markup inline in content.

Co-Authored-By: Claude Fable 5 (1M context) <[email protected]>
2026-08-30 20:50:46 +02:00
404oopsandClaude Fable 5 4199a2506d feat(ai): forward Mistral prompt_mode so magistral can emit separable thinking
Live-probing magistral-small-latest showed the model inlines its reasoning as
answer prose in a flat string — no ThinkChunk content, no markers, nothing a
client can separate. Mistral's chunked thinking shape is requested via
`prompt_mode: 'reasoning'`, which the provider previously dropped on the
floor: there was no way to even ask for it.

`custom.prompt_mode` now forwards to the SDK's `promptMode`, following the
BytePlus custom-params precedent. Opt-in rather than a default because the
API rejects the mode where the account/model lacks it ('Reasoning prompt
mode is not enabled for this model', code 3051) — verified end-to-end: the
3051 travels back through the stack, which also proves the parameter is
delivered. The moment Mistral enables the mode, the ThinkChunk content flows
into the existing splitter and comes out as `message.reasoning` and
`reasoning` stream chunks with no further changes.

Co-Authored-By: Claude Fable 5 (1M context) <[email protected]>
2026-08-30 20:50:46 +02:00
404oopsandClaude Fable 5 4aa66c7c9b feat(ai): make puter.ai.normalize tri-state — unset means the release-date policy
The SDK-wide flag now mirrors the per-call option's tri-state. Left unset
(the default), the release-date policy applies: models released on or after
2026-09-01 are normalized to the OpenAI shape, older models keep their
vendor-native shape, and nothing rides the wire — the server's policy
resolution decides. Setting `true` force-normalizes every chat() call
regardless of release date; `false` disables normalization for every call;
either explicit value is sent on each call that doesn't set its own.
A per-call `normalize` overrides the flag in both directions, and assigning
`undefined` restores the policy.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-30 20:50:15 +02:00
Daniel Salazar afe46a17a0 fix: alaem cascade (#3668) 2026-08-29 03:41:23 -07:00
Juan Fernando Castro 81d700d146 fix: publishing a directory takes ownership, not write (PUT-1619) (#3654)
Creating a hosted subdomain gated `root_dir` on `write`, and hosting serves
everything under that directory with the ACL deliberately bypassed. So a
recipient of a `write` share could point a `*.puter.site` subdomain at the
owner's folder and make the subtree world-readable — continuously, covering
files the owner added later, with the row under the recipient's account where
nothing the owner can list would show it. `update` had the same gate for a
changed `root_dir`.

`#checkPublishAccess` now decides both: the actor's own tree still takes
`write`, anyone else's takes `manage` — "Can edit & share", the level that
delegates the decision.

Keyed on who owns the entry rather than asking for `manage` outright, which is
what the ticket proposed. `manage`'s is-owner implicator declines to answer for
app actors, so a flat `manage` would refuse every app publishing a directory
its user handed it, with no way for the app to obtain the grant. The write
check still runs first — it is what masks a directory the caller cannot see as
a 404 — and `manage` satisfies every lower mode, so the order costs a
manage-holder nothing.

The GUI's Publish As Website item reuses the own-it-or-`manage` answer it
already computes for sharing, so it is not offered where this would refuse.
Docs state the rule on `hosting.create()` and in `share()`'s level list.

Regression tests fail without the driver change: a write-share recipient is
refused on create and on repointing an existing subdomain, while `manage` and
the actor's own directory are accepted.
2026-08-29 01:46:14 -07:00
LEANDER ROSHAN L d5e9c14b0d fix: update sharing indicator #3649 (#3665) 2026-08-29 01:43:40 -07:00
Juan Fernando Castro c17613669c fix: open read-only shared files instead of forwarding write_url=undefined (#3667)
Opening a file you hold read-but-not-write access on (a read-only share)
failed silently. For such a file the backend correctly omits write_url from
the /open_item signature, but launchApp appended it to the app iframe URL
unconditionally. URLSearchParams coerces undefined to the string \"undefined\",
so the app received puter.item.write_url=\"undefined\" — truthy, so the editor
believed the file was writable, and an invalid URL, so it broke on open. Only
read-only shares hit this; files you can write carry a real write_url.

Extract the puter.item.* param building into append_signed_item_params and
guard the write_url append so it is only added when present. launchApp.js is
too coupled to UIWindow/jQuery/window globals to unit-test directly, so the
pure helper carries the logic and its own test, matching the helpers/ pattern.

Regression test pins both directions: a read-only signature omits write_url
entirely (no \"undefined\"), and a writable signature still forwards it.
2026-08-29 01:42:46 -07:00
Juan Fernando Castro cdfd38bd4b fix: stop an embedded fs: in a path from escalating to full FS access (#3666)
The fs-path-to-uid permission rewriter split permission strings on the raw
\`fs:\` substring instead of parsing on component boundaries. A path can
itself contain \`fs:\` — a home dir named \`…fs\`, or \`fs\` in the mode
position — and the raw split mistook that for the mode delimiter.

Crafting \`fs:/<victim>fs:junk:read\` made the split do two things at once:
it dropped the \`junk:read\` mode, and it consumed the trailing \`fs\`, turning
the harmless-looking nonexistent path shown in the consent dialog into the
victim's real home path. The rewriter then stored a bare \`fs:<home_uuid>\`,
which subsumes every mode via parent-permission matching — full
read+write+delete from a request the user saw as \`junk:read\`.

Parse with PermissionUtil.split() in both matches() and rewrite(), matching
every other permission parser, and locate the \`fs\` component by position
(after an optional \`manage\` prefix). The path component is now exactly what
sits between \`fs\` and the next unescaped colon, and all trailing components
are preserved as the mode — so an embedded \`fs:\` is data, never a delimiter.
The crafted input now addresses the nonexistent \`/<victim>fs\` and 404s.

Regression tests pin both halves: the exact PoC must 404, and an \`fs:\` in
the mode position must survive the rewrite instead of collapsing to a bare
permission. Both fail on the old rewriter and pass on the fix.
2026-08-29 01:41:40 -07:00
Juan Fernando Castro 693e86d763 Merge pull request #3657 from HeyPuter/juancastro/put-1616-shareblocks-is-missing-requireuseractor-any-authorized-app
🔧 PUT-1616: Close /share/blocks to app tokens
2026-08-28 16:46:04 -04:00
Daniel Salazar 6d10ef2821 fix: stop a URL parameter putting puter.js into app mode (#3660)
`env = 'app'` was decided by the presence of a `puter.app_instance_id` query
parameter and nothing else, so a crafted link put any page that loads the SDK
into app mode — and app mode is what makes the URL's `puter.api_origin`
authoritative for every credentialed call.

App mode now also requires the document to be framed. The GUI only ever
launches an app into an iframe, so this costs a real app nothing while a
top-level document carrying the parameters is treated as the third-party site
it is. It is not an attestation that the framing document is the GUI — a
cross-origin ancestor's identity is not readable — so the token paths carry the
rest:

- The `web` boot branch adopted a stored token without consulting the origin it
  was bound to, which is what completed the fixation: one link plants a token
  bound to an attacker's origin, and every later visit adopted it. It now
  applies the same binding rule the app branch does, and drops a token that
  fails it rather than leaving it to be re-read.
- `signIn()` had no env guard, and in app mode delivered a real token to
  whatever `puter.api_origin` the launching URL named. Apps get their token
  from the session that launched them, so it now rejects there with
  `not_available_in_app`. Nothing internal reaches it in app mode:
  `authenticateWithPuter` and both implicit-auth call sites already gate on
  `env === 'web'`.
- The cross-origin-isolated branch polled `${this.APIOrigin}/login/wait` and
  adopted whatever came back. Pinned to `defaultAPIOrigin`, the same way the
  popup and its message handler already pin `defaultGUIOrigin`.

Backward compatibility: no signature, response field or existing error code
changes. The only behaviour a caller can observe is the new `signIn()`
rejection, which replaces a call that could not have worked correctly.

Covers the SDK side of the parameter PUT-1395 and PUT-1427 closed on the GUI.
2026-08-28 11:16:10 -07:00
Daniel Salazar 9fab4742c9 fix: complete the malformed-input guards, including the two paths still live (#3663)
Review of the previous change found three of its claims unmet.

The image-generation crash it reported fixed is still reachable. The assert was
scattered across three helpers, and Gemini and OpenAI call `isHttpUrl` directly
on `input_images` without going through any of them — so two of seven providers
still 500 on a non-string. `isHttpUrl` now refuses a non-string itself, and the
shape is settled once in `ImageGenerationDriver.generate`, where the driver call
arrives, rather than per helper. That also covers `input_images` that isn't an
array, which produced a different crash per provider.

The sixth case in the ticket, previously unlocated, is
`Messages.js` reading `tool_call.function.name` with no guard — reachable with
`{"messages":[{"role":"assistant","tool_calls":[{"id":"x"}]}]}`. Guarded, along
with the same shape in `make_claude_tools`: a TypeError there carries no status,
so the retry loop reads it as a provider failure and marks the route unhealthy
for every caller.

`#hardExpiryFromExpiresIn` returning null for a bad type moved the failure past
the session INSERT, leaving an orphaned non-expiring row and still answering
500. Reverted; the controller guard is the fix, now covering fractions,
negatives and unparseable durations rather than only wrong types.

Also: the batch write handlers check that the body is an array but not what is
in it, so a null element 500s the same way; `#requireObjectBody` accepted an
array despite its name; `handleCreateAccessToken` destructured a body that may
be absent; and two AGPL notices had been rewrapped with a Markdown link.
2026-08-28 11:14:30 -07:00
Daniel Salazar f3a46a9be4 fix: stop sockets outliving the session that authenticated them (#3658)
A socket was checked once at handshake and never again. Nothing in the backend
disconnected one, so logout-everywhere, password reset, session revoke and
suspension all left every connection streaming legacy FS entries, upload paths
and notification bodies — up to 400 per account — on a credential that had
already been revoked.

Three gaps, three fixes:

- The handshake skipped the suspension and pending-verification checks every
  authenticated HTTP route gets. `decideSocketAuth` now applies both.
- `revokeCascade` reports which rows it revoked, AuthService announces that as
  `auth.sessions.revoked`, and SocketService drops the account's room. The
  whole room goes, not just the revoked session: narrowing it would need
  `fetchSockets`, which the adapter builds on `serverCount()` — and that calls
  node-redis's `send_command`, which ioredis does not implement. A connection
  whose session survived reconnects on its own and re-authenticates.
- A bulk suspension writes `user.suspended` without touching `sessions`, so no
  revoke fires. A five-minute sweep re-verifies each live socket's token and
  drops the ones that no longer authenticate. De-duplicated by token, since a
  browser's tabs share one.
2026-08-28 11:12:27 -07:00
Daniel Salazar e460e9034c fix: answer 400 instead of 500 on four malformed-input paths (#3662)
Each of these read a field off caller input that wasn't the shape the code
assumed, threw a TypeError, and was served as a 500 with a critical page.

- POST /fs/write and /startWrite: a request whose body never parsed left
  `req.body` undefined, and the first read of `fileMetadata` threw.
- POST /drivers/call, image generation: `input_image` / `input_images` entries
  are documented as strings but nothing checked, so a number or an object
  reached `.startsWith`. Type confusion on caller input, so reachable on
  demand rather than by accident.
- POST /auth/create-access-token: `expiresIn` went to the expiry parser
  unvalidated, where anything but a string or a number has no `.trim`.
- POST /login/wait: destructuring `session` out of an absent body threw.
  Same class as the POST /login body ticket; that one covers /login itself.
2026-08-28 10:22:51 -07:00
Daniel Salazar 5c8defb940 fix: bound failed WebDAV Basic-auth attempts per account and per address (#3659)
The only thing in front of the bcrypt compare on the DAV host was the 600/min
request ceiling, keyed on a fingerprint that rotates with client-controlled
headers. /login guards the same credential with a captcha and two much tighter
buckets; DAV had neither, which left password and TOTP guessing viable from a
host that answers any origin.

The request ceiling can't double as a credential ceiling — a working DAV client
resends its credentials on every request — so the new buckets count only
verifications that failed: 10 per account and 50 per address per 15 minutes,
sized like /login's. They're read before the compare, so an exhausted bucket
costs no bcrypt round, and successful requests never draw them down. `-token`
attempts are held by the address bucket alone; bucketing them per account would
let bad tokens lock out good ones.

Reading a bucket without spending from it is new, hence `peekRateLimit` and the
matching `peek` on all three backends.

Also documents the DAV limits, which were undisclosed.
2026-08-28 10:21:34 -07:00
Daniel Salazar 88b851a423 fix: derive the signup client IP from req.ip instead of x-forwarded-for (#3661)
Both signup paths read the x-forwarded-for header directly for the
puter.signup.validate event, the puter.signup.success event and the
signup_ip_forwarded column. Behind an appending proxy a client can prefix that
header with anything it likes, which gives every per-IP abuse signal a fresh
bucket per request.

req.ip is the value `trust proxy` resolves, so it is the one the server can
stand behind; server.ts already uses it for the ip.validate gate for exactly
this reason. All three now share one derivation, so a per-IP counter is written
and read under the same key. The raw chain is still recorded, but only as
audit_metadata.ip_fwd, where nothing keys on it.

Rows written before this hold whatever the proxy appended, so per-IP velocity
over the trailing window is undercounted until they age out.
2026-08-28 10:19:24 -07:00
Juan Castro 94d798ccce fix: close /share/blocks to app tokens
All three block routes set only `subdomain`, `requireVerified` and a rate
limit, and the controller's actor check accepts anything carrying a user, so an
app-under-user token passed. Unlike `share` and `revoke`, nothing else bounded
them: an app the user authorized once could read exactly whom they had blocked,
then clear the list — blanket switch and per-username — and reopen the channel.

A block list is a personal safety control, not something an app can otherwise
reach, so it falls outside the "an app can share what it can already reach"
carve-out the other share routes rely on. `requireUserActor` on all three, and
deliberately without `allowFullAccessToken`: this is security management, which
stays closed to every access token, personal ones included.

The only caller is the desktop's Blocked Senders window, which sends the user's
own session token.

Tests fail without the gate: an app token minted through
/auth/get-user-app-token is refused on all three routes while the user's own
session still succeeds, and a metadata check pins the gate on every block route
so a fourth cannot quietly ship without it.
2026-08-28 12:32:17 -04:00
404oopsandClaude Fable 5 07998c32ed test(ai): point the provider-level replay test at the real driver fallback test
The comment claimed the fallback loop cannot be driven from a test — false
since ChatCompletionDriver.test.ts gained a two-attempt fallback test that
drives the actual loop. Say where that test lives instead.

Co-Authored-By: Claude Fable 5 (1M context) <[email protected]>
2026-08-28 01:09:14 +02:00
404oopsandClaude Opus 5 04d12d9524 fix(ai): route Mistral streamed thinking to the reasoning channel, unconditionally
Third triple-check round. Ten findings were put through independent skeptics
first; six did not survive — pre-existing on main, inert, or resting on a false
premise — and are not acted on here.

Mistral streamed thinking now goes to `reasoning` on every path. The previous
commit gated the split, which made this the only place in the repo where
chain-of-thought reached the visible text channel, and made Mistral the only
provider whose streamed chunk *types* depend on a response-format flag. Every
other reasoning path routes thinking to `reasoning` unconditionally —
ClaudeProvider's thinking_delta, the DeepSeek/OpenRouter rename, and this
branch's own Responses summary-delta handler. Removing the gate restores that
uniformity and makes the documented promise that streaming is unaffected by
normalization true again; the two opposing tests collapse into one that runs the
same fixture with and without `normalize` and asserts identical event streams.

Docs stop claiming older models are unchanged. Four reasoning fields were made
consistent across all models, ungated, and one of them removes a field: on
non-streaming responses `message.reasoning_content` is now `message.reasoning`.
chat.md gains a table naming all four so a caller reading `reasoning_content`
learns why it disappeared, instead of reading that nothing changed for them.

Adds the driver-level fallback test. Writing it surfaced that the invariant it
was meant to assert is false and always was: the driver rewrites string
`content` into text blocks in place on the caller's own messages
(`normalize_single_message`, pre-existing) before any provider runs. The test
now asserts what is true and load-bearing — both attempts receive the same array
reference, and the reasoning artifacts survive attempt 1 so attempt 2 can still
replay them.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-28 01:09:14 +02:00
404oops 875aac5db0 Revert "docs: record AI-normalization review rules in CLAUDE.md"
This reverts commit f220276724fdc1a16ae56f9c95e41773fe4231ed.
2026-08-28 01:09:14 +02:00
404oopsandClaude Opus 5 216e8d68ed fix(ai): scope the normalized flag, gate the Mistral stream split, correct four doc claims
Acts on a second triple-check audit.

`normalized` means one thing. The driver stamped it on both the OpenAI-shape
path and the legacy `response.normalize` path, which converts toward Anthropic
blocks — so a caller could get `normalized: true` alongside array content, and
the flag told them nothing they could branch on. The legacy branch no longer
sets it. That branch is reachable only by a direct driver call with
`response.normalize` and no `normalize`; the four wire routes pin
`normalize: false`, which skips it.

Mistral streaming, split by concern. Flattening a reasoning model's chunked
`delta.content` to a string is a correctness floor and stays ungated — the
shared handler passes the value straight to `addText`, so an array reaches the
caller as stringified objects. Splitting the thinking text out into a
`reasoning` delta is the dialect change and now sits behind the policy gate
like the non-streaming remap. On the native path the thinking text is kept
inline rather than dropped.

Mistral `finishReason` is deleted only once its value carried over. The delete
ran unconditionally, so a non-string `finishReason` with no `finish_reason`
left the choice with no finish reason at all.

Four doc claims corrected against the code paths they cover: `content` is
string-or-null on normalized responses (tool-only turns carry no text, and the
`// always a string` example comment was wrong); `reasoning_details` is not
scoped to normalized responses, since Responses models emit it either way; and
the release-date rule depends on the serving provider's own dates — OpenRouter
derives them from its live API, so models newly listed there from 2026-09-01
normalize by default.

Adds the test the copy-on-write fix was actually for: one messages array sent
through two sequential calls, asserting the caller's array is untouched and
both attempts carried the thinking signature. That is the fallback hazard; the
harness wires one provider per model, so the fallback loop itself cannot be
driven from a provider test.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-28 01:09:14 +02:00
404oopsandClaude Opus 5 c1b420e480 fix(ai): gate the Mistral remap, unify the reasoning join, stop mutating caller messages
Acts on a triple-check audit of this branch.

Gate the Mistral dialect remap. The camelCase→snake_case rewrite and the
chunked-content flattening were firing for every Mistral call regardless of
`normalize` or the cutoff, deleting `finishReason` and `message.toolCalls` out
from under any caller reading them. Both now sit behind the policy resolution
the driver already used, extracted as `shouldPresentAsOpenAI` so the provider
and the driver cannot drift. The streaming chunk-array split stays ungated:
handing an array to `addText` is a plain bug, and streamed chunks are
provider-uniform by design. The conformance matrix now passes `normalize: true`,
which is the contract it was always testing.

Unify the reasoning join. Three code paths produced two separators while one
doc sentence described them all: the coercer joined thinking segments with '',
the Responses handler and Mistral with '\n\n'. The coercer now matches, and
chatresponse.md's claim is true for every path it covers. Text blocks still
join with '' — Anthropic splits prose mid-sentence across them.

finish_reason is an open set. chat.md's normalize bullet and the SDK
ChatMessage typedef still declared a closed four-value set, contradicting the
documented pass-through of unmapped vendor reasons and the coercer that
implements it.

Stop mutating caller messages. Both reasoning-replay input paths deleted
output-only fields from the caller's own message objects, which the driver
reuses across fallback attempts. Both strip a copy now; tests pass a frozen
message through each.

Drop three dead things the type cleanup left: the no-op ChatProvider
checkModeration stub (no subclasses, no callers — its removal restores a
pre-existing baselined TS2420), the redundant second normalizeReasoningContent
call in BytePlus and ZAI, and the coercer's bare-string branch that no provider
reaches. A bare string now passes through by reference instead of being
coerced.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-28 01:09:14 +02:00
404oopsandClaude Opus 5 fbb9038651 revert: restore the 31 typecheck-baseline entries this branch removed
Commit 6b4f5b01f dropped 31 entries (49 error instances) from
tools/typecheck-baseline.json as a side effect of fixing the AI-code type
errors they suppressed. The file is a ledger the maintainer owns, and shrinking
it inside a feature PR ships a CI-gate change nobody asked for.

Restoring is free: tools/typecheck.mjs fails only on *regressions*
(count > baseline), so stale entries are non-fatal — the gate prints "49
baselined error(s) fixed. Run npm run typecheck:update to lock that in." and
exits 0. Nothing else in the repo reads the file, vitest included, and
tsconfig.build.json's noCheck:true means emit is unaffected. The errors stay
fixed in the source either way; only the ledger's own bookkeeping is deferred
to whenever the maintainer chooses to regenerate it.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-28 01:08:48 +02:00
404oopsandClaude Opus 5 74640d4e83 fix(ai): flatten Mistral reasoning models' chunked content
`magistral-*` returns `message.content` as a ContentChunk[] rather than a
string, with the thinking text nested one level deeper inside `thinking`
chunks. The camelCase remap did not touch it, so a non-streamed magistral
response reached the caller as an array with no `reasoning` — the one case
left where a provider did not produce the equalized shape this branch
promises. Streaming had the matching bug: the chunk array was handed to
addText, which would have stringified it into the text stream.

Both paths now split chunked content into a string `content` plus a
`reasoning` string, joining multiple thinking chunks with a blank line as the
Responses handler and the Anthropic coercer do. The streaming fix rides the
existing Mistral-only `chunk_but_like_actually` hook, so no new deviation is
introduced.

The conformance matrix had no Mistral reasoning fixture, which is why it
missed this; it now has one carrying chunked content, verified to fail
without the flattening.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-28 01:08:48 +02:00
404oopsandClaude Opus 5 3b8de6a90b docs: record AI-normalization review rules in CLAUDE.md
Rules from the post-normalization review: don't silently change what existing
models return, verify doc claims against every code path they cover, record
self-disclosed defects in the PR draft, finish with a fresh build + suites, and
check git stash before concluding an edit was lost. Plus the standing
typecheck-baseline no-go.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-28 01:08:48 +02:00
404oopsandClaude Opus 5 a6830f341a fix(ai): round-trip reasoning artifacts and pass unmapped stop reasons through
Closes the reasoning gaps left open by the normalization work.

Reasoning replay. The coercer dropped Anthropic thinking-block signatures and
the Responses handler dropped reasoning item ids/encrypted_content, so a
normalized reasoning turn could not be replayed — Anthropic rejects an
extended-thinking tool-use continuation whose thinking blocks lost their
signature. Both now ride `message.reasoning_details` verbatim, and both input
paths accept them back: ClaudeProvider splices the blocks ahead of the content
(Anthropic requires them to lead), and the Responses input processor expands
them into standalone `reasoning` items. Output-only fields a replayed message
carries (`reasoning`, `refusal`, `normalized`) are stripped on both paths,
since neither upstream accepts them. The docs caveat recommending
`normalize: false` for agentic Claude loops is gone; it is no longer true.

Unmapped stop reasons. chatresponse.md promised a vendor `finish_reason` with
no OpenAI analog "passes through unchanged" — true for the Mistral remap, false
for the Anthropic coercer, which discarded it. Anthropic's `pause_turn` means
"continue this turn", so flattening it to `stop` destroyed the signal. The
coercer now passes unmapped values through verbatim, matching both the doc and
the Mistral path, and the docs gain the full Anthropic stop-reason table.

Reasoning summaries. Multi-part summaries joined with '' instead of a blank
line, and the streaming Responses path emitted no reasoning at all;
`response.reasoning_summary_text.delta` now feeds the same `reasoning` stream
channel the chat-completions handler uses.

Types. `text?: string & { verbosity?: ... }` was an uninhabitable intersection
(providers read `text?.verbosity` as an object), and the verbosity enum was
`'concise' | 'detailed'` where OpenAI accepts `'low' | 'medium' | 'high'`.
Adds `reasoning`, `reasoning_details`, and `refusal` to the SDK ChatMessage
typedef.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-28 01:08:48 +02:00
404oopsandClaude Fable 5 548d26f884 test(ai): cover Hoonify in the provider-consistency matrix
Adds the upstream Hoonify provider (feat #3499, merged after this
branch was cut) to the cross-provider output conformance suite. It
speaks the OpenAI chat-completions dialect and conforms out of the box.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-28 01:08:48 +02:00
404oops 9b67a2b1dd Add AI response normalization controls
Introduces a new `normalize` option for chat completions, plus release-date based default normalization (post-2026-09-01) to coerce provider-native outputs into a consistent OpenAI-style shape. Adds shared normalization utilities, extensive driver/provider consistency tests, and controller safeguards that pin provider-native output where route-specific translators are used. Also wires the option through puter.js (`chat` options and `puter.ai.normalize` default), updates AI/chat response docs and examples, and resolves related TypeScript typing issues reflected in the typecheck baseline.
2026-08-28 01:08:47 +02:00
Juan Fernando Castro f952b5006b Merge pull request #3652 from HeyPuter/juancastro/put-1594-permission-requests-should-auto-return-true-and-resolve
🔧 PUT-1594: Settle a permission request from what is already granted
2026-08-27 19:02:15 -04:00
Nariman Jelveh 56b4ef7f2b Leave worker notifications out of the dashboard entirely 2026-08-27 15:59:25 -07:00
Nariman Jelveh 1d3963539f Keep worker notifications out of the dashboard toasts 2026-08-27 15:47:57 -07:00
Juan Castro c4be7fabac fix: settle a permission request from what is already granted
`puter.perms.request()` already pooled a permission read and prompted only
for what was missing. The raw `puter.ui.requestPermission()` did not, so
every caller still on it re-asked the user on each launch — including
`perms.requestAppData()`, whose own docs promise the opposite, and the
driver-denial retry.

- puter.js: `ui.requestPermission()` reads what is held before prompting and
  resolves true when the whole request is covered. Only in env=app and
  env=web, the environments that raise a prompt; elsewhere the method still
  answers false without asking anyone. A check that cannot be made — no
  token, an unreadable request shape, a failed read, or one that outlasts its
  timeout — falls through to the prompt rather than standing in for an
  answer. Public signature unchanged.

- GUI: the request-permission popup asks the same question as the app, using
  the user-app token its own exchange already mints, and skips the dialog
  when the access is held. This is the one case the SDK cannot settle for
  itself: a signed-out site holds no token to check with. An origin the
  browser does not vouch for never reaches the check, since the exchange
  fails first.

Both checks are time-boxed, because each one stands in front of something
that is waiting: the popup's gates the dialog, so a stalled read would leave
the prompt unshown and the opener pending, and the SDK's spends the browser's
transient activation, which a slow read would cost the popup.

Note that driver, service and feature scopes are implicitly granted to every
app (backend/data/hardcoded-permissions.js), so requests for those now
settle silently — the dialog was asking about access the app already had.
Consent scopes (email, fs, apps, subdomains, app-data, app-root-dir) are
unaffected and still prompt until granted.

Fixes a bug this method already had on the way past: `pollDecision` read an
undeclared `permission`, so every attempt threw a ReferenceError into its
network-failure catch and the COOP-severed-opener recovery burned its full
five-minute timeout before answering false. It polls `requested` now, and
requires the whole list.

Tests: the e2e suite drove its dialogs with an implicitly-held driver
permission, so the fixture now asks for a driver nothing implies, fresh per
page load, which also removes the cross-test grant carry-over the old
revokes worked around. The reconciliation tests ask for the held scope plus
an unheld one, since a fully-held request no longer reaches a dialog. Adds a
backend contract test for check-permissions under an app-under-user actor,
which is what the two new client paths rest on.
2026-08-27 16:35:06 -04:00
Nariman Jelveh 167e281cc8 Keep read notifications in the dashboard panel
The panel listed only what the user hadn't dismissed, so acting on a
notification made it vanish. It now shows the 30 most recent regardless
of state, with read/unread as a visual flag: unread rows carry a dot and
a check to mark them read; reading one (check, click-through, toast
close, mark-all, or an ack from another tab) leaves it listed but
quieter. The badge, tab title, and header count follow the unread count.
2026-08-27 13:31:39 -07:00
Nariman Jelveh c6ecc0c786 Soften dashboard notifications empty-state title 2026-08-27 13:14:05 -07:00
Nariman Jelveh f38dec07ea Remove empty-state hint from dashboard notifications 2026-08-27 12:59:01 -07:00
Nariman Jelveh 7332993ff3 Show share notifications in the dashboard (#3653)
* Show share notifications in the dashboard

The dashboard opens its own socket but never listened for notif.* events,
so a file shared with a user on the dashboard was announced to nobody.

Add a notification center to the dashboard: a bell in the sidebar with the
unread count (a dot when collapsed, and on the mobile hamburger), a panel
anchored to it — a bottom sheet on phones — listing what the server still
holds as unacknowledged, and toasts for what arrives live. Clicking a share
lands on Files › Shared with the item selected; dismissing, and "Mark all as
read", acknowledge on the server so other tabs clear too. A toast timing out
is not a dismissal: the entry stays unread in the panel.

Arrivals fold in by uid (a regrouped share rewrites its row and toast in
place), the panel refreshes on open, reconnect and tab focus so shares the
backend folds in silently past the sender's budget still surface, and a
burst on connect is capped at three toasts plus a summary.

Backend: notif.unreads carries created_at so delivered-on-connect items can
be dated, and listings break same-second ties by id so order is stable.

The desktop's mark-ack calls move to a shared helper; UINotification gains an
optional auto-hide timeout that pauses on hover/focus.

* fix: look up notification glyphs and icons by own key only

A notification whose `source` or `icon` was a prototype key such as
`constructor` made the glyph lookup return a function, and the toast
icon builder then threw inside the socket handler — which dropped the
whole burst of toasts it was part of. The list rendered the same entry
as "[object Object]".

* fix: show dashboard toasts above open app windows

App windows opened from the dashboard are stay-on-top and stack in the
99999999+ band, so the toast container at 10000000 sat underneath them:
any notification arriving while an app was open — the usual state of a
dashboard session — was drawn behind the app and never seen.

* fix: reveal the dashboard when a toast is clicked over an open app

Clicking a share toast switches the dashboard to Shared, and the "N new
notifications" toast opens the panel — both inside the dashboard window.
With an app maximized over it, all of that happened out of sight and the
click appeared to do nothing. Minimize the covering app windows first,
the way the minimize controls do, landing the URL on the dashboard's own
route, and act once the history pop has settled so the tab switch is not
traversed over.

* fix: keep keyboard focus in the notifications panel across re-renders

Every change to the list rebuilds its rows, which dropped focus to the
document body: dismissing an entry with Enter threw the keyboard out of
the dialog (the row it had just been moved to was replaced), and so did
any arrival while an entry was focused. Put focus back on the same entry
after a render, or on the one that took a dismissed entry's place, and
let Shift+Tab from the panel itself wrap to the last control instead of
leaving the dialog.

* fix: keep the notifications panel inside short viewports

The anchored panel is bottom-aligned with the bell and grows upward, but
its height was capped only by the viewport (560px or 100vh - 24px), not
by the room above the bell — on a short window the header ran off the
top of the page. Cap it to that room, so the list scrolls instead.

* fix: make notifications with nowhere to go inert in the panel

An entry with no target (a worker deploy result) showed a default cursor
yet, when clicked, was dismissed and took the panel with it — nothing
opened, the entry was gone, and the list had closed. Render such entries
as text with the ✕ as their only action; only share entries remain
buttons. The ✕ now names its notification for screen readers, since on
an inert entry it is the only focusable control.

* fix: stop a listing in flight from resurrecting dismissed notifications

The list is refreshed on open, on reconnect, and when the tab comes back
into view; a dismissal landing while that listing is in flight was undone
when it resolved, since the server's snapshot predates the ack. When the
listing also resolved after the server's own ack event, nothing removed
the entry again and it stayed until the next refresh. Leave out of the
reconciliation whatever was acknowledged — here or in another tab —
since the listing was requested.
2026-08-27 12:49:20 -07:00
Daniel Salazar 909949c68d fix: failed email alarms (#3651) 2026-08-26 23:22:14 -07:00
Juan Fernando Castro 5a6a1020a1 Merge pull request #3644 from HeyPuter/juancastro/put-1585-share-flag-in-readdir-shared-users-in-stat
🔧 PUT-1585: Share flag in readdir shared users in stat
2026-08-26 18:51:30 -04:00
Nariman Jelveh 7472002cf3 feat: add Hoonify AI chat provider (#3499) 2026-08-26 15:39:29 -07:00
Juan Fernando Castro 7bd6a2d89b Merge pull request #3646 from HeyPuter/juancastro/put-1590-sharing-shared-files-are-not-different-than-regular-files
🔧 PUT-1590: Mark shared items in the file listings
2026-08-26 17:55:19 -04:00
Juan Castro 3f7dac63b9 Merge remote-tracking branch 'origin/juancastro/put-1585-share-flag-in-readdir-shared-users-in-stat' into juancastro/put-1590-sharing-shared-files-are-not-different-than-regular-files
# Conflicts:
#	src/gui/src/UI/Dashboard/UIShareModal.js
#	src/gui/src/UI/UIWindowShare.js
2026-08-26 17:06:25 -04:00
Juan Fernando Castro 3d28b2bb99 Merge pull request #3647 from HeyPuter/juancastro/put-1586-1599-share-dialog-correctness
🐛 PUT-1586 + PUT-1599: Share dialog says what it can grant, and what it did
2026-08-26 16:58:36 -04:00
Juan Castro 63688f81b4 Merge branch 'main' into juancastro/put-1585-share-flag-in-readdir-shared-users-in-stat 2026-08-26 16:55:51 -04:00
Juan Fernando Castro 14ac6542e3 Merge pull request #3645 from HeyPuter/juancastro/put-1589-shared-file-fs-events-seem-to-be-lost
🐛 PUT-1589: Shared file fs events seem to be lost
2026-08-26 16:54:09 -04:00
Juan Castro 5739f4e59f fix: stop pushing file metadata to revoked recipients (PUT-1611)
The realtime fan-out resolved its audience straight from the `share`
index, which has no live-grant check. `/auth/revoke-user-user` deletes
the permission and leaves the index row, so a revoked recipient's socket
kept receiving name, size, masked path and mtime for every write and
move under the folder, with no expiry.

The service already solves this elsewhere — `#reachingHolders` returns
exactly the holder/entry pairs whose grant still stands, and
`listSharedWithMe` was moved onto it for the same reason. The realtime
path never got the same treatment; it does now.

Free on the unshared path: with no share rows reaching the entry there
are no holders to check, so the write path every user takes is unchanged.
Pinned by a test that counts permission reads.
2026-08-26 16:35:38 -04:00
Juan Castro cae51ce67a fix: trashing a top-level share is a removal, not a move
A grant on the entry itself is keyed on uuid, so it follows the entry
into the owner's Trash. Both ends of the move then resolved, and the
recipient was told the shared item had moved — to the GUID name Trash
gave it. Their own copy got renamed to a GUID and stayed on screen.

`shared-with-me` has always omitted trashed entries, so the listing and
the event disagreed; only the event was wrong. Trashing now reports
item.removed at the path the recipient knew, which is also what the
desktop's data-path selector needs to find the row. Restoring out of
Trash reports item.added.

A move that leaves the recipient's masked address unchanged now stays
quiet — a share masks its own root, so the owner shuffling it around
their tree is invisible to the recipient and the event carried nothing.
2026-08-26 16:25:02 -04:00
Juan Castro 8e622189ca fix: tell every recipient when a shared file disappears
Both ways a file can vanish were silent for anyone holding the folder
above it, so a third party's window kept showing a file that was gone
and 404'd on click.

A delete built its audience from the permission rows it removed, and a
file inside a shared folder has no grant of its own — only the folder
does — so the audience was empty. A move resolved its audience from the
entry's new path, and the GUI's Delete is a move to the owner's Trash,
where no recipient has a share.

Resolve the audience from where the entry was rather than from the
grants that went with it:

- Deletes also fan out to holders reaching the entry through an
  ancestor, coalesced by parent so a subtree stays a couple of queries.
  A holder covered by both passes is told once.
- Moves resolve both ends. Reaching both is item.moved, only the
  destination item.added, only the origin item.removed.

Recipients are named by the path they knew, masked through their own
share rather than the owner's tree.
2026-08-26 14:54:06 -04:00
Daniel Salazar c1c830fc32 docs: add puter site config docs (#3648) 2026-08-26 11:11:25 -07:00
Juan Castro cf00ebb9d4 Merge branch 'main' into juancastro/put-1589-shared-file-fs-events-seem-to-be-lost 2026-08-26 13:33:24 -04:00
Juan Fernando Castro b05ee63cb2 Merge pull request #3641 from HeyPuter/juancastro/put-1568-rename-srcguisrchelpers-files-to-camelcase
🧹 PUT-1568: Rename GUI helper files to camelCase
2026-08-26 13:06:58 -04:00
jelveh 40667bc811 Open Document Picture-in-Picture windows on behalf of apps
Browsers only allow documentPictureInPicture.requestWindow() from a
top-level document, and an app lives in an iframe, so an app calling it
gets NotAllowedError ("only allowed from a top-level browsing context").
The `document-picture-in-picture` token in the iframe's `allow` list does
nothing — it is not a policy feature the browser knows. Video PiP
(video.requestPictureInPicture) already works inside apps.

The GUI is the top-level document, so a new PictureInPictureService opens
the window for the app and fills it with an iframe of a page the app names,
which must come from the app's own origin (checked against the message's
origin, now carried on the IPC caller context). One window per app
instance; it closes with the app's window, and the app hears about a close
it didn't ask for. The window's opener is the GUI, so the page inside it
can reach its app's frame through parent.opener.frames and share objects
directly — a MediaStream included, which postMessage cannot carry (tracks
are not transferable between windows in Chromium).

puter.js gains puter.ui.requestPictureInPicture({ url, width, height,
onClose }) and puter.ui.exitPictureInPicture(), with docs.
2026-08-26 09:10:02 -07:00
Juan Castro 4b3d1112d1 Say when a share changed nothing
Sharing a file with someone who already had it answered "Shared with
X", the same as a first share, so the dialog claimed to have done
something it had not.

The service already knew — it computes isNew to decide whether to
notify the recipient — but the flag stopped at the controller. It now
travels on share results only; a listing describes standing access and
says nothing about it.

Which of the three things happened is settled client-side, since the
mode each recipient holds is already on screen: created access, raised
or lowered it, or changed nothing. That keeps the previous mode off the
wire, and an older backend that omits isNew still reads as a share,
which is what these dialogs said before.
2026-08-26 11:57:05 -04:00
Juan Castro 70edef561f Stop offering an access level a delegate cannot grant
A recipient given "can edit & share" could not pass that level on: the
dialog offered it, the server refused it, and the refusal was a bare
403 Forbidden that reads as a bug. Handing out manage needs authority
over manage, which only the owner has — the refusal is right, the dead
end and the silence were not.

The dropdown now withholds it from anyone who does not own the item; a
row already set to it keeps it, so opening the dialog cannot downgrade
the owner's own grant, and a mixed selection follows its strictest item.

The server says why, and only to someone who can already share the item
— a stranger still gets the ACL's own safe error, which does not admit
the node exists.

Verified against a running server: a delegate grants read and write as
before, and manage now answers cannot_delegate_manage with a sentence
naming the owner as the one who can.
2026-08-26 11:48:54 -04:00
jelveh e430ade7bd Reach Shared and Trash from the dashboard Files tab on phones
Below 480px the Files tab hides its directories sidebar, which was the only
entry point to Shared (a query, not a directory) and Trash (filtered out of
the Home listing). Home now carries a row for each; CSS shows them only at
the widths where the sidebar is hidden, using the complementary breakpoint so
the two never both show or both disappear.

The rows borrow the item markup for layout but aren't `.item`, so sorted
insert, selection restore, share-link selection and socket updates ignore
them. The footer count and keyboard select-all exclude them explicitly, and
the placeholder-removal sweeps leave them in place. They navigate on tap and
offer the same menu as their sidebar entry via the ⋯ button or long-press;
the Trash icon tracks empty/full alongside the sidebar's.

Also guard the `window.user.directories` lookup in renderDirectory: it is
undefined for some sessions, and since `puter://shared` doesn't look like a
path it always reached that branch, threw outside the try, and left the
spinner up with navigation stuck — from the desktop sidebar as well.
2026-08-26 08:18:13 -07:00
Juan Castro 519b132355 Inset the shared marker onto the icon glyph
It sat on the icon box's corner, which is 5px outside the artwork on
every side, so the dot read as clipped — half of it hanging over empty
padding with the icon's own drop-shadow falling across it. Nudged in on
both axes: 7px on the desktop, 2px on the dashboard rows.
2026-08-26 11:16:49 -04:00
Juan Castro b08dc70654 Move the shared marker onto the icon's corner and shrink it
Review feedback: too big, and in the wrong place. It sat in the badge
cluster, which the dashboard pins to the row's top-left corner rather
than to the icon — and at 12px it dominated a 24px row icon.

Now a dot on the icon itself, lower-right: 9px on the desktop's 45px
icons, 7px on the dashboard's 24px rows. Anchoring to .item-icon rather
than to the badge cluster is what keeps it on the corner at both sizes.

Dropping the people glyph with it — unreadable at either size, and
colour was the signal the ticket asked for.
2026-08-26 11:07:48 -04:00
Juan Castro a1d027e4a1 Mark shared items in the file listings
A shared file looked exactly like a regular one. The data to tell them
apart arrived with the readdir/stat share flag; nothing rendered it.

Adds the badge to both listings — UIItem (desktop, explorer windows,
file dialogs) and the dashboard's Files rows — fed from is_shared, and
keeps it in step with the share dialogs: both funnel every grant, mode
change and revoke through one render, so the badge follows without
waiting for a re-listing.

Inherited access is deliberately not badged. It is a state of the folder
that was shared, so marking every file inside would repeat one fact on
hundreds of items; the backend flag is direct-only for the same reason.

The icon (owner-shared.svg) and the strings (item_shared_by_you, in 40
locales) were already in the tree, unused — only the wiring was missing.
The blue ring is doing the work: list view shrinks badges to 8px, where
a glyph is illegible and the white circle the sibling badges use
disappears into the row.
2026-08-26 10:56:10 -04:00
jelveh defa37c106 Fix dashboard files tab mobile scrolling
Replace the Files tab's viewport-height sizing with flex-based layout sizing through the dashboard content chain. This keeps the internal file list within the visible content area on mobile browsers, preventing the bottom rows from being clipped when browser toolbars are shown.
2026-08-26 07:42:44 -07:00
Juan Castro 1514ab3cb5 Ignore fs events replayed by replication
Raised in review: could an event from another node re-trigger the
fan-out? Not today — broadcast carries outer.* and pubsub.* only, so
fs.* never crosses a node boundary, and the emitted outer.gui.* is
consumed on the peer by SocketService while ShareService listens to
fs.* alone, so nothing re-enters.

That safety is a property of what broadcast happens to replicate, which
is not this service's to rely on. The handlers now skip anything tagged
from_outside: the node that did the write has already told the audience,
and a second fan-out would only duplicate it.
2026-08-26 09:22:49 -04:00
roar_zx ca25915a38 docs: link Dutch and Odia README translations (#3635) 2026-08-26 00:59:16 -07:00
Juan Castro ee2b5adcf9 Tell share recipients about creates and renames
A recipient's client keeps its cache fresh from fs events pushed over
their socket, and ShareService fans those out to holders — but only for
write, move and delete. A new entry emits fs.create.<flavor>, not
fs.write.file, and an in-place rename emits fs.rename; neither had a
listener, so a recipient watching a shared folder never learned that a
file appeared in it or was renamed. Part of why: those keys and
outer.gui.item.renamed were missing from the typed event map, so a
listener for them did not compile.

Delivering the event is only half of it. Paths were masked against the
entry itself, so item.added named a parent no cached listing was keyed
on, and the payload carried no dirpath, which is how the desktop finds
the container to render into — the event would have arrived and changed
nothing. Paths are now masked at the share the holder reached the entry
through, which is the address their own reads returned, and from_path on
a move and old_path on a rename travel the same way (dropped when the
move started outside the share, self-masked when the share is on the
entry itself, where the root already carries the new path).

Creates fire per entry, so an upload would have cost one share lookup
per file; they are coalesced by parent folder the way subtree deletes
already are. Measured on a 25-file burst into one folder: 25 lookups
before, 1 after. A holder with a share on both a folder and something
inside it is told once, by the nearer of the two.
2026-08-25 19:38:38 -04:00
Juan Castro 2ef5d00d9b Type is_shared and say who the flag counts
stat() and readdir() return FSItemRead, so the is_shared the docs lead
with typechecks for TypeScript consumers rather than erroring on FSItem.

The docs said "you have shared", but the query has no issuer predicate:
a manage delegate's re-share sets the owner's flag too, which is the
useful answer and matches getShares().
2026-08-25 18:15:15 -04:00
Juan Castro bac3dde945 Forget cached entries when sharing changes
Nothing invalidated the SDK entry cache on share or unshare — the socket
handlers only fire on item mutations — so is_shared, which now rides in
the cached entry, stayed stale for every consistency: 'eventual' read.
That includes the GUI's own listing refresh, which defaults to it, so a
badge would not have appeared until an unrelated write flushed the cache.
2026-08-25 18:15:05 -04:00
Juan Castro 1600dc38a5 Retire the share index row with the grant it records
revoke-user-user withdraws a grant without touching the share index, so
the row outlived the access — invisible until now, because listSharesOf
filters against live grants, but the new flag reads the index and would
report a file as shared to nobody, permanently.

Drop the row where the grant goes. The alternative, filtering liveness on
the read side, is the per-entry work the flag exists to avoid.
2026-08-25 18:14:52 -04:00
Juan Castro 0c8dd8b6e4 Document the share flag and returnShares 2026-08-25 17:45:15 -04:00
Juan Castro 3217533594 Give the puter.js API suites rate-limit headroom
Around 500 tests run through one seeded free-tier account, so the
per-tier windows were throttling the suite rather than anything it
tests — adding a single readdir was enough to trip fs:readdir-burst.
Resolve the seeded users to the unlimited policy, alongside the
subscription gate the harness already turns off for the same reason.
Test config only; no published limit changes.
2026-08-25 17:44:56 -04:00
Juan Castro 0591f13cc2 Expose is_shared and returnShares in puter.js
Carry the flag into the v1 entry shape and add returnShares to stat(),
whose shares are mapped into the same Share objects getShares() returns.
returnShares joins the dedupe key and bypasses the entry cache in both
directions — a result carrying share data is never written to it, so a
later plain stat cannot serve other people's names from cache.
2026-08-25 17:44:50 -04:00
Juan Castro ee2f14576b Report sharing in stat and readdir
isShared on /fs/stat and /fs/readdir, is_shared on their legacy
counterparts, and return_shares now fills the shares array the legacy
stat has been stubbing with []. Null for entries the caller does not own,
so a share recipient is never told who else can reach the owner's files.
The share-to-wire mapper moves out of ShareController so both controllers
publish one shape.
2026-08-25 17:44:41 -04:00
Juan Castro 5115fdd48c Answer which entries are shared in one indexed query
Directory listings need a shared/not-shared flag per entry. Ask the share
index once per batch, chunked, rather than a query per entry, and answer
only for entries the caller owns so listing a foreign directory never
queries at all. Direct shares only — inherited access stays with
listSharesOf, which already reports it.
2026-08-25 17:44:25 -04:00
jelvehandClaude Fable 5 e006b19773 puter.peer: room names, relayed guest grants, servers that come back
A peer server could only be reached by the invite code the signaller
minted for it, which is unknowable ahead of time and dies with the
server's socket. Any app that wanted a link to share in advance or reuse
had to run a registry of its own that maps a stable code to whatever
invite is live — and keep it live, since the signaller socket can drop
without the library saying a word (`onclose` was an empty function),
leaving a host serving an invite nobody can dial.

`serve({ name })` serves under a room name of the caller's choosing;
`connect(name)` dials it. A name is held by whoever serves it and free
once they stop; serving a held name from another identity rejects with
`name_in_use`, from the same identity it takes over. A connection to a
room nobody serves fails with `no_host`, so a lobby has a definite answer
to poll on instead of guessing between "not yet" and "gone".

`serve({ guestGrant })` and `server.setGuestGrant()` leave a guest grant
with the signaller, which hands it to every anonymous guest in the connect
reply; the connection redeems it before making its offer, so a guest with
no session gets relays without the app publishing the grant anywhere.

A server whose signaller socket drops now re-registers on its own with
backoff — under the same name, or a fresh code announced by the new
`reconnect` event — and pings the socket to keep idle proxies from cutting
it. It fires `close` (`replaced`, `name_in_use`) when it has to stand
down for good. Existing connections are peer-to-peer and never affected.

Signaller refusals reach the connection's `error` event as an Error with
a `code` next to the message. Keepalive replies and stray frames no longer
throw in the message handlers.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-25 13:24:45 -07:00
Juan Castro 07e73efa40 Merge remote-tracking branch 'origin/main' into juancastro/put-1568-rename-srcguisrchelpers-files-to-camelcase 2026-08-25 15:10:29 -04:00
404oops 2a45a10854 Merge pull request #3630 from HeyPuter/FK/dedupe
refactor: dedupe model catalog aliases and stop mutating shared catalogs
2026-08-25 18:07:27 +02:00
Nariman Jelveh e052aec7fb Carry a share link through the OIDC round trip (#3642)
A share email lands on `/?shared=…`, and its recipient is signed out or
in a temporary session more often than not. Password login reloads the
same URL, so the link came back with it — but an OIDC login leaves the
origin and returns to a URL the backend builds from a whitelist of bare
paths. `return_to` was a pathname only, and `/` wasn't on the list, so
the recipient came back signed in on the Dashboard's Apps tab with
nothing to say what had just been shared with them.

`shared` now travels with the path. The GUI sends it along with the
return path; the backend accepts it as the one parameter a `return_to`
may carry, and only values shaped like the masked share path the mail was
built from — everything else rejects the whole value, the path is still
matched as a raw string so a protocol-relative one can't smuggle an
origin through, and the query is rebuilt rather than reflected. The items
ride onto the error page too, so a failed attempt retries on the link
instead of losing it.

The root joins the whitelist for this, but only when it names something:
on its own it is where the flow already lands.
2026-08-25 08:42:47 -07:00
Daniel Salazar cf4d743854 fix: testing for peer (#3643) 2026-08-25 08:31:45 -07:00
Daniel Salazar 3c866c645b feat: guest turn for peer (#3640) 2026-08-25 07:51:02 -07:00
Juan Castro 4a5d689af7 refactor: rename GUI helper files to camelCase
src/gui/src/helpers was mostly snake_case, disagreeing with itself and
with the camelCase file convention in AGENTS.md. Rename the 45 offenders
with git mv and repoint every import specifier at the new paths.

Files only — exported symbols are unchanged. applyItemAddedToContainers.js
still exports apply_item_added_to_containers and no call site is edited
beyond its import line; those identifiers cross module boundaries and some
hang off window, so renaming them is a separate, riskier change.
2026-08-25 10:49:59 -04:00
jelveh 6f1548e26a Move Share above Download in file context menus 2026-08-25 07:28:53 -07:00
Daniel Salazar 764ce2f8e2 feat: rep score middleware gateway (#3639) 2026-08-25 07:11:41 -07:00
Daniel Salazar 717c098503 fix: metering buffer improvements for manual editing (#3633) 2026-08-24 18:36:43 -07:00
Nariman Jelveh 2c9a5c4f7e Land share-email links in the Dashboard's Shared view (#3634)
* Land share-email links in the Dashboard's Shared view

A share email's links opened the item on the desktop, and "Open Puter"
went to the bare origin — the recipient arrived on Home with nothing to
say what had just been shared. Every link now lands in the Dashboard's
Files tab, on Shared, with the shared items selected.

Each named file still links to itself. "Open Puter" carries every item
in the mail (?shared=a&shared=b), so the whole batch lands highlighted;
the digest records now keep each item's masked path for that. The
button's href is rendered raw like the item links, so `=` and `&` read
the same in the html and text parts, and the unsubscribe link is built
from a separate origin value.

On the GUI side `/?shared=` boots the dashboard rather than the desktop;
`/desktop?shared=` keeps opening the item in place. The Files tab
selects the rows by uid, which survives a rename. A share only reaches a
real account, so a share link never mints a temp user and an existing
temp session is asked to sign in first, as the desktop already did. The
address-bar cleanup both shells need moves into a helper.

* Keep the share email's button link within what mail clients tolerate

The "Open Puter" link names every item in the mail, capped at twenty. But
a single item's parameter is ~150 characters once the owner, uuid and an
encoded name are in it, so twenty of them run to several kilobytes — past
the ~2000 characters where older mail clients cut a URL off or stop making
it clickable — and the count alone couldn't do what its comment promised
for the mail's primary button.

Add a length budget beside the count: items go in, in digest order, only
while the whole link stays under it, so the button always works and the
first items are the ones highlighted. A single item always fits.

* Keep a share link's own item however long its name runs

`shareDeepLink` now builds through `sharedViewLink`, whose length budget
applied to the first item too: a parameter that alone overran it was
dropped, and the link came out as a bare `?shared=`. A name of a few
hundred characters — the GUI allows five hundred, and encoding triples
every non-ASCII one — was enough, so that item's own link in the mail
landed on Shared with nothing picked out, where it used to open the item.

The first item now always goes in; the budget only decides how many more
join it. One long link is still the item the mail is about, and it is no
worse than a bare origin for the clients that truncate it.
2026-08-24 17:01:55 -07:00
jelveh 34af8d18d0 Share a whole selection from the Dashboard's Files tab
Sharing was one item at a time: the only way to give someone four files
was to open the dialog four times. A multi-selection now offers Share in
its context menu and in the mobile selection bar, and UIShareModal takes
a list of items.

With several items the access list folds into one row per person rather
than repeating per file, so a grant, a mode change or a revoke is one
decision about a person. A row says what it can't otherwise show: how
much of the selection the person reaches ("On 2 of 4 items", with an
"Add to all" that extends them), a mode select that rests on a
placeholder when their grants disagree rather than presenting one item's
mode as the batch's, and inherited grants left uncontrollable where they
belong. Changing a mode touches only the items the person already holds
— nothing here widens access without saying so.

Requests are chunked to the documented 50-items-per-request cap, and a
selection past it skips the per-item listing instead of firing one
request per file on every refresh.

The eligibility rule the Share entry already used moves into a shared
can_share() helper, since the multi-select menu needs the same answer
for every row.
2026-08-24 14:08:37 -07:00
Juan Fernando Castro 0527bcd98e Merge pull request #3632 from HeyPuter/juancastro/put-1560-file-sharing-deeplink-in-emailnotifications
🔧 PUT-1560: Deep-link the shared item from email and notifications
2026-08-24 12:30:07 -04:00
Juan Castro ea530e604c Merge branch 'main' into juancastro/put-1560-file-sharing-deeplink-in-emailnotifications 2026-08-24 12:21:21 -04:00
Juan Fernando Castro 97d137b94b Merge pull request #3623 from HeyPuter/juancastro/put-1564-perms-docs-drop-the-app-root-dir-raw-permission-string-wire
🛠️ PUT-1564: Perms docs — drop the app-root-dir raw string, wire the playground examples
2026-08-24 10:59:56 -04:00
jelveh 1ceffbe291 Add sudoku to recommended apps
This change adds Sudoku to the curated recommended apps list so it appears alongside the other bundled games in the app recommendations flow.
2026-08-23 21:59:52 -07:00
Daniel Salazar 684d6752f9 fix: provide fallback for signup verification (#3631) 2026-08-23 21:49:35 -07:00
jelveh 76cea02513 Treat .md like .txt; remove markus suggestion
Merge the .md extension case into the plain-text branch so it suggests ['editor', 'code'] instead of ['markus', 'editor', 'code']. Update the related test to use 'viewer'/'png' as the built-in guard example since 'markus'/'md' no longer applies.
2026-08-23 21:17:28 -07:00
404oopsandClaude Fable 5 308b78e96c refactor: dedupe model catalog aliases and stop mutating shared catalogs
- Add modelLookupNames() and route every provider's list() through it so
  repeated or self-referential aliases can't double-list a model.
- Stop the chat/image/video drivers' #buildModelMap from writing through
  to the module-level catalog constants (ids/aliases accumulated across
  instantiations); bucket copies preserve the models() wire shape.
- Remove self-aliases and exact duplicates from the claude, deepseek,
  groq, mistral, and openai catalogs; fold the duplicated
  gemini-3.7-flash entry — this corrects the live cached-token price
  from 8 to 7.5 and the knowledge date to 2026-03 (the previously
  effective first entry carried stale values).
- ClaudeProvider: derive default max_tokens from the resolved entry
  instead of a second name-based lookup that capped dated ids at 4096.
- Add cross-provider catalog invariants (modelCatalogs.test.ts) with a
  disk-scan registration guard, plus regression tests for catalog
  non-mutation, alias-dedup routing, wire shape, and max_tokens ceilings.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-24 03:42:47 +02:00
nevrkla 2d787c3fdf feat(i18n): add Czech GUI localization (#3617)
* feat(i18n): add Czech GUI localization

* feat(i18n): add Czech GUI localization

* fix(i18n): polish Czech GUI translation
2026-08-23 17:22:44 -07:00
Daniel Salazar 5918e3f4e2 fix: kv max number value (#3629) 2026-08-23 06:31:08 -07:00
Nariman Jelveh 2c9e818e5f Docs/remove discord reddit links (#3628)
* docs: remove Discord and Reddit links

Drops both links from the docs README (header row and Support list) and
from the footer generated on every built docs page.

* docs: remove Mastodon link
2026-08-22 22:14:56 -07:00
Nariman Jelveh 8826a9fc51 Remove Discord and Reddit links from README (#3627)
Removed links to Discord and Reddit from the README.
2026-08-22 13:07:33 -07:00
Daniel Salazar 8307e8c9f0 chore: bump up deps (#3626) 2026-08-21 21:03:54 -07:00
Daniel Salazar 732786a029 fix: clean up email validation (#3622) 2026-08-21 20:27:05 -07:00
Juan Castro 202c43f46e feat(share): deep-link the shared item from email and notifications
A share email named the file but had nowhere to go: the only link was "Open
Puter", and finding what someone shared meant hunting for it under Shared. Each
named file in the digest now links to itself, and a notification covering a
single item points at that item.

The link carries one parameter, the masked path a recipient is already given:

    https://puter.com/?shared=%2Falice%2F<uuid>%2Freport.txt

Its second segment is the uuid, so there is no second copy of it to disagree
with the path, and the GUI can still find the entry when a rename has left the
name segment stale - it stats the path, then falls back to the uuid.

Built from the owner, uuid and name rather than from `ResolvedShare.path`.
That path is masked for whoever made the request, and the issuer owns the
entry, so it comes back as the owner's *real* path - mailing it would tell the
recipient which folders the owner keeps things in, which is the one thing
masking exists to prevent. A test asserts the real path never reaches the mail.

`digestLines` now returns `lead`/`items`/`trail` beside `what`, so the template
can put an anchor around each name while Handlebars keeps escaping the names
themselves; the URL is machine-built from the configured origin and one encoded
path, so it stays literal. Concatenating the parts reproduces `what` exactly,
which a test pins - the linked and sentence forms must not describe different
shares.

Notifications carry the masked path rather than a URL: the recipient is already
in the GUI, which opens the item in place instead of reloading. Only a
single-item notification gets a target; folding into a group drops it rather
than picking one of five.

In the GUI, `?shared=` joins `?download=` and `?app=` as a param that keeps the
desktop booting at `/`, and the handler reuses the `/@user` public-folder flow -
extracted to `open_path_target`, which carried a TODO asking for exactly this -
so a file opens in its associated app and a folder in an explorer window. The
param is stripped from the address bar first, so a reload lands on the desktop
rather than opening the item twice.

Invites are deliberately not linked: there is no account to route to yet, and
the invite's own call to action is to create one.

Rolling-deploy safe: a digest entry queued before this has `names` and no
`items`, and still flushes - without links. New entries write both, so a node
on the previous build can flush them too.
2026-08-21 16:08:39 -04:00
Juan Castro e7be457a56 docs: redirect the retired perms pages, add the missing playground examples
Both were left as follow-ups on the previous commit.

Thirteen `puter.perms` method pages went when the surface collapsed onto
`request(resource, details)`, and `requestAppData` moved to `/Perms/appData`.
All fourteen had shipped, so an external link or a bookmark landed on nothing.
The build already generates meta-refresh redirects from a map; they are entries
in it now. Pages that only ever existed on the branch that removed them are
deliberately absent — nobody can hold a link to a URL that was never published.

Six documented APIs annotated a code block with a playground id but had no
example file behind it, so the build warned on every one and the Try-it link
resolved to nothing: `fs.share`, `fs.unshare`, `fs.listShared`, `fs.getShares`,
`ai.txt2speech` with Speechify, and `ui.showFeedbackDialog`. The files are the
documented blocks themselves, extracted rather than rewritten, so the example
and the page it appears on cannot drift. Each is indexed in `examples.js` beside
its siblings.

The build now runs clean: 12 warnings to none.
2026-08-21 11:26:32 -04:00
Juan Castro 9bf49b7574 docs(perms): drop the app-root-dir raw string, wire the perms playground
`app-root-dir:` was listed among the raw permission strings, but it reads as
nothing during a permission check - the rewriter yields the sentinel outside a
grant, so `check()` reports it ungranted even once it is and `request()` prompts
every call. Both contradict what the same page promises. The `'appRootDir'`
resource is the supported path and asks the server instead; the list now says so
rather than implying the string behaves like its neighbours.

The playground listed no perms examples at all: six files existed but nothing
referenced them in examples.js, so a freshly-reshaped API shipped with nothing
runnable. Adds a Perms group after UI, matching the sidebar's order, and two
examples for the features that had none - one prompt covering several resources,
and check() deciding whether to prompt.
2026-08-21 10:20:05 -04:00
f0cd251626 🛠️ PUT-1521: Cleanup puter js permissions api + backend routes (#3607)
* refactor(puter-js): collapse puter.perms request* to resource + access

Fifteen request methods differed only by a folder name or an access level, so
every new resource meant another method. Replace them with requestFolder,
requestApps, requestSubdomains and requestAppRootDir, each taking the access
level as an argument.

The old names stay as @deprecated aliases: puter.js ships unpinned from
js.puter.com/v2, so removing them would break live apps. They remain in the
generated declarations because stripInternal has no effect on declarations
emitted from JavaScript, and hand-omitting them would break TypeScript callers
the runtime still serves.

Also drops the user-to-user and user-to-group grant wrappers (groups.js and the
grantUser/grantGroup half of grants.js) plus the req_ shim, none of which were
documented or called. The app, origin and dev-app grants stay: the dashboard
uses puter.perms.revokeApp() to clear grants on app uninstall.

* docs(perms): document the collapsed puter.perms surface

Replace the twelve one-method-per-task pages with requestFolder, requestApps
and requestSubdomains, and rewrite the Perms overview around the seven public
methods. The deprecated aliases keep working but are no longer documented.

Boy Scout: drops the long-dead commented-out grantUser/revokeOrigin sidebar
block for pages that were never published.

* refactor(perms): drop unused user-to-user and user-to-group permission routes

Filesystem access is shared through /share, which records the grant so the
owner can see and revoke it. The older direct-grant paths were left behind with
no caller anywhere - not the GUI, not a doc, not an app: grant-user-user
(already a 501 stub), revoke-user-user, grant/revoke-user-group, and the five
/group/* CRUD routes.

Removing them orphans PermissionService.grant/revokeUserGroupPermission and its
group-members cache bump, the three PermissionStore group writers, and six
GroupStore methods, so those go too.

What stays, and why:
- grant/revokeUserUserPermission - ACLService and ShareService power fs.share
  through them.
- The group permission read path (#scanUserGroup, readUserGroupPerms) - a
  migration seeds the admin group unrestricted driver access, so it is
  load-bearing.
- GroupStore getByUid/addUsers/removeUsers - signup, save_account, OIDC and the
  self-hosted default user assign group membership.

No schema change: user_to_user_permissions, user_to_group_permissions and their
audit tables are untouched. Group rows now come only from migrations, so tests
that need one seed it with SQL the way a migration does.

* refactor(perms): reduce GroupStore to membership writes

With the /group/* routes gone, `getByUid` had no production caller left — the
routes were the only thing that read a group back. Removing it takes the row
decoder and the GroupRow type with it, since they exist only to shape its
result.

What remains is `addUsers`/`removeUsers`: signup, save_account, OIDC and the
self-hosted admin bootstrap all assign group membership. Permissions attached to
a group are read through PermissionStore, which joins the junction table itself
and never needed the store.

Tests that wanted a group id now select it, which is all `getByUid` was doing
for them.

* chore(perms): drop the three by-hand groups no code reads

freeai, experimental and dangerous exist in prod but in no migration — they
were added by hand when hardcoded permissions were keyed by group name. That
map is now a flat per-user floor (`default_user_permissions`), so a group
nothing looks up grants nothing.

Guarded rather than unconditional, because both tables the delete can reach
cascade: dropping a group that still carries permissions or members would
silently revoke them from every member. Only a group with neither goes. One that
survives has dependents and needs a deliberate decision — query
user_to_group_permissions by group_id to see what it holds.

system, admin, user and temp are untouched: config names two of them and code
names the others.

Matches on `extra.name`, not `metadata.name` — `metadata` carries the display
title and colour, and `critical: true` is set on all of these including freeai,
so it does not discriminate.

* feat(puter-js): collapse puter.perms onto request(resource, details) + check()

One method per task meant a new method, doc page and sidebar entry for every
resource. `request` now takes the resource and a payload whose accepted fields
depend on it, and `check` answers the same question without prompting.

    request('folder', { name: 'Documents', access: 'write' })  -> path
    request('apps', { access: 'read' })                        -> boolean
    request('email')                                           -> address
    check('folder', { name: 'Documents', access: 'write' })     -> boolean

Returns stay per-resource: a folder gives its path, email the address, the rest
a boolean, and anything denied is falsy so one `if` covers both.

An array asks for several at once. Everything already held is settled first, so
the prompt covers only what is missing and does not appear when the whole set is
held - the user answers once for the lot. `check` answers per entry, in order,
so a caller can tell which parts are missing rather than only that some are.

Each resource declares four things in one registry entry: how to ask for it
alone, whether it is held, the strings a batch pools into a prompt, and the
value once held. The strings themselves are defined once in
lib/permissionStrings.js, so a request and its check cannot name them
differently. `check` is built on /auth/check-permissions, already live and
already used by UI.js, and it throws rather than answering false when the check
cannot run: a caller that cannot tell "denied" from "never ran" would prompt
someone who had already granted it.

Backward compatibility: all 22 older methods stay callable and typed, marked
@deprecated with the call that replaces them. A lone string still routes to the
raw-permission path - no resource name contains a `:` and every permission
string does, so the two forms cannot collide. The grant/revoke app methods are
untouched; the consent dialog and the dashboard's uninstall path use them.

Also drops three copies of the access-level assertion onto one shared
validator, and gives `appRootDir` a non-prompting server probe, since
`app-root-dir:` only resolves while a grant is being written and a permission
check on it always answers false.

* docs(perms): document request() and check() as the perms surface

Five per-method pages became one `request()` page carrying the resource table,
the batch form and the raw-string escape hatch, plus a `check()` page. The
overview is rewritten around the two methods.

requestAppData's page is re-homed as /Perms/appData rather than deleted - its
scope table, private-entry guidance and lifetime notes are not signature
documentation and have nowhere else to live. Inbound links from KV/set.md and
Objects/app.md follow it.

Playground examples move to the new call form. They are not wired into
examples.js, but an example demonstrating a deprecated method is worse than one
nobody loads.

* fix(perms): keep /auth/revoke-user-user as a deprecated route

Dropping this route with the rest of the unused user-to-user plumbing went too
far. The grant side is retired and stays retired - puter.fs.share() is the only
way in - but access those grants left behind has to remain withdrawable, and a
caller reaching the endpoint over HTTP directly had no replacement. Revoking can
only ever narrow what someone can reach, so keeping it carries no risk.

revokeUserUserPermission never left the permission service; it is load-bearing
for puter.fs.share(). This only re-wires the handler to it, with the gates it
always had.

Nothing in this repo calls the route, which makes it exactly what a later
cleanup reads as dead, so a test pins the registration and its gate alongside
the restored 400 and grant/revoke round-trip cases.

The 501 stub at grant-user-user and the never-called /group/* routes stay
deleted, as does puter.perms.revokeUser - puter.fs.unshare() replaces it and
falls back to live grants when no share row exists.

* fix(perms): let a write grant satisfy a read check on apps and subdomains

`apps-of-user:<uuid>:write` covers managing the user's apps, which includes
reading them, but nothing said so to the permission system. Prefix implication
only widens the other way — an `apps-of-user:<uuid>` grant covers both modes —
so a scan for `:read` missed a `:write` grant, and `puter.perms.check('apps')`
reported an app holding write as holding nothing. A batched request would then
prompt again for access already granted.

Adds the read-from-write exploder for both namespaces, mirroring
`fs-access-levels`. The widening runs one way only, and does not cross into
another user's namespace; both are covered by tests.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* fix(perms): answer the app-root-dir check without provisioning it

`/auth/request-app-root-dir` conflates two questions: may the caller claim its
root directory, and where is it. The second provisions `AppData/<uid>` on first
ask, so a caller that only wanted the first — `puter.perms.check('appRootDir')`
— created a directory by asking about it.

Adds `check: true`, which runs the same actor guard and stops at the answer.
A caller that may not claim it still gets the 403, so the flag can't widen
anything. Existing callers are unaffected: without it the route behaves exactly
as before.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* fix(perms): put request() and check() on one path

`request` dispatched to the old per-task methods while `check` asked the
permission tables, so the two answered different questions about the same
access. Concretely, before this: `request('folder', { access: 'write' })`,
`'apps'`, `'subdomains'`, `'appData'` and `'permission'` prompted every time,
whether or not the access was held — which the docs said they wouldn't;
`check('folder')` reported false for a folder the app could read through an ACL
grant that no `fs:` string names, so a batch prompted for it needlessly; a
batch entry for `'appRootDir'` skipped the post-grant retry the single call
does, resolving `undefined` after a grant that had in fact succeeded; and an
N-entry batch made N permission reads plus 2N `whoami` calls.

Both now run the same pipeline — resolve the permission strings, read what is
held once, prompt for the remainder, resolve each entry — with per-resource
hooks for the parts only that resource can answer. So a batch costs one
permission read and one `whoami`, a check reports exactly what a request would
skip the prompt for, and `'folder'` uses the same stat-or-permission reading in
both.

Also:

- A resource is looked up as an own property, so `request('constructor')` is
  the permission string it always was rather than a TypeError.
- A permission read that fails no longer decides anything: `request` falls
  through to the prompt it would have raised anyway, `check` throws. Before,
  `check('appRootDir')` folded a failed check into "not granted", which is what
  the documentation says must not happen.
- Drops `requestFolder`, `requestApps`, `requestSubdomains` and
  `requestAppRootDir`. They were added in this branch and immediately deprecated
  — never shipped, and `request()` no longer needs to route through them. The 22
  methods that did ship keep their exact behaviour, prompting without consulting
  what is held, which the suite now asserts alongside the new behaviour.
- Documents `'appRootDir'`, which was a supported resource in every overload and
  in `PermsResource` but named in none of the docs.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* fix(perms): act on review of the three preceding commits

- `src/puter-js/test/perms.test.js` still called `requestApps`,
  `requestFolder`, `requestSubdomains` and `requestAppRootDir`, which the
  previous commit removed. Four cases in the interactive browser harness threw.
  Pointed at `request(...)` instead.

- `request('appRootDir', …)` made two round trips where the shipped method
  makes one: a read-only probe, then the call that names the directory. A
  request is going to claim it either way, so the claim is now the check, and
  the entry it returns carries through to the result. `check` keeps the
  read-only mode, which is the reason that mode exists. Matters because the
  route sits on the FS_SIGN bucket, shared with signed-URL minting.

- `requestPermission` is one of the shipped methods, and the previous commit's
  message was wrong to say all 22 keep their exact behaviour: it forwards to
  `request`, so it now settles a permission the caller already holds instead of
  prompting for it. The value can differ, not just the prompt count — a user who
  would have clicked Deny on a re-prompt used to get `false`. It is the more
  honest answer (the app does hold the access, and denying a re-prompt never
  took it away), but it is a change, and the suite assertion had been switched
  to an unheld permission, which hid it. Asserted both ways instead, in the unit
  tests and the API suite.

- An entry that names no permission no longer rides a grant given for the other
  entries in the same call. Unreachable today — every resource either names one
  or reports itself held — but nothing pinned it.

- Reverted three type-union reformats in `LegacyFSController.ts` that a
  formatter had folded into the app-root-dir commit. That file was not
  prettier-clean to begin with; reformatting it is somebody else's change.

- Docs and types: `Perms.md`'s `appRootDir` row now matches `request.md`'s,
  `check.md` says that a `true` is per entry and a batch still prompts if any
  one entry is missing, and `types.js` no longer names `requestFolder` /
  `requestAppData` in prose that ships in the generated declarations.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

---------

Co-authored-by: Daniel Salazar <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-08-20 23:48:08 -07:00
ZHOU7821 943adae622 docs: use absolute link to router page in workers create docs (#3615) 2026-08-21 13:30:30 +07:00
Daniel Salazar 65572dcf23 fix: nicer sms card fallback (#3621) 2026-08-20 23:12:09 -07:00
ZHOU7821andZHOU7821 b3923f86da docs: fix typo in workers description (#3614)
Co-authored-by: ZHOU7821 <[email protected]>
2026-08-21 12:26:20 +07:00
Nariman Jelveh 729114bd09 Prioritize app-center in recommendations
Reordered the recommended app list so app-center appears earlier and dev-center is kept at the end. This keeps the default app suggestions aligned with the expected homepage/app-center placement without changing behavior beyond ordering.
2026-08-20 19:16:03 -07:00
Nariman Jelveh da1c85d3c5 Add Meetings to recommended app defaults
Include `meetings` in `RECOMMENDED_APP_NAMES` so it appears in the default recommended apps set alongside other core productivity tools.
2026-08-20 17:16:39 -07:00
Nariman Jelveh 66410d7f1f Revert "Let a browser send the device fingerprint header it is offered"
This reverts commit fef1337b2b.
2026-08-20 17:10:55 -07:00
Nariman Jelveh 76bd05f228 Dashboard: let the trial be a detail line, not an alarm
The Usage card gives each of its three columns a meter and two lines. The
plan column had a boxed, tinted, bordered paragraph instead — and at the
~230px a third of that card comes to, thirty words of it wrapped into a
five-line ribbon standing twice as tall as the storage and resources meters
beside it. The box is the shape we use for the dunning banner. A trial is a
date you should know about, not a fault, and it was reading as the loudest
thing on the card.

So it takes the slot its neighbours use for "n% of 100 GB": a quiet hint-
coloured line under the badge. All three columns now measure the same.

The copy stopped repeating itself while it was there. The badge said "ends
Sep 20" and the sentence beneath it said "ends on September 20, 2026" — two
elements, one fact, and neither of them answering the question someone
actually has, which is how much room is left to decide. The badge now
carries "31 days left" and the line under it carries the consequence:
"First charge Sep 20 unless you cancel." Billing keeps the full sentence and
the opt-out, and Manage is directly below.
2026-08-20 16:59:07 -07:00
Nariman Jelveh fef1337b2b Let a browser send the device fingerprint header it is offered
`fingerprint.ts` reads the device fingerprint from a request body or, for
authenticated requests with no body to carry it, from
`x-puter-device-fingerprint`. That header is documented there as "the
header the GUI may send the device fingerprint on for non-signup
requests", and the middleware has always honoured it.

A browser could never actually send it. The CORS allowlist in
`#installCors` does not include it, so the preflight comes back without
it in `Access-Control-Allow-Headers`, the browser abandons the request,
and `fetch` rejects before anything reaches the server. Nothing in tree
sends the header today, which is why this went unnoticed: the first
client to try it sees every call fail with a network error rather than a
readable status.

Adds the header to the allowlist, and a preflight test asserting the
browser is allowed to ask for it.
2026-08-20 12:40:48 -07:00
404oops 58794f4f76 feat: add MetaProvider for Muse Spark models and integrate with ChatCompletionDriver (#3616)
- Implemented MetaProvider to interface with Meta's Muse Spark models.
- Integrated MetaProvider into ChatCompletionDriver, allowing for dynamic model selection.
- Added unit and integration tests for MetaProvider to ensure functionality and reliability.
- Updated documentation to include Meta as a supported vendor for AI models.
2026-08-20 15:09:56 -04:00
Nariman Jelveh 9809e428b5 Update shared label in email template
Adjust the share-notification email copy to reference the current "Shared" files section instead of "Shared with me," in both HTML and plain-text variants. This keeps onboarding messaging aligned with the UI.
2026-08-19 20:05:56 -07:00
Nariman Jelveh eaddd1d44e redesign: share notification emails (#3612)
* redesign: share notification emails

The share digests were an unstyled fragment: a 520px div with a couple
of paragraphs, no preview line, no small-screen or dark-mode handling,
and an html-only body that left every text-only client reading a machine
down-conversion of the markup.

Both digests (`file_shared_with_you` and `file_shared_invite`) now render
through one layout: a 600px table column that goes full width under
600px, every color written inline so a client that drops `<style>` still
gets the design, with the stylesheet carrying only what inline CSS can't
express — the small-screen and dark-mode overrides. The shares are a
tinted panel of hairline-separated rows rather than loose text, the call
to action is a cell-padded button Outlook can draw, and the reason for
receiving plus the unsubscribe sit below the card where they belong. No
images at all, so nothing depends on an asset a client may refuse.

Templates may now carry a `text` part, and both digests do: it goes out
beside the HTML as multipart/alternative, which is what plain-text
clients, screen readers and spam scoring prefer.

Copy: a preview line that adds to the subject instead of repeating it, a
heading before the list, and an honest unsubscribe label — the link
silences notification mail account-wide, not just shares. The invite now
says what to do with the address and that an existing account can claim
the shares by confirming it.

Also drops `share_by_username` and `share_by_email`, unreferenced since
the digests replaced them.

* fix: widen the template map to the interface before compiling

`Object.entries` over the literal map yields a union with a distinct
type per template, and only the share digests carry a `text` part —
reading it off the union is an error the build tsconfig hides
(`noCheck: true`) and `npm run typecheck` catches.
2026-08-19 18:49:11 -07:00
Reynaldi Chernando 53b792c52c connect to worker's kv with cli (#3613) 2026-08-20 08:36:46 +07:00
Daniel Salazar 2dd7073034 fix: vscode webdav (#3610) 2026-08-19 14:04:56 -07:00
Daniel Salazar a552ce0b87 fix: better metrics for cache hit rates (#3609)
* fix: better metrics for cache hit rates

* chore: type + docs
2026-08-19 11:38:14 -07:00
Neal Shah c04827fd3f add dynamic worker create event (#3608) 2026-08-19 14:20:15 -04:00
Daniel Salazar 9debdffc5d fix: email send frequency + ai ordering (#3604) 2026-08-18 18:13:55 -07:00
Nariman JelvehandJuan Castro 57b4cbab66 feat(dashboard): rewrite Files-tab sharing as a from-scratch modal (#3598)
* feat(dashboard): rewrite Files-tab sharing as a from-scratch modal

The Files tab's Share… action opened UIWindowShare, a desktop UIWindow,
which doesn't fit the dashboard. Replace it with UIShareModal, built on
the same overlay pattern as UIItemPropertiesModal: a centered card on
desktop, a bottom sheet on mobile, styled with the dashboard's design
tokens (dark mode included).

Wiring follows the onShowProperties precedent: generate_file_context_menu
gains an optional onShare hook that TabFiles supplies; every other caller
falls back to the desktop share window unchanged.

Feature parity with UIWindowShare — grant by email/username with an
access level, list who has access (owner, direct, and inherited-from-
ancestor grants), change a grant's mode, revoke — plus:

- revoke confirmation inlined into the row instead of a stacked UIAlert
- real form semantics: Enter submits, button disabled until input,
  spinner while in flight, API errors keep the typed name for correction
- dialog a11y: focus moves in on open and back on close, Tab is trapped,
  Escape closes (first Escape cancels an open revoke confirmation),
  status messages announce via aria-live
- backdrop close keyed on where the press started, so a text-selection
  drag out of the input can't dismiss the dialog
- name-derived avatar colors and a loading state for the first fetch

Also fixes a double-encoding bug (shared by UIWindowShare) where mode
labels ran through html_encode twice, rendering "Can edit &amp; share".

* fix(dashboard): keep keyboard focus inside the share modal across re-renders

Changing a grant's mode, revoking, or Escape-canceling the inline
confirmation re-renders the access list (or disables the focused
control), which dropped focus onto <body> - outside the dialog's Tab
trap and invisible to screen readers. Focus is now restored explicitly
after each of those actions: to the same holder's control when it
survives, else to the dialog itself (tabindex=-1), and the Tab trap
steps back into the cycle when focus rests on the dialog container.
A failed grant likewise returns focus to the recipient input.

* fix(dashboard): give share modal controls 44px touch targets

On touch devices the close (32x32) and revoke (30x30) buttons and the
26px-tall per-row mode select were below the 44px minimum. On coarse
pointers the icon buttons now hit-test at 44x44 through a centered
pseudo-element (visuals unchanged, and the row spacing absorbs the
overhang without overlapping neighbors), and the row select gets
taller padding. Fine-pointer rendering is untouched.

* fix(dashboard): clear the iOS home indicator in the share bottom sheet

The app opts into viewport-fit=cover, so on notched phones the
bottom-docked sheet extends to the physical screen edge and its last
row sat under the home indicator. The sheet body's bottom padding now
adds env(safe-area-inset-bottom), matching how the codebase pads other
bottom-docked surfaces.

* fix(share): say 'Updated access' when changing a grant's mode

Changing someone's access level reported 'Shared with X', the same
message as a fresh grant, which reads as if a new share happened.
Both share dialogs now confirm mode changes with a dedicated
'Updated access for X' message. The UIWindowShare call also drops the
html_encode() around the recipient - i18n() already encodes
interpolations, so the wrapper double-encoded.

* fix(dashboard): align the share dialog's accessible name with the properties modal

The dialog's aria-label read 'name - Share' with an em dash while the
sibling properties modal uses plain 'name Properties'; screen readers
announce the dash as noise. Use the same name-then-noun pattern.

* fix(dashboard): ellipsize the share input's placeholder when it overflows

At phone widths the 'Add people by email or username' placeholder was
clipped mid-letter; text-overflow: ellipsis truncates it cleanly.

* fix(dashboard): raise the share selects' chevron contrast in light mode

The hardcoded slate-400 stroke measured ~2.6:1 against light surfaces,
below the 3:1 minimum for non-text indicators. Light mode now uses
slate-500 (~4.7:1); dark mode keeps slate-400, which already clears
5:1 there.

* fix(dashboard): stop Files-tab shortcuts from firing behind the share modal

The document-level keydown.tabfiles handler kept running while the
share (or item-properties) modal was open. With focus on any of the
modal's buttons or selects, Enter and Space were preventDefault-ed
before they could activate the control, arrows could not drive the
mode selects, and letter typeahead was hijacked into row typesearch —
while Enter opened the selected row behind the overlay, Delete moved
it to Trash, and Cmd+A/C/X/V acted on the hidden list. Yield the
keyboard to the modal for as long as one is up; its own handlers
already cover Escape and Tab.

* fix(dashboard): keep the on-screen keyboard down when the share sheet opens

Autofocusing the recipient input popped the keyboard over the bottom
sheet the moment it opened, hiding the access list before the user had
chosen what to do — the same reason the revoke flow already focuses
the dialog instead of the input. On touch-primary devices give the
dialog container initial focus (which also anchors the Tab trap);
desktop keeps the input autofocus.

* fix(dashboard): give the share sheet's confirm and submit buttons 44px touch height

The inline revoke confirmation's Cancel/Remove pair rendered ~29px
tall on touch — small targets 6px apart where one of the two is
destructive — and the submit button was fixed at 38px. Grow both to
44px under pointer: coarse, matching the standard the modal's icon
buttons already meet. The touch block moves below the confirm-button
base rules it now overrides, since a media query adds no specificity
and source order decides.

* fix(dashboard): name the person in the share rows' accessible labels

Every grant row's mode select announced as bare 'Access level' and
every revoke button as 'Remove access', so a screen reader user
tabbing the list could not tell whose grant a control changes. Carry
the holder in the aria-label ('Access level for alice' / 'Remove
access for alice'); the visible UI and the revoke tooltip stay as
they were. i18n() encodes the interpolated string as a whole, quotes
included, so the labels stay attribute-safe for any holder name.

* fix(dashboard): keep the share status region in the accessibility tree

* fix(dashboard): give the share modal's add-row controls 44px touch height

* refactor(gui): extract the share dialogs' pure logic into tested modules

* feat(dashboard): adopt the shared mode helpers and handle pending invitations

---------

Co-authored-by: Juan Castro <[email protected]>
2026-08-18 17:34:40 -07:00
Juan Fernando Castro 5e1645d40e 🔧 PUT-1524: Sanity check file sharing api (#3603)
* fix: sharing answers "who can reach this" from the grants, not the index

Two ways a share listing could name access that was no longer there.

A recipient's listing paired the flat permission read with the list of
permissions it asked for by array index. That read drops misses and
dedupes its keys, so the two are not positional: one entry's live grant
vouched for another entry that had none, and listShared() kept
publishing a withdrawn item's name, size and signed thumbnail URL to
someone who could no longer open it. Read the permission off the value
instead.

getShares() had the same gap from the owner's side, with no liveness
check at all — a grant withdrawn through /auth/revoke-user-user or an
ACL mode change left the index row behind, and the owner was told
someone could reach a file they could not. Checked against the grants
now, one batched read per distinct holder. Pending invites are not
subject to it: they have no grant yet, which is the point of them.

Also covers the access-token actor, which reaches the same reach bound
as an app through a different arm of the ACL check. No behavior change
there — it was correct and untested.

* test: pin that a revoke crosses regions

A revoke reaches a peer region as a replicated SQL delete plus three
invalidation events, one per cache the region owns: the u2u row cache,
the flat view and the scan generation. The delete alone changes nothing
there, and each cache has a different consequence if its event is lost
— 20s for the generation, 5 minutes for the row cache, and forever for
the flat view, whose grant-path entries carry no expiry.

Nothing covered the whole path end to end. The store tests prove each
event is emitted and applied; this proves the result, which is that the
recipient stops being able to read. It asserts the read still succeeds
after the SQL delete alone, so the test also records why replication is
not sufficient on its own.

* test: pin that a leaked uuid buys no access

A masked share path hides which folder an item sits in; it was never the
thing deciding who may open it. Nothing checked that at the route level,
so the guarantee rested on unit tests of the resolver alone.

Reads one shared file through its masked path, then tries the sibling
four ways: the shared uuid with the sibling's name, the sibling's own
uuid, a `..` back out of the root, and the owner's real path.

Worth knowing about this one: it's mutation-checked. Removing the head !== root.name guard in sharePathMask.ts fails it with reachable: /testuser/55dd54c0…/share-http-1df8933e.txt. I verified that specifically because two tests I wrote earlier in this chunk passed with their guards broken — both were vacuous, and I deleted them rather than commit false assurance.

* docs: say what listShared's total actually counts

`total` counts the shares recorded for you; items are filtered after the
page is read, so a withdrawn grant leaves the count higher than anything
paging will yield. The page description already explained the short-page
behaviour, but the field read as an exact count and the example printed
it as one.

The test pins the gap it describes: two shares, one withdrawn outside
the index, one item listed and a total of two.

* fix: keep an undelivered broadcast event instead of dropping it

The outbound queue was cleared before the send, so a peer that timed out
took its events with it. Most were survivable — a lost cache invalidation
heals when the entry's TTL lapses. A revoke's flat-perm invalidation is
not: grant-path entries carry no expiry, so a peer went on serving a
withdrawn grant until something else wrote that key.

Failed sends now go back on the queue, which the existing flush timer
retries. Anything queued since wins over the retry, and the queue is
bounded at 10,000 with the oldest dropped first, so a peer that stays
down cannot grow it without limit. Each retry is signed at send time, so
it is not rejected against the replay window.

* fix: stop plus-addressing from deciding who a share reaches
2026-08-18 15:51:23 -07:00
b795b219a8 ✨ PUT-1497: Share file link sharing and notifications (#3595)
* refactor(share): move share notifications into their own service

* feat(share): invite an address with no account, and email it

* feat(share): surface pending invites in the SDK and share dialog

* fix(share): unreachable revoke confirmation, and double-encoded labels

* feat(share): budget share announcements, group them, and let people block senders

Sharing had one defence against noise: a 15-minute quiet window per (sender,
recipient) pair, which dropped the second share rather than folding it in.
Twenty senders each under their own window could still bury someone, and there
was no way to make one of them stop.

Announcements are now budgeted on two axes through the existing sliding-window
limiter: 1 per 15 minutes and 20 per day from one sender, and 10 per hour /
50 per day to one recipient from anyone. Over budget the share still succeeds
and the recipient's notification is still brought up to date — only the
interruption is dropped. Invite email to an address with no account is budgeted
the same way, keyed on a hash of the canonical address.

Notifications now fold across senders: a new share rewrites the notification
the recipient hasn't dismissed, so "alice and bob shared 5 items with you"
replaces a stack of five. The record is written even when suppressed, so the
count is right whenever they next look.

Blocking is a new `user_block` table with enforcement in ShareService: a blocked
sender's share is refused with `recipient_not_accepting_shares`, spends no
quota, and writes no row, and their unclaimed invite is dropped when the address
is confirmed. Existing access is untouched — that is what revoke is for.
Managed from a Blocked people card in the dashboard's Security tab.

Also publishes the sharing limits, including the ones already on this branch
that were never documented.

* fix(share): name the item in share email, instead of 'an item'

* fix(share): make the invite lifecycle canonical, authorized, and race-safe

* refactor(email): drop EmailClient.isConfigured; callers read config.email

* feat(share): batch share email into a per-recipient digest, durably

* docs(share): document the share error codes; steady the disk migration tests

* fix(share): log why a digest wasn't sent, and recover orphaned ones

* feat(share): email recipients about shares by default, with a way to decline

Share email was off unless a deployment opted in, which meant an account
holder was told about a share in the app only. It is now on unless
`share_email_notifications` is set to false.

The reason it defaulted off was that nobody could decline. So this also
honors `user.unsubscribed` — the account-wide opt-out the /unsubscribe page
already writes and app feedback already respects, which share email ignored —
and the digest carries that link. Sharing and the in-app notification are
unaffected by it; only the mail stops.

The link is composed in the template around an interpolated uuid rather than
passed pre-built: Handlebars escapes interpolated values, so a whole URL came
out as `user_uuid&#x3D;…`, which browsers decode but link scanners and older
mail clients need not.

* fix(share): count every shared file in the digest, not just the first

* feat(share): let a recipient refuse shares from everyone

Blocking answered "not from this person" but had no answer to "not from
anyone", so the only way to stop a stream of unwanted shares was to name
each sender after they had already reached you.

Stored as a key in the user row's existing `metadata` blob rather than a
column: the share path already holds the recipient's row by the time it
asks, so reading it costs nothing, and a one-bit preference doesn't earn
a migration per dialect. `updateMetadata` merges and refreshes the cached
row, so the switch bites on the very next share.

Refusing everyone reports the same code as refusing one person — which of
the two it is is the recipient's business, not the sender's. Enforced at
both moments the per-sender block is: when the share is issued, and when
a pending invite is claimed. The per-sender list is untouched while the
blanket switch is on, so turning it off restores what it hid.

`GET /share/blocks` now carries `all`; `POST`/`DELETE` take `{ all: true }`
beside the existing `{ username }`. Managed from the same Blocked people
card in the dashboard's Security tab.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* fix(share): keep the digest sweep off a window that still has a timer

The sweep treated an entry as orphaned the moment its window closed, which
is also the moment the node that armed it fires. Claiming an entry is only
exclusive among flushers that can see each other's deletes, so the two
could each claim a share of the same digest and both send. It now waits
out a grace period first, which costs a genuinely stranded digest that
much delay and nothing else.

Both digest listings were capped at 200 with no word when they hit it — a
truncated flush sends a digest that undercounts and reads as complete.
The cap is named and logged.

Also: `#emailHolder` still described share email as off by default, which
it stopped being; the config doc said the batch window defaults to 60s
when it is 90; and the two tests that need several calls inside one window
were racing a 50ms window across four sequential round trips, so they
failed under full-suite load rather than on the behaviour they cover.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* fix(share): stop double-encoding the recipient in two dialog messages

`i18n()` encodes what it returns, replacements included, so encoding the
recipient first showed the entities to anyone whose address or username
contains one. Same pattern already fixed two lines above.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* fix(notification): widen the mysql shown/acknowledged columns

Both arrived from the v1 schema as `tinyint(1)`, where they were flags.
The backend rework changed the writes to a unix second; sqlite (`INTEGER`)
and postgres (`bigint`) took it and mysql did not, so on mysql every
`markShown` and `markAcknowledged` has failed with
ER_WARN_DATA_OUT_OF_RANGE and left the column NULL. Dismissing a
notification never stuck — the unacknowledged count never moved and one
already delivered came back on every reconnect.

No backfill: every reader tests `IS NULL` / `IS NOT NULL` only, so a
legacy `1` keeps meaning "yes" once widened. Guarded on the current type,
because changing a column type copies the table and this directory
replays on every boot.

Not reachable from the test suite — it runs against sqlite and postgres,
both of which already have the right type. Verified by hand against mysql:
`/notif/mark-read` and `/notif/mark-ack` now persist, and a dismissed
share notification is no longer the one a later share folds into.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

---------

Co-authored-by: Daniel Salazar <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-08-18 09:36:33 -07:00
Reynaldi Chernando 401b6066b3 Use gpt 5.6 luna as default for docs (#3602) 2026-08-18 09:36:23 -07:00
Daniel Salazar ec3c33fea6 fix: misc hardening fixes (#3600) 2026-08-18 00:06:58 -07:00
Anany Singh 95d797b047 feat(workers): expose app_uid in puter.workers.get and puter.workers.list (#3596) 2026-08-18 00:05:17 -07:00
Daniel Salazar bd06e88185 feat: bring back referrals PUT-1463 (#3599) 2026-08-17 23:49:09 -07:00
Nariman Jelveh cabedc30b0 Require login on app landing pages
Prevent first-time visitors from being treated as temporary users when they open an app landing page such as `/app/<name>` or `/desktop/app/<name>`. These routes now always go through the real login/signup flow.
2026-08-17 20:11:29 -07:00
Daniel Salazar f81b76c1d1 fix: webdav connectivity fixes for macos (#3597) 2026-08-17 19:02:55 -07:00
404oops 9604cc3f23 feat(ai-chat): overhaul provider model catalogs to match current APIs (#3586) 2026-08-17 14:06:44 -04:00
2c852bf6b3 ✨ PUT-1412 File sharing backend api (#3553)
* refactor(permissions): drop hardcoded group permission map for a flat default

* test(drivers): assert credential-gate intent instead of a 403 proxy

* fix(permissions): report whether a revoke removed anything and persist the linked grant row before the flat view

* feat(permissions): replicate permission invalidations across regions

* feat(share): extend the share table into an index of active shares

* feat(share): query and maintain active shares in ShareStore

* feat(users): add a batched lookup by email

* fix(cache): apply cache updates broadcast from peer regions

* fix(permissions): scope a revoke to the issuer that granted it

* feat(share): add ShareService with a per-day share limit

A share is two writes that belong together: the permission grant, which
authorizes access, and a share row, which makes it listable and ties it to an
fsentry so it dies with the file. Nothing else grants fs:* to a user.

Authorization reuses canManagePermission — an owner satisfies it through the
is-owner implicator, a delegate through an explicit manage:fs:<uid> grant. An
owner may clear any issuer's share of their node; anyone else only the ones
they issued, or their own access. Self-revoke skips the manage gate but still
requires `see`, so it cannot be used to probe for files.

The per-day limit counts shares created rather than live rows, so revoking and
re-sharing cannot recycle a slot, and changing an existing share's mode is not
new reach and does not spend budget. Tunable via share_daily_limit.

* feat(share): expose sharing over HTTP

POST /share, POST /share/revoke, GET /share/shared-with-me, GET /share/shares.
The controller was registered but entirely commented out.

Recipients × items fan out concurrently — every pair is a distinct
(holder, entry) key, so none of them contend — bounded by
runWithConcurrencyLimitSettled, which returns results index-aligned with the
input for the per-pair outcome list. Responses carry usernames only, never
internal ids, and the 404-not-403 rule is preserved so a failed call cannot
confirm a file the caller could not otherwise see. Notifications are fired off
the response path; a share must not fail over its own notification.

Per-request caps on recipients and items bound one call's fan-out; the daily
limit bounds the total.

* feat(share): keep recipients consistent when a shared item changes

* fix(fs): stop listing issuer homes at the filesystem root

* fix(acl): serialize concurrent mode changes on one node and pin app containment on shared paths

* fix(fs): expire signed URLs over entries the signer doesn't own

signFile defaults to a ~317k-year TTL and verifySignature checks only uid,
expires and signature — never the ACL. A recipient who ever signed a shared
file therefore held a permanent, revocation-proof URL to its bytes: revoking
the share did nothing to it.

signEntry now takes the acting user and drops to NON_OWNER_SIGNATURE_TTL_SECONDS
(1 hour) when the signer is not the entry's owner. Owners keep the permanent
default, so no existing client changes behavior.

The signature-authenticated directory listing bounds its children
unconditionally: that route has no session actor, and a signature proves
possession rather than ownership, so a recipient holding a short-lived
directory signature could otherwise mint permanent URLs for every child.

A bounded window is not revocation — the durable fix is a per-entry signature
epoch folded into the HMAC and bumped on any permission change.

* refactor(permissions): drop the unused permission-issuer lookup

listUserPermissionIssuers and its store method listUserPermissionIssuerIds
existed to synthesize the filesystem root from the home directories of everyone
who had granted the caller a permission. That listing is gone — it advertised
folders readdir then refused to open — and the share index answers "who shared
with me" directly, so nothing wants them back.

One removed test only asserted that the call returned an array; the other
covered readLinkedUserUserPerms round-tripping and is kept, rewritten without
the issuer lookup.

* fix(share): return the created share, not just an acknowledgement

* feat(puter.js): add file sharing to puter.fs

share(), unshare(), listShared() and getShares() on puter.fs, following the
existing FS operation shape: positional and options-object forms through
defineOperation, JSDoc overloads as the published signature, relative paths
resolved against the app's root directory.

A bare recipient string is read as an email when it contains @ and as a
username otherwise. Sharing an item with someone who already has it replaces
their access rather than stacking a second grant, so raising read to write is
one more call.

Adds a sharing suite to the API runner, which passes unchanged on node,
browser and workerd. Documents all four methods with runnable examples, and
corrects the FS overview callout that told readers one user cannot read
another's files — true before this, not after.

* feat(gui): add a Shared folder for items others shared with you

A sidebar entry listing everything other users have shared with you, backed by
puter.fs.listShared().

The path is the sentinel `puter://shared` rather than /<user>/Shared: this is a
query, not a directory, and a path-shaped value could collide with a folder
someone actually creates. refresh_item_container and update_window_path both
branch on it to skip the stat there is no fsentry for, and the listing swaps
readdir for listShared.

Entries render at their real paths under their owners' directories — the item
container already preferred an explicit fsentry.path over joining onto the
container, so nothing else had to change. Each carries who shared it and at
what level, which the context menu reads next.

* feat(gui): share items from the context menu

A sharing dialog shaped like its neighbours — options object, HTML-string
template, jQuery wiring, delegating to UIWindow() — with a recipient field, a
read/edit/share dropdown, and the current access list with revoke buttons.

Reached from a new "Share…" context menu entry, which is hidden on items shared
*with* you: re-sharing needs manage, so the dialog would only surface an error.

Those items get "Remove from Shared" in place of Delete. Delete moves an item
to *your* trash, which for someone else's file means moving their data out of
their tree — FSService refuses it, and the user saw a bare 403. Removing your
own access is what the action was reaching for, so that is what it now does.

* fix(share): withdraw what a removed recipient re-shared

* feat(share): report access inherited from a parent folder

* fix(gui): load the puter.js bundle the server configured

* refactor(gui): extract the action icon set into a helper

* feat(gui): surface Shared in the file browser

* feat(gui): manage access from the share dialog

* test(share): cover access inherited from a parent folder

* fix(share): keep downstream access from surviving a delegate who leaves

* fix(gui): name the real owner in the share dialog

* fix(gui): page through every shared item instead of the first 50

* feat(share): return item metadata with a share

* fix(share): invalidate a holder's cache when the entry is deleted

* fix(gui): treat items inside a shared folder as someone else's

* feat(permissions): let manage inherit down the filesystem tree

Access already reached descendants through the ancestor chain while authority did not, so someone trusted to manage a shared folder could re-share the folder but nothing inside it, and could not see who had access to a file within it.

A manage-inherits-from-ancestor implicator resolves it in the permission layer, beside is-owner, so every caller agrees rather than just ShareService. It consults only the immediate parent — resolving that re-enters one level up, making a chain of depth d cost d checks rather than d².

That makes two cascade gaps reachable, both fixed here. A revoke now walks the subtree, since a grant on a descendant can rest on authority held at the folder. And it stops at a delegate whose authority survives another issuer, because what they granted was never theirs to lose.

Also pins that manage is not transitive: granting it needs manage:manage:fs:<uid>, which only the owner holds, so delegation is one level deep by construction.

* fix(gui): offer sharing inside a folder you manage

The menus encoded "manage does not inherit" and would now hide an action that works. The Shared listing records each root's mode; the menus resolve a child's by longest matching ancestor, loading on demand so a deep link or restored window works too.

* fix(share): make the daily share limit hold under concurrency

* test(share): cover concurrency, measure cost, and name cases for what they verify

* fix(gui): import the ownership helpers the item menu calls

The single-item context menu handler calls is_owned_by_me and
shared_mode_for, but the imports were only ever added to
generate_file_context_menu.js — so every right-click on an item threw a
ReferenceError before the menu could build, and the non-owner Delete
gating never ran.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(share): authorize before resolving the recipient

share() looked up the recipient in parallel with the entry, before the
manage check — and the two failures carried different error codes. Any
verified user with a real entry uid could probe arbitrary emails and
usernames for account existence, at no quota cost. Resolve the entry,
authorize, and only then resolve the recipient: an unauthorized caller
now sees the identical safe 404 whether or not the recipient exists.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(permissions): broadcast permission row-cache invalidations to peer regions

Every publishCacheKeys call for the u2u, u2a, and access-token row
caches omitted broadcast, so a revoke only cleared the mutating
region's Redis. A peer region applied the replicated generation bump,
re-scanned, read the deleted row from its own still-warm 5-minute row
cache, and re-warmed the flat view from it — revoked access outlived
the revoke by the row-cache TTL instead of the intended 60-second
bound. CacheReplicationService already consumes these events; the
emits were just never sent.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(fs): refuse to rename an entry owned by another user

remove and move both refuse to act on an entry the caller does not
own, even when the ACL allows the write — rename had no such guard, so
a write-mode share recipient could rename the owner's file, or the
shared folder itself, rewriting the owner's whole subtree's paths.
rename now takes the acting user and applies the same policy.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(permissions): decide a flat delete from the primary, not a lagging replica

revokeUserUserPermission deletes the SQL grant, then only drops the
flat KV entry once no issuer still grants the permission. That
remaining-check read through the row cache the delete had just
invalidated, straight to a replica — under any lag the deleted row
reappeared, the flat delete was skipped, and the stale rows were
re-cached for another five minutes. Grant-path flat entries carry no
TTL, so the holder kept working access with zero SQL rows behind it,
invisible to every listing. The check now reads the primary and
re-warms the cache with what it actually saw.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(permissions): keep a failed remote flat-invalidation from crashing the process

The outer.permission.flatInvalidated applier was fire-and-forget with
no catch, and it awaits a KV delete — one transient KV error while
applying a peer region's revoke became an unhandled rejection, which
is process-fatal under default Node. Its sibling appliers were already
guarded; this one now logs and moves on, leaving the entry to the next
invalidation or its TTL, same as a lost event.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(share): revoke every requested item and recipient, not just the first

revokeShare destructured only the first recipient and first item while
the parsers accept arrays up to the request caps — unshare({items:
[a, b, c]}) returned success having revoked only a, leaving access the
caller believes is gone. Revoke now fans out over every (recipient,
item) pair exactly like POST /share, reports per-pair outcomes, and
sums the revoked count; the response stays backward compatible.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(share): only a confirmed email designates a recipient

Recipient resolution by email accepted unconfirmed accounts, so
pre-registering someone else's address (unconfirmed) was enough to
receive shares meant for them once no confirmed account held it.
An email now only resolves to an account that has confirmed it;
username shares are unaffected.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(share): accept tilde-rooted paths like the FS routes do

The SDK resolves relative paths to ~/..., but the share routes never
expanded the tilde — a ~-prefixed string was read as a uid and every
relative-path call 404'd. Item parsing now treats ~ as path-shaped and
expands it to the actor's home with the same helper the legacy FS
routes use, on share, revoke, and the shares listing.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(share): walk a directory revoke by parent linkage, not path prefix

listByFsentrySubtree matched descendants with fsentry_id = ? OR path
LIKE ?, which has two problems: fsentries.path is lazily backfilled
and NULL on old rows, so those descendants' shares silently survived a
directory revoke, and the OR'd predicates forced a scan of every
active share. A recursive CTE over parent_id — the same shape the
lineage resolver already uses — covers every descendant and runs on
idx_parentId_name.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(gui): give each item its own share dialog

single_instance keyed the dialog on the app id alone, so opening
Share… on a second file focused the first file's dialog — typing a
recipient there granted access to the wrong file, with only the title
hinting at it. The dialog is now instanced per path: same item
refocuses, different item opens fresh. Also stops pre-encoding the
title, which UIWindow encodes again.

Co-Authored-By: Claude Fable 5 <[email protected]>

* feat(permissions): let manage answer a write check

A manage grant let its holder re-share a folder but not work in it: the
ACL mode family stops at write, and the fs exploder had no rule for the
narrowest mode, so `manage:fs:<uid>` never satisfied `fs:<uid>:write`.

Fold manage into the candidate list for every non-manage mode, in both
the access-token branch and the scan branch, and give `write` an (empty)
exploder rule so the manage arm is emitted for it too.

* fix(fs): authorize restructuring by write on the parent

* fix(fs): let a share recipient work inside a shared folder

rename, remove and move refused outright when the entry belonged to
someone else, so a recipient with write could neither delete nor rename
anything inside a folder shared with them. The GUI compounded it by
hiding Delete for any item it did not own.

Authorize the three by ACL write on the entry's parent. For an owner
that is the same answer; for a recipient it grants the inside of a
shared folder and withholds the folder itself, whose parent is the
owner's private tree.

Deleting sends the item to its owner's trash rather than the deleter's,
so it leaves the recipient's view without leaving the owner's account
and without changing hands. A move may not otherwise carry someone
else's entry out of their tree.

* fix(fs): give a new entry to the owner of the folder it lands in

A file a share recipient added to a shared folder was recorded as
theirs while living in the owner's tree, so a subtree could hold rows
belonging to several people — and the storage it consumed was checked
against the writer while being counted against the owner.

Take the owner from the parent row at every insert, charge the
allowance to that owner, and hand a moved entry over to the tree it
moves into. An entry now always belongs to whoever owns the directory
holding it.

* feat(fs): address shared entries as ~/share/<uid>

A recipient could read the owner's whole path off any shared entry —
where they keep the file and what sits beside it, neither of which the
share is about.

Give shares their own namespace. `~/share/<entry-uid>/rel/path` resolves
to the real path on the way in, and outgoing paths are rewritten to it
on the way out. Entries the actor owns pass through untouched, so no
existing client contract moves.

* revert(fs): mask only the directory bar, not the addressing

fe535d598 made `~/share/<uid>` the actual address for every shared
entry. That reached far past the intent: item names became uuids, the
Shared views rendered uuids instead of filenames, and navigation
addressed entries through a namespace nothing else understood.

Put real paths back everywhere — responses, the share listing, and
request handling — and do the masking where it was wanted, in the
window's directory bar. A recipient sees `Shared › Contents › sub`
while every crumb keeps the real path it navigates to.

The share listing now carries the entry's name, content type, owner and
a signed thumbnail. A share row has no fsentry behind it for a client
to stat, and the stored thumbnail is an `s3://bucket/key` URI that no
client can render and none should see.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* fix: path obfuscation, webdav + small ui stuff

* test(share): assert the masked share path by its exact shape

The substring check tripped on the scratch files' own names, which start
with `sharing-`; the exact-equality assertion on `/<owner>/<uid>/<name>`
already proves nothing above the share leaks.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(share): rename policy, shared-view guards, webdav share parent, quota/bucket invariants

- Rename: a directly-shared FILE renames with write on it; a shared
  folder root stays fixed (its name is the owner's tree structure).
  GUI can_rename mirrors the backend, guards all editor entry points.
- Up from a share root goes to the Shared view on both surfaces; the
  Shared view gets a single crumb, a disabled Up button, and refuses
  drops, New/Paste, uploads and ctrl+V everywhere (it is a query, not
  a directory).
- WebDAV: PROPFIND on /owner/uuid answers as a virtual collection
  holding the share root (ACL-gated; 404 for strangers).
- Storage allowance override no longer crosses user boundaries: a
  recipient's plan cannot raise the owner's cap.
- Overwrites stay in the bucket the entry already lives in instead of
  repointing to the handling server's bucket and stranding the old
  object.
- manage mode documented as implying write (matches enforcement);
  share dialog label now "Can edit & share". Documented that fs socket
  events are owner-only.
- Sidebar: saved orders gain the Shared entry once the user has shares.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix(share): close review findings, and retire /auth/grant-user-user

Security
- Recipient writes no longer echo the owner's real path back. The pending-write
  event and the upload-progress meta both go to the *acting* user, so a write
  into a shared folder handed out the layout above the share root.
- `maskerFor` failed open: the first caller fixed the actor, and one that ran
  before the request knew who was acting pinned `undefined` — after which every
  path published unmasked. It now adopts the first real actor and rebuilds for
  a different one.
- `/auth/grant-user-user` returns 501. It wrote user-to-user grants straight to
  the permission tables with no share row, so nothing could list or cascade a
  revoke over them — and the new `manage` mode meant a delegate could reach it
  for the owner's files. Filesystem access goes through `/share`; nothing else
  is meant to pass between two users. Undocumented (its docs page was never
  written) and no callers. Revoking is untouched, so grants made before this
  can still be withdrawn.
- `#assertCanManage` asks about the permission actually being granted rather
  than a fixed `read`, so sharing at `manage` is refused at the share layer
  instead of by `grantUserUserPermission` two levels down.
- `listSharedWithMe` checks the grants, not just the index: withdrawing access
  any other way left the row publishing name, size and a signed thumbnail URL.
- Moving an item into another tree now retires its shares. Grants are keyed on
  uuid, so they followed it and left the new owner with recipients they never
  agreed to.

Correctness
- `acl.check` gets the real path again, not the masked one. ACL matches on the
  path string, and a mask hides the `AppData/<appUid>` shape it needs.
- "Leave this share" works for a grant that predates the index; the fallback
  scoped the delete to the caller as issuer, which can never match.
- `move`/`copy` reject a name with a slash or a `.`/`..` segment, as `rename`
  already did. It matters more here: a move into the owner's Trash skips the
  destination write check.
- Descendant walks scope by path, not by owner, so rows predating the
  one-owner-per-subtree invariant aren't orphaned by their parent's deletion.

Performance
- Index `user_to_user_permissions(permission)`. Retiring a node's grants is a
  prefix match, but the primary key is (issuer, holder, permission), so it was
  a full scan.
- Retirement is coalesced and chunked. `remove()` emits one event per
  descendant, so deleting a directory fired one unindexed lookup per file, all
  at once and unawaited.
- `listReaching` is a plain `fsentry_id IN (...)` on `idx_share_fsentry`. It
  runs behind every file write, and the join-plus-OR it replaced was
  unindexable.

---------

Co-authored-by: Claude Fable 5 <[email protected]>
Co-authored-by: Daniel Salazar <[email protected]>
2026-08-17 09:08:23 -04:00
Ayush tiwari fc861da89f feat: add Gemini 3.7 Flash (#3587) 2026-08-16 23:51:37 -07:00
Parman Mohammadalizadeh facb844747 fix: derive express subdomain offset from the configured root domain (#3575)
Express derives `req.subdomains` by dropping a fixed number of labels
from the right of the hostname, defaulting to 2. A deployment whose
`domain` has more than two labels therefore reads its own root domain as
an active subdomain, so the user-site redirect sends the root origin to
the static hosting domain, which sends it back. Self-hosting docs
recommend exactly that shape (`puter.example.com`).

Set the offset from the label count of `config.domain`. Two-label
domains keep the express default, so existing deployments are unchanged.

Fixes #3561
2026-08-16 23:48:20 -07:00
Yashwarhade8010 3b791bb334 docs: update web search examples to gpt-5.6-luna (#3589) 2026-08-16 23:45:02 -07:00
Daniel Salazar a64a444a17 feat: batch delete for flush + metering fixes (#3593) 2026-08-16 15:26:33 -07:00
Daniel Salazar d3c9828207 fix: metering gui maths (#3592) 2026-08-16 14:57:29 -07:00
Daniel Salazar 87180b1081 fix: metering (#3591) 2026-08-16 14:19:05 -07:00
Daniel Salazar d22b656df8 fix: metering issues with addons (#3588) 2026-08-15 22:06:51 -07:00
Nariman Jelveh 19cd5f4476 feat: add BytePlus ModelArk providers (chat, image, video) (#3498)
* feat: add BytePlus ModelArk chat provider

Adds BytePlus ModelArk as a provider for the puter-chat-completion
driver, following the MiniMax/ZAI providers as reference per
doc/contributing-apis.md.

- OpenAI-compatible endpoint at ark.ap-southeast.bytepluses.com/api/v3
  (apiBaseUrl config selects the region)
- Static catalog of 16 chat models (Seed 2.x/1.x incl. vision, GLM,
  DeepSeek, GPT-OSS) with limits and per-token pricing from the
  official docs
- Passes Ark's thinking/response_format/stop params through custom;
  normalizes reasoning_content to reasoning
- Bare deepseek-v4-* names stay with the first-party DeepSeek
  provider; BytePlus only claims prefixed aliases
- Offline unit tests (mocked SDK against a real test server) plus an
  env-gated integration test

* feat: add BytePlus image and video providers

Extends the BytePlus ModelArk integration to the puter-image-generation
and puter-video-generation drivers, reusing the same services.byteplus
API key and regional apiBaseUrl as the chat provider.

Image (Seedream/SeedEdit via OpenAI-compatible /images/generations):
- dola-seedream-5-0-pro (pixel-tier pricing + billed input images from
  the 2nd on), seedream-5-0-lite, 4-5, 4-0, and seededit-3-0-i2i
- quality tiers 1K/1.5K/2K; aspect ratios resolve to Ark's documented
  pixel sizes; explicit WxH passes through with Ark's bounds enforced

Video (Seedance via Ark's async /contents/generations/tasks + polling):
- Seedance 2.0 / 2.0 Fast / 2.0 Mini / 1.5 Pro / 1.0 Pro / 1.0 Pro Fast
  (2.5 is priced but its API isn't live yet, so it's excluded)
- per-video-token billing from usage.completion_tokens, with per-second
  estimates feeding the credit cap; audio vs silent rates for 1.5 Pro
- first/last frame and reference-image inputs; generate_audio param
  added to IGenerateVideoParams

Pricing and capabilities hardcoded from the official docs (ModelArk
pages 1544106, 1330310, 1520757, 1521309, 1541523). Offline unit tests
mock the SDK / global fetch; integration tests are env-gated on
PUTER_TEST_AI_BYTEPLUS_API_KEY.

* fix: correct BytePlus catalogs and validation against the live API

Verified the three BytePlus providers against ModelArk with a real key;
these are the mismatches that surfaced.

- Drop seededit-3-0-i2i-250628. Ark reports it as Shutdown and every
  request 404s. Its now-unreachable image-to-image branches in the
  provider go with it.
- seedream-4-5 and the 5.0 series enforce a 3,686,400 pixel minimum, so
  they only accept the 2K tier. Mark them 2k-only and snap an
  unsupported tier up to the nearest allowed one, which also keeps the
  aspect-ratio table from mapping to a sub-minimum size.
- glm-4-7 has a 204,800 token context, not 256K.
- Guard the actor in the image provider like the video provider does.
- Round a sub-minimum video duration up to the shortest supported clip
  instead of reporting it as insufficient funds.
- Gate video resolution on the model's own dimensions; the dims table is
  shared across a family and accepts more than any one model does.

* Tighten BytePlus AI provider handling

Extract shared reasoning-content normalization for OpenAI-style chat providers, and harden BytePlus image/video behavior. This updates image tier and size validation, normalizes aspect ratios and input image refs, prevents mismatched BytePlus key/base URL fallback config, makes video resolution matching case-insensitive, and rejects excess reference images instead of silently truncating them. Tests were expanded to cover the new BytePlus request and validation paths.
2026-08-15 21:08:17 -07:00
404oops fc56075115 Merge pull request #3584 from rupesh0001-tech/rupesh
feat(ai-chat): add grok-4.6 model to xai provider
2026-08-15 21:22:01 +02:00
404oops e1998e39ab Increase max_tokens limit to 500,000 2026-08-15 21:20:45 +02:00
Daniel Salazar fb7968a1c7 fix: metering hardening; handle burst of unfinished ai requests (#3585) 2026-08-15 10:52:29 -07:00
rupesh0001-tech c88eeb3868 feat(ai-chat): add grok-4.6 model to xai provider
- Add grok-4.6 model definition with pricing and context specs
- Add aliases x-ai/grok-4.6 and grok-4.6-latest
- Add unit tests for alias resolution and metering calculation

Closes #3562
2026-08-15 20:32:22 +05:30
Reynaldi ChernandoandCopilot Autofix powered by AI 9e25ce1401 [PUT-1478] Add KV commands to CLI (#3579)
* Add KV commands to CLI

* docs

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-08-15 11:43:30 +07:00
Daniel Salazar f15d835eeb fix: restrict openai and anthropic compatible endpoints to be subscription (#3583) 2026-08-14 18:55:15 -07:00
Daniel SalazarandClaude Fable 5 27c4506e02 feat: usage rendered as credits on a 50c base, free allowance doubled (#3569)
* feat: usage rendered as credits on a 50c base, free allowance doubled

Usage is now displayed in credits: a configurable creditsPerDollar rate
(default 2,000, making the free tier's 50c allowance an even
1,000-credit base) ships with the metering usage response, and the
dashboard's usage cards and per-API table show raw credit numbers
through one shared formatter. The dashboard budget math is also fixed —
capacity is spend plus server-netted remainder, so held purchased
credit can never render as negative usage. The registered-user free
allowance doubles to 50c, tier display names move to Basic/Plus/Pro,
and dead referral-promise strings leave the English dictionary.

Co-Authored-By: Claude Fable 5 <[email protected]>

* refactor: the credits display rate exists only in deployment config

No default in code and no rate on any wire the plan surfaces read: a
deployment that doesn't configure creditsPerDollar renders usage in
dollars, exactly as before credits existed. The usage endpoint sends
the rate only when configured, and nothing in code or comments states
what any deployment's rate is.

Co-Authored-By: Claude Fable 5 <[email protected]>

* refactor: metering reports pre-scaled credits, never raw amounts

The usage, per-app usage, and cost-catalogue endpoints multiply every
monetary field by the config multiplier (renamed creditMultiplier)
before responding, and flag the unit; the multiplier itself never
ships. Counts, units, and byte figures pass through untouched. With no
multiplier configured the endpoints report raw amounts and clients
render dollars, as before credits existed.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix: absent addon fields stay absent when scaling to credits

Co-Authored-By: Claude Fable 5 <[email protected]>

---------

Co-authored-by: Claude Fable 5 <[email protected]>
2026-08-14 16:29:01 -07:00
Neal Shah 6a7c09f54e blacklist dynamic workers (#3582) 2026-08-14 18:35:34 -04:00
Reynaldi Chernando 6254714484 deprecate gemini 2 flash and lite (#3581)
* deprecate gemini 2 flash and lite

* fix test
2026-08-14 17:27:48 -04:00
Neal Shah efa2cb4441 add more extensibility to workers driver (#3565) 2026-08-14 17:24:36 -04:00
Nariman Jelveh 4bc969b99e Update RecommendedAppsService.ts 2026-08-14 14:05:44 -07:00
Reynaldi Chernando 65f6d38432 update gpt 5.6 luna and terra pricing (#3580) 2026-08-14 16:38:13 -04:00
Daniel SalazarandClaude Fable 5 d641f6f7a1 tests: count only this test's dynamo reads in the block-window assertion (#3576)
The spy sits on the test server's shared dynamo client, so a raw call
count also picks up background work and the async tail of earlier tests
in the file — which made the block-window test flakily report a third
read. Each test runs in its own random namespace, so filtering the
spy's calls to that namespace removes the cross-talk without loosening
the assertion.

Co-authored-by: Claude Fable 5 <[email protected]>
2026-08-14 11:05:25 -07:00
Daniel SalazarandClaude Fable 5 00828b9998 fix: concurrency limiter heals legacy INCR keys instead of failing open (#3574)
The zset rework of the redis concurrent backend (#3529) kept the same
key names the old INCR counter used. Against a leftover string key every
zset command in the acquire MULTI fails WRONGTYPE while the trailing
EXPIRE still succeeds — so steady traffic refreshes the stale key
forever, and the failed zcard result turned into NaN, which admitted
every caller unbounded. Release then errored WRONGTYPE on each request
(the '[concurrent] release failed' log storm).

Surface per-command MULTI errors instead of coercing them to NaN, and on
WRONGTYPE delete the legacy key and re-acquire against a clean zset.

Co-authored-by: Claude Fable 5 <[email protected]>
2026-08-14 01:40:05 -07:00
Daniel SalazarandClaude Fable 5 126ec09556 docs: publish rate limits and quotas, and make limit changes move the docs (#3568)
Developer-facing reference for every rate limit, concurrency cap,
quota, and error shape — an advanced page, since puter.js already turns
the common failures into prompts. AGENTS.md and CONTRIBUTING.md now
carry the rule that a PR moving any of these numbers updates the page
in the same PR: an undisclosed limit is one developers discover as a
service failure.

Co-authored-by: Claude Fable 5 <[email protected]>
2026-08-14 00:41:01 -07:00
jelveh 25a5799088 Update RecommendedAppsService.ts 2026-08-14 00:38:05 -07:00
Daniel SalazarandClaude Fable 5 ea2f9967a6 fix: over-quota batch uploads surface the storage prompt instead of failing quietly (#3566)
* fix: over-quota batch uploads surface the storage prompt instead of failing quietly

Partial batch failures now carry each item's code/status, and when every
failed item failed the same way the shared code/status is hoisted onto
the rejection itself — so an upload that exceeds the storage quota
rejects with storage_limit_reached/413 and the SDK's upload handler
shows the free-up-space prompt. A partial failure is also no longer
misread as the signed-batch endpoint being unavailable.

Co-Authored-By: Claude Fable 5 <[email protected]>

* fix: out-of-storage copies prompt to upgrade the same way uploads do

Any fs operation the server refuses with 413 storage_limit_reached now
surfaces the upgrade prompt — the check that lived inline in upload's
error handler moves to a shared helper wired into the operation
scaffold's reject path, so copy/move/mkdir/rename get it too. The
desktop's copy/paste suppresses its generic alert for that code, since
the SDK dialog already explains the refusal and carries the fix.

Co-Authored-By: Claude Fable 5 <[email protected]>

---------

Co-authored-by: Claude Fable 5 <[email protected]>
2026-08-14 00:26:07 -07:00
Daniel Salazar ba9b885a5a Revert "feat: dashboard app search continues into the App Center (#3567)" (#3572)
This reverts commit 6cc241ac31.
2026-08-13 21:00:02 -07:00
Daniel SalazarandClaude Fable 5 6cc241ac31 feat: dashboard app search continues into the App Center (#3567)
A search that matches none of the user's own apps now puts the same
query to the App Center catalogue and renders the hits under the empty
state — debounced, filtered to apps the user doesn't already have, and
launchable in place.

Co-authored-by: Claude Fable 5 <[email protected]>
2026-08-13 20:48:03 -07:00
Nariman Jelveh 7f8e24f06d fix: keep "Add an app" in the grid while searching
Typing in the Apps tab's search dropped the tail tile — deliberately, on the
grounds that a query asks which apps you HAVE and a tile matching nothing has
no business in the answer. That reads the search too narrowly: looking for an
app you don't have is the same gesture as looking for one you do, and the
moment the search comes up short is exactly when the way to GET an app is
worth having on screen.

So the tile is pushed unconditionally now, and a query that matches nothing no
longer replaces the grid with a bare "No apps match your search" — the line
moves above a grid holding just that tile. Keeping it a real grid, rather than
parking a tile inside the empty state, is also what keeps it reachable: arrows
and Enter only walk tiles inside .myapps-page, and the tail tile carries
tabindex -1 for the pager's roving focus.

The no-apps-at-all state is untouched: with nothing installed and nothing
typed, the empty state still stands in for the whole grid.
2026-08-13 18:53:59 -07:00
Nariman Jelveh 9b6627b1ea fix: an app's background helper must stay private to it
`launchApp(name, args, { background: true })` hid the child's window and
nothing else, so the instance was hidden but not private: it kept its
taskbar item, lit the running dot on its dashboard tile, and — because
the dashboard enforces one instance per app — WAS what clicking that tile
opened. Minimize the parent, click the child's tile, and Puter handed the
user the window the parent was mid-conversation with; the app, which only
ever meant that instance for its caller, said so on screen. Showing it
also dropped the never-shown marker, so from then on the helper outlived
its launcher and owned the tile.

Hidden now means unreachable. `user_facing_windows` is the one rule: of
an app's windows, the ones that are the user's. Everything the user
drives filters through it — the tile's reopen and its running dot and
Quit item, the taskbar item's click, window list and show/hide/close-all,
the file row's switcher and open-file dot, and the dashboard's
Back/Forward — so a helper is never focused, restored, listed, or counted
as running. With none of the user's own left, the tile simply launches a
fresh instance and the helper keeps serving whoever launched it. Paths
that act on the APP rather than on a window it happens to have open —
uninstall, and a launcher's close taking its helpers down with it —
deliberately keep the unfiltered list.

The taskbar item is now what a hidden launch EARNS by becoming visible,
rather than something it advertises from the start; makeWindowVisible
adds it (and fires the dots event) before showing, since focusWindow
marks an item active and needs it to exist. Windows stamp data-in_taskbar
when they take their place in data-open-windows, so the close path only
decrements a count it actually joined — otherwise a helper closing beside
the user's own window would zero the count and strip the item off a
window still open. For the same reason a helper's close no longer pops
the dashboard URL: it never claimed an entry (the push only happens for a
window created visible), and consuming one would minimize the user's
window of the same app.

is_unseen_background_window gains the other half of its own definition:
launched hidden AND launched BY another app. An app that is always
windowless (`background` on the app record) starts hidden too, but when
the user opens it there is nobody it is serving — it is the instance
their tile has to find, or every click would start another one they
cannot see.
2026-08-13 18:38:13 -07:00
Nariman Jelveh 7576e0b03a fix: route dashboard file menus by input modality, not touch capability
A mouse right-click on a file row in the dashboard Files tab opened the
mobile context-menu sheet (centered over the row, nowhere near the
cursor) on any touch-capable laptop or desktop, because phone/tablet
detection used navigator.maxTouchPoints > 0. The same check applied the
.touch-device class, degrading mouse selection and drag on those
machines.

Route by how the menu was invoked (the row's tracked pointer type) plus
isTouchPrimaryDevice() — coarse pointer and no hover — which is false on
touch-capable laptops but true on iPads whose UA claims macOS. Also let
sidebar-folder and background menus accept taphold on such iPads, where
they were previously unreachable (taphold dismissed, and iOS never fires
native contextmenu).
2026-08-13 17:46:58 -07:00
Nariman Jelveh d980a9f590 fix: don't invert full-color icons in the dashboard context menu 2026-08-13 17:33:14 -07:00
Nariman Jelveh d18ea1adb5 fix: a background app must not outlive the app that launched it
An app launched with `background: true` gets a real window from the moment it
starts, just hidden. Nothing ever took it down: when the app that launched it
closed, the child kept running with no way to reach it and no reason to be
there. On the dashboard the only sign was a running dot on a tile the user had
never lit up, and clicking that tile did nothing at all.

Three things were wrong, and all three had to go:

A window nobody has seen now dies with its launcher. UIWindow's close path
closes hidden children the closing app launched, keyed on a marker stamped at
creation. makeWindowVisible drops that marker the first time the window becomes
visible — showing itself with `puter.ui.showWindow()`, or the user showing it —
because from then on the window is the user's, and keeps running.

The dashboard tile is a real handle again. focusExistingAppWindow only routed
MINIMIZED windows through showWindow(); a hidden one fell through to
focusWindow(), which leaves it invisible while handing it the keyboard. With no
taskbar in dashboard mode the tile is the only handle on a background app, so
that click had nowhere else to go. It now asks whether the window is on screen
at all. The Files tab's row-click had the same one-line defect.

And a background instance can't take a tile from the user's own session: an
on-screen window wins, then a window the user has seen, then a hidden one.

Removing the child then hit a crash of its own: ExecService's `remove` handler
dereferenced the launcher's iframe to say goodbye, and the launcher was already
gone. Throwing there aborts jQuery's remove() itself, so the window stayed in
the DOM — running dot and all. That one also hit anyone closing a background app
from the taskbar after its launcher had closed.

The predicates behind all of this live in one helper, window_visibility.js, with
showWindow() reading the same `hidden, not minimized` rule it spelled out inline
before.
2026-08-13 14:36:08 -07:00
Nariman Jelveh 08f075d774 Update RecommendedAppsService.ts 2026-08-13 11:45:28 -07:00
Nariman Jelveh 664de0016b fix: a hidden window must not hold the keyboard
Launching an app to serve another one took focus away from the app the user
was working in, and they had to click it to get it back. Typing a guest name
into Calendar's event editor — which launches Contacts to read the address
book — dropped the user out of the field mid-word.

Four things conspired, all of them variations on "a window nobody can see is
treated as the window in front":

`window-active` was hardcoded into every window's markup, including windows
created hidden. focusWindow() — the thing that normally grants that class,
and strips it from everyone else — is already skipped for a hidden window, so
two windows ended up claiming it. It now follows the same rule as the
window_stack push a few lines above: visible windows only.

Both "focus the window once its IPC attaches" sites read that class to decide,
so a hidden child window pulled focus a beat after launching. Neither focuses
a window with data-is_visible="0" any more.

makeWindowInvisible left `window-active` on the window it had just hidden.
Since focusWindow() disables pointer events on every other app's iframe, an
app calling puter.ui.hideWindow() on itself left whoever launched it both
unfocused AND unclickable until the next click. It now hands activation back
to the top of the window stack, the way closing a window does, and drops
itself out of the activation order until it is shown again.

showWindow only ever un-minimized: for a window hidden by hideWindow() (which
keeps its geometry and writes no data-orig-*) every branch left it hidden and
stamped NaN geometry on it from the missing attributes. It now routes such a
window to makeWindowVisible. That is what makes the taskbar item a real
handle on a background app — clicking the item calls showWindow on the group.
2026-08-13 09:59:37 -07:00
Nariman Jelveh e273431f14 feat: let an app launch another app in the background
`puter.ui.launchApp(name, args)` had no way to say "I need this app's API,
not its window". That matters because we create and show an app's window
before the app's own code runs, so an app launched purely to serve another
one cannot avoid appearing on screen: the best it can do is call
`puter.ui.hideWindow()` once it boots, which reads as a window flashing
open and shut. In dashboard mode it was worse than a flash — the child
maximized into the tab and minimized its parent behind it, so asking a
service app a question took the user's app away from them.

So `launchApp` now accepts `background: true`, and the window starts
hidden. The app is otherwise entirely normal: it keeps its taskbar item,
so a user can see that it is running, show it, or close it, and it can
show itself with `puter.ui.showWindow()` whenever it has something to say.
Only a literal `true` counts, since the flag arrives over IPC from another
app.

The decision now lives in one predicate, `starts_hidden(app_info, options)`,
which folds this together with the existing app-level `background` flag and
is used everywhere the old flag was read — including the dashboard's
minimize-the-parent branch. `show_in_taskbar` deliberately still keys on the
app-level flag alone: an app that is always windowless has nothing to put in
the taskbar, while a background *launch* should stay visible there.

Existing callers are unaffected: with `background` unset, both paths
evaluate exactly as they did.
2026-08-13 09:47:35 -07:00
Daniel Salazar 8ed8feed4b fix: don't let an aborted upload take down the process (#3557) 2026-08-13 01:02:17 -07:00
Daniel Salazar 22f5bf5429 fix: duplicate emails (#3556) 2026-08-12 22:00:48 -07:00
Nariman Jelveh 198184f986 fix: drop the feedback dialog's rate limit entirely
Reopening still failed intermittently: any call the backoff refused looks
exactly like the user closing the dialog, so an app's "Send feedback"
button just did nothing, with nothing to see anywhere.

Rate limiting this dialog is not worth that. The other modals an app can
open with no user gesture — requestPermission, alert, prompt — have no
rate limit either, so one dialog at a time is the only rule left, and a
refusal now says so in the console.
2026-08-12 17:46:05 -07:00
Nariman Jelveh 026ae46530 fix: let an app reopen the feedback dialog after the user closes it
The abuse guard counted every dismissal that sent nothing as a strike
against the app, so closing the dialog blocked the app's next
showFeedbackDialog() for 10s, then 60s, then for the rest of the page's
life. The key is the app uuid, so relaunching the app did not clear it,
and a blocked call replies sent:false — the app just sees nothing happen.

Key the guard off how fast the app comes back instead. A reopen within a
second of the app's last dialog activity is machine-paced and gets the
same escalating backoff; attempts made while backed off count as activity
too, so a loop cannot wait out a tier and start from zero strikes. Any
human-paced reopen clears the app's record, so the tiers are only reached
by an app that reopens at machine speed several times running.

One dialog at a time, and a successful send clearing the record, are
unchanged.
2026-08-12 17:35:54 -07:00
Nariman Jelveh 0615c3aa3c feat: add "Show hidden" to the dashboard's folder context menu
The dashboard's files tab filtered out dot-files unconditionally, so
there was no way to reach them the way the desktop Explorer allows.
Add the same "Show hidden" toggle next to Refresh, driven by the
shared show_hidden_files preference so the two stay in sync, and dim
revealed rows with item-revealed like the Explorer does.

The socket-driven item.added path applies the same rule, so a hidden
file created elsewhere can't appear in a view that filtered its
siblings out.
2026-08-12 17:26:04 -07:00
Nariman Jelveh 748461aabb fix: show the new folder's row in the dashboard before mkdir answers (#3555)
* fix: show the new folder's row in the dashboard before mkdir answers

Both New Folder paths in the dashboard Files tab awaited mkdir before
drawing anything, so on a slow connection the button appeared to do
nothing for seconds. The toolbar path then did a full renderDirectory on
top of that -- a second round-trip, and with the default eventual
consistency the new folder could miss the listing entirely, leaving the
rename editor unopened.

Both now go through one createFolderInstant(), which renders the row
first: a locally predicted name (mirroring the backend's " (N)" dedupe
convention), a temporary uid, and the name editor already open. mkdir is
still asked for the plain "New Folder" path with rename: true, so the
server keeps owning deduplication; the prediction is only what we draw in
the meantime, and the row corrects itself if the two disagree. On failure
the row is withdrawn and the error is shown rather than swallowed.

Renaming is the next thing the user does and it needs the real uid, so
rename() awaits the create promise parked on the row. Everything else
that acts on the item -- open, menus, drag -- sits out while the row is
pending. mkdir's item.added comes back to the originating client (the
event carries no original_client_socket_id) and cannot match a temporary
uid, so _creatingItem still suppresses it, now as a counter: as a flag,
one create finishing uncovered another still in flight.

Two things found on the way:

- directory_depth_limit_exceeded had no translation key, so that alert
  (including the pre-existing desktop create_folder path) rendered the
  raw slug.
- The empty-directory notice is now restorable without refetching, since
  a withdrawn create has to put it back. It carries its own class because
  the loading overlay shares the same container.

Verified end to end against a dev backend with mkdir slowed to 3s:
toolbar and context-menu paths, rename and Escape before the response,
two overlapping creates, and a rejected mkdir.

* fix: don't draw the instant new-folder row while a listing is rebuilding

renderDirectory() clears .files before its readdir resolves, so a row
drawn during a load survives the clear and is left behind in whatever
directory the load lands on. Clicking the new-folder button while a
folder is still opening produced a row for `<old dir>/New Folder` sitting
in the new directory's listing, with the rename editor open on it —
clicking it navigated elsewhere and renaming it renamed a folder the user
wasn't looking at.

Drop the click while a rebuild is in flight, the same way renderDirectory
already drops navigation clicks that arrive while it renders.

* fix: stop drops onto a not-yet-created folder row from mangling files

A row drawn ahead of its mkdir carries a predicted path, but it was still
registered as a live drop target. Dropping a file on it called
move_items() with a destination that does not exist yet, and move treats
a non-existent destination as a rename target — so the dragged file was
silently renamed to "New Folder" instead of moving into the folder.
Reproduced against a slow mkdir: victim.txt became a 5-byte file named
"New Folder".

Sit the row out of the jQuery UI droppable (drop and the spring-load
hover) until the real fsentry lands, matching the guards already on
opening it, its menus and dragging it. The native-file dragster drop gets
the same guard: it uploads into the same predicted path.
2026-08-12 17:16:44 -07:00
Daniel Salazar 78cfe0c0f6 metrics: add metering buffer store coutns (#3554) 2026-08-12 15:55:03 -07:00
Nariman Jelveh 81f9f00fc0 fix: stop app feedback dialog clicks from focusing the iframe beneath
Clicking inside the feedback overlay (e.g. the textarea) reached
initgui's global mousedown -> focusWindow path: mouseover_window is
computed geometrically and is blind to the overlay, so focusWindow
focused the app window's iframe underneath — stealing keyboard focus
from the textarea and forwarding the click into the app.

Suppress it the established way (same fix as the dashboard app-group
panel): set window.mouseover_window = undefined in the overlay's own
mousedown handler, which runs before the document-level one; undefined
is the only value initgui's guard skips.
2026-08-12 15:00:32 -07:00
Nariman Jelveh 556380cf16 fix: keep app feedback send button blue on hover
The generic .app-feedback-btn:hover:not(:disabled) rule out-ranked the
.app-feedback-btn-primary:hover override (the :disabled argument inside
:not() counts toward specificity), so hovering Send repainted it with
the light --afb-hover background under white text. Strengthen the
primary hover selector so the blue gradient wins.
2026-08-12 13:42:11 -07:00
Daniel Salazar 908ec23eda fix: sanitize user data (#3552) 2026-08-12 12:08:54 -07:00
Juan Fernando Castro d5ae5a0049 🔧 PUR-1072: Flatten driver permissions to hardcoded values (#3545)
* refactor(permissions): drop hardcoded group permission map for a flat default

* test(drivers): assert credential-gate intent instead of a 403 proxy
2026-08-12 12:08:38 -07:00
Daniel Salazar 419d0aaa89 doc: update bounty doc 2 (#3551) 2026-08-12 09:56:34 -07:00
Daniel Salazar c3a0c28705 docs: update bug bountu (#3550) 2026-08-12 09:55:13 -07:00
Nariman Jelveh 7ceb2090b7 feat: app user feedback system (#3546)
* feat: app user feedback system

Add puter.ui.showFeedbackDialog(), letting users send feedback to an
app's developer. In the app environment the Puter desktop renders the
dialog; on a third-party website a puter.com popup hosts it. The message
is stored in a new app_feedback table and emailed to the app owner's
confirmed email — it never passes through the app's own code.

Feedback is strictly opt-in per app via a new apps.feedback_enabled
column (a real column, not an app-metadata key, so Dev Center's
whole-blob metadata saves can't silently erase it), settable through the
existing puter.apps.update path (feedbackEnabled).

Backend follows the layered stack: AppFeedbackStore (durable count
queries) -> AppFeedbackService (opt-in check, message normalization,
abuse caps, best-effort owner email) -> AppFeedbackController
(POST /app-feedback, GET /app-feedback/target). New app-user-feedback
email template uses the escaping-safe nl2br triple-stash.

Defensive by design:
- requireUserActor blocks app tokens, so feedback can't be submitted
  programmatically; guiOriginOnly keeps cross-origin pages out.
- App identity comes only from the validated IPC sender (desktop) or the
  browser-attested opener origin (popup), never from message contents.
- The send-feedback popup action is in NON_AUTH_POPUP_ACTIONS, so it
  never delivers a token to the opener.
- Layered limits: route rate limits, plus DB-count caps that fail closed
  when the limiter backend is down, plus a per-app daily owner-email cap.
- Owner email is fully best-effort: an unconfigured transport,
  unconfirmed/unsubscribed/suspended owner, or send failure never fails
  the request or blocks storage.
- The dialog and SDK method are resolve-only and always settle, so a
  caller is never left hanging.

Migrations for sqlite/mysql/postgres, puter.js types, docs, backend
tests (sqlite + postgres), and a Playwright e2e spec are included.

* feat: add feedback control to the dashboard app-drawer

Surface the feedback dialog directly from the app window's chrome in
dashboard mode: apps that opt in (apps.feedbackEnabled) get a "Send
Feedback" button in the dashboard app-drawer, next to minimize/close.
It opens the same UIWindowAppFeedback dialog, targeting this app by uid.

The control is only rendered when the app opted in — feedback_enabled is
threaded from the launched app's metadata into the window options — and
the dialog still re-checks opt-in server-side, so a stale flag can't send
anywhere. Reuses the existing .dashboard-app-drawer-btn styling and the
app_feedback_title i18n string, so no new CSS or strings.

Adds e2e coverage: the control appears and opens the dialog for an
opted-in app, and is absent for an app that hasn't opted in.

* feat: enable app feedback by default in Dev Center

New apps created in Dev Center now have feedbackEnabled set on creation,
so users can send the developer feedback without any extra setup. A "User
Feedback" toggle in the app's settings lets developers turn it off (and
back on); it's wired into the save payload, the dirty-state tracking, and
the reset-to-original path like the neighboring toggles.

The Save update omits feedbackEnabled unless the toggle is present, and
the backend leaves an omitted field untouched, so the default survives
the create-then-save flow Dev Center runs. Add an SDK apps-suite guard
covering that round-trip (create-on -> unrelated update keeps it -> can
be turned off).

* fix: feedback modal polish + share sender email

Address four issues with the app feedback UI:

- Dashboard app-drawer: the extra "feedback" control pushed the close
  button past the drawer's derived width and clipped it. A `has-feedback`
  modifier widens the surface by one button + gap so all three controls
  fit. The control's glyph is now a message bubble with text lines, which
  reads more clearly at 14px than the previous bare speech bubble.

- The feedback dialog is no longer a UIWindow. It's a from-scratch
  overlay modal in the spirit of the dashboard modals (uninstall,
  add-app): a fixed scrim + centered card with self-contained,
  theme-aware color tokens (light default + dark override), a bottom-sheet
  layout on narrow screens, backdrop/Escape close, and an entrance
  transition. This renders consistently across the three contexts it's
  opened from (desktop app-IPC, dashboard drawer, standalone popup), so
  the callers no longer pass UIWindow-specific window_options.

- Feedback now shares the sender's email (not just their username) with
  the developer so they can respond: the owner email sets Reply-To to the
  sender and shows the address in the body — but only when the sender's
  email is verified (an unverified address could be anyone's, so it's
  never used as a reply target). EmailClient.send gains an optional
  replyTo. The dialog note now says the email will be shared.

Tests: e2e updated for the new modal (7 pass); backend feedback suite
covers the verified/unverified sender-email split (sqlite + postgres);
EmailClient + GUI unit suites pass; type-check clean.

* fix: resolve 'app-'-prefixed app names in feedback target lookup

APP_NAME_REGEX allows names beginning with "app-" (e.g. the seeded
app-center), but resolveTargetApp's startsWith('app-') heuristic sent
those to a uid-only lookup with no name fallback, so feedback for such
apps 403'd even when enabled. Use AppStore.resolveApp (uid, then name)
like the rest of the codebase.

* fix: make feedback daily caps fail closed under concurrent submissions

The per-user and per-user-per-app caps were check-then-insert and the
per-app email cap was count-then-send, so parallel requests (or multiple
nodes, or the route limiter failing open) could all read a stale
under-cap count and push past every limit — the exact scenario the
DB-backed caps exist to stop.

Now the user caps recount after the insert (own row included) and roll
the row back with 429 if a burst breached them, and the email cap claims
its slot (email_sent=1) before sending, recounts, and releases the slot
if over cap or if the send fails.

* docs: disclose the Dev Center's feedback-on-by-default in SDK docs/types

The Dev Center deliberately creates apps with feedbackEnabled (see
32c950de5), but the SDK docs, apps.d.ts, and AppFeedbackService's class
doc all described feedback as strictly opt-in / default-false with no
qualification — so a Dev Center developer reading them would wrongly
conclude feedback is off for their app. State the Dev Center behavior
alongside the API default, and correct the update-path docs: an omitted
feedbackEnabled leaves the current value unchanged rather than
defaulting to false.

* fix: don't mint a user-app token as a side effect of the feedback popup

Every embedded_in_popup boot ran the user-app token exchange, and the
exchange is a write: /auth/get-user-app-token bootstraps an app row for
the opener origin, grants flag:app-is-authenticated (what makes the
site count as connected to the account), and creates its AppData dir.
So merely opening — or immediately cancelling — a send-feedback popup
recorded a user<->site relationship the read-only feedback flow never
needs: the server resolves the feedback target from the attested origin
without any of it.

Gate the exchange behind runsUserAppTokenExchange(action) in all three
popup paths that mint (main postAuthActions exchange, temp-user signup
success, manual signup fallback). request-permission keeps the exchange
since grants are written against the app row it bootstraps.

* fix: refuse feedback when the deployment cannot deliver it

With no email transport configured (the common self-hosted default),
submissions were stored in app_feedback — a table with no read path
beyond the abuse-cap COUNTs — the owner email was silently skipped, and
the sender was still shown 'Feedback sent. Thank you!'. The developer
never learns the feedback exists while the user believes it was
delivered.

Gate acceptsFeedback on clients.email.isConfigured so the pre-flight
reports enabled:false (the dialog shows its 'not accepting feedback'
pane) and submit returns 403 instead of swallowing messages. Owner-level
store-without-email cases (unconfirmed owner email, per-app email cap
overflow) keep their existing deliberate semantics.

* fix: settle showFeedbackDialog instead of hanging on older host GUIs

In the app environment showFeedbackDialog awaited an IPC reply with no
capability check. A host GUI that predates this feature (self-hosted
Puter running the live js.puter.com SDK) has no handler for the message
and never replies, so the promise documented as 'never rejects' also
never resolved.

The GUI now advertises the IPC dialogs it can answer via a
puter.gui_features param on the app iframe URL, and the SDK resolves
false when 'feedback-dialog' isn't listed. A reply timeout could not
substitute: legitimate replies only arrive when the user closes the
dialog, so any timeout would false-negative while the user is typing.
Older SDKs ignore the extra param.

* fix: guard app-triggered feedback dialog against desktop-lockout loops

The showFeedbackDialog IPC handler had no re-entry or abuse guard, and
the dialog it opens is a full-viewport overlay above the taskbar and
every window — so 'while (true) await puter.ui.showFeedbackDialog()'
kept the desktop permanently covered (for signed-out users, the same
loop spams the full-page signup window instead). Every dismissal just
settled the promise and let the app immediately reopen it.

Allow one dialog at a time, and back off reopens per app after each
dismissal that sent nothing: 10s, then 60s, then blocked until page
reload. A successful send resets the backoff, and user-initiated paths
(dashboard drawer) are unaffected since they don't go through IPC.

* fix: carry feedback_enabled in suggested/recommended app summaries

launch_app uses options.app_obj verbatim when provided, and the
suggested-apps launch paths (open_item.js, UIWindowSearch.js,
UIDesktop.js) pass summaries from toAppSummary — which omitted
feedback_enabled. So an opted-in editor launched by opening a .txt file
showed no Send Feedback control in the dashboard drawer, while the same
app launched from the Apps tab (full puter.apps.get object) did.

* fix: gate feedback dialog Cancel/X on an in-flight submit

Escape and backdrop clicks were already ignored while the POST was
pending, but the X, Close, and Cancel buttons weren't — clicking one
mid-send settled the promise false and tore down the overlay while the
submission still landed server-side: the developer got the email, the
app was told sent=false, and a user who resubmitted 'the failed one'
sent a duplicate and burned a daily-cap slot.

Apply the same !sending gate to the buttons and disable them visually
while the send is in flight.

* fix: reject feedback origins longer than the source_origin column

readTargetParam accepted values up to 3000 chars but the raw origin is
stored verbatim into source_origin VARCHAR(2048) (MySQL/Postgres), so a
2049-3000 char origin passed every validation and then blew up the
INSERT with an HTTP 500 on Postgres/strict MySQL — or was silently
truncated on non-strict MySQL, corrupting the abuse-forensics value the
column exists for. Cap the param at the column size.

* fix: make the feedback dialog's privacy note match what is shared

The note unconditionally said 'Your email address will be shared with
the developer so they can respond', but AppFeedbackService shares the
username always and the email only when it exists and is verified — an
unverified or temp-user sender was promised a reply path that never
materializes, and nobody was told about the username.

Show 'username and email' when the signed-in user's email is verified,
and 'username' otherwise.

* fix: stop HTML-escaping email subject lines

Subjects were compiled with default Handlebars escaping, so the
app-user-feedback subject rendered a title like "Bob's App & Games" as
"Bob&#x27;s App &amp; Games" — literal entities in the recipient's mail
client. Subjects are plain-text headers, not HTML; compile them with
noEscape. Header safety is unaffected: the transport encodes newlines
and free-form values collapse whitespace upstream.

* docs: state exactly what showFeedbackDialog shares with the developer

The doc claimed the dialog 'tells the user their username will be
shared', while the dialog's note talked only about the email address and
the implementation shares the username always plus the email (as
Reply-To) only when verified. Describe the actual disclosure: username
always, email when verified.

* docs: document the COOP false-resolve limitation of showFeedbackDialog

Under COOP the popup's opener link is severed, so the SDK deliberately
resolves false while the popup stays open and the user can still submit
(a feedback submission has no server read-back the way a permission
grant does). The documented contract ('resolves to true if the user
submitted feedback') was silently wrong on cross-origin-isolated pages —
state the limitation in the doc and the SDK jsdoc: false means 'not
confirmed', not 'not sent'.

* feat: point the feedback email footer at the Dev Center

The footer told developers to turn feedback off via a puter.apps.update
one-liner, but the toggle lives in the Dev Center app settings — and
Dev Center is where apps get feedback enabled by default in the first
place. Reword it to 'manage it in the Dev Center' with a link built
from config.origin (like app_link) so it holds on self-hosted
deployments.

* test: cover the feedback service and store layers directly

The service owns every feedback business rule — target resolution,
eligibility, message normalization, the durable caps, and the owner-email
preconditions — but was only reachable through the controller's tests. Give
it and the store their own suites so a regression names the layer it broke.

Service coverage adds the branches the route tests could not reach: a
blocked origin resolving to null rather than surfacing a 403, owners who are
suspended or unsubscribed, length measured after normalization, the 24h cap
window boundary, subject-header injection via the app title, and the email
links being rooted at config.origin.

The two describes already labelled `AppFeedbackService ...` move out of the
controller test, which keeps only the caller-facing promise that a failed
send still returns success.

* refactor: prep the feedback cap error once instead of via a factory

Both throw sites are in one call and only one can ever run, so a plain
const reads the same and drops a function that existed only to defer a
constructor.

* Require verified users for app feedback API

Add `requireVerified: true` to both app feedback routes (`GET /target` and `POST /`) in `AppFeedbackController`. This tightens access control so only verified user accounts can fetch feedback targets or submit app feedback.
2026-08-12 09:49:24 -07:00
jelveh ea63c3093e feat(dashboard): add Publish as website and Properties to folder menu
The Files tab's folder-background context menu (empty listing area,
sidebar folders, breadcrumb segments) now offers Publish as website and
Properties for the folder the menu was opened on, matching the desktop's
folder menus. Both are omitted at the filesystem root and in Trash, and
Publish is omitted inside trashed folders.

The properties modal can now resolve an entry by path when the caller
has no uid, which the folder-background menu doesn't.

The publish gate (account creation + email confirmation) was duplicated
in three places, so it moves to a publish_as_website helper that all
call sites now share.
2026-08-12 08:50:03 -07:00
Daniel Salazar e8236a100c chore: bump versions (#3548) 2026-08-12 01:18:17 -07:00
Daniel Salazar 20b3b88e39 metering: big fixes to metering + jsdoc types (#3547)
Changes are:
- global egress metering
- remove file egress cost
- introduce file op cost for the per request cost s3 has
- enforce fs read/download etc to through 402 when out of usage; allow for subdomains
- enforce kv metering when out of usage through 402; allow for workers
- jsdoc as source of truth for puter.js types
- kv driver caching for get and batchget operations with decreased costs
2026-08-12 01:06:04 -07:00
Chen, Ting-An cbae39a08f fix(i18n): add Traditional Chinese app management strings (#3541)
Translate the app discovery, app request, desktop shortcut, and app folder controls that currently fall back to English in the Traditional Chinese interface. Preserve the positional placeholders used by accessibility labels.
2026-08-11 21:18:37 -07:00
Daniel Salazar afad3e37bf fix: server health tolerance for primary read (#3542) 2026-08-11 01:19:09 -07:00
Daniel Salazar a6b2161b2c fix: misc sec fixes (#3540) 2026-08-10 22:24:44 -07:00
Neal Shah 9e864e9574 PUT-1432 (#3539) 2026-08-10 23:33:20 -04:00
Daniel Salazar 79d4201f12 fix: rate limits, AI routing, and a type-check gate (#3529)
- declare rate + concurrency limits on every route and driver that lacked one
- add acquireConcurrent for websocket connections and the DAV mount
- bucket AI models by identity key only; keep resold duplicates of any vendor
- skip recently-failed provider routes; cap the fallback chain at 3 attempts
- let full-access access tokens bind a worker to an app their own user owns
- cache resolved subscriptions so tiered limits don't add a round trip
2026-08-10 19:09:47 -07:00
Daniel Salazar 0c2d7dfa34 feat: add user created timestamp on whoami (#3538) 2026-08-10 19:08:50 -07:00
Neal Shah 2a6d2fea32 allow max-tokenless models on openrouter (#3536) 2026-08-10 18:40:10 -04:00
Juan Fernando Castro 1dec5e90c4 docs: add requestAppData() to Perms sidebar (#3534) 2026-08-10 11:38:09 -07:00
Neal Shah 566298d89c make context length on togetherAI more lenient (#3533) 2026-08-10 13:14:33 -04:00
Daniel Salazar 6bb5eacf61 fix: metering kv spamc (#3532) 2026-08-10 08:36:56 -07:00
Reynaldi Chernando 390a83c860 Fix puter.js docs and types drift 10 aug (#3531) 2026-08-10 12:47:18 +07:00
Nariman Jelveh 8f23bf7b75 fix(gui): hover the add-an-app options with the accent wash, not grey
The rows already answer hover with a --select-ring border; filling them
with the grey --dashboard-hover under that accent ring read as two
systems disagreeing. The weak select tint keeps the hover in one voice
and stays under the icon chip's stronger tint in both themes.
2026-08-09 18:23:07 -07:00
Nariman Jelveh aa85dddd38 Refresh Add App AI description copy
Update the English `add_app_ai_desc` translation string in the GUI to a more direct, enthusiastic message: “Describe the app you want and AI will build it!”.
2026-08-09 18:21:31 -07:00
Nariman Jelveh 8284f35b93 fix(gui): honor godmode file_paths launches now that /apps returns booleans
The godmode gate in ExecService.launchApp checked `godmode === 1`, but
GET /apps/:name serializes the flag as a boolean, so the check always
failed and file_paths launches (e.g. Dev Center opening a worker's
source in the editor, #2218) silently dropped the file. Accept both
shapes, matching the existing guard in launch_app.js.

Also fix the two issues hiding behind that gate:
- puter.apps.get returns `uid`, not `uuid`, so the /sign call for the
  target app sent app_uid undefined — no write grant and no user-app
  token for the launched app. Use `uid` with a `uuid` fallback.
- The closeApp IPC handler had the same `godmode === 1` comparison,
  preventing godmode apps from closing other apps' windows.
2026-08-09 18:06:58 -07:00
Nariman Jelveh ccec3ce39b fix(gui): open add-an-app choices through the deep-link intro, not a + tile morph
60686643b made App Center and the AI builder morph out of the + tile the
user clicked, which answers where the window came from but not the
question these two options exist to answer: where the APP went. The grid
never showed it arriving, so the user still ended a launch with nothing
to find, no tile for minimize to fly back to, and no lesson learned.

Choosing either option now plays exactly what an /app/<name> landing
plays (beginDeepLinkLaunch): when the app already has a tile the intro
travels to it, plays the click flourish, and the window grows out of the
app's own slot; when it doesn't, the tile is INSTALLED first — the slot
opens, the progress stroke draws, the icon springs in — and only then
does the window morph out of the tile that just arrived. Same beats,
same exposure decay, same interruptibility, same duplicate-launch claim.

The app info is prefetched in parallel and handed to launch_app, the
same contract as initgui's landing path, so the intro (which may need to
draw the arriving tile from it) never costs a second round-trip.

This also reverts 60686643b's anchor plumbing (UIWindow's
dashboard_tile_el option and the dashboard_tile_in_view export): the
intro installs a real tile for the by-app-name morph to find, so no
stand-in anchor is needed.
2026-08-09 18:02:39 -07:00
Nariman Jelveh 60686643b3 fix(gui): launch from the add-an-app modal with the tile morph, not a fade
Choosing App Center or the AI builder opened the window with the plain
fade while every other launch in the Apps tab grows out of the icon that
was clicked — the one launch that most needs to say where it came from
read as the app appearing from nowhere.

The morph resolved its anchor by app name, which cannot work here: the
whole point of these two options is installing an app you do not have,
and an app with no tile has no name to find. So the launcher may name its
anchor element (dashboard_tile_el), and TabApps resolves it once before
launching so the click flourish and the window's half can never disagree
about which tile the launch came from: the app's own tile when it already
has one on screen — minimize flies the window back there, so that is
where opening should come from — and otherwise the + tile itself.

dashboard_tile_in_view's visibility test is now a named helper it shares
with the new path, so an anchor on an offscreen pager page is still
rejected and still falls through to the fade.
2026-08-09 17:49:50 -07:00
Nariman Jelveh 61bfcbdc83 feat(gui): add an add-an-app tile at the end of the Apps grid
The Apps grid showed what you have and offered no way to get more. A
dashed plus tile now rides at the tail of every page of it: after every
app, on the last page, and nowhere else. It wears the same tile skeleton
as an app so hover, focus, and arrow keys treat it identically, but
carries no app name or group id — which is what keeps it out of the
saved order, the running dots, and the deep-link tile lookups. It cannot
be picked up, is never a drop target (so no app can land past it), has
no context menu, and sits still while the apps jiggle in reorder mode.
Search results leave it out: a query asks which apps you have.

Clicking it asks how you would like to get an app: find one in the App
Center, have one built by the AI builder, or request one that does not
exist yet. The request is a form in the same card rather than the stock
Contact Us window — a titled pane one step deeper, whose Back arrow
returns to the options with the draft intact. It posts the same
/contactUs request that window did; a failure is said inside the form,
where the request is still there to retry, rather than in an alert
window the next click on the dashboard would bury.
2026-08-09 17:37:09 -07:00
Nariman Jelveh c8985b621d Add copy-link support for app tiles
Extract app tile URL generation into a shared helper and use it for a new dashboard context menu action that copies the tile's destination. This keeps copied links aligned with the existing open-in-new-tab behavior and adds regression coverage for app, external, encoded, and folder tiles.
2026-08-09 16:54:18 -07:00
Nariman Jelveh 42299a64ed Update recommended apps list
Add 'blockarena' and remove 'pretty-tiles', 'galaxy-troops', and 'blend-fruits' from the recommended apps list.
2026-08-09 11:20:40 -07:00
jelveh 344db5cb0b Remove vault from recommended apps
Drop `vault` from the recommended apps list so it no longer appears in app recommendations.
2026-08-08 11:54:56 -07:00
jelveh 66824f607d feat(gui): install an app onto the grid when its landing is what installs it
A /app/<name> landing for an app the dashboard didn't list opened with
a plain fade and left the app NOWHERE: the grid had been fetched before
the launch granted the permission that installedApps reports, so Back
found no tile to minimize into and the user landed on a dashboard
without the app they were just inside. The round trip that teaches
"windows are inflated tiles" broke on exactly the landing where a new
user is forming that model.

Now the landing SAYS what it does. The app joins the grid at the tail
(where new apps land) with a tile drawn from the landing's own app-info
prefetch -- only a confirmed-real app ever materializes, with its real
icon -- held invisible until the intro has revealed the grid and
travelled to the tile's page, and then it is INSTALLED, in the grammar
every app store taught: the slot opens (the folder well's own surface)
with the icon dim inside it, a progress stroke draws clockwise around
the slot, and on completion the icon springs to full color and size as
the label names it. Only then does the flourish play and the window
grow out of the tile. The arrival is the one beat that never decays:
per-app news delivered at most once per app, not a repeated lesson.
Minimize now has a target, and the app is simply there afterward.

The regression surface is guarded on every edge: the parked-invisible
state is re-applied by renderApps itself so mid-intro re-renders can't
strip it, and settleDeepLinkLaunch -- which the landing's finally
always reaches -- force-reveals it, so no path leaves an invisible
tile. A _pendingInstalls overlay (the mirror of _removedLocal) keeps a
refresh fetched before the grant lands from evicting the tile, and
retires itself once installedApps confirms the app or the user
uninstalls it again. The order is never saved on the splice, so the
default-position append can't freeze a custom order the user never
made. Failed or absent app info adds nothing; installed-app landings
are untouched; animations-off and reduced-motion users skip the
choreography but still get the tile, silently. The progress ring is a
transient element (the tile's ::before is the well, its ::after the
running dot) drawn as an SVG dashoffset sweep -- no Houdini dependency
-- and the app-info prefetch now asks for the 128px icons every other
tile already uses.
2026-08-08 11:25:48 -07:00
jelveh 66dedf3082 feat(gui): let the app drawer's intro flash retire once learned
The control drawer on headless dashboard apps opened itself on EVERY
window open, forever -- 2.6 seconds of tray over the app's own top
edge to teach a lesson (the controls live in this tongue) that is
learned in a few exposures. Same doctrine as the dashboard's
deep-link intro: pedagogy that knows when to step aside.

A per-account kv counter records deliveries, once per window: a flash
played while the user could see it, or the user opening the drawer
themselves (hover, tap, focus) -- the stronger proof, since the
drawer is a headless app's only chrome and must never decay out of a
user's awareness. After three, new windows keep the bare tongue and
the flash stops; hover, tap, and focus expansion never decay.

The attach is synchronous and the stored count is not: the first
drawer of a session races the read against a short cap and defaults
to teaching -- a hung read must not hold the intro hostage, and every
failure mode (unparseable value, failed read, timed-out read, failed
write) errs toward teaching once more, never toward never teaching.
The resolved count is cached and kept current in memory, so later
windows decide synchronously and a session's own not-yet-written
increments still count. kv.incr keeps two devices from losing an
increment, and the pre-read caps the key once the lesson is learned.

If the user beats a still-deciding flash to the drawer, the flash is
skipped rather than played over their hand -- its auto-collapse would
shut a drawer they are actively using. A flash in a hidden tab still
defers to first reveal (it rides requestAnimationFrame, as before)
and an unseen one is never counted.
2026-08-08 10:25:26 -07:00
Daniel Salazar 95da802b13 fix: metering hardening (#3527) 2026-08-08 06:10:01 -07:00
Daniel Salazar 0491d5fea7 fix: mcp better uploads (#3528) 2026-08-08 06:09:49 -07:00
Juan Fernando CastroandDaniel Salazar d202be10a9 feat: let apps use another app's data with user consent (#3516)
* feat(perms): add cross-app app-data permission vocabulary

* feat(perms): sweep app grants by permission prefix

* feat(perms): resolve and withdraw cross-app data grants

* feat(kv): support an authorized namespace override and per-key privacy

* feat(kv): gate cross-app KV access behind app-data grants

* feat(fs): allow cross-app AppData access and require a scope to delete

* feat(auth): accept permission lists and gate app-data grants

* feat(perms): add requestAppData to the puter.js SDK

* feat(gui): carry permission lists through the IPC and popup transports

* feat(gui): describe cross-app data requests in the consent dialog

* docs: document requestAppData and per-entry KV privacy

* perf(perms): sweep cross-app grants only for origin-bootstrapped apps

* fix(gui): stop double-encoding cross-app consent text

* fix(perms): close three gaps in cross-app grant enforcement

* fix(kv): meter and batch the per-entry privacy probe

* fix(perms): resolve app identifiers and scopes more strictly in the SDK

* test(perms): cover the cross-app consent flow end to end

* fix: small missing token resolution for app

also adds the same exclusion for the batchPut api, small change

* fix: make resolved actor optional

---------

Co-authored-by: Daniel Salazar <[email protected]>
2026-08-08 04:04:07 -07:00
jelveh 2c17476c07 fix(gui): folder pages, live drag-out, and one merge pulse in My Apps
Three fixes to the My Apps folders:

A folder big enough to need it now paginates like the grid outside
(iOS folders page too) instead of growing a scrollbar: pages of
cols x 3 tiles in a scroll-snap scroller with dots below, wheel and
swipe to flip, and a drag held at the card's edge flips folder pages
so reordering works across them. The card's height stays constant
across pages, and a deep-link landing on an app that lives on a later
folder page travels there before the launch morph.

Dragging an app out of the open folder no longer drops it blind:
after a beat held outside the card, the app leaves the folder, the
card closes behind it, and the SAME drag carries on over the grid --
placeholder shuffle, edge page flips, even a drop into another
folder -- so the app lands where the user watched themselves put it.
A quick drop during the beat still lands beside the folder, and
swinging back inside within the beat cancels cleanly.

The folder well's fill played twice on nearly every merge: the rest
countdown anchored at first contact with the target, so the hand
decelerating INTO the tile always read as movement when the dwell
elapsed, and the deliberate refill-from-empty replayed the fill. The
countdown now re-anchors on the move events themselves -- rest is
only visible at its edges -- so the fill that completes is the one
started by the last movement, played exactly once.
2026-08-08 01:28:09 -07:00
Nariman Jelveh 06d94534e8 feat(gui): iOS-style app folders in the My Apps grid (#3525)
* feat(gui): iOS-style app folders in the My Apps grid

Drag one app onto another and let it settle: a well opens under the
target and the drop makes a folder of the two. Dropping onto an existing
folder joins it. A folder opens by growing out of its own icon into a
card over a blurred grid, where its apps can be launched, rearranged,
renamed, or carried back out.

Hovering a tile mid-drag means two things — "push over, I'm passing
through" and "swallow me" — and the tile is barely bigger than its icon,
so pixels can't separate them; motion does. The shuffle is held while
the folder offer stands and fires when the icon leaves the tile, or at
the drop, so a quick drop onto a neighbour still reorders exactly as it
did. The offer itself re-arms rather than cancelling on movement: the
last events of a drag are the ones carrying the icon onto the target and
nothing is dispatched while it rests, so a cancel-on-movement dwell
could never fire at all.

Folders are stored in their own kv key; the grid's ORDER stays entirely
in the existing saved app order, with a folder occupying its first
member's slot and its members contiguous. Every saved order therefore
stays valid with no migration, and an app whose installedApps page
failed to load keeps both its folder and its position. Folders never
nest, one that drops below two apps dissolves, and a corrupt kv value
degrades to "no folders" rather than a broken tab.

Elsewhere:
- Search looks THROUGH folders — a match the user then has to hunt for
  inside one is not an answer.
- Minimize morphs into the FOLDER when an app lives in one, and a
  /app/<name> landing opens the folder so the launch grows out of the
  icon where the app actually is.
- The uninstall FLIP keyed surviving tiles by app name, which a folder
  tile doesn't have; it now keys by identity.

New pure model in appGroups.js with tests; verified end to end in the
running dashboard (create, join, open, rename, reorder, eject, ungroup,
launch-from-folder) alongside plain reorder, search, and uninstall.

* fix(gui): keep the folder name field from inheriting input[type=text] sizing

style.css styles every input[type=text] with `width: 100%` and grows it to
`padding: 7px; border: 2px` on focus. `input.myapps-group-name` matches at the
same specificity, so it only wins the properties it actually declares — width
was never one of them, and the focus rule declared neither padding nor border
width. The name field therefore spanned the entire folder card (so its hover
and focus chip read as a full-width bar rather than the name) and grew 8px
taller the moment it was clicked, shoving the folder's app grid down.

Spell the three out, in both the resting and the focus rule — the same trap
.myapps-search already documents next door.

* fix(gui): size folder icon ghosts to the icon they stand on

Border-box only reaches a folder's icon through `.dashboard * { box-sizing }`,
and every ghost cloned from one is appended to <body>, outside that rule: the
drag ghost, the click-time launch flourish, and the open/minimize morph ghosts
all fall back to content-box, where .myapps-group-icon's 5px padding is added
to the 56px slot. Each ghost rendered 66px square and 5px off, so it visibly
popped at exactly the moment it was supposed to sit flush on the real icon.

State box-sizing on the rule itself so a clone carries it wherever it lands.

* fix(gui): stop a closing folder from swallowing the next click

_closeGroup drops the open class and leaves the overlay in place for
GROUP_PANEL_CLOSE_MS so the card can recede into its tile. The scrim is
`position: fixed; inset: 0` and still hit-testable for that whole quarter
second, so a click on the grid during it landed on the outgoing overlay — whose
handler only re-runs _closeGroup, now a no-op. Shutting a folder and reaching
straight for an app did nothing.

Take the outgoing overlay out of hit-testing; it has no interactive job left.

* fix(gui): keep a folder name typed right up to the moment it closes

The name box commits on blur, and every exit that goes through a pointer blurs
it while the folder is still open — so clicking outside, or launching an app
from inside, keeps what was typed. Escape does not: _closeGroup clears
_openGroupId first and only then moves focus to the tile below (or removes the
card outright), so the blur arrives with no open folder to rename and
_renameGroup drops it. A brand-new folder opens with its name selected for
exactly this edit, so "type Games, press Escape" — the obvious way to dismiss
a dialog — was the path most likely to lose it.

Commit the pending name on the way out, before the folder id is gone.

* fix(gui): close an open folder when the Apps tab is re-entered

The dashboard hides an inactive section and calls onActivate on the way back
in; there is no deactivate hook, so a folder left open survives the round trip
and greets the user still open over a grid they walked away from. Worse,
onActivate's focusSearch then lands the caret in the search box behind the
folder's scrim, and typing filters the grid the card is covering — a modal with
the keyboard pointed outside it.

Shut the folder as the tab comes back: returning to the tab is returning to
the grid.

* fix(gui): move focus into a folder when it opens

Opening a folder called .focus({ preventScroll: true }) on a jQuery
object. jQuery's .focus() shorthand reads a lone non-function argument
as event DATA and binds a handler with it, so it never moved focus:
the folder opened modal over the grid with focus still on the tile
behind its scrim, where Tab walked away through the inert grid instead
of cycling inside the dialog — and the object it bound as a handler
threw a TypeError on that tile's every subsequent focus.

Focus the DOM node instead, as every other focus call in this file
already does.

* fix(gui): stop renaming a folder from swallowing the click that commits it

The folder's name box commits on blur, and blur fires on the PRESS —
before the click that press belongs to. Committing re-rendered, and the
re-render replaced every tile in the open folder, so by the time the
click was dispatched the tile under the pointer was detached and the
delegated handler never saw it. Typing a name and then tapping an app
in the folder — the path a brand-new folder puts the user on — renamed
the folder and did nothing else; the app only opened on a second click.

Rebuild the folder's contents only when they actually differ from what
is on screen. A rename doesn't change them, so nothing is detached, and
a background refresh no longer throws away hover/focus either. Tiles
that survive get their drag resting-rects cleared, since the card can
have moved under them since the rects were taken.

* fix(gui): keep Enter in a folder's name box from leaving the folder

Committing the name with Enter blurred the box, which left focus on
<body> — outside a dialog that is marked aria-modal and that traps Tab
on its own subtree. The next Tab therefore walked off through the inert
grid the folder is covering, exactly what the trap exists to prevent.

Step out onto the folder's first app instead; the same blur still
commits the name. The keystroke is stopped at the box because the
grid's document-level key handler reads Enter on a focused tile as
"launch it", and would otherwise have taken the focus move as its cue
to open an app the user never asked for.

* fix(gui): stop an open folder clipping its own uninstall badges

The folder's grid scrolls, so it clips anything outside its padding box
— and reorder mode's uninstall badge deliberately overhangs the top-left
corner of every tile. The top row's badges therefore rendered as flat
tabs rather than circles, on the one surface where they are a touch
user's only way to uninstall an app they have filed away.

Give the scroller 9px of top padding for the overhang to sit in and take
it straight back off as margin, so the card and everything in it stays
exactly where it was.

* fix(gui): hold page edge-flips while a folder merge is being offered

A tile in the pager's last column sits inside the 60px edge-flip zone, so
resting a dragged icon on it — the folder-making gesture — armed the edge
dwell alongside the merge dwell, and the page flipped out from under the
very folder the user was watching form (the merge target scrolls away
mid-offer, and the drop then resolves against its stale resting rect).
Worst on phones, where 72px tiles overlap the zone across the whole last
column.

A live merge offer now holds the edge flip: entering the zone arms no
dwell while an offer stands, and an offer that arrives during a running
dwell is re-checked at the flip (a resting pointer fires no event that
could clear the timer). Carrying the icon off the tile withdraws the offer
and the hold with it, so deliberate flips — resting in the bare edge
gutter — behave as before.

* fix(gui): make Escape cancel a folder rename instead of saving it

Escape pressed mid-edit fell through to the folder's close handler, and
closing commits whatever the name box holds — so the one key every inline
rename uses for "never mind" stored the abandoned half-typed name. Escape
in the box now puts the stored name back and steps out to the folder's
tiles, exactly the cancel Finder/Explorer taught; with nothing left to
cancel (name untouched) it falls through and closes the folder as before,
so a second press still exits.

* fix(gui): refill the folder well when the merge countdown restarts

The merge dwell pins its stillness anchor at first contact with the tile,
and a hand decelerating INTO a target routinely covers more than the
7px allowance between that moment and the first tick — so the countdown
quietly restarts. The well's fill, tuned to the same 460ms, had already
completed by then and just sat there half-open: a drop it seemed to
promise a folder for actually reordered. Restart the fill with the
countdown, so what the well shows is always the countdown that is
actually running.

* fix(gui): keep keyboard focus inside an open folder across its edits

The folder card is a modal dialog, but three of its flows stranded focus
on <body>, where Tab walks the inert grid behind the scrim:

- Remove from Folder rebuilds the card's grid after the context menu has
  dropped focus, so nothing inside the dialog holds it. The rebuild now
  hands focus back to the same app's tile (or the first) whenever it finds
  focus on <body> — never stealing from an uninstall modal, which holds it
  legitimately.
- The same eject dissolving the folder re-renders the grid right after
  _closeGroup's focus hand-back, replacing the very tile it chose. The
  ejected app's own tile — where the user is looking — takes focus instead.
- A click on the card's empty space focused nothing at all. The card now
  carries tabindex=-1 so such clicks land on it (no visible ring; a focus
  ring around the whole card would misread plumbing as selection), and the
  Tab trap wraps from there instead of stepping off through the scrim.

* fix(gui): size the folder name box to the name it holds

The box sat at the browser's default ~20ch regardless of content: a short
name floated in a hover pill far wider than the word, and a 40-character
one clipped while the card had room to spare. field-sizing: content hugs
the text between a 90px floor and the card's width, iOS-style; engines
without the property keep the default box exactly as before.
2026-08-08 00:28:03 -07:00
Neal Shah aea828ff12 add worker create event and new query methods (#3524) 2026-08-07 17:51:37 -04:00
Daniel Salazar c24f0fe08b fix: mcp fs copy, move, rename (#3517)
* fix: mcp fs copy, move, rename

* feat: more mcp tools for kv
2026-08-07 17:14:40 -04:00
jelveh 085ac116c7 fix(gui): keep app landings through signup, and unstack the session picker
Signing up from a direct /app/<name> landing redirected to '/' on
success, silently dropping the app the URL asked for — the deep link's
launch (and its dashboard intro) never happened. Signup now mirrors
login's pathname-preserving redirect, but only for app-landing routes
(/app/<name>, /desktop/app/<name>): every other route keeps the
historical '/', notably /action/signup, where returning to the same
path would just show the signup form again. The query string stays
dropped, matching login's credential-leak hygiene. This covers all
three signup entry points reachable from a landing: the login cover's
"Sign up", the session picker's "Create Account", and the
must_login_or_signup fallback.

The session picker (UIWindowSessionList) also left itself on top of
the cover windows its two links open, hiding their username fields:
"Create Account" tried to close the picker via the LOGIN window's
c2a selector (which matches nothing in the picker), and "Log Into
Another Account" never closed it at all. Both now close the picker —
in the reload flows only: the no-reload (popup) flows keep it open,
where it doubles as the fallback UI when the login/signup window is
abandoned mid-flow.

Picking an account was already correct (location.reload() keeps the
landing URL); with these fixes all three picker paths, plain login,
and signup all return to the app landing, where the boot replays the
launch and its intro.
2026-08-07 11:51:44 -07:00
jelveh 5538a5d24b feat(gui): let the deep-link intro step aside for users who know it
The intro exists to teach the dashboard's spatial model; once learned it
would only tax every bookmarked landing. Two mechanisms remove that tax:

- Interruptible: any real user input (pointer/key/wheel, isTrusted only)
  during the intro skips the remaining choreography and launches at
  once — it wakes the in-flight beat sleep, so the skip is immediate.
  Input never cancels the launch itself and is never swallowed;
  whatever it was doing (typing a search, clicking a tile) still
  happens.

- Exposure decay: after 3 delivered — or deliberately skipped — intros
  the beats collapse and the sequence plays in one breath, exactly like
  a warm tile click. Counted per account in kv (kv.incr, atomic across
  devices; capped at the threshold so the key stops changing) rather
  than per device: the lesson lives in the user's head and the account
  follows them, while localStorage would also bleed between accounts on
  a shared browser. Only real exposures count: a delivered flourish or
  an active skip with the grid on screen — hidden tabs, timeouts, and
  no-tile landings teach nothing and don't count. The animated page
  flip is exempt from decay: it isn't a repeated lesson, it's live
  wayfinding to where this app lives, and its settle is needed anyway
  to put the tile in view for the morph. Every failure mode (slow or
  failed kv read) errs toward teaching once more, never toward never
  teaching.

Also bounds the intro's wait on the app-list load by the same deadline
as the tile wait — fetch has no timeout of its own, so a stalled
installedApps request used to hold the deep-link launch hostage
indefinitely.
2026-08-07 11:23:47 -07:00
jelveh 14c14fb5c5 feat(gui): animate the pager flip when a deep-linked app lives on a later page
The deep-link intro used to flip to the tile's page instantly behind the
grid's load-fade, so landings on off-page apps woke up on page N with
nothing but the pager dots hinting a move happened. Now the grid always
reveals on its first page, holds the grid beat, and then visibly travels
to the tile's page before the tile's flourish — the journey shows where
the app lives, which is also where minimize will put it back.

Smooth scrollTo has no reliable completion event across engines, so the
travel uses a settle allowance (DEEP_LINK_INTRO_FLIP_SETTLE_MS, same
pattern as the drag code's DRAG_FLIP_SETTLE_MS): the scroll's ~450ms
plus a rest so the landing reads before the tile pops. First-page apps
skip the flip entirely and are unaffected; the hidden-page bail-out is
re-checked after the flip settles.
2026-08-07 11:12:03 -07:00
jelveh 41fc8d890b feat(gui): play the tile click→morph→open intro on /app/<name> landings
A direct landing on /app/<name> now plays the same sequence a real
Apps-tab tile click does — grid appears, a beat, the tile's icon ghost
pops out of its slot, a beat, and the window morphs out of the tile —
so the landing shows the user what is being opened and where minimize
puts it back.

TabApps.beginDeepLinkLaunch waits (3s cap) for the tile to be genuinely
visible (list loaded, render done, pager flipped to the tile's page,
load-fade revealed, icon painted), paces the beats, and claims the app
in _launchingApps so a click mid-intro can't spawn a duplicate. The
launch's app-info fetch is prefetched in parallel so the intro never
delays the app's own round-trip. No tile, animations off, reduced
motion, or a background tab (hidden pages throttle timers and defer
rendering) all skip straight to the immediate plain-fade launch.

Also fixes the tab title sticking as the app's name after closing a
deep-linked app: the landing's replaceState('/') committed the
dashboard's history entry while the page still carried the server's
app-name title, and Chrome shows an entry's stored title when close/
Back traverses onto it — document.title is now reset before the
replaceState so the entry is stamped with the dashboard's own title.
2026-08-07 10:34:21 -07:00
Reynaldi Chernando 45bdc46df0 Remove deprecated models 7 aug (#3522) 2026-08-07 23:20:50 +07:00
jelveh 82ca390bf4 fix(gui): create-in-folder via sidebar right-click renders in target dir
Right-clicking a sidebar/breadcrumb folder in the dashboard Files tab and
choosing New > Folder (or any file type) created the item in the right-
clicked folder correctly, but the UI inserted the new row and started the
inline rename in whatever directory was currently open — so the item
appeared to be created in the wrong place until a refresh.

Now, when the creation target isn't the directory on screen, navigate to
the target and run the select + rename flow there; same-directory
creation keeps the incremental insert.
2026-08-07 08:49:13 -07:00
Neal Shah edfd67a83c fix PUT-1444 (#3515) 2026-08-06 17:11:04 -04:00
404oops ff16ec8900 Add Neuralwatt support (#3509) 2026-08-06 17:01:33 -04:00
Daniel Salazar c7edfc0c74 perf: improve metering perf + add extra compat for monthly charges (#3513)
closes PUT-1445 and PUT-1446
2026-08-06 10:26:47 -07:00
velzie 09f30d693c Peer: allow anontoken in place of authentication (#3501) 2026-08-06 02:03:53 -04:00
Reynaldi Chernando a9ec15d121 Update NPM readme (#3510) 2026-08-05 17:07:02 -07:00
Daniel Salazar eb53c842dd fix: oidc issues with cache (#3512)
closes #3497
closes #3502
2026-08-05 17:05:31 -07:00
Daniel Salazar 1be5ce45f7 feat: support dekstop app linking again (#3511) 2026-08-05 14:16:02 -07:00
Neal Shah 294055e055 PUT-1436, PUT-1435, PUT-1371 (#3507) 2026-08-05 17:11:50 -04:00
jelveh 036008d8a7 fix: keep uninstalled recommended apps from resurrecting in the Apps tab
Uninstall only revokes permissions, but the recommended launch list is a
global hardcoded set that knows nothing about per-user revokes — so an
uninstalled recommended app's tile came back on every reload. Persist
uninstalled app names in kv (dashboard_removed_apps) and filter only the
recommended merge against them; installedApps is never filtered, so a
genuinely (re)installed app always shows.
2026-08-05 11:01:14 -07:00
Daniel Salazar 6df292f495 fix: PUT-1429 (#3508) 2026-08-05 01:17:34 -07:00
Daniel Salazar 40c8d09f05 fix: PUT-1401 (#3504) 2026-08-04 16:37:33 -07:00
meridah7 4a211b9092 docs: document the provider option and refresh the vendor list in chat() (#3505) 2026-08-04 16:22:03 -07:00
meridah7 24fc0b0e5f fix(ai-chat): infron default model is dropped by the aggregator alias rule (#3506)
* fix(ai-chat): use a resolvable default model for the infron provider

* test(ai-chat): assert the infron default model is in the served catalog
2026-08-04 16:21:55 -07:00
Nariman Jelveh f58772ec33 feat: swap browser favicon to the focused app's icon in dashboard 2026-08-04 14:16:32 -07:00
Neal Shah eb830799c0 add limit bypass (#3500)
* add limit bypass

* update test
2026-08-03 19:43:59 -04:00
jelveh 8df72ef343 fix: dashboard app drawer icon popping in late
The drawer resolved its own icon URL (a differently-sized variant under a
different URL than the dashboard tiles use), so its <img> fetched cold and
the icon popped in mid-intro. Reuse the bitmap an Apps-tab tile or Home-tab
recent already decoded — instant from the image cache; when nothing is
rendered yet (deep links), fade the icon in on load instead of popping, and
fall back to the generic app icon on a failed fetch.
2026-08-03 11:50:43 -07:00
jelveh 63b2fc34d9 feat: highlight pasted items in dashboard files tab
Pasted (copied or cut) items now land selected, the same treatment
uploads get. copy_clipboard_items resolves with the created items'
paths instead of firing and forgetting, moveClipboardItems returns
each move response's authoritative final path (with Keep Both the
landed name differs from the source's), and both dashboard paste
entry points refresh with strong consistency and hand the new paths
to selectUploadedRows. Pastes into a folder that isn't rendered match
no rows and the highlight is a no-op.
2026-08-03 06:52:40 -07:00
Nariman Jelveh 33d7324a24 feat: 'Keep Both' option in name-conflict dialogs (#3496)
Pasting or moving onto an existing name only offered Replace or
Cancel. Add a macOS-style middle ground: Keep Both retries the
operation with dedupe_name, landing the item as "name (1).ext" and
leaving the existing item untouched.

- puter-js move.js now forwards dedupeName to the wire (copy already
  did; move dropped it).
- All four conflict dialogs offer the new button: copy_clipboard_items,
  copy_items and move_items in helpers.js, and the dashboard's
  moveClipboardItems. Multi-item selections show
  Replace / Replace all / Keep Both / Skip.
- New keep_both translation key (other locales fall back to English).
2026-08-03 06:39:18 -07:00
Nariman Jelveh 62be61642d fix: phantom name conflict when pasting onto a just-renamed path (#3495)
Renaming (or moving) an entry left the OLD path's cache key serving
the pre-update entry for the full 60s TTL: updateEntry invalidated
only keys derived from the updated row, whose path is already the new
one. Pasting an item under the freed name then hit the stale cache in
the collision check and reported a conflict for a file that no longer
exists — and accepting the Replace it offered deleted the renamed file,
since the stale entry carries its uuid.

Read the pre-update entry when the patch changes the path and
invalidate its keys alongside the new ones. The move flow was shielded
by the outer.gui.item.moved cache-invalidation handler at the
controller layer; rename had no such band-aid, and fixing the store
covers every caller regardless of which events fire.
2026-08-02 23:53:59 -07:00
Nariman Jelveh 8cebbcf3be fix: thumbnails breaking after copy — duplicate the S3 object per copy (#3494)
A copied fsentry kept its source's thumbnail pointer verbatim, so both
rows shared one S3 thumbnail object. fs.remove.node deletes the
pointed-to object, so the first removal among the sharers — e.g. the
remove performed by a replace-on-copy — broke every other sharer's
thumbnail. FSService already emits fs.copy.node for exactly this
reason (its doc comment describes the duplication), but the thumbnails
extension never subscribed to it.

Add the missing handler: S3-copy the thumbnail to a freshly minted key
and repoint the copied row, under the same only-keys-we-minted trust
rule as the read/remove paths. If the shared object is already gone
(pre-fix damage), null the pointer instead of leaving the row
advertising a thumbnail it doesn't have.
2026-08-02 23:22:24 -07:00
Nariman Jelveh 5c2a423658 fix: progress window covering paste conflict dialog; ghost row after Replace (#3493)
* fix: progress window covering paste conflict dialog; ghost row after Replace

Pasting a copied file onto a name collision buried the Replace/Cancel
dialog under a stuck 'Preparing...' progress window, and answering
Replace left a stale duplicate row in every client.

- helpers.js: copy_clipboard_items armed its delayed progress window
  with a 0ms timer (its siblings use 2s), so the window opened
  instantly over the dialog. Use 2s, and in all three of
  copy_clipboard_items / copy_items / move_items pause the timer while
  a conflict dialog (or the own-location / trash-deny alerts) is
  waiting for input, re-arming it after. A window that opens
  mid-operation now shows the current file instead of a stuck
  'Preparing...', and the trash-deny bail no longer leaks a timer that
  opened an orphan window after the operation ended.
- LegacyFSController: /copy and /move dropped the legacy 'overwritten'
  response field and never emitted item.removed for the entry an
  overwrite deleted, so clients kept a ghost row until re-listing.
  Resolve the entry before the operation, return it, and emit
  item.removed on success.
- helpers.js: copy_items read resp[0].overwritten but removed
  resp.overwritten (always undefined), and the data-uid cleanup
  selectors were unquoted — invalid CSS when a UUID starts with a
  digit. Fixed all three sites.

* test: pin the v1 overwrite/collision wire contract for move and copy

The collision tests asserted only statusCode 409, which is how the
item_with_same_name_exists code regressed to 'conflict' unnoticed and
broke every replace/skip prompt in the GUI. Assert the legacy code and
entry_name explicitly, and add controller tests for the overwrite path:
the replaced entry must ride along as 'overwritten' in the /copy and
/move responses and be announced via outer.gui.item.removed so clients
drop its row.
2026-08-02 22:17:10 -07:00
Nariman Jelveh 1a9f025db6 fix: surface name collisions when pasting instead of failing silently (#3492)
Cut+paste onto a folder containing an item with the same name failed
with no feedback: the dashboard's moveClipboardItems swallowed the
error into console.error and cleared the clipboard, and the rewritten
backend broke the v1 wire contract the GUI's conflict prompts key on.

- FSService: move() and copy() collisions again return
  item_with_same_name_exists + entry_name (the contract the write path
  already preserves) instead of a generic 'conflict' code. This also
  restores the desktop's existing Replace/Skip dialogs, which were
  silently broken against the new backend.
- Dashboard: moveClipboardItems now mirrors the desktop's move_items
  conflict flow (Replace / Replace all / Skip / Cancel, retry with
  overwrite) and surfaces other move errors in an alert.
- keyboard.js: the desktop's global Ctrl+V handler threw an uncaught
  TypeError on every paste in dashboard mode (its file container has
  no data-path); guard it — which also prevents a double-paste if
  dashboard containers ever gain one.
2026-08-02 21:33:01 -07:00
jelveh a4667073f5 Update RecommendedAppsService.ts 2026-08-02 20:55:33 -07:00
jelveh 23d251e482 fix: dashboard files list blanking during same-directory refresh
Re-rendering the directory already on screen (after an upload, sort
change, undo, etc.) used to clear the list and show a spinner before
the readdir round-trip, blanking the pane for the whole fetch. Keep
the current rows visible until the fresh listing arrives, then swap
the DOM in one pass and restore the scroll position. Navigation to a
different directory still clears immediately.
2026-08-02 20:30:20 -07:00
jelveh 0c9dfb03e2 Show action bar only in mobile select mode 2026-08-02 19:49:14 -07:00
Nariman Jelveh 6dc928e0c3 fix: file picker dialogs going behind parent window when dragged by titlebar 2026-08-02 17:38:25 -07:00
Daniel Salazar 84582ee33d fix: alarm channels (#3491) 2026-08-01 15:55:06 -07:00
Daniel Salazar 116d6e6663 tests: big test push for better coverage (#3490) 2026-08-01 14:29:59 -07:00
Daniel Salazar 7d0d44aef9 feat: slack alarms (#3489) 2026-08-01 13:12:41 -07:00
Daniel Salazar 3ac6c8532e fix: open ai cost (#3488) 2026-08-01 12:34:36 -07:00
Nariman Jelveh f6a50c4fb4 Update recommended apps list order
Reorders and updates the recommended apps list: removes 'butler', 'code', and 'traffic-tap-puzzle'; adds 'contacts', 'diagram', and 'basketball-tap' (relocated from end); adjusts overall ordering of several apps.
2026-08-01 12:26:44 -07:00
Daniel Salazar c8113d7514 fix: auth message popups (#3487)
* fix: auth message popups

* remove v1 auth
2026-08-01 10:45:16 -07:00
jelveh 6159bc9ae1 Polish dashboard settings button styling
Update `.dashboard-settings-card .button` to use dashboard theme tokens for text, background, and borders, and add clearer hover/focus/active states with subtle elevation and transitions. Also override disabled styles in this context so dark mode no longer shows hard-coded light greys from the base `.button:disabled` rule.
2026-08-01 00:27:27 -07:00
Daniel Salazar 3a11d0d1f1 feat: sandboxed app workers (#3486) 2026-08-01 00:02:06 -07:00
jelveh 535cf5753e Merge branch 'main' of https://github.com/HeyPuter/puter 2026-07-31 14:14:11 -07:00
jelveh cee4a6ccce Improve app reorder mode on touch devices 2026-07-31 14:14:04 -07:00
Daniel Salazar 1f1f95c2f8 fix: auth me for local dev (#3484) 2026-07-31 14:04:59 -07:00
jelveh f600e857b0 GUI: touch reorder mode for the dashboard Apps tab
Long-press-to-drag can't be made reliable on touch: touch-action is
consulted at gesture start, so the pager's pan-x claims the finger
before a drag can begin (worst on iOS). Replace it with an explicit
edit mode - a cog button (touch-primary devices only) enters it, tiles
jiggle and drag on first movement, iOS-style x badges uninstall, and
Done exits. Drops still persist immediately, same as desktop.

Also raise the drag ghost above the window z-index bands; it was
rendering invisibly behind the fullpage dashboard window.
2026-07-31 13:46:17 -07:00
Neal ShahandDaniel Salazar 08d1708378 change cors auth path (#3464)
* change cors auth path

* undo oidc ref changes

* scary OIDC state changes

* fix: bad cors signin

* puterjs changes

---------

Co-authored-by: Daniel Salazar <[email protected]>
2026-07-31 01:55:01 -04:00
Nariman Jelveh f1bc065730 GUI: fix dev-server port-retry crash under Express 5 (#3482)
Express 5's app.listen wraps the listen callback in once() and also
invokes it on 'error', with the error as the first argument — at which
point server.address() is null, so the startup log threw a TypeError
and killed the process before the EADDRINUSE handler could try the
next port. Bail out of the callback when it receives an error and let
the 'error' listener own the retry.

Verified: with 4000 occupied the server now logs the retry and comes
up on 4001; with the port free it binds 4000 as before.
2026-07-30 18:11:12 -07:00
Nariman Jelveh b55782f066 GUI: add npm start --server=<domain> to run the GUI against a remote backend (#3481)
- npm start --server=puter.com (or -- --server=...) skips the local backend
  and serves the bundled GUI locally, pointed at the remote server's API.
  Bare domains resolve to https://api.<domain>; full origins are used
  verbatim. gui_origin points at the remote origin so /whoarewe, login,
  anti-csrf, socket.io, and builtin apps hit the real backend (CORS-open).
- --extensions=<dir>[;<dir>...] bundles out-of-tree GUI extension
  directories (sugar for PUTER_GUI_EXTENSION_PATHS). Their imports resolve
  as if the files lived in src/gui/src/extensions, with the extension's own
  files taking precedence, and bare imports fall back to the repo-root
  node_modules.
- Fix the bit-rotted dev-server: Express 5 wildcard routes, pass gui()
  params (previously called with none), inject the service_script shim,
  load bundle.min.js + bundle.min.css in prod mode, serve /sdk, and
  properly await the webpack build (it previously resolved immediately).
2026-07-30 16:29:54 -07:00
jelvehandClaude Fable 5 2c9ae3489e Suggested apps: rank registered apps above the editor fallback
For extensions with no intentional built-in mapping (doc, docx, and
every other unmapped type), suggestionsForExtension fell back to
['editor'], and #resolveForExtension always placed built-ins ahead of
apps from app_filetype_association. Since suggested[0] drives the GUI's
double-click open path and /open_item, a .docx defaulted to opening as
plain text in editor even when a word processor explicitly registered
the extension.

Tag the unknown-extension result as a fallback and order third-party
filetype-association apps ahead of it. Intentional mappings (code, txt,
md, images, pdf, media) keep built-ins in the head slot as before, and
the editor guess still appears as a last-resort option.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-30 13:51:01 -07:00
Daniel Salazar b28b41c90b otel: better telemetry numbers (#3480) 2026-07-30 13:23:16 -07:00
Nariman Jelveh f34c4dc335 Apps: normalize filetype associations to bare lowercase extensions (#3479)
* Apps: normalize filetype associations to bare lowercase extensions

Suggested-apps lookups match app_filetype_association rows against the
bare lowercase extension ('docx'), but writes stored whatever the
developer typed. Rows like '.docx' never matched, so those apps
silently dropped out of Open With suggestions.

AppStore now canonicalizes on write (trim, lowercase, strip leading
dots, dedupe, drop empties) and tolerates the dotted legacy form on
read: getAppsByFiletype normalizes the requested extension, matches
both 'docx' and '.docx', and dedupes apps associated under both forms.
Cache invalidation keys are normalized the same way. Existing dotted
rows work without a data migration.

* Update apps tests for extension canonicalization

Adjust apps API tests to match current normalization behavior for `filetypeAssociations`: extension values are stored as lowercase bare extensions (e.g. `.txt` -> `txt`), while MIME types remain unchanged. Added inline comments in both test suites to document this expected remap.
2026-07-30 13:13:14 -07:00
Daniel Salazar 5a157197b6 fix: PUT-1398 (#3478) 2026-07-30 01:42:40 -07:00
Daniel Salazar 8a711e0254 driver controller change (#3477)
* fix: launch app

* driver controller change
2026-07-30 00:41:29 -07:00
jelveh a22321daa2 Dashboard: closing a launched app goes home, not into its launcher
An app launched by another app minimizes its launcher (iOS-style
takeover). Closing the child then popped onto the launcher's history
entry, and the popstate handler restored it — so quitting an app threw
the user into a different full-screen app they had not asked for, zoom
animation and all. Closing an app should go home.

Mark the launcher when it is minimized FOR a child
(data-minimized_for_child). If it still carries that mark when the child
closes, the close's single history hop lands on the dashboard instead:
the entry is rewritten to the dashboard's route and the launcher is left
minimized, still running behind its tile's running dot. No extra history
traversal — the joint session history an app's iframe shares is exactly
what pop_dashboard_app_url's watchdog exists to survive, so the hop
count is unchanged.

Back is untouched and still returns to the launcher — that is the
navigation gesture, whereas close dismisses. Any restore (Back, tile
click, Forward) clears the mark, so quitting a child after the user has
brought the launcher back leaves the launcher alone.
2026-07-29 22:04:10 -07:00
jelveh fbf1bd18b1 Dashboard: an app launched by another app takes over the tab
In dashboard mode apps are full-tab experiences, but an app launched by
another app (puter.ui.launchApp) opened as a floating titlebar window
over its full-tab parent: the parent stayed on screen around its edges,
couldn't be raised (focusWindow never raises stay_on_top windows), and a
child with no Apps-tab tile had no switcher to come back to once
minimized.

Give child launches the same treatment as tile launches — maximized, so
they get the headless chrome and control drawer — and minimize the
parent behind them, iOS-style. State only: the parent's /app/<name>
history entry already sits beneath the child's, so Back from the child
(and the child's close, which consumes its own entry) lands on the
parent's entry and the existing popstate handler restores it. The parent
keeps running while hidden, so parent/child IPC is unaffected.

Explorer keeps its windowed form, background apps don't minimize their
parent, and an explicit `maximized` option still wins. Desktop mode is
untouched: both changes are gated on is_dashboard_mode, so an app
launching an app there still gets a floating child over a visible
parent.
2026-07-29 21:36:47 -07:00
jelveh dc371fc4eb Windows: keep dialogs and their apps in the stay-on-top z band
focusWindow re-raised a focused window's parent (and children) with the
bare z counter. For a file dialog owned by a fullpage/dashboard app that
DEMOTED the app out of the 99999999+ stay-on-top band it was created in,
burying app and dialog under every other open app window — opening a
file picker from an app stacked over another (e.g. an app launched from
Dev Center) made both vanish beneath the window below. The dialog itself
had the same flaw: raised into the plain counter band, under every app.

Raise each window within its own stacking band instead: stay-on-top
windows (and windows hanging off one through parent_uuid, walked up the
chain) get 99999999 + counter; everything else keeps the bare counter —
so desktop stacking arithmetic is unchanged. Same demotion family as the
showWindow restore fix in #3427.
2026-07-29 21:11:21 -07:00
jelveh 97e4e78df4 Dashboard files: drop the root crumb from the breadcrumb
Every path rendered as "> Puter > user > ...", but the root crumb is
noise on anything beneath it. Render it only at the root itself, where
it's all there is to show (the Up button can still reach /, and an
empty breadcrumb bar there would strand the user). Each crumb keeps
its leading caret, including the first.
2026-07-29 20:12:22 -07:00
jelveh 007649296b Keyboard: stop swallowing Enter when nothing claims it
The global Enter handler preventDefault'ed unconditionally, then
returned without acting unless a launch-menu item, context-menu item,
or selected item existed. That suppressed the browser's native Enter
activation on whatever was focused — a focused link or button (e.g. a
dashboard sidebar item, a dialog button) did nothing on Enter.

Move preventDefault/stopPropagation into the branches that actually
handle the key; otherwise fall through so native activation runs. The
handled paths are unchanged: Enter still opens the selected item,
launch-menu entry, and context-menu entry.
2026-07-29 19:40:16 -07:00
jelveh 9392aed402 Dashboard: restyle keyboard focus ring on sidebar controls
Sidebar items (and the user/collapse/close buttons) had no
:focus-visible style, so keyboard focus painted the UA's default blue
ring — hard-edged and bleeding outside the item. Use the dashboard's
own selection ring instead, tucked inside the control so it hugs the
rounded corners. :focus-visible only, so mouse clicks never paint it.
2026-07-29 19:40:06 -07:00
jelveh 32e417fe79 Dashboard files: clicking an open file returns to its window
In dashboard mode there is no taskbar, so a minimized app window's only
switcher was its Apps-tab tile — invisible from the Files tab. Opening a
file, minimizing, and clicking the file again launched a second instance
of the app, stranding the first (and any unsaved edits) somewhere
unreachable.

Make the file row itself the switcher:

- launch_app stamps the opened file's uid on the window (data-file_uid;
  the signature's uid wins so shortcuts resolve to their target)
- open_item (dashboard mode) restores/focuses an existing window that
  has the file open instead of launching a duplicate, mirroring the
  Apps-tab tile's single-instance behavior — keyed by file, not app, so
  opening a different file still gets its own instance
- re-clicks while a launch's fetches are still in flight are swallowed
  (same idea as TabApps._launchingApps, keyed by file uid, TTL'd so a
  failed launch can't swallow clicks forever)
- dashboard file opens now default to maximized, so they get the same
  headless full-tab chrome + control drawer as tile launches instead of
  a floating titlebar window
- rows show a dot while their file is open in a (possibly minimized)
  window — under the name in grid view, inline after it in list view —
  driven by the existing dashboard-app-windows-changed event

Desktop mode is untouched: the reuse branch and maximized default are
gated on is_dashboard_mode, and opening the same file twice there still
creates two windows as before.
2026-07-29 19:03:33 -07:00
Daniel Salazar 0e1f617401 fix: errors for bad keys (#3475) 2026-07-29 15:58:53 -07:00
Felix-Ayush bd6efaaa4e fix(puter-js): ignore peer offers for unknown connections (#3473)
createAnswer ran outside the connection null-check, so stale or unknown
offer ids threw on the signalling socket. Guard the whole offer path and
return the #message promise from onmessage so callers can observe errors.
2026-07-29 15:58:39 -07:00
Nariman Jelveh 2b6dc528ce Merge branch 'main' of https://github.com/HeyPuter/puter 2026-07-29 15:48:21 -07:00
Nariman Jelveh 9368ad57b6 Preserve UI state across tab visibility refresh 2026-07-29 15:47:59 -07:00
Felix-Ayush e97d338f3a fix(ai-chat): preserve max_tokens 0 for Alibaba, DeepSeek, and Claude (#3472)
These providers used `max_tokens || default`, so an explicit zero was
replaced by the fallback. Use nullish coalescing so 0 is forwarded.
2026-07-29 18:38:31 -04:00
Nariman Jelveh a87a517b82 Anchor file row menu to button edge
File row overflow menus in the dashboard now open anchored to the ⋯ button (below it with right-edge alignment) instead of pointer position, improving placement consistency. UIContextMenu now supports `position.right` for right-edge pinning, and the ⋯ trigger keeps an active visual state while its menu is open so hover styling doesn’t drop when the cursor moves onto the menu.
2026-07-29 15:25:51 -07:00
Nariman Jelveh dbb52171c8 Refine dashboard file row hover styling 2026-07-29 15:05:21 -07:00
Daniel Salazar 6c020318f9 perf: traces and perf improvements (#3471) 2026-07-29 14:35:15 -07:00
Nariman Jelveh e16994db3b Fix I-beam cursor on dashboard file rows in Safari
Safari ignores user-select: none for cursor styling, showing a text I-beam over file rows. Setting cursor: default explicitly fixes this and is inherited by child elements.
2026-07-29 14:18:50 -07:00
Daniel Salazar 8491a0b55d fix: limit api pointing to apps only (#3470) 2026-07-29 14:03:27 -07:00
Felix-Ayush 710e4da4c0 fix(puter-js): size img2txt data URIs by decoded bytes (#3457)
Match speech2txt/speech2speech and reject on decoded payload size, not
data-URI string length. Base64 expands ~4/3, so string-length checks
falsely rejected valid images under the 10MB limit.
2026-07-29 12:21:21 -07:00
Felix-Ayush fd1f4e2ac2 fix(puter-js): forward temperature 0 and max_tokens 0 in ai.chat (#3455)
Truthy checks dropped legitimate zero values, so deterministic sampling
never reached the driver. Match the stream option and use !== undefined.
2026-07-29 12:21:15 -07:00
Kobi Hikri 70bf03a6e7 ci: attach provenance and SBOM attestations to the published image (#3463) 2026-07-29 12:21:02 -07:00
Felix-Ayush 6f90d7a199 fix(ai-chat): forward temperature 0 and max_tokens 0 to providers (#3456)
Completions-family providers used truthy spreads, so temperature: 0 and
max_tokens: 0 were stripped before the SDK call. Align with Responses
providers that already use !== undefined.
2026-07-29 11:49:36 -07:00
Daniel Salazar f0b1947c54 feat: make uninstall also revoke + dashboard css changes (#3469)
* feat: make uninstall also revoke

* fix: wording for free trial
2026-07-29 10:40:43 -07:00
Daniel Salazar 92193ff11f chore: kill collector (#3466) 2026-07-28 19:02:49 -07:00
Daniel Salazar f9396b7283 fix: thumbnail res (#3465) 2026-07-28 17:31:01 -07:00
Sauhbagya PrasadandDaniel Salazar 7cf3e03433 Replaced Nginx with Caddy (#3378)
* Replace nginx with Caddy

* updated caddy location

* seprate logic for local and with domain caddy setup

* updated install

* updated install scripts

new ps1 script with caddy, and removed instances of nginx

* fix Caddy Host routing, restore TLS/SELinux/healthcheck, update docs

---------

Co-authored-by: Daniel Salazar <[email protected]>
2026-07-28 14:52:13 -07:00
Neal Shah 0a61b4e78b add fixes 1 (#3458)
* add fixes 1

* change socketio test

* clarify that success/error callbacks are legacy

* fix wisp issues
2026-07-28 17:34:12 -04:00
Reynaldi Chernando 1db4324c02 remove deprecated ai models (#3444)
* remove deprecated ai models

* test

* fix tests
2026-07-28 12:41:04 -07:00
Daniel Salazar 69529ee0db perf: try to improve app opens speed (#3462)
* perf: try to improve app opens speed

* make /rao non blocking to allow faster conn swap
2026-07-28 11:12:44 -07:00
Daniel Salazar 7a7ff47442 chore: bump version (#3461) 2026-07-27 23:59:51 -07:00
Daniel Salazar 148771a82b fix: performance degradations in app fetching + puter-js module parent class (#3460)
* fix: centralize module methods in parent class

* fix: performance degradations in app fetching
2026-07-27 23:41:51 -07:00
Daniel Salazar 5bad6a972f fix: puter-js cleanup around docs and ai resolution (#3459)
* fix: puter-js cleanup around docs and ai resolution

* more jsdoc stuff

* fix: docs

* fix: doc types + misc hardening

* fix: harden auth
2026-07-27 22:31:05 -07:00
Luke Oliff 8bb7d59527 feat: add Speechify TTS driver (puter-tts) (#3453)
* feat: add Speechify TTS driver

Adds a SpeechifyTTSProvider under the ai-tts driver (mirrors the xAI/
ElevenLabs REST-provider shape), registered in TTSDriver alongside the
existing providers. Wires puter-js txt2speech with provider: "speechify"
support, default voice/model, and the speechify-tts driver alias.

Every outbound request sets Speechify-Caller: puter; base URL is
https://api.speechify.ai only; default model is simba-3.2.

* fix: replace placeholder voice IDs with real simba-3.2/simba-english voices

DEFAULT_VOICE and the starter voice catalog used invalid IDs (henry,
cliff, kristy, george, aria) that the real API rejects with 400. Swapped
in confirmed-real voices from a live GET /v1/voices call: geffen_32,
dominic_32, harper_32, hugh_32, imogen_32, and alec for the
simba-english model-override test.

* fix: purge remaining placeholder voice IDs from client, docs, and types

The previous fix only covered the backend provider — the client-side
default in tts.js, its test, the txt2speech docs page, and the ai.d.ts
type comment all still referenced the invalid henry/cliff/kristy/george/
aria set. All replaced with the live-verified voices (geffen_32 default).
Also corrects the docs link to docs.speechify.ai.
2026-07-27 17:04:11 -07:00
Neal Shah 8732494442 dead code cleanup (#3441) 2026-07-27 17:51:15 -04:00
Daniel Salazar cade75ac9b fix: PUT-1385 PUT-1382 PUT-1381 PUT-1380 PUT-1379 (#3454) 2026-07-27 11:42:40 -07:00
meridah7 9abc9d1a19 feat: add Infron AI chat provider (#3433)
Adds Infron (https://infron.ai) as an aggregator provider for the
puter-chat-completion driver, following the OpenRouter provider as
reference per doc/contributing-apis.md.

- OpenAI-compatible gateway at llm.onerouter.pro/v1
- Dynamic model catalog (kv-cached 15 min, authenticated fetch),
  filtered to chat-capable LLM entries
- Bills the gateway-reported authoritative cost when present
  (usage: {include: true}); falls back to catalog per-token pricing
- Registered as an aggregator so its aliases never shadow
  first-party providers
- Offline unit tests (mocked SDK/axios against a real test server)
  plus an env-gated integration test
2026-07-27 08:38:04 -07:00
Nariman Jelveh f3fd8a30da Rework permission requests: new dialog, working popup flow for websites (#3447)
* Rework permission requests: new dialog, working popup flow for websites

- Replace the UIWindow-based permission prompt with a standalone top-layer
  <dialog> (responsive, light/dark, app/site identity, input protection)
- Implement puter.ui.requestPermission for env=web: opens the GUI's
  /action/request-permission popup with pinned origin/source/msg_id,
  popup-closed detection, and a check-permissions polling fallback for
  crossOriginIsolated openers
- Move the GUI's request-permission action into postAuthActions so
  signed-out users sign in first; identify the app by opener origin,
  correlate responses with original_msg_id, close the popup after answering
- Always respond from the IPC handler so the SDK promise can't hang;
  normalize the result to a strict boolean (a failed grant no longer
  resolves truthy)
- Accept origin in /auth/grant-user-app and /auth/revoke-user-app,
  mirroring grant-dev-app (fixes puter.perms.grantOrigin/revokeOrigin)
- Add Playwright e2e coverage for both the desktop and popup flows;
  update e2e harness for the auth_token_v2 localStorage key
- Update types and docs (perms request methods now work on websites)

* Harden permission request flows

- Grace period before treating popup close as denial: the GUI posts the
  decision then closes the popup, and postMessage delivery is not ordered
  relative to `closed` becoming true, so a grant could race to a false
- Unique popup window name per request so window.open name-reuse can't
  hijack a still-pending request's popup
- request-permission action always answers the requester and closes the
  popup, even when app resolution or the dialog throws
- Permission dialog: refuse unidentifiable requesters, allowlist icon URL
  schemes, and time out the grant request into the retryable error path
- Validate app_uid/origin/permission types and length in grant-user-app
  and revoke-user-app
- Tests: revoke-by-origin and input-validation backend tests; e2e for
  dialog dedup, unsupported permissions, and the consent-dialog path

* Sign in first in the requestPermission fixture's email flow on the web

In env=web the site has no auth token, so whoami threw 401 immediately
and the email button appeared to do nothing. Sign in via popup first,
matching the real third-party flow; env=app already has a token and is
unaffected.

* Point the requestPermission fixture at the real api subdomain

The SDK sends credentialed CORS requests; the GUI host doesn't answer
with Access-Control-Allow-Credentials, so whoami (and any authed call)
from the fixture origin failed CORS and looped through retries.

* Fix /auth/list-permissions schema mismatches

The endpoint's queries referenced columns that don't exist:
user_to_app_permissions stores a numeric app_id FK (not app_uid), and
user_to_user_permissions uses holder_user_id (not target_user_id) —
every call 500'd. Join apps to expose the app's uid and use the real
column names.

Replace the catch-either-branch test (which documented the breakage
instead of failing on it) with real assertions covering all three
sections of the response.

* Identify permission requesters by origin only

The request-permission action took `app_uid` straight from the query
string and used it as the grant target whenever the origin was absent or
unresolvable. Now that /auth/grant-user-app accepts `origin` and prefers
`app_uid` when both arrive, the displayed identity and the grant target
could diverge; with only `app_uid` in the URL the dialog rendered with an
empty name, so a link could produce a bare "Allow" prompt for an unnamed
requester. Resolve the uid from the origin alone, and let the server
resolve it from that same origin when the client lookup fails.

Also give the no-gesture consent popup a unique window name. UI.js does
this on the direct path because window.open() reuses a window with a
matching name, but the PuterDialog fallback opened under the default
'Puter' — the same name sign-in uses, so a consent click could navigate
an in-progress sign-in popup away.

And guard the IPC responder: an app that closes its own window while the
dialog is up leaves target_iframe.contentWindow null.

* Keep the permission popup from signing the site in

The popup loads the GUI with embedded_in_popup=true, so it ran the
sign-in token exchange and posted puter.token to the opener before the
user answered the prompt. A site that called requestPermission() walked
away holding a user-app token for the account even when the user pressed
"Don't Allow" — and because the SDK's global puter.token handler feeds
event.data.token into setAuthToken() without looking at `success`, a
failed exchange posted token: null and wiped a token the site already
had. Keep running the exchange (it bootstraps the app row the grant
needs and caches host_app_uid) but leave the token in the popup. A site
that wants credentials still has to call signIn().

Escape on the SDK's consent dialog left the caller pending forever.
PuterDialog wired its Cancel and close buttons but not the <dialog>'s
native cancel event, so the browser dismissed the dialog and nothing
reported it: no dialog, no popup, no answer. Route cancel to the same
handler. Programmatic close() fires only `close`, so launching the popup
— which closes this dialog — is unaffected, and the implicit-auth flow
stops hanging on Escape too.

Serialize the permission dialogs. showModal() makes the whole document
inert rather than just the requesting app's window (which is what the
UIWindow it replaced did), and the dedup map only coalesced identical
requests, so an app asking for permissions in a loop stacked one modal
per request and walled the user off from the desktop — including from
the app doing it. Prompts now queue and open one at a time, and each
caller still gets its own decision.

Identify apps by more than their title. `title` is free-form text the
author picks and is not unique, so it was the whole identity of a prompt
an app titled "Puter Settings" could raise; the registered `name` is
unique and format-restricted, so show it underneath. Give the name line
the unicode-bidi isolation the origin line already had, since escaping
leaves bidi overrides intact.

Stop the dialog from answering over its own in-flight grant: a dismissal
while the POST was outstanding resolved false for a permission the server
was committing. Ignore dismissals while granting, and time-box the
request with AbortController (AbortSignal.timeout isn't everywhere) so a
hung network can't leave a modal no one can close. Fail closed on the
remaining paths that could reject or prompt uselessly — showModal()
throwing under <iframe sandbox>, and a requester known only by app_name,
whose Allow the server would always reject. Pass the error string to
.text() unencoded so translations containing an apostrophe don't render
&#39;.

The e2e suite covers all of it; each new test fails without its fix.

* Restrict the permission popup flow to third-party websites

requestPermission's new web path ran in every environment with a window,
including env='gui' — so a permission_denied driver retry inside the
Puter GUI would open a popup to the Puter origin from the desktop itself
and try to grant the permission to a phantom app for Puter's own origin.
Resolve false everywhere except env='web', the previous behavior.

* Settle the permission dialog when a failed grant has no dialog left

The cancel handler is preventDefault'd, but close requests can't be
suppressed forever: Chrome's close watcher lets a repeated Esc skip
cancel and force-close the dialog while the grant POST is in flight.
The close handler defers to that grant on purpose — but if the grant
then failed, fail_grant re-enabled buttons on a closed dialog and the
promise never settled, leaving the requesting app waiting forever.
Settle as a denial when the dialog is no longer open.

Also add regression tests for this and for the popup-flow env guard
(routing the CDN SDK URL to the local build, since the prod-built GUI
loads its SDK from js.puter.com).

* Withhold the auth token on the popup's first-visit paths

Keeping the token inside the permission popup only covered the plain
token exchange. Two other popup paths mint a user-app token and posted
it to the opener unconditionally: first-visit temp-user creation, and
the manual signup shown when temp users are refused. Both sit on the
path a brand-new visitor takes — the audience the website popup flow
exists for — so a site that asked about one permission and was denied
still walked away holding a token, for a temp account or a real one.
The SDK's global puter.token handler feeds whatever arrives straight
into setAuthToken(), so posting it is the whole of it.

Move the rule into util/popupAuth.js and consult it at every site that
posts the token, so the next token path has one place to ask.

The first-visit path also left the prompt itself unreachable: it waits
on the spinner promise, which only resolves when the spinner was up for
under 2s. End that wait for any action that keeps the popup open;
sign-in still closes the window as before.

The e2e test fails without the fix — the site holds a token after the
user presses "Don't Allow".

* Poll for the decision when the popup's opener is severed

crossOriginIsolated was the test for "the popup can't message us back",
but being isolated also requires COEP. A site sending COOP: same-origin
on its own still has its opener relationship severed when it opens the
Puter popup, and took the watch-the-window path instead — where the
detached proxy reports closed === true on the first tick, so
requestPermission resolved false about a second after the popup opened,
while the user was still reading the dialog. Their "Allow" then had
nowhere to go. Treat an already-closed popup as severed and poll.

Pin the expected event.source before those early returns. popupWindow
was assigned after them, so for the whole consent-dialog wait — as long
as the user takes to click Continue — the handler accepted a decision
from any window on the GUI origin. A forged answer is only advisory
since the grant is written server-side, but the check may as well hold.

Settle instead of rejecting when the consent dialog can't be appended:
document.body is null in a <head> script, and the throw both rejected a
promise documented to resolve to a boolean and left the message listener
behind.

* Key the dialog dedup by the identity its gate accepts

The gate treats an empty app_uid as absent and falls through to the
origin; the dedup key used ?? and kept the empty string, so two requests
from different origins would collide on one key and share a single
decision. No caller can produce a blank uid today — server uids are
never empty and the IPC path's empty attribute is stopped by the gate —
but the two lines have to agree.

* Close the gaps the permission-request flow left open

Seven defects found reviewing the new permission flow end to end, each
reproduced against a running server before being fixed.

Security:

- `cross_origin_isolated=true` bypassed `deliversTokenToOpener` entirely.
  That branch is checked first, mints a user-app token, publishes it via
  `/login/set` and returns — so one query parameter on a
  request-permission URL skipped the prompt and handed the opener a token
  through the unauthenticated `/login/wait`. Gate it with the same rule.

- Grant/revoke by `origin` could land on an unrelated app. An origin with
  no app row synthesises `app-<uuidv5>`, and the permission services
  resolve their identifier as uid *or name* — and the uuid namespace is a
  source constant, so the string is computable offline and registrable as
  an app name. Resolve origins to a uid that names a real app row.

- A website's host was elided on the right, hiding the registrable domain
  that says who is asking. Elide it from the left, as the sibling rule
  already intended.

- A grant whose response was lost (client-side abort, dropped reply) left
  the row committed while the dialog reported a denial. Withdraw it when
  the user then answers "Don't Allow".

Correctness:

- `pollDecision` needs the site's own token, which a permission popup
  deliberately never delivers, so a signed-out cross-origin-isolated site
  burned the full five-minute timeout before answering. Answer at once
  when there is nothing to poll with.

- `getUserAppToken` reports failure by returning null, and three callers
  read `.app_uid` off it. Guard all three, keep the first-visit spinner
  promise settling on its failure paths, and dispatch the `login` event on
  the manual-signup path so `postAuthActions` runs at all — a user who
  signed up inside a permission popup got a blank window and the site got
  no answer.

- Time-box the lookups that run while a request holds the dialog queue's
  slot: they have no timeout of their own, and a stall (not a failure)
  wedged every later permission request in the page.

Also harden the grant/revoke input validation the PR introduced — it
skipped `extra`/`meta`, so a non-object faulted *after* the row was
written, and its length cap was 16x the column it lands in — stop a
non-URL `origin` from throwing past the answer-and-close, and drop the CSS
left behind by the deleted dialog.

* Close three gaps left in the permission-request flow

Each was reproduced first — the squatting grant against a running server,
the COOP timing in a real browser — and each fix was then confirmed by
reverting it and watching the new test fail.

Security: the dialog could name one site and grant to another.

The squatter guard added for grant/revoke by `origin` only ran when
`app_uid` was absent, and the dialog sends both — so `app_uid` won and the
guard never applied. `getAppUIDFromOrigin` returns the synthetic
`app-<uuidv5(origin)>` for any origin with no app row of its own, and the
grant endpoint resolves `app_uid` as uid *or name*, so the grant landed on
whoever registered an app under that computed name (the format allows it,
and the namespace is a source constant). A link like
`/action/request-permission?origin=https://a-site-you-trust.example` named
that site in the prompt while "Allow" handed the permission elsewhere.

Fixed on both sides of the wire. The action now sends the origin alone —
no uid resolved in the browser is safe to forward, whatever its source —
and a supplied `origin` now decides the target on the server even when an
`app_uid` travels beside it: the origin is what the prompt showed the
user, so it is what the grant has to follow.

Correctness: a COOP-only site was answered before the user decided.

7efc0c0b routed a severed opener to `pollDecision` by treating an
already-closed popup as severed, but that reads `closed` synchronously
after `window.open()` — before the navigation whose response headers cause
the severing has committed. Measured in Chromium: `closed` is false at
0ms and true by 200ms. So a site sending COOP: same-origin without COEP
still took the watch-the-window path, and `requestPermission` resolved
false 1.1s after the click while the dialog was still on screen. The
"Allow" that followed committed a grant the site had been told it did not
get. Tell the two apart by when the close lands, and keep the in-flight
message's grace period on both branches — an answer already on its way
outranks whatever the close is taken to mean.

Correctness: a grant that timed out was not withdrawn.

`grant_may_have_committed` was only set in the fetch's `catch`, which
cannot run until the timeout's timer callback returns — and that callback
already calls `fail_grant`, which settles the dialog as a denial outright
when the dialog was force-closed mid-grant. The reconciliation was
skipped in exactly the case it exists for. Record the unknown outcome in
the timer, where the timeout already means the request left the browser.

Also require a `token` from the user-app exchange rather than just a
non-null body: an HTTP failure (a blocked origin, a 5xx) returns the
parsed *error* body, which is truthy, so the guard added for this missed
it — handing the opener an `undefined` token, and prompting for a grant
whose app row was never bootstrapped.

Known limitation, now more reachable: a severed opener cannot signal a
denial at all, since nothing is written for one, so those sites wait out
the poll timeout before receiving false. A grant still resolves promptly.

* Deliver the uncertain-grant withdrawal from a closing popup

The permission dialog reconciles a denial after an uncertain grant by
firing a revoke in the background, but the popup flow posts the answer
and closes the window right after settling — and a plain fetch is
cancelled with its document, so the withdrawal never reached the server
and the user was told "denied" while the grant stayed live. Send it
with keepalive so the browser delivers it independently of the popup,
and cover the popup flow with a regression test (the existing
withdrawal tests only exercise the desktop flow, where the GUI
outlives the dialog).

Also make the popup boot's getAppUIDFromOrigin guard functional: the
helper reports failure by resolving to a null/undefined uid, not by
throwing, so the catch never engaged and a failed lookup clobbered
window.host_app_uid with undefined despite the comment claiming the
token exchange's value was kept.

* Keep the ai-chat model-map build inside the server lifecycle

onServerStart fired #buildModelMap without awaiting or tracking it, so
the network fetches it does (notably Ollama auto-discovery, which is
enabled by default and doomed on any machine without a local Ollama)
kept running after server.shutdown() resolved. In vitest that let the
provider's console.error land during worker teardown, which surfaces as
"Closing rpc while onUserConsoleLog was pending" — the unhandled error
that intermittently fails CI (last seen attributed to
WispController.test.ts). A rejection in the detached chain would also
have been an unhandled rejection.

Track the promise, catch and log rejections, and await it from
onServerShutdown so no provider I/O or logging outlives the server.
Also disable Ollama auto-discovery in setupTestServer's defaults —
every test server was firing a pointless model-list fetch at localhost.

* Settle requestPermission on the launch paths that could still throw

Three gaps left by the permission-request rework, each verified against a
live stack before and after the fix.

The IPC handler normalises a non-object `options` so it can always reply,
but `typeof null === 'object'` let null through the guard; reading
`.permission` off it threw out of the message listener before any reply,
so `puter.ui.requestPermission(null)` hung forever in env=app while
env=web answered false for the same input.

In the env=web branch only the consent-dialog path was wrapped, even
though its own catch reasons that this resolves to a boolean for every
other caller. A `window.open` refused by throwing rather than by
returning null escaped the launch branch and rejected instead.

The perms docs were flipped to platforms: [websites, apps], but every
entry point except `request()` reads the signed-in user's identity
first, so on a signed-out site they reject with Unauthorized and never
prompt — the permission popup deliberately does not sign the site in.
Document the sign-in precondition on those pages.

* Measure a permission's width after the rewrite that decides it

The new grant validation capped `permission` at 255 to match the column
it lands in, but it measured the caller's raw string. `fs:/path:mode` is
rewritten to `fs:<uuid>:mode` before storage, so what lands in the column
is ~44 characters however deep the path is. Granting access to a deeply
nested file therefore returned 400 even though the identical target
granted by uuid returned 200 and stored 44 characters — and because a 4xx
is read as an outright refusal, the permission dialog showed its
retryable error and could never succeed on retry.

Bound the request body only against absurd input, and enforce the column
width in the permission service on the rewritten string, before the app
is resolved so an oversized permission still refuses ahead of a missing
app. Covered both ways: a rewritten-short permission is accepted, and one
that no rewriter shortens is still refused.

* Require a registered app when a dev-app grant names an origin

The user-app handlers resolve a caller-supplied origin through
#registeredAppUidFromOrigin because appUidFromOrigin synthesises
app-<uuidv5(origin)> for an origin with no app row, and the permission
services resolve their identifier as uid-or-name — so the synthetic uid,
derived from a published namespace constant and computable offline,
lands on whoever registered an app under that literal name. The dev-app
handlers were left resolving the raw synthetic uid.

That leg matters at least as much: a dev-app grant is scanned with the
issuer's authority for anyone running as that app, so a squatted grant
hands over the granting user's permission. Verified against the store —
the grant landed on the squatter rather than rejecting.

Without a squatter the synthetic uid resolves to nothing and these
already 404, so the guard costs the legitimate case nothing; a test
covers a registered origin still resolving to its app.

Also assert that revoke accepts the same oversized-but-rewritten
permission grant does, since the dialog's withdrawal of an uncertain
grant depends on that symmetry.

* Revoke the row a user-app grant actually wrote

`app-root-dir:<uid>:<mode>` is a pseudo-permission: its rewriter resolves
it to a real `fs:<root_uid>:<mode>` only while a user-app permission row
is being written, and resolves to a match-nothing sentinel at all other
times so a scan can't match through the fs path.

Revoke shared that rewrite but not the flag, so it aimed the DELETE at
the sentinel: it removed nothing and reported success while the fs
permission stayed live. The permission dialog withdraws a grant whose
outcome it couldn't confirm through exactly this path, so a user who
answered "Don't Allow" after a dropped grant response kept the access
they had just refused.

Grant and revoke now share one rewrite helper. It also has to work for a
caller outside a request scope — an internal job, or a direct unit test —
where `Context.set` has nothing to set the flag on; an empty scope reads
the same as no scope, so it only makes the flag settable.

* Elide a long host from the left, as its own rule intends

The identity line is the only thing on the permission dialog naming the
requester, so a host too long for the dialog has to lose its front, not
its tail: the registrable domain is the part that says who is asking.

`direction: rtl` was there for that, but paired with
`unicode-bidi: plaintext` it does nothing — plaintext takes the base
direction from the content's own first strong character, which for any
Latin host is LTR, so the ellipsis went back on the right. Measured in
the real dialog, `account-security.paypal.com.verify-login.example`
rendered as `account-security.paypal.com.verify-l…`, reading as PayPal.

Isolating instead keeps the box anchored to the end of the text, and
still stops a bidi control character in the host from reordering
anything around it.

The test that covers this asserted the computed `direction` — the
property, not the outcome — so it passed throughout. It now measures
which characters are actually on screen, and that the host still reads
in source order.

* Tell a severed opener from a closed one by whether it can answer

The web popup flow decided which it was looking at by timing: a
`popup.closed` flip within 3s of `window.open()` was COOP severing the
opener, anything later was the user closing the window. Both halves
misfire, and both were reproduced against a real popup.

A COOP-only site whose popup navigation commits after the cutoff had its
severing read as a close, so the site was told "denied" about a second
later — while the prompt was still coming up. The Allow the user went on
to click then committed a grant the site had been told it did not get,
which is the failure the cutoff was introduced to prevent: how long a
navigation takes says nothing about whether the opener survived it.

The other way round, a signed-in site whose user dismissed the popup on
sight had that close read as severing, and fell back to polling for a
decision. A denial writes nothing to poll for, so the caller waited out
the full five-minute timeout instead of being answered.

So ask the question directly: the popup now announces itself to its
opener, which it can only do while the relationship is intact. Having
heard from it proves a later close is a real close and the answer is now;
never hearing from it means the prompt may be live in a window that
cannot answer, and the decision is read back from the server as before.
The announcement carries no token, and goes out before any sign-in gate —
a gate that delayed it would make abandoning sign-in look severed.

Measured: the popup announces itself ~290ms after opening, and a close
just after that is answered in ~1.3s rather than five minutes.

* Stop revoking a literal `*` after a dev-app revoke-all

The `*` arm of /auth/revoke-dev-app fell through: after
`revokeDevAppAll` it also ran `revokeDevAppPermission(…, '*')`, a
DELETE naming a row called literally `*` — which matches nothing —
plus a second `revoke` audit entry for the same action. The user-app
twin already if/elses its two arms; the dev-app handler now matches it,
and a test pins the parity: everything revoked, one audit row.

* Match the popup's messages against a canonical GUI origin

The web flow compared `event.origin` to `puter.defaultGUIOrigin` as raw
strings, but they are different kinds of value: the event carries the
browser's canonical origin serialization, while the configured origin is
whatever text was supplied — a trailing slash, an explicit default port,
or a stray path all name the same origin and all fail the comparison.

The mismatch doesn't read as a config error, it reads as the user's
answer: with every message from the popup dropped, the missing
`permissionPromptReady` makes the popup's close look like a severed
opener, and the missing decision leaves that path to answer on its own —
"denied", for a guest, moments after the user clicked Allow and the
grant committed.

Parse the configured origin once and compare canonical-to-canonical; the
popup URL is built from the same parsed origin, so a trailing slash no
longer yields a `//action/...` path either. A configured origin that
cannot parse could never have hosted the prompt, so it now denies up
front instead of opening a broken window. Pinned by an e2e test that
re-points the SDK at the same GUI through a trailing-slash origin and
expects the grant to be heard; it fails against the raw comparison.

* Take a permission popup's requester from the browser, not the link

`app_uid` was removed from the request-permission URL because the uid
names who receives the grant, so it has to come from the requesting
origin rather than from whoever built the link. Two other parameters
still carried exactly that identity, and the origin is the identity
twice over: it is the name the dialog attributes the request to, and it
is what the server resolves into the app the grant is written against.

`opener_origin` is believed on every popup boot, ahead of the referrer.
`origin` was the fallback in the request-permission block itself,
reached whenever there is no opener at all. Either one lets a bare link
raise a consent prompt in some other app's name — the token exchange
bootstraps an app row for whatever origin was typed, so the grant then
commits against it — while the user is looking at a domain the requester
does not control. That is the whole dialog defeated: a site can name
`docs.google.com` and have the Allow land on Google's app row.

So a permission popup now takes only an origin the browser vouches for:
`document.referrer`, or the opener's own reply to the `requestOrigin`
handshake. Neither can be forged to another origin. Nothing legitimate
relied on the parameters — the SDK sends neither, and the OIDC redirect
`opener_origin` exists for drops `action` too, so no permission flow can
arrive through one. The `origin` fallback only ever fired when there was
no opener, which is to say when there was no requester either; that path
now reports its denial as usual instead of prompting.

The referrer is safe here precisely because `action` is only
`request-permission` on the popup's first load, so it is always the
opener's. Restoring the action across an OIDC hop would break that — the
returning navigation's referrer is the identity provider — which is why
the round trip is withheld rather than repaired:

A popup that signs in through OIDC comes back to a redirect URI the
server hard-codes to `/action/sign-in`, so it returns believing it is a
plain sign-in popup. It posts `puter.token`, which the SDK's global
listener feeds straight into `setAuthToken()`, and never runs the action
it was opened for. For a permission prompt that is the exact outcome
`deliversTokenToOpener` exists to prevent: the site is signed in without
ever asking, the user is never shown the permission they were brought
there to decide, and the request resolves as a denial. Nothing in the
returned URL says what the popup was for, so it cannot recover on its
own. Until the redirect can carry the action back — and the opener
origin can be re-established from the handshake on return — a popup
whose purpose cannot survive the hop does not offer the hop. Email
sign-in stays in the window and is unaffected.

Pinned by e2e tests that spoof each parameter and expect the prompt to
name the real opener, or not to appear at all. The long-hostname test
drove the dialog through `origin=`, which no longer produces one, so it
now asserts the CSS elision contract directly while the popup test
asserts the real flow applies the `perm-dialog-entity-host` class that
contract keys on.

* Refuse an origin the grant could never have named

The identity line elides a long host from the left, keeping the
registrable domain visible, which it does with `direction: rtl`. That is
sound for a host — every character in one resolves left-to-right, so the
string reads in source order — but it is not sound for arbitrary text,
whose neutral and RTL runs can render in an order they were not written
in. On the one line of this dialog whose whole job is saying who is
asking, that is the wrong thing to be lenient about.

The entity resolver reached that state through its own fallback: when
`new URL(origin)` threw it displayed the unparsed string and still marked
it as a host. An origin the server cannot parse cannot name a grant
target either — `AuthService#originFromUrl` rejects it, and rejects
non-http(s) schemes with it — so there was never anything to prompt
about. Deny at the gate, next to the existing "requester the grant can't
name" check, on the same test the server applies.

* Give the decision poll a deadline it can actually reach

`pollDecision` bounds itself with a five-minute budget, but it only reads
the clock between iterations and its `fetch` had no timeout of its own. A
request that never settles — a stalled connection, a proxy that accepts
and never answers — parks that `await` forever: the loop never comes
back round to check, `settle` is never called, and the caller's promise
stays pending for the life of the page with the message listener and
interval still attached. It is the only unconditional hang left in the
flow, and the least recoverable one, because the popup is already closed
on this branch and nothing the user does can rescue it. Each attempt now
gets ten seconds — long enough that a slow-but-working connection is
still heard, short enough that the deadline means something.

The request id changes for a related reason. It was `#messageID++`, a
small integer restarting at 1 on every page load, and `event.source` is
not pinned for as long as the no-gesture consent dialog waits for its
Continue click — a stretch of time the user paces. A permission popup
left open from before a reload posts this exact message shape to its
opener on the way out, and its counter value collides with a fresh
request's, settling it with the decision the user made about a different
permission. A random suffix makes the two impossible to confuse; the GUI
echoes the value back verbatim, which the loose comparison still handles.

* Answer the app when the signup gate throws

The requestPermission branch grew a `respond` helper so every exit tells
the app something and its promise settles instead of hanging. One exit
still doesn't: `await UIWindowSignup(...)` is outside the guarded region,
and `ipc_listener` has no outer catch, so a throw from the signup window
escapes the listener entirely — before any reply — and leaves the app
waiting forever. That is the precise failure the helper was added to rule
out. Treat it as the refusal it amounts to.

* Revert "Keep the ai-chat model-map build inside the server lifecycle"

This reverts commit 1b2482dcb8.
2026-07-27 08:37:41 -07:00
Daniel Salazar b2324cd212 chore: cleanup puter-js driver to match rest of changes (#3452) 2026-07-27 08:25:44 -07:00
jelveh a1c8ba4cdd Fix stuck grab cursor on aborted drag
When dragging is aborted by returning false from the sortable 'start' handler, the cursor plugin never fires its cleanup, leaving the body cursor stuck on 'grabbing'. Reset the body cursor explicitly on each early-return path.
2026-07-26 23:29:33 -07:00
jelveh 30461e7d95 Hide Trash from file explorer listing
Trash is accessible via the sidebar and should not appear as a row in the file explorer. Filters it out from directory listings and prevents socket events from re-adding it to the view.
2026-07-26 22:32:32 -07:00
jelveh 46253fb80a Disable hover during rubberband file select
Add a `rubberband-selecting` state on the dashboard while marquee selection is active in `TabFiles`, and remove it when drag ends. CSS now disables pointer events on surrounding files chrome (sidebar, directory tree, and header) during that state so hover highlights/tooltips don’t trigger when the cursor leaves the clamped selection area.
2026-07-26 22:23:54 -07:00
jelveh 29f2a4d9c9 Default file picker and sidebar to Home
Make Home consistently visible and selected in file navigation. The file tab now shows the Home directory entry and auto-selects Home (instead of Desktop) when no initial path is provided. In `UIWindow`, saved sidebar layouts are backfilled to include Home if older preferences are missing that entry, preventing users from losing quick access after upgrades.
2026-07-26 22:14:17 -07:00
jelveh e00e1e57da Centralize trash icon update logic
Extract duplicated trash icon update code into two shared helpers:

- `window.update_trash_icons(is_empty)` updates all trash icon surfaces (taskbar, desktop items, shortcuts, open window headers, Dashboard sidebar) in one place.
- `window.refresh_trash_state()` stats the trash, emits the socket event, and calls `update_trash_icons`.

Replace all scattered inline stat+emit+icon-update blocks across UIItem, UIWindow, UIDesktop, UIDashboard, keyboard, helpers, and generate_file_context_menu with calls to these helpers. Also syncs the Dashboard sidebar trash icon on load and after every destructive operation.
2026-07-26 21:51:07 -07:00
Nariman Jelveh 6668d778d2 feat: highlight uploaded items after upload
Uploads now land selected wherever they finish: the desktop, explorer
windows, file dialogs, and the dashboard Files tab. Selection is applied
from both completion channels — the batch response selects elements
already in the DOM, and items whose item.added socket event arrives
later are remembered (with a TTL) and selected on creation. The explorer
footer count and the open-file dialog's Open button are updated to
match, and disabled items (e.g. filtered out by a dialog's file-type
filter) are never selected.
2026-07-26 21:14:26 -07:00
Nariman Jelveh 7f3691aea3 Auth: land back on the /app/<name> the user came for after login/signup (#3435)
Landing on /app/<name> logged-out and authenticating used to dump the
user at the root dashboard on several paths, losing the app they came
for:

- OIDC login/signup only sent return_to for /desktop and /dashboard
  (and the backend whitelist only accepted those two), so OIDC from an
  app landing redirected to /.
- UIWindowSignup defaulted its post-success redirect to /, so password
  signup reached via the session list, ?action=signup, or in-app signup
  prompts (IPC.js) lost the app.
- OIDC error redirects always went to /?action=..., so a recovered
  attempt (e.g. account-not-found bounced to signup) also lost the app.

New helpers in src/gui/src/helpers/auth_redirect.js:
- get_auth_redirect_url(): stay on the page auth started from;
  /action/* pages go to /; strips action/auth_error/message/
  request_code so the reload doesn't re-open the auth window or pass
  auth params through to the app as launch args.
- get_oidc_return_to(): pathname when whitelistable, now including
  /app/<name> (trailing slash normalized).

Backend (OIDCController):
- Shared isWhitelistedReturnPath() accepts /desktop, /dashboard, and
  /app/<name> (charset mirrors APP_NAME_REGEX — no open redirect).
- buildErrorRedirectUrl() lands on the whitelisted originating page
  from the signed state's redirect_uri instead of always /.

Tested: 47/47 OIDC controller tests pass (4 new: return_to accepted/
rejected on start, success redirect to /app/<name>, error redirect
keeping /app/<name>); verified live on local dev for first-visit temp
user, password signup (incl. email-confirmation gate), and password
login — all land on /app/camera with the app open.
2026-07-26 20:33:46 -07:00
Nariman Jelveh 1e280601c6 fix: showSaveFilePicker from external websites (#3450)
Saving a file via puter.ui.showSaveFilePicker from a third-party website
(popup flow) consistently failed with a DataCloneError alert after
clicking Save, and saving over an existing filename showed a raw error
instead of the Replace/Cancel prompt.

Two bugs:

1. privacy_aware_path is a curried factory (world => fspath => ...), and
   initgui.js is the only module that imports it directly — so the popup
   save handler's privacy_aware_path(res.path) returned the inner
   function, which postMessage cannot structured-clone. Every other call
   site resolves the bare name to the correctly bound
   window.privacy_aware_path global, which is why only the external-site
   popup flow was broken. Use the global at the call site and import the
   factory under a distinct name so a bare call can't silently resolve
   to it again.

2. The v2 backend returns `conflict` for a same-name write, but the v1
   wire contract is `item_with_same_name_exists` + `entry_name`, which
   the GUI's save dialogs key on to offer the overwrite prompt. Restore
   the legacy code/field on the write-conflict error and carry
   HttpError.fields through the /batch per-op error serializer.

Verified end-to-end against a local backend: fresh save resolves the
caller's promise with the signed saved_file and closes the popup;
saving an existing name shows Replace/Cancel and Replace overwrites.
Backend suite shows no new failures.
2026-07-26 11:28:38 -07:00
Daniel Salazar 2262975785 fix: readdir response type (#3449) 2026-07-25 18:06:50 -07:00
Daniel Salazar e6e6e3ba9a chore: cleanup API driver calls PUT-1324 (#3448) 2026-07-25 18:05:36 -07:00
Daniel Salazar e85cd9d53d feat: readdir with depth (#3446) 2026-07-25 14:04:21 -07:00
Nariman Jelveh 828b5d9430 Fix popup file pickers rendering an empty explorer
The cover-page rule added for the auth windows forced `width: 100%` on
every `.window-cover-page .window-body`, including the popup file,
directory, and save pickers. That body is an item-container with
`overflow: auto`, so it establishes its own formatting context and may
not overlap the floated `.window-sidebar`. Unable to shrink to fit, it
dropped below the sidebar, pushing the file list and the Cancel/Open bar
outside the 700x400 popup and leaving the page background showing
through as grey.

`.window-body-filedialog { width: auto !important }` was meant to cover
this but loses on specificity, one class against two. Scope the auth
rule with `:not(.window-filedialog)` instead; that class is only set for
the three dialog kinds, so no auth or session cover page changes.
2026-07-25 13:02:15 -07:00
jelveh 3b1ba72ddd Share item-added updates across GUI shells
Extracted desktop `item.added` container update logic into a shared `apply_item_added_to_containers` helper and wired it into both `UIDesktop` and `UIDashboard`. The helper handles overwrite updates, new item insertion, icon refresh, and resorting for matching item containers. This fixes dashboard-hosted explorer/file dialogs not reflecting uploads until navigation.
2026-07-24 23:01:10 -07:00
jelveh 4245ac04ac Isolate upload dialog to prevent double uploads
Replace reuse of `#upload-file-dialog` with a dedicated hidden file input owned by `init_upload_using_dialog`. This avoids collisions with the dashboard Files tab’s `onchange` property handler, which could trigger duplicate concurrent uploads and "Entry already exists" races. The new flow stores the current target path once per dialog open, clears input value before click (so re-selecting the same file still fires `change`), and snapshots `FileList` to an array before clearing to keep async uploads reliable.
2026-07-24 18:26:43 -07:00
Daniel Salazar b8559c1221 chore: cleanup other puter-js modules to match new structure (#3440) 2026-07-24 17:42:06 -07:00
Daniel Salazar 6c4fa629a9 fix: allow root token to also call ai drivers (#3442) 2026-07-24 17:41:38 -07:00
jelveh e6531d4357 Merge branch 'main' of https://github.com/HeyPuter/puter 2026-07-24 15:38:38 -07:00
jelveh 0c27571030 Dashboard files: compact drag ghost + spring-loaded nav controls
- Replace the full-tile drag ghost with a compact icon+name chip:
  stacked sheets and a count badge for multi-selections, dimmed
  source rows, same design in list and grid views.
- Holding a dragged item over back/forward/up or a breadcrumb
  segment now spring-navigates there (700ms dwell); cancelling
  the drag returns to the original directory.
2026-07-24 15:37:33 -07:00
Neal Shah 6e6d9d2869 buildXhr, dedup, retry (#3432)
* buildXhr, dedup, retry

* change retry intervals
2026-07-24 18:37:09 -04:00
Nariman Jelveh 34529b2e79 Dashboard files: replace solid-blue selection with tinted accent wash
Selected tiles/rows now use a subtle accent tint plus hairline ring
instead of a solid --select-color fill, so icons and labels keep their
natural colors in both themes. Also refines the grid tile's hover
'...' button (inset, hairline border, hover state), fixes the
light-mode selected-row text color that referenced a dark-mode-only
variable, and drops the opaque icon chip visible on tinted list rows.
2026-07-24 13:09:31 -07:00
Nariman Jelveh 7e4ac6542e Update TabApps.js 2026-07-24 12:42:17 -07:00
Daniel Salazar 3331dbd464 chore: make fs upload cleaner in puter.js (#3436) 2026-07-24 12:18:19 -07:00
Daniel Salazar 391b175a68 fix: remove deprecated claude models (#3438) 2026-07-24 10:54:01 -07:00
Neal Shah 19f35b4200 add opus 5 (#3437) 2026-07-24 13:49:20 -04:00
jelveh 9877bb79d0 Polish mobile dashboard sidebar drawer UX
Refactors the dashboard’s mobile sidebar into a modal-style drawer with a coordinated state helper, scrim overlay, and dedicated close button. Adds accessibility improvements (`aria-label`, `aria-expanded`) and stronger dismissal behavior (scrim tap, close button, Escape, and swipe-left with velocity/threshold handling). Updates mobile CSS for safe-area-aware positioning, improved touch targets/pressed states, frosted toggle styling, drawer shadows/transitions, and drag-state handling for smoother interactions.
2026-07-23 18:56:43 -07:00
Nariman Jelveh 2982e894b1 Update dashboard.css 2026-07-23 18:14:47 -07:00
Nariman Jelveh 10bdf701e0 Dashboard: start the minimize morph immediately, bookkeep the URL behind it
The minimize controls consumed the app's /app/<name> history entry
first and let the popstate handler do the visible hide. When the app's
iframe had stacked joint session-history entries, the pop only settles
at pop_dashboard_app_url's 400ms watchdog — so clicking minimize sat
still for ~half a second before the morph began.

Hide the window in the click frame instead (minimize_window, shared by
the head button, the context menu, and the control drawer) and demote
the pop to pure URL bookkeeping. The eager hide is safe against both
ways the pop settles: every hideWindow branch marks data-is_minimized
synchronously, and the popstate handler and the watchdog both already
skip minimized windows. The browser's Back button still minimizes
through the popstate handler as before.
2026-07-23 17:50:32 -07:00
Nariman Jelveh e764a10ee4 Dashboard: recover minimize/close when history.back() misses the app entry
Minimize (and close's URL cleanup) on headless dashboard app windows
work by consuming the app's /app/<name> history entry with
history.back() and letting the popstate handler do the actual hide.
But back() traverses the JOINT session history, which the app's iframe
shares: if the app navigated internally after load (SPA router,
redirects — and browsers differ on which iframe navigations stack
joint entries), the back() consumes the IFRAME's entry instead. The
parent's URL never changes, no popstate arrives, and the
dashboard_url_pop_pending latch stays stuck — every later minimize and
close becomes a silent no-op, and the stranded /app/<name> entry makes
later traversals resurrect windows the user already dismissed.

Fix with a watchdog after each back(): a successful pop is a
same-document traversal of the parent (app entries are pushState over
the dashboard route), so its popstate lands well inside 400ms and the
watchdog no-ops. If the URL still names the app by then, do what the
popstate would have done — minimize through the same lookup and
minimized-guard — and replaceState the stranded entry back to the
dashboard's own route (captured at push time, tab hash included) so no
stale entry survives.
2026-07-23 17:23:03 -07:00
Neal Shah 7e461e14a2 remove unneeded write origin append (#3434) 2026-07-23 19:09:23 -04:00
Daniel Salazar 48cc706ad3 feat: paginated fetching for all (#3431)
* feat: paginated fetching for all

* fix: metering top up gui reporting
2026-07-23 15:07:58 -07:00
Daniel Salazar 20ea616b59 chore: cleanup kv module (#3430) 2026-07-23 10:05:19 -07:00
Nariman Jelveh 73a7a38ea8 Dashboard: redesign app control pill as a top-edge drawer (#3427)
* Dashboard: redesign app control pill as a top-edge drawer

The floating control capsule over headless dashboard apps consumed
noticeable space, especially on mobile. Replace it with a drawer: a
slim glass tray flush with the top edge (icon + title + minimize +
close) whose tongue-shaped handle hangs from its bottom center. At
rest only the tongue peeks in from the edge; hovering it (mouse),
tapping it, or keyboard-focusing the drawer slides the tray down.
The collapse is a single GPU transform instead of the pill's
max-width squeezes, and the open-then-retract intro now visibly
retracts into the tongue, teaching where the controls live.

Hover-expansion is gated on pointerType === 'mouse': touch taps
synthesize a pointerenter right before click, which made the old
pill's toggle see an already-open state and shut it again.

Also fixes two window-stacking bugs surfaced while testing:

- showWindow demoted stay_on_top windows (every fullpage/dashboard
  app window, created in the 99999999+ z band) to a plain counter
  z-index on restore. focusWindow deliberately never raises
  stay_on_top windows, so after minimize/restore a single dashboard
  focus buried the app permanently. Restore now re-raises into the
  stay-on-top band.

- Pressing the drawer now focuses its window, as the titlebar it
  replaces did. The document-level activation handler works off
  mouseover_window, which only mousemove refreshes — a tap with no
  intervening mousemove (touch, restored windows) would re-raise
  the dashboard over the app.

* Dashboard: restored windows come back with the drawer collapsed

The restore re-played the open intro (expand + auto-retract). A restore
should bring back the app, not the chrome — the user already met the
controls on open, and they just USED them to minimize. showWindow now
forces the drawer shut instead, which also covers the Back-button
minimize path, where the window hides without touching drawer state.

* Dashboard drawer: left-align the title against the icon

The tray is asymmetric — one icon on the left, two buttons on the
right — so a title centered in its fixed box landed off the tray's
true center and read as misaligned against the centered tongue below.
Left-aligned, icon + title cluster as the identity on the left and
the controls cluster on the right.

* Dashboard drawer: morph the tongue into the tray instead of sliding

The drawer is now ONE glass surface that changes shape, rather than a
tray that slides in from off-screen with a handle below it. At rest
it's the tongue; opened, the same surface swells into the tray while
the grabber bar rides the morph and settles into a slim strip along
the tray's bottom edge as the dismiss handle — same handle, both
states. Content is revealed from the center outward through an inner
clipping layer (the surface itself can't be overflow:hidden without
clipping the toggle's touch halo) and condenses in/out of focus with
an opacity + blur + scale crossfade. Opening gets a soft overshoot
and settles; closing is quicker and lands without bounce.

The open width is DERIVED in CSS from the same part variables that
lay out the controls row, so the surface always fits its content
exactly and breakpoints (touch sizes, hidden title under 500px) only
override parts.

* Refine dashboard drawer open-state handle

Update the headless dashboard app drawer so the grabber bar disappears when the drawer is open and only the bottom dismiss strip remains interactive. This adjusts tray/strip sizing on desktop and mobile, adds opacity timing for smooth dissolve/reappear transitions during open/close, and aligns in-code docs/comments with the new behavior.
2026-07-22 22:11:39 -07:00
jelveh 5c3fab5579 Revert "Dashboard: fix minimized apps getting permanently buried under the dashboard (#3429)"
This reverts commit bbc86e7b70.
2026-07-22 22:11:15 -07:00
jelveh 695862c61f Increase dashboard directory icon size
Adjusts the directory icon width in the dashboard files section from 28px to 35px for improved visibility.
2026-07-22 21:45:09 -07:00
Nariman Jelveh bbc86e7b70 Dashboard: fix minimized apps getting permanently buried under the dashboard (#3429)
* Dashboard: fix minimized apps getting permanently buried under the dashboard

Fullpage/dashboard app windows are created stay_on_top in the
99999999+ z band, but showWindow's restore path demoted them to a
plain counter z-index — and since focusWindow deliberately never
raises stay_on_top windows, the demotion stuck: one dashboard focus
after a minimize/restore buried the app permanently (URL and tab
title still naming an app the user could no longer see). Restore now
re-raises stay-on-top windows into their band.

Also make the control pill focus its window on mousedown, as the
titlebar it replaces did. The document-level activation handler works
off mouseover_window, which only mousemove refreshes — a tap with no
intervening mousemove (touch, restored windows) would activate the
stale window and could re-raise the dashboard over the app. Deferred
a tick so it runs after that handler and wins.

* Dashboard: restored windows come back with the pill collapsed

The restore re-played the open intro (expand + auto-retract). A restore
should bring back the app, not the chrome — the user already met the
controls on open, and they just USED them to minimize. showWindow now
forces the pill shut instead, which also covers the Back-button
minimize path, where the window hides without touching pill state.

* Dashboard pill: left-align the title against the icon

The pill is asymmetric — one icon on the left, two buttons on the
right — so a title centered in its fixed box landed off the pill's
true center and read as misaligned. Left-aligned, icon + title
cluster as the identity on the left and the controls cluster on
the right.
2026-07-22 21:40:04 -07:00
Daniel Salazar e35b57068b test: add extra tests (#3428) 2026-07-22 21:13:44 -07:00
Daniel Salazar 5faed55076 fix: autoclaim app when making a subdomain (#3426) 2026-07-22 21:12:38 -07:00
Daniel Salazar 928d5fec16 chore: cleanup AI module for puter-js (#3423) 2026-07-22 18:18:54 -07:00
velzie ebcc4bb597 Add loopback support to puter.peer (#3425)
* allow setting port instead of invite code in puter.peer

* fix grabbing fallbackice under wrong response
2026-07-22 20:13:35 -04:00
Neal Shah 51541d3739 initial pjs helper stuff (#3421)
* initial pjs helper stuff

* move resolveReauth

* move location of PuterClient and rename to networkUtils
2026-07-22 18:48:11 -04:00
Nariman Jelveh 43b9200205 Dashboard: headless full-tab apps with a floating control pill (#3424)
* Dashboard: headless full-tab apps with a floating control pill

Maximized app windows in dashboard mode no longer render a titlebar —
the app covers the full tab. The head's controls move to lighter-weight
affordances:

- A floating pill overlaid top-center of the app (parent DOM, above the
  iframe): expanded it shows the app icon, title, minimize, and close;
  it opens expanded so first-time and deep-link users see it, then
  collapses to a subtle capsule that re-expands on hover, tap, or
  keyboard focus. Minimize routes through the same URL-entry consumption
  as the Back button; close tears the window down normally. Dark
  translucent glass so it reads over any app content; safe-area aware;
  bigger targets on coarse pointers; title hidden under 500px; respects
  prefers-reduced-motion.
- Apps-tab tiles double as the app switcher: a macOS-dock-style running
  dot marks tiles with a live (visible or minimized) window, and the
  tile context menu gains a Quit item for running apps. UIWindow
  broadcasts window open/close so the dots stay current.
- puter.ui.setWindowTitle also updates the pill title.

Only maximized, URL-owning app windows in dashboard mode go headless:
dialogs, explorer, non-maximized child windows, and everything on the
desktop keep their titlebars. dashboard.css's 29px head-height
compensation is scoped to windows that still have heads, so headless
app bodies fill the window exactly.

* Fix pill buttons swallowed by their own hover halo

The pill's invisible hover halo (an absolutely-positioned ::after with
negative inset) painted above the pill's static children, so real
pointer clicks hit-tested to the halo and never reached the minimize/
close buttons — while element.click() (which skips hit-testing) worked,
hiding the bug from programmatic checks. Stack the halo at z-index -1
(the pill is its own stacking context, so the outside ring still sits
above the app's iframe) and raise the interactive children explicitly.

* Review round: pill/dashboard edge-case fixes

- Latch pop_dashboard_app_url while its history.back() is in flight: a
  double-click on minimize (or a close racing a minimize) issued two
  back()s, and the second popped the dashboard's own entry — navigating
  clean out of the page. Any popstate or push settles the latch.
- Close a running app's windows when it is uninstalled: the tile is a
  headless app's only switcher, so a minimized instance would otherwise
  be stranded — impossible to restore or quit.
- puter.ui.setWindowTitle in dashboard mode now also updates the
  browser-tab title (while that app owns the URL) and the window's
  data-name, so a later restore re-applies the app's current title
  instead of its launch-time one. Desktop behavior unchanged.
- Nudge collapsed-pill contrast (opacity 0.55 → 0.65, border alpha
  0.16 → 0.22) so the capsule stays findable over dark app content.

* Adjust dashboard tile spacing and label sizing

Tweaks My Apps tile layout constants to match the real icon/label geometry: tile height is increased, label top margin is widened, and the running-status dot is moved slightly lower to avoid overlap during icon hover scaling. It also raises dashboard app pill title line-height to prevent descenders from being clipped when ellipsis overflow is active.

* Pill and running-dot visual polish

- Fixed-width pill: the title gets a fixed 150px centered box instead of
  a cap, so every app's pill is identical and the minimize/close buttons
  sit at the same screen position in every app — they're operated by
  muscle memory, like any titlebar's controls.
- Give the pill title line-height 1.35: overflow:hidden (needed for the
  ellipsis) also clips vertically, and at line-height 1 it cut the
  descenders off g/p/y.
- More air around the tile running dot: label margin 6px → 10px and the
  dot 2px lower (tile row height 78px → 82px to keep the label line in
  budget — the pager layout reads the CSS var, so it follows). The
  icon's 1.08x hover growth no longer touches the dot.

* Size the pill icon to balance the capsule

16px read as undersized next to the 26px buttons in the 36px capsule —
bump the expanded icon to 20px with a proportional (25%) radius, and
object-fit: cover in case an app icon isn't square. Collapsed size is
unchanged.
2026-07-22 14:28:06 -07:00
jelveh d5e9417d2d Dashboard apps own the URL: /app/<name> entries with Back-to-minimize
- Opening an app in dashboard mode pushes a real history entry at
  /app/<name>; Back minimizes the app (it keeps running), Forward
  restores it — or relaunches it if it was closed
- The minimize/close buttons consume the entry via history.back() so
  the address bar never names an app that is no longer on screen
- Landing directly on /app/<name> now boots the dashboard with the app
  open maximized in-page instead of the desktop; embeds, popups, and
  explicit fullpage boots keep the desktop flow, and fullpage_on_landing
  no longer opts a landing out of the dashboard
- Desktop mode no longer rewrites the URL at all (no /app/<name> or
  folder-path replaceState on focus, no /desktop resets on close or
  minimize); tab titles still track the focused window
2026-07-22 10:50:10 -07:00
jelveh dec205d959 Lighten tile-to-window restore animation
Update `showWindow` to use a shorter, window-only morph when restoring a minimized app from a dashboard tile. `morph_window_from_tile` now accepts options for `icon_half` and `duration`, gates icon ghost creation accordingly, and derives transition/cleanup timing from the configured duration so un-minimizing feels distinct from a full app launch.
2026-07-22 09:57:24 -07:00
jelveh d87f3464fc Support Cmd/Ctrl+click and adaptive bg color
Update the dashboard app tile click handler so Ctrl/Cmd+click opens apps in a new tab (matching the context menu behavior) while keeping existing target-link/app-name routing. Also switch the default body background to white and add a dark-mode media query to use a dark background color.
2026-07-21 20:33:27 -07:00
jelveh 25410cac92 Allow tile morph animations on phones
Removes `isMobile.phone` checks that previously disabled dashboard tile morph transitions. Window open/close morph selection and tile-launch ghost setup now run on phone the same way they do elsewhere, while still honoring animation-disable and reduced-motion conditions.
2026-07-21 19:13:48 -07:00
jelveh 66a1baef24 Preplay dashboard tile launch morph animation
Add click-time launch feedback for dashboard app tiles so users get immediate visual response while app startup is still loading. TabApps now starts and settles tile launch state around `launch_app`, logs launch failures, and keeps duplicate-launch protection.

UIWindow now tracks in-flight tile feedback with a WeakMap, introduces `begin_dashboard_tile_launch`/`settle_dashboard_tile_launch`, and updates `morph_window_from_tile` to avoid replaying the icon half when it already ran at click time. Ghost/icon timing and cleanup were adjusted so fallback and failed launches do not leave stale tile state.
2026-07-21 19:09:32 -07:00
jelveh 5c4df9cbd7 Revert "feat(gui): start the tile open-morph on click, before the launch fetches"
This reverts commit f89b3a888a.
2026-07-21 18:25:39 -07:00
jelveh f89b3a888a feat(gui): start the tile open-morph on click, before the launch fetches
A fresh launch has a server round-trip (app info, signing) between the
click and the window's creation, so the open morph used to start late —
on a slow connection the click gave no feedback at all. The two halves
of the morph are now decoupled:

- On click, begin_dashboard_tile_launch starts the icon's half
  immediately: the ghost enlarges in place and dissolves exactly as
  before, and the real icon stays hidden — the empty slot reads as
  'launching' — while the fetches run.
- When the window opens, morph_window_from_tile claims the click-time
  ghost instead of spawning a second one, runs the window half alone,
  and restores the icon when it lands. On a fast launch the halves
  overlap into one motion; on a slow one the window zooms out of the
  empty slot.
- settle_dashboard_tile_launch (in the launch's finally) puts the icon
  back whenever the window never claims it: launch failed, app opened
  in background, or the morph fell back to the plain fade. The launch
  also gained a .catch, so a failed launch logs instead of leaking an
  unhandled rejection.

The un-minimize path has no fetch and is untouched: it still spawns its
own ghost inside the morph.
2026-07-21 17:58:05 -07:00
Nariman Jelveh bf545dda25 Dashboard: open apps maximized in-page, with minimize and single-instance behavior (#3419)
* feat(gui): open dashboard apps maximized in-page with minimize + single instance

Apps launched from the dashboard's Apps tab now open as maximized Puter
windows in the same page (via launch_app) instead of a new browser tab.
External website shortcuts still open in a new tab since arbitrary sites
can't reliably be iframed.

Dashboard app windows keep their minimize button (fullpage mode normally
hides it since there's no taskbar). With no taskbar item to animate
toward, hideWindow now hides the window in place and flags it with
data-minimized_in_place; showWindow un-hides it via that flag. An
explicit flag is used because data-orig-* can't distinguish the two
minimize paths - drag/maximize handlers set those attrs too.

Tiles are single-instance: clicking a tile un-hides a minimized
instance or focuses a visible one instead of launching a duplicate, and
launches in flight swallow repeat clicks.

Also fixes .window-body-app height in dashboard mode: fullpage mode
sizes it to 100% assuming no titlebar, which clipped the bottom 29px of
every app.

* feat(gui): iOS-style minimize-to-icon morph in dashboard mode

Minimizing a window in dashboard mode now zooms it into its app's tile
on the Apps tab — but only when the user can see that tile (Apps section
active AND the tile on the pager page currently in view); otherwise the
existing hide-in-place fade is kept, as on phones and with
prefers-reduced-motion.

The animation is a two-layer morph on one 450ms cubic-bezier(0.32,
0.72, 0, 1) path: the live window scales onto the tile's icon box
(transform + opacity only — no per-frame iframe reflow) while its corner
radius grows toward the icon squircle, and an enlarged clone of the icon
flies congruently with it, cross-fading in as the window fades out and
landing exactly on the real icon's slot (hidden until the handoff), so
the window reads as becoming the icon.

Window geometry is never touched: only inline transform/opacity/radius
are set and restored byte-identical when the animation ends, and
showWindow()'s existing minimized-in-place path restores as before —
including a reopen mid-animation.

* fix(gui): keep the minimize-morph ghost icon square (contain-fit)

The icon clone previously mapped rect-onto-rect over the window, which
stretched the square icon anamorphically. A covering square was tried
and jittered: it protruded past the card's short edge and the halo
popped in mid-crossfade.

Contain-fit resolves both: the ghost scales uniformly (always square),
sized to the window's short edge and centered — its side tracks the
card's short edge exactly for the whole flight (both interpolate
linearly between the same endpoints on the same curve), so the card's
rectangular flanks melt away around a steady, undistorted icon.

* feat(gui): add 'Open in new tab' to app tile context menu

Every tile's right-click menu now leads with Open in new tab, which
opens the app the way tiles did before in-page windows: /app/<name> in
a new browser tab (noopener), or the site link for external tiles.
Non-uninstallable apps previously had no menu at all; they now get this
single item, and uninstallable ones show it above a divider + Uninstall.

* feat(gui): reverse morph — dashboard tile icons zoom into their opening window

Opening an app in dashboard mode now runs the minimize morph backwards:
the window grows out of its tile's icon box (transform + opacity only,
radius relaxing from the 22% squircle to the resting value) while a clone
of the icon enlarges IN PLACE on its slot — capped at 2.5x, fully dissolved
by ~250% growth — as the window fades in underneath on the same 450ms
cubic-bezier(0.32, 0.72, 0, 1) path with the crossfade handoff mirrored
(window in at 80-240ms, ghost out at 120-320ms).

Both open paths get the morph, with the same visibility conditions as
minimize (Apps section active, tile on the pager page in view, not phone,
no reduced motion), falling back to the existing fades otherwise:

- fresh launch: TabApps passes window_options.morph_from_dashboard_tile,
  and UIWindow morphs instead of the 70ms opening fade. Since .window is
  display:none from the stylesheet until later in the pipeline, the hook
  shows it before measuring (nothing has painted yet, so neither the early
  show nor the hide-back on a declined morph can flash).
- un-minimize: showWindow's minimized-in-place branch morphs instead of
  fadeIn(150), keeping the z-index bump and 80ms focus timing.

A data-window_morphing flag guards against opposing morphs fighting over
the window's inline styles: minimize clicked mid-open-zoom (or a tile
click mid-minimize-zoom) falls back to the pre-morph fade behavior, and
each animation still restores every inline property byte-identical when
it ends.

* Update dashboard.css

* feat(gui): cap the open-morph ghost icon at 2x, dissolving in place

The tile icon no longer flies toward the window center nor grows to full
contain-fit (10x+ reads as a giant blurry sticker): it enlarges in place
on its own slot and its growth is capped so the fade-out completes right
around 200% of its size — the window alone carries the motion and the
rest of the growth.

* fix(gui): drop the tile :active press-shrink that stuttered the open morph

Clicking a tile launches the app and the open morph grows the icon in
place — the 0.95 press-shrink made every launch read as shrink-then-grow.
The icon now holds its hover scale through the click and enlarges
straight from there (the morph ghost is measured from the rendered rect,
so it picks up the hovered size seamlessly).
2026-07-21 17:41:45 -07:00
Neal Shah c706b4472d use max_tokens instead of hardcoded value 1000 (#3422) 2026-07-21 18:25:40 -04:00
Neal Shah 93b8041c3d don't allow prototype defined method to be called in drivers (#3413)
* don't allow prototype defined method to be called in drivers

* fix test
2026-07-21 18:01:52 -04:00
Daniel Salazar 89f9f9728f fix: PUT-1355 PUT-1351 PUT-1208 (#3420)
* fix: PUT-1355 PUT-1351 PUT-1208

* fix: dev center header
2026-07-21 14:17:33 -07:00
Daniel Salazar 645409eddb fix: misc hardening (#3418) 2026-07-21 13:55:00 -07:00
tamilselvanp57 58a763bcd1 Add Dev Center UI for viewing app users (#3349) (#3417)
Adds a 'View Users' link on the app Analytics tab that opens a modal
listing users who have authenticated into the app (username + email,
where the user has granted email:read to the app).

Consumes the existing puter.apps.get(...).users()/.getUsers() client
SDK method, backed by the app-telemetry driver's get_users - no new
backend work needed, per discussion on the issue.

Relates to #3349
2026-07-21 13:52:48 -07:00
Daniel Salazar fd91d72654 wip: better contributing docks (#3415) 2026-07-21 12:07:59 -07:00
Reynaldi ChernandoandCopilot Autofix powered by AI 7fbf491e6f Update docs meta tags and description (#3416)
* Update docs meta tags and description

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-07-21 16:43:00 +07:00
Daniel Salazar a8833de9d5 fix: misc hardening (#3414) 2026-07-20 23:53:37 -07:00
Daniel Salazar 3a8b6394de feat: standardized api pagination (#3412) 2026-07-20 15:58:23 -07:00
Nariman Jelveh f5d656650f feat(email): accept custom message headers in sendRaw (#3411)
* feat(email): accept custom message headers in sendRaw

Lets callers set transport-level headers such as List-Unsubscribe /
List-Unsubscribe-Post. Also documents the puter-email driver's automatic
unsubscribe / report-abuse footer and the new `suppressed` result field
in the puter.js email module.

* feat(email): envelope override in sendRaw + suppressed in EmailSendResult type

Adds an optional `envelope` field to SendMailOptions so callers can set
transport recipients independently of the visible To/Cc headers (used by
the email-send driver for per-recipient deliveries), and adds the
`suppressed: string[]` field to the public EmailSendResult typing to
match the driver's documented result.

Co-Authored-By: Claude Fable 5 <[email protected]>

* feat(email): document per-recipient best-effort delivery via `failed`

The email-send driver now attempts every recipient's private delivery
even when one fails, returning failed addresses in the result's
`failed` array instead of failing the whole call — so callers retry
only the failed subset and never re-mail delivered recipients. Adds
the field to the public EmailSendResult typing and module docs.
2026-07-20 11:55:46 -07:00
Daniel Salazar dd314da16d feat: require app or api tokens for ai api usages (#3407) 2026-07-20 08:34:44 -07:00
jelveh 47c1d4268f Fix overlapping context menu state on file rows 2026-07-19 20:08:00 -07:00
jelveh b9e87935cc Update dashboard.css 2026-07-19 20:00:18 -07:00
jelveh 73dd95bd41 Open Desktop by default in the Files tab 2026-07-19 19:53:52 -07:00
jelveh c5bc358ef2 Keep file rows visually active while their context menu is open 2026-07-19 19:51:38 -07:00
jelveh 57c9eb9e1a Fix grid badge drop shadow and hover overlap with item menu 2026-07-19 19:23:02 -07:00
jelveh a0c0544928 Remove extra top padding from files header 2026-07-19 19:15:51 -07:00
jelveh 6dcae81a56 Fix uninstall animation snapping after a prior FLIP slide 2026-07-19 18:57:04 -07:00
jelveh 09baee6381 Delay uninstall tile animation until after the modal closes 2026-07-19 18:48:06 -07:00
jelveh 68aab718a1 Add keyboard navigation to the Apps tab 2026-07-19 18:43:57 -07:00
jelveh 5d6b2f3265 Uninstall apps optimistically with a tile removal animation 2026-07-19 18:35:01 -07:00
jelveh 28730010c3 Fix inconsistent icon sizing in dashboard grid views 2026-07-19 12:24:21 -07:00
jelveh 817ece40ba Modernize folder icon yellows 2026-07-19 12:24:20 -07:00
jelveh 7c868e947a Fix Public folder icon grid and align glyph system 2026-07-19 12:07:10 -07:00
jelveh 66984cd3d6 Improve glyph sizing on system icons 2026-07-19 12:03:09 -07:00
jelveh 5fa508ba91 improve dashboard file list and grid styles 2026-07-19 11:48:46 -07:00
jelveh c1fca467bf Use bundled fallback for null app icons 2026-07-19 10:52:56 -07:00
jelveh e726c19311 Add compact grid option to Files view menu
Reworked the Files view toggle into a context menu with List, Compact Grid (`grid-sm`), and Grid modes, and refactored view handling into shared helpers (`isGridView`, `viewClass`, `setView`, `applyViewMode`) so grid behavior is applied consistently across rendering and drag previews. Added compact-grid CSS overrides to reduce tile, icon, text, and badge sizing while reusing existing grid layout behavior.
2026-07-19 09:48:31 -07:00
jelveh 6643642aa7 Fix item-more color for selected rows in dashboard
Ensure the item-more icon uses the correct sidebar item color when a dashboard file row is selected, including on hover.
2026-07-19 09:26:54 -07:00
jelveh 65dc3b5f4c Use thinner dashboard file nav icons
Switches the Files tab header navigation buttons to new thin arrow SVG assets and aligns icon styling with a lighter visual weight. It also updates several header action SVG paths (new folder, upload, list/grid, sort, select) and sets path action icon color to #5c5c5c so the controls look consistent.
2026-07-18 21:44:02 -07:00
jelveh c225fabbd4 Fix clipped app tiles and soften files header hover styling
Apps tab: tile rows only budget one label line, so two-line app names
made flexbox shrink the icon box into a landscape crop and clip the
label mid-glyph. Clamp labels to a single line and exempt the icon box
from flex shrinking.

Files tab: header hover states (nav arrows, breadcrumbs, action
buttons) now use a neutral #EEE chip and no longer recolor the glyph;
nav arrows also render at full opacity when enabled.
2026-07-18 21:27:24 -07:00
jelveh fdcc2e301b Fix My Apps tile icon and label overflow
Prevent app tile icons from shrinking when labels overflow, and clamp tile labels to a single line so they fit within the fixed tile height. This keeps the grid layout stable while preserving full app names in the existing tooltip.
2026-07-18 20:54:09 -07:00
Nariman Jelveh 183ab0780d fix: verified Dashboard bug fixes (routing, files, apps, usage, mobile menu, CSS) (#3406)
* fix: don't double-refresh Dashboard tabs on browser back/forward

A single back/forward navigation fires both popstate and hashchange, so
handleRouteChange ran twice, calling the tab's onActivate twice — every
back/forward to the Apps tab issued duplicate /installedApps and
/get-launch-apps requests and re-rendered the tab twice. Track the last
handled URL and skip the second event.

* fix: store raw values in Dashboard file-row data attributes

renderItem passed html_encode()d strings to setAttribute, which stores
them literally — a file named "Tom & Jerry.txt" got
data-path="...Tom &amp; Jerry.txt". Every flow that reads the attribute
back (keyboard cut/copy/paste, delete-to-trash, drag-and-drop, selection
actions) then hit the server with the mangled path and failed with
"Entry not found". The socket item.renamed/item.updated handlers had the
same problem via jQuery .attr(), and item.moved/item.removed matched rows
with html_encode()d selector needles that can't match raw attributes.

Store raw values everywhere (matching the desktop convention and the
raw readers throughout TabFiles), match paths by comparison instead of
selector interpolation, and repair the html_encode(x) ?? fallback
expressions that could never take their right-hand side. Verified live:
copy/paste of a name containing '&' now succeeds.

* fix: escape folder names in Dashboard nav-history menu (stored XSS)

The back/forward taphold menus interpolated path.basename(history_item)
straight into UIContextMenu item html, which renders it verbatim. A
folder named with an HTML/script payload executed when the user opened
the history menu after visiting it. The desktop file manager already
encodes this value; match it with html_encode(). Verified live: the
payload now renders as inert text and its onerror never fires.

* fix: harden Dashboard hash routing against malformed and unknown tabs

Three routing defects, all reachable from a shareable URL:

- A malformed percent-sequence (e.g. `#100%`) made parseDashboardRoute's
  decodeURIComponent throw at module load, blanking the entire GUI. Guard
  the decode and fall back to the raw hash. Verified: `#100%` now boots.

- A hash whose tab segment contained a quote (`#foo"bar`) was interpolated
  into a jQuery selector that throws, leaving dashboard event handlers
  unbound. Resolve the route tab against the known tab set (falling back to
  Apps) before it ever reaches a selector. This also fixes an unknown hash
  activating the Apps section without its `.dashboard-content.apps` styling.

- Re-clicking the already-active sidebar tab pushed duplicate history
  entries, so Back became a no-op until pressed repeatedly. Only pushState
  when the hash actually changes.

Verified live for all three.

* fix: keep Dashboard file list footer and size cells in sync on live updates

Incremental updates only touched hidden data attributes, so the visible
UI drifted from the data:

- Adding a file via the socket (item.added) or creating one inserted a
  row but never called updateFooterStats, so the "N items · size" footer
  stayed frozen at the old count. Removals and moves had the same gap.
- item.updated (and the in-place update in UIDashboardFileItem) rewrote
  data-size/data-modified but not the on-screen .item-size/.item-modified
  cells, so a remote overwrite left a stale size (e.g. "5 B" for a file
  that had grown to 2 KB).

Refresh the footer after add/remove/move and repaint the size/modified
cells on update. Verified live: add, overwrite, and delete now all
reflect immediately.

* fix: Dashboard Files shift-click selection after navigation and byte formatting

Shift-click selection:
- renderDirectory cleared the .selected class but left
  window.latest_selected_item pointing at a now-detached row from the
  previous directory. The shift handler set shift_clicked=true, found the
  anchor's index as -1, skipped the range select, and onclick then
  early-returned on shift_clicked — so the first shift-click in a new
  directory selected nothing. Reset the anchor when it detaches, only take
  the range path when the anchor is still in the list, and treat a
  shift-click with no valid anchor as a plain select that becomes the
  anchor (onclick otherwise ignores clicks while Shift is held).

formatFileSize:
- Returned "NaN undefined" for missing/invalid sizes and "1.5 undefined"
  for terabyte-plus files (sizes array stopped at GB). Guard non-finite
  and non-positive input, clamp the unit index, and add TB/PB.

Verified live: first shift-click selects the item, a second shift-click
extends the range, and formatFileSize returns 0 B / 1.5 TB / 2 PB.

* fix: show a message instead of a blank pane when a Dashboard folder fails to open

renderDirectory empties the file list before awaiting readdir, so a
readdir rejection (permission lost, folder deleted from another session,
network error) left a completely blank pane with only a console error.
Render a centered "This folder couldn't be opened." message on the catch
path. Verified live: a simulated readdir failure shows the message,
clears the spinner, and leaves navigation working (next folder loads).

* fix: Dashboard Usage/Home tab data freshness, errors, and dead controls

TabUsage:
- The Upgrade/Manage button was shown unconditionally and its click did
  `new window.UIUpgradeAccount()`, which only exists on hosted puter.com —
  on self-hosted it threw a TypeError from a dead button. Hide the button
  when UIUpgradeAccount is absent and guard the click.
- The tab had no onActivate and bound its refresh to a nonexistent
  element, so usage numbers were frozen at page-load for the whole
  session. Add onActivate to refetch (verified: reactivating refetches).
- Resource names rendered the backend's `_dot_` escaping literally
  ("gemini-2_dot_5-flash"); un-escape for display and html_encode the cell.
- The two loaders had no error handling; a failed fetch left the tab
  blank with an unhandled rejection. Catch each and show a fallback.
- Guard capacity 0 so storage no longer renders "NaN%".

TabHome:
- Plan button kept saying "Manage →" after a subscription lapsed; reset it
  to "Upgrade →" in the free branch.
- Guard capacity 0 ("NaN%") on the storage card.
- "Your Plan ›" card header had the arrow affordance but no target and did
  nothing on click; point it at the Usage tab like its siblings.
- Returning to the tab fired both focus and visibilitychange, and
  refreshAndBroadcast both called refresh() and dispatched the event its
  own listener handles — up to 4 duplicate reloads per focus. Drop the
  direct call and coalesce the focus/visibility pair.

TabHome + TabApps:
- window.open(externalAppUrl, '_blank') lacked noopener, exposing the
  dashboard tab to reverse tabnabbing from an external app site. Add
  noopener,noreferrer.

Verified live: Usage and Home render without NaN or console errors, the
upgrade button is hidden on self-hosted, and 'Your Plan' now navigates.

* fix: multiple Dashboard CSS defects (dead rules, contrast, responsive)

- The desktop rule that hides the row ⋮ button ended two selectors with a
  comma before an @media block, so the whole construct was invalid and
  discarded — the ⋮ showed on every list-view row on desktop instead of
  deferring to right-click. Verified: it's now hidden (display:none).
- Native-drop dark-mode styles keyed off .window[data-color-scheme="dark"],
  an attribute never set anywhere; converted to @media (prefers-color-scheme:
  dark) like every other dark rule so they actually apply.
- .myapps-tile-label set white-space:nowrap after a 2-line -webkit-line-clamp,
  defeating the clamp so long app names clipped mid-glyph on one line;
  removed it.
- .dashboard-sidebar-separator was defined a second time with a contradicting
  box model (background line + full-width margin), rendering a doubled,
  edge-to-edge divider; removed the duplicate so the inset border rule stands.
- Grid-view .item-icon had a hardcoded background:white and border-radius:2px
  overriding its own border-radius:8px (glaring white tiles in dark mode,
  square-ish corners); use var(--dashboard-background) and keep 8px.
- .files-footer used hardcoded #666/#CCC on theme-variable backgrounds
  (dim in dark, near-invisible separator in light); use the text/muted vars.
- Fixed the .ui-droppable-over typo (jQuery UI emits ui-droppable-hover).
- The context-menu backdrop's "desktop transparent" rule used min-width:768px
  while every mobile rule uses max-width:768px, overlapping at exactly 768px
  (a common tablet width) — a non-dimming, invisible modal shield; bumped to
  769px.
- At 481-768px the fixed hamburger toggle sat on top of the Files directories
  column's first folder because .dashboard-content.files padding wins over the
  media-query padding; add top clearance to the directories column there.

Verified light-mode desktop is unchanged (directories padding still 16px, ⋮
hidden, footer colors resolve).

* fix: only offer Uninstall for Dashboard apps where it actually sticks

Uninstall was suppressed via a hardcoded 8-name allowlist that had drifted
out of sync with the backend's ~26 recommended apps. For the ~18 unlisted
recommended apps (Calculator, Code, the games, …) the menu offered
Uninstall, revokeApp resolved, the tile vanished — then get-launch-apps
re-added it on the next load and it reappeared, so the uninstall silently
reverted.

Compute uninstallability from the actual lists: an app is uninstallable
only if it's in the user's installedApps AND not in the recommended list
(and not a protected core app). Recommended apps — installed or not —
resurrect on reload, so Uninstall is hidden for them. Verified live: a
synthetic installed-not-recommended app shows Uninstall; a recommended
app shows none.

* fix: guard Dashboard Apps loads against stale overwrites and drag/error clobbering

loadApps only checked for an in-progress drag before its await, and its
catch wiped whatever was on screen. Three concurrency issues followed:

- A slow, older load resolving after a newer one could overwrite the
  newer app list (and clobber a reorder the user saved while the stale
  fetch was in flight). Tag each load with an increasing id and skip
  applying one only when a strictly newer load has already applied —
  gating on "already applied" (not "latest started") so the first load to
  resolve still populates the list for the pager's ResizeObserver.
- A drag that began while a load was awaiting could have the grid rebuilt
  out from under it; re-check the drag after the await.
- A transient re-fetch error replaced a working grid with "Failed to load
  apps"; only show that placeholder when nothing has loaded yet.

Verified live: a slow older load no longer clobbers a newer one, and the
grid still renders normally on activation.

* fix: page through all installed apps in the Dashboard instead of capping at 100

The /installedApps endpoint clamps limit to 100 and paginates, but the
Apps tab fetched a single page — a user with more than 100 installed apps
silently lost the alphabetically-last ones from both the grid and search,
with no way to launch or uninstall them from the dashboard. Loop pages
until a short one comes back (the common <100-app case still makes a
single request). Verified: the request now carries &page=1 and stops
after one page for a small account; the loop pulls all pages otherwise.

* fix: make the mobile Dashboard context menu handle submenus, disabled items, and positioning

The touch context-menu modal (used whenever maxTouchPoints > 0) had three
defects:

- Items with a submenu and no onClick ("New", "Open With") rendered as
  plain buttons that did nothing and didn't even close the menu — the two
  submenu-bearing actions were simply unreachable on touch. Drill into the
  submenu on tap, with a Back row to return.
- disabled items were rendered as active buttons and executed their
  onClick, so a folder's disabled "Paste Into Folder"/"Publish as website"
  ran anyway. Render them inert (disabled attribute + dimmed class + a
  click-handler guard), mirroring the desktop UIContextMenu.
- Non-touch devices that still route here (touchscreen laptops) got the
  modal pinned at a hardcoded left:300px, far from the tapped item on a
  wide screen. Center it over the target and clamp to the viewport.

Verified live (with maxTouchPoints forced): "Open With" opens its submenu
and Back returns; disabled "Paste Into Folder" is inert; the modal is
positioned near the item.

* fix: repair Apps-tab regressions from the Dashboard bug-fix pass

- A non-array /installedApps response (an error payload) was read as
  end-of-pagination, silently rendering the grid without any installed
  apps; fail the load so the explicit error state shows instead.
- A loadApps result that resolved mid-drag was discarded with no retry,
  freezing the grid on stale data for the rest of the visit; stash it
  and apply it after the drag ends, reconciled against the drag's final
  order so it can't undo a reorder whose save is still in flight.
- Uninstall disappeared for recommended/recent apps, removing the only
  UI path that revokes their permissions; offer it again and instead set
  expectations in the confirm modal (the tile stays for apps that
  get-launch-apps re-adds).
- init and the initial-route onActivate both fired a full load on open;
  share the in-flight load instead of issuing a duplicate request trio.

* fix: repair Files/routing regressions from the Dashboard bug-fix pass

- The no-anchor shift-click fallback also fired when shift-clicking the
  current anchor, collapsing an existing multi-selection to one item,
  and it ignored Ctrl/Cmd; only run it when there is genuinely no
  anchor, and keep the existing selection when Ctrl/Cmd is held.
- Unknown hash values (a stale bookmark, an in-page anchor) were
  coerced to 'apps' and yanked the user off their current tab with a
  refetch and autofocus; ignore them outright, both at boot and on
  hashchange, while still keeping untrusted hashes out of selectors.
- The item.updated socket handler re-implemented the row-refresh from
  TabFiles and had already drifted (trashed items showed their raw UID
  instead of metadata.original_name); extract a shared row updater and
  delegate to it.

* fix: repair Usage-tab regressions from the Dashboard bug-fix pass

- Hiding the plan button whenever window.UIUpgradeAccount was missing
  at check time could hide it for the whole session on hosted
  deployments that attach the script after dashboard init; keep
  re-checking for a while before concluding the install is self-hosted.
- init and the initial-route onActivate both refreshed usage on a
  direct #usage open; share the in-flight refresh instead of issuing
  duplicate request pairs.

* fix: repair Dashboard CSS regressions from the bug-fix pass

- Repairing the malformed item-more rule put display:none into effect
  for the first time, removing the visible-and-used desktop row '⋯'
  button; drop the rule instead (it was never in effect on any release).
- The desktop context-menu backdrop breakpoint (min-width: 769px) left
  fractional viewport widths between 768px and 769px with the mobile
  dimming; use the exact complement of the mobile max-width: 768px
  rules instead.

* fix: make Dashboard app uninstall honest about recents and resilient mid-flight

- Recently-opened apps were classified as sticky-removable, but the
  recent list is built from app-open history that a revoke doesn't
  touch, so their tiles reappeared on the next load — the very bug the
  uninstall gating set out to fix. Treat recents like recommended.
- The confirm modal claimed every staying tile was 'provided by Puter',
  which is false for third-party recents; describe the actual reason.
- Uninstall now marks in-flight loads stale so a fetch that started
  before the revoke can't resurrect the removed tile.
- A pagination failure after the first page no longer discards the
  pages already fetched — one flaky request among N used to turn the
  whole grid into 'Failed to load apps'.

* fix: keep the Dashboard Usage tab stable through transient failures

- A failed refresh no longer wipes an already-rendered usage table;
  the unavailable note only shows when there is nothing on screen yet
  (mirrors the Apps grid's error handling).
- The plan-button check now re-checks indefinitely with backoff instead
  of giving up after ~10s, so an arbitrarily late UIUpgradeAccount
  attachment can't leave a subscriber without the button all session.

* fix: Dashboard Files footer sync and Home refresh resilience

- The shared row updater now refreshes the footer's item-count/total
  line, which is computed from the data-size attributes it just wrote;
  a remote overwrite no longer leaves the row and footer disagreeing.
- Size/Modified are only written when the update payload carries them,
  so a minimal event can't zero out correct values on screen.
- A failed readdir now resets the footer instead of keeping the
  previous directory's counts over an empty pane.
- Home's focus-refresh caps its wait on refresh_user_data, so a whoami
  that never settles can't leave the plan/usage cards stale forever.

* fix: contain partial Apps loads and keep the uninstall flag current

- A partial installed-apps list (a page beyond the first failed) now
  renders only when the grid is empty — it must never replace a
  complete grid already on screen — and saveOrder refuses to persist
  while the list is partial, since overwriting the saved order with a
  truncated one would drop the missing apps' positions for good.
- Opening an app from the grid now flips its tile's uninstallable flag:
  the open puts it in the server-side recent list, so a revoke from
  that moment on leaves the tile in place, and the modal must not act
  on the stale load-time snapshot.
- The in-flight-load invalidation moved into _invalidateInFlightLoads()
  so the seq protocol lives in one place.

* fix: Usage-tab error guard, dead spinner, and poll decay

- The transient-error guard now tracks 'a table has rendered' instead
  of data length, so an account with legitimately zero usage doesn't
  get its empty table replaced by the unavailable note on a flaky
  refresh.
- update_usage_details animated a spinner element that exists nowhere
  in this tab and held every refresh open for an artificial 1s minimum;
  both halves of the dead control are now gone.
- The plan-button recheck backs off to a 60s heartbeat instead of
  polling at 2s forever on installs where UIUpgradeAccount never
  appears.

* fix: guard minimal file updates; tighten selection and socket hot paths

- The shared row updater only writes the fields an update payload
  actually carries, so a minimal event can't blank a row's name/path —
  the same hazard the size/modified guards already covered.
- The all-rows lookup in the selection handler now happens only under
  Shift instead of on every click, and the single-select block shared
  by the no-anchor shift-click and drag-handle paths lives in one
  selectSingle helper.
- item.removed and item.moved narrow by data-uid (O(1) selector) before
  comparing paths instead of scanning every row per socket event.

* fix: replace partial-load and uninstall-flag patches with convergent designs

The previous round's containment patches each spawned new corner cases
(a persistently failing page froze all refreshes; the partial-load
saveOrder bail silently discarded reorders; the tile-open flag flip
lost races with in-flight loads, server recording, and popup blockers).
Replace both mechanisms:

- A partial installed-apps fetch (later page failed) now always applies,
  supplemented with the apps already known from the previous list — the
  grid and search can't shrink from one flaky request, refreshes never
  freeze, and an empty grid still gets the fetched pages.
- saveOrder carries over saved names missing from the current list
  instead of refusing to persist, so no app's saved position is ever
  dropped; stale names are harmless (reconcileAppOrder ignores them)
  and preserve the position of apps that return.
- The load-time uninstallable snapshot is no longer patched client-side
  on tile open. Uninstall now revokes, optimistically removes the tile
  when expected to stick, and refetches — the grid converges to
  server-side truth instead of guessing at recents state.

* fix: don't blank filenames on metadata-only updates; unify range selection

- A payload carrying metadata but no name resolved to an empty display
  name and blanked the row's visible filename — skip the write when the
  resolved name is empty.
- The shift-range branch now goes through the same applySelection
  helper as the no-anchor and drag-handle paths (it takes the row set),
  removing the last hand-rolled copy of the selection bookkeeping.

* fix: rank-preserving saved-order merge; keep the pager put after uninstall

- The saved-order carryover appended missing apps' names at the tail,
  permanently demoting their saved grid positions — the very thing it
  claimed to protect. Replace it with mergeSavedOrder in appOrder.js
  (beside its tested siblings, with unit tests): each missing name
  keeps its rank among surviving names, so a drag during a partial-load
  session neither drops hidden apps' positions nor teleports them
  behind the dragged tile.
- The post-uninstall convergence refetch rendered without preservePage,
  snapping the pager back to page 1 and replaying the load fade; thread
  render options through loadApps so the background sync keeps the
  user's page.

* fix: keep hidden apps' saved ranks through the mid-drag stash path

- _applyPendingLoad reconciled a stashed load against the visible-only
  on-screen order, tail-appending any app returning to the grid and
  contradicting the order the drag had just saved — the rank-demotion
  defect resurfacing through one more path. It now prefers
  _savedOrderNames, the canonical saved list that saveOrder keeps
  merged with hidden apps at their ranks, over the possibly pre-drag kv
  snapshot the stashed load fetched.
- The post-uninstall optimistic render now also skips the load fade;
  it was the one in-place rebuild still hiding the grid behind the
  opacity-0 icon gate.
- mergeSavedOrder's rank rescan collapsed to a single forward
  insertion pointer (verified output-identical; the 20 unit tests pin
  the behavior).

* fix: gate stale kv-order snapshots on the latest local save

A drag that started and ended while a load was in flight escaped the
stash path entirely: the load applied normally and replayed its
pre-drag kv snapshot, visibly reverting the just-saved reorder (and
permanently clobbering it after the next save). Conversely, the stash
path unconditionally preferred the local record, discarding a genuinely
fresher order fetched from another window when the drag committed
nothing.

Record the load-seq boundary at each saveOrder; a resolving load (both
apply paths, via _resolveOrderNames) replays its fetched kv order only
when it was issued after the latest local save — otherwise the
canonical in-memory saved list wins. Also rewrites the _applyPendingLoad
header, which described the pre-rank-merge implementation.

* Simplify app uninstall tile handling

Remove the uninstallability flag and modal warning logic, and treat uninstall as a local UI removal after permission revoke. This avoids an immediate reload that could re-add recommended/recent apps, while stale in-flight loads are still invalidated. Also simplifies app loading by dropping unused render options from `loadApps`/`_fetchAndRenderApps` and related merge comments.

* fix: match raw item paths in move_items cleanup and shortcut re-point

Item rows store data-path/data-shortcut_to_path unencoded, so the
html_encode()d attribute selectors missed names containing & < > " '
and the destination-row exclusion guard could remove a legitimate row
just created by a concurrent item.moved handler. Compare raw values
case-insensitively instead.

* fix: bound the Usage plan-button retry poll

The UIUpgradeAccount retry chain decayed to a 60s heartbeat but never
stopped, leaving self-hosted installs polling forever and pinning the
captured $el_window. Give up after ~30s of decaying retries; onActivate
re-checks on every return to the tab, so late script loads still get
the button.

* fix: drop the recent-opens list from the Apps tab grid

Recents are open history, not installs: they resurrected uninstalled
apps' tiles and showed merely-visited sites as if installed. The grid
is now recommended + installedApps; anything the user actually uses
still appears because opening an app grants it a permission. Recents
still power the Home tab.
2026-07-18 20:39:57 -07:00
jelveh 81c69f243b Align sign-up email button with OIDC styling 2026-07-18 09:35:13 -07:00
jelveh 6a3ecaff2a improve and unify OIDC button styling 2026-07-18 09:18:21 -07:00
jelveh 70f343d6fe Defer taskbar creation in fullpage mode 2026-07-17 14:38:06 -07:00
jelveh 172aa01e1c Trim file context menu actions 2026-07-17 14:23:52 -07:00
jelveh cba6ac8184 Clamp and normalize window progress values 2026-07-17 14:14:50 -07:00
jelveh 492f3d235a Add active label variant to context menu height rule 2026-07-17 13:54:12 -07:00
jelveh d9a01a3748 Add responsive item properties modal to Dashboard 2026-07-17 13:21:15 -07:00
Nariman Jelveh aab21ef91d don't record app open in iframe env 2026-07-17 11:42:48 -07:00
Daniel Salazar 2479e6a064 fix: FS permissions (#3404) 2026-07-17 11:01:34 -07:00
jelveh 7cba26bb39 Revert "fix(dashboard): make app drag-to-reorder work on touch (iOS)"
This reverts commit af0dc06f49.
2026-07-17 08:53:46 -07:00
jelveh af0dc06f49 fix(dashboard): make app drag-to-reorder work on touch (iOS)
On iOS/WebKit the pager's `touch-action: pan-x` made horizontal touchmove
non-cancelable, so the moment a long-press drag moved the finger the
browser started a native page-pan and fired pointercancel, aborting the
reorder before it visibly began. Preventing pointermove doesn't stop
native scrolling on iOS, and the reordering `touch-action: none` rule was
applied only after the drag began — too late, since touch-action is
latched at gesture start.

Drop the explicit pan-x (back to auto) so horizontal touchmove is
cancelable, and install a non-passive touchmove listener that
preventDefaults only once reordering is armed (post long-press). Before
arming it's a no-op, so a quick swipe still flips pages natively.
2026-07-17 08:47:58 -07:00
Nariman Jelveh 14900514b9 Dashboard: drag-to-reorder apps in the Apps tab (#3401)
* feat(dashboard): drag-to-reorder apps in the Apps tab

Let users arrange their My Apps tiles in any order via drag-and-drop.
The order is stored per-user in puter.kv (`dashboard_apps_order`) as a
list of app names and re-applied on load; apps installed since the order
was saved are appended, and uninstalled ones are dropped.

Interaction:
- Mouse/pen: drag past a small threshold to reorder; a plain click still
  opens the app.
- Touch: long-press to pick up a tile (a quick swipe still flips pages).
- Dragging to a scroller edge dwells, then flips to the adjacent page so
  tiles can move across pages; the floating drag image lives on <body> so
  the pager's overflow can't clip it, and displaced tiles reflow with a
  FLIP animation.
- Escape (or losing the window) cancels and reverts; reordering is
  disabled while a search filter is active; prefers-reduced-motion is
  honored.

Also fixes a latent pager bug where programmatic page changes (arrows,
dots, wheel) didn't update the active page indicator, because those
scrolls don't reliably emit 'scroll' events; goToPage now tracks the
page eagerly.

The order-reconciliation logic is extracted into a pure module
(appOrder.js) with unit tests.

* fix(dashboard): ignore stray pointers and no-op drags

- Filter drag pointermove/up/cancel by pointerId so a second finger can't
  hijack or prematurely end an in-progress reorder.
- Only persist a new order when the drop actually changed it, so an
  accidental long-press or drop-in-place doesn't freeze the default
  ordering into a custom one.

* fix(dashboard): address review of app drag-to-reorder

Correctness:
- Preserve the touch long-press → Uninstall path. A long-press now *arms*
  reordering instead of immediately grabbing the tile; moving begins the
  drag, while holding still lets the native context menu fire (which
  cancels the pending pickup). This restores the only touch route to
  Uninstall that the first cut had removed.
- Only swallow the post-drag click when the drop actually reordered
  something, so a small pointer drift or a drop-in-place still opens the
  app like a plain click.
- Guard the pre-start "intent" window: cancel a pending pickup before any
  re-render (ResizeObserver / loadApps), and bail out of _beginDrag if the
  pressed tile was detached, so a layout change mid-press can't reinsert a
  stale node and persist a corrupted order.

Cleanup:
- Reuse reconcileAppOrder for the drop path instead of a duplicate helper.
- Read the saved order in parallel with the app-list fetches.
- Cache the reduced-motion MediaQueryList instead of re-querying per move.
- Fold the touch-scroll cancel into _endDrag(false); drop _abortDragIntent.

* feat(dashboard): smoother, more tolerant app reordering

Make drag-to-reorder feel like the iOS home screen instead of snapping
and flickering:

- Slow the reflow to 320ms with a gentle spring easing.
- Hit-test against each tile's *resting* box, not its live
  getBoundingClientRect. Mid-animation a tile sits between slots, so
  testing its live box was dropping it under the pointer and swapping it
  straight back — the source of the back-and-forth jitter.
- Require the dragged icon's centre to be well inside a tile before it
  becomes the drop target (a deadzone around each tile), so hovering a
  boundary no longer thrashes.
- Probe with the dragged icon's centre rather than the fingertip, and
  batch the FLIP into a single reflow so large grids stay smooth.
2026-07-17 07:57:05 -07:00
Daniel Salazar 7faaef8cf0 tests: more tests for puter.js (#3402) 2026-07-16 22:35:15 -07:00
Nariman Jelveh c188257f85 Session Manager: compact redesign + responsive modal (no UIWindow) (#3400)
* redesign: compact, scannable Dashboard Session Manager

The session list rendered each entry as a bulky card with a 5-row
Created/Last active/Expires/IP/Client key-value table and a large filled-red
Revoke button, so only a couple of sessions fit on screen and destructive
actions dominated the layout.

Reworked it into an icon-led, compact list:
- One row per session: a device/kind icon tile (laptop / phone / globe by OS,
  bolt for workers, key for API tokens, the real app icon for app sessions),
  the title + badges, and two tight meta lines (client · IP, then a fainter
  last-active · created · expires with absolute-time tooltips).
- Destructive actions are calm: per-row Revoke and the rename pencil are quiet
  and reveal on hover (always shown on touch); "Revoke all other sessions" is a
  subtle ghost button instead of a filled block competing with search.
- Current session gets a green accent, tint, and pill, and has no revoke button.
- Toolbar search gains an inline icon + focus ring; added a session count line;
  restyled kind badges; nested child sessions get a proper tree line.

Styling uses the existing dashboard design tokens. All behavior is preserved:
search filtering, parent/child tree with expand/collapse, inline rename
(optimistic + rollback), per-session revoke (access-token vs session routing),
revoke-all, current-session guard, and focus/interval refresh.

Adds ui_session_count_one / ui_session_count_other to en.js (other locales
fall back to en).

* refactor: render Session Manager as a responsive modal, not a UIWindow

Replaces the draggable UIWindow shell with a self-contained DOM modal:
- Backdrop + centered card on desktop (max 680px / 90vh); full-screen sheet
  on phones (<=640px). Fade/scale in, respects prefers-reduced-motion.
- Adds a header bar (title + close), backdrop-click and Escape to close, and
  a scroll-contained body.
- Confirmations no longer use UIAlert (itself a UIWindow). Revoke, revoke-all,
  and the rename-error path now use in-modal confirm/alert sheets, so there is
  no cross-window z-index juggling — important because this can be opened from
  a stay_on_top window (UIWindowCopyToken).

Drops the UIWindow and UIAlert imports entirely. All behavior is preserved:
search, parent/child tree + expand/collapse, inline rename (optimistic +
rollback), per-session revoke (access-token vs session routing), revoke-all,
current-session guard, and the focus/60s-interval refresh (cleaned up on close).
2026-07-16 20:48:54 -07:00
Nariman Jelveh 4543a645f2 fix: verified Dashboard bugs (10 separate fixes) (#3399)
* fix: prevent crash rendering website files without a workers array in Dashboard Files

TabFiles.renderItem accessed `file.workers.length` unguarded when deciding
whether to show the website badge. Directory entries that have a published
website but no `workers` array (the common case) made this throw
`Cannot read properties of undefined (reading 'length')`, so the row failed
to render — the file silently disappeared from the list (swallowed by the
Promise.allSettled batch) or was never added on socket-driven updates.

The sibling `is_worker` derivation on the same entry already guards with
`file.workers?.length`, and the desktop reference (UIItem.js) normalizes
`workers` to an array and shows the badge via `!is_worker`. Reuse the safe
`is_worker` flag here instead of touching `file.workers.length` directly.

* fix: correct Dashboard usage that showed negative spend for users with credits

The Usage tab and Home usage card derived month-to-date spend as
`monthUsageAllowance - allowanceInfo.remaining`. But the metering service
computes `remaining = remainingAllowance + remainingPurchasedCredits`
(MeteringService.getAllowedUsage), so `remaining` exceeds the monthly
allowance whenever a user holds purchased credits — making the displayed
spend and percentage negative (e.g. "-$9.90 used of $0.25", "-3960%").

Use the actual reported spend (`res.usage.total`, already returned by the
same endpoint) and clamp the percentage/bar to 100%. For a free user with no
credits and no overage this yields the identical value as before.

* fix: make Dashboard Files Download button work for a single selection

In mobile select mode the floating action bar appears with one item selected
(minCountForActionBar is 1) and shows an enabled Download button, but the
click handler only acted when 2+ rows were selected — so downloading a single
file did nothing.

Gate on `> 0` instead. window.zipItems already normalizes a single item to an
array, so the one-file case works. On desktop the bar only appears at 2+
selections, so this changes nothing there.

* fix: auto-fit column width in Dashboard Files no longer scales with row count

Double-clicking a column resize handle is meant to fit the column to its
longest cell. The per-row loop did `maxWidth = Math.max(maxWidth + 10, textWidth)`,
which forces `maxWidth` to grow by at least 10px on every row regardless of
content — so a folder with N files produced a column ~10*N px wide and
persisted that runaway width to KV storage.

Compare against the running max only (`Math.max(maxWidth, textWidth)`);
`textWidth` already includes cell padding.

* fix: clear empty-directory placeholder when a file is added incrementally

When a directory is empty, renderDirectory appends an absolutely-positioned
"No files in this directory." placeholder. If a file then appears via an
incremental path (socket item.added/item.moved -> UIDashboardFileItem), the
new row was inserted but the placeholder was never removed, so the "No files"
text overlapped the real item. insertAtSortedPosition can't clear it because
the placeholder has no `.item.row` class.

Remove the placeholder in UIDashboardFileItem before inserting the row,
matching what the in-app New Folder / New File flows already do.

* fix: stop leaking a document keydown handler per uninstall-modal dismissal

showUninstallModal bound `keydown.uninstall-modal` on document but only
detached it on the Escape and Confirm paths. Dismissing via Cancel or a
backdrop click called `close()`, which just removed the overlay and left the
handler attached (closing over a now-detached overlay). Each open→cancel
cycle stacked another document-level listener for the page lifetime.

Move the `.off('keydown.uninstall-modal')` into `close()` so every dismissal
path cleans up, and drop the now-redundant explicit detaches.

* fix: resolve 2FA setup promise on every close so Dashboard toggle can't freeze

UIWindow2FASetup only resolved its promise from the Done button and, in
on_before_exit, when setup had NOT succeeded. Clicking "Enable" sets
setup_succeeded=true and advances to the recovery-codes screen without
resolving; if the user then closes that screen via the backdrop or Escape
instead of Done, the promise never settles.

The Dashboard Security tab is the only caller: it disables the 2FA toggle and
`await`s this promise, so the hang leaves the toggle permanently disabled and
stuck in the pending state for the rest of the session. Resolve with
setup_succeeded on any exit; resolve_promise is idempotent so a prior
Done-resolve is unaffected.

* fix: refresh Dashboard tabs when navigating via browser back/forward

The sidebar-click and initial-route handlers both call the target tab's
onActivate (its refresh hook), but handleRouteChange — wired to hashchange
and popstate — only swapped the active classes. Since tab switches use
history.pushState (which doesn't fire popstate/hashchange), the only way to
reach handleRouteChange is browser back/forward, and doing so left tabs like
Home/Apps showing stale data.

Look up the tab by id and call onActivate after switching, matching the
sidebar-click path.

* fix: refresh Home "Recently used" apps instead of freezing them for the session

loadRecentApps only hit /get-launch-apps when window.launch_apps.recent was
empty. Once populated (typically at page load), every subsequent init/onActivate
/focus just re-rendered the same cached array, so apps launched during the
session never showed up under "Recently used" until a hard reload.

Drop the empty-list guard so the list refetches on the same triggers that
already refresh the usage cards. The fetch can only make the list fresher.

* fix: sync window.user.otp when enabling 2FA from the Dashboard

The disable path clears window.user.otp (in UIWindowDisable2FA), but the
enable path updated only the card's DOM, never the in-memory flag. TabSecurity
html() reads user.otp to decide the toggle/badge state, so after enabling 2FA
a re-render of the Security tab from the cached window.user showed it as
disabled for an account that actually had 2FA on.

Set window.user.otp = enabling on success so both directions stay consistent.
2026-07-16 20:03:38 -07:00
jelveh 75d3b07e0f fix: phantom shortcut badge on files created via dashboard New menu
renderItem() showed the shortcut badge whenever file.is_shortcut !== 0.
Directory listings return is_shortcut as 0, but the puter.fs.upload()
result used to incrementally render newly-created items omits the field,
so undefined !== 0 was true and every new file got a phantom shortcut
badge. Normalize is_shortcut to 0/1 before using it.
2026-07-16 19:05:28 -07:00
Nariman JelvehandClaude Opus 4.8 9da32c73cb Restore Files tab in dashboard (#3397)
* Restore Files tab in dashboard

Reinstates the Files tab (TabFiles) that was removed in 973d046d, bringing
back the dashboard file browser: directory navigation, list/grid views,
sorting, drag-and-drop, context menus, upload, and trash support.

- Restore src/gui/src/UI/Dashboard/TabFiles.js (identical to pre-removal)
- Re-wire UIDashboard.js: tab registration, initial file path, item socket
  handlers, and route-based file navigation
- Re-add file-tab CSS in dashboard.css and the selection-area rule in style.css
- Re-add dashboard-mode item creation hooks in helpers.js move_items
- Re-add #files/<path> deep-link parsing in initgui.js parseDashboardRoute,
  while preserving Apps as the default dashboard tab

* Only remove stale rows when moving items

* Fix Dashboard Files tab bugs

- Escape filenames in renderItem to prevent stored XSS via HTML in file
  names (matches UIItem); raw name is still preserved for display/rename.
- Read clone data-id from the nested .row in drag drop handlers so
  multi-select drag moves all selected items, not just the grabbed one.
- Resolve sidebar drop target from the element's data-path so dragging
  onto Public/Home works (they aren't keyed in user.directories); fix the
  matching UID-vs-path comparison in the drag-out handler.
- Set data-is_worker/data-worker_url from is_worker itself instead of an
  always-true "!== undefined" check, so worker context-menu behavior only
  applies to actual workers.
- Give delete-confirmation buttons explicit values so permanent delete
  works in non-English locales.
- Refresh the view after a context-menu move-paste, mirroring Ctrl+V.
- Guard the item.updated socket handler against the client's own echo,
  matching the other handlers and UIDesktop.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

* Prevent Files tab lockup when readdir fails

renderDirectory sets renderingDirectory=true then awaits puter.fs.readdir
with no error handling. readdir rejects on any backend error (permission,
deleted directory, network), leaving renderingDirectory stuck true so the
re-entry guard blocks all future navigation and the spinner never clears.
Catch the rejection and reset state.

* Isolate render failures so one bad entry can't lock the Files tab

renderItem parsed file.metadata with an unguarded JSON.parse, but metadata
is client-writable and stored verbatim, so '', undefined, or malformed
values throw (item_icon.js guards the identical call). Combined with
Promise.all, one bad entry rejected the whole render and left the tab
frozen. Guard the parse and use Promise.allSettled for per-item isolation.

* Clear selection when clicking empty area in Files tab

The empty-area click handler is an arrow function, so `this` was the
TabFiles object rather than the container element, making `e.target === this`
always false. Only clicks landing exactly on `.files` deselected. Use
e.currentTarget so clicks on the container background deselect as intended.

* Avoid stacking image-preview document click handlers

showImagePreview bound a click.imagepreview handler without removing a
prior one. It is re-invoked during image arrow-navigation while a preview
is open, so identical document handlers accumulated until close. Remove
any existing handler before binding.

* Sort live-inserted items by display name

insertAtSortedPosition compared the new item's raw file.name against
existing rows' data-name (the display name). For trashed items, name is
the UID while the real name is in metadata.original_name, so newly trashed
items landed in the wrong position in Trash until a full re-render. Compare
on the new row's data-name to match sortFiles and the existing rows.

* Use display name in in-place item update

UIDashboardFileItem's in-place update path set data-name and the shown
name from raw file.name, unlike renderItem which uses
metadata.original_name || file.name. An update to an already-visible
trashed item replaced its name with the UID and corrupted data-name
(which sort and type-to-search read). Compute the display name to match.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-16 18:57:19 -07:00
Daniel Salazar 102cef523f fix: app id whitelisting (#3398) 2026-07-16 18:03:34 -07:00
Daniel SalazarandClaude Fable 5 0e1be72f92 test: tests for puter.js (#3396)
* test: tests for puter.js

* fix: ship lockfile for coverage devDeps; tolerate missing base coverage

npm ci failed on CI because package.json gained the babel/istanbul
devDependencies without the matching package-lock.json update. Also make
the coverage workflow's base leg best-effort so a base ref that predates
the coverage script reports without the comparison column instead of
failing the run.

Co-Authored-By: Claude Fable 5 <[email protected]>

---------

Co-authored-by: Claude Fable 5 <[email protected]>
2026-07-16 15:52:37 -07:00
Neal Shah ef1afb9cc1 add just app telementry (#3387) 2026-07-16 14:04:54 -04:00
Neal Shah 0462ddd6f5 add support for step-up sessions (#3395)
* add support for step-up sessions

* update step up session
2026-07-16 13:58:49 -04:00
Neal Shah 8d7e70cde4 add kimi k3 (#3394) 2026-07-16 12:47:44 -04:00
Daniel Salazar 52e481128f wip: puter js tests structure (#3393) 2026-07-15 19:09:35 -07:00
Daniel Salazar c237e2433f fix: clean apps on subdomain deletion (#3392) 2026-07-15 13:38:53 -07:00
tamilselvanp57 a4bb57bb79 Fix static hosting domain fallback for self-hosted custom domains (#3382) 2026-07-15 11:45:10 -07:00
Daniel Salazar 861cf5efb8 feat: email api wip (#3391) 2026-07-15 11:30:16 -07:00
Daniel Salazar cf34f9fea9 fix: sanitize get user response (#3390)
* fix: sanitize get user response

* fix: app creation in dev center
2026-07-15 02:02:06 -07:00
jelveh 92a6d30e26 Add calendar to recommended apps 2026-07-14 23:04:24 -07:00
Neal ShahandDaniel Salazar 23e8705b03 Implement workers without cloudflare for local dev testing (#3389)
* typeify subdomains wip

* initial (untested) logic for LocalWorkerService

* Make it work, add lifecycle expiry since workers are process heavy in current implementation

* fix type errors

---------

Co-authored-by: Daniel Salazar <[email protected]>
2026-07-15 01:01:42 -04:00
Daniel Salazar 3240a4670a fix: admin gates (#3386) 2026-07-14 12:58:04 -07:00
Daniel Salazar 3bf83d40e9 fix: ui signup order (#3385) 2026-07-13 18:47:11 -07:00
Neal Shah c3368f553e Add GUI button for custom OIDC (#3384) 2026-07-13 20:32:37 -04:00
velzie 27def94d8b feat: support cross-origin-isolated login (#3338) 2026-07-13 17:36:56 -04:00
Neal Shah 2c139929ac Check if user is suspended on WebDAV basic auth and others (#3369) 2026-07-13 02:46:28 -04:00
Neal Shah b957f797da add support for ndjson logging (#3381)
* add support for ndjson logging

* move install location
2026-07-13 02:43:56 -04:00
jelveh 393500d565 Add calculator to recommended apps
Include 'calculator' in RECOMMENDED_APP_NAMES within RecommendedAppsService.ts so the calculator app is included in the recommended apps list.
2026-07-11 23:04:39 -07:00
jelveh a108837e82 Revert "Add delayed centered spinner for apps tab"
This reverts commit 859e88753f.
2026-07-11 15:21:59 -07:00
jelveh 859e88753f Add delayed centered spinner for apps tab
Show a subtle centered loading spinner for the Apps dashboard when fetching apps if the request is slow. Implements a 1.5s delay before showing the spinner and guarantees a minimum 1.5s visible time to avoid blinking; the spinner is only shown when the container is empty (so background refreshes keep existing tiles). Adds a finish helper to clear the spinner timer and await the minimum visible time before rendering results or errors. Also adds CSS for the spinner element and its animations.
2026-07-11 15:16:04 -07:00
Daniel Salazar 5160b44c4b fix: missing OIDC error messages (#3377)
* fix: missing OIDC error messages

* fix: card verification user prefill out for subs
2026-07-11 08:18:13 -07:00
Daniel Salazar 17a9485fb2 Add spans to drivers and high frequency paths (#3376) 2026-07-10 23:15:09 -07:00
Daniel Salazar d3c44f3d6c fix: cache healthcheck in mem for each node (#3375) 2026-07-10 17:41:09 -07:00
Neal Shah d49ba5281d add support for ignoring specific issues in healthcheck (#3374)
* add support for ignoring specific issues in healthcheck

* add mark-degraded to healthcheck
2026-07-10 17:08:03 -04:00
jelveh c107c80bd8 Open dashboard links at #home anchor 2026-07-10 13:22:58 -07:00
Daniel Salazar cf90e775bf fingerprint: use device info for rate limit too (#3372) 2026-07-09 20:22:56 -07:00
Daniel Salazar 0a46096c41 fix: ai rate limits (#3371) 2026-07-09 16:35:03 -07:00
Daniel Salazar 289a44ae79 fix: OIDC state (#3370) 2026-07-09 14:47:34 -07:00
Neal Shah 827e9bc343 fix possible XSS entrypoints (#3368) 2026-07-09 17:19:55 -04:00
Daniel Salazar f2ffaeb823 fix: add phone errors into kv for debugging (#3367) 2026-07-09 12:25:17 -07:00
Neal Shah 6f594f4b60 add 5.6 models (#3366) 2026-07-09 14:46:57 -04:00
jelveh 326be042f1 Merge branch 'main' of https://github.com/HeyPuter/puter 2026-07-08 22:33:20 -07:00
jelveh 5b824fb745 Extract resolveTileDisplay and broaden app search
Move logic that determines a tile's displayed title and target link into resolveTileDisplay (use hostname/index_url for external apps) and have buildTileHtml consume it. Expose data-target-link on tiles. Update app search to match the displayed title, raw title, name, and uid so queries find website-shortcut tiles and external apps consistently (matching Home tab behavior).
2026-07-08 22:33:13 -07:00
Reynaldi Chernando cf6cb126b5 fix grok 4.5 release date (#3365) 2026-07-09 12:30:39 +07:00
Reynaldi ChernandoandCopilot Autofix powered by AI 302df1edd2 update user pays model docs (#3364)
* update user pays model docs

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-07-09 08:54:04 +07:00
jelveh e212509ed3 Avoid clipping scaled icons in horizontal scroller
Add a negative top margin and matching top padding to the horizontal scroller to prevent first-row icons from being clipped when they scale on hover. Overflow-x:auto previously caused vertical clipping of scaled icons; margin-top:-8px and padding-top:8px bleed the clip edge upward so scaled icons remain visible without changing scroll behavior.
2026-07-08 18:35:57 -07:00
Daniel Salazar d3e3755d6d chore: cleanup uneeded ai messages (#3363) 2026-07-08 17:55:49 -07:00
jelveh 948ce6e529 Merge branch 'main' of https://github.com/HeyPuter/puter 2026-07-08 17:51:38 -07:00
jelveh d117dc231e Implement paged apps launcher UI 2026-07-08 17:50:34 -07:00
Daniel Salazar eefa53e5bd fix: misc auth bug fixes (#3362) 2026-07-08 17:50:22 -07:00
Neal Shah db89fbfc52 add grok 4.5 (#3360) 2026-07-08 14:44:05 -04:00
Daniel Salazar 97ec5d115c fix: double counting purchased credit usage (#3359) 2026-07-07 21:43:09 -07:00
Daniel Salazar 722a6cf50f fix: phone retry limit messagin (#3358) 2026-07-07 21:05:41 -07:00
Neal Shah d039dcfee5 fix appTelemetry (#3357) 2026-07-07 20:10:13 -04:00
Daniel Salazar d09aa11f2e feat: add whatsapp support? (#3356) 2026-07-07 16:13:18 -07:00
jelveh 8a2264546d Always use hash for dashboard tabs
Previously the dashboard used a clean root URL for the 'apps' tab and hashes for other tabs. This change makes tab links and history entries consistently use a hash (e.g. #apps, #home) by always generating href as `#<id>` and pushing `#<section>` to history. Simplifies URL handling and ensures the Apps tab also reflects its hash in the address bar.
2026-07-07 15:16:59 -07:00
0801e1dc44 feat: add signup disable config and fix telemetry startup (#3319)
* feat: add signup disable config and fix telemetry startup

* fix: nits for config spread and 403 checks

Co-Authored-By: Claude Fable 5 <[email protected]>

---------

Co-authored-by: Daniel Salazar <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
2026-07-07 13:52:29 -07:00
Daniel Salazar a04d5fa5e0 fix: package-lock (#3355) 2026-07-07 13:43:15 -07:00
e1280e8cc7 Add custom icon support for web links (#3325)
* feat: add custom web link icon support and context menu option

Introduce the ability to change and display custom icons for .weblink files. Added a "Change Icon" context menu item that invokes the changeWeblinkIcon helper, and updated the icon rendering logic to use getWeblinkIcon instead of the default link icon. This allows users to personalize web link appearance in the file manager.

* Fix security and robustness issues in web link custom icons

 # UIWindowSearch and require the icon data URL body to be pure base64 in
  #isValidWeblinkIcon. A shared/downloaded .weblink is untrusted input and
 # the previous prefix-only check let a crafted icon break out of the
 # <img src> attribute.
 # byte-signature MIME sniffing and capping stored icon size (was storing
 # full-resolution images as base64).
 # without picking a file.
 # weblinks no longer fetches every file's contents on each render.
 # path instead of the target weblink).
 # label, add the AGPL license header, and drop redundant stored icon
 # copies.

* Keep SVG weblink icons as vectors instead of rasterizing

Rasterizing a picked SVG to a 256px PNG threw away its scalability for no
real benefit: an SVG rendered in <img> runs in script-free static mode, and
the base64-body validation already prevents attribute injection. Store SVGs
as data:image/svg+xml;base64 (content-sniffed, size-capped), and keep
rasterizing raster formats and oversized SVGs to bound stored size.

Co-Authored-By: Claude Fable 5 <[email protected]>

---------

Co-authored-by: Daniel Salazar <[email protected]>
Co-authored-by: Claude Fable 5 <[email protected]>
2026-07-07 13:41:37 -07:00
Aman Rai 70884c2e30 fix: rename start-gui script to start:gui (#3346) 2026-07-07 12:09:49 -07:00
Reynaldi Chernando 917e95e3d7 Add nano banana 2 lite (#3336) 2026-07-07 12:08:36 -07:00
jelvehandClaude Opus 4.8 27222bbb0d Let ctrl/cmd+f use browser find while dashboard is open
The global ctrl/cmd+f shortcut opened UIWindowSearch and preventDefault'd
the keystroke, blocking the browser's native find. Skip that interception
while a dashboard window is open so ctrl/cmd+f falls through to the browser.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-07 09:43:34 -07:00
jelveh 3720034464 Make Apps the default dashboard tab
Treat the Apps tab as the default (root URL) instead of Home. UIDashboard now reads an initial route from window.dashboard_initial_route?.tab and falls back to 'apps' for unknown/absent routes. Sidebar and section active class logic and tab href/hash generation were updated so 'apps' uses the clean root URL while all other tabs (including home) use #tab. The history.pushState logic was adjusted accordingly. parseDashboardRoute in initgui.js was updated to default to 'apps' and its comment clarified the new behavior.
2026-07-07 09:31:43 -07:00
jelveh de6cab1f9a Reduce myapps tile icon size to 56px
Update .myapps-tile-icon in src/gui/src/css/dashboard.css to change width and height from 60px to 56px, adjusting tile icon sizing for improved layout and spacing.
2026-07-06 21:04:32 -07:00
jelveh 2d1fbc2611 Auto-focus My Apps search on activation
Call focusSearch when the Apps dashboard is activated and add a focusSearch helper. The helper imports isTouchPrimaryDevice and skips focusing on touch-primary devices to avoid showing the on-screen keyboard. It retries up to 12 times (30ms interval) until the search input is visible to handle cases where the dashboard is briefly hidden while entering full-page mode.
2026-07-06 20:10:44 -07:00
jelveh 0afc70218f Use input[type=search] and normalize styling 2026-07-06 20:03:48 -07:00
jelveh 8d3abbc5f0 Increase myapps tile icon size to 60px
Update .myapps-tile-icon width and height from 52px to 60px to improve icon visibility and better match the updated UI design. Other styles (overflow, background, transitions) are left unchanged.
2026-07-06 19:47:17 -07:00
jelveh 7ec14bc7db Add audio-editor and ai-image-project to recommended apps 2026-07-06 19:42:20 -07:00
jelveh 2843010a97 Increase myapps tile size to 100px 2026-07-06 19:37:46 -07:00
jelveh ad4e21ee61 Open external apps via index_url from Apps tab
When an app is external and provides an index_url, use its hostname as the tile title and store the index_url in a new data-target-link attribute. Update the click handler to open the target link in a new tab for external apps, and fall back to opening the internal /app/{name} page for others. This aligns Apps tab behavior with the Home tab and ensures external apps navigate to their website.
2026-07-06 19:21:34 -07:00
Nariman Jelveh 4de39ab6f2 Mark external apps and use the flag for dashboard titles (#3354)
* Mark external apps and use the flag for dashboard titles

An app with no owner_user_id (null/empty) isn't owned by a Puter user —
it's an external, origin-bootstrapped app whose uuid/name/title are all the
opaque app-… id. The dashboard used to detect these client-side by comparing
uuid/name/title and a name.startsWith('app-') check.

Expose an authoritative `external` flag from the API instead:

- /installedApps and /get-launch-apps now return `external`, derived from
  owner_user_id, and no longer leak the raw owner id.
- The dashboard (Home + Apps tabs) shows the index_url hostname for external
  apps based on `external` rather than the uuid/name/title heuristic.

Add/extend extension tests to cover the `external` flag and non-leak.

* Use hostname for opaque external app titles

Detect opaque external app IDs (when name === title === uid/uuid) and replace the displayed title with the hostname from index_url. Adds a uid/uuid fallback and tightens the external-app check in both the Apps and Home dashboard tabs so they behave consistently; preserves target_link for Home entries.

* Add external flag for apps without owner

Expose an `external` property in AppSummary (toAppSummary in RecommendedAppsService.ts) to mark apps that are not owned by a Puter user. The flag is set when `owner_user_id` is null or an empty string, allowing clients to identify origin-bootstrapped/external apps.
2026-07-06 18:00:56 -07:00
Nariman Jelveh fbb646b8eb Return index_url from /installedApps for dashboard app titles (#3352)
The dashboard derives a hostname title for anonymous (app-…) apps whose
uuid/name/title are all identical, falling back to the host of index_url.
That worked for launch/recent apps but not for apps that come only from
/installedApps, because the endpoint didn't return index_url.

Add apps.index_url to the SELECT (alongside apps.icon, relying on the
functional dependency on the apps.id primary key) and assert it in the
extension test.
2026-07-06 16:46:31 -07:00
Neal Shah 46f75ecd6f add type for puter.app.authenticated (#3353) 2026-07-06 18:38:30 -04:00
Daniel Salazar f68caa3bbd feat: allow optional card fallback for failed phone verifications (#3351) 2026-07-06 14:59:55 -07:00
jelveh 0109bf5b72 Use index_url hostname for anonymous app title
Detect anonymous apps whose name/title/uid are identical opaque ids (starting with 'app-') and, when index_url is available, replace the displayed title with the index_url hostname (matching the Home tab behavior). Also persist index_url into the mapped app object and make title a mutable variable to support the change.
2026-07-06 14:43:39 -07:00
Nariman Jelveh c69fb52d5c Make the dashboard the default interface at root (#3345)
* feat: make the dashboard the default interface at root

The dashboard now loads at / (with /dashboard kept as an alias), and the
desktop moves to a new /desktop route. An "Open Desktop" button pinned at
the bottom of the dashboard sidebar switches to the desktop.

Root URLs that carry a desktop-only flow keep booting the desktop:
auth popups (?embedded_in_popup=), app deep links (?app=), direct
downloads (?download=), fullpage mode (?puter.fullpage=), and iframe
embeds.

Desktop-context redirects are retargeted so desktop users stay on the
desktop: logout, the QR "continue on phone" link, the auth cover-page
logo click, and window close/hide URL resets now use /desktop. OIDC
login/signup gains a strictly whitelisted return_to param (/desktop or
/dashboard) so social login returns to the interface it started from.

Also: the dashboard strips ?ref= like the desktop does, ?auth_token=
cleanup preserves the path and tab hash, the logged-out session list
gets the wallpaper back, ?download= also works at /desktop, and the GUI
dev server serves /desktop and /dashboard.

* Add Open Desktop bento card and CSS

Replace the previous desktop-switch UI with a full-width "Open Desktop" bento card that links to /desktop. Removes the pinned sidebar Open Desktop button and the old desktop-switch button/handler, and adds new CSS variables and styles for the desktop card (icon background, shadow, surface/header colors), hover shadow and arrow transition, and layout/padding adjustments.

Changed files: TabHome.js (removed old switch, added anchor card), UIDashboard.js (removed sidebar button), dashboard.css (new desktop color vars and styles; removed legacy desktop-switch/button styles).

* Remove box-shadow from myapps search input

Delete the box-shadow declarations from input.myapps-search::placeholder in dashboard.css. This simplifies the placeholder styling (removes subtle and light shadow layers), likely to reduce visual noise or fix rendering inconsistency.

* Show index_url hostname for opaque app IDs

Only replace an app's title with the hostname from index_url when the app appears to use an opaque id. Add a check for names starting with 'app-' so the hostname is used only if title, name and uuid are identical and the name looks like an opaque app id. This avoids overwriting meaningful user-facing names that may coincidentally match the uuid and clarifies the intent in the comment.

* Update dashboard.css
2026-07-06 13:22:27 -07:00
Neal Shah 3a26f1f1c2 add admin moderation events table (#3348) 2026-07-06 11:49:09 -04:00
Daniel Salazar f1b94a5b69 fix: otel upgrade bump (#3328) 2026-07-06 08:42:25 -07:00
Neal Shah e3fce9191a emit puter.app.authenticated event (#3337) 2026-07-06 11:23:27 -04:00
Nariman Jelveh 2c0a1b9bbb Revert "feat: add sign-in flow for crossOriginIsolated contexts (#3253)" (#3335)
This reverts commit 6fff1fd75f.
2026-06-30 23:32:27 -07:00
jelveh 0d7417f858 Add 'contacts' to recommended apps
Include 'contacts' in the RECOMMENDED_APP_NAMES array so the Contacts app appears in the recommended apps list. Updated src/backend/services/apps/RecommendedAppsService.ts.
2026-06-30 19:08:11 -07:00
Neal Shah 2eee098c66 Add suspension reasons (#3331) 2026-06-30 18:09:00 -04:00
Neal Shah 890d4b3c16 remove temperature from sonnet-5 (#3330) 2026-06-30 17:18:29 -04:00
Neal Shah af9a7c6345 add claude sonnet 5 (#3329) 2026-06-30 17:08:42 -04:00
velzie 6fff1fd75f feat: add sign-in flow for crossOriginIsolated contexts (#3253)
* poc

* route login key through broadcastservice

* cleanup

* security validation and prevent additional webhook sends

* block double-broadcast from redis
2026-06-30 20:17:53 +01:00
velzie e6b7b08bda Add forceRelay option to Peer API and document raw peerconnection property (#3313)
* add forceRelay options

* document peerconnection
2026-06-30 12:28:49 -04:00
Daniel Salazar f4c3cbd53d feat: add logs for failed sms (#3318) 2026-06-30 06:50:47 -07:00
Reynaldi ChernandoandCopilot Autofix powered by AI c0c2f35266 Update docs model drift (#3326)
* Update docs model drift

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

* standardize

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-06-30 16:55:42 +07:00
Nikhil Kumar SinghandDevblaze14 ccea980753 feat: add Ideogram 4.0 Together AI image model (#3309)
Co-authored-by: Devblaze14 <[email protected]>
2026-06-29 15:33:01 -04:00
Neal Shah 2bddebd576 add ability to suspend apps (#3322) 2026-06-29 13:06:08 -04:00
Neal Shah b9866ddbeb add suspended_at col (#3321) 2026-06-29 09:51:00 -04:00
Mochammad Fadhlan Al-Ghiffari 6fc79a7184 fix(docs): highlight code blocks after client-side navigation (#3287) (#3288)
* fix(docs): highlight all code blocks after client-side navigation

The docs site highlights code on full page load via an inline
hljs.highlightAll(), which targets the 'pre code' selector and so
highlights every fenced block, including those without a language tag.

The client-side navigation path (pathchange handler) instead selected
only code[class^="language"], so fenced blocks written without a
language hint were left unhighlighted after in-app navigation while
appearing correctly on a hard reload.

Align the pathchange handler with highlightAll() by selecting 'pre code'
and skipping blocks hljs has already processed (data-highlighted=yes),
keeping the pass idempotent across repeated pathchange events.

Fixes #3287

* fix(docs): hoist hljs.configure and scope highlight to docs content

Address review nits on the pathchange highlight pass:
- Move hljs.configure({ ignoreUnescapedHTML: true }) out of the per-element
  loop since it is global config and only needs to run once.
- Scope the selector to '.docs-content pre code' so the re-highlight pass
  only touches the swapped-in docs body and leaves code blocks elsewhere
  on the page untouched.
2026-06-28 23:27:07 +07:00
Nariman Jelveh 50039571b6 Reorder recommended apps and add vault
Adjust RECOMMENDED_APP_NAMES ordering: place 'editor', 'camera', and 'recorder' immediately after 'builder' and move 'app-center' accordingly. Also add 'vault' to the recommended apps list. This changes the resolved ordering of recommended apps at call time.
2026-06-27 17:55:52 -07:00
Daniel Salazar 1216f20567 fix: package-lock issue (#3316) 2026-06-27 14:33:11 -07:00
Daniel Salazar 0752ea761c feat: remove stych, add prelude client (#3312) 2026-06-27 14:07:52 -07:00
Daniel Salazar 98461088f8 fix: decrease puts for unused stamps (#3310) 2026-06-26 12:33:04 -07:00
Neal Shah d4a3224aa3 force locale en-US (#3311) 2026-06-26 15:31:58 -04:00
Daniel Salazar 197ce6faff fix: LegacyFSController (#3308) 2026-06-25 14:47:29 -07:00
MRB Labs c98e293879 fix: unlink OIDC providers when user updates email address (#3307) 2026-06-25 14:46:41 -07:00
Miika Kuisma ebbe382596 tweak context menu's text labels (#3306) 2026-06-25 09:46:05 -07:00
Neal Shah 01d28eb2c5 Await phone verification event (#3305) 2026-06-24 20:08:30 -04:00
Daniel Salazar 7d1c2e7f0a fix: fsService copy (#3304) 2026-06-24 16:32:34 -07:00
Daniel Salazar 22b499af20 fix: cleanup fs responses (#3303) 2026-06-24 14:35:58 -07:00
Neal Shah 7208f86723 bind btoa and atob in emulated worker globalspace (#3302)
* bind btoa and atob in emulated worker globalspace

* Create working directory for workers
2026-06-24 15:56:26 -04:00
Neal Shah 2974a8b01c store app owner ID even when worker is deployed from root ctx (#3301) 2026-06-24 15:21:48 -04:00
Daniel Salazar 7f05a707bd feat: improve kv store incr/decr costs (#3300) 2026-06-24 11:57:36 -07:00
Miika Kuismaandjelveh 1d056253ef contextmenu design tweak (#3298)
* contextmenu design tweak

* icon gap fix (mobile context menu web component)

* fix submenu item padding

* add dark theme support for puter.ui.contextMenu and puter.ui.setMenubar (works only with puter.env === 'web')

* Add theme test & refactor context menu items

Extract shared mediaMenuItems to remove duplication and simplify context menu calls. Add a light-theme context menu handler and a "Run theme test" button that executes runContextMenuThemeTest(), which programmatically renders menus to verify the theme attribute and .puter-theme-dark class for dark, light, and default cases (mirrors existing Playwright assertions). Update testContextMenu and testContextMenuDark to use the new item factory and clean up rendered menus after checks. UI text is updated to show pass/fail results.

---------

Co-authored-by: jelveh <[email protected]>
2026-06-24 11:30:16 -07:00
Neal Shah a22dc5facb fix whoami user token check (#3299) 2026-06-24 14:28:02 -04:00
Neal Shah aeafd4ac79 txt2img megaupdate (#3294)
* Update OpenAIImageProvider with txt2img with input source

* Grok image provider mega update

* make input_images universal
2026-06-24 10:24:09 -04:00
Daniel Salazar 14861df6b2 fix: bad boot error (#3295) 2026-06-24 00:33:38 -07:00
Daniel Salazar 34a7595a6d fix: bad empty file error handling (#3293) 2026-06-23 16:13:41 -07:00
Daniel Salazar b2108c0216 fix: update email for supprot (#3292) 2026-06-23 15:43:12 -07:00
Philip Ifeanyi 5a5a449210 feat: enhance playground UI with page title and style adjustments (#3289) 2026-06-23 22:45:18 +07:00
Daniel Salazar 0405de30bd update taskbar apps (#3286) 2026-06-22 14:26:35 -07:00
Nariman Jelveh 40c2799b06 Add 'builder' to recommended apps list
Include 'builder' in the RECOMMENDED_APP_NAMES array in src/backend/services/apps/RecommendedAppsService.ts so the RecommendedAppsService treats the builder app as a recommended application and surfaces it accordingly.
2026-06-22 14:22:27 -07:00
Daniel Salazar 4bcdeefe68 chore: bump up deps (#3285) 2026-06-22 13:58:45 -07:00
Daniel Salazar b6ba6dd90e fix: [PUT-1199] more prelude signals (#3282) 2026-06-22 08:16:59 -07:00
Daniel Salazar 954f8b7b8d fix: puter self host guides + default bug (#3281)
* fix: oss dev center html_encode hardening

* fix: puter self host guides + default bug
2026-06-21 22:32:43 -07:00
Neal Shah 24d700673c Compaction support for OpenAI and Anthropic (#3279)
* Alpha: compaction support for OpenAI and Anthropic

* update lock

* fix billing for anthropic compactions

* Fix max_tokens bug in together provider

* Fix responses compaction
2026-06-21 21:57:56 -04:00
c6d64029e0 feat: meter Gemini thinking tokens and grounding requests (#3178)
* feat: meter Gemini thinking tokens and grounding requests

- Thinking tokens: Extracted from standard completion tokens to ensure they are billed accurately at the correct model-specific rate.
- Grounding requests: Added flat-fee metering for Google Search by tracking grounding_metadata across both streaming and non-streaming responses.
- Pricing updates: Corrected stale rates for Gemini 2.5 Flash output, cached tokens, thinking tokens, and grounding requests.

* fix: correct Gemini 2.x metering rates and harden grounding capture

Pricing corrections (verified against ai.google.dev/gemini-api/docs/pricing):
- gemini-2.5-flash output is $2.50/M, not $1.00/M: restore
  completion_tokens to 250 and bill thinking_tokens at the same output
  rate (250). The previous 100 under-billed output ~60%, and this is the
  provider's default model.
- gemini-2.5-flash cache read is $0.03/M: restore cached_tokens to 3
  (the 7.5 value over-billed).
- Grounding with Google Search is $35 / 1,000 requests for Gemini 2.x
  models and $14 / 1,000 for 3.x. Set grounding_requests to 3_500_000
  for gemini-2.0-flash, gemini-2.5-flash, gemini-2.5-flash-lite and
  gemini-2.5-pro; 3.x models keep 1_400_000.

Streaming robustness:
- In create_chat_stream_handler, don't let a later extra_content chunk
  without grounding_metadata overwrite an earlier one that carried it,
  so grounding requests are still metered.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>

---------

Co-authored-by: Daniel Salazar <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-20 15:08:38 -07:00
jelveh 40ff866598 Add 'butler' to recommended apps
Include 'butler' in the RECOMMENDED_APP_NAMES array in RecommendedAppsService so it appears in the recommended apps list. Updates src/backend/services/apps/RecommendedAppsService.ts.
2026-06-19 15:50:57 -07:00
Nariman Jelveh 36888e35d3 Add phone verification UI improvements and helpers (#3274)
Revamps the phone verification dialog and adds reusable phone helper modules.

- Heavily refactors UIWindowPhoneVerificationRequired.js to add a searchable inline country picker, national-number live formatting, country autodetect for "+" input, WebOTP auto-fill support, resend cooldown timer, accessibility improvements, proper teardown/cleanup, and last-used country persistence.
- Introduces helpers/src/helpers/country_codes.js (get_country_list, flag emoji) which builds a localized list of dialable countries from libphonenumber-js and Intl.DisplayNames.
- Introduces helpers/src/helpers/phone.js with thin wrappers around libphonenumber-js: format_phone_as_you_type, inspect_phone, phone_example_for, detect_country_from_input.
- Adds English i18n strings for the new UI in src/gui/src/i18n/translations/en.js.

These changes keep submission canonicalization using libphonenumber-js (E.164), improve UX for selecting/formatting numbers, and make the country list and phone utilities reusable across the app.
2026-06-19 10:28:30 -07:00
Reynaldi Chernando 30432b931a Add PUT and DELETE to preflight allowed methods (#3278) 2026-06-19 12:35:29 -04:00
Reynaldi Chernando e2174a14cf Update router cors preflight docs (#3277) 2026-06-19 20:50:41 +07:00
Daniel Salazar d3cb89d8c9 fix: import in extensions (#3276) 2026-06-18 21:30:00 -07:00
Reynaldi Chernando c8625b3396 Release puterjs npm (#3275)
* Release puterjs npm

* add package lock
2026-06-18 18:26:39 -07:00
Reynaldi Chernando b576f01d12 Sync Puter.js types and docs (#3194)
* AI chat types

* ai voice types

* update tts docs and jsdoc

* stt types and docs

* txt2img docs and types

* txt2vid and img2txt

* apps

* signin

* perms

* fs

* kv

* hosting

* workers

* net

* ui

* jsdoc
2026-06-18 09:34:13 -07:00
Vyasdev a87cafee3c Revise bug report and feature request instructions (#3220)
Updated the wording for reporting bugs and feature requests in Japanese.
2026-06-18 09:27:55 -07:00
Reynaldi Chernando 1c51fde163 Add minimax m3 direct integration + cleanup model list (#3263) 2026-06-18 10:12:44 -04:00
Daniel Salazar b05699db77 fix: AGENTS.md cleanup (#3273) 2026-06-17 17:07:20 -07:00
Daniel Salazar 163e48ab27 feat: viz over user verification types (#3271) 2026-06-17 14:21:55 -07:00
Reynaldi Chernando 0b41d992a4 Add glm 5.2 direct integration (#3269) 2026-06-17 09:40:10 -04:00
Miika Kuisma c2ddfd6867 Merge pull request #3270 from HeyPuter/fix-file-dialog
puter.js - fix issue where content of file dialog wasn't visible
2026-06-17 13:08:43 +03:00
Miika Kuisma 81b9dc1f06 fix issue where content of file dialog wasn't visible 2026-06-17 13:07:13 +03:00
Daniel Salazar 5506ddb2c2 feat: fp cleanup and better devex (#3268) 2026-06-16 22:48:54 -07:00
Neal Shah c74469b01a prelude RCS (#3267) 2026-06-15 19:08:30 -04:00
Daniel Salazar b706693f82 wip: hardening (#3266) 2026-06-15 16:07:44 -07:00
Daniel SalazarandNeal Shah cd800148d5 feat: optional additional verification gates (#3262)
* phone number verificiation initial

* finish phone verification

* feat: add card gate for signups

* chore: npm

* fix: modal order and wording

* fix:wording

---------

Co-authored-by: Neal Shah <[email protected]>
2026-06-15 09:16:00 -07:00
Ricardo Sawir 900b0d7aa6 fix: correct puter container healthcheck URL (#3255)
The healthcheck was using 'puter.localhost:4100/test' which fails for
two reasons:
- 'puter.localhost' does not resolve inside the container; the service
  listens on all interfaces at port 4100, so 'localhost' works
- '/test' endpoint does not exist; use '/' which serves the shell

This caused the container to be perpetually marked as unhealthy.

Fixes #3191
2026-06-13 23:17:44 -07:00
Daniel Salazar 7e21c1f888 fix: fs metadata sanitation (#3257) 2026-06-12 22:56:06 -07:00
Daniel Salazar 00d6f9c230 fix: disallow unverified outlook emails (#3256) 2026-06-12 18:52:24 -07:00
jelveh 4c03080efa Update mcp.md 2026-06-12 16:55:37 +02:00
jelveh 432a11d289 Add Cursor MCP docs and icons 2026-06-12 16:37:53 +02:00
jelveh e9e233404b Add icons for Claude, Codex and OpenCode 2026-06-12 13:20:15 +02:00
jelveh 8101d42604 Capitalize OpenCode in MCP docs 2026-06-12 13:16:41 +02:00
jelveh 88cedd43bc Add opencode MCP example to docs 2026-06-12 13:11:24 +02:00
Daniel Salazar d3a2934d9b feat: fingerprinting for signup checks (#3254) 2026-06-12 00:59:21 -07:00
Daniel Salazar 13a36b6199 fix: secure http calls (#3252) 2026-06-11 13:43:58 -07:00
Daniel Salazar a155464d46 fix: more data for puter site serve event (#3251) 2026-06-10 23:27:13 -07:00
Daniel Salazar 40d1c998bb feat: pass args to all events (#3248)
* feat: pass args to all events

* fix: alias app joining

* fix: actor in event
2026-06-10 14:13:04 -07:00
Daniel Salazar b4837d49b6 perf: some perf gains from fable (#3249) 2026-06-10 13:26:35 -07:00
ProgrammerIn-wonderland e23042b42e add preperation for reputation score persistence (#3250) 2026-06-10 16:09:42 -04:00
Daniel Salazar 240a733285 sec: misc fable hardening (#3244)
* sec: misc fable hardening

* more fixes

* more fixes

* fix: cors issue
2026-06-10 11:19:41 -07:00
Reynaldi Chernando bb202be12c Minor clarification local webserver in deployment (#3247) 2026-06-10 23:04:42 +07:00
Reynaldi Chernando 8c4cb601c9 Add cli docs (#3246) 2026-06-10 20:53:53 +07:00
Reynaldi Chernando 64a7c7b7c4 Add mcp docs (#3245) 2026-06-10 20:31:31 +07:00
wwb1942 2dd2887ff7 ci: add docs build workflow (#3235)
* ci: add docs build workflow

Add CI workflow that runs npm ci and npm run build in src/docs

whenever files under src/docs change in a pull request.

Closes #3225

* ci: also trigger docs build when workflow file changes

* ci: address docs build workflow review
2026-06-10 10:53:40 +07:00
ProgrammerIn-wonderland 4bbe8a2789 add protections for PUT-1094 (#3243) 2026-06-09 22:29:57 -04:00
Dilan Melvin T 3e9ceb673b fix: coerce Mistral image_url parts from object to string (#3177)
* fix: coerce Mistral image_url parts from object to string

Mistral's API expects image_url content parts to be a plain string URL,
not the OpenAI-style { url: string } object that process_input_messages
produces. Without this coercion, sending an image to any Mistral model
that supports vision (mistral-small, mistral-medium, mistral-large,
ministral-*) results in a request error from the Mistral SDK.

Add #coerceImageUrls() as a private method on MistralAIProvider that
maps { type: 'image_url', image_url: { url } } -> { type: 'image_url',
image_url: url } for every content part in every message. Messages with
plain string content are left untouched, as are parts whose image_url is
already a string.

Add four unit tests covering: object-to-string coercion, already-flat
strings, plain string message content, and mixed text+image content.

* style: use plain ASCII dashes in comment section divider
2026-06-09 20:12:44 -04:00
Daniel Salazar 9c4d1ef535 fix: misc bugs + new middleware for before/after routes (#3242) 2026-06-09 17:05:56 -07:00
ProgrammerIn-wonderland bf57518262 MCP: assert worker_exec ends with puter.work (#3241) 2026-06-09 17:43:34 -04:00
Reynaldi Chernando d48fb11de6 Add claude fable 5 (#3238) 2026-06-09 14:05:31 -04:00
ProgrammerIn-wonderland 7ed87f760b make max tokens less lenient (#3240) 2026-06-09 14:03:13 -04:00
Reynaldi Chernando ee37be16f0 Add cli deployment docs (#3239) 2026-06-10 00:40:19 +07:00
Reynaldi Chernando a8cfaeefbd Add subdomain and workers github actions deployment (#3226)
* Add subdomain and workers github actions deployment

* minor adjust
2026-06-09 23:35:34 +07:00
Badri467 58cb8ee048 skip github actions backend for docs only changes (#3236) 2026-06-09 23:28:48 +07:00
Daniel Salazar a72fbd1d47 fix: inform acl of full access flag (#3237) 2026-06-09 08:04:36 -07:00
Daniel Salazar f6408db74e fix: access tokens with full accesses allowed through with new middleware gate (#3234) 2026-06-08 18:47:07 -07:00
ProgrammerIn-wonderland df20993d8b set azure openai as the default (#3233) 2026-06-08 20:33:41 -04:00
ProgrammerIn-wonderland 708fe1bc4e azure ai provider (#3232) 2026-06-08 18:31:49 -04:00
Daniel Salazar e782fa832e fix: kv costs (#3231) 2026-06-08 13:32:36 -07:00
ProgrammerIn-wonderland c947c2c989 fix mcp server cloudfront cache bug (#3230) 2026-06-08 15:42:49 -04:00
Daniel Salazar 3de4613b7d Revert "feat (PUT-1091): have gui tokens labeled and be different than reques…" (#3229)
This reverts commit 1335b46404.
2026-06-08 11:15:24 -07:00
Daniel Salazar def7290c48 feat: emit user.deleted event on user deletion (#3228) 2026-06-08 10:30:24 -07:00
Daniel Salazar 1335b46404 feat (PUT-1091): have gui tokens labeled and be different than requestor ones (#3222)
* feat (PUT-1091): have gui tokens labeled and be different than creator ones

* fix: errors with auth token
2026-06-08 09:03:02 -07:00
Reynaldi Chernando 0e15ac98a9 Update cli readme and set version (#3227) 2026-06-08 22:23:32 +07:00
Reynaldi ChernandoandCopilot Autofix powered by AI f127b2509d Add docs fixes for deployment and workers pages (#3223)
* Add docs fixes for deployment and workers pages

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

* handle router edge case

* explicit info about wildcard requiring name

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-06-08 17:43:00 +07:00
Sourabh Sharma 15134c99bf Fix mkdir dedupeName for existing directories (#3215) 2026-06-07 12:49:00 -07:00
Daniel Salazar 8262e3193e perf: don't batch get app stats (#3219) 2026-06-06 18:28:59 -07:00
Reynaldi Chernando 98a21c4ac0 More workers docs improvement (#3218)
* More workers docs improvement

* Add mention of workers alongside mention of user scope
2026-06-06 01:27:24 +07:00
ProgrammerIn-wonderland c52eb1b903 Ns/bug fixes 060426 (#3214)
* Harden backend auth

* Puter.js auth hardening
2026-06-05 13:55:23 -04:00
mohit_parmar_007 d6a71e50bb fix: remove unnecessary cache console.log statements (#3216) 2026-06-05 10:01:59 -07:00
Reynaldi Chernando a4b6ee0dd2 [PUT-1090] Improve worker docs (#3217)
* Improve worker docs

* refine
2026-06-05 21:54:56 +07:00
Daniel Salazar bb61103080 feat: add apps api into mcp (#3213) 2026-06-04 17:19:53 -07:00
Daniel Salazar 9bbc76b2dd drop metering alerts to low severity (#3212) 2026-06-04 14:01:44 -07:00
Daniel Salazar 918aba9c80 fix: reduce alarms further (#3211)
* feat; update bug-bounty

* fix: reduce alarms further
2026-06-04 10:43:50 -07:00
Reynaldi ChernandoandCopilot Autofix powered by AI 3ceba9e3b3 Minor fix deployment docs (#3210)
* Minor fix deployment docs

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
2026-06-04 23:48:25 +07:00
Daniel Salazar a480679a2d vis: make metering service alarm only go off on actual abuse (#3208) 2026-06-03 22:45:18 -07:00
Daniel Salazar e99ae40e93 chore: bump puter-js (#3207) 2026-06-03 18:59:07 -07:00
Daniel Salazar 3cd50fbaf3 move the token migration to root (#3206) 2026-06-03 18:54:22 -07:00
ProgrammerIn-wonderland 60dd1453d4 Fix issues (#3205) 2026-06-03 21:19:33 -04:00
ProgrammerIn-wonderland 07781cd681 allow overriding origin from workers.dev on mcp server (#3204) 2026-06-03 17:48:37 -04:00
ProgrammerIn-wonderland 2387d8dcc9 MCP whoami (#3203) 2026-06-03 17:13:13 -04:00
Reynaldi Chernando 723608f4db Add new puter cli (#3199)
* Add new cli

* update package lock

* fix readme and license
2026-06-04 01:51:31 +07:00
Reynaldi Chernando bd1dcde7b0 Add info for puterjs deployments (#3202)
* Add info for puterjs deployments

* update external links

* hide github actions method
2026-06-04 01:25:57 +07:00
ProgrammerIn-wonderland 5b8e41e66d MCP Server (#3197)
* beginnings of mcp

* oauth support

* add workers and better prompt engineering
2026-06-03 12:23:06 -04:00
Nariman Jelveh acc4796b99 Allow Cache-Control and Pragma headers (#3198) 2026-06-03 14:30:33 +02:00
jelveh 106e85d6ca Force revalidation on FileSystem reads 2026-06-03 14:15:22 +02:00
ProgrammerIn-wonderland 0ffc32f19e add whitelist for signed batch uploads (#3196) 2026-06-02 21:30:34 -04:00
Daniel Salazar d897cc5dd0 refactor: move subscriptions to webhook system (#3193)
* fix: dont sign write urls if they don't have write perm

* wip: new subscriptions

* refactor: move subscriptions to
2026-06-02 17:58:56 -07:00
Daniel Salazar 6d2f277ce2 fix: some error handling (#3190) 2026-05-31 18:58:27 -07:00
ProgrammerIn-wonderland 86f80b29c0 tighten RAO policy (#3188) 2026-05-29 20:52:21 -04:00
Daniel SalazarandProgrammerIn-wonderland 39243735e8 feat (put-1049): worker types (#3185)
* feat (put-1049): worket types

* Implement changes to worker types

---------

Co-authored-by: ProgrammerIn-wonderland <[email protected]>
2026-05-29 20:51:57 -04:00
ProgrammerIn-wonderland b3ff9d74b7 add browserjs to taskbar and RecommendedAppService (#3189) 2026-05-29 20:32:53 -04:00
ProgrammerIn-wonderland 7b7604440f Add serverless only filtering for togetherai chat models (#3187) 2026-05-29 14:33:55 -04:00
ProgrammerIn-wonderland 382d2b3c14 add minimax provider (#3171)
* add minimax provider
2026-05-29 13:36:10 -04:00
Anurag Pappula eda5379c17 fix(docs/search): handle search index loading and failure states (#3184)
* fix(docs/search): show loading state and replay query when index isn't ready

Previously performSearch rendered "No results found" while the
MiniSearch index was still loading, which is misleading on slow
networks. Track the last query as pendingQuery and replay it from
fetchSearchIndex once the index is ready; render a distinct
"Failed to load search index" message on fetch error so the
loading message doesn't persist indefinitely.

Fixes #3180.

* fix(docs/search): close stale-replay race and consolidate status messages

Drop pendingQuery synchronously in the input handler when the query
falls below the minimum length, so a fetchSearchIndex that resolves
within the 300ms debounce window after the user clears the field can
no longer replay the cleared query into an empty input.

Move the idle, loading, and failed copy into a single
renderSearchStatus(kind) helper so the four .search-no-results
renderings can only drift in one place.
2026-05-29 16:00:59 +07:00
Ron HernausandDaniel Salazar d2fee51844 Support PostgreSQL database backend (#3167)
* feat(database): add postgres database client

Adds the PostgreSQL database client, native bootstrap migration, SQL preparation helpers, and database config/factory wiring.\n\nRefs #3165.

* feat(database): make backend queries postgres-aware

Updates runtime SQL call sites for database-specific booleans, identifiers, insert-ignore, upserts, JSON extraction, intervals, and Postgres insert ids.\n\nRefs #3165.

* test(database): cover postgres client behavior

Adds unit coverage for SQL preparation, factory selection, write-result mapping, and transaction rollback/commit ordering, plus an env-gated PostgreSQL integration flow.\n\nRefs #3165.

* docs(self-hosting): document postgres database setup

Adds PostgreSQL configuration examples and migration path guidance for self-hosted deployments.\n\nRefs #3165.

* fix: harden postgres oidc tests

* fix(postgres): normalize query results and SQL prep

* fix(user): preserve normalized cache booleans

* test(postgres): run integration coverage with pgmock

* tests: add way to run all tests with postgres though slow

Also adding note that postgres is not in active use so might not work out the box

---------

Co-authored-by: Daniel Salazar <[email protected]>
2026-05-28 14:12:17 -07:00
Daniel Salazar 8ac4bad196 fix: readUrl perm check (#3183) 2026-05-28 11:44:16 -07:00
Reynaldi Chernando f140d7221c Add opus 4.8 (#3182)
* Add opus 4.8

* update alias

* handling opus 48 omit temperature
2026-05-28 13:27:46 -04:00
Daniel Salazar 631f0bda1b chore:deploy latest puter.js (#3181) 2026-05-28 09:58:33 -07:00
Reynaldi Chernando 1121314582 Docs search improvement (#3179)
* Init search improvement

* Add fuzzy implementation

* update package lock

* package lock matched with runner 24.16.0
2026-05-28 23:11:34 +07:00
Daniel Salazar dda6b82f0f fix: missing english i18n (#3176) 2026-05-27 16:31:40 -07:00
ProgrammerIn-wonderland 6c757c3fc8 Don't use passed in authorization in workers (#3175) 2026-05-27 18:09:59 -04:00
Daniel Salazar eba194936e tests: more tests for session and auth (#3174) 2026-05-27 12:32:15 -07:00
Daniel Salazar a7bdac16da tests: Add unit tests for XAISpeechToTextDriver (#3173)
closes #3002
2026-05-27 11:49:16 -07:00
Daniel Salazar 716a8d06e2 fix: session store kind column + duplicate error handling (#3172) 2026-05-27 11:44:08 -07:00
Daniel Salazar e95cf44fec fix: small fixes for perf and username checks (#3169) 2026-05-27 03:10:56 -07:00
Daniel Salazar 8f8efcb349 feat (PUT-1025 PUT-1026 and PUT-1017): better handling old token auth required in gui (#3166)
* feat (PUT-1025 PUT-1026 and PUT-1017): better handling old token forcing in gui

* fix: misc issues with token inval project
2026-05-27 02:26:35 -07:00
Daniel Salazar b188942436 feat (PUT-1016 & PUT-1020) (#3164)
* feat (PUT-1016 & PUT-1020)
temp account preservation on forced relogin
hosted asset cookies to v2 token too

* fix: remove llm dashes and ugly comments

* update agents
2026-05-26 23:35:16 -07:00
Daniel Salazar 9b7e9a98c8 fix: session revocation (#3163) 2026-05-26 22:13:12 -07:00
Daniel Salazar d6f7fb6155 chore: package-lock update (#3161) 2026-05-26 20:33:11 -07:00
Daniel Salazar bd91f5e192 feat: worker sessions get their own kind + per-(user, app, worker_name) row (#3160)
* feat: worker sessions get their own kind + per-(user, app, worker_name) row

Schema
------
- mysql_mig_11.sql + sqlite 0054: add idx_sessions_user_worker_active,
  a partial unique index over (user_id, app_uid, meta.worker_name) for
  kind='worker' rows. Active worker sessions are deduped by that triple
  so each named worker gets its own session row and they don't fight
  the existing idx_sessions_user_app_active (which still constrains
  kind='app' only). app_uid is allowed NULL for user-scoped workers
  with no app binding.

SessionStore
------------
- getOrCreateWorker(userId, { appUid, workerName, ... }): mirrors the
  getOrCreateApp pattern — cache lookup, partial-unique re-SELECT on
  insert-ignore, all keyed on the worker triple. expires_at lands at
  WORKER_WINDOW_SECONDS (~99y) so the worker doesn't have to re-mint
  on any cadence.
- #cacheKeyWorker + #allCacheKeysForRow worker branch so revoke /
  update invalidates the worker cache view alongside the by-uuid one.

AuthService
-----------
- createWorkerSessionToken(user, workerName, meta?) now takes the
  workerName explicitly and routes through getOrCreateWorker. Emits
  the same { session, token, gui_token } shape but both JWTs carry
  { worker: true, worker_name }.
- createWorkerAppToken(actor, appUid, workerName) likewise — JWT
  carries the worker_name claim so a verifier can tell two workers
  under the same app apart without a DB round-trip.
- Both methods 400 on empty workerName.

WorkerDriver
------------
- Five auth-mint call sites swapped over: app-bound deploy (3x:
  appId branch, actor.app fallback, hot-reload redeploy), user-bound
  fallback (2x: cold deploy, hot-reload). All pass `workerName` so
  the worker's session row is naturally idempotent across redeploys.

GUI manage-sessions
-------------------
- sessionTitle adds a kind='worker' branch ("name (app)" for
  app-scoped workers, just "name" for user-scoped), pulling worker_name
  from the meta-spread that listSessions already surfaces.
- en.js adds ui_session_kind_worker.

* fix(workers): MySQL JSON_EXTRACT quoting + revoke cache invalidation +
SQLite NULL-distinct in worker index

Three real bugs in the worker session plumbing from the prior commit,
plus a misleading comment. Schema design kept (worker_name lives in
`meta` rather than a dedicated column) per offline review:

1. `#selectWorkerRow` compared `JSON_EXTRACT(meta, '$.worker_name')`
   directly to a bind parameter. MySQL's `JSON_EXTRACT` returns a
   JSON-typed value with embedded quotes (`"name"`, not `name`), so
   the comparison never matched. After the first INSERT, every
   follow-up getOrCreateWorker call missed the existing row in the
   SELECT, hit INSERT-IGNORE, then missed again in the re-SELECT —
   the caller would receive whatever the INSERT-IGNORE returned (a
   no-op row in conflict cases). Wrap with `JSON_UNQUOTE` on MySQL
   via `db.case`; SQLite's `json_extract` already returns the
   unwrapped scalar so it keeps the literal form.

2. mig_11's generated `worker_unique_key` had the same JSON-quoting
   bug. Mirror the fix: `IFNULL(JSON_UNQUOTE(JSON_EXTRACT(...)), '')`
   so the concatenated unique key is a plain string that lines up
   with what `#selectWorkerRow` now binds against.

3. SQLite UNIQUE indexes treat NULL columns as distinct (per the SQL
   standard), so two user-scoped workers (app_uid NULL) with the same
   worker_name would both insert. Wrap the index expression with
   `IFNULL(app_uid, '')` so they correctly conflict — matches the
   MySQL side's `IFNULL` in the generated column.

4. `removeByUuid` / `revokeCascade` SELECTed only the identity
   columns (no `meta`), so `#allCacheKeysForRow`'s worker branch
   couldn't read `meta.worker_name` and the composite
   `sessions:v2:worker:<user>:<app>:<name>` cache key survived
   revocation. Up to CACHE_TTL_SECONDS (15min) afterwards,
   getOrCreateWorker would short-circuit to the cached (revoked) row.
   Add `meta` to both SELECTs; the existing meta-parsing logic in
   `#allCacheKeysForRow` handles the rest.
2026-05-26 20:05:31 -07:00
Daniel SalazarandClaude Opus 4.7 971a1b5071 chore: drop linear/issue ticket references from source comments (#3159)
54 references across 18 files (PUT-1010, PUT-1014, PUT-1019, PUT-1021,
PUT-1022, PUT-1023, PUT-1024 + sub-tags AUTH-2/4/5, SDK-1, PJS-1/2,
GUI-1/2, ROLLOUT-1) removed from inline comments, doc comments,
test describe blocks, and SQL migration headers. The substantive
explanations stay; only the ticket pointers go.

No behavior change. Full backend test suite: 2172 passed / 16 skipped.

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-26 18:50:43 -07:00
Daniel SalazarandClaude Opus 4.7 ac5eecb7f3 feat (put-1019 put-1021): v2 auth revoke endpoints + silent v1->v2 to… (#3158)
* feat (put-1019 put-1021): v2 auth revoke endpoints + silent v1->v2 token migration

PUT-1019 (AUTH-5): full revoke-endpoint coverage
- /logout: soft-revoke web session + its asset cookies via revokeCascade
  (app sessions and access tokens survive)
- POST /auth/revoke-session: cascade per row kind (web/app/access_token/asset)
- POST /auth/revoke-all-sessions: revoke all web rows for user; optional
  include_apps=true nuclear option; gated by userProtected (cookie-only)
- revokeAccessToken: soft-revoke matching access_token row in addition to
  removing access_token_permissions
- All revokes are UPDATE revoked_at = now(); no DELETE statements remain

PUT-1021 (SDK-1): backend POST /auth/migrate-token
- v1 access_token/app -> mint matching-kind v2 token, idempotent on
  (auth_id, kind, token_uid)
- v1 web/session -> 409 { code: "reauth_required" } (interactive relogin only)
- Same-origin / signed-referer hardening; rate-limited per IP and auth_id
- Gated by auth.allow_v1_tokens; emits puter_token_v2 cookie for app-in-browser

DB migrations: mysql_mig_10, sqlite 0053 (sessions.access_token_uid column)

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* fix(put-1019): reject self-revoke; enrich list-sessions response

- handleRevokeSession refuses uuid === req.actor.session.uid (use /logout
  instead). The cookie that authenticated the call should never be the
  target of a self-revoke — the response can't write fresh auth state
  and the client ends up with an ambiguous identity. revoke-all-sessions
  still has the explicit include_current opt-in for the nuclear case.

- AuthService.listSessions now joins the apps table for kind='app' rows
  (returning { uid, name, title, icon } so the manage-sessions UI can
  render the authorizing app without a second round trip), surfaces
  kind / expires_at / label / last_ip / created_via, and filters out
  asset rows (per-cookie children of web rows, revoked transitively via
  cascade — surfacing them as standalone entries would be confusing).

- Sort order: current session first, then most-recently-active. UI
  relies on this to anchor "you are here" at the top.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* fix(put-1019 put-1021): review nits — origin normalization, cookie fallback, types, migration order

B1: createAccessToken.options.expiresIn widened to string | number.
    The impl (#hardExpiryFromExpiresIn) and existing callers/tests use
    jsonwebtoken-style strings ('1h', '30d'); narrowing to number forced
    unsafe casts at every call site. Cast at the single sign() boundary
    where jsonwebtoken's typed template-literal SignOptions clashes
    with the wider runtime contract.

B2: Inline comment on the DELETE in access_token_permissions. The
    AUTH-5 "no DELETE on revoke" rule scoped to the `sessions` table
    (where the cascade graph + audit trail matter). Permissions rows
    are the grant manifest for an active token — once its session is
    soft-revoked they're dead-weight cache entries. A future audit
    requirement would land as a `revoked_at` column on this table,
    not a behavior change in this PR.

B3: handleMigrateToken now sets the puter_token_v2 cookie (with the
    shared sessionCookieFlags + httpOnly) when the migration result
    is kind='app'. The endpoint is already gated on Origin so the
    caller is by definition in a browser; access tokens deliberately
    skip the cookie since they're programmatic.

B4: #isMigrateTokenOriginAllowed normalizes both incoming origin and
    config.origin / allowlist entries (trim + strip trailing slash +
    lowercase) before equality. A misconfigured `config.origin =
    "https://puter.com/"` would otherwise reject every same-origin
    browser call.

B5: Replaced 4x `this.config.cookie_name!` non-null assertions in
    AuthController with `(this.config.cookie_name ?? 'puter_token')`.
    IConfig is `Partial<IConfigOptional>` so cookie_name is undefined
    at runtime in some deployments / test setups; the fallback matches
    the pattern in userProtected / OIDCController / puterSite.

B6: MySQLDatabaseClient sorts migrations numerically by trailing
    integer instead of lexically. Existing files use unpadded names
    (`mysql_mig_<N>.sql`), so plain `.sort()` ran mysql_mig_10 before
    mysql_mig_2 — a future migration that depended on _2..9 running
    first would break. Non-numeric filenames fall through to
    localeCompare for determinism.

B7: Restored the docstring for SessionStore.getOrCreateApp's
    `opts.auth_id` ("Stable per-user identity (survives re-login);
    carried on every v2 JWT so manage-sessions can group by identity")
    — the previous edit truncated it to a fragment.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* test + feat: backend test coverage for PUT-1019/1021 review fixes + worker session methods

Tests
-----
- compareMigrationFilenames (new) covering B6 numeric-sort: confirms
  mysql_mig_10.sql lands after mysql_mig_9.sql; non-numeric files sort
  after numbered ones; stable for already-ordered input.
- listSessions (AuthService.test.ts): excludes kind="asset" rows;
  enriches with kind/expires_at/last_ip/created_via; joins kind="app"
  rows with the apps table; sorts current first then by last_activity
  desc.
- handleRevokeSession (AuthController.test.ts): refuses self-revoke
  with 400; still allows revoking a sibling session.
- handleMigrateToken (AuthController.test.ts): rejects missing/
  disallowed Origin; tolerates trailing slash and uppercase Origin
  (B4 normalization); returns 409 reauth_required for v1 web tokens;
  does NOT set the cookie for access-token migration; DOES set the
  puter_token_v2 cookie (httpOnly + sessionCookieFlags) for
  app-under-user migration.
- SessionStore tests updated to import APP_WINDOW_SECONDS /
  WEB_WINDOW_SECONDS rather than hardcoded 30/90 day values — the
  windows just got bumped to 1y and the assertions need to follow
  the constant.

Refactor
--------
- MySQLDatabaseClient exports compareMigrationFilenames so the sort
  logic is unit-testable in isolation.

Worker tokens
-------------
- AuthService.createWorkerSessionToken(user, meta?): mints a new
  kind="web" row tagged meta.worker=true, expires_at =
  WORKER_WINDOW_SECONDS, returns { session, token, gui_token }
  with worker: true on each JWT.
- AuthService.createWorkerAppToken(actor, appUid): mints a new
  kind="app" row tagged meta.worker=true, expires_at =
  WORKER_WINDOW_SECONDS, returns an app-under-user JWT with
  worker: true. Note the existing idx_sessions_user_app_active
  unique index will collide with an existing non-worker app
  session for the same (user, app) — future schema work can
  carve workers out of that uniqueness.

SessionStore.js: WEB/APP_WINDOW_SECONDS now 1y;
WORKER_WINDOW_SECONDS = 99y added for the worker path.

Full backend suite: 2172 passed / 16 skipped / 0 failed.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-26 18:49:36 -07:00
Daniel SalazarandClaude Opus 4.7 3ae076b73e feat (put-1022 put-1023 put-1024): puter.js reauth handling + GUI v2 modal + silent v1 migration (#3157)
* feat (put-1022 put-1023 put-1024): puter.js reauth handling + GUI v2 modal + silent v1 migration

PUT-1022 (PJS-1): puter.js handles 401 reauth_required
- Single apiCall wrapper intercepts 401 { code: "reauth_required" }
- Clears local token, emits puter.auth.reauth_required { reason, auth_id }
- Queues in-flight requests, re-issues after re-auth completes
- web/app: opens puter.com login popup forwarding auth_id
- gui: no-op (handled by GUI-1 modal)
- workers: surfaces as structured exception
- All token writes go through setAuthToken() (future-proofed for PJS-2)

PUT-1023 (GUI-1): web GUI reauth modal + v2 token storage
- Detects 401 reauth_required across http + websocket connect paths
- Soft modal preserves URL/window state; auth_id forwarded into login form
- Storage key migrated: auth_token -> auth_token_v2
- Cookie cleared on logout: puter_token (legacy) cleared, backend writes puter_token_v2
- Cross-tab propagation via localStorage storage events
- WebSocket revocation surfaces as same modal (no silent failure)

PUT-1024 (PJS-2): puter.js storage versioning + silent v1->v2 migration
- New storage key puter.auth.token.v2
- On SDK init: prefer v2 key; else legacy v1 -> silent POST /auth/migrate-token (SDK-1)
- On success: store v2, clear v1. On failure: fall back to PJS-1 reauth flow
- URL-param tokens (?puter.auth.token=, ?auth_token=) also run through silent migration
- Logout clears both keys; setAuthToken writes v2 only

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* fix(put-1023): manage-sessions polish — hide self-revoke, fix modal stack, richer rows

Three issues surfaced during local testing of the manage-sessions UI:

1. The session row representing the caller's own cookie had a Revoke
   button that, if used, left the client in an ambiguous identity state
   (backend now rejects it too — see put-1019 backend fix). The button
   is now omitted entirely when session.current=true; /logout remains
   the right path for ending the active session.

2. The confirm-revoke prompt rendered behind the manage-sessions
   window because both share the dominant z-index pool. UIAlert calls
   now pass parent_uuid (the manage-sessions window's data-element_uuid)
   plus stay_on_top, so the prompt stacks above its parent.

3. Each row only showed the bare uuid. Now renders: title (app
   title for app sessions, label / "Browser session" / "Access token"
   otherwise), app icon when applicable, kind / current badges,
   created / last-active / expires (timeago, with absolute on hover),
   and last_ip. App metadata is joined server-side per the backend
   listSessions change.

Adds en.js strings for the new labels (ui_session_*).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* fix(put-1022): tighten reauth replay + iframe postMessage hygiene

driverCall_ replay (G1): on 401 reauth_required, re-enter driverCall_
instead of calling replayXhrAfterReauth. The generic helper wires the
retried XHR through setupXhrEventHandlers which resolves with the
parsed response and silently skips driverCall_'s streaming detection,
usage-limit / email-confirmation handling, settings.transform, and
resp.result unwrapping — i.e. it would change the driver call API
contract on retry. One-shot via settings._reauthReplayed so a
fresh-token rejection bubbles up instead of looping.

responseType drift (G2): driverCall_ sets xhr.responseType from
settings AFTER initXhr (which captured the stale value into
xhr._puterReq). Mirror the mutation onto _puterReq so any replay path
builds the retry with the live config rather than the snapshot.

targetOrigin lockdown (G3): triggerReauth's parent.postMessage now
targets this.defaultGUIOrigin instead of '*'. The payload carries
reauth metadata + auth_id and is only meaningful to the GUI; '*'
would leak the signal to whatever frame happened to be embedding us.

event.source pinning (G4): the reauth wait listener also matches
event.source against globalThis.parent, not just event.origin —
origin alone admits any same-origin frame on the GUI domain.

event name alignment (G5): the SDK now emits and listens for
'puter.auth.reauth_required' (matches the documented name in the
PR / commit description). The old 'auth.reauth_required' key isn't
yet consumed externally so this is a safe rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-26 18:49:17 -07:00
Daniel Salazar 5394ccc45c feat: add verification for v2 auth (#3155) 2026-05-26 15:34:54 -07:00
Daniel Salazar 3649109f40 fix: add back AGENTS.md (#3154) 2026-05-25 16:01:35 -07:00
Daniel Salazar 0ff0ea7743 fix: fs event emissions (#3153) 2026-05-25 14:25:27 -07:00
Daniel Salazar 8be115096f feat (put-1012 put-1014): new tokens version signature and logic (#3152) 2026-05-25 14:19:23 -07:00
Daniel Salazar e66fd2373f feat: start adding support for token expiry and invalidation (#3151)
* feat: new expirable + revokable session

* fix: msql migration
2026-05-25 12:30:20 -07:00
jelveh 0e2cce152d Update PuterAlert.js 2026-05-24 17:03:34 -07:00
Daniel Salazar 101e0bc930 fix: search leaking metadata (#3150) 2026-05-24 16:21:33 -07:00
jelveh ea078250bf Strip non-essential media from docs' markdown 2026-05-24 16:15:24 -07:00
jelveh db79f8e484 Add note: serve Puter.js via HTTP server 2026-05-24 15:48:21 -07:00
Daniel Salazar 6422f2d513 fix: associated app ids as input (#3149) 2026-05-23 13:01:03 -07:00
ProgrammerIn-wonderland c60626f772 Add preamble versioning (#3147)
* Add preamble versioning

* update migrations index
2026-05-23 01:15:58 -04:00
ProgrammerIn-wonderland cafdaf7b50 fix bug with signed url directory listings (#3146) 2026-05-22 18:48:41 -04:00
Daniel Salazar bb0f56d758 fix: bring back puter site config logic (#3145) 2026-05-22 11:15:45 -07:00
NighttandReynaldi Chernando 7438db7a90 Add OpenRouter model release dates (#3144)
* Add OpenRouter model release dates

* simplify implementation

---------

Co-authored-by: Reynaldi Chernando <[email protected]>
2026-05-22 12:58:59 -04:00
Daniel Salazar 948f771838 feat: ai limits tightning and add severity alert (#3142) 2026-05-21 20:46:19 -07:00
Nariman Jelveh 82e34f014d Warn on file:// loads using PuterDialog 2026-05-21 19:15:21 -07:00
Nariman Jelveh 9e4c3f8ba3 Merge branch 'main' of https://github.com/HeyPuter/puter 2026-05-21 14:39:44 -07:00
Nariman JelvehandClaude Opus 4.7 e6acd7386a Bump @heyputer/puter.js to 2.4.2
Record the 2.4.2 release in the repo. The version was published to npm
(via prepublishOnly's `npm version patch`) but the bump was never
committed, leaving package.json stuck at 2.4.1 on GitHub.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-21 14:39:18 -07:00
Daniel Salazar b04e8b046a fix: fixing misc issues around alerting and bugs (#3141)
- decrease ai related alerts and make errors not 500
- decreased bad fs controller checks to be 404s instead of 500s
- force bucket regions for now
- validate webdav perms for locking/unlocking
2026-05-21 14:26:47 -07:00
Nariman Jelveh 3262b984b7 Unify Email/Usage dialogs with Puter dialog style 2026-05-21 14:26:26 -07:00
Nariman Jelveh 71af88c73c Bump @heyputer/puter.js to 2.4.1 2026-05-21 14:06:48 -07:00
Nariman Jelveh 2275f65169 Centralize auth popup handling and consent dialog 2026-05-21 12:06:47 -07:00
ProgrammerIn-wonderland 71b7d6367f fix together provider issues (#3140) 2026-05-21 08:58:48 -04:00
Nariman Jelveh 08369d840b Add cssstyle to docs dependencies (#3139) 2026-05-20 17:41:02 -07:00
Daniel Salazar 94236133b5 fix: event types (#3138)
* fix: agents.md

* fix weird names

* fix: weird names again

* fix: event types

* cleanup types
2026-05-20 16:26:16 -07:00
Daniel Salazar 84b48541bd fix: event types + emit subdomain serve event (#3137)
* fix: agents.md

* fix weird names

* fix: weird names again
2026-05-20 12:47:56 -07:00
Daniel Salazar a33d02f522 fix: agents.md name (#3136) 2026-05-20 12:18:35 -07:00
Reynaldi Chernando f94d4aa7d9 Update gemini 3.5 flash release date (#3135) 2026-05-20 13:25:46 -04:00
Daniel Salazar 89cfb0c634 fix: subdomain htmls (#3134) 2026-05-19 22:04:57 -07:00
ProgrammerIn-wonderland c9096e9eed more validation for signed URLs (#3133) 2026-05-19 19:04:42 -04:00
Daniel Salazar 859ca207c5 feat: new gemini 3.5 flash model (#3131) 2026-05-19 15:16:07 -07:00
Daniel Salazar 58fc122f0d fix: app creation dupped names limit (#3130)
* fix: app creation dupped names limit

* fix: app dupped names
2026-05-19 12:18:59 -07:00
ProgrammerIn-wonderland 0e990da961 import ESM by URL instead of path (#3129) 2026-05-18 19:31:03 -04:00
db8236cc97 update Indonesian section (Indonesian language) (#3117)
* Update id.js

* Update id.js

* Update id.js

* Update id.js

* Update README.id.md

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

* refine indonesia i18n

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: Reynaldi Chernando <[email protected]>
2026-05-18 17:15:01 +07:00
jelveh d731ccf873 Bump puter.js version to 2.3.4 2026-05-17 23:20:41 -07:00
Daniel Salazar 6493d66901 fix: misc write issues with fs + openrouter refresh (#3125)
* feat: refresh openrouter models every 15 min

* fix: if no extensions, skip build step

* fix: misc write issues with fs
2026-05-17 12:34:08 -07:00
Daniel Salazar 9e7f38f473 fix: validate private apps token too (#3124) 2026-05-17 12:28:32 -07:00
Daniel Salazar a568ca0f99 fix: expose upstream ai errors as not 500s (#3123) 2026-05-17 12:01:22 -07:00
Nariman Jelveh 41e7228a9f Update PuterDialog.js 2026-05-16 17:01:40 -07:00
Nariman Jelveh 4568639718 Adjust PuterDialog footer and button spacing 2026-05-16 16:57:35 -07:00
Nariman Jelveh 73ecff0bd7 Tweak PuterDialog spacing and button widths 2026-05-16 16:50:31 -07:00
Nariman Jelveh f2f023880f Remove mobile column-reverse for dialog buttons 2026-05-16 16:42:27 -07:00
Nariman Jelveh f2093e9204 PuterDialog: UI/style tweaks and button reorder 2026-05-16 16:36:53 -07:00
Nariman Jelveh 23497dd371 Add dark mode for puter.js login prompt 2026-05-16 16:04:29 -07:00
Nariman Jelveh 37619fb2a3 Remove embedded background image from PuterDialog 2026-05-16 15:43:15 -07:00
Nariman Jelveh f976686eba Update index.md 2026-05-16 13:12:31 -07:00
ProgrammerIn-wonderland 7af3721543 Make confirming an email unconfirm any other accounts using that email (#3121) 2026-05-16 15:07:38 -04:00
ProgrammerIn-wonderland 93edec0d01 assert normalized (#3119) 2026-05-15 17:01:32 -04:00
Daniel Salazar 54b61f2e24 fix: bad cookie parse test (#3120)
* fix: deepseek alias

* fix: bad cookie parse test
2026-05-15 13:40:43 -07:00
Nariman Jelveh 184ed77493 Use fixed colors for OIDC login divider 2026-05-14 20:26:46 -07:00
Nariman Jelveh 8234b72fc3 Improve login UI: logo, forgot link, OIDC divider 2026-05-14 20:20:21 -07:00
Nariman Jelveh cc9921945e Make auth logo clickable for cover pages 2026-05-14 20:13:33 -07:00
Daniel Salazar ac6f23a41f Update README.md (#3116) 2026-05-14 13:01:34 -07:00
Nariman Jelveh 973d046d33 Remove legacy TabFiles component
Delete the large TabFiles.js file (file browser tab) and update dashboard, styles, helpers, and init logic accordingly. Related changes in UIDashboard.js, dashboard.css, style.css, helpers.js and initgui.js remove or adapt references to the removed component and adjust UI/initialization and styling to account for the file-tab extraction. This reduces duplicate/legacy code and centralizes file browser functionality; review UIDashboard and helper updates to ensure file management features (navigation, upload, context menus, previews) are migrated or re-implemented as needed.
2026-05-14 12:13:48 -07:00
Miika Kuisma dcb50cde8f Merge pull request #3115 from HeyPuter/puter-js-update260514-2
PuterJS - Fix submenu behavior on mobile devices in Menubar web component
2026-05-14 11:45:47 +03:00
Miika Kuisma 08beb55853 PuterJS - Fix submenu behavior on mobile devices in Menubar web component 2026-05-14 11:43:47 +03:00
Miika Kuisma bb0220e163 Merge pull request #3114 from HeyPuter/puter-js-update-260514
Puter JS MenuBar Web Component improvements
2026-05-14 09:14:19 +03:00
Miika Kuisma f3e4c8c6d0 menu item focus tweak 2026-05-14 09:09:40 +03:00
Miika Kuisma 44254671bb - When navigating with keyboard the main level of menubar (file, edit etc) is should also open the menus, now it just highlights the opener
- When hovering main menu items, it must clear hover effects
- Two submenus under each other and diagonal moving
- separator hovering removes highlight but disabled item should do the same
- better way to remove focus
- when mouse leaves context menu highlight should be removed
2026-05-14 08:26:36 +03:00
Daniel Salazar bcc6cc8f00 fix: express proxy chain (#3112) 2026-05-13 18:13:39 -07:00
jelveh 84549a1c31 Add Authorization header to deletion request 2026-05-13 17:21:40 -07:00
Daniel Salazar 0276420213 fix: treat access tokens as non-auth unless opted in (#3111)
* fix: treat access tokens as non-auth unless opted in

* fix: tests
2026-05-13 14:20:15 -07:00
ProgrammerIn-wonderland 6353a08fd5 accept web input in speech2txt (#3110) 2026-05-13 15:53:16 -04:00
Daniel Salazar c265fa308a fix: double rate limits across the board (#3108)
* fix: sqlite auto create path if missing

* fix: double rate limits across the board
2026-05-13 09:30:08 -07:00
Miika Kuisma d3f72bc33a Merge pull request #3105 from HeyPuter/puter-js-menubar-fixes
Puter JS UI Component updates
2026-05-13 11:51:42 +03:00
ProgrammerIn-wonderland 700fc4d27e alibaba provider (#3103)
* Add alibaba provider

* add tests
2026-05-13 03:21:15 -04:00
Miika Kuisma 9c7f30a150 Add theme attribute for each web component, which can be used for forcing dark or light theme (in case the application doesn't have dark mode support it might be odd if just menubar turns dark) 2026-05-13 10:08:59 +03:00
Miika Kuisma 85e45b30f5 fixes https://github.com/HeyPuter/puter/issues/3102 2026-05-13 09:52:21 +03:00
Miika Kuisma 5483e32eab fixes https://github.com/HeyPuter/puter/issues/3101 2026-05-13 09:37:36 +03:00
Miika Kuisma f63c7d8142 - Fixes https://github.com/HeyPuter/puter/issues/3100
- Also fixes similar issues with navigating top level menubar items and submenus
2026-05-13 09:27:44 +03:00
Miika Kuisma 5a2071f852 fix https://github.com/HeyPuter/puter/issues/3099 2026-05-13 09:01:57 +03:00
Miika Kuisma 238ed12e28 - add dark mode support for UI components
- fix https://github.com/HeyPuter/puter/issues/3098
2026-05-13 08:54:23 +03:00
Daniel Salazar d1afe6c3cf fix: puter site redirect for non paid apps (#3104)
* fix: puter site redirect for non paid apps

* add tests
2026-05-12 21:03:33 -07:00
Nariman Jelveh e58dd48e80 Fix link formatting in BUG-BOUNTY.md (#3097) 2026-05-12 17:19:10 -07:00
Daniel Salazar 69f87d4dcd fix: return code (#3096)
* fix: return code

* fix: http error
2026-05-12 16:54:00 -07:00
Daniel Salazar 7b0dd11f7f fix: dev accounts not showing (#3095) 2026-05-12 16:39:42 -07:00
Daniel Salazar 620934fbf4 fix: add user_agent to email signup (#3094) 2026-05-12 15:51:30 -07:00
Daniel Salazar 182fc723f1 expose hasDevAccountAccess at top level (#3093) 2026-05-12 13:56:00 -07:00
Daniel Salazar 5d3c5b6873 fix: whoami (#3092) 2026-05-12 13:44:02 -07:00
slashdevcorpseandCodex f20445bab7 Restrict cross-origin session-cookie auth (#3088)
* Restrict cross-origin cookie auth

Block the auth probe from using ambient session cookies when a browser Origin does not match the request Host. Explicit bearer, body, and x-api-key tokens continue to work for cross-origin SDK calls.

Co-authored-by: Codex <[email protected]>

* Normalize origin checks for cookie auth

Compare normalized origins for browser cookie authentication so default ports and protocol mismatches are handled consistently. Add coverage for default-port and protocol-mismatch cases.

Co-authored-by: Codex <[email protected]>

---------

Co-authored-by: Codex <[email protected]>
2026-05-12 13:40:25 -07:00
Nariman Jelveh 8ad1a58f98 Reorder OIDC Apple and Microsoft buttons 2026-05-12 13:35:18 -07:00
Daniel Salazar 17e475236a fix: mistral ai tests from renames (#3091) 2026-05-12 12:28:32 -07:00
Daniel Salazar b948eaaaa6 chore: update mistralAi providers (#3090) 2026-05-12 12:12:24 -07:00
Nariman Jelveh 9b0c034247 fix: correct xAI TTS pricing to $15.00/1M characters (#3089)
xAI's Voice pricing table lists Text to Speech at $15.00 / 1M characters,
but we were charging $4.20 / 1M characters (420 microcents/char), undercharging
by ~72%. Update the cost constant, listEngines pricing, and test expectation
to 1500 microcents/char.
2026-05-12 11:57:11 -07:00
Miika Kuisma b0dc9c7f1b Merge pull request #3086 from HeyPuter/puter-js-update-260512
PuterJS menubar web component improvements
2026-05-12 12:01:08 +03:00
Miika Kuisma e79abd43e3 PuterJS menubar web component improvements 2026-05-12 12:00:15 +03:00
Miika Kuisma 36c9c478ec Merge pull request #3073 from HeyPuter/puter-js-tests
Puter JS Web Component update
2026-05-12 09:56:58 +03:00
Daniel Salazar 90d01b87ea fix: potential fix for some linux distros (#3085) 2026-05-11 23:28:59 -07:00
Daniel Salazar b0823449bc fix: don't allow dav access control credentials (#3084) 2026-05-11 19:11:02 -07:00
ProgrammerIn-wonderland 760d5d346d add missing GPT 5.4 models (#3083) 2026-05-11 21:34:23 -04:00
Daniel Salazar 4e11d1dd0f fix: updaet deepseek models (#3082) 2026-05-11 18:01:35 -07:00
ProgrammerIn-wonderland 5e8c66142d ai image video fs output (#3079)
* Add puter_output_path

* Fix error reporting in puterjs. Add precheck for puterOutputPath

* add tests

* add tests

* frontend puterjs tests
2026-05-11 20:55:45 -04:00
Daniel Salazar f80016e4e6 feat: rate limit all ai requests (#3081)
* chore: cleanup types for metering

* fix: error responses

* wip: rate limit refactor

* rate-limit for some drivers

* fix: ai driver limits

* tests: rate limiting
2026-05-11 16:18:21 -07:00
Daniel Salazar c8fdbdf8c9 fix: self host mysql (#3080) 2026-05-11 15:36:16 -07:00
ProgrammerIn-wonderland a04267a4e3 Add login with microsoft (#3077) 2026-05-11 15:40:44 -04:00
Daniel Salazar 80a081d62a fix: sql migrations (#3078) 2026-05-11 12:29:56 -07:00
Daniel Salazar bb131c6690 fix: oss icons for new apps (#3076) 2026-05-11 10:52:52 -07:00
Daniel Salazar 4a4a131226 fix: add validation for bad username password input (#3075) 2026-05-11 10:35:12 -07:00
Daniel Salazar 26cff23af4 chore: cleanup types for metering (#3074)
* chore: cleanup types for metering

* fix: error responses
2026-05-11 08:58:13 -07:00
Miika Kuisma 189dae25ef remove hover effect from menubar shortcut labels 2026-05-11 17:58:23 +03:00
Miika Kuisma b2f4a86224 Hide keyboard shortcuts from mobile phone menubar 2026-05-11 11:47:10 +03:00
Miika Kuisma 122811eb7a Puter JS menubar web component now accepts shortcut attribute, improven submenu ux 2026-05-11 11:41:30 +03:00
Miika Kuisma bc98dacf65 Merge branch 'main' into puter-js-tests 2026-05-11 09:55:35 +03:00
Daniel Salazar f00445254d oss: add more apps into oss (#3072) 2026-05-10 22:38:47 -07:00
Daniel Salazar 6686e3a0d7 tests: add tests for SpeechToTextDriver (#3071)
closes #3001
2026-05-10 22:27:35 -07:00
ProgrammerIn-wonderland 5bcb425926 Add tests for Peer, WebDAV, Workers, and WISP. (#3070) 2026-05-10 21:44:30 -04:00
Nariman Jelveh b4e9fa7688 Add dark mode colors to dev console CTA 2026-05-10 17:43:06 -07:00
Daniel Salazar 594cbe03ef tests: big test push with lots of missing areas (#3067)
- Strengthen Broadcast tests
- strengthen oidc tests
- add middleware tests
- add extensions test
- add puter hosting tests
- add Chat Completion Driver tests
2026-05-10 15:06:48 -07:00
Daniel SalazarandClaude Opus 4.7 ec04afe0ad tests: add unit tests for XAITTSProvider (#3060)
Adds offline XAITTSProvider.test.ts covering voice/format selection,
request shape, error paths, and cost reporting. Spies on global fetch
(the provider's egress point) against a real PuterServer + live
MeteringService.

Closes #2998

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:28:04 -07:00
Daniel SalazarandClaude Opus 4.7 539c928920 tests: add unit tests for ElevenLabsTTSProvider (#3066)
Adds offline ElevenLabsTTSProvider.test.ts covering voice/format
selection, request shape, error paths, and cost reporting. Spies on
global fetch (the provider's egress point) against a real PuterServer
+ live MeteringService. The companion integration test stays untouched.

Closes #2999

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:27:55 -07:00
Daniel SalazarandClaude Opus 4.7 a470857d4e tests: add unit tests for OpenAITTSProvider (#3057)
Adds offline OpenAITTSProvider.test.ts covering voice/format selection,
request shape, error paths, and cost reporting. Mocks the OpenAI SDK at
the module boundary against a real PuterServer + live MeteringService.
The companion integration test stays untouched.

Closes #3000

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:27:45 -07:00
Daniel SalazarandClaude Opus 4.7 dea40ca8be tests: add unit tests for TogetherVideoProvider (#3058)
Adds offline TogetherVideoProvider.test.ts covering parameter mapping
(togetherai: prefix stripping, seconds default vs no_extra_params,
width/height/fps/steps, reference_images / frame_images filtering),
polling for queued → in_progress → completed jobs (under fake timers),
failure / cancellation / missing-url error paths, and per-video
metering. Mocks together-ai at the module boundary against a real
PuterServer + live MeteringService.

Closes #2994

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:27:37 -07:00
Daniel SalazarandClaude Opus 4.7 3d593f7cd7 tests: add unit tests for OpenAIVideoProvider (#3059)
Adds offline OpenAIVideoProvider.test.ts covering parameter mapping
(size and seconds snapping to allowed values, input_reference
forwarding), polling for queued/in_progress jobs (under fake timers),
sora-2-pro size tiers (xl/xxl per-second pricing), per-second metering
on default tier, failure handling, and error paths. Mocks the OpenAI
SDK at the module boundary against a real PuterServer + live
MeteringService.

Closes #2993

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:27:30 -07:00
Daniel SalazarandClaude Opus 4.7 1d36811dd6 tests: add unit tests for GeminiTTSProvider (#3061)
Adds offline GeminiTTSProvider.test.ts covering voice/format selection,
request shape (transcript framing + speechConfig), error paths, and
cost reporting (token-priced input + output:audio batching, including
the PCM-to-WAV wrapping path). Mocks @google/genai at the module
boundary against a real PuterServer + live MeteringService.

Closes #2997

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:27:21 -07:00
Daniel SalazarandClaude Opus 4.7 4d53faf5b6 tests: add unit tests for GeminiVideoProvider (#3065)
Adds offline GeminiVideoProvider.test.ts covering parameter mapping
(size → aspectRatio/resolution, isHighRes forcing 8s, reference_images
clamping to 3 with image/lastFrame suppression, data-URL parsing,
negative_prompt), polling the long-running operation (under fake
timers), tier-aware metering (default / :1080p / :4k suffixes),
content-filter handling, and error paths. Mocks @google/genai at the
module boundary against a real PuterServer + live MeteringService.

Closes #2992

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:27:14 -07:00
Daniel SalazarandClaude Opus 4.7 c101fe74ab tests: add unit tests for TTSDriver (#3064)
Adds offline TTSDriver.test.ts covering provider selection/dispatch
(args.provider, legacy driverAlias via Context.driverName, registered
fallback), voice/format param validation, error mapping, and metering
propagation (provider failures must not bill). Mocks each provider's
SDK / fetch boundary against a real PuterServer wired with credentials
for every TTS provider.

Closes #2995

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:27:08 -07:00
Daniel SalazarandClaude Opus 4.7 b4fad80a8c tests: add unit tests for AWSPollyTTSProvider (#3063)
Adds offline AWSPollyTTSProvider.test.ts covering voice/format
selection (caller-supplied, language-derived, default-per-engine
fallback), SSML handling (TextType=ssml routing), request shape to the
AWS SDK SynthesizeSpeechCommand, engine validation, error paths, and
cost reporting. Mocks @aws-sdk/client-polly at the module boundary
against a real PuterServer + live MeteringService.

Closes #2996

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:27:02 -07:00
Daniel SalazarandClaude Opus 4.7 41e0049045 tests: add unit tests for VideoGenerationDriver (#3062)
Adds offline VideoGenerationDriver.test.ts covering provider
selection/dispatch (args.provider, model-id resolution across the
unified catalog, Context.driverName fallback), parameter validation
(seconds + dimension snapping to model.durationSeconds /
model.dimensions, string coercion), error mapping (provider
HttpErrors pass through, SDK errors don't bill), and metering
propagation (driver-level dispatch reaches the provider's
incrementUsage). Mocks each provider's SDK boundary against a real
PuterServer wired with credentials for every video provider.

Closes #2991

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-10 14:26:56 -07:00
Daniel Salazar 4aaa09bb04 tests: more tests for drivers and perm service (#3056) 2026-05-10 13:46:52 -07:00
Daniel Salazar 3f2c45be26 cleanup: authcontroller with testable methods and tests (#3054)
* cleanup: authcontroller with testable methods and tests

* fix: types

Tested this on zenpacket, seems to all be working
2026-05-10 13:24:17 -07:00
jelveh f7202955ef Move TOS blurb and update copy 2026-05-09 19:08:17 -07:00
jelveh 07432b0967 Update UIWindowSignup.js 2026-05-09 19:00:42 -07:00
jelveh 065eeda72a Add 'Sign up with email' option for OIDC 2026-05-09 18:55:18 -07:00
jelveh 65ce9a67ef Include user-agent in OIDC payload 2026-05-09 15:50:40 -07:00
Nariman Jelveh 4996d7f37f Include user_agent in auth request data (#3053) 2026-05-09 09:25:57 -07:00
Daniel Salazar 86adf4ebc0 fix message at end of selfhost script (#3052) 2026-05-08 23:46:54 -07:00
Daniel Salazar 9a4a0ac9f1 tests: add unit tests for XAIImageProvider (#3045)
Mocks the OpenAI SDK at the module boundary, boots a real PuterServer
for the wired MeteringService, and exercises construction (xAI base
URL, missing-key throw), model catalog (default + verbatim list),
test_mode bypass, prompt validation, the credit gate (402 before SDK),
model resolution (alias and unknown-id fallback), and the success
path covering URL/b64_json branches plus per-image metering with the
expected microcent override.

closes #2988
2026-05-08 23:34:39 -07:00
Daniel Salazar 2543179ae7 tests: add unit tests for OpenAiImageProvider with mocked client (#3050)
Mocks the OpenAI SDK at the module boundary, boots a real PuterServer
for the wired MeteringService, and covers the three model families
the provider treats differently. Exercises construction, model catalog
(dall-e-2 default + verbatim list), test_mode bypass, prompt
validation, the credit gate (402 before SDK), DALL-E request shape
(allowedRatio snap, hd-only-on-DALL-E-3, per-size metering, url and
b64_json output), gpt-image-* token-priced metering (input + output
batched line items at the model rates), and the gpt-image-2 size
normalizer (pixel-budget snap to multiples of 16, 3:1 ratio clamp,
3840 edge cap).

closes #2990
2026-05-08 23:33:52 -07:00
Daniel Salazar 07a049c8ac tests: add unit tests for TogetherImageProvider (#3049)
Mocks the together-ai SDK at the module boundary, boots a real
PuterServer for the wired MeteringService, and exercises construction
(missing-key throw), model catalog (default + verbatim list), test_mode
bypass, prompt validation, the credit gate (402 before SDK), all three
pricing branches (per-MP × ratio, per-image, per-tier with resolution
map rewrite), request shape (togetherai: prefix stripping, dimension
snap to multiples of 8 with min 64, optional knob clamping/forwarding,
input_image → image_base64 aliasing), and output handling for both
url/b64_json branches plus the wrapped error message.

closes #2987
2026-05-08 23:33:46 -07:00
Daniel Salazar 0990fc2667 tests: add unit tests for ReplicateImageGenerationProvider (#3048)
Mocks the replicate SDK and util/secureHttp at the module boundary
(real network egress points), boots a real PuterServer for the wired
MeteringService. Covers construction (missing-key throw), model
catalog (flux-schnell default + verbatim list), test_mode bypass,
prompt validation, the credit gate (402 before SDK), per-image
billing (replicateId routing, aspect_ratio gcd formatting,
single-output metering, string vs array output extraction, missing
URL → 400), megapixel billing (run + output_mp batched components),
the param-aliasing/transform/filter machinery (drops disallowed
keys, renames steps→num_inference_steps + response_format→output_format,
injects go_fast=true default for flux-2-dev, appends ' MP' suffix to
flux-2-pro resolution), and the costs_go_fast pricing branch.

closes #2986
2026-05-08 23:33:39 -07:00
Daniel Salazar 98bb203c84 tests: add unit tests for GeminiImageProvider (#3047)
Mocks @google/genai at the module boundary, boots a real PuterServer
for the wired MeteringService, and covers both the generateContent
(Flash) and generateImages (Imagen) code paths. Exercises
construction (missing-key throw), model catalog (default + verbatim
list), test_mode bypass, prompt validation, the credit gate (402
before SDK), Flash request shape (aspect ratio, allowedRatio fallback,
inlineData → base64 data URL extraction), Flash 3-line metering
(input + output:text + output:image with the IMAGE-modality token
count), Imagen routing (generateImages, per-image metering,
empty-response and rai-filtered failure modes).

closes #2989
2026-05-08 23:33:34 -07:00
Daniel Salazar 0e82a0aed6 tests: add unit tests for ImageGenerationDriver (#3046)
Boots a real PuterServer with API keys for every image provider
configured (so the driver indexes them all), drives
server.drivers.aiImage directly, and mocks each provider SDK at the
module boundary so the driver's routing is exercised without real
network egress. Covers 401 without actor, 400 on unknown model,
catalog dedup + sort, list() and getReportedCosts shape, provider
routing (id-based, lowercased lookups, args.provider override,
Context.driverName fallback), ratio normalization (width/height and
aspect_ratio "w:h" forms), and the ai.log.image audit event firing
both before the upstream call and even when it fails.

closes #2984
2026-05-08 23:33:28 -07:00
Daniel Salazar 3dc9d521b4 tests: add unit tests for CloudflareImageProvider (#3051)
Boots a real PuterServer for the wired MeteringService, stubs global
fetch (the provider talks to the Cloudflare REST API directly with no
SDK). Covers construction, model catalog, test_mode bypass, prompt
validation, the credit gate (402 before fetch), request shape (JSON
body, account-scoped /ai/run/<model> endpoint, apiBaseUrl override,
multipart routing for requiresMultipart models, steps clamping
[1,50]), output extraction (binary image/* → base64 data URL, JSON
envelope image with output_format → MIME, http(s) URL passthrough,
success:false 400, non-2xx 400, missing image 400), and per-scheme
cost components (tile-plus-step and flux2-klein-9b-mp split).

closes #2985
2026-05-08 23:33:21 -07:00
Daniel Salazar 4dbbc7c7c9 tests: add unit tests for GroqAIProvider with mocked client (#3042)
Mocks the groq-sdk at the module boundary, boots a real PuterServer
for the wired MeteringService, and exercises construction, model
catalog/resolution, request shape (max_completion_tokens rename, tools
passthrough, content blanking when paired with tool_calls), non-stream
+ streaming output (including Groq's x_groq.usage envelope deviation),
error mapping, and moderation.

closes #2977
2026-05-08 23:06:23 -07:00
Daniel Salazar 31f22bc339 tests: add unit tests for ClaudeProvider with mocked Anthropic SDK (#3038)
Mocks @anthropic-ai/sdk at the module boundary, boots a real
PuterServer for the wired MeteringService/stores/FSService, and
exercises construction (long timeout for Opus 4.7 thinking), model
catalog/resolution, request shape (tool_choice locking, system message
extraction, OpenAI-shape tool_calls → Claude tool_use blocks, tool
role → user tool_result, opus-4.7 temperature drop, adaptive thinking
config, enabled budget thinking + temperature=1 for older Sonnet),
non-stream output (input/output/cache token metering), streaming via
the message_start/content_block_*/message_delta/message_stop event
graph for both text_delta and input_json_delta tool_use, and the
moderation throw.

closes #2958
2026-05-08 23:06:05 -07:00
Daniel Salazar 87f0294f73 tests: add unit tests for OpenAiChatCompletionsProvider (#3036)
Mocks the OpenAI SDK at the module boundary, boots a real PuterServer
for the wired MeteringService/stores/FSService, and exercises
construction, model catalog (responses_api_only filtering), argument
validation (messages-array gate, web_search routing — error when no
sibling, delegation when one is set), request shape (max_completion_
tokens rename, gpt-5 vs non-gpt-5 reasoning_effort/verbosity gating,
stream_options gating), non-stream + streaming output (cached-token
splitting), the moderations.create flagging branch (above and at the
0.8 threshold), and error mapping.

closes #2959
2026-05-08 23:04:55 -07:00
Daniel Salazar df9c55daf9 tests: add unit tests for OpenAiChatResponsesProvider (#3037)
Mocks the OpenAI SDK at the module boundary, boots a real PuterServer
for the wired MeteringService/stores/FSService, and exercises
construction, the responses_api_only-filtered model catalog (with
no_restrictions toggle), argument validation (messages-array gate),
request shape (input messages, max_output_tokens rename, function-tool
unraveling, Responses-only knobs, gpt-5 vs non-gpt-5 reasoning controls),
model resolution, non-stream output (output_text → message.content,
function_call items → tool_calls, empty-response 400 gate), streaming
(response.output_text.delta text events, response.completed usage,
response.output_item.done function_call → tool_use), moderation, and
error mapping.

closes #2960
2026-05-08 23:01:45 -07:00
Daniel Salazar 9246aff4e4 tests: add tests for VoiceChangerDriver (speech2speech) (#3039)
Boots a real PuterServer with an ElevenLabs apiKey configured, drives
server.drivers.aiSpeech2Speech, and stubs global fetch (the real
network egress for ElevenLabs). Covers getReportedCosts mirroring
costs.ts, argument validation (test_mode bypass, missing actor 401,
missing audio 400), the credit gate (402 before fetch), the success
path (POST URL with voice id, default + override voice/model, optional
knobs forwarded via FormData and search params, audio stream return
shape), per-second metering math, and error mapping when ElevenLabs
returns a non-2xx body.

closes #2963
2026-05-08 23:01:36 -07:00
Daniel Salazar 21c37e6d35 tests: add unit tests for DeepSeekProvider with mocked client (#3040)
Mocks the OpenAI SDK at the module boundary, boots a real PuterServer
for the wired MeteringService, and exercises construction, model
catalog/resolution, request shape (max_tokens, tools, stream_options,
DeepSeek's content-blanking and tool-result system-message workarounds),
non-stream + streaming output paths, error mapping, and moderation.

closes #2976
2026-05-08 23:01:28 -07:00
Daniel Salazar cbdad4a65e tests: add unit tests for TogetherAIProvider with mocked client (#3041)
Mocks the together-ai SDK at the module boundary, boots a real
PuterServer for the wired MeteringService, and clears the kv-cached
model list between tests. Covers construction, model catalog (kv
caching, embedding-type filtering, alias flattening, synthetic
model-fallback-test-1), request shape (togetherai: prefix stripping,
max_tokens omission, tools/stream_options gating), model resolution,
non-stream + streaming output (with input/output cost-key remap),
error mapping, and moderation.

closes #2981
2026-05-08 23:01:20 -07:00
Daniel Salazar 91ecf54746 tests: add unit tests for OpenRouterProvider with mocked client (#3043)
Mocks both the OpenAI SDK and axios at the module boundary, boots a
real PuterServer for the wired MeteringService, and clears the
kv-cached model list between tests. Covers construction (default and
custom apiBaseUrl), model catalog (axios fetch + kv caching, openrouter:
prefix on ids, openrouter/auto filtering), the openrouter/auto disallow
gate, request shape (prefix stripping, usage:{include:true}, stream
options, retry-without-max_tokens on context-length errors, rethrow on
unrelated errors), both cost-calculator branches (cost-bearing vs
per-token fallback) for non-stream and streaming, and moderation.

closes #2980
2026-05-08 23:01:12 -07:00
Daniel Salazar 4bcfe6c7f4 tests: add unit tests for GeminiChatProvider with mocked client (#3044)
Mocks the OpenAI SDK at the module boundary (Gemini speaks the
OpenAI-compat dialect at the v1beta/openai endpoint), boots a real
PuterServer for the wired MeteringService, and exercises construction,
model catalog/resolution, request shape (max_completion_tokens rename,
cache_control stripping, stream_options gating), non-stream + streaming
output (cached-token splitting in the metered usage shape), error
mapping, and moderation.

closes #2961
2026-05-08 23:01:08 -07:00
Daniel SalazarandClaude Opus 4.7 3ada6f1569 tests: XAIProvider uses setupTestServer + real metering:[#2982] (#3035)
Drops the local makeMeteringStub in favour of a live PuterServer-wired
MeteringService. The OpenAI SDK is still mocked at the module boundary
(the real network egress point); the mock now also exposes a default
export so the test server can boot every chat provider (some import
the default and read .OpenAI off it). Aligns with AGENTS.md: "Prefer
test server over mocking deps."

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-08 19:21:52 -07:00
Daniel SalazarandClaude Opus 4.7 64402b01db tests: add tests for OCRDriver: [#2964] (#3028)
* tests: add tests for OCRDriver: [#2964]

Adds offline OCRDriver.test.ts covering both providers:

  • test_mode short-circuit; argument validation (missing actor, missing
    source, unknown provider, AWS/Mistral not configured)
  • aws-textract: raw-bytes vs S3Object source selection (regional
    client when fsEntry has a bucket), block normalisation (PAGE/WORD/
    TABLE filtered, LINE/LAYOUT_TITLE → text/textract:* blocks),
    402 on insufficient credits, per-page metering
  • mistral: image vs PDF chunk packaging (image_url with base64 data
    URL vs document_url with documentName), pass-through of pages /
    annotation / image-limit options, markdown → LINE-block
    normalisation with page indices, per-page metering, additional
    annotations metering when bbox/document annotation formats are set
  • default-provider selection (AWS preferred → Mistral fallback →
    500 when neither is configured)
  • getReportedCosts mirrors costs.ts

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* tests: OCRDriver uses setupTestServer + real fs/metering

Drops the manual config/clients/stores/services stub apparatus and
the loadFileInput mock in favour of the live wired driver from
server.drivers.aiOcr. The Textract and Mistral SDKs are still mocked
at the module boundary (the real network egress points); inputs go
through the real loadFileInput against real fs/store wiring (data
URLs for most cases; FSService.write produces a real fsEntry for the
PDF documentName test). Aligns with AGENTS.md: "Prefer test server
over mocking deps."

The S3Object-source/regional-client assertion was dropped because it
isn't deterministic against the in-memory S3 store and the driver's
per-region TextractClient cache leaks across tests. That branch is
better exercised by a real-cloud integration test.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-08 19:15:57 -07:00
Daniel SalazarandClaude Opus 4.7 6226db73d4 tests: add unit tests for MoonshotProvider with mocked client: [#2979] (#3030)
* tests: add unit tests for MoonshotProvider with mocked client: [#2979]

Adds offline MoonshotProvider.test.ts covering construction, model
resolution and aliasing, request shape (hardcoded max_tokens=1000,
stream_options gating, tool_use → tool_calls hoisting), vision-model
image-inlining hook, non-stream and streaming output, error logging
and rethrow, and metering. Existing integration test is left
untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* tests: MoonshotProvider uses setupTestServer + real metering

Drops the local makeMeteringStub in favour of a live PuterServer-wired
MeteringService. The OpenAI SDK is still mocked at the module boundary
(the real network egress point); inlineHttpImageUrls is mocked because
verifying the provider invokes it for vision-capable models is the
unit's concern. Aligns with AGENTS.md: "Prefer test server over
mocking deps."

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-08 19:15:45 -07:00
Daniel SalazarandClaude Opus 4.7 6ab2a2a6cc tests: add unit tests for MistralAiProvider with mocked client: [#2978] (#3032)
* tests: add unit tests for MistralAiProvider with mocked client: [#2978]

Adds offline MistralAiProvider.test.ts covering construction, model
resolution and aliasing, request shape (camelCase maxTokens, tool_calls
→ toolCalls and tool_call_id → toolCallId rewrite, complete-vs-stream
routing), non-stream output with the camelCase usage coercion,
streaming with the chunk.data unwrap and toolCalls deviation, error
mapping, and metering. Existing integration test is left untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* tests: MistralAiProvider uses setupTestServer + real metering

Drops the local makeMeteringStub in favour of a live PuterServer-wired
MeteringService. The Mistral SDK is still mocked at the module
boundary (the real network egress point); everything else runs through
the real wired graph. Aligns with AGENTS.md: "Prefer test server over
mocking deps."

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-08 19:15:34 -07:00
Daniel SalazarandClaude Opus 4.7 ba03fd7965 tests: add unit tests for PuterAIController: [#2965] (#3031)
* tests: add unit tests for PuterAIController: [#2965]

Adds offline PuterAIController.test.ts with stubbed drivers covering:
route registration (paths and per-route auth options), app-actor
gating across all four chat-proxy routes, body validation (messages
must be an array; openaiCompletions prompt must be a string;
openaiResponses provider must be openai-responses), driver delegation
and request shaping (model + messages + provider defaults), response
shaping for OpenAI chat-completion / text-completion / Responses
envelopes and Anthropic message envelope (text + tool_use blocks),
SSE streaming with [DONE] terminator, model-listing endpoints with
hidden-id filtering and 501 when list() is unavailable, and the
HMAC-gated video proxy's input/expiry/secret guards.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* tests: PuterAIController uses setupTestServer + spy on aiChat.complete

Drops the manual driver/controller stub apparatus (makeStubDriver,
makeController, custom dep builders) in favour of the live wired
controller from server.controllers.puterAi. Each test that needs a
canned chat completion result spies on server.drivers.aiChat.complete,
which keeps the unit-of-test focused on the controller (validation,
response shape, SSE streaming) without dragging in chat-driver model
resolution and credit checks. Aligns with AGENTS.md: "Prefer test
server over mocking deps."

The "500 when URL signature secret missing" assertion was dropped —
the default config wires a secret, so the branch is unreachable in
the live test server. Replaced with the equivalent 403-on-invalid-
signature assertion which actually exercises the HMAC gate.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-08 19:15:23 -07:00
Daniel SalazarandClaude Opus 4.7 1c188d6325 tests: add unit tests for ZAIProvider with mocked client: [#2983] (#3029)
* tests: add unit tests for ZAIProvider with mocked client: [#2983]

Adds offline ZAIProvider.test.ts covering construction, model
resolution and aliasing, GLM-specific request shape (custom params,
cache_control stripping, user_id derivation, stream_options gating),
non-stream output with reasoning_content normalisation, streaming
deltas (text and tool_use), error mapping, and metering. Existing
integration test is left untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* tests: ZAIProvider uses setupTestServer + real metering

Drops the local makeMeteringStub in favour of a live PuterServer-wired
MeteringService. The OpenAI SDK is still mocked at the module boundary
(the real network egress point); everything else — config, Context,
metering recording — runs through the real wired graph. Aligns with
AGENTS.md: "Prefer test server over mocking deps."

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-08 19:14:15 -07:00
ProgrammerIn-wonderland 8b1226aa1b OIDC referrer (#3034)
* oidc referrer

* optionally infer referrer from window.openerOrigin

* infer referrer from openerOrigin if there

* add log in signupCb

* remove excess logs

* remove FSEntry.js
2026-05-08 22:05:09 -04:00
Daniel Salazar 2c1d320bba ci: push to dockerhub too (#3033) 2026-05-08 17:36:21 -07:00
Daniel Salazar b6414442dd fix: contributing (#3027) 2026-05-08 16:58:05 -07:00
Daniel Salazar f5470f123f tests: add tests for xaiProvider: [#2982] (#3026) 2026-05-08 16:09:25 -07:00
Nariman Jelveh ea9a44c9ad Implement inline 2FA UI, remove old components (#3025)
* Implement inline 2FA UI, remove old components

* Re-enable login button on window close
2026-05-08 15:59:40 -07:00
jelveh 881ee90e76 Remove stray fullscreen hint from translations 2026-05-08 15:16:47 -07:00
jelveh fbb570fb36 Reapply "Remove toolbar clock feature (#3024)"
This reverts commit e781b60bcb.
2026-05-08 15:15:03 -07:00
jelveh e781b60bcb Revert "Remove toolbar clock feature (#3024)"
This reverts commit 78a071ae54.
2026-05-08 15:11:55 -07:00
Nariman Jelveh 78a071ae54 Remove toolbar clock feature (#3024) 2026-05-08 15:08:15 -07:00
Daniel Salazar 9bcd77c85b chore: add legacy codes back to all errors (#3022) 2026-05-08 13:51:55 -07:00
Daniel Salazar 960bbb6965 doc: code architecture doc + contributing guide for backend (#2953)
* architecture doc

* agents and contributor md guides

* fix: userStore
2026-05-08 13:51:41 -07:00
Nariman Jelveh 46a56e474b README edit (#3012)
* Add 'For Users' and 'For Developers' sections

* Update README.md

* Update README.md

* Update README.md
2026-05-08 13:30:33 -07:00
Reynaldi Chernando 666b60bd29 Use GA version of gemini 3.1 flash lite (#3013)
* Use GA version of gemini 3.1 flash lite

* add model name alias
2026-05-08 13:51:56 -04:00
Daniel Salazar 63f128457e remove driver usage endpoint (#3017) 2026-05-08 10:18:26 -07:00
Daniel Salazar 5e8e9a852d test: add unit tests for ai-chat utils (#3016)
Covers `Messages` (normalize_single_message / normalize_messages /
extract_and_remove_system_messages / extract_text), `FunctionCalling`
(normalize_json_schema / normalize_tools_object /
make_openai_tools / make_claude_tools), and `Streaming`
(AIChatStream / AIChatMessageStream / AIChatTextStream /
AIChatToolUseStream). All three are pure data transforms — Streaming
is exercised against a real `AIChatStream` wired to a buffering
Writable, so no method-level spies are needed.

Closes #2956
2026-05-08 10:17:46 -07:00
Daniel Salazar 3166ad933c test: add unit tests for OpenAIUtil shape normalization (#3015)
Covers the Puter↔OpenAI shape conversion (`process_input_messages`,
`process_input_messages_responses_api`), usage extraction
(`extractMeteredUsage`, `create_usage_calculator`), the streaming
handlers (`create_chat_stream_handler` and the responses-API variant),
and the non-stream `handle_completion_output[_responses_api]` paths
including moderation, missing-content, and per-provider deviations.
Streaming is exercised via a real `AIChatStream` wired to a buffering
Writable so no method-level spies are needed.

Closes #2955
2026-05-08 10:17:42 -07:00
Reynaldi Chernando 7e5f64e04b Fix minor typo for tls cert in self hosting docs (#3014) 2026-05-08 09:23:06 -07:00
jelveh 908c02fd99 fix ASCII art for PUTER.JS 2026-05-08 08:04:21 -07:00
jelveh 38fcc6d6bd Detect fullpage apps early and skip desktop load 2026-05-07 22:17:27 -07:00
Daniel Salazar 16652347c6 test: add tests for HomepageController (#3010)
Covers the early-return guard when the homepage service is unwired,
shell rendering at /, /settings, /dashboard, /action, /@:username,
canonical_url + meta inheritance from gui_params, /app/:name (404 +
shell, embedded app metadata, JSON / object metadata, malformed JSON),
and /show/* launching the explorer with the trimmed path.

Closes #2973
2026-05-07 21:41:16 -07:00
Daniel Salazar 5f28b988ec test: add tests for SystemController (#3009)
Covers /healthcheck (live status, 503 on failure, fallback when service
unavailable), /version (semver parsing, env defaults), /contactUs
(validation, persistence, email best-effort, default support address),
/whoarewe, /lsmod (interface grouping + driverName fallback), and the
prepareShutdown drain-flag flip.

Closes #2971
2026-05-07 21:40:27 -07:00
Daniel Salazar 160631b158 test: add tests for OIDCController (#3008)
Covers the provider listing route, the auth-start redirect (404 / 400 /
500 / 302), all three callback flows (login / signup / revalidate)
including state validation, suspended accounts, unconfirmed-email
linking refusal, redirect_uri origin clamping, and the
revalidate-done landing page. Routes are collected via PuterRouter and
invoked with stubbed services that return prefab data.

Closes #2966
2026-05-07 21:38:47 -07:00
Daniel Salazar 3ab9923f0c fix: ai provider integration tests (#3011)
* fix: ai provider integration tests

* change name for ai test
2026-05-07 21:38:40 -07:00
Daniel Salazar cc799e069f test: add unit tests for fileInput driver utility (#3007)
Covers `loadFileInput` (validation, data-URL decoding, FS-path resolution,
maxBytes enforcement, ACL gating) and `inferFilenameFromUrlOrPath`. Stubs
stores/fsService with prefab data so tests don't require a real server.

Closes #2957
2026-05-07 21:38:27 -07:00
Daniel Salazar 9a7d3bac5f test: add tests for DesktopController (#3006)
Covers /set-desktop-bg (partial updates, null clearing, type validation),
/update-taskbar-items (JSON serialization), /set_layout (layout
allowlist, ownership gate, path/uuid resolution), and /set_sort_by
(sort_by/sort_order allowlists, default ordering). Routes are
collected via PuterRouter and driven with stub stores returning
prefab fsentry rows.

Closes #2970
2026-05-07 21:37:34 -07:00
Daniel Salazar 0a9a4f629d test: add tests for StaticPagesController (#3005)
Covers /robots.txt (bot disallow + sitemap), /sitemap.xml (docs +
approved-listing apps), /unsubscribe (missing/invalid uuid, idempotent
re-runs), and /confirm-email-by-token (token mismatch, already-confirmed
short-circuit, duplicate-email rejection, success path with verified-
group promotion + best-effort side channels). Stub stores hold prefab
user rows; the DB stub returns canned EXISTS / SELECT results.

Closes #2975
2026-05-07 21:36:50 -07:00
Daniel Salazar 32c2c0c1a5 test: add tests for AppController (#3004)
Covers /apps, /apps/nameAvailable, /rao, /apps/:name (single + batch),
/query/app (max-entries cap, marketplace shape, hidden-app gating), and
/app-icon (default fallback, data-URL decoding, MIME allowlist, CDN
redirect). Routes are collected via PuterRouter; AppDriver is injected
through the shared `driversContainers` registry, and stub stores return
prefab app rows.

Closes #2969
2026-05-07 21:35:49 -07:00
Daniel Salazar 508d652194 test: add tests for StaticAssetsController (#3003)
Covers each config-gated branch (client_libs_root, puterjs_root,
gui_assets_root, builtin_apps) using real temp directories so the
existsSync checks see real files instead of mocked module behavior.
Asserts both registration outcomes (which routes appear, on which
subdomains) and the file resolution rules for the puter.js / puter.dev.js
fallback.

Closes #2974
2026-05-07 21:35:17 -07:00
jelveh 471ba94ba2 Update index.js 2026-05-07 20:04:43 -07:00
jelveh 66e24a07d4 Update console banner and messaging 2026-05-07 19:49:01 -07:00
jelveh 5ffac54c86 experimental cute CTA 2026-05-07 19:39:06 -07:00
ProgrammerIn-wonderland c5b12b61d9 Unconditionally send Access-Control-Allow-Private-Network, fix LNA fix in GUI (#2954) 2026-05-07 16:38:04 -07:00
Daniel Salazar 8d5e9ef9cf fix: types for open ai driver (#2950)
* fix: types for open ai driver

* fix: add extra time to tests

* fix: test

* fix: together ai tests

* fix: tests
2026-05-07 14:48:47 -07:00
Daniel Salazar 25fe9a3cdf fix: add coverage reports for changes (#2949)
* tests: ai integraton tests

* fix: add coverage reports for this too
2026-05-07 13:55:09 -07:00
Daniel Salazar 05425d20a7 chore: cleanup types for tests (#2948) 2026-05-07 13:40:58 -07:00
Nariman Jelveh ff10e47d67 Show fullscreen overlay when signup is blocked (#2947) 2026-05-07 11:37:23 -07:00
Daniel Salazar 6c19dfbafd fix: linux build (#2946) 2026-05-07 11:23:10 -07:00
Nariman Jelveh 360cbf48af feat: support code in puter.signup.validate error responses (#2945)
Extensions listening on the `puter.signup.validate` event can now set a
`code` field (in addition to `message`) when blocking signups. The code
is forwarded through HttpError and appears in the JSON error response,
giving clients a stable, machine-readable signal to act on.

Covers both the AuthController (password signup) and OIDCService paths.
Adds tests for the new field.
2026-05-07 10:11:08 -07:00
Daniel Salazar bbe93defe9 tests: add some more driver tests (#2944) 2026-05-07 10:04:39 -07:00
Reynaldi Chernando 5e01c13b31 Fix duplicate textract result (#2943) 2026-05-07 09:15:28 -07:00
Daniel Salazar 4b37f35803 test: tests for fs endpoints (#2942) 2026-05-06 22:55:53 -07:00
Daniel Salazar 775c9c49e2 test: add harness and some examples (#2941)
* test: add harness and some examples

* feat: tests ran on pr
2026-05-06 22:43:22 -07:00
Nariman Jelveh e35260924e Scope .myapps-search to input and tweak UI styles 2026-05-06 17:59:54 -07:00
Nariman Jelveh 90aad8918c Support light/dark sidebar logo 2026-05-06 17:54:37 -07:00
Nariman Jelveh 46974beba1 Replace gradients with flat colors in system buttons 2026-05-06 17:47:45 -07:00
Shruc 5e9dc33be1 expose costs in ai chat response (#2921)
* expose costs

* microcents
2026-05-06 15:59:16 -07:00
Daniel Salazar 1e271f188e fix: bring back old app names functionality and fix build (#2937) 2026-05-06 15:48:25 -07:00
jelveh f333597754 Update IPC.js 2026-05-06 15:40:38 -07:00
jelveh 3b33d16356 Merge branch 'main' of https://github.com/HeyPuter/puter 2026-05-06 15:33:21 -07:00
jelveh 2289d61d3c Update UIPrompt.js 2026-05-06 15:33:13 -07:00
Daniel Salazar 8e02f38bad fix: templates (#2936) 2026-05-06 15:31:41 -07:00
angelinazzz1809 5b65a6bc78 Update UIPrompt.js (#2930)
In the app environment, the prompt input was initialized using `options.value`, so `defaultValue` was not reflected.

This change ensures that `defaultValue` is used when provided, while keeping backward compatibility with `options.value`.
2026-05-06 15:27:28 -07:00
ProgrammerIn-wonderland 872d2c01d4 Add support for log in with Apple (#2935)
* Add experimental login with Apple support

* Fix revalidate URL

* Fix OIDC provider revalidate in whoami as well
2026-05-06 16:47:24 -04:00
jelveh b7f199ddbc Normalize string options to object 2026-05-06 11:59:28 -07:00
jelveh 906c00af97 Support options.defaultColor in color picker 2026-05-06 11:48:47 -07:00
Shruc f00d52f879 per model allowed params on replicate image, normalize ratio (#2898)
* replicate allowed params, normalize ratio

* update docs
2026-05-06 14:16:30 -04:00
Devendra Reddy Pennabadianddevareddy05 7a1a885e89 fix: inline http(s) image URLs for Moonshot vision models (#2929) (#2931)
Co-authored-by: devareddy05 <[email protected]>
2026-05-06 13:53:52 -04:00
Daniel Salazar ff8c275317 chore: package-lock.json (#2934) 2026-05-06 10:52:22 -07:00
Devendra Reddy Pennabadianddevareddy05 b3bf979cac fix: support defaultValue in showColorPicker app env (#2895) (#2932)
Co-authored-by: devareddy05 <[email protected]>
2026-05-06 10:46:32 -07:00
Reynaldi Chernando eb9e316ed5 Update Z.AI vision model id to z-ai/z-ai for consistency (#2928) 2026-05-06 02:41:04 -04:00
Daniel Salazar 224ea5f7f8 fix: extensions (#2926) 2026-05-05 20:55:53 -07:00
Daniel Salazar c1dacab4c2 extension events after boot fixes (#2925) 2026-05-05 17:42:55 -07:00
Daniel Salazar 8d0b8d4905 fix: app errors (#2924) 2026-05-05 17:20:31 -07:00
jelveh e7190f442e Update README.md 2026-05-05 16:49:01 -07:00
Nariman Jelveh 95e1b7d171 New README.md (#2915)
* Update README branding, screenshot, and links

* Update README: rephrase intro and add goals

* Update README.md

* Update README.md

* Rename self-hosting docs and add Windows installer

* Update self-hosting headings and README link

* Update README.md

* Update README.md

* Update README.md
2026-05-05 16:35:07 -07:00
Daniel Salazar f9ac017faf fix: fsEntry and tscofnig (#2923) 2026-05-05 16:18:09 -07:00
Daniel Salazar 4252b7f76f fix: email (#2922) 2026-05-05 15:21:15 -07:00
Daniel Salazar 58a7459e45 fix: broken apps in self hosted (#2920) 2026-05-05 12:45:17 -07:00
ProgrammerIn-wonderland 5dd601a90b add back web input into OCR (#2919) 2026-05-05 14:44:54 -04:00
Daniel Salazar 50fe867e0d fix: fs issues [PUT-846] (#2918)
* fix: fs issues

* windows install script
2026-05-05 10:49:04 -07:00
Daniel Salazar 98bdaf0c42 add email into metering alert (#2917) 2026-05-05 10:18:45 -07:00
Nariman JelvehandClaude Opus 4.6 1f1149e32e Block unconfirmed users from API endpoints server-side (#2916)
Add a default-on email confirmation gate that rejects users with
`requires_email_confirmation && !email_confirmed` on all authenticated
routes, returning 403 with `email_confirmation_required`.

Previously this was only enforced client-side via a GUI modal, meaning
direct API calls could bypass the check entirely.

Essential routes are exempted via `allowUnconfirmed: true`:
  `/whoami`, `/logout`, `/send-confirm-email`, `/confirm-email`,
  `/save_account`, `/get-anticsrf-token`, `/get-gui-token`,
  `/session/sync-cookie`, `/auth/revoke-session`,
  `/user-protected/delete-own-user`

No impact on temp users (`requires_email_confirmation` is false),
self-hosted deployments without email (flag is never set), or
unauthenticated routes (login, signup, password recovery, OIDC).

Co-authored-by: Claude Opus 4.6 <[email protected]>
2026-05-05 10:08:50 -07:00
jelveh 51b81c82bf Update keyboard.js 2026-05-05 06:24:49 -07:00
Daniel Salazar 15201b7a3c fix: nginx missing in self host script (#2911) 2026-05-05 00:42:54 -07:00
Daniel Salazar ad3f0f6c2e fix: handle fs duplicates on write (#2910) 2026-05-05 00:33:55 -07:00
Daniel Salazar 838d6a7178 docker-compose from index (#2909) 2026-05-05 00:22:25 -07:00
Daniel Salazar a5cb484e52 cleanup config (#2908) 2026-05-04 23:12:34 -07:00
jelveh 3a252fb948 Rename moonshot provider key to moonshotai 2026-05-04 21:43:31 -07:00
jelveh 69365cbae4 Standardize Moonshot provider ID to moonshotai 2026-05-04 21:40:38 -07:00
jelveh 2f1b9aad06 Update UIDesktop.js 2026-05-04 21:09:48 -07:00
jelveh 9e8371bde6 Update UIDesktop.js 2026-05-04 21:03:53 -07:00
Daniel Salazar 704fcecbdf fix: selfhosted thumbnails extensions (#2905) 2026-05-04 19:56:10 -07:00
jelveh 785d8b0cc5 Remove recovery warning block from 2FA setup 2026-05-04 19:45:52 -07:00
jelveh eaa68c243a Remove fullscreen button and handlers 2026-05-04 18:56:51 -07:00
Daniel Salazar a24246bfbc selfhosting: p3 cleanup docs + small fixes again (#2904)
* fix: Perms and configs

* rm broken editor for now

* selfhosting cleanup
2026-05-04 18:47:37 -07:00
Daniel SalazarandCopilot 50679e6a01 selfhosting: p2 fixed default configs and guide + some other errors (#2903)
* fix: ollama support

* fix: more self host cleanup

* fix: bad auth

* fix: more session cookie stuff

* allow emailclient

Co-authored-by: Copilot <[email protected]>

* fix: broken migration

* fix: full-stack comment

* fix: hardcoded perms

* new docker build steps

---------

Co-authored-by: Copilot <[email protected]>
2026-05-04 18:14:23 -07:00
jelveh d8cc884f01 Revamp 2FA setup UI with new wizard 2026-05-04 17:49:38 -07:00
jelveh 6a534b8479 Add pending state for 2FA toggle 2026-05-04 17:13:23 -07:00
jelveh 4048dfbaf1 Remove 'Show Desktop' toolbar button 2026-05-04 16:26:59 -07:00
Daniel Salazar 2de8807942 selfhost: fullstack self host p1 (#2902)
* wip: self hosted full setup

* wip: self hoast modes

* more wip self host stuff

* wip: full release

* fix: custom apps

* fix: readme

* full-stack md

* docs update

* fix

* fix: commands

* remove comments

* fix: docs and migs

* mysql mig

* fix: docker changes

* fix: mysql checks

* fix: mysql mig

* fix: docker more

* fix: redis conn issues
2026-05-04 15:58:03 -07:00
Daniel Salazar 8642a5b58c fix: subdomain cache invalidaton (#2901) 2026-05-04 15:17:20 -07:00
Nariman Jelveh 36de2b9aa4 Remove settings UI & service; redirect to dashboard (#2900) 2026-05-04 14:11:56 -07:00
jelveh c6bacca7f6 Open dashboard in new tab from UI clicks 2026-05-04 12:26:39 -07:00
Reynaldi Chernando da0255a805 Update UI docs and types (#2854) 2026-05-04 14:43:24 +07:00
jelveh dee193502f Add txt2speech.listEngines and listVoices docs 2026-05-03 22:12:49 -07:00
jelveh b9458497fb Update package-lock.json 2026-05-03 19:17:44 -07:00
jelveh 52d2c8574f Update build.js 2026-05-03 18:53:37 -07:00
jelveh 3da16e98e3 Produce llms.txt and llms-full.txt outputs for docs 2026-05-03 18:48:29 -07:00
Nariman Jelveh 85336f3c0e Add Moonshot AI (Kimi) chat completion provider (#2893) 2026-05-03 15:15:41 -07:00
jelveh 9720516185 Bump puter.js version to 2.3.2 2026-05-03 11:38:40 -07:00
jelveh 2a0efcff87 Bump puter.js version and update homepage 2026-05-03 11:34:11 -07:00
jelveh f9143a05c2 Add Gemini/xAI TTS and xAI STT examples 2026-05-03 11:24:38 -07:00
Nariman Jelveh bd30cda4a9 Add xAI (Grok) TTS and STT providers and integrate client/docs (#2890)
- Add XAITTSProvider calling POST /v1/tts with 5 voices (eve, ara, rex,
    sal, leo), speech tags, and configurable output format
  - Add XAISpeechToTextDriver calling POST /v1/stt with support for
    diarization, multichannel, text formatting, and xAI's native URL
    param for remote audio files
  - Register both providers in TTSDriver and driver index using existing
    xAI API key from config
  - Update puter.js client to route provider:'xai' for both txt2speech
    and speech2txt, including listVoices/listEngines
  - Add TypeScript types for new STT options (provider, format, diarize,
    multichannel, etc.)
  - Update txt2speech.md and speech2txt.md with xAI options and examples
  - Add playground examples for both TTS and STT

  Cost metering:
    TTS: 420 microcents/char ($4.20/1M chars)
    STT: 2778 microcents/sec ($0.10/hr)
2026-05-03 11:00:31 -07:00
Nariman Jelveh 33d5c0737e Add Gemini TTS provider and integrate client/docs (#2889)
Introduce a new Gemini TTS provider and wire it through the driver, client, docs, and examples. Adds src/backend/drivers/ai-tts/providers/gemini/GeminiTTSProvider.ts (Google GenAI client usage, PCM->WAV wrapping, metering, model/voice validation) and a costs table in providers/gemini/costs.ts. Registers the provider in TTSDriver, exposes the alias gemini-tts, and prefers it in provider selection. Updates puter-js client to recognize "gemini" provider/engine and route driver calls to gemini-tts. Documentation updated with Gemini options, a usage example, and a playground example HTML file.
2026-05-03 09:33:50 -07:00
Daniel Salazar cb27fd1f98 Revert "Revert "remove exports (#2885)" (#2887)" (#2888)
This reverts commit 14cde26291.
2026-05-02 10:20:01 -07:00
Nariman Jelveh d4ef956660 Remove RecoveryCodeEntryView and inline UI 2026-05-02 10:14:27 -07:00
Nariman Jelveh 789c62ef71 Remove RecoveryCodesView and inline in 2FA setup 2026-05-02 09:55:12 -07:00
Nariman Jelveh b2a70a6a38 Remove ConfirmationsView and inline checkboxes 2026-05-02 09:52:09 -07:00
Nariman Jelveh dd9607b54e Remove StepHeading component and inline headings 2026-05-02 09:46:44 -07:00
Daniel Salazar 14cde26291 Revert "remove exports (#2885)" (#2887)
This reverts commit 4e94cb07be.
2026-05-02 09:41:42 -07:00
jelveh 388577a799 Update style.css 2026-05-02 08:30:27 -07:00
jelveh d0310ac211 Add Upgrade/Manage Plan button to Usage tab 2026-05-02 08:28:46 -07:00
jelveh 99babf3879 Remove System Information window 2026-05-02 08:03:05 -07:00
jelveh ffae2a1d0a Remove PuterDialog and ExportRegistrantService 2026-05-02 07:58:12 -07:00
jelveh ce69bc14a8 Remove groups manager UI extension 2026-05-02 07:53:38 -07:00
Daniel Salazar 4e94cb07be remove exports (#2885) 2026-05-01 23:52:52 -07:00
jelveh 4395c8bea5 Handle OIDC popup flow: skip session list 2026-05-01 23:49:35 -07:00
Daniel SalazarandCopilot 5b35a5db69 errors for fs (#2884)
* remove bloated tests and

* errors for fs

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
2026-05-01 23:24:05 -07:00
jelveh c1ff8a3a9a Enable email confirmation code and style modal 2026-05-01 23:23:31 -07:00
jelveh c352dfe284 Send confirmation code and hide close button 2026-05-01 23:06:18 -07:00
jelveh 9f2ec29586 Prefer app upgrade prompt on storage errors 2026-05-01 21:07:49 -07:00
jelveh 63be2308d3 Show upgrade dialog on storage limit errors 2026-05-01 20:24:09 -07:00
jelveh e509f8ab46 Remove obsolete theme.css and its reference 2026-05-01 19:54:38 -07:00
jelveh b481753526 Remove obsolete GUI docs and .idx files 2026-05-01 19:46:20 -07:00
Daniel Salazar 1796fdb37b fix: misc fs issues (#2883)
* fix: deps

* fix: FS issues
2026-05-01 18:54:10 -07:00
jelveh 25f02378cb Update StaticPagesController.ts 2026-05-01 17:29:07 -07:00
jelveh e95e2f5187 Use full HTML template for static pages 2026-05-01 17:18:06 -07:00
jelveh 3f8365ad7e Add logout handler and disable modal dragging 2026-05-01 17:00:22 -07:00
ProgrammerIn-wonderland 8bd0d7c8c9 invalidate subdomains on delete (#2882) 2026-05-01 16:49:22 -07:00
Daniel SalazarandCopilot 2c261fc6c0 fix: extensions (#2881)
Co-authored-by: Copilot <[email protected]>
2026-05-01 16:36:15 -07:00
jelveh 0ffb7d3d1e Remove Amplify config; add nwsapi dep 2026-05-01 15:39:50 -07:00
jelveh 1305bf16e8 Add Amplify build config and update docs deps 2026-05-01 15:27:46 -07:00
jelveh d9cbdf3394 Update package.json 2026-05-01 15:00:40 -07:00
Daniel SalazarandCopilot a3b11de1a2 fix: better error codes + unlimited local credit (#2880)
* fix: better error codes

Co-authored-by: Copilot <[email protected]>

* fix: add in local unlimited metering again

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
2026-05-01 14:43:13 -07:00
Nariman Jelveh cf3f943177 Delete license_header.txt (#2879) 2026-05-01 14:06:55 -07:00
Nariman Jelveh 267f464232 Add AGPL license headers to source files (#2877) 2026-05-01 13:50:42 -07:00
ProgrammerIn-wonderland b70aabdeae zai --> z-ai (#2878) 2026-05-01 13:39:25 -07:00
ProgrammerIn-wonderland 8936f79716 Ns/return better together video error (#2876)
* Return better together video error
2026-05-01 13:13:08 -07:00
ProgrammerIn-wonderland 968452a45e Add grok 4.3 (#2875) 2026-05-01 13:00:02 -07:00
jelveh 05c4b40497 Merge branch 'main' of https://github.com/HeyPuter/puter 2026-05-01 12:59:08 -07:00
Nariman Jelveh 60ea48dbaa Remove gross legacy tools and docs (#2873) 2026-05-01 12:58:36 -07:00
Nariman Jelveh 284ca86b7c Remove gross retarded legacy tools and docs (#2873)
* Remove gross retarded legacy tools and docs

* Remove tools scripts

* nuke the bs

* Remove contributor/self-hosting docs, update license

* Remove src/useapi package and update configs

* remove source map files

* Remove wiki submodule

* ok not everything is retarded, for example this one (v86) is cool but has to go for now

* Remove puter-wisp module

* Remove install.md

* Remove twisp submodule

* Remove epoxy-tls submodule

Remove the epoxy-tls submodule and its configuration: delete the gitlink at submodules/epoxy-tls and remove the corresponding entry from .gitmodules.
2026-05-01 12:32:41 -07:00
ProgrammerIn-wonderland 7cd762afa2 Add z.ai chat completions (#2874) 2026-05-01 12:23:23 -07:00
Daniel Salazar 1b39bd2a4a fix: app autocreation (#2872) 2026-05-01 09:03:42 -07:00
Daniel Salazar e8fbb88102 puter models list fix (#2869) 2026-05-01 01:41:56 -07:00
Daniel SalazarandCopilot f6e1f90225 fix: dbConfigs and ai routes (#2868)
* fix: db configs

Co-authored-by: Copilot <[email protected]>

* fix: ai routes

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
2026-04-30 23:56:18 -07:00
Daniel SalazarandCopilot 0e53edafa3 fix: send right error codes (#2867)
Co-authored-by: Copilot <[email protected]>
2026-04-30 21:42:48 -07:00
Daniel Salazar 4a10124574 fix: oidc and chat validation events (#2866) 2026-04-30 21:05:07 -07:00
Nariman Jelveh d2555835c7 Remove email confirmation requirement in feedback 2026-04-30 21:04:39 -07:00
Nariman Jelveh 73d26e02b3 Only reset URL/title for owning windows 2026-04-30 20:54:17 -07:00
Daniel Salazar 48a85998ad fix: sync ips for validation (#2865)
* oidc email validate

* fix: sync ips for validation
2026-04-30 17:53:25 -07:00
Daniel Salazar 1a6b02999b fix: more clean ip (#2864) 2026-04-30 16:45:54 -07:00
Daniel Salazar 976f1de806 fix: event (#2863) 2026-04-30 16:37:27 -07:00
Daniel Salazar 1546e0e02f fix: auth checks (#2862)
* rename validate email

* fix: authService
2026-04-30 16:32:22 -07:00
ProgrammerIn-wonderland ce18b914b4 backport devwatcher (#2861) 2026-04-30 16:23:34 -07:00
Nariman Jelveh a54d6ceee5 Merge branch 'main' of https://github.com/HeyPuter/puter 2026-04-30 16:03:51 -07:00
Nariman Jelveh a32ac4e672 Add dynamic usage-bar colors and refine layout 2026-04-30 16:03:39 -07:00
Daniel SalazarandCopilot 93ed2068de fix: fail unauthed sessions nicely (#2860)
Co-authored-by: Copilot <[email protected]>
2026-04-30 16:01:23 -07:00
Daniel SalazarandCopilot 6b8152d3bc fix: cleanup some errors (#2859)
Co-authored-by: Copilot <[email protected]>
2026-04-30 15:10:19 -07:00
Daniel SalazarandCopilot eaa3d8c83c fix: no default gemini image quality (#2858)
Co-authored-by: Copilot <[email protected]>
2026-04-30 15:03:53 -07:00
Nariman Jelveh d772b557a0 Replace 2FA buttons with toggle switch 2026-04-30 15:01:06 -07:00
Nariman Jelveh 867d967b37 Use 'Current' badge and style active plan pill 2026-04-30 14:13:10 -07:00
Daniel SalazarandCopilot 56eef339a8 fix: ai driver errors (#2857)
Co-authored-by: Copilot <[email protected]>
2026-04-30 13:41:41 -07:00
Nariman Jelveh 15b93abe04 Set body overflow to hidden in dashboard CSS 2026-04-30 13:02:55 -07:00
Daniel Salazar 208abda841 fix: bad ai endpoint (#2856) 2026-04-30 12:38:39 -07:00
d4d78ac7db rework: change backend and backend extensions to use simpler code structure and patterns (#2815)
* fix:  dynamodb health checks and client recreation (#2789)

* wip: no nanoServices groundwork

* feat: data clients in new shape

* wip: auth and perms in new system

* more wip

* middlewaters mainly done

* wip: fsv2 in new layout

* old fs v2 migration

* driver system

* driver and old fs fixes

* ai drivers wip

* stream support

* metering in ai chat driver

* wip: new auth

* rate limit and auth routes

* captcha and anti csrf

* fix: types

* auth store

* app logic

* wip most other dricvers

* fs

* mostly kill all legacy stuff

* fs finish

* fix: redis usage

* ai controller

* driver cleanup

* socket io in v2

* broadcast and crudq stuff

* subdomains

* notifcations and shares

* fix bad syntaxes

* auth wip

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* extensions

* extension setup

* more routes

* sql migrations and default services

* home router

* tier 7

* everything else

* everything else

* remaining missing bits

* server health

* logs

* cleanup

* deps

* cleanup 2

* more cleanup 2

* boot

* fix launch

* config fix

* move file

* fix: tsconfig things

* fix: extension loading

* launching

* fix: drivers

* fix: others

* fix: icons

* fix: file uploads

* fs fixes

* fix: fs api

* fix: dev-center

* config

* add back telemetry

* lint stuff

* husky hooks

* fix: fs oss

* fix: config migration

* config migration

* migrate scripts + replicate

* runner

* fix: merge defafult config

* fix: default region

* fix: api domain

* fix paths in readfile

* fix fs entry default s3

* NS: Remove Referral && Entri Service

* dep cleanups

* fix: static assets

* fix: kv and perms

* fix: driver registrations

* fix: home mapping

* fix: rao

* adding back 500 alarm

* fix: build paths

* fix: fs and kv shapes

* fix: kv shape

* more kv coercing and ai chat matching format as prior

* fix:  private app gates

* private app caches

* fix: whole bunch of legacy shape issues

* update template jsonc

* fix caching partial oidc and fs signed paths

* more oidc fixes

* fix: wip

* fix: private apps

* admin route fixes

* fix: last few things hopefully

* claude uploads

* fix security for app only routes

* fix kv system namespace

* stuff

* fix: app and kv and suggested apps

* fix:open item

* fix: FS operations

* fix: default app icons

* add back token-read and WSL support

* metering fixes

* fix: fsEntry

* perm scanners and implicators

* proper download endpoint

* fix: download

* fix anti csrft on v2

* fix file extensions, app icons

* fold in v1 fixes from origin/main into v2 equivalents

Re-applies the v1 fixes that landed on origin/main into their v2
counterparts since the v1 files were deleted on DS/wip during the v2
migration. v1 commits referenced below.

- SQLBatcher: flush immediately when queue hits maxBatchSize instead
  of racing the timer (v1 12f48238).
- RedisClient: drop maxRetriesPerRequest from 2 to 1 to shrink failure
  window (v1 b6776ab4).
- ChatCompletionDriver: default minimumCredits to 1 when unset/zero so
  zero-cost precheck doesn't auto-pass (v1 36bd6073).
- OpenAiImageProvider: add gpt-image-2 support — open-ended size rules,
  token-based cost estimator, arbitrary-size normalizer, isGpt prefix
  broadened to gpt-image- (v1 f14f1bf4). models.ts auto-merged via
  rename detection.
- AppStore: bump row cache TTL from 5m to 24h (v1 6b3196ed).

Not ported: v1 app-object Redis cache (bdfa12b5/b886dde3) — v2's
#toClient recomputes filetype_associations/created_from_origin per
read; adding a second cache layer is a larger change for a follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* remoe anti-csrf from auth routes that had not used them

* more icon fixes

* fix worker functionality

* fix: app and subdomain es

Co-authored-by: Copilot <[email protected]>

* fix PUT-761

* fix: PUT-748

* fix: rename fsService

* Add security back to WorkerDriver

* Migrate worker from fsEntry to fs. Fix cache issue

* remove ability to create symlinks

* strict webdav acl

* require auth for wisp

* chore: service renames

* Add metering back to puter peer api

* fix: PUT-760 PUT-749

* fix: PUT-746

* fix: peer cost

Co-authored-by: Copilot <[email protected]>

* fix: 771

* change order of peer controller

* fix: create appdata folder for app on get auth token

* fix: align delete site and list sites

* delete: putility

* fix subdomains

* Add support for tilde in subdomains, fix subdomain update

* cleanup PeerController.ts and fix billing oversight (#2844)

* fix: PUT-786

* fix: bugs

* fix: issues with multiple subdomain queries, or permission checks

* fix: harden response shapes to not contain uneeded fields

* fix: move state to redis

* fix: missing kv methods + better sec

Co-authored-by: Copilot <[email protected]>

* fix: subdomainStore limit

* fix: missing path resolution

Co-authored-by: Copilot <[email protected]>

* fs fixes

* fix: undef error

* fix fs + cleanup

* fix: npm audit fixes

* heal path entries where missing

Co-authored-by: Copilot <[email protected]>

* fix: caching

Co-authored-by: Copilot <[email protected]>

* fix: cache inconsistencies

Co-authored-by: Copilot <[email protected]>

* fix: app driver metadata

Co-authored-by: Copilot <[email protected]>

* remove extraneous comma

* fix: associated app icons

* fix: bad tool call

* Add validation to WorkerDriver#getFilePaths

* misc fs and auth issues

Co-authored-by: Copilot <[email protected]>

* fix: oidc errors

Co-authored-by: Copilot <[email protected]>

* fix: PUT-797

* fix: legacy appdata_app

Co-authored-by: Copilot <[email protected]>

* fix: add alert logs

Co-authored-by: Copilot <[email protected]>

* fix: error handling

* Disable sharecontroller

* fix: remove private user identifier for ai

* fix: private app fixes

* Add backback signup_server

* fix: completionId size

Co-authored-by: Copilot <[email protected]>

* fix: revalidate path for oidc

* fix: revalidate path for oidc

* fix: email validation

Co-authored-by: Copilot <[email protected]>

* fix: user create query

* fix: middleware extensions

Co-authored-by: Copilot <[email protected]>

* use x-forwarded-for for req ip forwarded

* fix: missing last_activity ts

* feat: add cache broadcast to subdomains

* fix: update config typing

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: ProgrammerIn-wonderland <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Nariman Jelveh <[email protected]>
Co-authored-by: velzie <[email protected]>
2026-04-30 12:13:43 -07:00
Miika Kuisma b593eb5630 Tests update 2026-04-29 16:45:09 +03:00
Daniel Salazar 255dde9e96 fix: oidc errors again (#2853) 2026-04-28 16:20:20 -07:00
Daniel Salazar 3b6ae2d06b fix: oidc errors (#2852) 2026-04-28 16:15:34 -07:00
Nariman Jelveh 4c096f2af7 Remove file sharing UI and related code (#2817)
RIP
.
.
.
for now!
2026-04-28 15:59:19 -07:00
jelveh 23f45532d6 Avoid stacking panels/invisible windows; reset URL 2026-04-28 12:49:51 -07:00
jelveh ce39c7f734 Sync profile picture updates across UI 2026-04-28 11:57:27 -07:00
jelveh 5e667e21f8 Refactor dashboard bento colors & welcome styles 2026-04-28 11:06:30 -07:00
jelveh 8297cbec99 Use i18n welcome text and adjust UI styles 2026-04-28 10:41:01 -07:00
jelveh a781776b38 Introduce bento theme and remove gradients 2026-04-28 10:05:58 -07:00
jelveh cc21a33a31 Make copy-token window responsive and closable 2026-04-28 09:57:14 -07:00
Nariman Jelveh d344d9e5a5 Remove dashboard window style override 2026-04-27 19:24:47 -07:00
Miika Kuisma aa5e398e8b Fixing issues with mobile contextMenu (#2848)
* Fixing issues with mobile contextMenu in puter env app where user couldn't tap on menu items and there was checkmark in wrong place

* context menu mobile version - handle submenus

* context menu mobile icon placement tweak
2026-04-27 12:18:04 -07:00
Nariman Jelveh 66fa5fd569 Flush cache after username change 2026-04-27 12:13:26 -07:00
Reynaldi Chernando acf84a7929 Update docs setMenubar (#2845) 2026-04-27 12:51:08 +07:00
jelveh d55c3c1637 Add UI playground examples and update docs 2026-04-26 19:23:12 -07:00
Miika Kuisma 5e9a0f0a70 Puter JS - Web Components for UI API (#2808)
* Web Components for Puter SDK UI API

* Rest of the components

* component docs

* Revert file and directory picker changes

* style matching with puter.com and support for custom styling

* item divider style tweak

* Puter JS - Web Components tweaking

* alert default image fix

* context menu mobile style fix

* Fix app iframe height when app is in fullpage mode and has puter-js menubar

* menubar web component tweak

* Action sheet behavior for contextmenu on mobile also in env app

* replace alert icons

* context menu and menubar keyboard navigation, submenu mouse navigation improvements

* package-lock

* Improve submenu mouse hovering
2026-04-26 19:02:11 -07:00
jelveh 3e21479f17 Add content background var; remove card shadow 2026-04-25 19:01:33 -07:00
jelveh bb08d5b53b Adjust myapps grid to 4 columns 2026-04-25 13:55:41 -07:00
jelveh 0905095bc8 Enforce 5-column myapps grid with responsive wrap 2026-04-25 13:51:29 -07:00
jelveh 8188d2b58b Increase myapps-grid gap to 30px 2026-04-25 13:43:59 -07:00
jelveh 67f14db74a Use anchor tags for dashboard sidebar items 2026-04-25 11:25:03 -07:00
jelveh 7f1c13183b Disable dialog dragging in TabHome 2026-04-25 11:19:13 -07:00
jelveh 2e2f85fea5 Hide horizontal overflow; move apps CSS 2026-04-25 11:17:47 -07:00
jelveh 50a0073fc8 Revert "Hide horizontal overflow in apps tab"
This reverts commit d3c4aa1cfd.
2026-04-25 11:13:36 -07:00
jelveh d3c4aa1cfd Hide horizontal overflow in apps tab 2026-04-25 11:12:52 -07:00
jelveh 0b3de54a37 Use pushState for dashboard tab hashes 2026-04-25 10:45:09 -07:00
shashank shubham 53291fb8c6 chore: improve validation error messages for clarity (#2833) 2026-04-25 08:33:56 -07:00
jelveh e8c566bf3d Update TabAccount.js 2026-04-25 08:14:01 -07:00
jelveh 5174f90ed4 Hide dialog header in account tab 2026-04-25 08:11:12 -07:00
jelveh 700854e3f5 Refactor auth token card markup, disable drag 2026-04-25 08:09:17 -07:00
jelveh 2449c3f385 Scroll dashboard content to top on change 2026-04-24 23:18:50 -07:00
jelveh 205a8bbbc5 Replace lodash _.replace and _.pullAll usage 2026-04-24 22:36:31 -07:00
jelveh 0ae3f4dcfa Remove lodash from GUI vendor lib lists 2026-04-24 22:23:17 -07:00
jelveh ba31f8e533 Make app search header sticky with blur 2026-04-24 22:16:41 -07:00
Nariman Jelveh 1cfdf79e05 GUI cleanup (#2842)
* Remove deprecated helper functions from helpers.js

* Remove Croppie library and references

* Remove bundled jQuery UI assets

* Remove vendored socket.io client files

* Remove lodash and replace with native utils

Replace common lodash usages with native JS alternatives: _.isEmpty -> null/empty checks via Object.keys, _.size -> Object.keys(...).length, _.uniqBy -> Map-based dedupe/spread. Remove bundled lodash file and its About/license entry. Updated files include UIDashboard.js, UIDesktop.js, UIWindow.js, launch_app.js, update_title_based_on_uploads.js, initgui.js, UITabAbout.js, and static-assets.js to reduce dependency and bundle size.
2026-04-24 21:52:47 -07:00
ProgrammerIn-wonderland cb7e5a475e add gpt 5.5-pro (#2843) 2026-04-25 00:34:29 -04:00
jelveh e1d082fc48 Remove getUsage helper in GUI 2026-04-24 21:16:12 -07:00
ProgrammerIn-wonderland 4e0ff1992c add gpt 5.5 (#2841) 2026-04-25 00:13:12 -04:00
Nariman Jelveh 231bfbd8a9 Replace QRCodeView with UIQRCode helper 2026-04-24 17:57:45 -07:00
Nariman Jelveh 1aa51b7371 Remove puter audio assets 2026-04-24 17:42:52 -07:00
Nariman Jelveh 57f296a6cb Remove def(UIAlert, 'ui.window.UIAlert') 2026-04-24 14:44:04 -07:00
Nariman Jelveh b78565a6fa Remove commented putility import 2026-04-24 14:07:03 -07:00
Nariman Jelveh 1b4308c624 Comment out putility import and def 2026-04-24 13:59:24 -07:00
Daniel Salazar 36bd60731b fix: AIChatService.ts (#2836) 2026-04-23 20:20:16 -07:00
Daniel Salazar 968831c729 Revert "fix: anticsrf to store tokens in redis (#2834)" (#2835)
This reverts commit 1a6009c00c.
2026-04-23 19:12:47 -07:00
Daniel Salazar 1a6009c00c fix: anticsrf to store tokens in redis (#2834)
* fix

* fix: anticsrf to store tokens in redis
2026-04-23 18:46:43 -07:00
Nariman Jelveh f22206fe5a Import and register putility in async init 2026-04-23 16:52:07 -07:00
Nariman Jelveh 4a37e44d38 remove putility dependence from GUI 2026-04-23 15:27:04 -07:00
Daniel Salazar b6776ab47e shrink redis failure (#2831) 2026-04-22 13:27:34 -07:00
Shruc f14f1bf49e add gpt image 2 (#2829)
* add gpt image 2

* index cost key

* docs + default low
2026-04-22 14:00:18 -04:00
jelveh b886dde3d6 Await DB write and add UID cache key
Make the DB update in AppES awaitable so the write completes before proceeding (avoids race conditions). Also add invalidation of the Redis object key for the app UID in AppInformationService to ensure cached entries keyed by uid are cleared after updates.
2026-04-21 19:32:19 -07:00
jelveh bdfa12b566 Add app object Redis cache and use in AppES 2026-04-21 18:52:17 -07:00
jelveh 6b3196ed0c Increase cached app TTL to 24 hours. Cause, where is your sense of adventure? 2026-04-21 17:41:35 -07:00
jelveh e9a80d0834 Update dashboard.css 2026-04-20 16:17:25 -07:00
Daniel Salazar 7f9873edd2 fix: cdn cache invalidation (#2826) 2026-04-20 11:59:35 -07:00
jelveh 4de724c996 Update UIItem.js 2026-04-19 21:41:24 -07:00
jelveh 7bb27ffbb4 fix #2803 2026-04-19 21:40:14 -07:00
jelveh 4c578acce2 Update dashboard.css 2026-04-19 20:14:22 -07:00
jelveh a3fd275783 Remove Beta badge from dashboard sidebar 2026-04-19 19:56:29 -07:00
jelveh 2a1f0da04b Add bottom padding to .myapps-container 2026-04-19 19:50:43 -07:00
jelveh 1260bd506b Pass parent to context menu; keep icon scaled 2026-04-19 19:44:41 -07:00
jelveh d66b70e05e Request 128px icons and prefer iconUrl 2026-04-19 19:34:00 -07:00
Shruc eaad07e002 adjust and refactor together models costs (#2811)
* adjust, refactor together costs

* aliases follow rule
2026-04-17 17:28:26 -04:00
jelveh f6c1991068 Remove referral UI and related logic 2026-04-17 12:25:29 -07:00
jelveh 4adf7b41b9 Remove Drivers docs and sidebar entry 2026-04-17 12:05:10 -07:00
jelveh b1a5c41028 Remove custom domain UI and Entri integration 2026-04-17 11:58:04 -07:00
Subhrabaran P b34f69512e fix: update knowledge date for Claude Opus 4.7 model (#2816) 2026-04-17 10:44:09 +07:00
Trevin Chow 4130fc4104 fix: close start menu popover on repeated click (#2784)
When the Start button is clicked while the popover is already open,
close it instead of doing nothing. This fixes the toggle behavior
on Android Chrome where the menu stays open on repeated taps.

The `.popover-launcher` removal triggers the UIPopover remove event
handler which automatically cleans up the `has-open-popover` class.

Fixes #1681
2026-04-16 09:44:00 -07:00
Shruc 6f54edbc76 add opus 4.7, adjust thinking (#2813) 2026-04-16 09:23:06 -07:00
Miika Kuismaandjelveh 2790879fc1 Dashboard Update (#2788)
* Consistent header with files

* custom order with draggable app icons

* mobile style tweak

* Drag apps to sidebar

* uninstall

* Add desktop switch button to home tab
Drag sidebar apps order

* Display app storage use in Usage tab

* Add context menu options to apps: open in new tab, open in window

* Sidebar apps section with taskbar/dock behavior

* add close button to sidebar app item

* prevent dashboard files items from being selected when dragging

* File contextmenu shows filename
Keep dashboard URL when opening items

* Fixed issue with mobile selecting

* sidebar toggling

* sidebar tooltips

* done!

* Files tab statusbar width fix

* Consistent header with files

* custom order with draggable app icons

* mobile style tweak

* Drag apps to sidebar

* uninstall

* Add desktop switch button to home tab
Drag sidebar apps order

* Display app storage use in Usage tab

* Add context menu options to apps: open in new tab, open in window

* Sidebar apps section with taskbar/dock behavior

* add close button to sidebar app item

* prevent dashboard files items from being selected when dragging

* File contextmenu shows filename
Keep dashboard URL when opening items

* Fixed issue with mobile selecting

* sidebar toggling

* sidebar tooltips

* done!

* Files tab statusbar width fix

* Remove desktop switch button from Home tab

* App uninstall fix

* mobile style tweaks for dashboard sidebar

* Usage tab header fixes

* style tweaks

* Disable Uninstall for certain system apps

* Use app title in uninstall modal

* Remove delete-data option from uninstall modal

* Update dashboard.css

* Update TabApps.js

---------

Co-authored-by: jelveh <[email protected]>
2026-04-15 19:46:25 -07:00
ProgrammerIn-wonderland 90a4970a03 remove glitched submodule (#2810) 2026-04-15 18:05:49 -04:00
Shruc 6f4ec8bd1e add replicate image provider (#2806)
* add replicate image

* docs replicate

* pkg lock

* maybe fix ci
2026-04-15 17:47:57 -04:00
ProgrammerIn-wonderland e863240ad9 Add WSL support for signed uploads (#2809) 2026-04-15 13:36:09 -04:00
ProgrammerIn-wonderland 389e11f33b Ns/simplify 2 (#2790)
* Remove mostly unused TechnicalError and featureflag. Fold Group into GroupService.

* move modutil to util

* remove unused public/assets

* Remove anomaly service, fold logic into groups

* remove unused modules

* Remove AnomalyService import from tests

* remove shutdownservice

* remove unused filetracker service

* [will break prod] remove Puter AI Module, inline to coremodue

* MariaDB compatibility
2026-04-15 12:03:51 -04:00
Shruc edf1736292 add gemini image models in .chat (#2771)
* add gemini image models in .chat

* update docs for gemini image .chat

* actually snake case

* fix multi-turn thoughtsignature
2026-04-10 17:33:52 -04:00
Daniel Salazar 7f7c01956e fix: origin app Ids (#2801) 2026-04-10 13:47:53 -07:00
Daniel Salazar 9c38c43f82 fix: app canonization for puter.com apps (#2800) 2026-04-10 13:00:59 -07:00
Shruc 18e909f1a3 fix veo video with proxy link (#2799) 2026-04-10 13:37:34 -04:00
Daniel Salazar 14f2da3206 cleanup: batcher to batch more appropriately (#2794) 2026-04-10 00:27:14 -07:00
Daniel Salazar 1cfe69faa1 fix: redis max retries and fail fast timeouts (#2793) 2026-04-09 14:08:35 -07:00
Reynaldi Chernando 72430a1939 Minor fix docs and update puter resource unit (#2792)
* Minor fix docs and update puter resource unit

* change to 1 cent -> 1 mio microcents
2026-04-09 15:13:49 +07:00
jelveh 481a1a1d90 Prevent redirect to /action/login after login 2026-04-08 18:47:04 -07:00
Daniel Salazar 9a6c414f9d fix: dynamodb health checks and client recreation (#2789) 2026-04-08 15:47:09 -07:00
Shruc 32be3a0a88 better error reports for chat fallbacks (#2783) 2026-04-08 17:47:02 -04:00
HemantandReynaldi Chernando 69bb7e4a38 Close #2718 : added querying with prefix patterns example and documentation (#2778)
* feat: add querying with prefix patterns example and documentation

* refine

---------

Co-authored-by: Reynaldi Chernando <[email protected]>
2026-04-08 13:49:00 +07:00
Subhrabaran P 8cc29724b2 fix: add showSpinner and hideSpinner to docs sidebar (#2779)
The pages existed but were missing from the sidebar navigation,
causing 404s when clicking their links under /UI/#additional-ui-elements.
2026-04-08 13:36:46 +07:00
jelveh adc28ac7e8 Delete structure.md 2026-04-07 17:06:56 -07:00
jelveh d03303a3b1 Delete batch-and-symlinks.md 2026-04-07 17:03:13 -07:00
jelveh 94c4fcb242 Remove backend drawio diagram 2026-04-07 16:58:49 -07:00
jelveh 9bbb3af0bb Remove filesystem API spec doc 2026-04-07 16:56:42 -07:00
Shruc dbf87753c5 derive aliases from puterid (#2777) 2026-04-07 19:55:59 -04:00
Daniel Salazar f21dd4160c delete command service files? (#2782) 2026-04-07 14:45:37 -07:00
Daniel Salazar 4f468dcda8 chore: delete remaining "command" service (#2781) 2026-04-07 14:00:32 -07:00
ProgrammerIn-wonderland c1da2c3aaa Fix openrouter enumeration (#2780) 2026-04-07 16:54:42 -04:00
jelveh 81a0d721eb Remove alpha notice from Peer docs
Remove the alpha notice banner and spacer from Peer documentation pages (Peer.md, connect.md, ensureTurnRelays.md, connect.md, serve.md). This updates the docs to stop advertising the Peer API as alpha and cleans up redundant banner markup.
2026-04-06 15:09:39 -07:00
Daniel Salazar 2368b2bc8f fix: missing subdomains and worker flags in readdir (#2772) 2026-04-06 11:08:03 -07:00
ProgrammerIn-wonderland 649db33763 Ns/simplify 1 (#2764)
* Rid devconsole

* lots of removals

* more commandservice
2026-04-06 14:05:48 -04:00
jelveh b0bd8a12a7 Replace inline Google SVG with WebP image 2026-04-05 17:34:51 -07:00
jelveh f867519a1c Use root URL as default signup redirect
When reload_on_success is set, use '/' as the fallback redirect URL instead of the current page (window.location.href). This prevents redirecting back to the signup page after a successful signup while preserving any explicit options.redirect_url value.
2026-04-05 16:59:25 -07:00
jelveh 2dd991700e Make esbuild platform dep optional; update lock
Move @esbuild/linux-x64 from dependencies to optionalDependencies in src/docs/package.json so the platform-specific esbuild binary is treated as optional. Update package-lock.json to reflect that change (adds platform-specific @esbuild entries, marks various packages as peer/optional, bumps @emnapi/wasi-threads to 1.2.1 and removes obsolete @emnapi core/runtime entries).
2026-04-05 15:32:06 -07:00
jelveh 67d941a7af Add @esbuild/linux-x64 dependency 2026-04-05 11:56:06 -07:00
jelveh 5840348dec Move esbuild entry in docs package.json to dependencies rather than devdependencies 2026-04-05 11:48:09 -07:00
Daniel Salazar 5319940156 fix: app id shortcut batch (#2768) 2026-04-04 17:21:58 -04:00
jelveh b99d7be510 Preserve existing disable_temp_users value
Do not unconditionally overwrite window.disable_temp_users during GUI init. If window.disable_temp_users is already set, keep it; otherwise fall back to options.disable_temp_users (or false). Added a clarifying comment explaining the behavior.
2026-04-03 11:48:09 -07:00
Daniel Salazar 95cbbc5de6 feat: enable singed uploads on oss and fix broken migration (#2765)
* fix: proper shutdown

* feat: enable singed uploads on oss

* fix: s3 in oss

* fix: thumbnails in oss
2026-04-03 07:29:22 -07:00
Trevin ChowandReynaldi Chernando e23df0b589 Add kv.list() pagination playground example (#2760)
* Add kv.list() pagination playground example

Create an interactive playground example for kv.list() that
demonstrates cursor-based pagination with sample data (6 items,
2 per page). Also wire the pagination docs example to the playground
by changing the code fence from plain html to html;kv-list.

Fixes #2755

* fix: address review feedback - restore code example, create new pagination playground

* minor refactor

---------

Co-authored-by: Reynaldi Chernando <[email protected]>
2026-04-03 17:23:42 +07:00
Shruc 5e6aff63c4 add google video native provider, imagen models (#2759)
* update gemini .chat models, add imagen, add gemini veo

* add models

* update documentation

* add veo 3.1 lite, 1080p pricing
2026-04-02 16:03:38 -04:00
Daniel Salazar 0505a5df1f fix: no shutdown outside of puter servers (#2762) 2026-04-02 11:36:49 -07:00
Daniel Salazar 99d96edd9c feat: s3 fs in oss (#2761)
* feat: s3 fs in oss

* feat: new endpoints in OSS

* fix: name of fs extension

* perf: signed uploads

* fix: await socket events to align fs events

* fix: default bucket names

* fix: backend tests

* fix: deps

* fix: order
2026-04-02 11:20:59 -07:00
Reynaldi Chernando ed7c18bffa Update prompt caching example (#2758) 2026-04-01 18:18:31 +07:00
Raffy LeongandReynaldi Chernando 0e83af7e2b docs(kv): add sorting section with examples to list() API reference (#2739)
* docs(kv): add sorting section with examples to list() API reference

Added sorting section with examples for lexicographic order and zero-padding for numbers.

* docs(kv): add sorting note to list() description

* feat(playground): add kv-list-sort example

* feat(playground): add kv-list-padding.html

* add Sorting examples to kv list on doc/src/examples.js

* docs(kv): add sorting examples to list.md examples section

* Refine copy and code example

* remove extra newline

---------

Co-authored-by: Reynaldi Chernando <[email protected]>
2026-03-31 18:04:12 +07:00
Daniel Salazar 83985318fb feat: thumbnail event for gui (#2754) 2026-03-30 18:29:01 -07:00
Daniel Salazar ef243c9854 feat: signed upload urls (#2753)
* feat: signed upload urls

* fix: make sessions write to dynamo

* fix: add logs for failures
2026-03-30 16:27:29 -07:00
John Costa 00b34d7329 Add context field to OpenRouter, MistralAI, and OpenAI models (#2653)
* Map context_length for OpenRouter models

OpenRouter's API returns context_length for each model, but it was not
being mapped to the context field in the model list response. This
caused the context window size to be missing for all OpenRouter models.

Closes #2347

* Add context field to MistralAI and OpenAI model definitions

Addresses reviewer feedback to support the context field in more
providers. All 9 providers now consistently expose context window
sizes via the context field.

- MistralAI: 16 models (context matches known window sizes)
- OpenAI: 27 models (128k for GPT series, 200k for o-series,
  1M+ for GPT-4.1 and GPT-5.4)
2026-03-30 16:46:08 -04:00
ProgrammerIn-wonderland ad85026a8c Getting rid of Endpoint (#2732)
* Get rid of Endpoint and ExpectationService

* Migrate user-protected endpoints to eggspress

* eggspress better typedefs
2026-03-30 16:23:41 -04:00
Shruc cea40b3e78 support video inputs in .chat (#2740)
* support video inputs in .chat

* update docs for .chat
2026-03-30 10:26:34 -04:00
Reynaldi Chernando 7fc9a97269 Fix prompt caching example broken character (#2750) 2026-03-30 11:21:41 +07:00
Leandre Chamberland-DozoisandReynaldi Chernando 55bdd50de4 docs: update code examples from gpt-5-nano to gpt-5.4-nano (#2738)
* docs: update code examples from gpt-5-nano to gpt-5.4-nano (#2716)

* Remove unrelated changes

* remove more unrelated

---------

Co-authored-by: Reynaldi Chernando <[email protected]>
2026-03-30 10:56:57 +07:00
jelveh 6c1019a1a8 Add recover-password window, its action URL, and styles 2026-03-29 17:18:50 -07:00
jelveh add9b1e774 Update dashboard.css 2026-03-29 13:59:08 -07:00
jelveh 54dbd57811 Update dashboard.css 2026-03-29 13:45:26 -07:00
jelveh 7c092d1a22 Increase dashboard grid gap and icon size 2026-03-29 13:36:29 -07:00
Daniel Salazar 107521e45a fix: remove recommended app caching in favour of stronger caching at app fetch layer (#2748) 2026-03-29 13:07:00 -07:00
jelveh 8c47f12aa5 Update recommended apps list 2026-03-29 10:51:34 -07:00
jelveh bf3bbab468 Increase dashboard sidebar width to 250px
Bump the .dashboard-sidebar width from 200px to 250px to provide more room for navigation items and improve layout spacing. min-width, background, and border styles remain unchanged.
2026-03-29 10:26:13 -07:00
jelveh 0a6dd0c611 Add prependHeadContent and optional autofocus flags 2026-03-29 10:10:09 -07:00
jelveh bfea3bbce9 Pass req and relocate extension body content 2026-03-28 15:19:34 -07:00
jelveh 1ab73d8726 Make dashboard card headers clickable 2026-03-28 13:02:43 -07:00
jelveh 813e78843a Remove debug log; update captcha modal styles 2026-03-28 11:04:10 -07:00
jelveh 8a33c663cd Always enable cover_page in window options 2026-03-27 19:01:30 -07:00
Daniel Salazar 3e0829474e fix: incrememnt ddb sharding to 10k (#2744) 2026-03-27 18:59:48 -07:00
Nariman JelvehandDaniel Salazar 92ac05e4f2 Display logged-in banner on homepage (#2742)
* Display logged-in banner on homepage

Pass auth_user from the router into PuterHomepageService and show a logged-in banner when a user is present. _default.js now includes auth_user in the svc_puterHomepage.send call. PuterHomepageService.send signature was updated to accept auth_user; the service stores logged_in_user, forwards it to generate_puter_page_html, and injects a styled "Logged in as <username>" banner into the top of the page when available. This surfaces the current user on the GUI and exposes logged_in_user to page generation and addons.

* Include request path and logged in user in GUI params; remove banner

* fix: bad auth_user check for homepage

---------

Co-authored-by: Daniel Salazar <[email protected]>
2026-03-27 18:48:05 -07:00
Daniel Salazar 677bc29658 fix: remove dynamo health check for now (#2743) 2026-03-27 18:34:40 -07:00
Daniel Salazar b3656fdaa1 fix: handle closing server nicer on shutdown signal (#2741)
* fix: handle closing server nicer on shutdown signal

* fix: bad check
2026-03-27 17:24:33 -07:00
jelveh 89a67a4a6f Update dashboard.css 2026-03-27 15:23:13 -07:00
jelveh 266b3ae3d4 Add sidebar separator to dashboard 2026-03-27 14:14:10 -07:00
Reynaldi ChernandoandCopilot 14ed1b6db8 Add claude cache control docs (#2737)
* Add claude cache control docs

* refine

* Update src/docs/src/AI/chat.md

Co-authored-by: Copilot <[email protected]>

* Update src/docs/src/AI/chat.md

Co-authored-by: Copilot <[email protected]>

* Update src/docs/src/examples.js

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
2026-03-27 17:35:53 +07:00
jelveh c20ef3c98c Remove dynamic dashboard CSS injection 2026-03-26 21:14:19 -07:00
jelveh 829295228a Adjust dashboard grid spacing and tile size 2026-03-26 21:03:31 -07:00
jelveh ae33f6f42b Remove static myapps loading placeholder 2026-03-26 20:40:47 -07:00
jelveh e1e2cad31d Hide apps grid until icons finish loading
Prevent a visual flash by hiding the apps grid until all app icons have loaded. Adds revealWhenLoaded($container) which removes the myapps-grid-loading class when images finish (or error). TabApps now caches the .myapps-container lookup and calls revealWhenLoaded after initial render, after search results, and after loading installed apps. CSS changes: add .myapps-grid-loading (opacity:0 + transition) and a small padding-right tweak for the search input.
2026-03-26 20:29:35 -07:00
velzie 017308a741 Small tweaks to puter.peer (#2734)
* small tweaks to puter.peer

* document connections field
2026-03-26 19:34:07 -04:00
jelveh 5c913fc359 Add search bar to My Apps tab 2026-03-26 16:31:08 -07:00
jelveh 5eddd0949f Merge launch & installed apps, tweak app tile CSS
Fetch both the installedApps and get-launch-apps endpoints in parallel, normalize recommended + recent launch items, and merge them with installed apps while deduplicating by name (launch items are prioritized). Update this._apps and render the combined list. Also simplify the app tile icon styling by removing border-radius and box-shadow for a flatter icon appearance. Error handling for failed loads is preserved.
2026-03-26 15:43:09 -07:00
Daniel Salazar b857fc8743 fix: return fallback icons if no icon present (#2731) 2026-03-25 16:50:34 -07:00
jelveh 02bc010989 Include dashboard.css in GUI assets
Add /css/dashboard.css to the GUI asset lists so dashboard styles are served and bundled. Updated src/gui/puter-gui.json and src/gui/src/static-assets.js to include the new stylesheet.
2026-03-25 16:31:14 -07:00
jelveh 94395cd539 Add Apps tab UI and installed apps fetch 2026-03-25 16:10:10 -07:00
Daniel Salazar ec766eecc2 fix: syntax issue with sql (#2730) 2026-03-25 15:05:43 -07:00
Daniel Salazar 187b14dacd fix: remove last opened (#2729) 2026-03-25 14:43:06 -07:00
Shruc 2da083e7c1 use case sensitive together video model ids (#2728) 2026-03-25 16:21:16 -04:00
Daniel Salazar 393f4b70d4 fix: remove flaky event loop check (#2727) 2026-03-25 11:59:18 -07:00
Daniel Salazar d292c1e4e4 fix: healtcheck improvements (#2726)
* fix: decrease logs

* fix: healtcheck improvements
2026-03-25 11:10:58 -07:00
Daniel Salazar 08fa2d7a41 fix: installed apps api (#2725) 2026-03-25 09:41:53 -07:00
Daniel Salazar 25b9911651 fix: extension type import (#2723) 2026-03-24 23:32:12 -07:00
Daniel Salazar 9511323cdf fix: init installed apps controller (#2722) 2026-03-24 23:17:46 -07:00
Daniel Salazar 68985e9f47 fix: letter case issue (#2721)
* fix: letter case

* fix: name
2026-03-24 22:46:19 -07:00
Daniel Salazar 0a3ac7b035 Revert "feat: root level kv accesses, and installed app listing + server health check fix (#2719)" (#2720)
This reverts commit e75ccb0a41.
2026-03-24 20:28:36 -07:00
Daniel Salazar e75ccb0a41 feat: root level kv accesses, and installed app listing + server health check fix (#2719)
* feat: root level kv accesses, and installed app listing

* fix: revert server health check
2026-03-24 19:18:42 -07:00
ProgrammerIn-wonderland c52fa351a5 WIP openai responses support (#2715) 2026-03-24 06:12:13 -04:00
iamsrishanthandProgrammerIn-wonderland 4fe255347a feat: Add Anthropic Messages API compatibility layer (#2704)
* feat: add Anthropic Messages API compatibility layer

Add a new endpoint at /puterai/anthropic/v1/messages that implements the
Anthropic Messages API wire format, allowing clients using the Anthropic
SDK to point directly at Puter.

- New router translates between Anthropic format and Puter's internal
  svcAiChat.complete() pipeline
- Supports non-streaming, SSE streaming (proper Anthropic event sequence),
  and tool use round-trips
- Translates system field, tool definitions (input_schema -> parameters),
  and tool_result content blocks
- Integration tests covering non-streaming, streaming, tool use,
  Anthropic SDK compatibility, and system parameter

Closes #2554

* Fix authentication middleware

---------

Co-authored-by: ProgrammerIn-wonderland <[email protected]>
2026-03-24 06:08:25 -04:00
Shruc bed84cad76 refactor ai video gen (#2711)
* refactor ai video generation into one service

* use old duration and dimension keys

* use costoverride billing like the others
2026-03-24 05:42:52 -04:00
Daniel Salazar 76f5a26d84 fix: issue with tokens not being received by puter app (#2713) 2026-03-23 17:37:54 -07:00
Daniel Salazar 931507e74e chore: remove dead code and docs (#2705)
* chore: remove dead code and docs

* fix: healthService caching
2026-03-22 23:58:02 -07:00
Dailin 3451bab09f docs: add ai-voice-changer playground example (#2708) 2026-03-23 13:23:30 +07:00
jelveh 34bf2799b6 Fix App Store links and remove install stub 2026-03-22 16:29:13 -07:00
jelveh c99e23d737 change default credits 2026-03-21 20:17:01 -07:00
jelveh a4be42a390 Exclude login/signup from temp user creation
Prevent creating temporary users on unauthenticated first visits when the current action is the login or signup flow. The initgui else-if was expanded to include explicit checks for action !== 'login' and action !== 'signup', avoiding interference with explicit authentication routes and Turnstile challenges.
2026-03-21 19:15:01 -07:00
jelveh f89079f907 Fix login form layout and window options 2026-03-21 18:39:38 -07:00
jelveh c434af7c71 Center auth forms; add Google icon; set cover_page 2026-03-21 18:14:46 -07:00
jelveh e6726a1a94 Add peer icon and update sidebar reference 2026-03-21 11:42:42 -07:00
Vusal Huseynov c31d665fff docs: fix 404 in CreateAppResult documentation due to case sensitivity (#2702) 2026-03-20 22:15:09 +07:00
Nandini Kashyap f9511e42a4 Fix double slash in canonical URL (#2690) 2026-03-20 21:21:09 +07:00
Daniel Salazar b526c08ffe fix: ws double messages (#2700) 2026-03-19 20:56:04 -07:00
Nariman Jelveh ba1f9669d2 Peer docs (#2699) 2026-03-19 20:11:18 -07:00
jelveh 4a4a92ccaf Simplify plan name localization in dashboard
Use a single expression to derive the plan key (offering.name or 'free') and pass it to i18n when updating .bento-plan-name. This removes the previous ternary and duplicates, allowing dynamic offering names to be localized consistently.
2026-03-19 18:28:42 -07:00
jelveh a6b18ff844 Add basic/professional/business/free translations
Add missing English translations for plan tiers (free, basic, professional, business) to src/gui/src/i18n/translations/en.js and perform a minor formatting cleanup near billing messages to ensure keys are available for UI display.
2026-03-19 18:23:25 -07:00
jelveh 815b0424a3 Use subscription.offering.name for plan display
Update TabHome to read the plan name from subscription.offering.name instead of subscription.plan_name. This adapts to the updated subscription object shape while keeping the fallback to the 'pro' translation and the 'free' label when no active subscription exists.
2026-03-19 17:16:50 -07:00
Charlie Tonneslan 3628cf4909 fix(gui): account for iOS safe area inset on taskbar/dock (#2682)
The taskbar uses position:fixed with bottom:5px, which gets hidden
behind the iOS Safari bottom toolbar on devices with home indicators.

Use env(safe-area-inset-bottom) to push the dock above the safe area.
The viewport-fit=cover meta tag is already present in initgui.js.

Fixes #2517
2026-03-19 16:56:43 -07:00
Daniel Salazar ee3a3e79f2 chore: decrease uneeded logging (#2697) 2026-03-19 15:28:24 -07:00
Daniel Salazar b87f4988e1 fix: socket io sockets (#2696) 2026-03-19 14:32:20 -07:00
Daniel Salazar c2e77d3503 fix: broadcast pubsub + cleanup old code (#2695) 2026-03-19 13:13:01 -07:00
Daniel Salazar 5e2c7e0495 Revert "fix: tighten cors logic for socket io (#2688)" (#2694)
This reverts commit a94620de49.
2026-03-19 12:24:14 -07:00
Daniel Salazar a94620de49 fix: tighten cors logic for socket io (#2688)
* fix: tighten up cors for socket io

* fix: allow socket io to push to rooms in redis

* fix: various socket io issues to improve cross session stability
2026-03-19 12:08:24 -07:00
ProgrammerIn-wonderland ff126d12b1 turn metering support (#2689) 2026-03-18 23:26:00 -07:00
Daniel Salazar bb733e72c8 fix: websocket credentials (#2687)
* fix: websocket syncing on redis

* fix: websocket syncing on redis
2026-03-18 16:09:05 -07:00
ProgrammerIn-wonderland 4fb0977105 Change turn customIdentifier fully (#2685) 2026-03-18 00:36:55 -07:00
ProgrammerIn-wonderland 6a8be1505d change turn customIdentifier seperator (#2684) 2026-03-17 23:59:57 -07:00
ProgrammerIn-wonderland 817c30739b change capitalization of inviteCode (#2683) 2026-03-17 23:40:38 -07:00
velzieandProgrammerIn-wonderland 8d38e07e98 feat: add puter.peer to sdk, create PeerService in backend (#2664)
* feat: add puter.peer to sdk, create PeerService in backend

* cloudflare turn, typedefs, fallback ice, bugfixes

* minr tweak

* restrict peerservice to api.puter.com, make customIndentifier more detailed

---------

Co-authored-by: ProgrammerIn-wonderland <[email protected]>
2026-03-17 23:08:44 -07:00
Daniel Salazar 9347644f81 feat: redis pubsub for multiple connected clients in broadcast service and webhook fixes (#2681)
* debug: logs for webhook broadcasts

* fix: broadcast webhook calls

* fix: add error log with body

* fix: fetch form

* feat: redis pubsub for multiple connected clients in broadcast service

* test: add pubsub tests
2026-03-17 18:45:23 -07:00
Eric Dubé ef93ed4572 fix: change_email and user-protected endpoints (#2680)
Update check for suspended users on change_emeail and user-protected
endpoints. The `change_email` endpoint isn't using the auth middleware
because it infers from the token that was passed - this means it needs
explicit logic to check suspended users; before suspended users were
able to complete a a flow for changing their username if they already
started it before being suspended.

Update user-protected endpoints and configurable_auth so endpoints that
make sensitive account changes do not rely on cached information about a
user.
2026-03-17 14:54:29 -07:00
jelveh 2bafa03a74 Add 'Add to Desktop' English translation
Introduce a new i18n key `add_to_desktop` with value 'Add to Desktop' to the English translations file. This provides a label for UI actions that add items or apps to the desktop.
2026-03-17 13:52:26 -07:00
Daniel Salazar e6d125e17c feat: notify prod (#2679) 2026-03-17 13:48:57 -07:00
Daniel Salazar 6352bc6a9a fix: webhook message to peer (#2678) 2026-03-17 13:33:01 -07:00
Daniel Salazar 8118582496 fix: add console log to webhook for debugging (#2677) 2026-03-17 13:07:06 -07:00
Eric Dubé 814791872f Manual package updates, npm audit --force, etc (#2669)
* chore: upgrade git-date (used for release notes generator)

* chore: update vitest, vitest plugins, and svgo

* chore: run `npm audit fix`

* chore: run `npm audit --force`

* meta: empty commit to run git tests

* fix: tests gone because of a... syntax error?

I question GitHub's judgement of handling a syntax error in the file
that defines tests to run on PRs by pretending everything is fine and
passing all PRs. That to me seems like the worst possible way to handle
that. I think they should have done it not like that.
2026-03-17 12:43:17 -07:00
ProgrammerIn-wonderland c7a481118f add reasoning to claude models (#2676) 2026-03-17 12:26:53 -07:00
Miika Kuisma 53f8d67679 Merge pull request #2675 from HeyPuter/darkmode-fix
darkmode fix
2026-03-17 09:50:34 +02:00
Miika Kuisma c325eed3af darkmode fix 2026-03-17 09:49:26 +02:00
Daniel Salazar c96bb9acb1 feat: add hook on merge for deployments (#2673)
* fix: tests

* fix: add logging for webhook events for debug
2026-03-16 22:34:39 -07:00
Daniel Salazar 573d5a3ff4 fix: limit referralCodeService (#2670)
* fix: limit referralCodeService

* fix: ECMAP unlink
2026-03-16 17:33:28 -07:00
ProgrammerIn-wonderland 55dd9841c5 add x-puter-no-auth option to puter.workers.exec (#2668) 2026-03-16 10:59:11 -07:00
Eric Dubé 0af0eb127e chore: update package-lock.json (#2667) 2026-03-16 08:56:34 -07:00
ProgrammerIn-wonderland ce9c8341d1 Interpret mpga as mp3 for OpenAI transcriptions (#2666) 2026-03-15 22:01:26 -07:00
Shruc b3787ac0e0 fix flash image quality level (#2665) 2026-03-15 16:47:14 -07:00
Shruc 89904ca563 fix coercion service not selecting correct conversion path (#2660) 2026-03-13 17:37:21 -07:00
Nariman Jelveh e28a5b01d8 Use ClickHouse for app open stats (#2662)
When a global ClickHouse client is available, run two parallel ClickHouse queries (JSONEachRow) to fetch per-app open_count and distinct user_count, parse results into Maps (parsing counts as integers). If ClickHouse is not present, fall back to the original MySQL aggregate queries. Apps list still comes from MySQL as before. This enables using ClickHouse for analytics performance while preserving the existing behavior as a fallback.
2026-03-13 14:46:44 -07:00
Eric Dubé 9506c537ab fix(security): shell escape paths in HostDiskUsageService; null-prototype objects in batch parser (#2659)
* fix(core): escape path in HostDiskUsageService

* fix: always use null prototypes on operation specs

* fix: update test.yml so that tests work again
2026-03-13 14:17:36 -07:00
Daniel Salazar 9169114e60 fix: tests oom breaking (#2661)
* fix: healthcheck route visible in subdomains

* fix: tests oom breaking

* fix: don't spawn many dynalites

* fix: possible loop when merging self owned apps
2026-03-13 13:41:07 -07:00
ProgrammerIn-wonderland 87672802fe mute puterjs error (#2657) 2026-03-12 11:17:59 -07:00
Daniel Salazar 5505da027d fix: app merging (#2654)
* fix: only set authToken if present for apps

* fix: keep bootstrap in url for app to do whatever

* fix: tests

* fix: app merging

just cleaning up how merging subdomain and canon apps work, namely, persisting data better and making sure its temp alias are deleted when appropriate

* fix: tests oom
2026-03-12 10:18:02 -07:00
Eric Dubé d086e4961c feat(puter-js): add Batch builder class (#2651)
Usage example:
  const b = new puter.fs.Batch();
  b.move('file_1.txt', '~/Trash');
  b.move('file_2.txt', '~/Trash');
  await b.end();

Chaining is also supported:
  await new puter.fs.Batch()
    .move('file_1.txt', '~/Trash')
    .move('file_2.txt', '~/Trash')
    .end();

This commit provides `move` and `delete` methods for Batch.
2026-03-11 22:33:51 -04:00
ProgrammerIn-wonderland 721af2a9b1 Ns/worker global public fetch (#2652)
* add global_fetch_strictly_public compatibility flag

* add comma
2026-03-11 19:27:28 -07:00
Daniel Salazar fc273d436d feat: scope index_url uniqueness to hosted domains (#2644)
* feat: scope index_url uniqueness to hosted domains

Allows duplicate non-hosted origins while enforcing hosted-origin uniqueness and joining new app creation into an existing owner-matching hosted app UUID.

Restricts hosted index_url joins to unowned conflict apps, persists old-to-canonical app UID aliases in kvstore via sudo, and resolves aliases on read with parallel lookup to minimize latency.

* fix: allow merge for owned origin bootstrap apps

Restores hosted update/create merge when the conflicting app is the same-user auto-created origin bootstrap app while still blocking merges into normal same-owner apps to avoid multi-join behavior.
2026-03-11 18:21:09 -07:00
Eric Dubé 9a78b6bffa fix(fs) optimize stat operation. (#2649) 2026-03-11 20:18:42 -04:00
Eric Dubé 7ff1ecfcd7 dev(fs): fetch subdomains using join in readdir (#2647)
* dev(fs): fetch subdomains using join in readdir

* fix(fs): handle readdir of root directory
2026-03-11 20:06:13 -04:00
Daniel Salazar 34fdd94767 feat: phase 3 public hosted actor cookie bootstrap (#2626)
Adds non-blocking public hosted actor cookie mint/verify flow for non-private apps, sets actor context when available, and includes focused middleware/auth tests for security and performance-sensitive paths.
2026-03-11 16:15:03 -07:00
Daniel Salazar a4aea52322 fix: keep bootstrap in url for app to do whatever (#2648)
* fix: only set authToken if present for apps

* fix: keep bootstrap in url for app to do whatever
2026-03-11 15:27:30 -07:00
Eric Dubé 8c9c476969 dev(extension): [+] test-actions (#2575)
Adds an extension that presents an unauthenticated page for testing
various actions of Puter when it's under development. This action is
only meant to be used in development and is not loaded by default.
2026-03-11 14:20:03 -04:00
Eric Dubé 58738ebbb1 dev: get system user from SUService in AppIconService (#2601)
* dev: get system user from SUService in AppIconService

* fix: accidental addition
2026-03-11 14:18:45 -04:00
Eric Dubé e56d8f6889 dev(fs): add move command to batch executor (#2646)
Effectively this makes it possible to perform multiple move operations
in a batch request.
2026-03-11 14:15:49 -04:00
Daniel Salazar bba0533078 feat: checkName api for puter apps (#2643) 2026-03-11 00:23:35 -07:00
Eric Dubé ebb9015045 fix(core): handling of refer code storage add (#2642) 2026-03-10 22:39:02 -04:00
Eric Dubé 05b047c8b9 Revert "perf(core): very simplistic minifier for homepage (#2630)" (#2641)
This reverts commit ae96912699.
2026-03-10 21:36:14 -04:00
Eric Dubé ae96912699 perf(core): very simplistic minifier for homepage (#2630) 2026-03-10 21:24:13 -04:00
Daniel Salazar e96221b0b6 feat: phase 2 enforce index url ownership and uniqueness (#2625)
* feat: phase 2 enforce index url ownership and uniqueness

Adds write-time index URL uniqueness checks, expands hosted subdomain ownership enforcement to private hosting domains, and updates AppService tests for duplicate-index behavior.

* test: align app service comp fixtures with index url uniqueness

Updates regression test fixtures that intentionally exercise name conflicts and selection paths to use unique index_url values under the new one-index-per-app constraint.

* fix: exempt placeholder index url from uniqueness checks

Skips index_url uniqueness enforcement for the shared dev-center coming-soon URL in both AppService and AppES, and adds unit/comp regressions to keep one-index-per-app behavior for all other URLs.
2026-03-10 18:18:01 -07:00
jelveh 1052d4d51d Avoid reload when embedded in popup
Set reload_on_success explicitly when invoking UIWindowLogin so the UI does not trigger a page reload if the GUI is embedded in a popup. Previously the call forwarded a reload_on_success variable; now it uses !window.embedded_in_popup to prevent unwanted reloads in popup embeds.
2026-03-10 18:10:23 -07:00
Daniel Salazar 156d571b10 feat: limit concurrent request for ai chat (#2640) 2026-03-10 16:13:20 -07:00
ProgrammerIn-wonderland 14f218ef72 fix assets_url bug in GUI buildstep (#2638)
* fix assets_url bug in GUI buildstep

* add await
2026-03-10 13:55:06 -07:00
ProgrammerIn-wonderland 26a7ae9d4c s/mv/cp/ for gui buildstep (#2637) 2026-03-10 13:47:40 -07:00
ProgrammerIn-wonderland 031a3da7f1 s/icons/assets/ for building GUI (#2636) 2026-03-10 13:38:32 -07:00
ProgrammerIn-wonderland c297715875 add support for building with custom icons (#2635) 2026-03-10 13:21:05 -07:00
Eric Dubé c9787c1d4b devex(core): avoid email verification on dev (#2634)
Add guard to check if `env` in the backend configuration is set to
`'dev'`. When it is set to `'dev'`, do not invoke email verification
extensions.
2026-03-10 15:56:00 -04:00
Eric Dubé cc70e49472 Fix missing password entry (#2632)
* Revert "dev(oidc): hide unnecessary div"

This reverts commit 468558f8dc.

* fix(oidc): remove the "You will be asked to..." box properly

Earlier this was removed with a simple `display: none` in CSS to avoid
changing any logic, and the reason for that was OIDC had already gone
through significant testing, re-testing, and bug fixes; it became clear
that changes to the auth flow are fragile and the test surface is very
large. Now unfortunately what seemed like a smart decision to fix a
cosmetic issue with CSS instead of updating logic actually wound up
breaking the change username/password flow for non-OIDC users. This
commit removes this box properly and hopefully does not introduce a
subsequent terrible bug. Why would it? There's absolutely no reason I
can see that it would, but it would seem that nothing is safe, not even
CSS.

* temp: disable LRU cache of homepage for now

This is working fine but we're disabling it temporarily so we can test
specific future changes in isolation without managing two separate
branches.

* fix: put verify password text in the box

There's always something...
2026-03-10 03:08:29 -04:00
ProgrammerIn-wonderland 9d82f333e5 revert puterjs gui ordering (#2631) 2026-03-09 21:41:53 -07:00
Eric Dubé 34d4f491b3 perf(core): LRU cache PuterHomepageService (#2627)
LRU cache the output of PuterHomepageService with a cache key based on
metadata that affects the output of the homepage (if an app was
specified, and if so what app was specified).

With this change in place we can afford more time processing this
output, for example to minify the output and reduce outbound bandwidth.
2026-03-09 22:11:48 -04:00
ProgrammerIn-wonderland b687ba0456 Ns/configurable gui bundle (#2629)
* add configurable GUI bundle

* also support CSS and puterjs custom location

* simplify ternary

* used bundled instead of use_bundled_gui

* Quote the string

* close script tag
2026-03-09 19:08:24 -07:00
Daniel Salazar 57a29999e3 feat: phase 1 canonical app origin resolution (#2624)
* feat: phase 1 canonical app origin resolution

Adds cache-first canonical app uid resolution for origin-based auth flows with oldest-app selection and deterministic fallback, plus regression tests for hosted/non-hosted canonicalization behavior.

* refactor: use kv singleton for origin local cache

Replaces AuthService app-origin local canonicalization Map cache with kvjs singleton keys, applies TTL via EX on writes, and rotates local cache namespace on version bumps to avoid broad clears.

* refactor: target origin cache invalidation

Removes global app-origin cache version bumps and invalidates canonical origin cache entries by affected app index URLs from app.changed payloads. Also emits app and old_app data on update events for targeted invalidation.

* fix: avoid invalid old_app owner field in app change event

Removes owner_user_id access from AppES old_entity event payload because the entity model does not expose that property, fixing AppService comp upsert regression tests.
2026-03-09 16:32:32 -07:00
Daniel Salazar e4a52947fe fix: private app token (#2623) 2026-03-09 12:49:14 -07:00
5e7c2c3ddd Update Hosting API description #2612 (#2620)
* Update Hosting API description #2612

* Update copy and fix minor formatting

* Update copy 'deployment'

---------

Co-authored-by: artyz <[email protected]>
Co-authored-by: Reynaldi Chernando <[email protected]>
2026-03-09 14:19:24 +07:00
Michael LipandReynaldi Chernando 19df50bcba Add Networking examples to docs index page (#2613)
* Add Networking examples to docs index page

Fixes #2611

* Add icons and fix playground link

---------

Co-authored-by: Reynaldi Chernando <[email protected]>
2026-03-09 13:52:19 +07:00
Shruc 06b66719fe fix gemini image provider implementation (#2569)
* implement proper calls to gemini image

* remove hardcoded image prices

* fix model selection

* add flash 3.1 image, fix pricing

* also handle uris with data prefix

* more efficient uri parsing

* fix token calculation

* re-add some costs for models page
2026-03-08 23:25:11 -07:00
jelveh 62df3df6a9 Add nl2br Handlebars helper and use in template
Convert newline characters in email reason text to <br /> tags and ensure proper escaping. Replaced {{reason}} with {{{nl2br reason}}} in the rejection template and registered an nl2br Handlebars helper that escapes HTML entities, transforms newlines to <br /> and returns a SafeString so line breaks render correctly in emails.
2026-03-08 15:51:54 -07:00
ProgrammerIn-wonderland 004777824d use openrouter provided USD cost when present (#2619) 2026-03-08 12:12:24 -07:00
Eric Dubé 0fa0340ca2 clean(apps): merge fns only called by get_app_icon_url (#2617)
Each of these methods is only being called by get_app_icon_url. By
changing that ternary operator into an `if` block with an early return
we can move the bodies of these functions here. If one of the former
functions ever needs to be used in more than one place, it's easy to
extract it out of here agian - for now though let's not pay the cost of
jumping to another function definition while trying to understand this
code if we're not gaining anything from it.
2026-03-06 20:07:14 -05:00
Eric Dubé 2a027ed410 fix(puterfs): await queue items for fsentry action (#2616)
* style(puterfs): update adherence to linter rules

* fix(puterfs): await queue items for fsentry actions

This will ensure some operations always function as expected in a
sequence, although it may incur some performance costs.
2026-03-06 20:04:18 -05:00
ProgrammerIn-wonderland a0fc1bca30 add gpt 5.3 codex and gpt 5.4 (#2618)
* add gpt 5.3 codex and gpt 5.4

* add gemini 3.1 pro preview
2026-03-06 16:59:39 -08:00
Daniel Salazar a861c3e27a chore: typeFixes (#2615) 2026-03-06 00:04:39 -08:00
Miika Kuisma 8e794faf06 Merge pull request #2595 from HeyPuter/miika/put-611
Fix border colors in Settings panel
2026-03-06 10:03:25 +02:00
Eric Dubé f167da9a0a clean: remove a log (#2610) 2026-03-04 22:02:36 -05:00
Daniel Salazar 4aab06611e feat: redirect away cookie (#2609) 2026-03-04 17:54:58 -08:00
ProgrammerIn-wonderland 9a6178e66f Make credentialless false by default 2026-03-04 20:54:04 -05:00
Daniel Salazar 237973f227 fix: fetching user from session token (#2607)
old bug was causing issues trying to use sessions as auth checks for tighter security for private apps. missed it without more detailed logs
2026-03-04 17:29:52 -08:00
Daniel Salazar 3f0b0bfd1d feat: more robust error logs (#2605) 2026-03-04 16:47:01 -08:00
Daniel Salazar d28cc46e02 fix: add logs to debug on prod (#2604) 2026-03-04 16:20:52 -08:00
Eric Dubé 0864b9ece1 dev(apps): add configuration to not use app icon subdomain (#2603)
* dev(apps): add configuration to not use app icon subdomain

For some local configurations of Puter, such as using ngrok or a hosting
service that has limited subdomains or limited subdomain depth, the
static hosting subdomain for app icons is difficult to configure and may
not be viable. Since this is only done so an external geo-replicated
cache can be used, and it's always possible for Puter's backend to
generate an app icon, it should be possible to configure Puter's backend
to use icons from a URL hosted on the default subdomain.

Add a configuration parameter to the service "app-icon" called
"no_subdomain" which prevents Puter's backend from sending puter-icons
subdomain URLs or redirecting to them.

Also perform some small cleanup changes to make the existing code easier
to understand, including:
- rename `buildAppIconUrl` to `buildAppIconSubdomainUrl` to make it
  clear which of the two types of icon URLs are being generated.
- replace `withAppIconUrl` with `get_app_icon_url` so it is possible to
  get an icon URL without mutating an app object.
- make the `get_taskbar_items` helper use the same code for getting app
  icons as the `get_apps` helper.

* fix(apps): test initializes a service with no config
2026-03-04 19:10:32 -05:00
jelveh d802d12a05 Add UI notify API and notification handling 2026-03-04 15:29:50 -08:00
Daniel Salazar 9721943040 fix: prioritize new token thant anything outdated stored in localstorage (#2600) 2026-03-04 14:49:05 -08:00
KernelDeimos fc29e57730 fix(oidc): request object reference in oidc signup
The request object was not being passed to OIDC signup because it is
called by createUserFromOIDC which doesn't take a request object as a
parameter. It was decided to have `create_user` take the request object
from context if it's not specified rather than change the signature of
createUserFromOIDC.
2026-03-04 14:33:36 -05:00
Daniel Salazar 1720c97851 fix: origin canonization (#2597) 2026-03-04 11:09:25 -08:00
Daniel Salazar 8a14871dde fix: bad token generation for private apps (#2596) 2026-03-04 10:09:16 -08:00
Miika Kuisma f887c56e61 Restored previously used border colors 2026-03-04 10:32:39 +02:00
jelveh 6248a89a59 Add autoplay to iframe allow list 2026-03-03 22:20:31 -08:00
Daniel Salazar 6b6f9b4743 fix: puter site middleware host (#2594) 2026-03-03 22:18:47 -08:00
Daniel Salazar 8380b28d8a fix: reset subdomain if empty (#2593) 2026-03-03 21:07:55 -08:00
Daniel Salazar adf034b120 feat: add subdomain to private asset tokens (#2591) 2026-03-03 20:37:17 -08:00
KernelDeimos 468558f8dc dev(oidc): hide unnecessary div
I decided not to remove it because I really don't want to introduce a
bug right now while everything is finally working smoothly... I'm making
a note to properly clean this up later when it can be more easily tested
in isolation from everything else.
2026-03-03 23:08:05 -05:00
Daniel Salazar dbdead9ad1 fix: remove redis cache scan in favour of direct key invalidation (#2589) 2026-03-03 19:55:41 -08:00
jelveh 80cabca7ad Add Google SVG icon to sign-in button 2026-03-03 19:31:39 -08:00
Baptiste Lyet f0d0e1d8ca docs : udpdate current year (#2585) 2026-03-04 10:30:42 +07:00
Daniel Salazar 911c163fc8 feat: private app config to use app urls + app routing (#2587)
* feat: private app config to use app urls

* fix: launch app

* fix: cookie origin
2026-03-03 18:34:33 -08:00
KernelDeimos 3cd5268379 fix(oidc): login flow with puter.ui.authenticateWithPuter
It turns out there are nuances between `puter.ui.authenticateWithPuter`
vs `puter.auth.signIn` - these don't do the same thing. The primary
difference is that `puter.ui.authenticateWithPuter` will display an
override if it's not triggered by a user action, whereas
`puter.auth.signIn` will not. This definitely suggests
`puter.ui.authenticateWithPuter` should be a caller of
`puter.auth.signIn` instead of implementing its own logic for handling
the popup - that makes this part of the code more fagile - but that
refactor is out-of-scope for this bug fix.
2026-03-03 21:20:46 -05:00
Daniel Salazar 1f975b9d19 fix: private app config to use app urls (#2586) 2026-03-03 15:49:33 -08:00
Daniel Salazar 4f5fec5ee4 feat: resolve private app hosts by index_url fallback (#2583)
* feat: resolve private app hosts by index_url fallback

Adds a private-app lookup fallback for hosted subdomains without associated_app_id by matching owner-scoped index_url candidates built from request host and configured protocol.

* fix: redirect path

* fix: add new domains too

* fix, bootstrap url

* fix: bootstrap url

* fix: auto sign in puter pirvate app
2026-03-03 13:52:12 -08:00
KernelDeimos 930cbfb770 fix(ai): additional auth guard (corrected 676b6c3) 2026-03-02 19:55:07 -05:00
KernelDeimos 91b9aa014a Reapply "fix(auth): add explicit check for access token suspension (#2576)" (#2579)
This reverts commit 8349b0d692.
2026-03-02 19:45:11 -05:00
KernelDeimos 9fd1d0a2e2 Revert "fix(ai): additional auth guard (#2577)"
This reverts commit 676b6c31e1.
2026-03-02 19:37:18 -05:00
Eric Dubé 8349b0d692 Revert "fix(auth): add explicit check for access token suspension (#2576)" (#2579)
This reverts commit f6b9c69ce6.
2026-03-02 19:24:15 -05:00
Eric Dubé 8073f73032 Eric/26323 revert 26322 (#2578)
* fix(ai): additional auth guard

* Revert "fix(ai): additional auth guard"

This reverts commit 03d4e66e3b.
2026-03-02 19:12:41 -05:00
Eric Dubé 676b6c31e1 fix(ai): additional auth guard (#2577) 2026-03-02 18:45:33 -05:00
Eric Dubé f6b9c69ce6 fix(auth): add explicit check for access token suspension (#2576) 2026-03-02 17:10:42 -05:00
Miika Kuisma c0583a9095 Fix: When a maximized window gets resized, Puter apps should be resized as well (#2498)
* Fix: When a maximized window gets resized, Puter apps should be resized as well

* Fix maximixed selector to match any window with data-is_maximized (not just apps)
2026-03-02 10:48:47 -08:00
jelveh 43b313972c Revert "Permission modal now displays application's icon and title. Read and write access requests have their own text strings. (#2499)"
This reverts commit 0f33e49335.
2026-03-01 21:59:10 -08:00
Miika Kuisma 0f33e49335 Permission modal now displays application's icon and title. Read and write access requests have their own text strings. (#2499) 2026-03-01 20:02:20 -08:00
Eric Dubé f2926c948e fix(oidc): bring "Add Existing User" to working state (#2572) 2026-02-28 16:39:20 -05:00
Daniel Salazar 314c671778 fix: redis startup (#2571)
add event logging and handling to deal with redis startup
2026-02-28 13:25:42 -08:00
Daniel Salazar bb02fc6e6b fix: hardcode default perm (#2570) 2026-02-28 13:13:05 -08:00
Daniel Salazar 537f3957ed feat: add private app direct-login bootstrap page (#2566)
* feat: add private app direct-login bootstrap page

Serves a lightweight puter.js sign-in interstitial when private app identity is missing, then retries with a bootstrap token query param while preserving entitlement redirect behavior for authenticated denies.

* fix: allow private app subdomain
2026-02-28 13:04:14 -08:00
Daniel Salazar 2eb16ceab6 chore: switch private hosting domain to puter.dev (#2565)
Updates private app hosting defaults and middleware/test expectations from puter.app to puter.dev for current rollout needs.
2026-02-27 16:24:54 -08:00
Eric Dubé 2cc8cb22f8 [OIDC] allow user deletion for accounts without a password (#2567)
* fix: user deletion for OIDC accounts

* clean(backend): update copied license header

* clean(backend): replace previously removed comments

* fix: double-encoding
2026-02-27 18:55:12 -05:00
Eric Dubé 9d4e990b92 dev(oidc): switch login/signup flows where applicable (#2550)
For convenience, switch flow if the user's action doesn't match the
system state when signing up or logging in with Google:
- If the user chooses "signup" but they already have an account, log
  them into that account.
- If the user chooses "login" but they do not have an account yet,
  create an account where their authenticated email address.
2026-02-27 18:30:17 -05:00
Daniel Salazar 7e07c3d937 feat: add private access rollout gate and auditing (#2560)
Adds a config flag to disable private app gate enforcement, structured middleware audit logs for private access decisions, and regression coverage for the disabled-gate path.
2026-02-27 13:55:15 -08:00
Eric Dubé 866825767b fix(backend): default rate-limit scope instead of error (#2564)
When a rate-limit scope is not configured, use a default configuration
instead of throwing an error. Display a warning about the unconfigured
rate-limit scope when the default is used.
2026-02-27 15:58:36 -05:00
Anshuman Tripathi 7c437fabf3 fix: corrected service reference (#2559) 2026-02-27 13:45:01 -05:00
Reynaldi Chernando 613b0482e8 Add nano banana 2 (#2562) 2026-02-27 13:00:36 -05:00
Daniel Salazar 784847b1b1 feat: enforce private app hosting access gate (#2557)
Add private app access gating in PuterSiteMiddleware with entitlement event checks, bootstrap/private cookie token flow, and camelCase helper/test updates.
2026-02-26 23:42:32 -08:00
Daniel Salazar 23089901dd perf:remove recents cache (#2558) 2026-02-26 16:38:58 -08:00
Daniel Salazar adce8c64db feat: add private app access extension event contract (#2556)
* feat: add private app access extension event contract

Define app.private-access.check in extension API typings with mutable allow/redirect decision fields for entitlement handlers.

* refactor: camelCase private access event contract

Rename private access extension event and payload fields to camelCase for consistency with repo conventions.
2026-02-26 15:04:23 -08:00
Daniel Salazar 15e7a3503b feat: add private app asset token auth helpers (#2555)
* feat: add private app asset token auth helpers

Add mint/verify helpers and hardened cookie option helpers for app-private-asset tokens in AuthService.
Add focused tests for claims validation, mismatch denial, and cookie option defaults.

* fix: add prvate app config for new subdomain
2026-02-26 14:19:59 -08:00
Daniel Salazar f8560cf0f9 fix: delete redis keys in parallel, don't grant both read and write if just write needed (#2552) 2026-02-26 14:03:21 -08:00
Daniel Salazar 1887352301 fix: don't await cache invalidation for grant app permission (#2551)
* fix: disable broadcast for cache invalidation

* fix: remove broadcast for redis events for now

* fix: don't await cache invalidation for grant app permission
2026-02-25 17:26:42 -08:00
Daniel Salazar 2c1b21e197 feat: type extension cache update events (#2548)
* feat: type extension cache update events

Expose outer.cacheUpdate in extension API typings and consolidate extension service typing via ServicesMap.

* fix: batch broadcast events

* fix: bad import

* fix: import socket io

* fix: bad undefined call

* fix: simplify await for broadcast processing
2026-02-25 17:05:05 -08:00
Daniel Salazar aa04dfabb4 feat: add is_private to apps (#2546) 2026-02-25 13:26:16 -08:00
Eric Dubé c4346df24e fix(gui): defer login event until listener registered (#2547)
Fixes an error introduced in 4b8c46e where the page load is attempted to
be triggered by dispatching the login event, however the listener which
handles loading the page has not yet been registered.
2026-02-25 14:22:06 -05:00
Daniel Salazar 7a1468d070 fix: app icons via subdomain on localhost (#2544) 2026-02-25 10:14:39 -08:00
jelveh 71f7698a46 Await update_auth_data to avoid races 2026-02-24 18:33:30 -08:00
jelveh 0515b65138 Await update_auth_data to avoid race conditions 2026-02-24 18:24:33 -08:00
Daniel Salazar 66f1cd0bc3 fix: remove broadcast for cache updates (#2542)
* fix: disable broadcast for cache invalidation

* fix: remove broadcast for redis events for now
2026-02-24 16:45:32 -08:00
Eric Dubé 6658a90b6a fix(backend): invalidate app permission debounce (#2541)
* fix(backend): debounce app permission invalidation

* fix(backend): debounce app permission invalidation
2026-02-24 19:00:34 -05:00
Daniel Salazar 4c863cc5bc fix: make invalidations more robust (#2529) 2026-02-24 15:45:46 -08:00
Daniel Salazar 6544e8c250 cleanup,:remove debugger calls in our code (#2535) 2026-02-24 15:42:39 -08:00
Eric Dubé ce3c9bff34 Fix OIDC in popups (#2539)
* fix(oidc): OIDC login with puter.js popup auth

Bring login through OpenID Connect to a working state in the puter.js
popup authentication flow. This allows OIDC login to work with
third-party websites and apps.

* fix(oidc): error handling, use const (initgui)

Remove a condition that can be handled by the control flow logic
already implied by a try...catch, which also allows a variable to become
const, and log errors in this catch block.

* doc(oidc): make this comment a little more helpful

* clean(oidc): remove out-of-scope puter.js change

Remove a change that gives explicit overrides of the `defaultGUIOrigin`
paramter precedence over other sources of this value. This was necessary
when testing but might not be the correct fix for this issue.
2026-02-24 17:17:18 -05:00
Neal Shah 267713481c fix desktop gui error handling for workers (#2538) 2026-02-24 16:32:14 -05:00
Neal Shah 1e3193366a dont forward data urls through cors proxy and fix core.validation (#2537)
* exempt data urls from using cors proxy

* disallow unlimited use

* make core.validation defined again
2026-02-24 16:11:00 -05:00
Daniel Salazar 052e3f9dcb cache: extend cache invalidation to emit events out too (#2532) 2026-02-23 22:24:57 -08:00
Neal Shah c14dd5ae78 WIP: use cors proxy for outbound requests (#2533) 2026-02-24 01:10:23 -05:00
jelveh eaaeb4e6a4 Await update_auth_data before continuing
Await the window.update_auth_data call in initgui.js so subsequent logic (such as popup spinner hiding and timing) runs after authentication data has been updated. This prevents race conditions where later UI code executes before auth state is fully applied.
2026-02-23 18:19:35 -08:00
jelveh 8f4a38ae0b Load user preferences with error handling
Read user preference keys (show_hidden_files, language, clock_visible) into local variables with try/catch and sensible defaults, instead of fetching/parsing them inline. This prevents exceptions from missing or malformed KV entries and centralizes parsing for show_hidden_files. Also remove an extra blank line in initgui.js's AJAX complete callback.
2026-02-23 16:52:56 -08:00
Eric Dubé 4554331eff dev(oidc): redirect to login/signup on error (#2531)
Redirect to the login or signup page when there is an error signing in
or creating an account using OIDC, instead of displaying the error on a
new page. Alter the flow in cases where the suggested action is not the
same as the initial action taken by the user (based on the error case).
2026-02-23 17:56:38 -05:00
Daniel Salazar eda9f117c7 fix: default timeout on user caches of 15 min (#2530) 2026-02-23 14:21:24 -08:00
Daniel Salazar e60f55f20e fix: stricter invalidation for 2fa and confirm email codes (#2528) 2026-02-23 09:01:59 -08:00
P3il4 779321d334 fix nano banana pro pricing and resolutions (#2501)
* fix nano banana pro pricing and resolutions

* move gemini resolution map into models.ts

* require gemini 3 model for specific resolution and price logic

* fix usageamount for mp models
2026-02-23 03:39:48 -05:00
samarthmishra46 0ee2ebd7b4 added keyboard shortcut in the setting for better ui navigation (#2484) 2026-02-22 18:31:15 -08:00
Eric Dubé 96be8707b8 Merge pull request #2526 from HeyPuter/eric/262L0_PUT-533
fix: bad copy with reference in UIItem
2026-02-21 20:19:59 -05:00
KernelDeimos 7ba40f8062 fix: bad copy with reference in UIItem
UIItem makes a recursive call when there are multiple matching elements
in the `options.appendTo` argument. When calling recursively, the
`appendTo` property of the `options` object is mutated to a specific
element before the call, which expects that each call to UIItem occurs
synchronously. UIItem was made asynchronous by
9d598f7965
which resulted in a bug causing duplicate item icons in one directory
window instead of one item icon in each directory window after a file
upload when multiple instances of a window at the same directory
location exist.

Resolves #2514
2026-02-21 20:14:08 -05:00
Neal Shah 1ed765cb86 Clarify expiration time unit in getReadURL.md (#2525)
Updated the documentation to specify that the expiration time is in milliseconds instead of seconds.
2026-02-21 04:15:27 -05:00
Daniel Salazar 9f87ccb460 fix: cleanup some app es and app service validation (#2523)
we saw some errors with icons not allowed when being objects, this likely user error, but this adds some validation to at least avoid nulls being flagged wrong
2026-02-21 00:10:55 -08:00
Daniel Salazar 3a89deaf02 fix: wrong icon for workers (#2524) 2026-02-20 19:20:18 -08:00
Daniel Salazar 3834571ab8 fix: don't call stat on each file in dir (#2522)
* fix: decrease metering service gloabl rate of change check

* fix: don't call stat on each file in dir
2026-02-20 19:07:16 -08:00
Daniel Salazar d418976ee4 perf: batching get_apps cache look ups (#2521)
should not be slow in any case, but this should help a bit more with speed in trade of more ram and cpu usage
2026-02-20 18:02:47 -08:00
Daniel Salazar 22c1cd8be4 lint: fix eslint indentation for switch cases (#2520)
also trying to preserve call indentations, but afraid its not exactly the same, but fairly close
2026-02-20 17:22:00 -08:00
Daniel Salazar 3b32b4a437 fix: don't await for cache writes (#2519)
* fix: allow healthcheck from other hosts

* fix: don't await for cache writes

we think some awaiting on redis writes was causing issues, we shouldn't need to await really, so removing now. will have optimistic caching for these

some style changes from a recently changed rule that seems to clash with prior one
2026-02-20 17:19:01 -08:00
Miika Kuisma 808b78c234 Fixed: puter.chat button has weird gradient when browser is dark mode (#2516)
Fixed: The gradient and progress bar on the usage details page is not very pleasant and looks inverted
Fixed: The billing card on the billing tab is still light mode
2026-02-19 19:43:20 -08:00
Eric Dubé 21185cdb3f Merge pull request #2460 from HeyPuter/eric/262A0_PUT-453
Login/Signup with OIDC

Wellp... this is not a rebase, this is merge. My hands were tied this time.
2026-02-19 22:39:44 -05:00
KernelDeimos ef0a665a5f fix(oidc): add code lost due to editing a .js
This code was previously lost because I edited `outcomeutil.js` instead
of `outcomeutil.ts`. We're not building into a `dist/` directory and
`tsc` has a most peculiar lack of generating a comment at the top of
output files stating something like "// GENERATED - DO NOT EDIT" as I've
seen from every other code generator or transpiler I've worked with.

This caused the bug with duplicate confirmed emails and "account not
found" during testing on the staging server.
2026-02-19 21:25:24 -05:00
Daniel Salazar b39bbe0a0a Merge remote-tracking branch 'origin/main' into eric/262A0_PUT-453 2026-02-19 16:45:10 -08:00
Daniel Salazar 2e7765004c fix: redis cache deletions (#2518) 2026-02-19 16:43:56 -08:00
Daniel Salazar 0cca9d5535 fix : import 2026-02-19 16:08:48 -08:00
KernelDeimos 1be3eca335 fix: rate limits for oidc too extreme 2026-02-19 19:00:01 -05:00
Daniel Salazar 7493573c61 Merge remote-tracking branch 'origin/main' into eric/262A0_PUT-453 2026-02-19 15:28:14 -08:00
Daniel Salazar ec412eaff6 feat: cleanup cache invalidation and pull out keys to be easily used in other places that need the same cache (#2515)
fix: tests
2026-02-19 15:07:04 -08:00
KernelDeimos 0112f097db style(oidc): if instead of return with ternary expression 2026-02-19 17:18:48 -05:00
KernelDeimos 4e01608e4a dev: remove guarded debug log 2026-02-19 17:02:33 -05:00
KernelDeimos b3b32980db clean(oidc): remove jwt remap in ESM code 2026-02-19 16:32:41 -05:00
KernelDeimos f3bf40a3c0 style(oidc): rename httpPowers to hasHttpOnlyCookie 2026-02-19 16:29:19 -05:00
KernelDeimos 4de6d38604 style(oidc): make this a private method 2026-02-19 16:23:40 -05:00
KernelDeimos 4c518830ea clean(oidc): remove "ghost files" 2026-02-19 16:23:40 -05:00
KernelDeimos b5d719e110 lint: [+] no-useless-computed-key:error 2026-02-19 16:23:38 -05:00
KernelDeimos c97a499bc9 style(oidc): private members in OIDCService 2026-02-19 16:21:43 -05:00
KernelDeimos 16f2f5bf5f style(oidc): address PR rev on oidcCallbackPreamble_ 2026-02-19 16:21:42 -05:00
KernelDeimos 720277c9bd style(oidc): migrate cjs to esm 2026-02-19 16:21:42 -05:00
KernelDeimos 7ca0fe2ac4 clean: remove commented code 2026-02-19 16:21:42 -05:00
KernelDeimos ccecf0a86e fix(oidc): remove generated source file
I forgot that our transpile tooling requires manually gitignoring
individual javascript files because we don't actually create a full
generated build of backend.
2026-02-19 16:21:42 -05:00
KernelDeimos 8d18ee527c refactor(oidc): address review comment
https://github.com/HeyPuter/puter/pull/2460/changes#r2819861213
2026-02-19 16:21:42 -05:00
KernelDeimos 7858f5ba3e fix(oidc): add error log for QR login flow 2026-02-19 16:21:42 -05:00
KernelDeimos a2b9193287 clean(oidc): remove temporary debugging logs
These logs were temporary. I have a pre-merge TODO list item that says
to remove these. They were caught in review so I'm removing them early.
2026-02-19 16:21:42 -05:00
KernelDeimos d0c2e9b7fc fix(oidc): rate-limit identity for username 2026-02-19 16:21:41 -05:00
KernelDeimos 2b802143fc fix(oidc): add missing awaits 2026-02-19 16:21:41 -05:00
KernelDeimos 42d3f9e816 fix(oidc): http-only cookie sync for switch user 2026-02-19 16:21:41 -05:00
KernelDeimos b5a3323811 fix: incorrect parameters in UIWindowChangeEmail 2026-02-19 16:21:41 -05:00
KernelDeimos 2cdc211b29 fix: incorrect parameters in UIWindowChangePassword 2026-02-19 16:21:41 -05:00
KernelDeimos 298f1cdb42 fix: incorrect accessor reference in OIDCService
During development a property named `success` was inverted to a property
named `failed` which resulted in an incorrect accessor reference with a
referring piece of code that wasn't updated. This is type error.
2026-02-19 16:21:41 -05:00
KernelDeimos e145f5dcc3 dev(oidc): rewrite "Disable 2FA" window
In lieu of knowing exactly what happened (probably more than one thing),
the "Disable 2FA" window was very broken. It was blank, but then after
fixing that all the actions were broken. There wasn't much value in
keeping the implementation though, because it was already inconsistent
with other flows - instead of fixing what was there it made more sense
to re-use the pattern of UIWindowChangeUsername and UIWindowChangeEmail,
creating UIWindowDisable2FA. After testing this, it works much better
(it actaully works), but there is a caching issue unrelated to the UI
implementation.
2026-02-19 16:21:39 -05:00
KernelDeimos 4d49f5dfa6 fix: allow html property in UIComponentWindow
A component was removed and an html property was passed to
UIComponentWindow. This makes sense because UIWindow accepts an html
property, so rather than update the calling code it made more sense to
update UIComponentWindow to be more intuitive.
2026-02-19 16:13:45 -05:00
KernelDeimos 8ecd6cd13e dev(oidc): confirm email by default for OIDC 2026-02-19 16:13:45 -05:00
KernelDeimos 21e959bbaa dev(oidc): remove button to manually invoke re-auth
This button was useful during manual testing, but the re-authentication
flow for protected endpoints with OIDC users reliably invokes the popup,
so this is no longer necessary. Removing this button reduces clutter on
these screens and might make the flow easier for users to understand.
2026-02-19 16:13:44 -05:00
KernelDeimos e2068e7b9c fix(oidc): fix QR code login issues caused by OIDC
In implementing OIDC it became necessary to introduce the separation of
"GUI Tokens" and "Session Tokens". This breaks QR login because Puter
does not set the HTTP-only session cookie when logging in with this
flow.

Add a middelware to WebServerService to detect QR Code logins and set
the appropriate HTTP-only session cookie.
2026-02-19 16:13:44 -05:00
KernelDeimos 8923bdac95 refactor(oidc): update UIWindowChangePassword
Use the openRevalidatePopup function in util/openid.js within
UIWindowChangePassword instead of re-implementing that functionality.
Additionally, normalize some of the code so it is more similar to
UIWindowChangeUsername and UIWindowChangePassword.
2026-02-19 16:13:44 -05:00
KernelDeimos df1f5c44cc refactor(oidc): extract common (email + username)
There is common functionality between all of the GUI code for actions on
protected endpoints. Update UIWindowChangeEmail and
UIWindowChangeUsername to both use a new utility function called
openRevalidatePopup in util/openid.js.

This file is called `openid.js` instead of `oidc.js` so that it's more
easily recognized by contributors who might be more familiar with the
name of the organization than the name of the standard itself.

After these changes, UIWindowChangePassword and the "disable 2FA" button
in UITabSecurity still need to be updated to use `util/openid.js`
instead of duplicating this functionality.

The justification for following DRY here instead of leaving the
implementation as-is is because these flows are particularly error
prone and will be difficult to maintain without this consistency. Some
subtle bugs I previously wasn't aware of got fixed in the process.
2026-02-19 16:13:44 -05:00
KernelDeimos 0b8eafa128 dev(oidc): re-auth remaining protected endpoints
The OIDC re-authentication flow, which replaces password confirmation
for accounts that were created with OIDC and do not have a password, was
previously added to "change username" for manual testing of the
backend-side implementation. Add the re-authentication flow to the
remaining user-protected endpoints, which are:
- change password
- change email
- disable two-factor authentication

When using "change password" on a new account created via OIDC, the
account changes state to a passworded account which causes these flows
to use password confirmation as before instead of re-authentication.
2026-02-19 16:13:41 -05:00
KernelDeimos 142d745f0a fix: "Popup Closed" message, + excess logs 2026-02-19 16:10:22 -05:00
KernelDeimos 3a9a345600 tweak: make monthly username changes configurable
The monthly number of username changes was hardcoded as `2`. Being able
to configure this value makes it easier to test the username change
flow. Hosters of OSS Puter may also find this configuration beneficial.
2026-02-19 16:10:21 -05:00
KernelDeimos d532b3d47b fix(oidc): session token vs gui token issues 2026-02-19 16:10:21 -05:00
KernelDeimos 5d22ee0517 tweak: re-enable re-auth popup closing 2026-02-19 16:10:21 -05:00
KernelDeimos 4374281070 dev: add re-authentication flow for protect actions
When users make sensitive changes to their account they are asked to
re-enter their password. This prevents a hijacked session from causing
futher damage.

Users created with the new OIDC flow do not necessarily have a password
set on their account, and they need to also be able to make these
changes. While removal of the password entry requirement for these users
would solve this problem, it would also make their accounts more
vulnerable. To solve this problem while maintaining the same security
standard for OIDC users, we need them to confirm via either 2FA or
re-authentication via OIDC. Since users aren't required to have 2FA, the
re-authentication via OIDC approach is also the minimum viable solution.

This commit adds OIDC re-authentication support for all endpoints under
UserProtectedEndpointsService, and makes updates to the
UIWindowChangeUsername dialog for manual testing.

Currently this implementation fails at the final submission to change
the username because of a separate issue with the correct authentication
token not being set; this is related to the separation of GUI tokens vs
http-only tokens.
2026-02-19 16:10:21 -05:00
KernelDeimos 7c8f0d5572 dev(backend): OIDC continued [1]
This commit is rather monolithic. An attempt to split it up into smaller
changes proved too difficult (as well as frustrating) and I realized it
would absolutely increase the chance of having a broken commit (making
bisects more difficult) unless a lot of testing effort between commits
was performed, which would have very little benefit.

The changes in this commit include:
- Outcome utility used by SignupService for error handling
- SignupService, whichs implements re-usable create_user function
- Signup method in OIDCService
- flow-specific callbacks in OIDC (separates login from signup)
- **SEPARATE SESSION COOKIE AND GUI COOKIE**
  - this change "rocks the boat" the most and has the highest likelihood
    of causing problems
2026-02-19 16:10:21 -05:00
KernelDeimos 47b133d512 dev(backend): incomplete oauth2 OIDC impl 2026-02-19 16:10:20 -05:00
Neal Shah 78a4ccb9a4 make image models case insensitive for backwards compatibility reasons (#2512) 2026-02-18 17:01:50 -05:00
Miika Kuisma 1ec2aec66c Dashboard: Files tab fixes (#2508)
* Fixed issues where file list wasn't scrollable on mobile device, and tap'n'hold on file opened wrong context menu.

* Fixes text color of selected row
- [x] Fixes path navigation button transitions
- [x] Fixes path navigation button colors
- [x] Hide AppData folder
- [x] Hide hidden files
2026-02-18 12:19:46 -08:00
KernelDeimos cecb63b372 fix(backend): ESM/CJS interop is sad
Fix ESM/CJS interop issue in unit tests with a hack that checks the
class name as a string instead of just doing an `instanceof` check. This
is assuming that the "rewriter must be a PermissionRewriter" error I'm
seeing on GitHub is because there are two different "copies" of
PermissionWriter due to ESM/CJS interop issues. If this is not the case,
then you're not reading this commit message on `main`; if this commit is
on `main` then that's exactly what went down.
2026-02-17 22:19:52 -05:00
KernelDeimos 05cc4ad477 dev(puter.js): add support to request app dir
Add support for requesting access to the root directory of an app's
associated subdomain.
2026-02-17 22:19:52 -05:00
KernelDeimos bfff2d20f9 dev(backend): add /auth/request-app-root-dir
Add the ability to request an app's root directory. A permission
rewriter is provided so that apps may refer to a permission when
requesting this access without knowing the path of the app's root
directory.
2026-02-17 22:19:52 -05:00
KernelDeimos d21ed31d67 dev(backend): add debug mode for 403 responses 2026-02-17 22:19:52 -05:00
Daniel Salazar 5df1ca88ca feat: sonnet-4.6 support (#2506)
* feat: sonnet-4.6 support

* fix: tests
2026-02-17 12:10:50 -08:00
9d598f7965 Files tab for dashboard view (#2331)
* Dashboard - Added files tab with basic folder and files listing.

* clearing out some linter errors

* Removed Public folder for now

* Added "modified" column
Subfolder are listed before the files

* Dashboard - files tab: context menu basics

* Dashboard - Files tab: subfolders can be opened. Items can be opened from more-menu or by double clicking on them

* Dashboard - Files tab: use UIContentMenu instead of custom menu for "more menu"

* Dashboard - Files tab: Delete implemented, Trash folder added

* refactored context menu rendering

* Implemented UIItem context menu functionalities
Added path

* Rename files and folders

* Rename fix

* tweaks and fixes

* WIP: Multiple selection, drag and drop, trash folder improvements

* clean

* Files handling improvements

* empty trash fix

* grid view

* grid view improvements

* update icons
context menu for multiple items shows file counts such as: Delete (9)

* Path navifation buttons

* better way to get user's directories

* Added icons for various file types

* Use puter.kv instead of window.user_preferences

* sorting and column resizing

* documentation of the functions

* Style update. Dashboard colors now as CSS variables

* refactored restoring from trash and emptying trash with proper callbacks & refreshing

* select documents folder by default
style tweaking

* Drag to select files and folders

* dark mode

* style tweaks

* removed some dead code..

* Keyboard shortcuts (copied from UIWindow - untested & in progress)

* Add drag-and-drop file upload support to Dashboard

Implement native file drag-and-drop from local filesystem to Dashboard:
- Add dragster handlers for main content area, sidebar folders, and folder rows
- Create uploadFiles() method with progress modal and directory refresh
- Add visual feedback CSS for drop zones (highlight on hover)
- Fix subfolder drop detection to prevent duplicate uploads
- Add callback support to unzipItem/untarItem for directory refresh

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* style tweaks

* Fix cut/paste functionality in Dashboard

The cut operation was storing clipboard items as plain path strings, but
window.move_clipboard_items() looks for .item DOM elements which don't
exist in Dashboard (it uses .row elements). Added a Dashboard-specific
moveClipboardItems() method that calls puter.fs.move() directly with UIDs,
and updated cut to store objects with path and uid like copy does.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* Add mobile phone layout optimizations for Dashboard

- Add responsive CSS for screens ≤480px with two-row file list layout
- Wrap item-size and item-modified in item-metadata div for mobile grid
- Hide directories sidebar on mobile (use breadcrumbs for navigation)
- Reorganize header with breadcrumbs on top row, nav buttons below
- Add single-tap to open folders on touch devices
- Fix context menu "Open" action in Dashboard by adding onOpen callback
- Hide column headers on mobile since metadata is shown per-item

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* Add CSS variables to Dashboard bento elements for dark mode support

Replace hardcoded color values with CSS custom properties throughout
the bento card components to enable proper dark mode theming. Adds new
variables for icon shadows, fancy headers, gradients, and usage bars
with appropriate values for both light and dark color schemes.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* Add spacebar image preview feature to Dashboard Files

Pressing spacebar on a selected image file now shows a full-size preview
popover centered over the files container. Features include:
- Toggle behavior: press spacebar again to close
- Auto-switch: selecting another file updates the preview
- Click outside to dismiss
- Works in both grid and list view

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* Add floating action bar for multi-file selection in Dashboard Files

When 2+ files are selected, a floating action bar appears above the footer
with quick access buttons for common operations:
- Download, Cut, Copy, Delete for normal files
- Restore and Delete Permanently for items in Trash

The bar slides up with a smooth animation and disappears when clicking
the background to deselect. Includes mobile-responsive styling with
icon-only buttons on smaller screens.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* Add mobile select mode for multi-file selection in Dashboard Files

On mobile devices, users can now tap a select button in the path actions
to enter select mode. In this mode, tapping files toggles their selection
instead of opening them, with checkboxes appearing next to each item.
The floating action bar appears with 1+ selected items (vs 2+ on desktop)
and includes a Done button to exit select mode.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* Center empty directory message in Dashboard Files

Replace row-based layout with centered flex positioning for the
"No files in this directory" message, improving visual presentation.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* Fixed issue where clicking on files background created blue dot (drag rectangle selection bug)

* Image preview size tweak

* Add URL-based routing to Dashboard with hash fragments

Enable shareable/bookmarkable URLs for Dashboard tabs and file paths.
The URL hash reflects current location (e.g., #files/username/Documents,
#usage, #account). Browser back/forward navigation now works for folder
navigation, and direct URL entry loads the correct tab and path.

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* fixing draggable styles

* drag clone fixes

* Add smart column resizing and filename truncation to Dashboard Files

- Add middle-truncation for filenames preserving extensions (e.g., "longfile…name.txt")
- Double-click column resize handles to auto-fit content width
- Reset saved column widths to defaults if they don't fit smaller screens
- Apply truncation to both list and grid views

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* Separated dashboard styles into dashboard.css and loading it dynamically only when navigating to /dashboard

* Files and folders can be dropped over path items in order to move them. This is useful when you want to move items into parent folders.

* Use custom context menu component for item-more menu on mobile devices

* Created callback system to undo_last_action so that dashboard file list would always refresh after undo operation

* gray update

* hovering folder while dragging items opens the folder

* Fixed issue with hover-dropping

* Fixed chained drag-over-folder-and-hover system

* dark mode tweak

* - [x] Right clicking on background of an empty folder doesn't trigger context menu
- [x] Right clicking on path should keep path item active
- [x] Sidebar folder don't have context menu
- [x] Drag item should be opaque so I can see through it
- [x] Transition animation issue when hovering path action buttons
- [x] Double clicking on column resizer: add padding
- [x] Load dashboard.css before loading the page content
- [x] Mobile: opening menu, clicking outside menu should close it
- [x] Mobile: on smaller screen there should be still two columns
- [x] Mobile: file name truncation in grid view doesn't work

* Added missing badges

* WIP has_worker

* display worker icon on the .js files which are workers

* Display worker badge on worker files, hovering badge shows worker URL.
Worker URL added to file properties modal.

* disable "publish as website" from context menu for folders that are already published

* Loading spinner for Files

* tweaks and fixes

* Files clean loading spinner

* Files: worker URL in the properties modal is clickable link

* use custom tooltip to display worker URL

* refactored renderDirectory

* Fix Sidebar folder highlighting

* add Beta badge on Files tab

* Implemeting socket based item updating

* Put newly added items into the position where they would land when list is sorted

* restore from trash refresh fix

* Revert "Revert "Adds worker badge to .js files which have been registered as workers. Hovering badge shows popover with worker URL. File properties modal also shows clickable worker URL. (#2462)""

This reverts commit c2750f2ca1.

* worker in stat

* update puterjs and frontend code to support returnWorkers in stat

* Better way of handling worker info

* Fixed issue where right clicking on background opened two instances of a context menu

* Fixes issue where while renaming a file, double clicking on word opened the file

* fixes issue where while dragging multiple items the top-most item was transparent resulting blurry mess

* when opening a folder, update view instantly

* Improved drag-to-select items

* Added feature where typing selects matching file items
Fixed issue where keyboard listener for file list was active when context menu was open

* Fixed issues with File -> New in context menu
Fixes issue where files-selection-actions menu didn't disappear after deleting items

* Improved drag to select behavior
Improved drag items
Improved worker badge handling

* Cancel zone for dragging items (when spring-loading subfolders)

* context menu's submenu tweak

* Fixed issue where resizing window didn't work (when using "Open in New Window" from context menu)

* Disabled buttons on .files-selection-actions while drag-to-select is happening

* Fixes issue where creating new items using right-clicking re-rendered the directory view

---------

Co-authored-by: Claude Opus 4.5 <[email protected]>
Co-authored-by: ProgrammerIn-wonderland <[email protected]>
2026-02-17 10:50:08 -08:00
Neal Shah 4279cd92df WebDAV don't fetch thumbs or associated apps (#2505) 2026-02-17 01:53:59 -05:00
Neal Shah 2fe4ed50c3 WebDAV don't fetch subdomains (#2504) 2026-02-17 01:47:43 -05:00
Neal Shah 562671e498 add extra permission check for granted apps (#2503) 2026-02-17 01:29:54 -05:00
Daniel Salazar 00befdc192 fix: allow b64 srings without mime type for app icons (#2502) 2026-02-16 19:28:44 -08:00
Daniel Salazar 44bb5953b4 fix: app icon origin (#2500)
* fix: app icon origin

* fix: app icon origin size
2026-02-16 12:35:30 -08:00
Daniel Salazar 32682e73eb perf: improve app open time (#2490) 2026-02-16 11:00:32 -08:00
KernelDeimos d9167744ef patch(puterfs): limit directory depth to 35
This is a temporary measure while we fix a production issue.
2026-02-13 20:53:56 -05:00
Neal Shah c87506c7d8 workers ai realias - to dot (#2493) 2026-02-13 16:40:10 -08:00
Neal Shah 0f97653b4c fix stat options when stat(path, options) (#2492) 2026-02-13 15:38:56 -08:00
Neal Shah a211aa04bc add more alises (#2491) 2026-02-13 13:46:42 -08:00
Neal Shah f65ab05b40 Add workers AI image model support (#2489) 2026-02-13 13:07:50 -08:00
Jatin SharmaandReynaldi Chernando 9a47bf16da Bundle docs CDN assets locally for full offline support (#2473)
* docs: bundle CDN assets locally for full offline support

* fix

* fix

* fix

* revert accidental package-lock.json changes

---------

Co-authored-by: Reynaldi Chernando <[email protected]>
2026-02-14 02:14:46 +07:00
Daniel Salazar 809d375854 fix: don't stream back bytes for icons (#2486)
* decrease global check alerts

* fix: don't stream back bytes for icons
2026-02-12 23:34:37 -08:00
Daniel Salazar 4136cb1d24 fix: do not await for puter icon write in db (#2485) 2026-02-12 22:43:23 -08:00
jelveh f1a8fdb5c8 Trigger in-app upgrade flow for app env
Handle upgrade flow when running in the app environment by calling await puter.ui.requestUpgrade() in driverCall_. Added app-specific branches in two places where usage/insufficient-funds were previously handled only for web (which showed a web dialog). This ensures the in-app UI is used for upgrade requests and awaits the result.
2026-02-12 21:45:03 -08:00
jelveh b4c58c4f5c Update UITabUsage.js 2026-02-12 18:09:52 -08:00
jelveh 286895ff66 Disable publish worker UI badge updates
Temporarily comment out code in UIWindowPublishWorker that updates item UI after publishing: hiding the lines that show the item website badge, show per-item website-url badges, and set the data-website_url attribute. This prevents the publish worker from automatically modifying those DOM elements/attributes (kept commented for potential rollback or debugging).
2026-02-12 16:45:23 -08:00
Neal Shahandjelveh a23f272fd2 add sandboxing by default in god mode created workers (#2481)
* add sandboxing by default in god mode workers

* closes #2481

* Update UIWindowPublishWorker.js

* Add sandbox option to worker publish UI

Add a collapsible 'Advanced' section with a 'Sandboxed' checkbox (checked by default) to UIWindowPublishWorker. On publish the code reads the checkbox state and builds createOptions ({ sandbox: true } or { sandbox: false }) and passes it to puter.workers.create as an argument so workers can be created in sandboxed or non-sandboxed mode. Small UI styling and markup for the details/summary block included.

---------

Co-authored-by: jelveh <[email protected]>
2026-02-12 16:06:40 -08:00
Daniel Salazar 354ac314a9 feat: subdomain error redirect (#2483) 2026-02-12 15:39:18 -08:00
Daniel Salazar 1292148b41 fix: app-icons protocol (#2480) 2026-02-12 13:47:23 -08:00
jelveh 9991d58613 Refine 'listing-rejected' email copy 2026-02-12 12:49:13 -08:00
Daniel Salazar 8a6d07ec1f fix: app icon again (#2478) 2026-02-12 12:07:03 -08:00
Daniel Salazar bfd8a4e16d fix: app icons saving (#2477) 2026-02-12 11:55:27 -08:00
Neal Shah 36b1499819 Ns/workers in stat attempt 2 (#2476)
* worker in stat

* add returnWorkers to stat

* workers in readdir
2026-02-12 10:45:22 -08:00
Neal Shah b209a94a80 dedup image models (#2475) 2026-02-12 10:39:23 -08:00
Het Savani 5cd731db3d feat(start-menu): add "Add to Desktop" option for all apps (#2386) 2026-02-11 21:59:14 -08:00
Daniel Salazar 1d22ab5fb7 cleanup: remove thumbnail service for client side thumbnails (#2468)
* cleanup: remove thumbnail service for client side thumbnails

* fix: emit thumbnail create event and not just use raw data

* fix: broken test
2026-02-11 17:12:47 -08:00
jelveh cbab7a30e2 Emit user signup success event 2026-02-11 16:53:31 -08:00
Daniel Salazar d7a3f61902 fix: false alarm from openrouter (#2470) 2026-02-11 16:49:42 -08:00
Neal Shah d024fdda0d Add cache tokens for grok 3 mini fast (#2469) 2026-02-11 16:49:12 -08:00
jelveh 292603af96 Merge branch 'main' of https://github.com/HeyPuter/puter 2026-02-11 15:14:02 -08:00
jelveh c2750f2ca1 Revert "Adds worker badge to .js files which have been registered as workers. Hovering badge shows popover with worker URL. File properties modal also shows clickable worker URL. (#2462)"
This reverts commit 50e2d275bc.
2026-02-11 15:13:56 -08:00
Daniel Salazar 0a594bdfc3 fix: metering alerts for missing costs (#2466) 2026-02-11 15:03:23 -08:00
Neal Shah 81c88c1434 add extra model details, update grok models (#2465) 2026-02-11 13:55:20 -08:00
Daniel Salazar afeac494ac feat: remove file cache service (#2464) 2026-02-11 12:57:10 -08:00
Miika Kuisma 50e2d275bc Adds worker badge to .js files which have been registered as workers. Hovering badge shows popover with worker URL. File properties modal also shows clickable worker URL. (#2462) 2026-02-11 12:02:10 -08:00
Daniel Salazar 512986880b feat: app icons in subdomain (#2461)
* feat: app icons in subdomain

* fix: imports

* fix: icon location
2026-02-10 19:04:15 -08:00
Neal Shah 56ee3d23df Ns/web dav range fixes (#2459)
* better calculation for ContentLength

* lets try that again
2026-02-10 16:11:01 -08:00
Neal Shah 4f84decdec fix tool call blank content (#2458) 2026-02-10 14:14:27 -08:00
Neal Shah e55829623f Revert "allow empty message (#2455)" (#2457)
This reverts commit 7880ade5d7.
2026-02-10 14:01:31 -08:00
Daniel Salazar 5e8ce3a021 fix: decrease large error log from wrong model (#2456)
* [PUT-471] feat: estimate and bill input for gemini imgaes :dev:

* fix: decrease large error log from wrong model
2026-02-10 13:36:35 -08:00
Neal Shah 7880ade5d7 allow empty message (#2455) 2026-02-10 12:53:56 -08:00
Daniel SalazarandProgrammerIn-wonderland 91afa2c356 [PUT-471] feat: estimate and bill input for gemini imgaes :dev: (#2453)
* [PUT-471] feat: estimate and bill input for gemini imgaes :dev:

* [PUT-472] add input/output costs to openai image models too

* npm version bump

* remove second url log

* fix gemini pro image

---------

Co-authored-by: ProgrammerIn-wonderland <[email protected]>
2026-02-10 12:52:33 -08:00
Reynaldi Chernando febcceb042 Fix auth type typo (#2454) 2026-02-10 10:00:53 -08:00
Neal Shah 4fb84bc117 add configurable backend (#2452) 2026-02-09 21:47:12 -08:00
jelveh 4a4ca331e5 Persist api_origin during auth flow if provided in url 2026-02-09 21:15:01 -08:00
KernelDeimos e5750d8eb7 fix: add explicit handling for access token in ACL
For reasons still unknown, there are circumstances where the permission
scanner denies permission to access tokens that should have been granted
permission. This change de-abstracts/flattens the logic for checking
access tokens so that it is easier to understand and maintain. The newly
implemented code does not suffer from the same issue.
2026-02-09 18:26:03 -05:00
Reynaldi Chernando e2ccaadf2f Fix gemini 3 pro image model name (#2450) 2026-02-09 12:24:40 -08:00
jelveh 102592bc18 Increase dialog popup height to 700 2026-02-08 23:10:05 -08:00
Daniel Salazar f9805dfffb fix: decrease log usage (#2449) 2026-02-08 22:26:23 -08:00
Daniel Salazar 380e72cad2 fix: axiosRequest log dumping b64 urls (#2448) 2026-02-08 21:47:04 -08:00
jelveh 53647a0f5b Update UIWindowEmailConfirmationRequired.js 2026-02-08 21:04:43 -08:00
stuffbymax 7c9bbd4336 Add shell reload instructions for nvm setup (#2446)
Added instructions to reload the shell after loading nvm. 
i forgot to add it because i am stupid
2026-02-08 19:31:46 -08:00
Nariman Jelveh 362e4d4636 Merge branch 'main' of https://github.com/HeyPuter/puter 2026-02-08 18:39:47 -08:00
Nariman Jelveh 32b83bae58 Preserve full redirect URL and forward reload flag 2026-02-08 18:39:36 -08:00
Daniel Salazar 7d84d7a46b fix: dev center emails (#2447) 2026-02-08 18:37:32 -08:00
stuffbymax 2eff1386d1 Create installation guide for Node.js and npm
Added comprehensive installation guide for Node.js and npm across various Linux distributions.
2026-02-08 15:31:48 -05:00
stuffbymax ac35b672de Add npm and node installation instructions
Added installation instructions for npm and node.
2026-02-08 15:31:48 -05:00
KernelDeimos f429d5f76a chore: fix eslint issues 2026-02-08 15:27:11 -05:00
Nariman Jelveh 74c23f609e Set email confirmation default to false
Change default behavior for email confirmation by initializing email_confirmation_required to 0 (not required) instead of 1. Remove the duplicate declaration and clarify the comment; existing logic still overrides this default (sets to 0 for matching pseudo_user/uuid_user and to 1 when event.requires_email_confirmation). Minor whitespace cleanup.
2026-02-08 12:02:23 -08:00
Nariman Jelveh d8a586ad66 Update UIWindowSignup.js 2026-02-08 10:56:59 -08:00
Zachary a875524a85 Update french translations (#2445) 2026-02-08 10:53:36 -08:00
Nariman Jelveh f9c35b4fae Improve email confirmation window layout and options 2026-02-08 10:32:01 -08:00
Daniel Salazar de7e831eff fix: gemini via openrouter models (#2438)
* fix: gemini

* feat: let logservice log to console

* fix: log

* feat: dev-center emails
2026-02-08 01:42:31 -08:00
Nariman Jelveh 4e88d28ecb Reload on signup unless embedded popup 2026-02-07 19:18:27 -08:00
Nariman Jelveh cfc56877e2 Store email confirmation flag on signup 2026-02-07 19:15:59 -08:00
Nariman Jelveh 873da5ae61 Honor event.requires_email_confirmation flag 2026-02-07 19:00:19 -08:00
Neal Shah ce96fb54ae Update error message for email confirmation (#2442) 2026-02-07 18:51:49 -08:00
Nariman Jelveh 934886d861 Add email confirmation dialog & checks 2026-02-07 18:51:11 -08:00
Neal Shah 8e3d285671 merge users (#2441) 2026-02-07 18:44:31 -08:00
Nariman Jelveh f6531d29f0 Send app token to opener and close popup
After a successful flow, fetch the user app token for the opener origin, cache the returned app_uid on window.host_app_uid, and post a 'puter.token' message to the opener containing success, msg_id, token, username, and app_uid. If the action is absent or equals 'sign-in', close the popup window. This enables parent windows to receive credentials in popup/embedded auth flows.
2026-02-07 17:58:24 -08:00
Nariman Jelveh 6be60f6973 Hide Turnstile captcha when showing signup 2026-02-07 17:39:22 -08:00
Neal Shah 262e31a6a6 Ns/service guard (#2440)
* add enforcer mechanism

* update better-sqlite3
2026-02-07 17:24:09 -08:00
Nariman Jelveh 48e37251df Return JSON errors for signup and handle in GUI 2026-02-07 16:41:59 -08:00
Neal Shah 03827e4197 Increase opus 4.6 max tokens (#2439) 2026-02-07 13:05:07 -08:00
KernelDeimos 020a64dbbd fix: ensure cache invalidation when verifying OTP
It is possible this broke after redis caching was employed because it
broke the expectation that assignments to attributes on cached objects
would remain for future accesses on said objects. This has not been
confirmed as the cause.
2026-02-06 23:42:47 -05:00
Neal Shah ac8456f8d3 Restrict apps from using /puterai/openai/v1 (#2435) 2026-02-06 18:43:18 -08:00
Neal Shah 28cedec9de chat_completions tool call fixes (#2434)
* chat_completions tool call fixes

* update chat completions test
2026-02-06 15:10:27 -08:00
Sanjeev 06fe07e384 fix: auto-collapse playground menu on mobile (#2430) (#2431)
* fix: auto-collapse playground menu on mobile (#2430)

* style: remove unused code reference after review
2026-02-07 01:30:19 +07:00
Reynaldi Chernando 10e1999304 Update puter-js readme for getAuthToken (#2417) 2026-02-06 17:49:30 +07:00
Daniel Salazar fbb2080a66 fix: don't use ai aggregators if we have the model ourselves (#2424)
* cleanup: eslint changes

* fix: don't use ai aggregators if we have the model ourselves
2026-02-05 16:30:45 -08:00
Daniel Salazar 5fdfae6087 fix: usage limited error handling (#2423) 2026-02-05 15:15:27 -08:00
Reynaldi Chernando da0907d3c5 Document getAuthToken for web based login (#2418) 2026-02-06 01:59:39 +07:00
Neal Shah 15bd2ec5ac opus 4.6 fix billing (#2422) 2026-02-05 10:21:09 -08:00
Neal Shah e3db664690 Ns/opus 4.6 (#2420)
* add opus 4.6

* remove log from webserver service
2026-02-05 10:08:52 -08:00
Neal Shah f8f134412f web-cdn-test (#2414)
* web-cdn-test

* fix tests
2026-02-04 16:29:27 -08:00
Daniel Salazar e9d0bdf19b feat: add alerting for usage abuse (#2413) 2026-02-04 13:08:18 -08:00
KernelDeimos b8bdc16a03 fix: move readdir-subdomains to ESM
This also causes the filename to have the extension `.mjs` instead of
`.js`, as well as an await added in FilesystemAPIService. Luckily
lifecycle events are async so this didn't cause any problems.

I add this change somewhat reluctantly because this _should_ be a
non-functional change. Technically adding the `await` in
FilesystemAPIService makes it possible (albiet incredibly unlikely) for
some subtle bug or change in behavior to be introduced.
2026-02-04 14:13:43 -05:00
KernelDeimos acb5fa512c clean: log removal and formatting changes 2026-02-04 14:13:43 -05:00
KernelDeimos 13fc737ca0 clean: remove debug logs added to /readdir-subdomains 2026-02-04 14:13:43 -05:00
KernelDeimos 1cda9b7ba8 dev: implement GUI behavior to fetch subdomains later
This change makes GUI invoke readdir without fetching subdomains, and
then fetch subdomains after. This allows displaying the directory items
sooner and then later populating the icons with glyphs to indicate if
there is an associated subdomain.

This was AI-assisted with manual modifications and bug fixes as
necessary.
2026-02-04 14:13:43 -05:00
KernelDeimos 0a694154b1 dev: add /readdir-subdomains endpoint
This endpoint can be called to get subdomain information after
performing a readdir without fetching subdomains.

This was AI-assisted with modifications and bug fixes as necessary.
2026-02-04 14:13:43 -05:00
KernelDeimos d94e3f45ac dev: add readdirSubdomains 2026-02-04 14:13:43 -05:00
KernelDeimos a4088023a3 dev: add parameter to exclude fetching subdomains
This parameter will allow readdir requests to not include subdomain
fetching, which will allow for the later effort of fetching subdomains
for directory listings in the gui with a separate request.
2026-02-04 14:13:43 -05:00
Daniel Salazar eead0fdfa9 fix: redis cache for user (#2409) 2026-02-03 17:47:43 -08:00
KernelDeimos 5433dde6d7 dev(extensions): [+] dev-socket
This extensions brings back the dev-socket functionality, which is
really important when testing things like broadcast, alarms, events, etc
; it saves a lot of time if you can invoke a command directly to the
backend.

This is an optional extension that will not be included in production
deployments. This is for development purposes only.
2026-02-03 19:39:07 -05:00
KernelDeimos de7fbced6b log: add debug logs for BroadcastService
These will be more important now that we're changing the transport for
broadcast messages between instances from websockets to webhooks.
2026-02-03 19:39:07 -05:00
KernelDeimos 3a7314d119 dev(backend): add send support for webhook broadcast
This still needs to be tested. I was going to test this using the `test`
command registered by BroadcastService that exists for this purpose but
`dev.sock` doesn't seem to be working anymore.

Why wasn't `dev.sock` working? Well... we deleted all the code that
makes it work. Why did we delete it? That question isn't a setup for my
next statement; I genuinely do not know. The whole point of dev.sock was
so we could remove the dev console but still maintain support for this
commandline interface that's absolutely needed for testing things that
aren't accesible directly from Puter's GUI.
2026-02-03 19:39:07 -05:00
KernelDeimos a40ec79d66 dev(tools): script to manually test broadcast webhooks
This tool makes it possible to manually test webhook support in
BroadcastService without running multiple Puter instances. This helps to
verify the functionality without setting up multiple Puter peers
locally.
2026-02-03 19:39:07 -05:00
KernelDeimos 47432853c4 dev(backend): add broadcast webhook endpoint
This commit adds the "receive" side of webhook support for
BroadcastService, which will eventually make broadcasting stateless and
not requiring of persistent connections.

Some specific considerations taken into account include:
- incremental nonce to prevent replay attacks
- request timestamp to prevent nonce-reuse after restarting
- HMAC signature to ensure authorized peer

Known limitations:
- if instances run indefinitely, eventually the nonce value would wrap
  around to zero and broadcasts would stop working. It is assumed that
  9 quintillion requests in the lifetime of an instance is reasonably
  impossible.
2026-02-03 19:39:07 -05:00
Daniel Salazar e938d5183a fix: limit open router expensive models for now (#2407)
* fix: limit open router expensive models for now

* fix: import extension
2026-02-03 14:43:15 -08:00
Neal Shah 665aee735b dav.puter.com CORS headers (#2406)
* webdav cors stuff

* if OPTIONS request just let it through
2026-02-03 14:13:42 -08:00
KernelDeimos cbde123aa1 fix(backend): undo part of 35461a0
It turns out this part of `35461a0` was not necessary to fix this issue,
and the code is still more correct if it falls true when the token's
authorizor has a permission granted.
2026-02-03 15:46:30 -05:00
KernelDeimos 8cd0a7f76b dev(backend): clear cache when revoking tokens 2026-02-03 15:46:30 -05:00
KernelDeimos 5fd1e9b6a6 dev(puter.js): add revokeReadURL 2026-02-03 15:46:30 -05:00
KernelDeimos 3ffe8eaf30 dev(backend): add revoke_access_token endpoint 2026-02-03 15:46:30 -05:00
Daniel Salazar 0234e34b46 Reapply: reverted redis migration changes (#2403) 2026-02-03 11:25:28 -08:00
Daniel Salazar baceb05b48 Revert "feat: replace serializible caches with redis instead of kvjs 🚀 (#2381)"
This reverts commit 7a47047c0d.
2026-02-03 12:43:00 -05:00
Daniel Salazar a4b90083e0 Revert "fix: missing redis changes (#2401)"
This reverts commit 07a389798d.
2026-02-03 12:43:00 -05:00
Daniel Salazar 07a389798d fix: missing redis changes (#2401) 2026-02-03 02:55:44 -08:00
Daniel Salazar 7a47047c0d feat: replace serializible caches with redis instead of kvjs 🚀 (#2381)
* wip: redis move

* fix: redis in extensions

* fix: bad isEMpty assignment

* fix: bad redis client config

* wip

* fix: redis keys cache

* fix: redis batch delete

* fix: change bulk cache times to allow for more instaces

* fix: broken tests
2026-02-03 02:18:31 -08:00
KernelDeimos 5250671b01 fix: range headers in file.js
Range header support was mostly incorrect, which brought to surface
undefined behavior in OnlyOffice which resulted in a request hanging.
This was the cause of the `pdf-editor` app hanging for a while when
opening it with a new file.
2026-02-02 20:08:02 -05:00
Daniel Salazar e2e4794bbc fix: alerting for metering (#2399) 2026-02-02 15:38:45 -08:00
Neal Shah fa76c21300 WebDAV post migration fixes (#2398) 2026-02-02 11:48:16 -08:00
jelveh 7aedeae991 Pass redirect_url to UIWindowSessionList 2026-02-02 09:24:21 -08:00
Neal Shah bf233c8fe0 Add X-EXPECTED-ENTITY-LENGTH for HTTP/2 connections on webdav for predictive file length (#2396) 2026-02-02 07:52:56 -08:00
Neal Shah 3d34b36159 Add more coersions to responses toolcalling support (#2395) 2026-02-02 07:45:56 -08:00
jelveh 6bd64808df Add redirect_url handling and adjust auth flow
Set and propagate a redirect_url for auth flows and use it when navigating after login/signup to avoid leaking sensitive data.
2026-02-02 00:16:35 -08:00
Neal Shah 7cce0705d3 Add back worker redeploy notification (#2394) 2026-02-01 21:57:23 -08:00
Daniel Salazar afbb76f95f fix: ai metering (#2393)
* fix: expose getUserService in extension typings

* fix: ai metering
2026-02-01 18:14:14 -08:00
Nariman Jelveh b15b466d36 Update TabAccount.js 2026-02-01 17:48:57 -08:00
Neal Shah 5216cccbce More Anthropic tool calling coercions (#2392) 2026-02-01 17:29:22 -08:00
Neal Shah 9e9a7b4dcf Fix tests for ChatAPIService (#2391)
* Fix tests for chatapiservice

* Anthropic Claude Provider fixes for toolcalling in OpenAI completions compatible service
2026-02-01 17:04:16 -08:00
Neal Shah 3a0f466ef6 OpenAI chat interface API concept (#2390) 2026-02-01 15:46:23 -08:00
Nariman Jelveh 6fbe83d982 Show cancelled state in auth window
When the user clicks Cancel in the authorization window, the code now disables action buttons and replaces the window body with a cancellation UI (header with icon, title, description and a message). Added corresponding English i18n keys (authorization_cancelled, authorization_cancelled_desc, authorization_cancelled_message) to provide localized text for the new cancelled state.
2026-02-01 15:34:02 -08:00
Neal Shah be290e2d3c fix typo gemini service (#2389) 2026-02-01 14:24:48 -08:00
Nariman Jelveh a92bbc4ec2 Disable dragging for AuthMe window 2026-02-01 13:43:46 -08:00
Nariman Jelveh 1e6521927f Add UIWindowAuthMe authorization dialog
Introduce a new UIWindowAuthMe component that displays a security-focused consent dialog for redirecting to third-party URLs with the user's auth token. Adds related i18n strings and integrates the dialog into initgui, replacing the previous UIAlert confirm flows; when approved (resolves true) the token is appended to the redirect URL and navigation proceeds. Changes: adds src/gui/src/UI/UIWindowAuthMe.js, updates src/gui/src/i18n/translations/en.js, and imports/uses the new dialog in src/gui/src/initgui.js.
2026-02-01 13:26:13 -08:00
Nariman Jelveh 4b8c46efc8 Add UI to view and copy auth token
Introduce a new UIWindowCopyToken component to display the user's auth token with a copy-to-clipboard button and confirmation message. Integrate the token UI into the account dashboard (TabAccount) by adding an auth token card and click handler to open the window. Add corresponding i18n keys (auth_token, token_copied, copy_token_message, copy_token_description) and import the new window in initgui. Also wire the global action 'copyauth' to show the token dialog and adjust session/login flow so the session list/login windows respect the action (avoid auto-reload when showing the token dialog). Minor UI string cleanup to use i18n('approve') directly.
2026-02-01 13:02:25 -08:00
Nariman Jelveh bfea66a1d6 Serve HTML success page on auth callback
Replace the plain text response with a styled HTML confirmation page for the local authentication callback. The handler now sets Content-Type to text/html and returns a responsive, animated "Authentication Successful" page (with checkmark graphic and Puter branding) while preserving the existing token extraction from the callback URL's search params.
2026-02-01 12:34:26 -08:00
Neal Shah 22606f29b2 getAuthToken on node package (#2388) 2026-02-01 12:03:30 -08:00
Nariman Jelveh 97cf80b068 Support authme action from URL query
Read the 'action' value from URL query params and handle a new 'authme' action. When 'authme' is present, prompt the user to approve redirecting to the provided redirectURL; if approved, append the current auth token as a 'token' query parameter and navigate to that URL. The prompt is shown in two places (after auth data is updated and before loading the desktop) to cover different entry flows. Also removed a stray blank line.
2026-02-01 11:51:29 -08:00
Daniel Salazar 114fbff2cd fix: expose getUserService in extension typings (#2385) 2026-01-31 13:19:28 -08:00
Daniel Salazar 7a9302f479 [PUT-487] fix: set max-min on app-user-count queries 🐛 (#2384) 2026-01-31 00:52:53 -08:00
Neal Shah af62835d48 video model costs (#2383) 2026-01-30 12:03:36 -05:00
Neal Shah aa508a74dc puter x-expected-entity-length for site (#2379) 2026-01-30 11:34:32 -05:00
Daniel Salazar e1b52a9828 cleanup: remove informationService in favour of existing helper methods and logic (#2374) 2026-01-29 17:25:28 -08:00
velzieandNeal Shah 1e1de413c5 Add canonical puterId to image provider models (#2322)
* add canonical puterId to image provider models

* return fully qualified puterIds in AIImageGenerationService.list()

* add aliases to openai image models

---------

Co-authored-by: Neal Shah <[email protected]>
2026-01-29 14:47:51 -05:00
Daniel Salazar de14bf7273 fix: match override properly (#2373) 2026-01-28 22:45:11 -08:00
Devansh DubeyandReynaldi Chernando fecd67a196 fix(resume-analyzer): add preprocessing for DOCX and TXT files (#2359)
* Update ai-resume-analyzer.html

* Cleanup comments and update to haiku 4.5

---------

Co-authored-by: Reynaldi Chernando <[email protected]>
2026-01-29 13:38:35 +07:00
Daniel Salazar 5a8e9063ec fix: map again (#2372) 2026-01-28 22:34:45 -08:00
Daniel Salazar 4aa2039956 fix: cost mapping for together ai from openai sdk (#2371) 2026-01-28 22:20:59 -08:00
Daniel Salazar 40f805f64b [PUT-475] fix togetherai chat being broken + deprioritize them 🐛 (#2369) 2026-01-28 22:04:06 -08:00
Daniel Salazar 6daac664c6 fix: remove rate limit await on writes (#2368)
* otel: logs and spans for dynamo db

* fix: imports

* fix: add more logging

* fix: import paths

* fix: console log

* fix: better logs

* fix: logging

* fix: remove rate limit await on writes

* cleanup, remove uneeded spans in ddb client
2026-01-28 16:13:53 -08:00
KernelDeimos 35461a0345 fix: app-under-user access token ACL
There were a couple issues with ACL where access would be denied to app
tokens within access tokens, caused by:
- incorrect recursion: only `false` was considered when in fact the
  result from the recursive call is appropriate
- files without a known path are incorrectly handled, which can happen
  when iterating over parent directories
2026-01-28 16:00:01 -05:00
Arya DasguptaandReynaldi Chernando 0028b41fe3 docs: add example for streaming with function calling (#2365)
* docs: add example for streaming with function calling

* Minor fix and add example to playground

---------

Co-authored-by: Reynaldi Chernando <[email protected]>
2026-01-28 18:01:28 +07:00
jelveh fc8117df1e add login indicator with animated spinner 2026-01-27 23:39:18 -08:00
Daniel Salazar 89c49902b6 otel: add spans to all kv methods (#2358) 2026-01-27 19:16:04 -08:00
Daniel Salazar 4183d5de06 [PUT-466] fix: count request costs in openrouter models with request cost present (#2356) 2026-01-27 18:32:43 -08:00
Daniel Salazar cc5285f88a fix: only rate limit login when failed (#2355) 2026-01-27 18:24:05 -08:00
KernelDeimos e7443338fb fix: more reliable 404 responses for .api endpoint
This fix avoids some situations where a non-existing route hangs instead
of responding with 404.
2026-01-27 15:46:28 -05:00
KernelDeimos a8dc62ef80 fix: header resend issue with catch-all handler
WebDAVService catches `/*`, which shouldn't be a problem because it is
on the `dav.` subdomain - however, other middlewares were being invoked
before the subdomain check. Thanks to the `'route'` parameter for the
`next` function we can handle subdomain checks in a more reliable way
2026-01-27 15:46:28 -05:00
Lui DuarteandDaniel Salazar bbe6f9dc27 Feat: Add system info (Client + Server metrics) (#2311)
* Add ststem info to user options extensions - Add UIWindowSystemInfo, add ui sections for client and server, add basic getClientinfo function

* Fix typo

* Replace accidentally deleted es.js file

* Refactor client information to be consistant with project standard

* Complete Client information in ststem information window

* Remove console logs

* Add basic api functionality for getting server system information

* Structure return data from system server information endpoint | Add copyright to UIWindowSystemInfo

* Add function to format server system api data | Add loading element to server container while waiting for data | Complete System Information

* fix: disallow non admin for backend + move to extensions

---------

Co-authored-by: Daniel Salazar <[email protected]>
2026-01-27 10:29:02 -08:00
ProgrammerIn-wonderland bbe1242eff Move webdav to dav.puter.com 2026-01-27 20:31:32 +05:30
KernelDeimos 404a5e9050 dev: fix issues with dns lookup, remove fallback
This is the effort remaining to bring back URL parameters to drivers
which support them. This fixes the implementation for DNS resolution
resulting in errors for undefined IP addresses when DNS resolution is
successful.
2026-01-26 15:01:22 -05:00
KernelDeimos 72078d3bc1 wip: try to resolve DNS with cloudflare DNS 2026-01-26 15:01:22 -05:00
KernelDeimos b935006ee7 Revert "fix: disable requests from server in two services"
This reverts commit de77b11954.
2026-01-26 15:01:22 -05:00
Daniel Salazar 66a3af69c9 fix: suggested apps breaking (#2343) 2026-01-26 10:17:48 -08:00
Seril Evanjaline S 70454521ef fix: skip CI tests when only docs are changed (#2335) (#2338) 2026-01-25 00:05:31 +07:00
Daniel Salazar 8bb4dec231 perf: don't fetch b64 icon for apps always, and lru suggestedApps (#2336)
* perf: don't fetch b64 icon for apps always, and lru suggestedApps

* fix: fallback to default file icon if present
2026-01-23 20:57:12 -08:00
Reynaldi Chernando 143cbdce23 Add info about usage data scope for docs (#2334) 2026-01-24 10:18:54 +07:00
Daniel Salazar 2402e49cce fix: log format (#2333) 2026-01-23 13:47:02 -08:00
Daniel Salazar 2287704102 perf: batch readdir suggested apps into single big query (#2332)
* perf: batch readdir suggested apps into single big query

* fix: cleanup fucntions to go through single entry
2026-01-23 12:24:02 -08:00
KernelDeimos de77b11954 fix: disable requests from server in two services 2026-01-23 08:40:00 -05:00
ProgrammerIn-wonderland 5922f36358 fix gemini cost key 2026-01-23 18:45:10 +05:30
ProgrammerIn-wonderland 17e5edd643 Video model details 2026-01-23 16:01:50 +05:30
Nariman Jelveh 894bb939b1 Add aspect ratio resize options to window menu
Introduced a resize_window_to_aspect_ratio function and added 'Advanced' menu items to allow resizing the window to 16:9, 4:3, or 9:16 aspect ratios. This enhances user control over window dimensions for specific use cases.
2026-01-22 15:59:07 -08:00
Daniel Salazar d42f9b0e10 fix: disable bad token checks? (#2326) 2026-01-22 15:38:26 -08:00
Daniel Salazar d3a27be88e fix: dedup get_apps app requests (#2325)
* fix: dedup get_apps app requests

* fix: WSPushService errors

* fix: error messages
2026-01-22 11:07:42 -08:00
ProgrammerIn-wonderland 2a8ec97c09 add safety checks for worker updates 2026-01-22 18:53:59 +05:30
Daniel Salazar e9631b5a04 perf: dedup and cache get_apps in puter gui, also add more app batching in backend (#2319)
* perf: dedup and cache get_apps in puter gui

* feat: batch more apps
2026-01-21 23:31:49 -08:00
Daniel Salazar fbe87369f5 fix: add back test (#2317) 2026-01-21 21:37:36 -08:00
KernelDeimos b98f1be5fb Revert "feat(data-access): move puter.js read to app driver"
This reverts commit 2139551abf.

It looks like this breaks dev-center because the file associations
aren't properly sent. I will need to investigate this.
2026-01-22 00:35:56 -05:00
jelveh 70f58b08eb Update label from 'Publish Web Pages' to 'Hosting API' 2026-01-21 20:50:52 -08:00
KernelDeimos 20b5662704 dev(backend): make data-access an essential module 2026-01-21 23:00:45 -05:00
KernelDeimos 2139551abf feat(data-access): move puter.js read to app driver
This is the first functional migration from ths `es:app` driver to the
`app` driver. Any call to `puter.apps.get` will go through `es:app`
after this change.
2026-01-21 23:00:45 -05:00
jelveh 0b55d19f89 Add initial Puter.js documentation site 2026-01-21 19:39:01 -08:00
Daniel Salazar 6e9e5371c8 fix: batch fetch get apps for launch apps and recommended apps (#2315)
* wip: batch fetch get apps for launch apps and recommended apps

* fix: boot issues

* fix: bad refresh app cache

* tmp: remove test for now since can't mock db call
2026-01-21 18:17:15 -08:00
KernelDeimos 17b5ff4cb5 Revert "feat(data-access): move puter.js read to app driver"
This reverts commit f3100eca59.
2026-01-21 12:33:25 -05:00
KernelDeimos f3100eca59 feat(data-access): move puter.js read to app driver
This is the first functional migration from ths `es:app` driver to the
`app` driver. Any call to `puter.apps.get` will go through `es:app`
after this change.
2026-01-21 12:25:59 -05:00
Daniel Salazar 929fc6956e [PUT-456] fix: delete apps from marketplace when deleting anywhere else (#2310) 2026-01-20 23:42:24 -08:00
Daniel Salazar 4e6d9c9f33 perf: improve tel + decrease logs (#2309)
* perfmon: lower healthcheck status cache, add kv health signal

* perf: improve tel + decrease logs

* logs
2026-01-20 20:21:08 -08:00
KernelDeimos bf84ff4b10 config(perms): allow apps service to all users 2026-01-20 16:28:22 -05:00
KernelDeimos 3fe304ebac dev(data-access): re-add protected app support
Adds support for the "protected apps" feature to the new `apps` driver
that will replace the existing `es:apps` driver.
2026-01-20 16:28:22 -05:00
KernelDeimos d08a828226 test(data-access): avoid SQL error in app:es
It turned out this error was not coming from `app`, but it was coming
from `app:es` due to a pre-existing issue. Since these tests are meant
to compare the resulting behavior and `app` can handle this case while
`app:es` cannot, the best course of action is to avoid invoking the
issue and only test the intended behavior.
2026-01-20 16:28:22 -05:00
KernelDeimos 768a35e9b5 fix(data-access): read response regression
In `es:app`, attempting to read an app that doesn't exist results in an
error being thrown. This commit updates `app` to have the same behavior.
2026-01-20 16:28:22 -05:00
KernelDeimos 5b33beb6a1 test(data-access): check for error, not undefined
Check for error when an app doesn't exist, because this is the behavior
`es:app` already exhibits.
2026-01-20 16:28:22 -05:00
KernelDeimos 519ad336ba test: differences between es:app and app
Add tests for all the CRUD operations and related edge cases in `app` to
ensure the behavior is the same as `es:app`. These tests detect 3 issues
across 4 failing tests.
2026-01-20 16:28:22 -05:00
KernelDeimos bd416b0190 test: ensure kv global is always available
This is comitted separately from the commit for AppService.comp.test.js
that will follow because it interacts with all other test cases. It did
not cause any issue based on what I observed, but I'm still wrapping it
in a separate commit in case we need to revert or change it later.
2026-01-20 16:28:22 -05:00
KernelDeimos 503c1a4bb8 test: refactor AppService comparison test 2026-01-20 16:28:22 -05:00
KernelDeimos 1c438107aa test(data-access): verify and fix database state compare
An "anti-test" (test that should fail) was created to verify that a test
fails when apps are different. This revealed a problem in the original
logic of comparing the database state (UUIDs don't need to be, and will
not be, identical; they need to be excluded from comparison). This
commit contains the new test and fixes the existing test case, which was
passing because this problem caused a false-negative.
2026-01-20 16:28:22 -05:00
KernelDeimos b17486b1b4 fix(backend): fix context dual-instance problem
The file `context.js` causes problems in unit tests because vitest does
not play nice with CJS, especially when both CJS and ESM are in use such
as in our repository.

Given that it is not feasible to solve the underlying interoperability
issue, I have elected to make `context.js` a singleton in `Symbol.for`.
This worked very well with `helpers.js`.
2026-01-20 16:28:22 -05:00
KernelDeimos be8b5ef70a fix(backend): singleton in helpers for testability
The `helpers.js` file has two instances when testing with vitest.
Usually this can be solved by creating an "import bridge" file - another
CJS file that imports the desired CJS file and re-exports it so that the
`require` mechanism for caching modules is used instead of the `import`
mechanism for caching modules. Unfortunately in my most recent test
cases this does not work. I do not know why this does not work. However,
without doing a deep-dive into the internals of vitest I can at least
see that the only state in helpers is for providing `services` as a
pseudo-global, so a hack with `Symbol.for` solves everything.
2026-01-20 16:28:22 -05:00
KernelDeimos 7531a94687 clean(data-access): remove bad fixes and simplify 2026-01-20 16:28:22 -05:00
KernelDeimos 01b50b66f2 test(data-access): regression test for es:app vs app
This test was very difficult to get working because of issues
initializing the context under vitest. After a lot of effort and trying
to narrow down the issue in many ways that didn't work, I eventually
found that manually setting the storage and calling run on the
AsyncLocalStorage object got it working. I'm currently unsure if this is
specific to vitest or not. We don't seem to do this in Puter's kernel
but everything works fine in the typical runtime. Maybe this is
side-effect of otel's own use of AsyncLocalStorage.
2026-01-20 16:28:22 -05:00
KernelDeimos 3a268e6f16 test(data-access): add tests for delete method 2026-01-20 16:28:22 -05:00
KernelDeimos 3fab0ca6a2 dev(data-access): implement .delete() method 2026-01-20 16:28:22 -05:00
KernelDeimos 1e3b704ea8 fix(data-access): add guard for app actors 2026-01-20 16:28:22 -05:00
KernelDeimos 25d23d687c dev(data-access): add simplified upsert method
This is a naive implementation of the `.upsert()` method that simply
calls `.create()` or `.update()` depending on whether or not the app
already exists.
2026-01-20 16:28:22 -05:00
KernelDeimos c47c52a298 test(data-access): test .create() and .update()
Primarily these tests were AI generated an then checked over for sanity.
These tests are good unit tests to avoid regressions as a result of
changes to this code but are not sufficient to test for regressions
introduced by this new implementation that will replace `es:app`.
2026-01-20 16:28:22 -05:00
KernelDeimos bec39e578f dev(data-access): implement .create() method 2026-01-20 16:28:22 -05:00
KernelDeimos fc03fafab9 dev(data-access): misc improvements to .update()
DRY some redundant code and use guard clauses where applicable.
2026-01-20 16:28:22 -05:00
KernelDeimos 464241e743 dev(data-access): implement .update() method 2026-01-20 16:28:22 -05:00
KernelDeimos 7c5639005b test(data-access): app .select() and .read()
Fixes are also included for a couple issues that were found:
- `null` being included in extensions list
- property called `user_owner` instead of `owner`
2026-01-20 16:28:22 -05:00
KernelDeimos ec0b333ad7 dev(data-access): implement .read() method
Most of this implementation matched `.select()` which saved time. The
common behavior can be factored out, but since the purpose of this
refactor is to flatten everything as much as possible I'm going to leave
the duplicated code and make a note to do this later.

The challenging part was `#build_complex_id_where()`, which is the
equivalent to the `fetch_based_on_complex_id_()` method in
EntityStoreService. This allows `uid: app-UUID-OF-APP` and `id: { name:
'editor' }` to both work.
2026-01-20 16:28:22 -05:00
KernelDeimos 2bb036616f dev(data-access): app select icon_size` param
Adds the `icon_size` parameter to the `.select()` method on the new
non-ES/OM implementation.

When adding the necessary `params` parameter to the `.select()`
method, it was noticed that the `predicate` parameter did not have a
default value - potentially causing a regression; a default value was
set for both `params` and `predicate`.
2026-01-20 16:28:22 -05:00
KernelDeimos 7cd7be7af5 dev(data-access): add filetype associations 2026-01-20 16:28:22 -05:00
KernelDeimos 3839afd805 dev(data-access): add app owner relationship
It turns out self-referencing tables add some nuances to what is and
what isn't ambiguous in SQL queries, so getting this right took a little
longer than expected. Following the entire chain doesn't seem to be
possible so a compromise is made by only traversing one level of depth.
(you can the uid of the owner of the app, but not the uid of the owner
app's own owner)
2026-01-20 16:28:22 -05:00
KernelDeimos 1a8130b8fd dev(data-access): add owner object to app select 2026-01-20 16:28:22 -05:00
KernelDeimos 6592f87882 dev(data-access): coerce boolean values from db
Adds `as_bool` utility function for boolean values from MySQL and
Sqlite, based on the previous implementatoin for ES/OM.
2026-01-20 16:28:22 -05:00
KernelDeimos a85d2b7098 fix(perms): fix revokePermission for "flat" impl
The "flat" implementation of permissions was broken because
revokePermission tried to delete entries by calling `.set` with an
option called "delete". I'm not sure if this has ever existed on the
puter-kvstore interface, so it's weird that it was called like that.
2026-01-20 16:07:10 -05:00
KernelDeimos 79fda7b8c2 fix(backend): update protected app perm implicator
The permission implicator for protected apps was written before changes
to the permission system that affect the conditions under which a user
is allowed to grant and revoke permissions; specifically this is the
`manage:` set of permissions, which now needs to be granted to the owner
of a protected app.

Additionally, the "level" component of the permission is ignored because
the owner of a protected all is implied to have all the permissions
pertaining to that protected app.
2026-01-20 16:07:10 -05:00
jelveh 6805c90252 Remove unnecessary logging in get_app function
Eliminated redundant cache and info log statements from the get_app helper to reduce log noise and improve code clarity.
2026-01-20 11:45:06 -08:00
Neal Shah 13578e81e6 gemini 2.5/3 no preview (#2306) 2026-01-20 11:43:01 +05:30
KernelDeimos 3da318129c fix(puter.js): check for uuid before relative path 2026-01-19 19:55:04 -05:00
Daniel Salazar 35797536ba feat: usage endpoints, allow appName (#2303) 2026-01-19 15:15:06 -08:00
KernelDeimos c715057065 feat(puter.js): make home directory default cwd
Make the home directory (AKA "~") the default CWD for puter.js, making
relative paths work in environments other than app environments (i.e.
gui or worker environments).
2026-01-19 13:29:28 -05:00
Neal Shah e95aa81e00 OpenAI web_search support (#2299) 2026-01-19 00:01:47 +05:30
Daniel Salazar f9888e6705 feat: paginated list (#2296)
* feat: paginated list

* fix: kv list
2026-01-16 16:16:47 -08:00
Neal Shah bd57f7a221 Add GPT 5.2 Codex (#2293) 2026-01-16 22:52:28 +05:30
Nariman Jelveh 6b45667220 Revert "feat(gui): add keyboard shortcuts guide dialog (#2278)" (#2288)
This reverts commit 340d932ae1.
2026-01-15 15:35:13 -08:00
Rahul aswal 340d932ae1 feat(gui): add keyboard shortcuts guide dialog (#2278)
* feat(gui): add keyboard shortcuts guide dialog

* feat(gui): add dedicated keyboard shortcuts dialog
2026-01-15 15:34:40 -08:00
KernelDeimos 21d02e7dae fix(backend): status code check and handle HLMkdir
Fix the status code handling in hl_mkdir and handling to the HLMkdir
operation itself. This effectively fixes #1603.

Resolves #1603
2026-01-15 18:32:08 -05:00
KernelDeimos 452d1de92e refactor: MkTree and QuickMkdir parent dir check
Extract common behavior from MkTree and QuickMkdir to a separate method
which is user by both operations.
2026-01-15 18:32:08 -05:00
KernelDeimos f125830fba fix(backend): handle ll_mkdir exists race condition
Handle a race condition affecting mkdir operations with the
`createMissingParents` option enabled. When creating a directory because
this option was specified, errors because the directory already exists
are likely due to a race condition and should not be propagated to the
client but instead handled by using the directory that's already there.
2026-01-15 18:32:08 -05:00
KernelDeimos f9a3e86fe9 fix: normalize file object in /writeFile 2026-01-14 18:21:46 -05:00
KernelDeimos 5e4dfbc963 fix: attempt coercion to fix vscode corruption 2026-01-14 15:05:17 -05:00
sn-o-w c367d00ce4 Revise README.ro.md for updates and corrections (#2280) 2026-01-14 10:03:50 -08:00
Daniel Salazar 0b9863814c fix: shard app usages properly by user (#2279) 2026-01-13 20:32:46 -08:00
Sauhbagya Prasad 529a3d026b Improve UI for App Deployment Options in Dev Center (#2266)
* Improve UI for App Deployment Options in Dev Center

- Added CSS styling for deployment option cards
- Implemented active state switching between deployment methods with guardrails
- Abstracted saveEditApp for reuse across Deploy and Edit tabs
- Added error handling for invalid URLs in the Deploy tab

* updated mode's description and fixed function's error

* updated by npm install

* Revert "updated by npm install"

This reverts commit 82cd962f62.

* in url mode the deploy button is enabled by default
2026-01-13 10:54:08 -08:00
jelveh 07f3387363 Add CAPTCHA required message to English translations
Introduced a new translation key 'captcha_required' with the message 'Please complete the CAPTCHA verification' in the English locale file.
2026-01-13 10:19:31 -08:00
Daniel Salazar cdb422659c feat: more extension controller decorators (#2272) 2026-01-13 00:32:03 -08:00
Neal Shah f4c37d4cf4 prevent signout from workers (#2276) 2026-01-13 13:18:06 +05:30
Neal Shah edcfe63131 no_extra_params in together service to prevent defaults from being specified (#2275) 2026-01-13 13:08:30 +05:30
Neal Shah 989ee58f05 Retry for openrouter on max_tokens overage (#2274) 2026-01-13 12:30:05 +05:30
dependabot[bot] 237a96c706 chore(deps): bump qs and body-parser
Bumps [qs](https://github.com/ljharb/qs) and [body-parser](https://github.com/expressjs/body-parser). These dependencies needed to be updated together.

Updates `qs` from 6.13.0 to 6.14.1
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.13.0...v6.14.1)

Updates `body-parser` from 1.20.3 to 1.20.4
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/1.20.3...1.20.4)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.14.1
  dependency-type: indirect
- dependency-name: body-parser
  dependency-version: 1.20.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-01-12 19:43:04 -05:00
Neal Shah bb6b40be7b Support getDeveloperProfile with no arguments (#2270) 2026-01-12 16:06:45 +05:30
Neal Shah 8e6d3d8d9f Make puter boot on windows (#2269) 2026-01-12 15:26:53 +05:30
Neal Shah 04901a7cd1 provide safety_identifier in addition to user (#2268) 2026-01-12 13:24:30 +05:30
Talasu_DeepakandNariman Jelveh 44b2a0bd9a Add README for Puter localization and setup (#2043)
* Add README for Puter localization and setup

This README provides an overview of Puter, including installation instructions, system requirements, and support information.

* Update README.od.md

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2026-01-11 16:41:50 -08:00
Nariman Jelveh c051a6caa6 Add automatic thumbnail generation to file uploads in GUI (#2261)
Introduces thumbnail generation for image files during upload operations. Thumbnails are generated client-side if enabled via the `generateThumbnails` option, and are included in file metadata and operation payloads. This enhances file previews and user experience in the file system.
2026-01-11 09:38:33 -08:00
KernelDeimos 8e418a11a1 fix(backend): race condition in hashing_stream
Based on a stack trace from production and manual static analysis, it
appears that a race condition occurs within hashing_stream
intermittently. The conditions that cause this issue might be heavy
backpressure. The source stream emits the 'end' event before
stream.Transform's transform callback has had a chance to process all of
the chunks, which results in an incorrect order in calling methods on
the `typeof crypto.createHash()` object.

It would appear that `source.pipe(stream)` is not able to propagate
errors from Transform because the chain was simply broken and upload
would get stuck (if this was indeed the cause of upload getting stuck,
which seems likely but not conclusive)
2026-01-09 20:02:50 -05:00
Daniel Salazar d64bd21a99 feat: give referrals (#2262) 2026-01-09 16:48:49 -08:00
Neal Shah 5aa25bae5f Model singularity (#2255)
* model naming singularity

* model singularity pt2

* Remove incorrect assumption check which breaks openrouter:openai/gpt-5-image
2026-01-09 16:18:54 -08:00
Daniel Salazar 13f7d7b502 fix: husky (#2260) 2026-01-09 15:41:37 -08:00
Daniel Salazar f88ca5d4bd feat: kv.remove feature to remove nested elements or list indices (#2258)
* chore: update npm version

* feat: kv.remove feature to remove nested elements or list indices

* chore: update npm version
2026-01-09 15:10:02 -08:00
KernelDeimos 353f163f46 chore(backend): upgrade nodemailer 2026-01-09 17:54:38 -05:00
KernelDeimos e07d1ae4af dev(backend): limit thumbnail size from client
There was a configuration parameter for this but it isn't being used and
has the incorrect name in `config.js`. I decided to keep the old check
here anyway because having support to configure a lower size limit could
come in handy.

I set the limit to 2MiB through the following logic:
- largest icon size I've ever heard of is 512px
- 512*512*4 (4 color channels) is 1048576 (1MiB)
- increase to next MiB just to be safe
2026-01-09 16:36:47 -05:00
KernelDeimos b5ae9181f1 dev(puterjs): add thumbnail parameter to puter.js 2026-01-09 16:36:47 -05:00
KernelDeimos 645d60a84b dev(filesystem): add thumbnail parameter 2026-01-09 16:36:47 -05:00
Daniel Salazar 23d7b751b9 feat: new kvstore operatios for more granular updates 🚀 (#2254) 2026-01-09 12:20:54 -08:00
dependabot[bot] 53133e2623 chore(deps): bump qs and express
Bumps [qs](https://github.com/ljharb/qs) to 6.14.1 and updates ancestor dependency [express](https://github.com/expressjs/express). These dependencies need to be updated together.


Updates `qs` from 6.13.0 to 6.14.1
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.13.0...v6.14.1)

Updates `express` from 4.21.2 to 4.22.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.2...v4.22.1)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.14.1
  dependency-type: indirect
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-01-09 14:12:33 -05:00
Nariman Jelveh 092d8fe632 Revert "doc: add README.md for GUI directory (#2021)" (#2253)
This reverts commit 8b324a8950.
2026-01-08 10:06:30 -08:00
SuryaGanesh284 8b324a8950 doc: add README.md for GUI directory (#2021)
Added README.md for the Puter GUI with details on structure, development, contributing, and resources.
2026-01-08 10:06:04 -08:00
Nariman Jelveh a0c2ac4d07 Add 'Open in AI' option to item context menus (#1974)
* Add 'Open in AI' option to item context menus

* Add new AI-related English translations
2026-01-07 22:49:31 -08:00
jelveh dade7a6cba Add preview images upload for app listings 2026-01-07 17:32:24 -08:00
Nariman Jelveh 3f934c5f16 Remove ComplainAboutVersionsService and related code (#2179)
Deleted the ComplainAboutVersionsService and its registration in SelfHostedModule, as well as cleaned up related service mappings in DriverService. This streamlines the codebase by removing the version complaint feature.
2026-01-07 16:55:55 -08:00
Eswar Venkata Ram Charan Seeram 77fc14b743 i18n(de): polish German translations & fix typos (Fixes #1532) (#2009)
* i18n(nn): fix typos & finalize translation cleanup

* i18n(de): polish German translations & fix typos (Fixes #1532)
2026-01-07 15:30:06 -08:00
dependabot[bot] 05a2c69d43 chore(deps): bump jws from 4.0.0 to 4.0.1
Bumps [jws](https://github.com/brianloveswords/node-jws) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/brianloveswords/node-jws/releases)
- [Changelog](https://github.com/auth0/node-jws/blob/master/CHANGELOG.md)
- [Commits](https://github.com/brianloveswords/node-jws/compare/v4.0.0...v4.0.1)

---
updated-dependencies:
- dependency-name: jws
  dependency-version: 4.0.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-01-07 16:23:04 -05:00
Daniel Salazar b1e7bc5fca feat: method for updating users metering directly (#2252)
* chore: cleanup ts extensions controller

* feat: method for updating users metering directly
2026-01-07 12:53:00 -08:00
Het Savani e20daf276b Fix/explorer cursor grab on click (#2176)
* Fix sidebar cursor grabbing on click

* Final commit
2026-01-07 10:33:04 -08:00
Daniel Salazar 754e820403 fix: openrouter costs always being 0 (#2250) 2026-01-07 09:11:44 -08:00
Daniel Salazar 7f76bff3f3 fix: more strict metering limits, disable ambigious openrouter one (#2249) 2026-01-06 23:57:03 -08:00
Daniel Salazar 2ef9aa3fb1 fix: add catch all for minimum usage amounts (#2248)
* ts: extension type updates

* fix: add catch all for minimum usage amounts
2026-01-06 23:09:29 -08:00
Reynaldi Chernando 2c84cd4cfa Remove flux schnell-free (#2243) 2026-01-06 22:39:01 -08:00
Daniel Salazar 93afbe4dd9 fix: ts extensions (#2247) 2026-01-06 18:03:38 -08:00
Daniel Salazar 1642431615 lint: hook for precommit (#2245) 2026-01-06 16:45:05 -08:00
Om vataliya 677426cbe7 fix: Enable godmode for dev-center to open worker files in editor (#2224)
Fixes #2218

The DEV Center was unable to open worker files in the text editor because
it lacked godmode permissions. The file_paths parameter in puter.ui.launchApp
requires the calling app to have godmode=1 in order to work.

Changes:
- Added database migration 0044_dev-center-godmode.sql to set godmode=1
  for the dev-center app (uid: app-0b37f054-07d4-4627-8765-11bd23e889d4)
- Updated SqliteDatabaseAccessService.js to include the new migration

This allows DEV Center to successfully pass file paths when launching the
editor app, fixing the issue where clicking on a worker file path resulted
in an empty editor window.
2026-01-06 16:19:29 -08:00
KernelDeimos a5bbc7e95b fix: issues creating shortcuts
There were two different things here:
- invalid requests have an ambiguous error message
- migration of PuterFSProvider to an extension caused an issue
  for shortcut creation in some flows

Closes #2200
2026-01-06 19:09:48 -05:00
KernelDeimos 0ecae43d2f clean: remove dead code in hl_mkdir
Remove a method in hl_mkdir which was determined to not be referred to
anywhere. hl_mkdir was re-tested to verify that this did not cause a
regression.
2026-01-06 19:09:48 -05:00
KernelDeimos d091b20b6a dev: improve error message for dest_does_not_exist
This error message was ambiguous for mkdir operations where a shortcut
target is specified for hl_mkdir. The message looks like it's referring
to the shortcut target but really it is referring to the parent
directory for the new directory that will be created.
2026-01-06 19:09:48 -05:00
KernelDeimos 630f76d8b4 test: add automated test for subdomain redirect
This merits a test because changes to how `puter.site` works in the
future could easily break this redirection, and maintaining this
redirect is important to us.
2026-01-06 18:31:39 -05:00
KernelDeimos 4d60168d2f feat!: implement redirect for hosting base domain
Redirect the subdomains `""` and `"www"` to a configurable URL, which is
by default `https://developer.puter.com/static-hosting/`.

This is potentially a breaking change for local instances that have a
subdomain called "www". Users hosting their own Puter may want to be
aware of this.

Closes #2214
2026-01-06 18:31:39 -05:00
Reynaldi Chernando 678363b0ba Init fix FS types (#2201) 2026-01-06 10:18:01 -08:00
jelveh 7ef57d5052 Increase PENDING_QUERY_TTL to 10 seconds 2026-01-05 12:50:34 -08:00
jelveh fa402f9785 Add gpt-5.1-codex-max support 2026-01-03 21:28:09 -08:00
jelveh f9925c0337 Increase PENDING_QUERY_TTL to 5 seconds 2026-01-03 20:02:08 -08:00
jelveh 987effc5ec Revert "Remove debug logs and improve query coalescing timeout (#2241)"
This reverts commit 71bee556f6.
2026-01-03 19:34:30 -08:00
Nariman Jelveh 71bee556f6 Remove debug logs and improve query coalescing timeout (#2241)
Removed unnecessary console.log statements from PuterFSProvider.js and WebServerService.js. Increased PENDING_QUERY_TTL to 3 seconds and added a timeout mechanism for coalesced queries in get_app to prevent indefinite waiting.
2026-01-03 19:28:40 -08:00
Soumyabrata Bhattacharjee 363b798026 Update first-run-issues.md with dnf5 instructions (#2239)
* Update first-run-issues.md with dnf5 instructions

Add installation instructions for Development Tools on dnf5.

* Fixing the command to install it on Fedora 41+
2026-01-03 18:35:59 -08:00
Neal Shah f8997b7d75 Responses API support for OpenAI (#2226)
* Responses API support for OpenAI

* Fix toolcalling in Responses API
2026-01-01 16:25:57 +05:30
Daniel Salazar aafdec9b81 perf: make app entries more scalable, avoid writing global entries since its just puter itself and isn't relevant (#2233) 2025-12-30 19:26:46 -08:00
jelveh 58c8ec7f43 Increase auth popup height to 600px 2025-12-29 23:24:09 -08:00
jelveh 98d0c25ce8 Adjust auth popup size and style for embedded mode 2025-12-29 23:12:52 -08:00
jelveh 773b82638a Update helpers.js 2025-12-29 22:54:38 -08:00
jelveh 8b1bcfa601 Reduce PENDING_QUERY_TTL to 10 seconds 2025-12-29 22:45:33 -08:00
jelveh d7c56472c5 Add request coalescing to get_app with pending query cache
Introduces a TTL-based pending query cache to the get_app function to prevent duplicate database queries for the same app lookup. This change improves efficiency by coalescing concurrent requests for the same app and ensures only one database query is performed per unique lookup within the TTL window.
2025-12-29 20:37:26 -08:00
Daniel Salazar f3b5e1b03f fix: don't cache nor fetch raw b64 url for app icons (#2230) 2025-12-29 18:09:56 -08:00
Daniel Salazar 174e6130ee fix: cache get_app result with expiry to lessen load on db (#2229)
* fix: cache get_app result with expiry to lessen load on db

* fix: use EX instead
2025-12-29 16:38:57 -08:00
jelveh a4afc41a1c Remove global access route for cloud.js 2025-12-25 17:27:56 -08:00
Daniel Salazar 6cc86ff58b feat: support extension divs headers and tags being inserted to puter homepage load (#2221)
* feat: support extension divs headers and tags being inserted to puter homepage load

* wip: demo div

* fix: extension typing

* fix: extension typing

* feat: hompage gui add on
2025-12-24 13:48:36 -08:00
Reynaldi Chernando a32a16d306 Fix workers types (#2198) 2025-12-23 12:35:25 -08:00
Reynaldi Chernando eb23863b6e Fix apps types (#2197)
* Fix apps types

* Remove get overload
2025-12-23 12:34:58 -08:00
Reynaldi Chernando 99220b5b18 Add optional requestCallbacks options to getUser (#2186) 2025-12-23 12:34:41 -08:00
Daniel Salazar 91e12f6886 fix: don't load bench.js files (#2207)
* fix: autoloader grabbing bench.js files

* fix: errors failing

* fix: extension cache typ

* cache: app icons
2025-12-22 15:52:24 -08:00
KernelDeimos f8bdcf8470 dev: [+] DataAccessModule > AppService > select()
This commit adds the DataAccessModule, which is where replacement
"flatter" implementations for what is currently implemented via
EntityStorage/OM will be developed.

This commit also adds AppService, which is where the `crud-q`
implementor for apps will be implemented.

This commit adds the `select()` implementation for AppService. Currently
it is missing many behaviors for parity with the current ES/OM
implementation including:
- coercion of boolean values
- nested objects and their properties
- `icon_size` parameter support
2025-12-22 17:13:07 -05:00
KernelDeimos 3c1a4cd31a dev: specify 'es:app' in puter.js apps module
The EntityStorage/OM mechanism for data access is being replaced.
Specifying 'es:app' in puter.js calls will allow the ES/OM mechanism and
its replacement to be tested together to check for regressions. When the
replacement is done, we can change 'es:app' to the new service name.
2025-12-22 16:08:35 -05:00
KernelDeimos 7786deefb7 lint: sync Apps.js with linter rules
This is comitted separately because it should not have any functional
changes. Do not skip this in a `git bisect`, but do not revert this when
testing commits for functional changes.
2025-12-22 16:08:35 -05:00
jelveh dc5f61b438 Add screen-wake-lock to iframe allow attribute 2025-12-22 08:32:51 -08:00
jelveh 85877259a6 Update initgui.js 2025-12-20 18:26:02 -08:00
jelveh 0520251249 Remove spinner display in popup during temp user creation
Eliminated the spinner shown when creating a temporary user in popup mode and removed the corresponding hideSpinner call. This streamlines the user experience during account setup.
2025-12-20 18:13:27 -08:00
jelveh abd28d8935 Improve captcha modal styling and messaging 2025-12-20 18:03:00 -08:00
jelveh a058912c1f Style captcha modal for embedded popup context 2025-12-20 17:40:48 -08:00
KernelDeimos c43f3990d9 fix: import issues on run form benchmarks (somehow) 2025-12-19 23:16:17 -05:00
KernelDeimos c737a28c34 Revert "Revert 2206 eric/25 cj0 more benchmarks (#2208)"
This reverts commit 2be2dcaea0.
2025-12-19 23:16:17 -05:00
Daniel Salazar 2be2dcaea0 Revert 2206 eric/25 cj0 more benchmarks (#2208)
* Revert "perf: more benchmarks (2)"

This reverts commit 2c60faf516.

* Revert "perf: more benchmarks"

This reverts commit d3c1fc3103.
2025-12-19 19:57:22 -08:00
Daniel Salazar f360cf17e6 chore: update our required node version (#2204)
* feat: fix broken queue bench

* chore: update our required node version
2025-12-19 19:24:05 -08:00
KernelDeimos 2c60faf516 perf: more benchmarks (2) 2025-12-19 17:02:20 -05:00
KernelDeimos d3c1fc3103 perf: more benchmarks 2025-12-19 17:02:20 -05:00
KernelDeimos 75f3092077 bench: extract and benchmark CircularQueue
- Move CircularQueue class from AntiCSRFService to util directory
- Add benchmark to ensure we don't slow it down
2025-12-19 15:49:38 -05:00
KernelDeimos 49b90bde12 test: add benchmark config and first unit bench
Adds the necessary configuration and the `npm run bench` script, as well
as the first benchmark to verify everything is working. The first
benchmark is permissionUtils. This is important to benchmark because
permission strings are used often and there is some non-trivial logic
such as escaping of full-colon characters. Other overheads like database
access will be much more significant, but it may be useful to know how
much more significant in quantifiable terms.
2025-12-19 15:49:38 -05:00
Daniel Salazar a1689c4ea3 feat: dynamo in oss (#2195)
* feat: dynamo in oss

* fix: service name mismatch for dynamo client

* fix: dynalite boot

* fix: tests
2025-12-18 17:22:49 -08:00
Neal Shah 9aefed5515 add user iteration to all methods which return an App object (#2203) 2025-12-18 17:03:31 -05:00
jelveh af066356cf Show AI button regardless of email confirmation 2025-12-17 20:36:31 -08:00
jelveh 9d307d54ed Adjust font size in UsageLimitDialog message 2025-12-17 20:14:49 -08:00
jelveh 6d5b8e45c0 Remove email confirmation check before launching AI app 2025-12-17 17:25:53 -08:00
KernelDeimos 7228e63c8b perf(es): generate client-safe objects in parallel 2025-12-17 17:12:33 -05:00
KernelDeimos 6edd7debb8 perf: improve parallelization in SQLES
It turns out SQLES was doing some things very sequentially when this was
not necessary. This should make SQLES a lot faster in general.
2025-12-17 17:12:33 -05:00
Reynaldi Chernando 3b646328f7 Add gemini 3 flash to models (#2191) 2025-12-17 14:11:14 -08:00
KernelDeimos eea9d8b27e perf: split implied user-app permissions
It took a long time to figure out why this was happening, but
user-to-app permissions and dev-to-app permissions were being checked in
sequence instead of concurrently. It turns out it was a recursive call
in user-to-app permissions that was blocking. This recursive call was
not actually a dependency of the query for user-to-app permissions; it
was only needed for determining if default user-to-app permissions are
held by the user. This was fixed by simply splitting up these
non-dependent queries into two separate scanners.
2025-12-17 16:17:07 -05:00
KernelDeimos 576900ebcc clean: readdir optimization 2025-12-17 16:17:07 -05:00
Daniel Salazar a6617527db fix: types and tests? (#2193) 2025-12-17 13:11:51 -08:00
Neal Shah d76adcf831 add typescript transpilation for legacy node support ☹️ (#2190)
* add typescript transpilation for legacy node support ☹️

* add typescript as devdep
2025-12-17 02:56:56 -05:00
Reynaldi Chernando 28526eb6b7 Add flux.2 max for together provider (#2189) 2025-12-16 21:34:06 -08:00
Neal Shah 21fb86752a App telemetry user iteration (#2188)
* add app-telemetry interface, and user-iteration feature

* Rid app-user-count.ts from workspace imports

* Remove semicolon at the end of query :(
2025-12-16 19:26:27 -05:00
jelveh 2d5fb8576e Update OpenAiImageGenerationProvider.ts 2025-12-16 16:19:03 -08:00
jelveh 49ab36d8be Add GPT Image 1.5 model and cost mapping 2025-12-16 15:55:33 -08:00
jelveh a3bcc488de Update usage limit dialog to indicate insufficient funds 2025-12-16 11:15:50 -08:00
Nariman Jelveh dc78af3590 Add usage limit dialog and integrate with driverCall_ (#2185) 2025-12-16 10:37:26 -08:00
jelveh 1e864b4bd5 Update UIDashboard.js 2025-12-15 20:50:59 -08:00
Daniel Salazar ed51a042b4 telemetry: config telemetry to run by default (#2184) 2025-12-15 18:49:49 -08:00
jelveh 358b64124e Add extension events to dashboard initialization 2025-12-15 17:43:05 -08:00
KernelDeimos 9bac2cba07 perf: [+] readdirstat_uuid optimized implementation 2025-12-15 20:28:34 -05:00
Reynaldi Chernando dc827f90c4 Fix more puter.js typescript types (#2181)
* Fix networking types

* Fix os types

* Fix UI types

* Remove constructor in util.d.ts

* Fix worker types

* Fix puter.d.ts

* Fix apps types

* Change socket and tlssocket back to psocket and ptlssocket
2025-12-15 19:29:04 -05:00
Reynaldi Chernando 85c548d0d3 Fix speech2speech options (#2133) 2025-12-15 16:11:25 -08:00
jelveh 66cf679aab Delete devlog.md 2025-12-15 13:59:53 -08:00
KernelDeimos 6d36c90032 fix: add missing 'tel' runtime module 2025-12-15 14:35:05 -05:00
jelveh 5ba94092f7 Map 'xai' provider to 'xai-image-generation' 2025-12-14 16:05:50 -08:00
jelveh a030fcd9b8 Add xAI image generation provider integration 2025-12-14 15:46:28 -08:00
Daniel Salazar 54dd60d44b fix: missing video gen ai services in ai module (#2180) 2025-12-14 11:08:52 -08:00
Nariman Jelveh 560307d587 Remove unused putility features (#2168)
* Remove smol utility library and update usage

Deleted the smol utility library from putility, removed its documentation, and refactored code in linux.js to use native string methods instead of smol.split. This simplifies the codebase by eliminating a redundant utility.

* Remove `putility.libs.time` and inline time utilities

* Update imports and time constant usage in core modules

Replaced usage of time.SECOND with a local SECOND constant in ServerHealthService for clarity and removed unused import. Updated all service imports in TestCoreModule to explicitly include the .js extension for compatibility with ES module resolution.

* Remove unused `wrap_text` and `ansi_visible_length` functions

Deleted the wrap_text and ansi_visible_length utility functions from string.js, as they are no longer needed or used in the codebase.

* Remove `format_as_usd` utility and related docs

The format_as_usd function and its documentation have been removed from the codebase and README files. This cleans up unused or deprecated currency formatting utilities.

* Remove osclink utility and update references

The osclink function and its documentation have been removed from putility. All usages in backend modules have been updated to use plain URLs instead of OSC 8 hyperlinks. This simplifies string utilities and avoids terminal-specific formatting.

* Remove PosixError utility module

* Remove NariMethodsFeature and related references

Deleted the NariMethodsFeature module and removed its usage from AdvancedBase and PuterJSFileSystemModule. This simplifies the codebase by eliminating unused or deprecated NARI method support.
2025-12-13 17:59:16 -08:00
Daniel Salazar 6652a1d332 fix: make cache calls async on boot (#2173) 2025-12-13 17:00:02 -08:00
Daniel Salazar 25221e539d fix: bad caching query crashing our db (#2172)
* logs: add errors to cache log

* logs: add errors to cache log

* fix: bad caching query crashing our db
2025-12-13 16:48:36 -08:00
Daniel Salazar 5c9a98a7a1 Ds/main (#2171)
* logs: add errors to cache log

* logs: add errors to cache log
2025-12-13 15:48:37 -08:00
Daniel Salazar d7b3ba3bb0 cd: make our deploy reliably wait for server to be ready (#2170)
* chore: continue removing extra logs

* cd: make our deploy reliably wait for server to be ready
2025-12-13 14:34:44 -08:00
Daniel Salazar e79f8a46f0 chore: add better logging to broadcast connections (#2169)
* fix: await fetching app cache on init

* chore: add better logging to broadcast connections
2025-12-13 14:07:25 -08:00
Daniel Salazar bbd5f52320 chore: continue removing extra logs (#2159)
* fix: await fetching app cache on init

* await for methods on boot now
2025-12-13 13:34:25 -08:00
Nariman Jelveh 87ac67a340 Remove DevConsoleService and related dev console widgets (#2167)
* Remove DevConsoleService and related dev console widgets

Eliminates `DevConsoleService` and `NullDevConsoleService`, along with all code that registers or manages dev console widgets across the backend. Developer messages and notifications are now logged directly to the console. Removes related commands and test mocks, simplifying the developer experience and reducing code complexity.

* Remove MinLogService and related registration code

Deleted MinLogService.js and removed its registration from SelfHostedModule.js. This cleans up unused or deprecated logging functionality.

* Remove `DevSocketService` and related registration

* Increase test job timeouts in CI workflow

* Remove dev environment widget ops counter

Eliminated increment and decrement of the dev_batch-widget ops counter in BatchExecutor. This simplifies the code and removes dev-only UI tracking logic from the batch operation flow.

* Remove console Puter logo feature and related code

Deleted the src/fun/logos.js file and removed all references to the Puter logo display in WebServerService and documentation. This streamlines the server startup output and eliminates unused or unnecessary code.

* Update WebServerService.js

* Standardize console banner formatting in services
2025-12-13 13:31:16 -08:00
jelveh d07d5fd5cb Remove DevTODService and its registration 2025-12-13 11:33:06 -08:00
Nariman Jelveh 794ff1e255 Remove tag cache refresh logic from AppInformationService (#2166)
* Remove tag cache refresh logic from AppInformationService

Eliminated the _refresh_tags method and its scheduled interval from AppInformationService. This change removes the tag cache refresh functionality, likely due to refactoring or deprecation of tag-based app discovery.

* Remove AI usage testing contributor docs
2025-12-13 09:45:13 -08:00
jelveh 888fab42e1 Remove AI response normalization files 2025-12-13 00:23:35 -08:00
jelveh 9c5938e2fd Remove comment-writer and AI METADATA comments from backend source files 2025-12-13 00:16:31 -08:00
jelveh f838fe4ecc Remove Threads module from puter-js 2025-12-13 00:06:43 -08:00
Nariman Jelveh 8f7a735cc0 Remove dev-console-ui-utils and update related services (#2163)
* Remove dev-console-ui-utils and update related services

* Remove debug console.log statements from backend code

Eliminated various leftover console.log and debug print statements across multiple backend modules and services to clean up the codebase and reduce unnecessary logging in production.

* Remove unnecessary console.log statements
2025-12-12 23:46:39 -08:00
Nariman Jelveh b8ed8caa3a Remove CommentService and related tests (#2160)
Deleted the CommentService implementation and its test file, and unregistered the service from CoreModule. This removes all comment-related backend functionality.
2025-12-12 21:49:54 -08:00
Nariman Jelveh 6bb4e9dfae Remove Bootstrap 5.1.3 assets from public directory (#2161)
* Remove Bootstrap 5.1.3 assets from public directory

* Create bootstrap.min.css
2025-12-12 21:41:16 -08:00
Nariman Jelveh ae92233b95 Remove fat from puterjs (#2156)
* Refactor puter-js to remove putility and service layer

* Add fallback for IPC listener registration

* Remove TeePromise in favor of `createDeferred` pattern

* Update utils.js

* Bump version to 2.2.0 in package.json

* Remove model name normalization and driver mapping logic

Eliminated the code responsible for normalizing model names and mapping models to specific AI drivers. The default driver is now set to 'ai-chat', simplifying the model selection and driver assignment process.

* Simplify AIService selection logic in image generation

* Remove unused Together image model constants
2025-12-12 19:44:15 -08:00
Daniel Salazar ef69865dd1 chore: decrease uninmportant logs (#2158) 2025-12-12 18:50:01 -08:00
Daniel Salazar f3e143e74a fix: bad usageType (#2157) 2025-12-12 17:31:40 -08:00
Daniel Salazar 797b87b004 cleanup: remove dead cloudwatch call (#2155) 2025-12-12 17:08:26 -08:00
KernelDeimos 6c0daf58c4 perf: is()/is_above() determine when to fetch 2025-12-12 17:38:43 -05:00
KernelDeimos af9a2b8300 perf: don't await on modifying 'accessed' 2025-12-12 17:38:43 -05:00
KernelDeimos 3fe6b8d23a fix: fsNode.is() requiring unnecessary fetch
When you have two path selectors, .is() should compare path strings
instead of fetching any entries.
2025-12-12 17:38:43 -05:00
KernelDeimos 4b31204224 perf: condition for re-fetch in fsNode.exists() 2025-12-12 17:38:43 -05:00
jelveh 54c2d9768e Update package.json 2025-12-12 13:47:27 -08:00
jelveh 348e000863 Bump puter.js version to 2.1.15 and update metadata
Added a homepage field and specified the repository directory in package.json for improved project metadata.
2025-12-12 13:43:25 -08:00
jelveh bb697616c0 Refine signup form spacing and title styling 2025-12-12 13:28:18 -08:00
Reynaldi Chernando ce2a509221 Fix hosting types (#2153) 2025-12-12 12:55:59 -08:00
Reynaldi Chernando 17ca4c7c93 Fix speech2txt options (#2150) 2025-12-12 12:55:51 -08:00
Reynaldi Chernando e431ac265c Fix FS types (#2134) 2025-12-12 12:55:39 -08:00
Reynaldi Chernando 697b3424c7 Add missing AI types (#2151) 2025-12-12 12:55:20 -08:00
Reynaldi Chernando c950be13f2 Fix KV types (#2152) 2025-12-12 12:54:13 -08:00
jelveh 7dcf590cf1 Add hide-scrollbar class to sidebar and user options 2025-12-12 11:58:59 -08:00
Reynaldi Chernando 7b15ee0bd0 Add alias for gpt-5.2-chat (#2148) 2025-12-11 19:59:21 -08:00
jelveh bb7b71236f Add new GPT-5.2 chat models to OpenAI provider 2025-12-11 19:43:22 -08:00
jelveh e75259dfd0 Add GPT-5.2 model to OpenAI provider models 2025-12-11 19:07:30 -08:00
Daniel Salazar aa225e3049 fix: batch app info referral (#2146) 2025-12-11 18:31:22 -08:00
jelveh 77c7214a1d Optimize app stats cache update with aggregate queries 2025-12-11 18:08:38 -08:00
Daniel Salazar 9e2ae1c004 fix: bad ai calls (#2144) 2025-12-11 17:13:25 -08:00
Daniel Salazar 83eab0d6ac Revert "Revert: single ai image entry point (#2131)" (#2143)
This reverts commit 907d0db328.
2025-12-11 17:03:20 -08:00
jelveh 89fbcffc7a Remove backend documentation section from CONTRIBUTING.md 2025-12-11 17:03:12 -08:00
jelveh 83eff9da87 Remove style guide and first contribution sections 2025-12-11 17:00:46 -08:00
jelveh f961dd4acd Update CONTRIBUTING.md 2025-12-11 16:58:21 -08:00
Daniel Salazar a103ca9bcb cleanup: remove Library + bloated utils where possible (#2142) 2025-12-11 16:55:29 -08:00
Nariman Jelveh ef9f240a45 Remove terminal phoenix emulator (#2141)
* Remove terminal and phoenix built-in apps and emulator

This commit removes the terminal and phoenix built-in apps from the backend, database migrations, and permissions. It also deletes the entire emulator and phoenix/terminal app source directories, assets, and related configuration files. References to these apps in the backend module loader and router are removed, and related SQL migrations are updated to reflect their removal.

* Remove emulator references from SelfHostedModule

* Remove emulator integration and related references

* Remove parsers and pty modules

* Update package-lock.json
2025-12-11 16:53:21 -08:00
jelveh f07092164f Delete app.js 2025-12-11 15:29:55 -08:00
jelveh a423820e4b Remove unused backend HTML and module files
Deleted ThirdPartyDriversModule.js, html_footer.js, and html_head.js from the backend source directory. These files are no longer needed and have been removed to clean up the codebase.
2025-12-11 15:08:51 -08:00
Nariman Jelveh 6b7f6baeab Delete backend README links from README.md (#2140) 2025-12-11 13:34:30 -08:00
Daniel Salazar 57f5163e51 chore: remove deprecated threads (#2139) 2025-12-11 13:28:34 -08:00
Nariman Jelveh 7524933ca1 Remove backend-core-0 and inline validation helpers (#2138)
Deleted the src/backend-core-0 package and moved its validation helpers directly into src/backend/src/validation.js. Updated references in CoreModule.js and helpers.js to use the new local validation module. Adjusted ESLint configs to remove backend-core-0 references.
2025-12-11 13:22:32 -08:00
Daniel Salazar 907d0db328 Revert: single ai image entry point (#2131)
* Revert "fix: together ai image prices (#2130)"

This reverts commit 04c8b06616.

* Revert "feat: single image ai endpoint (#2129)"

This reverts commit 161ca74aa3.
2025-12-11 00:56:06 -08:00
Daniel Salazar 04c8b06616 fix: together ai image prices (#2130) 2025-12-10 23:46:52 -08:00
Daniel Salazar 161ca74aa3 feat: single image ai endpoint (#2129) 2025-12-10 23:29:11 -08:00
jelveh 4b2135f896 Update style.css 2025-12-10 22:56:38 -08:00
jelveh 6b71eb04ec Add box-sizing and responsive padding to sidebar 2025-12-10 22:28:15 -08:00
Daniel Salazar 1a0e2d3def fix: bad method name for together ai (#2128) 2025-12-10 20:45:41 -08:00
jelveh 902c1f7944 Add save account warning for temporary users 2025-12-10 20:10:01 -08:00
jelveh 0d2f4c3f2c Add window options to feedback and account modals 2025-12-10 19:44:04 -08:00
jelveh cfe497bd0c Update UIDashboard.js 2025-12-10 19:30:08 -08:00
jelveh 1ed8b2a86a Refactor dashboard modals and update danger zone UI 2025-12-10 19:22:13 -08:00
Neal Shah 6929e48b8e Fix ratio in TogetherImage (#2127) 2025-12-10 17:56:10 -05:00
Reynaldi Chernando bcd96523cb Add auth types (#2117) 2025-12-10 16:44:31 -05:00
jelveh ddf9bd1358 Add Security tab to dashboard with 2FA and session management 2025-12-10 12:10:20 -08:00
jelveh 357cb8bcca Simplify call to UIWindowConfirmUserDeletion 2025-12-09 23:55:49 -08:00
jelveh f18e349c21 Add profile-pic class to profile avatar div 2025-12-09 23:48:02 -08:00
jelveh 9806a8bc81 Add Account tab to dashboard UI 2025-12-09 23:25:37 -08:00
jelveh 00f3699335 Add chevron rotation for user menu toggle 2025-12-09 22:28:37 -08:00
jelveh de67d25baf Update recent apps grid layout and styling 2025-12-09 22:20:27 -08:00
jelveh 1e79d9e192 Merge branch 'main' of https://github.com/HeyPuter/puter 2025-12-09 17:09:03 -08:00
jelveh 462ec01de6 Add 'Show less' button to usage table 2025-12-09 17:09:01 -08:00
Daniel Salazar b40ca1df2c Revert: change to ai model names (#2123)
* Revert "fix: prevent loot qp if failing ai models? (#2122)"

This reverts commit 8d52cefe47.

* Revert "feat: rename ai models to match norm (#2121)"

This reverts commit 9da8aa0849.
2025-12-09 17:00:01 -08:00
Daniel Salazar 8d52cefe47 fix: prevent loop if failing ai models? (#2122) 2025-12-09 16:54:17 -08:00
jelveh 010c9b1a82 Update style.css 2025-12-09 16:50:11 -08:00
jelveh ab5f168cd7 Add expandable usage table with show more button 2025-12-09 16:42:52 -08:00
Daniel Salazar 9da8aa0849 feat: rename ai models to match norm (#2121) 2025-12-09 16:38:34 -08:00
KernelDeimos 2aa4cd857d type: add extension.span to api.d.ts 2025-12-09 19:17:05 -05:00
KernelDeimos 2e4a504cda fmt: apparently api.d.ts was out of sync with linter 2025-12-09 19:17:05 -05:00
Daniel Salazar e2ae313589 feat: refactor ai to have single entry point and follow defined model structure (#2114)
* feat: refactor ai to have single entry point and follow defined model structure

* fix: missing openrouter registration

* fix: dedupe models

* feat: provide usage in stream mode 🚀
2025-12-09 15:59:21 -08:00
jelveh 2ab99d38da Update TabHome.js 2025-12-09 15:58:51 -08:00
jelveh e9de337645 Show up to 8 recent apps on 4K screens in TabHome 2025-12-09 15:49:08 -08:00
jelveh dd1bb8416f Improve recent apps grid layout for dashboard 2025-12-09 15:43:22 -08:00
KernelDeimos d8dc438a7d dev: extension.span 2025-12-09 18:42:10 -05:00
KernelDeimos 1d7a5b7c58 fix: downgrade opentelemetry so it works again
We weren't able to see any custom spans, only the builtin
instrumentations for node.js. This commit downgrades opentelemetry so
that we can see custom spans in tools like jaeger as before.
2025-12-09 17:30:52 -05:00
KernelDeimos cb7c83f670 fix: add simple 30s cache to /healthcheck 2025-12-09 00:14:03 -05:00
jelveh 38da15853f Update style.css 2025-12-08 18:15:05 -08:00
KernelDeimos d0ea063d0f dev: update use of spans in extensions 2025-12-08 18:50:23 -05:00
KernelDeimos 64b0ba89cc doc(extensions): fix incorrect documentation link 2025-12-08 18:50:23 -05:00
KernelDeimos 87dbb34a8d fix: pass exporter to NodeSDK constructor
Previously a new ConsoleSpanExporter was passed to the constructor of
NodeSDK. This was possibly unintentional but it did not cause any
issues. After the recent update to opentelemetry, or perhaps the changes
introduced in 3c579dcc0d, this no longer
works as it prevents tools like Jaeger from getting any spans from
Puter's backend.
2025-12-08 18:41:21 -05:00
jelveh c9bbca875f Redesign dashboard usage and plan cards 2025-12-08 14:59:08 -08:00
Reynaldi Chernando 7b5d90d678 Fix AI types (#2100)
* Remove constructor and global methods

* Fix streaming type and stricter type

* Add missing chat options param

* Fix messages type

* Fix img2txt types

* Fix txt2img types

* remove unused

* Fix test mode in txt2img

* Fix txt2vid types

* Fix speech2txt types

* Fix speech2speech types

* Fix txt2speech types

* Add missing chat types

* Fix missing txt2speech types
2025-12-08 14:06:36 -08:00
jelveh f09cac99eb Update style.css 2025-12-08 13:27:19 -08:00
Daniel Salazar 910e6041fa fix: eleven labs metering costs (#2112) 2025-12-08 11:07:16 -08:00
jelveh 31460fc70b Update home tab label and card backgrounds 2025-12-07 01:14:32 -08:00
jelveh 94b2af9d88 Update welcome card UI for lighter theme 2025-12-07 00:49:09 -08:00
jelveh afc21a9903 Add user avatar to home tab welcome section 2025-12-07 00:27:16 -08:00
KernelDeimos b92dcc8146 chore: associate googlemail with gmail rules 2025-12-07 02:11:29 -05:00
jelveh 6f24176ea3 Add external link support for recent apps 2025-12-06 21:54:59 -08:00
jelveh dc2f4953eb Fix recent app title display logic in TabHome (jesus take the wheel!) 2025-12-06 21:41:18 -08:00
jelveh 08599efd78 Adjust recent apps display and update dashboard styles 2025-12-06 21:31:46 -08:00
jelveh c45c40c304 Update style.css 2025-12-06 21:21:11 -08:00
jelveh 1e7f815946 Improve recent apps display and style in TabHome 2025-12-06 20:57:05 -08:00
jelveh ba1855cff6 Add usage card to dashboard home tab 2025-12-06 20:32:00 -08:00
jelveh c2bcd3092d Add Home tab with bento dashboard layout 2025-12-06 19:40:07 -08:00
jelveh 622f53468b Adjust dashboard icons and app card styles 2025-12-06 19:13:47 -08:00
jelveh 7f7ab1957f Add Usage tab to dashboard with sortable usage table 2025-12-06 18:26:58 -08:00
jelveh ba6ea233ad Update style.css 2025-12-06 17:18:10 -08:00
jelveh 19c96e9797 Update style.css 2025-12-06 17:14:26 -08:00
Nariman Jelveh ed509ad286 Dashboard (#2104)
* Add dashboard UI and routing support

Introduces a new Dashboard UI component with sidebar navigation and user options. Updates backend routing to redirect /dashboard to the root path. Integrates dashboard mode detection and initialization in the GUI, including responsive styles and logic to open the dashboard or desktop as appropriate.

* Improve dashboard user menu and UI behavior

Added support for multiple logged-in users, session saving for temporary users, and improved context menu options in the dashboard. Updated CSS for user button state and adjusted font size for signup terms. Changed dashboard initialization to use UIDashboard instead of UIWindow.

* Add dynamic apps section to dashboard UI

* Add specific class for dashboard apps section

* Refactor dashboard tabs into modular components

* Update style.css

* Add Developers menu and improve signup window behavior

Added a 'Developers' menu item to the dashboard linking to developer.puter.com. Updated login and signup window logic to ensure the signup window opens centered and dominant, improving user experience when transitioning from login to signup.

* Update UIWindowLogin.js

* Refactor apps tab UI and improve app card interaction
2025-12-06 17:06:20 -08:00
KernelDeimos 277ee6ca5a rename: requestPermission -> request 2025-12-05 13:06:29 -05:00
Daniel Salazar ebeaf33412 npm: publish new readme (#2098)
* fix: togetherAi metering

* npm: publish new readme

* Revert "fix: togetherAi metering"

This reverts commit 2b3eb76d90.
2025-12-05 03:04:59 -08:00
KernelDeimos 2db3331729 tweak: add puter.perms.requestPermission
It calls requestPermission on the UI module. The method on the UI model
needs to still exist because the UI module is tightly-coupled with IPC.
A refactor of the IPC mechanism on the puter.js side could solve this.
2025-12-04 19:50:38 -05:00
KernelDeimos 237dc2ef9a fix: get subdomains permission working 2025-12-04 19:50:38 -05:00
KernelDeimos 349438458a dev: add user-friendly permission requests for apps/subdomains 2025-12-04 19:50:38 -05:00
KernelDeimos bee780cc69 dev: i12ize permission messages (no translations) 2025-12-04 19:45:22 -05:00
KernelDeimos 56301281d7 dev: ensure proper encoding in dialog 2025-12-04 19:45:22 -05:00
KernelDeimos d9875a5be5 dev: puter.perms methods to request directories
This commit adds methods to request standard directories like the
Desktop, Documents, Pictures, or Videos directory. Additionally, the
message displayed when permission for these directories is requested is
easier to read.
2025-12-04 19:45:22 -05:00
Nariman Jelveh 66786a0015 Update Node.js section header in README.md (#2095) 2025-12-04 11:26:01 -08:00
KernelDeimos 09b8c29e2f tweak: avoid use of puter global in Perms module 2025-12-04 13:26:22 -05:00
KernelDeimos ef6dea2bec fix: skip cache when checking user:<>:email:read 2025-12-04 13:26:22 -05:00
KernelDeimos 3d7cf1c1c4 dev: add await puter.perms.requestEmail() shorthand 2025-12-04 13:26:22 -05:00
KernelDeimos 1c9ed12044 dev: add permission dialog message for email:read 2025-12-04 13:26:22 -05:00
KernelDeimos 3ea309e93b fix: requestPermission Promise never settled
This bug took a long time to diagnose, so I also made an async/await
wrapper around #postMessageWithCallback called #postMessageAsync so that
similar promise resolving errors are less likely here in the future.
2025-12-04 13:26:22 -05:00
Neal Shah a202e57480 Add flux.2 costmaps (#2092) 2025-12-03 11:39:02 -05:00
Daniel Salazar 6419d57d84 types: fix puter-js type exports (#2090)
* chore: add typedefs for puter.js

* types: fix puter-js type exports
2025-12-02 21:36:46 -08:00
KernelDeimos 71e6a59d13 dev: add __import_identity__ to config for debug use
The vitest test suite can import different states of the same module, so
this value was very helpful in determining that this was happening and
eventually the cause.
2025-12-02 16:54:27 -05:00
KernelDeimos 06d56fd711 fix: update validation for permission endpoints
Permission endpoints would trigger 500 errors in cases where the request
did not have correct types for values in the request body. This migrates
all of these endpoints to use the new `validate_fields` function, which
is intended to make validation of fields clearer and more consistent.
2025-12-02 16:53:48 -05:00
KernelDeimos e5ac7af52d dev: add utility for field validation 2025-12-02 16:53:48 -05:00
KernelDeimos 11a18078be fix: improve response error handling in Perms module 2025-12-02 16:53:48 -05:00
Neal Shah 66d9344407 Fix turnstile auth (#2087)
* attempt to fix turnstile auth
2025-12-02 16:25:18 -05:00
Daniel Salazar 34134a2e35 chore: add typedefs for puter.js (#2086) 2025-12-02 13:04:26 -08:00
Daniel Salazar cce2c4ac27 fix: stricten undef checks (#2082) 2025-12-01 20:26:33 -08:00
Daniel Salazar d3beac0518 fix: wrong order for telemetery init (#2078) 2025-12-01 20:18:03 -08:00
Daniel Salazar 3c579dcc0d fix: TelemetryService (#2077) 2025-12-01 18:11:56 -08:00
KernelDeimos b42a106676 dev(perms): [+] apps-of-user:<user-uuid>:write
This commit also adds a new check to verify that the app which owns the
entity being edited matches. Previously this was not necessary because a
read on the same entity would have always performed the same check and
caused this operation to stop early. (now that an app may have
permission to read entities created by other apps, this is no longer the
case.)
2025-12-01 17:14:41 -05:00
KernelDeimos a71fa826b3 dev(perms): [+] apps-of-user:<user-uuid>:read 2025-12-01 17:14:41 -05:00
KernelDeimos cf9a867190 fix: inaccurate error on update of non-existing
...entity (app, subdomain, etc). When trying to update some non-existing
entity the error message can state that an entity with a particular UID
was not found even if a UID wasn't specified. The UID reported will in
fact be a randomly generated UID because of how default properties work
in entities. This fix makes the error message more specific about which
identifier was used when an entity was not found. This is accomplished
by printing the predicate in a human-readable format.
2025-12-01 17:14:41 -05:00
Daniel Salazar 405e02cf9c test: claudeService (#2074) 2025-12-01 13:39:55 -08:00
Daniel Salazar c77272012d ci: add test coverage (#2073)
* ci: add test coverage

* ci: add test coverage
2025-12-01 08:56:44 -08:00
Daniel Salazar d978c37e0b ci: package and docker fixes (#2072)
* ci: package and docker fixes

* ci: fix package conflicts
2025-12-01 02:10:36 -08:00
Daniel Salazar 0568b64821 ci: fix docker again (#2071) 2025-12-01 01:47:00 -08:00
Daniel Salazar cc5be578bf ci: cleanup docker build (#2070) 2025-12-01 01:25:08 -08:00
Daniel Salazar 45fb5c32b1 chore: various test related changes (#2069)
* fix: backend tests breaking with permision

* test: cleanup running tests

* chore: config.d.ts
2025-12-01 01:14:44 -08:00
Neal Shah 596f77d888 Working main 2025 11 29 (#2068)
* add logging hook to togetherai image service

* add gemini-3-pro-image to costmap
2025-11-30 11:39:34 -05:00
Daniel Salazar cea94d16cb fix: backend tests breaking with permision (#2067) 2025-11-29 13:50:27 -08:00
Daniel Salazar e8f00e1121 fix: typo in dbkvStore (#2066) 2025-11-29 13:18:37 -08:00
Daniel Salazar dccfa8085e chore: some type and eslint fixes for tests (#2065) 2025-11-28 23:38:04 -08:00
Neal Shah f99c78e4d3 Email read permission for whoami (#2064) 2025-11-28 17:34:26 -05:00
Daniel Salazar f6fa17a575 feat: KV testing (#2061) 2025-11-27 18:45:49 -08:00
KernelDeimos c4e380c140 test: add tests for services in CoreModule 2025-11-27 15:15:56 -05:00
Daniel Salazar f120bc9c58 fix: metering service alerts + missing claude costs (#2058)
* fix: missing haiku costs, updating opus 4.5 id to match documentation

* fix: improve alert logic for metering service misses
2025-11-27 11:45:56 -08:00
jelveh c6af50ea98 Update claudeCostMap.ts 2025-11-27 09:08:14 -08:00
KernelDeimos 8e2ed18fb3 refactor: introduce TestCoreModule for test kernel 2025-11-26 18:58:34 -05:00
Daniel Salazar 59e6418b00 feat: meteringService test suite (#2052) 2025-11-26 15:46:53 -08:00
Neal Shah 6dffa3d6f2 Worker + NodeJS support for puter.ai.txt2img and puter.ai.txt2vid (#2051)
* Attempt to get workers working with AI media generation

* add FileReader polyfill

* fix import path
2025-11-26 18:10:11 -05:00
Daniel Salazar 93eddd2238 feat: MeteringService test fixes for now (#2050) 2025-11-26 15:09:30 -08:00
Nariman Jelveh 6284b390b7 Revert "Create README.tel.md (#2045)" (#2049)
This reverts commit 94a411f30f.
2025-11-26 14:49:40 -08:00
rajucreate 94a411f30f Create README.tel.md (#2045) 2025-11-26 14:49:22 -08:00
PARTH PRATYUSHandNariman Jelveh 14a5f20404 Add Traditional Chinese (繁體中文) Translation for Issue #1501 (#2032)
* i18n(zhtw): add missing Traditional Chinese translations (fix #1501)

This PR adds missing Traditional Chinese (繁體中文) translations to the zhtw.js file.

Translations added:
- confirm_download_file_to_desktop
- downloading_file
- error_download_failed
- Resources
- Storage
- untar / untarring
- uploading / uploading_file
- tar / tarring / download_as_tar
- set_as_background
- error_user_or_path_not_found
- error_invalid_username

Closes #1501

* Fix formatting of confirm download message

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-11-26 14:45:30 -08:00
2400060033 d4f44be5e4 Update tsconfig.json (#2035)
This update fixes configuration issues in the TypeScript setup by standardizing the tsconfig.json. It sets modern compiler targets (ES2024), uses Node16 module resolution, enables strict type checking, and cleans up test-related exclusions. These changes improve build reliability, prevent casing inconsistencies, and ensure accurate source mapping during development.
2025-11-26 17:38:30 -05:00
KernelDeimos eda1c45ffb test: migrate _test tests to vitest tests 2025-11-26 16:32:07 -05:00
Daniel Salazar cb66c56a6b fix: tsconfig to ignore vite config files (#2048) 2025-11-26 13:26:09 -08:00
KernelDeimos 1a0e727113 clean: rename TestService.mts -> TestService.ts 2025-11-26 14:52:31 -05:00
KernelDeimos d6651498eb fix: minor issue in root package.json 2025-11-26 14:52:31 -05:00
KernelDeimos 5f78552005 fix: update MeteringService and add utility for TestKernel 2025-11-26 14:52:31 -05:00
KernelDeimos e95b0be371 fix: update import in TestService 2025-11-26 14:52:31 -05:00
Daniel Salazar a397707c7b fix: bad export 2025-11-26 14:52:31 -05:00
KernelDeimos 8a05b65ff3 dev(test): enable use of TestKernel in unit tests 2025-11-26 14:52:31 -05:00
Daniel Salazar 001e174b81 fix: oss boot error fixes (#2039) 2025-11-26 11:08:40 -08:00
Neal Shah 47ebbc1b90 Use aliases when calculating max_tokens (#2046) 2025-11-26 13:46:53 -05:00
jelveh 142ed0b902 Add cost mapping for Claude Opus 4.5 2025-11-25 18:51:54 -08:00
jelveh 014b5ac713 Enforce ownership of puter.site subdomains for apps 2025-11-25 15:43:14 -08:00
jelveh 6558bc26e9 Refactor AI model listing and provider retrieval 2025-11-25 13:49:39 -08:00
Daniel Salazar e2f1200ad5 test: add test infra to run vitest on all of backend wip (#2023) 2025-11-24 19:20:09 -08:00
KernelDeimos 8eee9ad1df fix(puterfs): use node crypto instead of Web API
By default node has a global `crypto` variable conforming to the
standard for the Web Crypto API. However, this `crypto` object does not
have the `createHash` function, so 'node:crypto' must be imported
instead.
2025-11-24 14:34:55 -05:00
jelveh 613f6379e7 Add Claude Opus 4.5 2025-11-24 11:33:24 -08:00
krishna3324andNariman Jelveh a355761359 docs: add Punjabi translation link to README (#2020)
* docs: add Punjabi translation link to README

The Punjabi (ਪੰਜਾਬੀ) translation README.pa.md was added 2 weeks ago but was missing from the translations list in the main README. This adds it to maintain completeness of the translations section.

* Fix Punjabi link formatting in README.md

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-11-24 09:04:53 -08:00
48d8762ccf Gemini nano banana pro updated (#2012)
* Update AI.js

* Update GeminiImageGenerationService.js

* Update cost map

* Gemini to OpenAI SDK refactor (#2014)

* WIP Gemini OpenAI refactor

* refactor: gemini open ai service + geminiCostMap

* Gemini Service fixes

* Cleaning up old Gemini cruft

---------

Co-authored-by: Daniel Salazar <[email protected]>

---------

Co-authored-by: Nihhaar0002 <[email protected]>
Co-authored-by: Daniel Salazar <[email protected]>
2025-11-24 10:36:00 +04:00
Neal ShahandDaniel Salazar ed2d1368ca Gemini to OpenAI SDK refactor (#2014)
* WIP Gemini OpenAI refactor

* refactor: gemini open ai service + geminiCostMap

* Gemini Service fixes

* Cleaning up old Gemini cruft

---------

Co-authored-by: Daniel Salazar <[email protected]>
2025-11-24 09:55:19 +04:00
jelveh 7e1d50d0d1 Add allenai to openrouter model prefix list 2025-11-23 21:20:23 -08:00
SuryaGanesh284andjelveh 9f9820923d Add missing Traditional Chinese translations to zhtw.js (#2013)
* Add missing Traditional Chinese translations to zhtw.js

* Update zhtw.js

---------

Co-authored-by: jelveh <[email protected]>
2025-11-23 15:49:02 -08:00
bangarumahesh22 385f4ecea2 Docs: improve clarity in README introduction (#2010) 2025-11-23 09:38:32 -08:00
Daniel Salazar 85d13a9d4b fix: openrouter missing usage (#2008) 2025-11-22 15:54:53 -08:00
Eswar Venkata Ram Charan Seeramandjelveh 02716d0e3e i18n(nn): finalize Norwegian Nynorsk translation fixes (Fixes #1514) (#2007)
* i18n(nn): fix typos & finalize translation cleanup

* Update nn.js

---------

Co-authored-by: jelveh <[email protected]>
2025-11-22 10:12:20 -08:00
Nariman Jelveh 133e3dc77c Add 11labs speech-to-speech voice changer integration (#2006) 2025-11-21 23:24:43 -08:00
Daniel Salazar 262b359633 fix: fallback models (#2005) 2025-11-21 20:09:19 -08:00
Reynaldi Chernando fdbd742d7a Add missing together image model prefixes (#1972) 2025-11-22 07:16:26 +04:00
Nariman Jelveh bb752a5bb5 Add ElevenLabs TTS provider integration (#2004)
* Add ElevenLabs TTS provider integration

Adds ElevenLabs text-to-speech support in the backend and frontend. Adds `ElevenLabsTTSService`, updates `PuterAIModule` to register the service, documents configuration, and integrates cost tracking with zero cost in `MeteringService` for now (todo). updates `AI.js` to support 11labs as a provider and adds related tests for `txt2speech` functionality.

* Update 11labs cost map values
2025-11-21 17:31:21 -08:00
Daniel Salazar 11e057557d fix: eslint autofixable errors (#2002) 2025-11-21 13:22:19 -08:00
Daniel Salazar f1773974c0 fix: only fallback to models that are immediately the same (#2001) 2025-11-21 10:46:43 -08:00
John Boulanger f6139bc79a fix: Add debounce to toolbar reveal when dragging windows to prevent accidental activation (#1989)
* fix: debounce toolbar display after dragging a window

* change naming convention for debounce to match others. (snake case)

* revert changes to package.json that werent meant to be comitted

* Revert "change naming convention for debounce to match others. (snake case)"

This reverts commit aaedee0dfa.

* revert commit aaedee0dfa

* use snake case for drag_release_debounce_timer
2025-11-20 23:52:13 -08:00
KernelDeimos 8dafafa749 ci: mandatory eslint rules for build
This commit adds verification for statically identifiable definite
errors. Sometimes global variables used will be falsely reported as
undefined variables in which case the new file
`mandatory.eslint.config.js` should be updated to include these
definitions in the narrowest scope possible that has these definitions
2025-11-20 21:34:21 -05:00
KernelDeimos 12559f7d28 lint: use this.services instead of global here
This is the last error for the mandatory eslint rules. Now we can put a
rule into place so that CI always fails when there's an undefined
variable, which I think is pretty cool.
2025-11-20 21:34:21 -05:00
KernelDeimos 7b38131b65 fix: desktop_items in whoami
There's a potential issue here because of an undefined reference, but I
can't seem to reproduce any problem caused by this. However without this
fix this line of code is guarenteed to throw an exception so this fix
should be safe.
2025-11-20 21:34:21 -05:00
KernelDeimos c4b5b48904 doc: add notes to AppInformationService
I was having issues getting to a branch that calls a non-existing
function so I wrote some comments about the issue here.
2025-11-20 21:34:21 -05:00
KernelDeimos 813ea63d21 fix: possible undefined when handling stuck stream
This is an error in a handler for a failure case so it shouldn't be
affecting users, but let's handle this error gracefully.

This was a symbol that became not defined after moving PuterFSProvider
to the extension.
2025-11-20 21:34:21 -05:00
KernelDeimos 92d03e5501 fix: size_measure_stream in streamutils 2025-11-20 21:34:21 -05:00
KernelDeimos f11d0f0c8b clean: remove unused method in DriverService 2025-11-20 21:34:21 -05:00
KernelDeimos 909f9afb9b link: format DriverService 2025-11-20 21:34:21 -05:00
KernelDeimos 2ae2d3c9af lint: format eggspress.js
It's about time to do this now. This file will for the first time (in...
ever?) be indented with 4 spaces instead of 2.
2025-11-20 21:34:21 -05:00
KernelDeimos 71a26156bd fix: add missing Context import to IconResult 2025-11-20 21:34:21 -05:00
KernelDeimos 5062e3c5ed fix: add missing ref to next()
We might get rid of this later, or re-write it, so this isn't really a
concern right now but this cleans up eslint error output.
2025-11-20 21:34:21 -05:00
KernelDeimos d429d2f5bc fix: incorrect variable ref in hl_move for shared 2025-11-20 21:34:21 -05:00
KernelDeimos e55bd4a796 lint: format hl_move.js 2025-11-20 21:34:21 -05:00
Daniel Salazar 02d95db7ed fix: open router cache token metering (#1988) 2025-11-20 17:49:05 -08:00
KernelDeimos fb41eaae23 fix: id2path import 2025-11-20 18:25:20 -05:00
KernelDeimos 3cdb182355 debug: add missing log message 2025-11-20 18:25:20 -05:00
Neal Shah b035fda778 Fix gemini when tools are null (#1992) 2025-11-21 01:57:39 +04:00
KernelDeimos 452e0b7001 doc: update documentation for TestKernel 2025-11-20 14:29:55 -05:00
KernelDeimos bb90595431 fix: move dependency in LocalDiskStorageController
LocalDiskStorageController was dependent on putility for TeePromise, but
since putility is a workspace module it's difficult for extensions to
access it (Puter backend core would need to expose it). Since TeePromise
itself is very small and will rarely (if ever) be changed I decided to
move it to a separate package on npm.
2025-11-19 17:08:15 -05:00
KernelDeimos 03db975e3e chore: attempt to disable memoryfs test
The test for memoryfs isn't relevant at the moment because it will be
updated to work with newly refactored filesystem code later.
2025-11-19 17:08:15 -05:00
KernelDeimos 1cb27fb25f dev: make puterfs storage controller configurable 2025-11-19 16:13:26 -05:00
KernelDeimos 91f948f1fc dev: LocalDiskStorageController with upload method
Begin work on LocalDiskStorageController in the `puterfs` extension.
This replaces LocalDiskStorageStrategy and LocalDiskStorageService from
the core. The `upload()` method is implemented to verify that it's
working.

This commit by itself will break other storage strategies. The next step
is to allow extensions to register storage controllers for puterfs. Part
of that work is done in this commit by emitting an event to register
storage controllers, but this commit does not include a way to
configure/select storage controllers.
2025-11-19 16:13:26 -05:00
KernelDeimos d7538cf3c0 refactor: merge FSEntryFetcher with FSEntryController 2025-11-19 16:13:26 -05:00
KernelDeimos d3881f2440 dev: decouple FSEntryFetcher by adding hasChild
Adding the hasChild method of FSNodeContext as well as a corresponding
method to filesystem providers is prerequisite to moving
FSEntryFetcher's logic into the new puterfs extension.
2025-11-19 14:30:42 -05:00
KernelDeimos cdcce31d03 rm: remove DatabaseFSEntryService from core 2025-11-19 14:30:42 -05:00
KernelDeimos 35d32f7fc8 dev(puterfs): move mkshortcut, make ll_rmdir...
...use readdir from the provider instead of calling
fast_get_direct_descendants directly on fsEntryService.

This change is prerequisite to removing FSEntryService from core.
2025-11-19 14:30:42 -05:00
Neal Shah 33a8814feb new gemini models (#1986) 2025-11-18 20:00:34 -05:00
KernelDeimos a50866ec76 dev(puterfs): move get_recursive_size to extension 2025-11-18 15:34:49 -05:00
KernelDeimos c9c745740d dev(puterfs): remove dependency on FSEntryService
This commit was ammended to fix a missing import of Context from 'core'.
2025-11-18 15:34:49 -05:00
KernelDeimos 94032ddafd move(puterfs): take PuterFSProvider out of main.js 2025-11-18 15:34:49 -05:00
KernelDeimos 0db322fda6 chore: move puterfs extension to esmodule 2025-11-18 15:34:49 -05:00
jelveh f51c0740c7 Bump puter.js version to 2.1.6 2025-11-17 12:18:40 -08:00
jelveh e894c694e6 Bump puter.js version to 2.1.5 2025-11-17 09:56:18 -08:00
jelveh 0e5ca01875 Bump puter.js version to 2.1.3 in package.json 2025-11-17 09:55:10 -08:00
jelveh 45cde630a0 puterParent on globalThis instead of window 2025-11-17 09:41:21 -08:00
Neal Shah 3fec2ed351 Move thumbnail mutation to getSafeEntry (#1980) 2025-11-16 21:38:48 -05:00
jelveh 064a5e6c67 Update OpenAI model max_tokens and cost map values 2025-11-14 23:31:53 -08:00
jelveh 968150db7e Update openrouterCostMap.ts 2025-11-14 23:24:17 -08:00
jelveh 0957dd29e7 add all gpt-5.1 models 2025-11-14 23:10:25 -08:00
Neal Shah 52978d4dd6 add puter.tools (#1973) 2025-11-14 14:16:43 -05:00
Nariman Jelveh 545b5a071e Add support for GPT-5.1 model and reasoning controls (#1967)
closes #1966
2025-11-13 19:23:04 -08:00
Toshit Chawda 849beecd4f fix: x86 not booting locally (#1959)
* fix: x86 not booting locally

* use cross instead of the host cargo
2025-11-13 21:01:48 -05:00
Neal Shah 5cad75e85a change claude service max_tokens calculation (#1962) 2025-11-13 13:29:22 -05:00
KernelDeimos 3aadaf8420 fix: explicit actor not passed to fs provider 2025-11-12 15:13:42 -05:00
KernelDeimos ba994f8d88 refactor(backend): remove PuterFSProvider from core 2025-11-12 14:51:21 -05:00
KernelDeimos 8d4f788888 dev(puterfs): move misc methods to extension
The get_capabilities and update_thumbnail methods in PuterFSProvider are
moved to the extension by this commit. This is prerequisite to the
removal of PuterFSProvider in the core.
2025-11-12 14:51:21 -05:00
KernelDeimos 2285f8b553 clean: remove unused from old PuterFSProvider
Now that most of the functionality from PuterFSProvider in core has been
moved to PuterFSProvider in the `puterfs` extension, there are a lot of
unused symbols which need to be cleaned up.

This cleanup reveals that `update_thumbnail` and `get_capabilities` are
the only remaining functions left before PuterFSProvider in core can be
fully removed.
2025-11-12 14:51:21 -05:00
jelveh 6d5f1efce4 Add support for condition image models in Together AI 2025-11-11 20:30:24 -08:00
Nariman Jelveh 7b93d7c15b Add Mistral OCR support and imrpove img2txt API (#1957)
Introduces Mistral OCR integration in backend and updates the `AIInterfaceService` and `MistralAIService` to support new OCR options and response normalization. Updates metering cost map for OCR and annotation usage. Refactors `DriverService` to support interface-specific service aliases. Expands the puter.js `AI.img2txt` API to support flexible options and provider selection, including Mistral OCR.
2025-11-11 17:06:44 -08:00
KernelDeimos fdc8582dde clean: remove log 2025-11-11 19:22:41 -05:00
KernelDeimos 705901fd2b fix: references to global_config in puterfs 2025-11-11 19:22:41 -05:00
KernelDeimos ea3dbcd411 dev(puterfs): move write_overwrite to extension 2025-11-11 15:32:03 -05:00
KernelDeimos a2cebf8c5b refactor(backend): migrate FileCacheService
FileCacheService was still a legacy service extending AdvancedBase. This
commit changes it to extend BaseService and implement the lifecycle
methods consistent with other services. This is a prerequisite for
moving write_overwrite which needs to import the service via
`extension.import` (not possible for legacy services) so that it may
invalidate file cache when a file is written to.
2025-11-11 15:32:03 -05:00
KernelDeimos bd81c533bc dev(puterfs): move write_new to extension 2025-11-11 15:32:03 -05:00
KernelDeimos 689fb91a0e dev(extensions): expose extension.errors API 2025-11-11 15:32:03 -05:00
Het Savani 2b8081d100 Fix: missing published/attached website icon for folder on different views (#1764) (#1945) 2025-11-10 22:28:10 -08:00
Neal Shah bb2c78ae2d Add failsafe incase max_tokens is 0 or negative for a model (#1954) 2025-11-09 19:22:34 -05:00
Neal Shah 3c3367ca52 Autodiscover ollama support (#1953) 2025-11-09 18:51:07 -05:00
Neal Shah 0077944bd4 Openrouter reasoning fixes (#1951)
* Fix for OpenRouter reasoning models
2025-11-09 15:33:36 -05:00
vipul264og 65c213f9a7 Add Punjabi (ਪੰਜਾਬੀ) translation README (#1944) 2025-11-09 00:25:19 -08:00
KernelDeimos 47f7c1146e tweak(apitest): reduce benchmark size
We want this to be fast enough that this benchmark doesn't take a long
time, but part of the effort of making it faster will be running the
benchmark repeatedly, and if it takes a long time then it will take
longer for us to make it faster.

This commit reduces the benchmark size for stat_intensive and
write_intensive so that they don't take several minutes to complete.
2025-11-09 00:37:23 -05:00
Hariz S. 7d78381fe1 Re-add direct download via URL parameter (#1914)
* Re-add direct download via URL parameter

* Add comments

* Confirm before downloading remote file

* Allow aborting remote downloads

* Preemptively add AbortController to fetch call
puter.net.fetch currently doesn't support it (yet!)

* Add filename to download dialog/progress dialogs
2025-11-07 23:32:06 -08:00
Eric Dubé e5e242512f Revert "docs: add complete French translation of README (#1936)"
This reverts commit cb60b0b1d8.
2025-11-07 17:53:48 -05:00
KernelDeimos 54310ad0ab chore: remove rollup, always use webpack
These two issues have affected us, but go away without rollup:
- https://github.com/npm/cli/issues/4828
- https://github.com/rollup/rollup/issues/6168

We can just use webpack instead; it has never caused build/npm issues.
This migration was done using AI, by pasting error messages over and
over again until everything worked. Since we're not actively working on
terminal and phoenix (dependents of rollup) currently it doesn't make
sense to focus on doing this migration manually, and any errors not
observed in basic use can be remedied later.
2025-11-07 17:17:54 -05:00
Daniel Salazar 7e21aad986 docs: prefix together ai model (#1939) 2025-11-07 12:23:56 -08:00
vipul264og cb60b0b1d8 docs: add complete French translation of README (#1936)
- Added a full French translation of the main README.
- Preserved all formatting, links, code blocks, and HTML elements.
- Ensures feature parity with the English version for French-speaking users.
2025-11-07 08:11:49 -08:00
Daniel Salazar 3592c4bfe8 chore: ts lint stuff (#1934) 2025-11-06 15:26:40 -08:00
KernelDeimos e602e5f6cc ux(gui): use standard color picker in theme dialog 2025-11-06 18:05:59 -05:00
KernelDeimos 8c9dfb880f dev(puterfs): move readdir to extension 2025-11-06 17:14:09 -05:00
KernelDeimos 7988dc9adf dev(puterfs): move 'move' to extension 2025-11-06 17:14:09 -05:00
Daniel Salazar 5d1d5125ab performance: batch metering service usage increments when relevant (#1930) 2025-11-06 12:32:47 -08:00
Nariman Jelveh c21b0a1f6e Revert "feat: Settings and modal UI/UX improvements (#1828)" (#1931)
This reverts commit 191916321b.
2025-11-06 11:32:56 -08:00
Utku 191916321b feat: Settings and modal UI/UX improvements (#1828)
* feat: comprehensive settings and modal UI/UX improvements

Redesigned settings interface and modal windows with improved visual
hierarchy, spacing, and modern styling throughout the application.

Settings UI improvements:
- Enhanced section headers with proper flexbox layout and centering
- Simplified storage usage display to single percentage with clearer info
- Improved settings cards with consistent spacing and hover states
- Redesigned session manager with horizontal card layout
- Reordered account settings (username → email → password)
- Removed duplicate password option from security tab

Form and input improvements:
- Increased container padding (20px → 24px) for better breathing room
- Tightened label-to-input gap (8px → 6px) for better visual grouping
- Enhanced labels with bolder weight (500 → 600) and refined color
- Larger input fields (12px 14px padding) with smoother corners (6px)
- Added hover states with border color transitions
- Removed distracting box-shadow focus rings across all inputs/selects

Button improvements:
- Modernized primary buttons with solid colors (removed gradients)
- Added flexbox centering for consistent text alignment
- Reduced button text size (13px) for cleaner appearance
- Improved default button styling with refined gray palette
- Better active/hover state transitions

Select dropdown improvements:
- Custom SVG chevron arrow with proper 12px right spacing
- Fixed select resizing issue on focus (removed global border/padding override)
- Full-width selects in modals with consistent styling
- Smooth hover states without size changes

Modal windows:
- Consistent 380px width for form modals, 400px for desktop bg settings
- Unified .settings-form-container class across all modals
- Proper ARIA labels and semantic HTML structure
- Error/success messages with refined colors and better contrast

Desktop background settings:
- Color blocks increased to 32px for easier interaction
- Fixed focus outline clipping with proper overflow handling
- Removed scale effects for cleaner interactions
- Flexbox layout for color grid with proper spacing
- Fixed palette icon display with inline background image

Window chrome:
- Increased default shadow (0 12px 24px, 0.12 opacity)
- Enhanced active window shadow (0 16px 40px, 0.18 opacity)
- Better visual depth and window hierarchy

File organization:
- Moved UIWindowManageSessions to Settings folder
- Created helpers/build_settings_card.js for reusable components
- Updated all imports to reflect new structure

* bring back shadow

* improve 2fa + fix theme not changing on cancel bug + fix couple more issues

* style polish

* remove unused styles

* i18n

* fix search bar clipping

* group reset & customize color buttons

* more polish

* enforce min width/height on resizable

* resizable settings and show full name on hover

* style tweaks
2025-11-06 10:14:32 -08:00
2400032286 ac47753879 Fix formatting: Add space after slash in German translation (#1925)
Changed 'German/ Deutsch' to 'German / Deutsch' to match the formatting style of all other translation entries in the list.
2025-11-06 10:08:10 -08:00
Reynaldi Chernando 03860ab779 Add missing puter env enums (#1926) 2025-11-06 10:07:52 -08:00
Nariman Jelveh 12e88e2c04 Revert "Add hindi readme (#1927)" (#1929)
This reverts commit b3f8e11be9.
2025-11-06 10:07:31 -08:00
Nariman Jelveh e4d60670a3 Revert "Add hindi readme (#1927)" (#1928)
This reverts commit b3f8e11be9.
2025-11-06 10:03:40 -08:00
PARTH PRATYUSHandsirparth b3f8e11be9 Add hindi readme (#1927)
* Added Hindi translation of README

* Added Hindi translation of README

---------

Co-authored-by: sirparth <[email protected]>
2025-11-06 10:03:24 -08:00
KernelDeimos 117eda190f dev(puterfs): move copy_tree to extension 2025-11-05 20:09:58 -05:00
KernelDeimos 2b22406181 dev(puterfs): move stat to extension 2025-11-05 20:09:58 -05:00
KernelDeimos 6a2cac5d57 fix: incorrect implementation of ll_mkdir
When ll_mkdir functionality was moved to PuterFSProvider, ACL and FSLock
concerns were erroneously moved into PuterFSProvider. The intended
design has ll_mkdir responsible for ACL and FSLock, and providers should
never be responsible for ACL.
2025-11-05 20:09:58 -05:00
Daniel Salazar 045ef0a4e7 chore: type fixes (#1920) 2025-11-05 16:32:36 -08:00
KernelDeimos 1877a26c6b dev(puterfs): move mkdir to extension
An important note: it was noticed during this change that mkdir in
PuterFSProvider implements its own ACL check, instead of the ACL check
being performed in ll_mkdir. This means permissions won't be checked for
other implementors of mkdir! This needs to be fixed before custom
filesystem implementations can be considered production-ready.
2025-11-05 19:22:10 -05:00
KernelDeimos 33cba30124 clean(backend): process.exit(1) -> throw new Error 2025-11-05 19:22:10 -05:00
KernelDeimos acb9c4660c dev(puterfs): move quick_check to extension 2025-11-05 19:22:10 -05:00
KernelDeimos f2ad7ddfb5 dev(puterfs): move read to extension 2025-11-05 19:22:10 -05:00
Daniel Salazar 0fd7100795 fix: allow mysql json object response (#1918) 2025-11-05 15:22:46 -08:00
KernelDeimos 656a01f2fa fix: error calling .startsWith on null mime_type
According to the package documentation: https://www.npmjs.com/package/mime
> null is returned in cases where an extension is not detected or recognized

This call to `.startsWith()` was causing an exception to be thrown upon
right-clicking files without an extension, making it impossible to fix
them.
2025-11-05 18:13:15 -05:00
KernelDeimos 75073403f8 clean: remove rmnode and lint PuterFSProvider 2025-11-05 16:06:35 -05:00
KernelDeimos 215bc9020b lint: configure eslint not operator spacing
The styleguide for Puter's backend expects spaces after top-level not
operators inside conditions. This commit adds an AI-generated eslint
plugin and, since it conflicts with the existing space-unary-ops plugin
from stylistic, also adds a wrapped version of space-unary-ops that
ignores top-level not operators so that this plugin will work as
expected.
2025-11-05 16:06:35 -05:00
KernelDeimos e8d9b7b35d dev(puterfs): move rmdir to extension 2025-11-05 16:06:35 -05:00
jelveh 3b3b9d0ee0 closes #1911 2025-11-05 07:58:20 -08:00
Nariman Jelveh cbbc4ce359 improve window snap logic to have delayed trigger 2025-11-04 21:44:10 -08:00
Daniel Salazar 490cd45336 fix: bad wrapper wrap (#1908) 2025-11-04 20:16:14 -08:00
KernelDeimos d7ea6769cb fix: check if system_prompts is an empty array
It was assumpted that `system_prompts[0]` could not be undefined which
is not accurate because sometimes there are no system prompts.
2025-11-04 22:32:57 -05:00
KernelDeimos b853383c6e clean: remove debug log from puterfs.unlink 2025-11-04 21:32:41 -05:00
KernelDeimos a5c26eaece clean: remove verbose log for getUserSubscription 2025-11-04 21:32:41 -05:00
KernelDeimos a0ff03b13d dev: implement unlink in puterfs extension 2025-11-04 21:32:41 -05:00
KernelDeimos 24b1570007 refactor: make TraceService a proper service
This service was registered within FilesystemService for legacy reasons
but now it needs to be accessed by an extension. In order for the
extension import to work as expected this service needs to be registered
at the same phase as other services.
2025-11-04 21:32:41 -05:00
KernelDeimos e7357054b0 fix: undefined svc_fs
This fixes PD incident Q3ZNFWILVOFKU3. This issue was not caught in
testing - in fact after deleting a user the files were deleted as
expected, but it's unclear to me how I observed that with this issue
present.
2025-11-04 21:32:41 -05:00
KernelDeimos 4b959f3f4b dev: add proxy for PuterFSProvider
This temporary proxy provider will allow methods of the puterfs
filesystem type to be moved to an extension incrementally instead of all
at once. See comment above the class for a more detailed explanation.
2025-11-04 21:32:41 -05:00
Daniel Salazar 5ff8c7e040 feat: rawBody parser, user metadata column + other misc fixes (#1904) 2025-11-04 18:19:55 -08:00
KernelDeimos cc7369d9d7 fix: also check this.entry.id when checking mysql_id
There is a case where this.entry.id has a value in FSNodeContext while
this.mysql_id does not. I was under the impression that this state was
not possibole. The cause of this eludes me. This commit does not correct
the root cause - it only adds a workaround to this issue by falling back
to this.entry.id if this.mysql_id is `undefined`.
2025-11-04 21:05:16 -05:00
KernelDeimos a44e1fc074 fix: access internal ID without assuming fetch
It might not be okay to assume an fsentry was already fetched when
updating the accessed time in ll_read. I'd like to know what changed
this to make this be the case, if it happens to be the case.
2025-11-04 20:34:44 -05:00
KernelDeimos 19314d6496 sync: implement read in MemoryFS 2025-11-04 13:58:46 -05:00
KernelDeimos 875ecc051b clean: remove dead code from ll_write
The `_storage_upload` method in ll_write.js is no longer used, which
also means the LLWriteBase class is no longer necessary.
2025-11-04 13:58:46 -05:00
KernelDeimos d936fc47b0 dev: move read implementation to PuterFSProvider 2025-11-04 13:58:46 -05:00
KernelDeimos db8f45f386 fix: rm another ref to storage, rm dupe meter
There were two references to `storage` in file.js but the search string
I used only detected one of them. I was looking for more references to
`storage` when I found this one. Also, I realized the metering updates
in file.js become redundant if ll_read is used instead so I've removed
those as well.
2025-11-04 13:58:46 -05:00
Nariman Jelveh f823eddfa5 make together.ai image and video models work! (#1881)
* make together ai image models work!

* add video models too!

* add costmaps for together ai image and video
2025-11-03 19:13:39 -08:00
Neal Shah aa8860b3ea Add cache_control support and haiku 4.5 (#1897)
* Add cache_control support and haiku 4.5
2025-11-03 17:52:03 -05:00
Nariman Jelveh 9ae4e7227b Revert "fix(i18n): complete and clean up German translation (#1893)" (#1898)
This reverts commit 4e91774b95.
2025-11-03 14:33:42 -08:00
POLKAM ARAVIND 4e91774b95 fix(i18n): complete and clean up German translation (#1893) 2025-11-03 14:33:25 -08:00
Reynaldi Chernando c82a7a0bf9 Add monthly and detailed app usage types (#1843) 2025-11-02 17:51:25 -08:00
jelveh 52751d5002 make Settings window resizable
fixes #1852
2025-11-02 14:52:10 -08:00
Daniel Salazar 85432c886e fix: adding more benign changes (#1891) 2025-11-02 06:48:56 -08:00
Daniel Salazar 11d2515cb2 fix: ts issue when building for deploy (#1890) 2025-11-02 06:36:02 -08:00
Daniel Salazar e8e8fa92c2 cleanup: more benign changes (#1889) 2025-11-02 06:30:30 -08:00
Daniel Salazar 93aaeef9e0 fix: add back non-functional changes (#1888) 2025-11-02 06:17:59 -08:00
Daniel Salazar 758bef0582 Revert: commits for user metadata changes (#1887) 2025-11-02 06:09:13 -08:00
Daniel Salazar 823c06c371 fix: don't set metadata until migration (#1886) 2025-11-02 04:42:08 -08:00
Daniel Salazar 89a3a3228f fix: bad amount of sql params (#1880) 2025-11-01 17:52:43 -07:00
Daniel Salazar 98cf4bbb08 fix: bad amount of sql params (#1879) 2025-11-01 17:48:54 -07:00
Daniel Salazar 7085bcbb93 fix: bad naming (#1878) 2025-11-01 17:42:22 -07:00
Daniel Salazar 71fb04cd55 fix: allow stripe header and commit db migration (#1877)
* fix: allow stripe header

* fix: commit db migration
2025-11-01 16:16:49 -07:00
Xiaochen Cui a0cd6ed781 ci: expose server logs (#1860) 2025-10-31 15:56:49 -07:00
Xiaochen Cui 38aa9009af ci: disable job "puterjs (browser env, playwright)" (#1871) 2025-10-31 15:56:21 -07:00
Daniel Salazar 603746951b feat: ui for dev account + util decorators for controllers in extension (#1864)
* fix: IPC trigger for dev account setup + util decorators for ext controllers

* feat: allow extension to bypass json

* fix: ts building in volatile
2025-10-31 15:48:21 -07:00
KernelDeimos 7cc79077d1 fix(fs): better errors for unresolved selectors
Adds an appropriate error at a couple different levels. The first is in
FilesystemService. Callers of FilesystemService.node are expected to
provide either an absolute path or an instance of a filesystem node
selector, but there wasn't an explicit check for this so instead an
arbitrary error (read property of undefined) would be thrown. The second
is a higher-level APIError in the batch executor that's a bit more
helpful than a 500 Internal Server Error.
2025-10-31 15:26:15 -04:00
Nariman Jelveh d6a168e402 Revert "Update Norwegian Nynorsk translations in nn.js (#1859)" (#1874)
This reverts commit 783cd24e8b.
2025-10-31 11:33:20 -07:00
Palla. Gnana Sai KiranandGnanasaikiran 783cd24e8b Update Norwegian Nynorsk translations in nn.js (#1859)
Co-authored-by: Gnanasaikiran <[email protected]>
2025-10-31 11:33:06 -07:00
KernelDeimos 08e9ab399a clean: use window.sleep in place of setTimeout
Also another change to make duration handling consistent for the two
blocks of code that have the "ensure 2 seconds" logic.
2025-10-30 19:40:50 -04:00
KernelDeimos e37e009305 refactor: reduce indentation and arithmetic
This commit reduces the indentation level and complex arithmetic inside
the createTempUser function in initgui. It is suspected that this change
should greatly reduce measures of the "cognitive complexity" metric.
2025-10-30 19:03:39 -04:00
KernelDeimos 52d4ca6caf fix: according to jquery spec, this is more robust
Apparently the callback operand of $.fn.fadeOut may be called more than
once if there are multiple matching elements. Although we expect there
to only be one element matching the selector `".captcha-modal"`, someone
editing the CSS and HTML would not expect such consequences to the
logic of captcha.
2025-10-30 19:03:39 -04:00
KernelDeimos ec505366e6 fix: do not animate non-existing captcha modal
Calling `.fadeOut()` on the result of a jquery selector (i.e. the
evaluation of `$('.some-element-class')`, when it returns an object with
`length=0`) is a NOOP. That's right, it doesn't throw an error; it just
does nothing. This was preventing a temporary user from being created
when `.captcha-modal` isn't present because [the code intended to execute
after the animation] was never run. (square brackets for clarity because
the English is inherently ambiguous)
2025-10-30 19:03:39 -04:00
jelveh e70c871c4d Update ExecService.js 2025-10-30 14:55:14 -07:00
jelveh 9b7c4205fe I swear taskbar is fixed now 2025-10-30 13:02:32 -07:00
KernelDeimos c12485995a dev: restore simplification in api.d.ts
The PR I merged before putting this one up had my changes to api.d.ts
which I thought where on this branch - turns out I only thought that
because this branch had that one as a parent.

However #1818 has a simplification that this change overwrites. I'd like
to keep this simplification so this commit is restoring it.
2025-10-30 14:06:28 -04:00
KernelDeimos 571cd91380 dev: update deleteUser to use FS provider
The previous implementation of deleteUser was hard-coded to use the
PuterFSProvider file system type's storage implementation specifically,
even if a different filesystem type is mounted as root or for a
particular user.

This change was tested by creating a user, adding some fsentries, and
then deleting that user. The following classes of filesystem entry were
checked:
- [x] user created directory (with contents)
  - [x] directory fsentry was deleted
- [x] user created directory (empty)
  - [x] directory fsentry was deleted
- [x] immutable directory
  - [x] directory fsentry was deleted
- [x] user created file
  - [x] file fsentry was deleted
  - [x] file storage was deleted
- [x] user created file in trash
  - [x] file fsentry was deleted
  - [x] file storage was deleted
2025-10-30 14:06:28 -04:00
KernelDeimos 896082ba62 refactor: use ll_read in file.js
Accessing the storage object directly duplicates effort of locating the
correct filesystem provider based on the mountpoint of the file with the
contents being requested; an effort that file.js did not perform which
made it incompatible with filesystem mountpoints.

This change has been made to make it easier to move filesystem type
implementations to extensions, because accessing storage directly will
not be supported after puterfs is an extension.
2025-10-30 14:06:28 -04:00
Xiaochen Cui 831d9017de ai: return reasoning tokens in the streaming mode (#1356) 2025-10-30 10:47:30 -04:00
jelveh 5d22ad1edb Update UIWindow.js 2025-10-29 18:30:36 -07:00
Nariman Jelveh 64f86daddb feat: add speech2text (#1855)
- A new stt driver in `AIInterfaceService` and `PuterAIModule`.
- added methods for audio transcription and translation in the speech-to-text interface.
- updated cost mapping for stt models in `openAiCostMap.ts`.
- Updated permissions and interfaces to support new speech-to-text features.
2025-10-29 12:04:09 -07:00
Nariman Jelveh b6af2df257 Revert "Complete Traditional Chinese translations (#1501) (#1822)" (#1856)
This reverts commit ff7f6d7f94.
2025-10-28 23:04:29 -07:00
Arun kumarandArun24-8 ff7f6d7f94 Complete Traditional Chinese translations (#1501) (#1822)
Co-authored-by: Arun24-8 <[email protected]>
2025-10-28 23:04:10 -07:00
Nariman Jelveh 861aeddf3e feat: add OpenAI support to text-to-speech (#1853)
- added support for OpenAI as a tts provider in `AIInterfaceService` and `PuterAIModule`.
- Updated cost mapping for OpenAI tts models in `openAiCostMap.ts`.
- improved `Txt2SpeechOptions` interface to include new parameters for provider, model, and response format.
- added tests for OpenAI provider in `txt2speech.test.js` to ensure functionality.
2025-10-28 18:51:04 -07:00
Daniel Salazar 62b6582d85 feat: meter ll_read for the person reading (#1854) 2025-10-28 18:35:27 -07:00
Nariman Jelveh 0507f1782d Merge branch 'main' of https://github.com/HeyPuter/puter 2025-10-28 17:09:40 -07:00
Nariman Jelveh 507b6d343e Fix multiple issues with taskbar and windows being affected by the side panel 2025-10-28 17:09:28 -07:00
Xiaochen Cui c93a53ead2 ci: init e2e test for browser env, tidy other tests (#1796)
* ci: init e2e test for browser env

stash changes

* test: update fsentry definition, add tests

stash changes

* test: pass puter-js mkdir test

* test: add test for puter-js move

* tidy code

* tidy code

* doc: add docs for playwright test

* recover memoryfs

* test: puter-js readdir/stat

* test: puter-js write

* test: puter-js read

* test: puter-js move_cart

* test: fix failed tests on move

* tests: rename files

* test: puter-js copy_cart

* tests: puter-js batch/delete, read config from file

* ci: add vitest

* ci: update names and timeout

* ci: simplify playwright-test

* ci: simplify api-test

* move "api-tester" from tools to tests

* test: update example config

* test: remove folder tests/api-tester/ci

* test: unify config location

* test: remove unused files

* ci: fix wrong config

* ci: fix wrong path

* test: add docs

* ci: update timeout, print artifact url
2025-10-28 16:35:37 -07:00
Eric Dubé c3d66503ab dev: add /update-fsentry-thumbnail (#1794) 2025-10-28 17:31:17 -04:00
Daniel Salazar 0bb14261c2 feat: devCenter open ui message (#1850) 2025-10-28 13:41:00 -07:00
Nariman Jelveh d7f10b2205 Update call.js (#1849) 2025-10-28 13:25:07 -07:00
Daniel Salazar ff9932b2f3 fix: dbkv raw import (#1848) 2025-10-28 13:04:54 -07:00
Nariman Jelveh b1e3430a9d Set correct URL for test video in txt2vid 2025-10-27 19:00:40 -07:00
Reynaldi Chernando 117f8e393d Add UploadOptions for Puter.js types (#1832)
* Add UploadOptions

* Add name option
2025-10-27 18:15:27 -07:00
Daniel Salazar d1ae2bfe80 chore: update typedefs and fix dbkv issue (#1840)
* chore: update typedefs

* fix:dbkv decr
2025-10-27 18:13:49 -07:00
KernelDeimos cd5d0ca5dc dev(extensions): [+] puterfs (copies memoryfs)
This extension has a copy of memoryfs which is exposed as `testfs`. The
purpose of this is to register a new filesystem type from an extension
to ensure it works as expected and to get feedback on a working example.
2025-10-27 19:54:36 -04:00
KernelDeimos dda1c00614 dev(extensions): exports and types for FS 2025-10-27 19:54:36 -04:00
KernelDeimos a36b76e030 dev(extensions): event to register FS providers 2025-10-27 19:54:36 -04:00
Hariz S. 2487251bb9 Improved public folder file links (#1687)
* Don't update URL when opening public files via direct URL

* Alert user when attempting to open a nonexistent file

* Fix toolbar autohide in public file urls

* Remove extraneous debug logs

* Properly define stat var in public folder URL handling

* Update window URL when focusing an app opened through file URL

* Localize error messages
2025-10-27 15:35:11 -07:00
Daniel Salazar fd8a88b8f4 fix: lessen alert triggering for metering (#1837) 2025-10-27 12:41:48 -07:00
Nariman Jelveh 2c7343115a Add sora 2 support (#1834)
* Update OpenAI package to version 6.7.0 and add video generation capabilities

- Updated `openai` dependency in `package-lock.json` and `package.json`.
- Introduced new permissions for video generation in `hardcoded-permissions.js`.
- Added video generation service in `AIInterfaceService.js` and registered it in `PuterAIModule.js`.
- Implemented coercion for video streams in `CoercionService.js`.
- Updated driver service to include video generation.
- Added `txt2video` method and options in `AI.js` and corresponding TypeScript definitions in `index.d.ts`.

* Update openaiVideoCostMap.ts

* Revert "Update openaiVideoCostMap.ts"

This reverts commit 9e66f93605.

* change `txt2video` to `txt2vid`
2025-10-27 12:27:52 -07:00
Nariman Jelveh 5ae8ed98eb Fix issues with Settings accessibility 2025-10-26 17:42:56 -07:00
Nariman Jelveh bce244b867 Remove taskbar item animation 2025-10-26 17:12:21 -07:00
Nariman Jelveh 3720369d87 default txt2img model set to gpt-image-1-mini 2025-10-26 11:52:28 -07:00
Nariman Jelveh 5476389795 add support for gpt-image-1-mini 2025-10-26 11:33:44 -07:00
Eric DubéandNariman Jelveh b73764d210 more reliable suspended (#1696)
* fix: remove verbose parameters log

* fix: more reliable check for suspended user

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-10-25 16:27:36 -07:00
NUDURUMATI H R N PRASANNA SAVITHRUandNariman Jelveh 6edb2a30e7 chore: update phrasing based on review (#1821)
* chore: update phrasing based on review

* Update nb.js

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-10-25 16:11:40 -07:00
Nariman Jelveh 46cb188877 Update ig.js 2025-10-25 15:11:08 -07:00
Reynaldi Chernando e11182f817 Add dedupeName to CreateAppOptions (#1783) 2025-10-25 15:09:25 -07:00
Tamalampudi Siva Harsha Vardhan ReddyandNariman Jelveh 1bfdab8825 i18n(ig): translate missing entries in src/gui/src/i18n/translations/… (#1820)
* i18n(ig): translate missing entries in src/gui/src/i18n/translations/ig.js

* add missing double quotes

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-10-25 15:07:48 -07:00
Neal Shah 20601ce5e4 fix: Switch to new OpenAI Moderation model (#1826) 2025-10-24 19:13:18 -04:00
Neal Shah d0c5f12682 optimization: change for (msg.. messages) in moderation to pass in everything in one call (#1825) 2025-10-24 17:44:15 -04:00
Daniel Salazar 3fb3cf0e60 fix: simplify export import typedef (#1818)
* fix: simplify export import typedef

* feat: expose kvstore methods in the service too

* chore: update versioning
2025-10-24 12:52:58 -07:00
Eric Dubé 1a1e9e8bb2 dev: add event to mutate app origin (#1823)
* dev: add event to mutate app origin

* fix: location of app origin event
2025-10-24 14:09:13 -04:00
Daniel Salazar 219fd2274c feat: allow for unlimitedAllowList + typedefs snuck in by accident (#1813)
* feat: allow for unlimitedAllowList

* feat: add clearer types to extensions
2025-10-23 13:57:32 -07:00
XiaochenCui ce38983e73 memoryfs: fix wrong args for fs.node 2025-10-23 15:05:47 -04:00
XiaochenCui 4fdca1e47b ci: capture the error during setup 2025-10-23 15:05:47 -04:00
Nariman Jelveh c4d4bc9758 remove progwin for desktop mkdir (#1814) 2025-10-22 18:52:35 -07:00
Daniel Salazar 256189a7de feat: route for global usage aggregate (#1810)
* feat: route for global usage aggregate

* feat: add globalUsageEndpoint to puter-js

* fix: globalUsage endpoint
2025-10-22 16:46:13 -07:00
Daniel Salazar c9ab01cf1e fix: usage limited issue whens treaming (#1806) 2025-10-22 11:22:59 -07:00
KernelDeimos 5b16774a9a fix: throw error not lorem when moderation fails
Instead of switching to test mode, which responds with "Lorem Ipsum"
sample output to test the API, throw an appropriate error message for
content moderation failures. This is especially useful when OpenAI's
moderation is way way way way too aggressive as this confuses users.
2025-10-22 13:59:53 -04:00
KernelDeimos 16e7fe9851 fix: openai configuration regression
I was not able to locate a change causing a configuration regression,
however I do know AI was working in my OSS clone and that I had no
reason to change my AI configuration in my `local.json` file. In any
case, it is clear that configuration was not working as intended.

This commit fixes PuterAIModule which was not enabling OpenAI services
when `openai` was configured within the `services` block, even though
the `services` block configuration is supposed to be the recommended
configuration and the global `openai` config object is supposed to be
deprecated.

This commit also fixes OpenAIImageGenerationService which was not
accepting the current parameter name for the API key (`apiKey`) and
instead only accepted the legacy key (`secret_key`) which created this
interesting problem where using the recommended parameter name would
prevent Puter from booting successfully.
2025-10-22 13:59:53 -04:00
KernelDeimos 06d6eb83e7 doc: dependencies when moving PuterFS to extension
This commit begins the plan towards moving PuterFS to an extension. It
is first necessary to analyze the dependencies and determine which
services and modules are part of PuterFS and which ones are not.
2025-10-22 13:59:40 -04:00
KernelDeimos b80c0ba79e chore: puter.js version 2.1.1 2025-10-22 13:59:19 -04:00
KernelDeimos 547acf6988 Revert "patch version bump for puter-js and putility in it"
This reverts commit 55d07acdee.
2025-10-22 13:59:19 -04:00
jelveh 55d07acdee patch version bump for puter-js and putility in it 2025-10-22 10:44:50 -07:00
KernelDeimos d398dc90fd chore: putility patch version 1.1.1 2025-10-22 13:32:56 -04:00
KernelDeimos 4a69cd26c2 chore: putility minor version 1.1.0 2025-10-22 13:18:34 -04:00
KernelDeimos ecad29a30e sync: update license headers in putility
The `putility` package had AGPL-3.0 license headers but it should be
under the MIT license because puter.js (the SDK) depends on it.
2025-10-22 13:18:34 -04:00
Eric Dubé c375b30810 Update putility to MIT
Huh, I thought it was already...
2025-10-22 12:18:55 -04:00
Daniel Salazar 9394b5e204 docs: metering and examples (#1803)
* chore: expose meteringService methods in wrapper while not in an extension

* docs: metering and examples
2025-10-21 17:25:46 -07:00
Daniel Salazar 16fd614b84 feat: rename meteringAndBilling to metering (#1800) 2025-10-21 14:59:24 -07:00
Daniel Salazar 435d26608a feat: shard apps as well to avoid hot partitions (#1799) 2025-10-21 13:30:34 -07:00
Daniel Salazar 6bbd9bdc9f feat: limit alerting (#1798) 2025-10-21 12:50:38 -07:00
Daniel Salazar 3229fe0b61 Revert "Revert: fs metering (#1790)" (#1795)
This reverts commit 4b14ef863c.
2025-10-21 11:07:05 -07:00
Daniel Salazar 4b14ef863c Revert: fs metering (#1790) 2025-10-20 21:58:44 -07:00
Daniel Salazar 760bc22743 fix: bad acl check returning early (#1789) 2025-10-20 20:13:43 -07:00
Daniel Salazar 0260a9cbce Revert "Revert "Revert "Revert "feat: alert when going over usage limits sign…"
This reverts commit f2265cca59.
2025-10-20 18:45:08 -07:00
Daniel Salazar f2265cca59 Revert "Revert "Revert "feat: alert when going over usage limits significantl…" (#1787)
This reverts commit 0d0cdce1cf.
2025-10-20 16:51:31 -07:00
Daniel Salazar 0d0cdce1cf Revert "Revert "feat: alert when going over usage limits significantly + egre…" (#1786)
This reverts commit 54d73b1998.
2025-10-20 15:56:34 -07:00
Daniel Salazar 54d73b1998 Revert "feat: alert when going over usage limits significantly + egress meter…" (#1785)
This reverts commit 27f24118f3.
2025-10-20 15:25:52 -07:00
Daniel Salazar 27f24118f3 feat: alert when going over usage limits significantly + egress metering (#1782)
* feat: alert when going over usage limits significantly + meter egress/ingress

* fix: metering roundings
2025-10-20 13:54:21 -07:00
Nariman Jelveh eb123d873f feat: introduce PANEL_WIDTH constant and refactor UIWindow for panel handling (#1780)
Added a constant for PANEL_WIDTH to standardize panel width across the application. Refactored UIWindow logic to utilize this constant for positioning and resizing, ensuring consistent behavior when panels are open. Restored the getSnapDimensions function to adjust available dimensions based on the taskbar position and open panels.
2025-10-17 18:43:59 -07:00
Neal Shah 3184e01307 add puter.workers.getLoggingHandle (#1779) 2025-10-17 17:03:57 -04:00
Xiaochen Cui d7a0a81991 ci: avoid potential hanging via hard limit (#1778)
* ci: avoid potential hanging via hard limit

* ci: remove build phase

* ci: print tmp_password for test
2025-10-17 12:29:56 -07:00
jelveh 76dcdd4927 Refresh the stat cache regularly 2025-10-16 20:57:23 -07:00
Nariman Jelveh 0713599281 Update stat.js (#1753) 2025-10-16 20:41:40 -07:00
Reynaldi Chernando 5a8f06db9e Remove fixed width in publish website input (#1747) 2025-10-16 20:40:40 -07:00
Xiaochen Cui 103bac32d8 ci: add timeout for api-test (#1768) 2025-10-16 20:15:22 -07:00
KernelDeimos 31fa030a38 devex: use 'stars' style for webserver notice
This change is made to make notices more consistent as well as presented
in a way that works well with dark and light terminal color schemes.
2025-10-16 20:09:37 -04:00
Nariman Jelveh 8fc533338a implement an extension event for IPC messages coming in (#1776) 2025-10-16 16:52:01 -07:00
Daniel Salazar 686c2bc966 fix: permission writeback to flat kv perissions (#1774) 2025-10-16 16:30:17 -07:00
KernelDeimos 1404f10333 devex: remove verbose logging on copy and paste 2025-10-16 19:17:53 -04:00
Nariman Jelveh d2346ff1c7 cleanup usage reporting (#1772) 2025-10-16 15:25:33 -07:00
KernelDeimos 9529d87e31 devex: add log tracing feature
simply set `trace_logs` to `true` in your config and you can easily
figure out where logs are coming from.
2025-10-16 18:00:04 -04:00
KernelDeimos dc6a931a23 fix: error logs are too verbose
There were some extra logs when an error triggers an alarm that don't
need to be there.
2025-10-16 18:00:04 -04:00
KernelDeimos 294fda2433 devex: cosmetic log fixes 2025-10-16 18:00:04 -04:00
KernelDeimos 68d3ccc774 devex: misc. log changes
- removes extra log from dev socket service
- changes SYSTEM logs so they don't look like warnings
- adds optional hiding of INFO label
2025-10-16 18:00:04 -04:00
KernelDeimos da0228b19f devex: hide system actor from extension log fields 2025-10-16 18:00:04 -04:00
KernelDeimos 6cdf91fbc9 devex: add log level support for extensions 2025-10-16 18:00:04 -04:00
KernelDeimos fd602aabac devex: get extensions on the service logger 2025-10-16 18:00:04 -04:00
KernelDeimos abcb2e9580 dev: handle 'console.log' through log service 2025-10-16 18:00:04 -04:00
KernelDeimos 13a70f5394 devex: update notices and better ANSI handling 2025-10-16 18:00:04 -04:00
KernelDeimos 5e6b628491 devex: more log reduction (2) 2025-10-16 18:00:04 -04:00
KernelDeimos 77b167eb0a doc: document the dev socket 2025-10-16 18:00:04 -04:00
KernelDeimos cd279f7355 devex: more log reduction 2025-10-16 18:00:04 -04:00
KernelDeimos 3a8bab920d devex: remove logs that print when uploading 2025-10-16 18:00:04 -04:00
KernelDeimos c6dc55d362 devex: add support for 'stars' to notice() 2025-10-16 18:00:04 -04:00
KernelDeimos 0373f20de6 devex: misc. log cleanups 2025-10-16 18:00:04 -04:00
Nariman Jelveh b1f70fa63e Put some stars around the credentials box 2025-10-16 18:00:04 -04:00
KernelDeimos 8efecdec18 devex: update default admin password output 2025-10-16 18:00:04 -04:00
KernelDeimos 482d88639c doc: document log configuration 2025-10-16 18:00:04 -04:00
KernelDeimos 8f05a13918 devex: re-enable Puter logo by default 2025-10-16 18:00:04 -04:00
KernelDeimos b53dc01b45 devex: show full time in dev log output 2025-10-16 18:00:04 -04:00
KernelDeimos 0892e476bd devex: disable dev console by default, add socket 2025-10-16 18:00:04 -04:00
KernelDeimos c68457c91c devex: no more tip of the day unless you ask for it 2025-10-16 18:00:04 -04:00
KernelDeimos afea8fe80d dev: introduce NullDevConsoleService
In the prod environment there is no instance of DevConsoleService. If
methods are called on the service without a check to see if it exists,
this results in "read on undefined" errors that can only be produced in
a prod environment. This was the cause of the issue caused by the
previous log cleanup PR where it looked like "websockets were broken".
The missing undefined check is fixed by #1734, but the change in this
commit will catch future cases.

Additionally, this change will help with moving away from the dev
console.
2025-10-16 18:00:04 -04:00
KernelDeimos 75a759015c devex: introduce service-level log configuration 2025-10-16 18:00:04 -04:00
KernelDeimos 0b6b871144 devex: disable logs for missing fsentries and cache
Often fsentry stats are used to see if an fsentry exists, so fsentry not
found logs are common and expected. This commit disables those by
default. Additionally, logging for cache events is disabled as well,
since those are only helpful when debugging cache specifically.
2025-10-16 18:00:04 -04:00
KernelDeimos 441622d526 devex: make http logs configurable 2025-10-16 18:00:04 -04:00
KernelDeimos 354da08f64 clean: non-functional changes to WebServerService 2025-10-16 18:00:04 -04:00
KernelDeimos 20c9ac7539 sync: package-lock.json 2025-10-16 18:00:04 -04:00
Nariman Jelveh 00e122d3d1 cleanup usage reporting (#1771) 2025-10-16 14:29:57 -07:00
Daniel Salazar 9bdb139f7a fix: bad null check (#1770) 2025-10-16 14:00:20 -07:00
Daniel Salazar c38da86293 fix: bad math check for max consumed credits (#1769) 2025-10-16 13:56:52 -07:00
Daniel Salazar fc7a51bd2f fix: NaN value for consumedPurchaseCredits accounting (#1767) 2025-10-16 13:21:11 -07:00
Nariman Jelveh 74f583024d Improve usage report UI (#1766)
* Update style.css

* take into account credits added to monthly allowances
2025-10-16 13:03:35 -07:00
Daniel Salazar b7cee87370 feat: purchase addons logic in metering (#1765) 2025-10-16 13:02:19 -07:00
Daniel Salazar 08e26af85d feat: enforce new metering + get rid of old methods (#1762)
* feat: enforce new metering + get rid of old methods

* fix: make openrouter metering more robust
2025-10-16 10:33:17 -07:00
Daniel Salazar 15b65dab7d fix: app monthly usage details error (#1761) 2025-10-16 00:50:05 -07:00
Nariman Jelveh 61fbc45e3c Add refresh button for updating usage data in Settings (#1760) 2025-10-15 23:42:18 -07:00
Nariman Jelveh aca1292886 adjust usage table styling (#1759) 2025-10-15 18:49:12 -07:00
jelveh 206633293c Update UITabUsage.js 2025-10-15 12:35:39 -07:00
jelveh 33f9036abc usage unit format hot fix 2025-10-15 12:26:55 -07:00
jelveh 9cdcb2f108 Update UITabUsage.js 2025-10-15 12:21:24 -07:00
Nariman Jelveh ed5d629e02 Detailed usage report (#1752)
* Implement detailed usage report table

- Added `number_format` function for flexible number formatting with options for decimals, separators, and negative formatting.
- Updated `UITabUsage.js` to include a toggle for viewing driver usage details, fetching and displaying usage data dynamically.
- Improved CSS styles for driver usage details to improve layout and interactivity.

* Update style.css

* Refactor driver usage display in UITabUsage.js

- Updated UITabUsage.js to improve the layout of driver usage information, including a new header structure for better organization.
- Added CSS styles for the new header layout and adjusted existing styles for improved visual consistency and interactivity.

* fix progress bar logic
2025-10-15 12:12:45 -07:00
Daniel Salazar b4cafaa5bb fix: alowance typo (#1756) 2025-10-15 12:09:57 -07:00
Daniel Salazar 7e8842e35d feat: add alarms to meteringService if cost for service is unexpectedly 0 (#1755)
* feat: add alarms to meteringService if cost for service is unexpectedly 0

* fix: better sub checks
2025-10-15 12:05:15 -07:00
Daniel Salazar 24a51c59ae fix: metering typos (#1754) 2025-10-15 10:39:18 -07:00
Daniel Salazar e51d0c4600 feat: metering service allowence checks and subscription integration 🚀 (#1749)
* feat: metering allowence checks

* fix: bad math
2025-10-15 02:28:25 -07:00
Daniel Salazar 96a58ced29 metering: new usage endpoint + puter-js changes for it (#1738)
* metering: new usage endpoint

* metering: new usage endpoint + puter-js changes for it
2025-10-14 12:44:40 -07:00
jelveh 2819ec7b06 Update index.js 2025-10-13 00:36:15 -07:00
Nariman Jelveh 661f13fc92 improve caching mechanism by deleting specific caches on item addition in FileSystem module (#1745) 2025-10-12 19:50:48 -07:00
Neal Shah 8bf13b1b82 add guard around sending thumbnail event if thumbnail url is blank or falsey (#1744) 2025-10-12 20:18:41 -04:00
Neal Shah 9e0ba954ff fix npm pacjage not importing init.cjs (#1743) 2025-10-12 19:46:04 -04:00
jelveh 6a72c261e2 closes #1722 2025-10-12 16:28:12 -07:00
Nariman Jelveh f083e6b060 Improve puterjs caching (#1739)
* add regular cache checking for popular directories

* Update index.js

* implement `readdir` request deduplication to improve performance

* Update index.js
2025-10-11 21:03:38 -07:00
Nariman Jelveh 35507b33b7 taskbar positioning hotfix 2025-10-10 18:22:56 -07:00
Nariman Jelveh 62341aa030 Update UITaskbar.js (#1737) 2025-10-10 18:00:51 -07:00
Daniel Salazar ef6c7b17f1 metering: rest of ai (#1736)
* metering: rest of ai

* fix: wrong cost name
2025-10-10 17:58:35 -07:00
Nariman Jelveh 5a4a1f16a4 Taskbar pos (#1735)
* Update UIWindow.js

* wip

* Update UITaskbar.js
2025-10-10 17:08:57 -07:00
KernelDeimos b6e12762ce fix: missing check for dev console service 2025-10-10 15:01:07 -04:00
KernelDeimos 70c7aa41ac Reapply "Logs Update" (#1730)
This reverts commit 8f7a68ace6.
2025-10-10 15:01:07 -04:00
Nariman Jelveh 9607706d11 fix: adjust toolbar positioning for sidepanel based on taskbar location (#1731)
* fix: adjust toolbar positioning for sidepanel based on taskbar location

* fix: update window width calculation for left position based on open panels
2025-10-09 21:16:26 -07:00
Neal Shah 8f7a68ace6 Revert "Logs Update" (#1730)
* Revert "fix: quick fix for config context issue"

This reverts commit 0c06040e6c.

* Revert "sync: package-lock.json"

This reverts commit 1e1bd0f2ba.

* Revert "devex: misc log cleanup"

This reverts commit a64a786528.

* Revert "devex: minimal first page load logs"

This reverts commit 196e463c59.

* Revert "devex: minimal initialization logs"

This reverts commit ea9c222c09.

* Revert "fix: add missing await in kv example extension"

This reverts commit 9b34e67d0d.

* Revert "devex: reduce logs at init"

This reverts commit fa221149c2.

* Revert "sync: package.json changes"

This reverts commit 4db73d75a5.

* Revert "fix: remove unused AWS SDK v2 import"

This reverts commit 4d8692fd31.

* Revert "devex: hide `npm install` output unless it fails"

This reverts commit fe03a4b598.

* Revert "devex: rollup via module instead of subprocess"

This reverts commit 360082d8bd.

* Revert "devex: webpack via module instead of subprocess"

This reverts commit 1449d12b0e.

* Optional chain logger
2025-10-09 23:08:01 -04:00
Daniel Salazar 2c614b2b99 cleanup: remove auxilary return for now (#1727) 2025-10-09 19:20:52 -07:00
Daniel Salazar a3c6c0b914 Revert "revert: revert devex changes (#1728)" (#1729)
This reverts commit fc725d0130.
2025-10-09 19:16:20 -07:00
Daniel Salazar fc725d0130 revert: revert devex changes (#1728)
* Revert "fix: quick fix for config context issue"

This reverts commit 0c06040e6c.

* Revert "sync: package-lock.json"

This reverts commit 1e1bd0f2ba.

* Revert "devex: misc log cleanup"

This reverts commit a64a786528.

* Revert "devex: minimal first page load logs"

This reverts commit 196e463c59.

* Revert "devex: minimal initialization logs"

This reverts commit ea9c222c09.

* Revert "fix: add missing await in kv example extension"

This reverts commit 9b34e67d0d.

* Revert "devex: reduce logs at init"

This reverts commit fa221149c2.

* Revert "sync: package.json changes"

This reverts commit 4db73d75a5.

* Revert "fix: remove unused AWS SDK v2 import"

This reverts commit 4d8692fd31.

* Revert "devex: hide `npm install` output unless it fails"

This reverts commit fe03a4b598.

* Revert "devex: rollup via module instead of subprocess"

This reverts commit 360082d8bd.

* Revert "devex: webpack via module instead of subprocess"

This reverts commit 1449d12b0e.
2025-10-09 18:43:03 -07:00
Daniel Salazar c0d96c7e97 fix: openrouter usage calculator (#1725) 2025-10-09 17:12:48 -07:00
KernelDeimos 0c06040e6c fix: quick fix for config context issue
I don't know what causes this
2025-10-09 19:39:02 -04:00
KernelDeimos 1e1bd0f2ba sync: package-lock.json 2025-10-09 19:39:02 -04:00
KernelDeimos a64a786528 devex: misc log cleanup 2025-10-09 19:39:02 -04:00
KernelDeimos 196e463c59 devex: minimal first page load logs 2025-10-09 19:39:02 -04:00
KernelDeimos ea9c222c09 devex: minimal initialization logs 2025-10-09 19:39:02 -04:00
KernelDeimos 9b34e67d0d fix: add missing await in kv example extension 2025-10-09 19:39:02 -04:00
KernelDeimos fa221149c2 devex: reduce logs at init
Moves more logs to debug level, removing a few that were unnecessary.
2025-10-09 19:39:02 -04:00
KernelDeimos 4db73d75a5 sync: package.json changes 2025-10-09 19:39:02 -04:00
KernelDeimos 4d8692fd31 fix: remove unused AWS SDK v2 import
This was done to reduce init logs by removing the AWS SDK v2 deprecation
notice from the output.
2025-10-09 19:39:02 -04:00
KernelDeimos fe03a4b598 devex: hide npm install output unless it fails
Since extensions are loaded as packages, the `npm install` outputs can
get very verbose. This change reduces log noise when Puter initializes.
2025-10-09 19:39:02 -04:00
KernelDeimos 360082d8bd devex: rollup via module instead of subprocess 2025-10-09 19:39:02 -04:00
KernelDeimos 1449d12b0e devex: webpack via module instead of subprocess
This was really really really (100 more "really"s) tedious compared to
what I had expected.
2025-10-09 19:39:02 -04:00
Daniel Salazar 248b199fa3 feat: add openrouter metering (#1724)
* feat: add openrouter metering

* fix: models promise await parenthesis

* fix: openRouter name for metering
2025-10-09 16:36:21 -07:00
Neal Shah 3703f7e14f Add in events for thumbnails (#1700) 2025-10-09 17:07:22 -04:00
Daniel Salazar 5450c85b3a fix: bad boolean check (#1721) 2025-10-09 11:15:47 -07:00
Nariman Jelveh 5a9284a2cb Update UIWindow.js (#1720) 2025-10-09 09:49:57 -07:00
Nariman Jelveh abc8d7fcce Npm run test puterjs (#1719)
* chore: add http-server as a dev dependency and update package scripts

* refactor: move maximized window positioning logic to UIWindow and remove from UITaskbar
2025-10-08 22:14:42 -07:00
Nariman Jelveh 6fdea68eec chore: add http-server as a dev dependency and update package scripts (#1718) 2025-10-08 19:13:05 -07:00
Daniel Salazar eea27be8eb fix: metering service global write and open ai default model (#1717) 2025-10-08 18:41:15 -07:00
Daniel Salazar 73a24af951 feat: meter claude ai (#1716)
* feat: meter claude ai

* fix: claude meteringService dep
2025-10-08 17:49:12 -07:00
Xiaochen Cui 89ad06afae ci: fix failure by upgrading library (#1713) 2025-10-08 17:17:37 -07:00
Daniel Salazar 3df1d31a37 fix: broken open ai moderation (#1714) 2025-10-08 16:41:32 -07:00
KernelDeimos e59f4e6c16 devex: reduce webpack verbosity 2025-10-08 19:25:53 -04:00
KernelDeimos 74ceb2fa1b devex: move more init logs to debug
Removes init/construct logs, moves many boot logs to debug level,
introduces debug level in BootLogger, moves "CONFIGURATION MUTATED AT
RUNTIME" message to debug level and allows config.js to output logs to
the standard logger in context.
2025-10-08 19:25:53 -04:00
KernelDeimos cae50b8859 dev: add experimental parallel init emit
This is put behind a flag for now because potential bugs that may arise
from this change are difficult to locate or predict.
2025-10-08 19:25:53 -04:00
Nariman Jelveh 64cfa8158d feat: immprove UIPopover and UIWindow behavior for sidepanel visibility (#1711)
- Adjust `UIPopover` positioning when a sidepanel is visible.
- Update `UIWindow` to manage visibility states and adjust toolbar positions accordingly.
- Modify CSS for AI Button to change z-index for better layering.
2025-10-08 15:40:14 -07:00
askmanu[bot] 0270b64bc4 Added reference documentation for: src/backend/src/modules/puterai/lib/Messages.js 2025-10-08 16:52:11 -04:00
askmanu[bot] 4fb06d3b3e Added reference documentation for: src/backend/src/modules/puterai/lib/GeminiSquareHole.js 2025-10-08 16:52:11 -04:00
askmanu[bot] aed3ce7ed7 Added reference documentation for: src/backend/src/modules/broadcast/connection/CLink.js 2025-10-08 16:52:11 -04:00
Daniel Salazar 248b38e732 fix: undefined alias array (#1709) 2025-10-08 13:12:58 -07:00
Daniel Salazar 0acb884ed0 feat: meter open ai (#1703)
* feat: meter open ai

* fix: dep injections & moderation

* feat: add paging
2025-10-08 12:58:05 -07:00
jelveh a70a621dd5 Update style.css 2025-10-08 12:33:56 -07:00
Nariman Jelveh 508ed920f6 Update globals.js (#1702) 2025-10-07 15:23:56 -07:00
Nariman Jelveh b02e6c86b0 Update helpers.js (#1701) 2025-10-07 14:36:02 -07:00
Daniel SalazarandNariman Jelveh d9c64a9378 feat: manage permission for user to user and dev to app file sharing (#1567)
* perf: move user-user perm checks to flat kv entries

* feat: manage permission for user to user and dev to app file sharing

* fix typings cuz macos sucks

* fix: mac os typecase

* fix: chore macOs typecase

* fix: bad join of permissions

* feat: add check-permissions endpoint for checking an users perms

* Add 'manage' to permission lists in the Sharing dialog

* fix: manage being allowed through our ACL

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-10-07 13:46:00 -07:00
Daniel Salazar 6d35496252 chore: publish npm (#1698)
* chore: bump puter-js version and publish

* chore: package-lock
2025-10-07 11:56:18 -07:00
Daniel Salazar 2a2a1f6a99 fix: backward compatibility for puter kv incr/decr (#1697) 2025-10-07 11:39:23 -07:00
KernelDeimos 44522f0a22 fix: remove verbose parameters log 2025-10-07 02:31:35 -04:00
Nariman Jelveh 70cde54f80 Update LogService.js 2025-10-06 22:16:53 -07:00
Nariman Jelveh dfccbdccce Update LogService.js 2025-10-06 21:58:14 -07:00
Nariman Jelveh 84a28b9637 Sidepanel (#1694)
* add AI side panel to UIDesktop

* integrated `UIAIChat` component into `UIDesktop` for AI interactions.
* added styles for AI side panel, including buttons and chat message formatting in style.css, enhancing user experience with AI features.

* add support for window-based side panels

* remove window resizing logic that is simply broken

* whitelisting added

* Add `showWindow` and `hideWindow` methods to Puter.js
2025-10-06 18:40:44 -07:00
Daniel Salazar e3f9455cae test: vitest tests for puter js (#1693) 2025-10-06 15:00:40 -07:00
Daniel Salazar f06bec4cd4 feat: extract and centralize cost maps (#1691) 2025-10-06 14:52:09 -07:00
ProgrammerIn-wonderland 44fcb5800b fix: options.no_options_auth should be optional chained 2025-10-06 13:46:57 -04:00
KernelDeimos a5fa16b7bb fix: preflight issue with protected endpoints
When /user-protected/change-password (and presumably other endpoints
under /user-protected) receive a preflight request they respond with
HTTP status 401. This is because `.use()` calls on the router apply to
all request methods erroneously.

This commit fixes the issue. Further investigation is required to
determine when preflight requests started happening on this endpoint.
2025-10-06 11:31:21 -04:00
Rajeshwar Singhandjelveh 3120d6a057 feat(Translation): added support for Armenian and also added Bulgarian (Closes #1523) (#1676)
* feat(Translation): added support for Armenian and also added Bulgarian

* fixed

* add license header to bg.js

* Update package-lock.json

---------

Co-authored-by: jelveh <[email protected]>
2025-10-05 22:59:58 -07:00
ProgrammerIn-wonderland 82732b9e96 Safari fix for TLS connections in puter 2025-10-05 02:06:36 -04:00
Nariman Jelveh 5b09dbb1f5 Update UIDesktop.js (#1682) 2025-10-04 18:14:54 -07:00
Nariman Jelveh 4dae0d6370 I18n for sys dirs (#1679)
* improve UIItem and UIWindow to support internationalization for system directory names. Updated UIItem to display localized names for trash, desktop, home, documents, pictures, videos, and public directories. Modified UIWindow to set the window title using localized names for the desktop and home paths.

* refactor UIWindow to use i18n for system directory titles. Updated window title settings for desktop, documents, pictures, videos, public, and trash paths to use localized names, improving user experience across different languages.
2025-10-04 13:04:31 -07:00
Nariman Jelveh 2cedb05a8a add option to automatically set window title to opened file's name (#1678)
* add option to automatically set window title to opened file's name

A new checkbox in the app edit section to allow users to automatically set the window title to the name of the opened file. Updated related functions to handle this new setting, ensuring it is saved and reset correctly.

* Update launch_app.js
2025-10-04 12:13:57 -07:00
gulizar ElhalilandNariman Jelveh 3d44609d80 Update ku.js (#1677)
* Update ku.js

translation has been added.

* Update ku.js

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-10-04 11:24:04 -07:00
KernelDeimos 74430da673 style: small change to test deploy
Arbitrary whitespace change just to test something.
2025-10-03 21:36:44 -04:00
Eric DubéandDaniel Salazar 4eaba05136 chore: update package-lock.json with npm v11.6.1
* try: update package-lock.json from Linux/x86 on 11.6.1

* darwin

* darwing

* dev: try updating rollup

* try: npm 11.6.1 delete package-lock.json and run `npm i`

* push darwin pacakge lock

* sync: package-lock.json with npm 11.6.1

---------

Co-authored-by: Daniel Salazar <[email protected]>
2025-10-03 20:18:13 -04:00
Nariman Jelveh db66fecadf Update style.css (#1671) 2025-10-03 16:24:44 -07:00
Nariman Jelveh 44bc7b7437 Replace "Save As..." with i18n('Save As…') (#1670) 2025-10-03 15:54:43 -07:00
Nariman Jelveh cc8a658122 Update UI.js (#1668) 2025-10-03 14:59:23 -07:00
KernelDeimos 39fdcec9bf fix: add missing utilities.js 2025-10-03 17:12:41 -04:00
KernelDeimos 9c5b96305a example(extensions): [+] example-kv 2025-10-03 16:53:23 -04:00
KernelDeimos 9ff59d9290 fix: system actor for extension lifecycle events
Using services such as `kv` which expect an actor in context would not
work in a handler for a lifecycle event such as `'init`' in an
extension. In core backend modules is it generally expected that if a
user actor is not in context a backend service will explicitly specify
that the system actor should be used with the `su` service's `sudo`
method. We cannot require extension developers to add this wrapping code
whenever they want to use kv.

In the future it might be better to have a specific "ExtensionActorType"
for this purpose.
2025-10-03 16:53:23 -04:00
ProgrammerIn-wonderland f60e02565f add conditional type overload for streaming 2025-10-03 16:38:44 -04:00
Kishan_Singh 1affbb4cc8 fix: support async iterator for AI chat streaming mode in types 2025-10-03 16:38:44 -04:00
Hariz 4eab7167e6 Disable browser context menu on launcher popover (#1648)
* Disable browser context menu on launcher popover

* Allow system context menu on launch search bar

* Remove extraneous debug log
2025-10-02 20:40:42 -07:00
Daniel Salazar 4a1aee0713 fix: increment for non-existent keys (#1649) 2025-10-02 15:51:56 -07:00
KernelDeimos 36b30ebf57 dev(extensions): [+] extension-examples:ii:hello-world 2025-10-02 18:35:20 -04:00
KernelDeimos aef8227454 doc(extensions): data import 2025-10-02 17:00:51 -04:00
KernelDeimos 54b8990c70 devex(extensions): simplify kv get and set methods
The basic `.get()` and `.set()` calls should be the same between
persistent key-value store (puter-kvstore) and in-memory cache (kv.js).
This commit wraps these methods to support the "shorthand" usage.
2025-10-02 16:53:59 -04:00
KernelDeimos b9f42f6daa fix: PayloadTooLargeError for JSON + base64 images
The `/drivers/call` endpoint hangs when the JSON middleware produces
(or, is going to produce?) a PayloadTooLargeError. Increasing the limit
avoids this issue for typical use.
2025-10-02 15:41:09 -04:00
Dan Tran a17ab22ab7 feat: Add missing Vietnamese translations (#1641) 2025-10-02 10:18:43 -07:00
Daniel Salazar cc3b0db6b1 feat: initial metering service supporting monthly tracking of service consumption (#1630) 2025-10-01 14:04:36 -07:00
KernelDeimos 36ddad0ecc lint: add config global to extensions 2025-10-01 16:58:46 -04:00
KernelDeimos 7137d1a178 doc: permission grant in extension drivers 2025-10-01 16:57:44 -04:00
KernelDeimos bfffdfdc36 doc(extensions): exports not front-and-center
The extension documentation mentions imports and exports together very
early on, but extension exports should be used sparingly. I suspect most
extensions with exports will be among Puter's builtin extensions.
2025-10-01 16:47:56 -04:00
KernelDeimos 9946d2ffc5 dev(extensions): event for extensions to grant permst 2025-10-01 16:46:59 -04:00
KernelDeimos 574088ea55 doc: improve extension documentation
- describe extension events
- link drivers documentation
2025-10-01 16:03:24 -04:00
KernelDeimos ec8111cc2f dev(extensions): improved configuration support
Extensions now read configuration objects under the "extensions" block
in the backend configuration. Additionally, a `config.json` for default
values directly in the extension's directory is now supported.
2025-10-01 15:29:13 -04:00
Yukirin 94c0490f34 Update id.js (#1638)
Added missing translations and re-translated some of existing translations
2025-10-01 10:46:43 -07:00
KernelDeimos 887536b811 fix: cleanup EngPortalService commands
- removes commands from EngPortalService that were previously moved to
  ParameterService
- renames `eng:test` to `eng:list-operations`

Closes #1624
2025-10-01 13:17:04 -04:00
Daniel Salazar 5b3bc9ddf4 fix: permission batch get (#1637) 2025-09-30 20:17:01 -07:00
biranzegelman97andNariman Jelveh 916f419e0f added missing hebrew translations + fixed some existing translation + changed he.js export variable from en to he (#1634)
* added missing hebrew translations + fixed some existing translation + changed he.js export variable from en to he

* remove "Missing translations" comment?

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-30 19:16:35 -07:00
Hariz 62f5cc54cf Fix bug with context menu positioning on page load (#1636)
* Fix bug with context menu positioning on page load

* Fix double context menu bug on mobile
2025-09-30 18:58:54 -07:00
Nariman Jelveh 6ee60f9c13 Closes #629 2025-09-30 18:27:33 -07:00
HarizandNariman Jelveh 6429dcf15e Add 'Set as Desktop Background' context menu item to images (#1635)
* Add 'Set as Desktop Background' context menu item

* Use the `mime` library to detect images in the `UIItem` context menu

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-30 18:06:09 -07:00
KernelDeimos c11a4008ee doc: improve comments in hellodriver.js 2025-09-30 17:12:09 -04:00
KernelDeimos 5cc182653e doc: document creating extensions through drivers 2025-09-30 16:33:34 -04:00
KernelDeimos 057eaa46ca dev(extensions): [+] hellodriver
The hellodriver extension provides a useful interface for generating
greetings at the same time as a simple example of how to implement
drivers.
2025-09-30 16:33:34 -04:00
KernelDeimos 87f2fbf36b clean: DriverService
Removes dead code and reduces branching. In the get_service_or_throw_
method, the changes in this commit show how the branching got more
redundnat in the previous change.
2025-09-30 16:33:34 -04:00
KernelDeimos 41820baba6 dev: add extension support in DriverService
Adds new events that DriverService emits: `create.interfaces` and
`create.drivers`. Returns the functionality of the "drivers" registry,
which now expects objects provided by extensions.
2025-09-30 16:33:30 -04:00
Nariman Jelveh eaa31ba18f Update copyright headers that were translated to non-english 2025-09-30 12:54:00 -07:00
Nariman Jelveh 343f042f39 feat: add tar and untar functionality for file management
- Implemented `tarItems` function to create tar archives from selected files or directories.
- Added `untarItem` function to extract tar archives.
- Updated UI to include options for downloading and tarring files.
- Enhanced item icon handling to display tar file icons.
- Added translations for tar and untar operations.

- Fixes #1629
2025-09-30 10:35:55 -07:00
Daniel Salazar 9c47a7f8ca perf: move user-user perm checks to flat kv entries (#1562) 2025-09-29 19:41:39 -07:00
Nariman Jelveh d085568674 Delete .github/ISSUE_TEMPLATE directory 2025-09-29 18:48:35 -07:00
KernelDeimos 1c64cb274b fix(ai): try overriding timeout to disable error
The Anthropic SDK preemptively throws an error if it thinks a response
is going to take longer than 10 minutes:
https://github.com/anthropics/anthropic-sdk-typescript#long-requests

According to this documentation, overriding the `timeout` option
disables this error. In this commit the option is changed to the default
value of 10 minutes plus an additional 1 second; it is assumed based on
the documentation's phrasing that it is not necessary to make the
timeout higher but simply to specify a value.
2025-09-29 15:08:23 -04:00
KernelDeimos df6fc8a432 test: fix test kernel after adding runtimle modules
RuntimeModules (a feature for extensions) can be accessed by core
modules through a registry exposed in Context by Kernel. However,
TestKernel was not exposing this same registry which caused an error
when module installation occurred during tests.
2025-09-29 14:27:07 -04:00
jelveh 208d25f371 Update ClaudeService.js 2025-09-29 11:20:34 -07:00
Andrei Onelandaskmanu[bot] d216887fa0 doc: add comments under filesystem, modules, entitystorage
* Added reference documentation for: src/backend/src/modules/puterfs/DatabaseFSEntryFetcher.js

* Added reference documentation for: src/backend/src/modules/dns/DNSService.js

* Added reference documentation for: src/backend/src/filesystem/ll_operations/ll_write.js

* Added reference documentation for: src/backend/src/filesystem/strategies/storage_a/LocalDiskStorageStrategy.js

* Added reference documentation for: src/backend/src/om/entitystorage/WriteByOwnerOnlyES.js

---------

Co-authored-by: askmanu[bot] <192355599+askmanu[bot]@users.noreply.github.com>
2025-09-29 14:16:50 -04:00
jelveh 5caf148ae9 Update ClaudeService.js 2025-09-29 11:16:13 -07:00
jelveh 847b3a07a4 Improve item.add cache invalidation logic so that it doesn't purge the entire cache 2025-09-29 00:02:03 -07:00
jelveh a69072b31b More precise cache invalidation in case of item rename 2025-09-28 23:43:36 -07:00
jelveh fe022cff1d Back to native purge to build from first principles?! 2025-09-28 22:50:55 -07:00
jelveh 1195e319a8 update kv.js version in package.json 2025-09-28 22:05:30 -07:00
Nariman Jelveh ebb0162d79 Increase cache efficiency 2025-09-28 21:30:31 -07:00
Nariman Jelveh 7382264648 more nuanced cache invalidation strategy with logging enabled by default 2025-09-28 20:35:51 -07:00
Nariman Jelveh a965df0cc0 Remove cache expiry in puter.js 2025-09-28 19:16:29 -07:00
Nariman Jelveh 72341c78dc Update index.js 2025-09-28 18:59:44 -07:00
jelveh ef74a1a660 fix: prevent unnecessary updates on socket events
Updated the `bindSocketEvents` method to check the `original_client_socket_id` before posting updates for 'cache.updated' and 'item.renamed' events. This prevents unnecessary updates when the event originates from the same client socket.
2025-09-28 14:35:45 -07:00
jelveh f1fd372933 refactor: improve metadata handling in WSPushService
Updated the `WSPushService` to pass additional metadata during user timestamp updates and event emissions for file system operations. This includes modifications to the `_on_fs_create`, `_on_fs_update`, `_on_fs_move`, and `_on_fs_pending` methods to ensure metadata is consistently included, improving the context for GUI updates.
2025-09-28 13:43:08 -07:00
jelveh 740089aff1 fixes #1622 2025-09-27 00:03:49 -07:00
Xiaochen Cui 891093fd2b fix a typo (#1627) 2025-09-26 21:45:00 -07:00
Haitamandjelveh 733c7b638d feat: Complete missing Ukrainian, Turkish and Thai translations (#1616)
* feat: Complete missing Ukrainian, Turkish and Thai translations

* add the trailing comma

---------

Co-authored-by: jelveh <[email protected]>
2025-09-26 21:40:20 -07:00
KernelDeimos baf261c0c4 fix: check if shraed files exist in ll_readshares
This may have been breaking the ability to see directories shared by
other users sometimes.
2025-09-26 18:59:23 -04:00
KernelDeimos 088ff4d696 fix: update path when renaming during save_account
We do update the path of all child directories by calling
filesystem.update_child_paths(), but this was never done for the user's
actual home directory itself (only everything under it).

The most ideal solution would be to delegate this behavior to the move
operation instead of updating the fsentries table directly, but making
this change right now has a high risk of breaking changes since this the
behavior in this file is very old.
2025-09-26 18:44:32 -04:00
Nariman Jelveh fae33301a8 fix the issue with last_valid_ts always being 0 2025-09-26 15:05:44 -07:00
mrtbgauandNariman Jelveh b8263fd8e0 feat: add missing Persian and Finnish translations (#1614)
* feat: add missing Persian translations

* feat: add missing Finnish translations

* Remove "Missing translations" comment

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-26 15:05:04 -07:00
KernelDeimos d85f5fad5e dev: expose 'kv' as 'cache' from data extension 2025-09-26 17:31:00 -04:00
KernelDeimos d5a2a34f53 dev(extensions): add extension.use
The extension.use method allows registering routers and generic handlers
(not wrapped by eggspress) to express.
2025-09-26 17:30:09 -04:00
KernelDeimos 601eb019a2 dev(extensions): [+] data
The data extension adds convenient access to the database and kvstore
via it's 'db' and 'kv' exports.

Example usage:
  const { db, kv } = extensions.import('data');
  await kv.set('some-key', 'some-value');
  await db.write('INSERT INTO something (a, b) VALUES (1, 2)');
2025-09-26 15:28:00 -04:00
KernelDeimos 63bf4eccbe dev: make services importable by extensions
For example you can access WebServerService with
extension.import('service:web')
2025-09-26 15:28:00 -04:00
KernelDeimos 0c30a9e157 fixup! dev(extensions): [+] whoami 2025-09-26 15:28:00 -04:00
KernelDeimos dabf8cac56 fix: add missing dep to whoami extension 2025-09-26 15:28:00 -04:00
KernelDeimos 570409ef15 doc: add more extension internals documentation 2025-09-26 15:28:00 -04:00
KernelDeimos 27d7668a72 dev: '@extension name' and priority in puter.json
Adds the '@extension name <name>' directive for single-file Puter
extensions, and adds support for defining priority in 'puter.json'.
2025-09-26 15:27:59 -04:00
KernelDeimos cb31c1d44e dev: add command to list extensions
This commit adds the `extension:list` command for listing extensions.
This command is itself defined in an extension. To make this possible,
an event called 'create.commands' is emitted form CommandService with
the event object holding a function that can be used to add commands.
2025-09-26 15:27:59 -04:00
KernelDeimos 7b4c62d1c3 lint: minor formatting issue with catch(e)
The custom eslint pluggin for the formatting rule I have for the
expressions in control structures isn't a good fit when the condition is
a single variable named by a single character. This happens a lot with
`catch`. `catch ( e ) {` has too much spacing, but `catch (e) {` looks
relatively normal.
2025-09-26 15:27:59 -04:00
KernelDeimos 62e77a15a2 conf: add block in eslint.config.js for extensions 2025-09-26 15:27:59 -04:00
KernelDeimos 353cf397cb dev: remove legacy whoami and use extension 2025-09-26 15:27:59 -04:00
KernelDeimos db5aef51b0 fix: missing await in extension loader 2025-09-26 15:27:59 -04:00
KernelDeimos ebbe18f72d dev(extensions): [+] whoami 2025-09-26 15:27:59 -04:00
KernelDeimos 943a3c7bab type(extensions): config and add core.util.helpers 2025-09-26 15:27:58 -04:00
KernelDeimos 1358e98c5b devex: add some types for extension intellisense 2025-09-26 15:27:58 -04:00
KernelDeimos dde652fb27 dev: expose 'core' from useapi as runtime module 2025-09-26 15:27:58 -04:00
KernelDeimos 15cb98107c doc: add extension documentation for core devs
Extensions need to be documented at different layers of concern:
1. How to use/run extensions
2. How to create extensions as a contributor
3. How extensions work under the hood

This documentation addresses the third layer, describing how Kernel
and core modules interact with extensions.
2025-09-26 15:27:58 -04:00
KernelDeimos 4353c2dc46 dev: expose 'web' from useapi as runtime module
This will allow extensions to import from the 'web' module:
const { Endpoint } = extension.import('web');
2025-09-26 15:27:58 -04:00
KernelDeimos f6be6952dc dev: export runtime module registry to context 2025-09-26 15:27:58 -04:00
KernelDeimos b328355a90 fix: apparently setters shadow getting
I thought you could:
  method() {}
  set method (v) { /* ... /* }

but you can't. You have to:
  get method() { return (function () {}).bind(this) }
  set method (v) { /* ... /* }

I don't know why a setter can't just only shadow setting, but that's
how they designed the language. ¯\_(ツ)_/¯
2025-09-26 15:27:57 -04:00
KernelDeimos 6ff3d154fa devex: .git is not an extension
This change makes sure Kernel skips `.git` directories when scanning
for extensions. This allows me to make a git repository containing
example extensions for Puter.
2025-09-26 15:27:57 -04:00
KernelDeimos bdd60c63d8 devex: add '{repo}' variable for extension paths
Previously '{source}' was added but this is a bit difficult to work
with since it's the path from the source file, which is usually the
'src/' directory under the repository. This won't be obvious anyone
who doesn't already know this. '{repo}' just points to the path of
the repository itself.
2025-09-26 15:27:57 -04:00
KernelDeimos 06cd14353a doc: document import/export mechanism for extensions 2025-09-26 15:27:57 -04:00
KernelDeimos e271476e0b tweak: alias 'runtime' to 'extension'
Extension developers should not have to remember what comes form
where between two different globals. This change makes Extension
effectively a facade (Facade Pattern) containing the behaviors
of both extensions and runtime modules.
2025-09-26 15:27:57 -04:00
KernelDeimos 9aef281ad2 dev: add runtime modules for imports and exports
RuntimeModule is a new construct which represents the import/export
mechanism for Puter extensions. This can be thought of as analogous
to node's Module class. These are called "runtime modules" because
extensions have less control of what they're consuming than a typical
npm module; i.e. `runtime.import('database')` will provide a version
of 'database' that's compatible with the importing extension, but the
version used can't be locked or otherwise determined by the extension.
2025-09-26 15:27:57 -04:00
Xiaochen CuiandNariman Jelveh 860388c3cb update client-cache logic (#1626)
* client-cache: remove pulling

* client-cache: fix wrong ts field

* client-cache: purge cache on any local update

* client-cache: last_updated_time -> last_valid_time

* client-cache: update cache on remote update

* client-cache: update last_valid_ts every sec

* client-cache: switch to localstorage

* do the cache and purge test when `setAuthToken` is called

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-26 11:44:12 -07:00
Nariman Jelveh a0b567da52 chore: update @heyputer/kv.js dependency to version 0.2.0 and initialize cache with dbName in puter-js (#1623) 2025-09-26 10:58:16 -07:00
Daniel Salazar 3fc183297f revert: eslint config rules (#1625) 2025-09-26 10:52:00 -07:00
Daniel SalazarandNeal Shah d70d412115 feat: DAV Locks support + refactor of DAV method handler (#1486)
* feat: DAV Locks support + refactor of DAV method handler

* format: Restore old whitespace for CoreModule.js

* fix: options route registering after likecycle hooks

---------

Co-authored-by: Neal Shah <[email protected]>
2025-09-26 11:00:29 -04:00
Xiaochen Cui 7bfa85d4fe client-cache: remove pulling (#1620)
* client-cache: remove pulling

* client-cache: fix wrong ts field

* client-cache: purge cache on any local update
2025-09-25 16:56:01 -07:00
Daniel Salazar 8d36e52ae7 Merge pull request #1621 from HeyPuter/DS/main
dep: updating node dep version to one that supports modules
2025-09-25 12:17:15 -07:00
Daniel Salazar 9705c58160 dep: updating node dep version to one that supports modules 2025-09-25 12:08:36 -07:00
OnitsagandNariman Jelveh 1cff4fd46a feat: Add missing Portuguese translations (#1615)
* feat: Add missing Portuguese translations

* feat: Add missing Swedish translations

* remove missing translations comment

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-25 11:47:04 -07:00
velzie 8b9fefa4a2 fix puterjs throwing errors after consuming message events not meant for it (#1612) 2025-09-25 11:11:34 -07:00
Thomas NGUYEN 72ee05fefb feat: Add missing Urdu translations (#1618) 2025-09-25 10:58:46 -07:00
Xiaochen Cui 681c084180 client-cache: update cache-invalidation policy to ts-based comparison (#1611) 2025-09-24 18:08:09 -07:00
Nariman Jelveh 8b7e764af9 add instancesOpen to puter.js UI 2025-09-24 17:03:36 -07:00
KernelDeimos fa436a7775 devex: make it impossible to commit eslint errors 2025-09-24 17:41:48 -04:00
KernelDeimos fe1d78d5bf conf(eslint): fix backend rule, -@stylistic/quotes
This commit fixes the block that's meant to match backend files. There
was an error in the arguments for '@stylistic/indent' which was
effectively disabling the entire block. In vscode, it is very unclear
that this is happening, so I had to manually run this command:

npx eslint "src/backend/**/*.js" --debug

This commit also disables @stylistic/quotes; I disagree with this
rule for several reasons:
1. Sometimes the appropriate quote depends on the contents:
   i.e. '""""' + "''''" is cleaner than '""""\'\'\'\''.
2. If you argue that mixing quotes between concatenated strings
   (like the previous example) is a bad idea, then I can further
   state that this rule forces me to mix quotes:
   `we use a ${templateString}` + "but can't do it here"
2025-09-24 16:58:28 -04:00
Khilfi KA 99ebbfa00d Add Bahasa Malaysia (Malay) i18n Support (#1609)
* Complete Bahasa Malaysia (Malay) translation of Puter

* Fix code styling

* Add Malay README.md

* Removed dash from `sub-projek`

* Make `Library` italic

* Add Malay language to `Translations` section
2025-09-24 12:44:41 -07:00
ProgrammerIn-wonderland cf05413b83 ux: Whitelist onlyoffice applications from copy dialog in IPC 2025-09-23 18:10:54 -04:00
Daniel Salazar 25de96c8c9 Merge pull request #1607 from HeyPuter/DS/main
chore: add jsdoc typings for KV interface
2025-09-23 14:26:48 -07:00
Daniel Salazar 8cc14fece3 chore: add jsdoc typings for KV interface 2025-09-23 14:26:35 -07:00
Daniel Salazar 06f89a8a80 Merge pull request #1606 from HeyPuter/DS/main
feat: allow setting puter origin via globalThis variables
2025-09-23 14:26:17 -07:00
Daniel Salazar bf76a1edea feat: allow setting puter origin via globalThis variables 2025-09-23 13:26:12 -07:00
KernelDeimos aae3da39f8 sync: package-lock.json 2025-09-23 15:03:09 -04:00
Hariz 67be35b6a0 Don't raise window if close/minimize btn clicked (#1589) 2025-09-22 18:52:57 -07:00
Nariman Jelveh e0316b9cbe remove unnecessary console.log() 2025-09-22 16:36:48 -07:00
KernelDeimos 1ea8f9ddf1 devex: performance monitor environment variable
Instead of requiring developers to keep changes in their git index to
use the performance monitor, make it configurable through the .env
file.
2025-09-22 19:31:03 -04:00
KernelDeimos f729eaa31f fix: use dynamic import for dotenv 2025-09-22 19:30:37 -04:00
KernelDeimos 15eb44d62d feat: add optional dotenv support
This adds an optional import for 'dotenv'. If dotenv is installed
via npm then the .env file will be loaded.
2025-09-22 19:13:05 -04:00
KernelDeimos 49341321f1 dev: add option to make the database slow
Adds a configuration parameter called "slow" to database config which
adds a hardcoded delay 70ms to database operations. This is useful
when testing for performance issues.
2025-09-22 19:10:48 -04:00
jelveh b93890b008 Update package.json 2025-09-21 22:36:40 -07:00
jelveh 502ef3c32b Update README.md for Puter.js: Enhance formatting, add installation instructions, and include community links 2025-09-21 22:33:13 -07:00
dependabot[bot] 4dfdd2839f build(deps): bump webpack from 5.89.0 to 5.101.3 in /src/puter-js (#1601)
Bumps [webpack](https://github.com/webpack/webpack) from 5.89.0 to 5.101.3.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.89.0...v5.101.3)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.101.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-21 14:50:30 -07:00
Nariman Jelveh 32962211b4 Revert "Enhance login GUI: improve layout and add show/hide password (#1599)" (#1600)
This reverts commit 9e07fa74b7.
2025-09-21 09:53:12 -07:00
SaifAttar003 9e07fa74b7 Enhance login GUI: improve layout and add show/hide password (#1599) 2025-09-21 09:52:55 -07:00
dependabot[bot] 8e3cc68701 build(deps): bump requests from 2.32.3 to 2.32.4 in /tools/api-tester/ci (#1598)
Bumps [requests](https://github.com/psf/requests) from 2.32.3 to 2.32.4.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.3...v2.32.4)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.32.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-21 00:49:21 -07:00
Hariz 3de3c21f66 Add context menu to apps in the start menu (#1487)
* Add context menu to apps in the start menu

* Start menu context menus: Close other menus

* More bugfixes for start menu context menus

* Start menu context menus: Add/remove from taskbar

* Bugfixes for adding to taskbar through start menu

* Highlight start menu icons when ctxmenu is opened

* Close context menus on start menu kbd navigation

* Reset start menu icon state when ctx menu closed

* Fix multiple start item context menus opening simultaneously

* Remove parent argument from start icon context menus
2025-09-20 18:52:14 -07:00
Daniel Salazar 6910b41a22 Merge pull request #1595 from HeyPuter/DS/main
npm: fix publish
2025-09-19 17:22:24 -07:00
Daniel Salazar 44284eb788 fix: typedefs 2025-09-19 17:12:01 -07:00
Daniel Salazar d6fbe94364 npm: fixed publish 2025-09-19 16:52:18 -07:00
dependabot[bot] a3cbee1b58 build(deps): bump serialize-javascript in /src/puter-js (#1594)
Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-version: 6.0.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-19 14:28:36 -07:00
Daniel Salazar 0ef2b1c05e Merge pull request #1593 from HeyPuter/DS/main
fix: package name
2025-09-19 14:02:36 -07:00
Daniel Salazar 9d5a09f0bc fix: package name 2025-09-19 14:01:03 -07:00
Daniel Salazar 3cb9040a94 Merge pull request #1592 from HeyPuter/DS/main
npm: release to npm
2025-09-19 13:58:50 -07:00
Daniel Salazar a936333006 npm: release to npm 2025-09-19 13:58:25 -07:00
jelveh a023c24c35 Update package.json 2025-09-19 13:55:19 -07:00
jelveh 41191c65d7 Update puter.js README.md 2025-09-19 13:52:54 -07:00
Xiaochen Cui c8500ba1ab test: add puterjs test to apiteste (#1590) 2025-09-19 13:27:47 -07:00
Xiaochen Cui 9d0199f858 add apitest to github actions (#1591) 2025-09-19 13:27:32 -07:00
coluccifrancesco 0c60ebd1d0 Update it.js (#1588)
I translated the last part of the document for the italian language.
All the updates are typo-checked for errors , and there's none.
The translation has been made keeping in mind the italian use of various terms, some of the english words haven't been translated due to the extended use of the orignal term in everyday vocabulary.
2025-09-19 11:07:02 -07:00
Daniel Salazar 770e5e071e Merge pull request #1587 from HeyPuter/DS/main
ci: drop support and testing for node 18
2025-09-19 10:29:39 -07:00
Daniel Salazar 493334b030 chore: update README for puter.js to publish on npm 2025-09-19 02:34:33 -07:00
jelveh 654dfa9124 Update style.css 2025-09-18 23:03:16 -07:00
jelveh c0b03e147b add redundant readdir to cache the home dir 2025-09-18 21:03:28 -07:00
Nariman Jelveh 7000831138 make whoami return last_activity_ts 2025-09-18 19:07:53 -07:00
Nariman Jelveh 31fffb087d Refactor file system operations in GUI and puter.js to use eventual consistency (#1579)
* Refactor file system operations in GUI and puter.js to use eventual consistency for stat and readdir calls

This update modifies multiple instances of file system operations to include a consistency option set to 'eventual'. This change aims to improve performance and responsiveness by allowing for eventual consistency in file system interactions across various components, including helpers, UI elements, and IPC handling.

* Update cache expiration time for file system operations in readdir and stat to 1 hour

* feat: add network connectivity monitoring and cache purging

This update introduces a new feature that monitors network connectivity and purges the cache when the connection is lost. The implementation includes event listeners for online/offline changes and visibility changes to ensure cache consistency during network disruptions.

* clean up logs
2025-09-18 17:13:39 -07:00
Daniel Salazar 466cc113c6 ci: drop support and testing for node 18 2025-09-18 16:10:44 -07:00
software developer, self taughtandNariman Jelveh 89d5030ae3 Add missing polish translation (#1584)
* add missing polish translation

* Clean up comments in pl.js translations

Removed comments about missing translations from the Polish translations file.

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-18 13:58:35 -07:00
dependabot[bot] 5fe28ee8e2 build(deps): bump serialize-javascript and mocha in /src/terminal (#1585)
Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) to 6.0.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `serialize-javascript` from 6.0.0 to 6.0.2
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.0...v6.0.2)

Updates `mocha` from 10.2.0 to 10.8.2
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v10.2.0...v10.8.2)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-version: 6.0.2
  dependency-type: indirect
- dependency-name: mocha
  dependency-version: 10.8.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-18 12:04:44 -07:00
dependabot[bot] c9c92e806a build(deps-dev): bump rollup from 3.21.4 to 3.29.5 in /src/phoenix (#1583)
Bumps [rollup](https://github.com/rollup/rollup) from 3.21.4 to 3.29.5.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG-3.md)
- [Commits](https://github.com/rollup/rollup/compare/v3.21.4...v3.29.5)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 3.29.5
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-18 10:38:52 -07:00
dependabot[bot] 1475183b06 build(deps): bump multer from 1.4.5-lts.2 to 2.0.2 (#1582)
Bumps [multer](https://github.com/expressjs/multer) from 1.4.5-lts.2 to 2.0.2.
- [Release notes](https://github.com/expressjs/multer/releases)
- [Changelog](https://github.com/expressjs/multer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expressjs/multer/compare/v1.4.5-lts.2...v2.0.2)

---
updated-dependencies:
- dependency-name: multer
  dependency-version: 2.0.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-18 10:36:39 -07:00
dependabot[bot] a9699a9f77 build(deps): bump braces from 3.0.2 to 3.0.3 in /src/terminal (#1581)
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-version: 3.0.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-18 10:28:44 -07:00
dependabot[bot] ce237b5c4a build(deps): bump form-data from 4.0.2 to 4.0.4 in /test/integration (#1580)
Bumps [form-data](https://github.com/form-data/form-data) from 4.0.2 to 4.0.4.
- [Release notes](https://github.com/form-data/form-data/releases)
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](https://github.com/form-data/form-data/compare/v4.0.2...v4.0.4)

---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-18 10:26:20 -07:00
jelveh abc0d7b16c Update refresh_item_container.js 2025-09-17 16:12:35 -07:00
jelveh e4ada292f1 Update index.js 2025-09-17 15:59:24 -07:00
ProgrammerIn-wonderland 8884c7f472 fix: get rid of preflight for non-apifs readdir/stat 2025-09-17 18:57:57 -04:00
Nariman Jelveh e37166dae0 Cache is king baby! Let's go 🚀 (#1574)
* Implement the first naive version of `readdir` cache

* Purge the entire cache on every single mutation

Right now we're going to use the very naive, but safe, approach to purge the entire cache whenever there is change in the user's fs. We're going to incrementally improve this; but for now, better safe than sorry!

* Add socket event listeners to flush cache on file system item changes

This update introduces event listeners for 'item.added', 'item.renamed', and 'item.moved' events, triggering a cache flush on each event to ensure data consistency in the file system module.

* increase exp time for the cache

* Update readdir.js

* Update index.js
2025-09-17 15:36:42 -07:00
Amritpandey5andjelveh 214fd3010e added missing values (#1577)
* added missing values

* Update de.js

---------

Co-authored-by: jelveh <[email protected]>
2025-09-17 14:09:35 -07:00
aaryanandjelveh f4af6874b0 doc: added missing Dutch translations (#1575)
* doc: added missing Dutch translations
- fixes #1515

* Update nl.js

---------

Co-authored-by: jelveh <[email protected]>
2025-09-17 08:56:06 -07:00
Neal Shah b1facfbabd fix: get rid of a console log 2025-09-16 19:46:53 -04:00
ProgrammerIn-wonderland a48f3e0274 get rid of noReallyItsJson 2025-09-16 19:46:53 -04:00
ProgrammerIn-wonderland 1e620c73bc make drivers and KV also preflightless 2025-09-16 19:46:53 -04:00
ProgrammerIn-wonderland 135d7b81a4 preflightless stat/readdir 2025-09-16 19:46:53 -04:00
Nariman Jelveh 079d060747 Make templates non blocking (#1573)
* refactor: update available_templates function for non-blocking template loading

- Changed the available_templates function to initiate loading templates asynchronously without blocking the UI.
- Initialized window.file_templates with an empty array and updated it once the templates are loaded.
- Added a console log in UIDesktop to track transaction duration upon completion.

* Update UIDesktop.js
2025-09-16 14:57:01 -07:00
Nariman Jelveh 6d17385f09 add getDuration() to the Transaction class 2025-09-16 14:31:55 -07:00
Jatin SharmaandNariman Jelveh b6da8ba9ce Complete Missing Hungarian Translations in hu.js (#1572)
* Update Hungarian translations in hu.js

* Update hu.js

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-16 13:39:32 -07:00
dtakahashi333 42302b12ac fix: add Japanese translations (#1519) (#1570) 2025-09-16 12:30:09 -07:00
Thiago (Teet) b2d38e2058 Fixes to PT-BR translation (br.js) (#1568)
Fixed spelling and missing accentuations

Adjusted capitalization for consistency with other strings

Made wording more natural in PT-BR (e.g. “site” instead of “website”, “Login” instead of “Início de Sessão”)
2025-09-15 23:39:36 -07:00
KernelDeimos c588ff20d0 clean: remove logs (obvious cases)
This commit removes debug logs that meet these criteria:
- used console.log instead of the log service
- were left in the source tree accidentally
- show up at boot or during stat/readdir operations

This is not a comprehensrve removal; this is a first pass to get a
few of the trivial cases.
2025-09-16 01:12:57 -04:00
Nariman Jelveh e4c2581623 Make readdir workd with uid in addition to path 2025-09-15 20:12:45 -07:00
KernelDeimos d482d7cdf5 dev: add immutable default directories to whoami 2025-09-15 22:11:02 -04:00
Nariman Jelveh eb53b86c8a feat: add optional input image fields to AIInterfaceService
- Introduced `input_image` and `input_image_mime_type` as optional parameters in the AIInterfaceService schema to enhance image processing capabilities.
2025-09-15 16:57:38 -07:00
Nariman Jelveh 4e8aad675d feat: improve image generation and coercion for data URLs
- Updated `GeminiImageGenerationService` to differentiate between data URLs and web URLs for image handling.
- Added coercion support in CoercionService for converting data URLs to streams, including extraction of content type.
- Documented the txt2img method in AI.js to clarify usage for text and image-to-image generation.
2025-09-15 15:45:54 -07:00
KernelDeimos 6480d37ec0 fix: make optimization for is_empty conditional
Usually Puter has a UID by this point, but if it ever doesn't we can
fall back on using the path with a `LIKE ? + '%'` query. However,
users before a particular date might have fsentries without a path,
so we need to perform a check on the user's timestamp to avoid issues.
2025-09-15 18:29:10 -04:00
KernelDeimos 3af84c0647 fix: is_empty sometimes being wrong
is_empty wasn't working correctly while running concurrently with
fetchEntry because because the check in fetchIsEmpty was too
specific. This commit fixes this issue while also adding support for
a 'path' parameter to is_empty.
2025-09-15 18:29:10 -04:00
Nariman Jelveh f4fc24bce3 feat: add support for image-to-image generation in GeminiImageGenerationService
- Enhanced the `generate` method to accept base64 encoded input images and their MIME types.
- Implemented validation for input image and MIME type to ensure proper usage.
- Updated the content construction logic to handle both text-to-image and image-to-image generation scenarios.
2025-09-15 15:08:06 -07:00
BarnakandNariman Jelveh 47acb141da Updating ru.js (#1566)
* Update ru.js

Added missing translations from english to russian

* Update ru.js

* Update ru.js

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-15 12:06:03 -07:00
KernelDeimos ef76d33cc2 fix: string coercion for email verify code
Some databases will automatically do this string coercion, but others
will not. This commit ensures the value is always a string.
2025-09-15 14:56:42 -04:00
Nariman Jelveh 5121dbd300 Update PuterHomepageService.js 2025-09-15 11:28:42 -07:00
Nariman Jelveh 5e16259209 Update UIWindowDesktopBGSettings.js 2025-09-15 11:13:49 -07:00
Nariman Jelveh 2db29a01ba Default wallpeper url for prod should be the CDNed one 2025-09-15 10:58:01 -07:00
Daniel Salazar 4e563b4238 Merge pull request #1560 from HeyPuter/DS/main
fix: expiry time for dbkv
2025-09-15 10:44:21 -07:00
Leo f89f429849 Romanian Translation Done (#1565)
* romanian translation

* romanian translation
2025-09-15 09:57:18 -07:00
KernelDeimos b92a4edb83 fix: missing return for app icons on init 2025-09-15 04:31:36 -04:00
KernelDeimos 4d92f4a3ce fix: missing span name ("fn is not defined" error) 2025-09-15 04:28:51 -04:00
KernelDeimos ed5464f0c0 tmp: disable refresh_app_cache
Earlier I actually thought this wasn't running in prod because when I
run Puter locally the "refresh app cache" message doesn't appear.
I ensured that minlog was off but I forgot that around the same time
I also disabled the "tick" log level by default. If it weren't for
that I would've realized this an hour ago. That said, it's kind of
odd that this seems to be the source of the leak, because this isn't
new behavior.
2025-09-15 04:15:19 -04:00
KernelDeimos 3a0733f557 debug: add annotation class for app objects 2025-09-15 04:00:27 -04:00
KernelDeimos 7d7291cde4 fix: add unlink() methods to clear ECMAP 2025-09-15 03:19:46 -04:00
KernelDeimos 509f1add4e tmp: for now, make refresh_apps_cache a noop 2025-09-15 02:47:11 -04:00
KernelDeimos f98c78504b fix: try disabling this 30 second app cache for now
OOM conditions happening... maybe this will fix it
2025-09-15 00:12:46 -04:00
Nariman Jelveh 735f16725d refactor: make theme service non-blocking and fix captcha issues (#1564)
Replaced inline styles with CSS classes for the captcha modal to improve maintainability and readability. Adjusted JavaScript to accommodate the new structure and ensure proper functionality. Enhanced error handling and loading state management during the captcha verification process.
2025-09-14 20:20:19 -07:00
KernelDeimos 42abfcc5e7 perf: huh, right... not sure how I missed that
These two async operations depend on fetchEntry, but they do not
depend on each other; they can be run in parallel.
2025-09-14 20:40:18 -04:00
KernelDeimos 27ab23e7b1 fix: read 'push' of undefined 2025-09-14 19:01:59 -04:00
KernelDeimos f3fdfea65b perf: add 30 second app cache
There used to be an app cache here that would be invalidated but I
think this may have been removed because the invalidation logic
was causing issues. A 30 second cache seems reasonable though, so
let's do that for now.
2025-09-14 19:01:59 -04:00
KernelDeimos 733b6a653e perf: further readdir improvements 2025-09-14 19:01:59 -04:00
Daniel Salazar 860f68a9a5 fix: expiry time for dbkv 2025-09-14 12:48:25 -07:00
Aryan Arlikar 9820794470 Translate and improve emojis (#1557)
* chore(i18n/emoji): improve clarity of confirmation and name validation emojis

* chore(i18n/emoji): improve clarity of confirmation and name validation emojis
2025-09-14 12:45:54 -07:00
Watson 4c5032ff47 Update ko.js with full Korean translations (#1558)
* Update ko.js with full Korean translations

* fix: update 'public' translation from '공개' (open) to '공용' (shared) for clarity
2025-09-14 11:22:24 -07:00
Webb321andNariman Jelveh cab3d130c7 fix: add Chinese transaltions (#1559)
* fix: add Chinese transaltions

* fix: formatting

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-14 10:55:41 -07:00
KernelDeimos 094dd183b2 fix: event multiplication introduced in ebf4d7 2025-09-13 22:41:09 -04:00
KernelDeimos 7872fd58ed perf: optimize extension loader
Parallelize as much as possible, and avoid reading data from the
package.json when the file was generated by the extension loader
in the first place.
2025-09-13 22:41:09 -04:00
KernelDeimos 7730877c91 dev: add extension initialization priority 2025-09-13 22:41:09 -04:00
KernelDeimos 55c53d9eee dev: extension registry and lifecycle
Adds `register`, `registry`, `preinit`, and related symbols to the
available extension globals.
2025-09-13 22:41:09 -04:00
KernelDeimos 9135632129 dev: add support for ES6 Module extensions
Previously ES6 Module extensions would only work on versions of node
with --experimental-require-module enabled by default, and provided the
entry file had no top-level await. This commit uses "await import"
conditionally if the "type" in package.json is set to "module".
2025-09-13 22:41:09 -04:00
Daniel Salazar 0608958117 Merge pull request #1555 from HeyPuter/DS/main
fix: br.js transaltions
2025-09-13 18:14:25 -07:00
Daniel Salazar 6b05c90a21 fix: br.js transaltions 2025-09-13 18:12:57 -07:00
Daniel Salazar 740fef2306 Merge pull request #1484 from HeyPuter/DS/main
feat: logging for queries in puter js
2025-09-13 18:12:31 -07:00
Daniel Salazar 5569af8961 Merge branch 'main' into DS/main 2025-09-13 18:10:08 -07:00
AlfreThiagoandNariman Jelveh 07f97deab5 Adding missing translations for Brazilian Portuguese. (#1554)
* Feat: Adding missing translations for Brazilian Portuguese. Fixes #1500

* Corrections in brazilian translation

* Clean up translation file by removing comments

Removed comments indicating missing translations in br.js.

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-13 17:30:41 -07:00
KernelDeimos a5882889dd perf: make stat really fast 2025-09-13 20:27:44 -04:00
KernelDeimos c70434d947 perf: avoid reduntant fetches due to concurrency
Sometimes the same fs entry is fetched multiple times concurrently
because of parallel methods with separation of concerns.

After this commit, only one parallel fetch will go through and the
others will wait for it. Subsequent fetches will not occur is the
data that was needed is already there.
2025-09-13 20:27:44 -04:00
KernelDeimos 6a129ba8cc perf: skip quick_check for only one provider
The 'quick_check' increases the amount of time it takes to perform a
stat operation significantly proportional to the time it takes to do
a stat because an fsentry fetch occurs before a transient
memoization map is available for an operation.
2025-09-13 20:27:44 -04:00
dependabot[bot] 915358cec4 build(deps-dev): bump rollup from 3.23.0 to 3.29.5 in /src/terminal (#1553)
Bumps [rollup](https://github.com/rollup/rollup) from 3.23.0 to 3.29.5.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG-3.md)
- [Commits](https://github.com/rollup/rollup/compare/v3.23.0...v3.29.5)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 3.29.5
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-13 16:01:23 -07:00
dependabot[bot] 1f3e83a9a0 build(deps): bump path-to-regexp from 6.2.1 to 6.3.0 in /src/phoenix (#1552)
Bumps [path-to-regexp](https://github.com/pillarjs/path-to-regexp) from 6.2.1 to 6.3.0.
- [Release notes](https://github.com/pillarjs/path-to-regexp/releases)
- [Changelog](https://github.com/pillarjs/path-to-regexp/blob/master/History.md)
- [Commits](https://github.com/pillarjs/path-to-regexp/compare/v6.2.1...v6.3.0)

---
updated-dependencies:
- dependency-name: path-to-regexp
  dependency-version: 6.3.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-13 13:48:24 -07:00
Nariman Jelveh 1c64aee87e Update package-lock.json 2025-09-13 13:45:49 -07:00
dependabot[bot] 298cb83c48 build(deps): bump braces from 3.0.2 to 3.0.3 in /src/phoenix (#1551)
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-version: 3.0.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-13 13:43:31 -07:00
dependabot[bot] d746d3ef55 build(deps): bump serialize-javascript and mocha in /src/phoenix (#1550)
Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) to 6.0.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `serialize-javascript` from 6.0.0 to 6.0.2
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.0...v6.0.2)

Updates `mocha` from 10.2.0 to 10.8.2
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v10.2.0...v10.8.2)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-version: 6.0.2
  dependency-type: indirect
- dependency-name: mocha
  dependency-version: 10.8.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-13 13:38:43 -07:00
dependabot[bot] 7e1a3c9ac7 build(deps): bump get-func-name from 2.0.0 to 2.0.2 in /tools/api-tester (#1549)
Bumps [get-func-name](https://github.com/chaijs/get-func-name) from 2.0.0 to 2.0.2.
- [Release notes](https://github.com/chaijs/get-func-name/releases)
- [Commits](https://github.com/chaijs/get-func-name/commits/v2.0.2)

---
updated-dependencies:
- dependency-name: get-func-name
  dependency-version: 2.0.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-13 13:30:47 -07:00
dependabot[bot] a38d8db965 build(deps): bump axios from 1.4.0 to 1.12.0 in /tools/api-tester (#1548)
Bumps [axios](https://github.com/axios/axios) from 1.4.0 to 1.12.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.4.0...v1.12.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.12.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-13 13:28:13 -07:00
dependabot[bot] 3c2639403c build(deps): bump form-data from 4.0.0 to 4.0.4 in /tools/api-tester (#1547)
Bumps [form-data](https://github.com/form-data/form-data) from 4.0.0 to 4.0.4.
- [Release notes](https://github.com/form-data/form-data/releases)
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](https://github.com/form-data/form-data/compare/v4.0.0...v4.0.4)

---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-13 13:26:11 -07:00
Nariman Jelveh a582c0ee38 Update package-lock.json 2025-09-13 13:19:58 -07:00
Nariman Jelveh 8392396b1b Update Axios 2025-09-13 13:18:01 -07:00
Nariman Jelveh 338ae161d7 closes #1545 2025-09-13 13:16:37 -07:00
shadow-tawandjelveh ac9a42b8e2 Updating the Arabic (العربية) translation (#1543)
* the Arabic (العربية) translation of Puter is Completed

* Update ar.js

* updating the Arabic (العربية) translation of Puter

---------

Co-authored-by: jelveh <[email protected]>
2025-09-12 18:26:30 -07:00
KernelDeimos e926738d64 perf: add some new keys to initial fetch 2025-09-12 19:40:26 -04:00
KernelDeimos 7bc03fe17c perf: fix sequential kv gets for default apps 2025-09-12 19:33:43 -04:00
KernelDeimos 5d3863d473 style: user_preferences.default_apps
This snippet of code doesn't need to iterate over keys, it can iterate over
values instead. Also, this "let" can be a "const".
2025-09-12 19:23:24 -04:00
KernelDeimos 5119efaf79 Reapply "feat: support Gemini imagegen service"
This reverts commit 05071b4338.
2025-09-12 19:16:58 -04:00
KernelDeimos c40c138aa2 fix: I have no idea how I didn't catch this
Apparently this just never happens when I use Puter locally.
2025-09-12 19:09:41 -04:00
KernelDeimos 05071b4338 Revert "feat: support Gemini imagegen service"
This reverts commit e13b008c79.

This is being done temporarily to debug something else without
confounding variables.
2025-09-12 18:43:20 -04:00
ProgrammerIn-wonderland e13b008c79 feat: support Gemini imagegen service 2025-09-12 18:17:31 -04:00
KernelDeimos b3e2b69c4d perf: execution context memoization map for filesystem
This commit adds an object called ECMAP. This object is a transient
memoization store for use by FSNodeContext.
2025-09-12 18:13:41 -04:00
KernelDeimos 43a0be33ca fix: selector handling from 8cfa0ece
For instances where svc_fs.node was called and explicitly passed a
NodePathSelector (instead of being passed a legacy-style object
with a path attribute) this code was failing. This commit moves the
affected code snippet after input coercion and updates references
to use the coerced input.

style: formatting changes were applied to the code. Instead of using
nested conditional blocks we use labelled breaks
2025-09-12 16:59:47 -04:00
KernelDeimos c508189455 fix: missing condition in ownership check
Not sure when this went away, but we were always getting the
permission though the file path instead of ID/UUID from what it
looks like, which was hiding this problem.
2025-09-12 16:45:39 -04:00
KernelDeimos b8354cc4a6 perf: always shortcut is-owner implicator 2025-09-12 15:26:09 -04:00
Nariman Jelveh 8cfa0ece15 Hit the cache under the user object when trying to resolve paths to system directories 2025-09-12 11:43:49 -07:00
Nariman Jelveh a1eb954221 Short-circuit for apps accessing their own AppData directory. 2025-09-11 22:03:27 -07:00
Nariman Jelveh 7511a1518c Short-circuit the permission check for users accessing their own files 2025-09-11 21:41:42 -07:00
KernelDeimos 9582297547 perf: naive permission cache
Add a simple 20 second cache with kv.js to the scan_ method of
PermissionService. This will not improve the performance for
the permission system, but it will invoke it less often.
2025-09-11 22:37:09 -04:00
KernelDeimos 7dfb05f589 fix: try skipping any directory in extensions named gui
Putting the constants at the top of these files breaks things, but
skipping any directory named "gui" is probably safe.
2025-09-11 20:15:19 -04:00
Neal Shah acda7b73ef New image models (#1542)
* Refactor OpenAIImageGenerationService to more easily support new models, add GPT-image-1

* set default image model to gpt-image-1
2025-09-11 20:00:22 -04:00
KernelDeimos 709f5444b2 fix: skip files with //!noprepend at the top
This is a quick solution for javascript files that should not have Puter
extension code prepended to the top of them. We may want to do something
different in the future like skipping directories named "gui" or
following imports (we can only do that with ESM though) or actually
having a way to run ES modules in their own global context (which is
avaialble in node.js as vm.Module under an experimental flag, but there
is no way to use the default linker for imports in the module);
basically there's no good way to do this and it is very unfortunate.
2025-09-11 18:08:15 -04:00
Siddharthan P S 76eb76c277 i18n(ta): complete missing Tamil translations in ta.js (#1541) 2025-09-11 12:12:42 -07:00
Md. Sabbir Ahmed ef16f904ce dev: add missing bengali translations (#1537) 2025-09-10 22:18:19 -07:00
shadow-tawandjelveh 8f928b1442 the Arabic (العربية) translation of Puter is Completed (#1538)
* the Arabic (العربية) translation of Puter is Completed

* Update ar.js

---------

Co-authored-by: jelveh <[email protected]>
2025-09-10 22:15:50 -07:00
f8edb1d31e Adding missing Spanish translations (#1536)
* feat: adding missing Spanish translations. This fixes #1530

* fix: fixing typos

* remove the `Missing translations` comment

---------

Co-authored-by: RicMonster1 <[email protected]>
Co-authored-by: jelveh <[email protected]>
2025-09-10 22:11:13 -07:00
Daniel Salazar 63433880ec Merge pull request #1497 from HeyPuter/DS/expireAt
feat: add expiry support to DBKV, and eslint config
2025-09-10 17:18:13 -07:00
ProgrammerIn-wonderland b3191e3b5d fix: Remove polluting logging in __all__.js 2025-09-10 14:44:16 -04:00
Daniel Salazar f8ea790824 feat: add expiry support to DBKV, and eslint config 2025-09-10 11:33:21 -07:00
Deepam Goyal 3f746b94de feat(i18n): add missing Hindi translations (#1525) (#1534) 2025-09-10 09:33:03 -07:00
jelveh 7ff5786038 add missing keys and placeholders to i18n 2025-09-09 20:27:58 -07:00
KernelDeimos eb6c23dd83 sync: package-lock.json
Previous commit to do this contained accidental other changes that I
staged and forgot about. This commit really only contains the sync for
package-json. This was broken for a while - since when we did work on
AWS secrets manager.
2025-09-09 22:37:36 -04:00
KernelDeimos 5a66bdeb20 Revert "sync: package-lock.json"
This reverts commit 281d9ebaae.
2025-09-09 22:37:12 -04:00
KernelDeimos 281d9ebaae sync: package-lock.json
This got out of sync after the AWSSecretsPopulator commit, I think.
2025-09-09 22:31:01 -04:00
Nariman Jelveh bb6bcd05c2 Remove unnecessary comment from some i18n files 2025-09-09 19:01:53 -07:00
Tarun sainiandNariman Jelveh fb04c55216 feat(UI): Differentiate tablet UI based on pointer capabilities (#1482)
* feat: Differentiate tablets by pointer type

Reclassifies tablets with a mouse/trackpad to use the desktop UI.

This is detected by checking for `(hover: hover)` media query capabilities. This ensures that touch-only tablets retain their original, touch-friendly mobile UI while fixing the bug for users with pointer devices.

* Make sure `matchMedia` exists before using it

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-09 18:58:04 -07:00
Nariman Jelveh c59dbcfaa2 Revert "Refactor GeminiService for modularity, error handling, and readabilit…" (#1496)
This reverts commit 318ecb9f49.
2025-09-09 18:00:43 -07:00
Imroz 318ecb9f49 Refactor GeminiService for modularity, error handling, and readability (#1438) 2025-09-09 18:00:29 -07:00
Xiaochen Cui 046e905857 captcha: complete the docs (#1494) 2025-09-09 17:49:38 -07:00
KernelDeimos d198e26629 fix: oops, it's not puter.config here
abuse.js is not an extension, but I was treating it like an extension.
2025-09-09 19:09:39 -04:00
KernelDeimos 2ba6152c70 dev: add stack trace for database in jaegar
When using opentelemetry to analyze the system with jaegar, I found this
additional information helpful.
2025-09-09 19:05:33 -04:00
KernelDeimos 7d4c7bae20 dev: improve error message in UIDesktop
This error message in UIDesktop caused me confusion earlier because it
didn't provide any indication of where the error came from. This commit
adds a string behind the error to specify that it happened while trying
to launch an app.
2025-09-09 19:04:44 -04:00
KernelDeimos 6120515300 dev: allow passing JWT options to create_access_token 2025-09-09 19:04:12 -04:00
KernelDeimos 2954b6225b fix: add undefined check for gui metadata
This commit adds an undefined check for metadata from Puter's desktop
GUI inside a filesystem operation frame; this information won't always
be available.
2025-09-09 19:03:01 -04:00
KernelDeimos 8e6fba9e66 dev: options to disable undesirable checks in dev
Allows disabling abuse checks undefined origin checks with config
parameters to make development more convenient. The approach before this
change has been to manually comment out these lines of code.
2025-09-09 19:01:27 -04:00
KernelDeimos a4d1855b70 fix: add missing file
File missing from previous commit
2025-09-09 15:42:00 -04:00
KernelDeimos 34501e34b7 dev(kernel): make extension variable more global-like
The extension pseudo-global was only available at the root synchronous
execution context of a module loaded as an extension, which meant it
wasn't available for such things as handler functions for listeners even
though it looks like it should be lexically scoped.

This commit writes a `const` to the top of javascript files in the
runtime copy of an extension so that it works as nearly to a real global
as possible.

A real global isn't possible here for two reasons. First, running in the
same v8 VM as Puter means we can't have distinct global objects with the
same name across different extensions. Second, we can't use node:vm
because we would then be unable to support ES modules, which are
experimental in node:vm and also there's no equivalent to createRequire
for the linker even if we wanted to require the
--experimental-vm-modules flag in our package.json. This seems to be the
best we can do given the state of affairs of the runtime.
2025-09-09 15:37:22 -04:00
Daniel Salazar caa383d5cd feat: logging for queries in puter js 2025-09-09 12:08:21 -07:00
KernelDeimos 8c2e459f3c fix: third times the charm 2025-09-09 13:44:53 -04:00
KernelDeimos b44278197e dry: query parameter makes more sense for /healthcheck 2025-09-09 13:32:08 -04:00
KernelDeimos 8242ade01b mon: add alternative to /healthcheck
Some monitoring services want a system to look like it's failing hard
instead of a system being able to report that it's failing successfully.
This commit adds an alternative to healthcheck that throws 500 when any
service is failing, as though reporting such depended on the services
working, to appease these monitoring services and their semantically
incorrect nature of operation.

This commit message sets the precedent for "mon:" as a conventional
commit style prefix for changes related to system health and monitoring.
2025-09-09 13:14:11 -04:00
KernelDeimos 48982cac84 perf(kernel): parallelize extension installation
This optimization speends up load time for Puter significantly when many
extensions are present. This is also necessary for subsequent changes
which may require prepending code to all the source files inside an
extension, which would be too slow without this optimization.
2025-09-09 03:25:04 -04:00
KernelDeimos 6919974d66 dev: minlog is off by default for Archlinux
We can assume Arch users are comfortable with making configuration
changes and observing high volume log output (maybe not true for
alternative distributions of arch, but for base Arch absolutely) so it
probably makes sense to have the log minimizer off for these cases.
2025-09-08 21:37:46 -04:00
Nariman Jelveh c2bd222532 Create BUG-BOUNTY.md (#1483)
* Create BUG-BOUNTY.md

* Update BUG-BOUNTY.md
2025-09-08 18:38:40 -07:00
Zac0511 6904017183 Update fr.js (#1493)
Added missing translations from latest updates
2025-09-08 14:43:20 -07:00
ProgrammerIn-wonderland 72e66da8a1 fix: webdav MOVE/COPY escaping bug 2025-09-08 11:45:51 -04:00
Nariman Jelveh bd818d86be Revert "Fix mac setup bug (#1449)" (#1492)
This reverts commit dfcf234d47.
2025-09-07 16:08:40 -07:00
Pranav AgoneandPranav Agone dfcf234d47 Fix mac setup bug (#1449)
* fix(desktop): prevent horizontal scrolling by constraining window drag #710

* docs: Force add config.example.json for Mac Docker setup (#1427)

---------

Co-authored-by: Pranav Agone <[email protected]>
2025-09-07 16:08:21 -07:00
Vara Rahul RajanaandNariman Jelveh cddfa0ca11 fix(gui): prevent background apps from stealing focus (#1491)
* fix(gui): prevent background apps from stealing focus

* remove the `background` option as it's not really needed or used in other parts

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-09-07 15:44:32 -07:00
Nariman Jelveh d324814e06 Update AI.js 2025-09-07 13:15:00 -07:00
Nariman Jelveh 47012a67ab Update UIWindowPublishWebsite.js 2025-09-05 17:33:38 -07:00
ProgrammerIn-wonderland ecff560480 fix: Use APIErrror.create in place of newAPIError 2025-09-05 20:26:39 -04:00
Hariz 4a0de7b2fc Reduce bottom bound on dragging UIItems (#1485) 2025-09-05 17:17:22 -07:00
ProgrammerIn-wonderland ba2609be28 fix: APIErrors in entri service 2025-09-05 20:14:25 -04:00
ProgrammerIn-wonderland 7e0b8c66c4 fix: use correct API error in entri-service 2025-09-05 19:10:40 -04:00
ProgrammerIn-wonderland 7082059fa4 dev: Add deleteMapping to entri service, add extra validation for getConfig 2025-09-05 19:03:04 -04:00
ProgrammerIn-wonderland 35c66f7d42 webdav range support and URI encode fixes 2025-09-05 18:18:03 -04:00
KernelDeimos e6eff9940d dev(backend): emit rename through EventService
While previously the /rename endpoint sent only a websocket message to
the client, move didn't fire a rename event if the name of the file had
changed. This commit adds a more generalized rename event that can be
reliably used to update a UI whenever the name of a file changes.
2025-09-05 12:57:38 -04:00
KernelDeimos 994233aa0a clean: remove a couple of verbose logs 2025-09-05 12:57:38 -04:00
Hariz 85451447c4 Fix buggy arrow key navigation in start menu (#1477)
* Fix buggy arrow key navigation in start menu

* More fixes for start menu keyboard navigation

* Fix issue with start menu searchbar focus

* Rewritten start menu keyboard navigation
2025-09-05 00:19:23 -07:00
Nariman Jelveh bf9be900cc Update UIItem.js 2025-09-04 19:38:02 -07:00
Nariman Jelveh a68f0edc41 Don't allow items to be dragged out of the viewport 2025-09-04 19:36:03 -07:00
Nariman Jelveh 55c173c0b7 surgically accurate item name editor sizing 2025-09-04 12:36:30 -07:00
Neal ShahandDaniel Salazar 628459209c fix: puter workers url 🐛 (#1480)
* fix: puter workers url 🐛

---------

Co-authored-by: Daniel Salazar <[email protected]>
2025-09-03 12:41:01 -04:00
Nariman Jelveh 222117c39a Revert "docs: Add documentation for Entity Storage internals (#1478)" (#1479)
This reverts commit 6ef404aa54.
2025-09-03 08:13:01 -07:00
Tarun saini 6ef404aa54 docs: Add documentation for Entity Storage internals (#1478) 2025-09-03 08:12:37 -07:00
jelveh ea056aa9f3 Update OpenAICompletionService.js 2025-08-31 09:06:38 -07:00
jelveh 3f3895b0b4 Update AI.js 2025-08-30 00:07:09 -07:00
Nariman Jelveh 99ee3279c3 Update AI.js 2025-08-29 18:31:13 -07:00
ProgrammerIn-wonderland 23b65eee49 Disable AWSSecretsPopulator 2025-08-29 20:38:42 -04:00
ProgrammerIn-wonderland c61b736ac8 AWS Secrets populator support 2025-08-29 20:30:06 -04:00
KernelDeimos 43232ccc32 fix: less copying of service configs 2025-08-29 19:30:48 -04:00
KernelDeimos aebc758cbf fix: objutil 2025-08-29 19:06:36 -04:00
KernelDeimos e4262201d8 dev: update objutil 2025-08-29 18:41:28 -04:00
KernelDeimos d05696f1a7 dev: object value transform iterator utility
When you need to transform strings or other primitives inside an object
and preserve the object's structure in an optimally memory-efficient
way, this does that.
2025-08-29 17:33:45 -04:00
KernelDeimos d1b4458c74 fix: possible missing path properties in /sign
When /sign is called with UIDs instead of paths, it is possible to get a
response without 'path' properties present in "signed fs item" objects.
This commit addresses the issue by fetching paths from FS node objects
as a last resort.
2025-08-29 16:08:17 -04:00
Nariman Jelveh d4674d7ddd Use the correct blue background for the logo in the loading CAPTCHA 2025-08-28 15:58:33 -07:00
KernelDeimos 6d8889e434 dev: add config.__set_config_object__() 2025-08-28 18:28:29 -04:00
Nariman Jelveh 4c8d170202 Merge branch 'main' of https://github.com/HeyPuter/puter 2025-08-28 15:27:40 -07:00
Nariman Jelveh 23be92e64c keep the signup button enabled by default 2025-08-28 15:27:13 -07:00
Xiaochen Cui 0c39f83078 captcha: imporve condition checks for cloudflare turnstile (#1469)
* captcha: imporve condition checks for cloudflare turnstile

* captcha: fix undefined "resetTurnstile" func

* captcha: set appearance

* captcha: add the missing prefix
2025-08-28 15:23:26 -07:00
Xiaochen Cui a98cc45f22 feat: memory filesystem provider
* Reapply "dev: memory filesystem"

This reverts commit 6f3bace4c4.

* fs: improve the robustess of set/get_storage api
2025-08-28 16:08:21 -04:00
KernelDeimos 481b18b228 fix: hoist resetTurnstile 2025-08-28 14:12:25 -04:00
jelveh 245a04047e Update initgui.js 2025-08-27 17:29:34 -07:00
ProgrammerIn-wonderland 42d561416e Merge branch 'XiaochenCui-captcha' 2025-08-27 20:02:08 -04:00
ProgrammerIn-wonderland 4027ad951f Merge branch 'captcha' of https://github.com/XiaochenCui/puter into XiaochenCui-captcha 2025-08-27 20:01:57 -04:00
ProgrammerIn-wonderland f0d1a424a6 dev: Range header support in puter hosting (puter.site) 2025-08-27 19:19:36 -04:00
XiaochenCui bb2c51b840 captcha: add captcha widget to the signup window 2025-08-27 16:19:06 -07:00
ProgrammerIn-wonderland 45c8bfa335 expose offset && byte_count in fs.read 2025-08-27 18:55:17 -04:00
ProgrammerIn-wonderland e48179a1f9 fix: improve support for unbounded range headers 2025-08-27 18:01:19 -04:00
ProgrammerIn-wonderland 9863f92aaa better range header support 2025-08-27 17:33:11 -04:00
KernelDeimos 6f3bace4c4 Revert "dev: memory filesystem"
This reverts commit 1f6bbe1672.
2025-08-27 14:26:03 -04:00
Xiaochen Cui 1f6bbe1672 dev: memory filesystem
* fs/memory-provider: passed all apitests

* test: write benchmark

* fs: add benchmark for stat-intensive scenario

* apitest: update duration

* fs: remove "NodeSelector", add checks to memoryfs, passed simple test

* test: update apitest

* debug: remove a debug stmt
2025-08-27 14:12:31 -04:00
XiaochenCui c34bd8177c test: fix apitest, add new unit tests and benchmarks, normalize output 2025-08-27 13:48:00 -04:00
ProgrammerIn-wonderland c0c601ac8f return partial content header 2025-08-26 18:43:29 -04:00
KernelDeimos 4a996c556a fix: issue cancelling replace during save by move 2025-08-26 18:36:44 -04:00
ProgrammerIn-wonderland 1b25dc6e50 change capitalization of getReadURL.js 2025-08-26 18:27:10 -04:00
ProgrammerIn-wonderland 542cda38b7 create getReadUrl 2025-08-26 18:17:03 -04:00
jelveh d2ea480dc6 clean: log 2025-08-26 14:53:42 -07:00
KernelDeimos 2a9310edf2 clean: log 2025-08-26 17:49:48 -04:00
KernelDeimos 64f7f928d6 dev: add expiresIn 2025-08-26 17:26:54 -04:00
DHANUSH RAJAandNariman Jelveh 607b555961 fix: remove unnecessary scrollbar from Account page (#1307)fix: remove unnecessary scrollbar from Account page (#1307)Fix account scrollbar issue by changing overflow:hidden to overflow:v… (#1465)
* Fix account scrollbar issue by changing overflow:hidden to overflow:visibleFix scrollbar issue by changing overflow:hidden to overflow:visibleUpdate UITabAccount.js

* Update license URL in UITabAccount.js and improve code formatting

---------

Co-authored-by: Nariman Jelveh <[email protected]>
2025-08-26 14:24:24 -07:00
KernelDeimos 915bcf5f07 fix: sometimes WebServer log doesn't have context 2025-08-26 16:46:17 -04:00
KernelDeimos b2d43a0783 dev: add access token permission scanner 2025-08-26 16:17:28 -04:00
ProgrammerIn-wonderland 3dc4bb0d7d dev: add range header to /token_read 2025-08-26 14:55:36 -04:00
ProgrammerIn-wonderland c610fc98e9 update ll_read cache logic to be more respectful of Range header 2025-08-26 14:41:26 -04:00
ProgrammerIn-wonderland 122a93af18 dev: direct range header support in /read 2025-08-26 14:15:43 -04:00
ProgrammerIn-wonderland a08948f905 fix: Diswhitelist credential sharing for CORS 2025-08-26 13:35:40 -04:00
Nariman Jelveh 4c3a68ee51 feat: improve 404 error handling in Puter sites with custom page support (#1466)
- Implement a new method to serve a custom 404.html file if it exists in the subdomain root path.
- Update existing error responses to utilize the new custom 404 handling.
- Ensure fallback to default error handling if the custom file is not found or an error occurs during reading.
2025-08-25 16:08:49 -07:00
Nikhil 090d1afa9c feat: update Norwegian Nynorsk (nn.js) translations (#1463)
- Add translations for all previously missing keys in nn.js
- Add translations for UI elements including window titles, alerts, and desktop UI
- Maintain consistent formatting with proper indentation
- Add contextual English comments to aid future translators
- Ensure all keys follow correct naming conventions

Fixes #366
2025-08-24 11:28:23 -07:00
ProgrammerIn-wonderland 1907e2db6a fix error in macOS's metadata rejection 2025-08-22 17:05:59 -04:00
Neal Shah c1f83bd85f macOS webdav pollution fix (#1462) 2025-08-22 16:59:17 -04:00
Karthikayan 6b11ee1b3a bug: fix tamil language selection text (#1460) 2025-08-22 11:13:39 -07:00
Neal Shah 64126179cc Fix: Microsoft office Bearer issue (#1461) 2025-08-22 14:01:28 -04:00
Nariman Jelveh 76584b9f87 Update UIWindowPublishWebsite.js 2025-08-21 18:24:00 -07:00
Nariman Jelveh 9e648e3e97 Revert prev update 2025-08-21 18:08:29 -07:00
Nariman Jelveh 5d50f838c3 Update UIWindowPublishWebsite.js 2025-08-21 17:45:34 -07:00
Nariman Jelveh 992b10b566 Add UI for custom domains 2025-08-21 16:12:15 -07:00
ProgrammerIn-wonderland a770c5ade6 Merge branch 'main' of https://github.com/HeyPuter/puter 2025-08-21 17:12:26 -04:00
ProgrammerIn-wonderland 439f5fa850 fix: dav: Allow macOS x-epected-entity-length 2025-08-21 17:12:24 -04:00
jelveh 0eb47ac1d3 Update DeepSeekService.js 2025-08-21 10:01:53 -07:00
Nariman Jelveh 91a45c25de Update apps.js 2025-08-20 14:53:01 -07:00
XiaochenCui 04ef8fbc0f fs: fix wrong file content on read 2025-08-20 13:45:30 -04:00
KernelDeimos 018059258b fix: allow paths like %appdata%/subdir
This commit expands on the previously implemented '%appdata%' value for
the 'path' option for "Open File" dialogs and allows it to be a prefix
for arbitrary subdirectories under an app's AppData directory.
2025-08-20 12:42:41 -04:00
KernelDeimos 47e2e8ee78 feat: add 'path' option to showOpenFileDialog
This commit adds a 'path' option to showOpenFileDialog by supporting it
in the relevant conditional block in IPC.js. A special path "%appdata%",
which would otherwise produce an error in the file explorer (so no
conflict is possible), will resolve to the appdata directory of the
current app.
2025-08-20 12:42:41 -04:00
Andrei OnelandEric Dubé 986b0f66e8 doc: putility
* Added reference documentation for: src/putility/src/bases/BasicBase.js

* Added reference documentation for: src/putility/src/libs/context.js

* Added reference documentation for: src/putility/src/libs/log.js

* Added reference documentation for: src/putility/src/concepts/Service.js

* Update src/putility/src/bases/BasicBase.js

Co-authored-by: Eric Dubé <[email protected]>

* Update src/putility/src/concepts/Service.js

Co-authored-by: Eric Dubé <[email protected]>

---------

Co-authored-by: Eric Dubé <[email protected]>
2025-08-18 19:04:44 -04:00
Andrei Onel 7849776605 doc: various jsdoc additions
* Added reference documentation for: src/backend/src/services/auth/Actor.js

* Added reference documentation for: src/backend/src/om/proptypes/__all__.js

* Added reference documentation for: src/backend/src/middleware/anticsrf.js

* Added reference documentation for: src/backend/src/services/auth/AntiCSRFService.js

* Revert "Added reference documentation for: src/backend/src/om/proptypes/__all__.js"

This reverts commit a9bb0fb48b.
2025-08-18 19:01:27 -04:00
ProgrammerIn-wonderland a27f4b60e4 fix: webdav service name for undefined origin 2025-08-18 18:03:57 -04:00
ProgrammerIn-wonderland a046f186d8 fix: webdavfs class init method name init to _init 2025-08-18 17:50:13 -04:00
Neal Shah fcb5aa4078 Dav (#1450)
* Windows WebDav support

* feat: 2fa support for dav

* fix auth cookie when Basic auth present

* dev: dav: refactor handler, support root level navigation

* dev: dav: JSDOCing important things

* fix: possible edge case of password containing colon character

* feat: direct token login for webdav

* set cookie to not be session cookie

* fx: webdav undefined origin support
2025-08-18 17:32:29 -04:00
jelveh b1e3fb136a Merge branch 'main' of https://github.com/HeyPuter/puter 2025-08-18 00:35:55 -07:00
jelveh caa77e61e6 Update apps.js 2025-08-18 00:35:47 -07:00
Shahidpathan22 4f983ff400 Added Norwegian Bokmål translations for missing keys (#1447)
* Added Norwegian Bokmål translations for missing keys

* Added Norwegian Bokmål translations for missing keys
2025-08-17 12:06:29 -07:00
Nariman Jelveh 7202060903 Revert "fix(desktop): prevent horizontal scrolling by constraining window dra…" (#1446)
This reverts commit c93c2965d2.
2025-08-17 00:51:16 -07:00
Pranav AgoneandPranav Agone c93c2965d2 fix(desktop): prevent horizontal scrolling by constraining window drag #710 (#1443)
Co-authored-by: Pranav Agone <[email protected]>
2025-08-17 00:50:47 -07:00
jelveh 81e3428177 Update refresh_item_container.js 2025-08-16 14:20:06 -07:00
jelveh b7860ee099 Update launch_app.js 2025-08-16 13:46:10 -07:00
jelveh bc4cb61331 add transaction for opening apps 2025-08-16 13:43:25 -07:00
jelveh 2ed16b8b43 add support for transactions 2025-08-16 13:15:04 -07:00
Andrew Poženel - SloDevTeamandjelveh 58fa69a2aa Update sl.js (#1445)
* Update sl.js

Added Slovene/Slovenian translation

* Update sl.js

---------

Co-authored-by: jelveh <[email protected]>
2025-08-16 09:46:15 -07:00
jelveh 470dbc8d6b Update UI.js 2025-08-15 23:42:17 -07:00
jelveh d807672af7 close #1103 2025-08-15 23:33:53 -07:00
jelveh 89dd335208 close #1134 2025-08-15 23:01:34 -07:00
Nariman Jelveh 91e6749645 Create template file for the Slovenian i18n 2025-08-15 16:21:07 -07:00
KernelDeimos 7375cb7382 dev: add .undefinedOnCancel to open dialog too 2025-08-15 09:48:37 -07:00
KernelDeimos 5522cfbd52 feat: make it possible to pass signed files to launchApp
Allow apps to launch new instances or other apps with specific files.
The files must be passed as file signature objects, ensuring it was a
file the app was granted access to through a user action.
2025-08-15 09:48:37 -07:00
KernelDeimos e8d63819a8 fix: add .undefinedOnCancel to showSaveFilePicker 2025-08-15 09:48:37 -07:00
KernelDeimos 6b0865e284 feat: add copy mode save
Adds a 'copy' mode to showSaveFilePicker. In this mode, a source file is
copied to the target file. The file may not exist in another apps
AppData directory. Unlike the 'move' mode, the file can be outside of
the app's AppData directory (a "user" file); in this situation the user
will be prompted to grant permission for the copy action. The app will
have access to the newly-created copy.
2025-08-15 09:48:37 -07:00
jelveh 483ba14af8 Update ExecService.js 2025-08-14 23:40:52 -07:00
Nariman Jelveh 8b97657205 Merge pull request #1441 from HeyPuter/launchapp-imrpvements
send source app data to opened app
2025-08-14 23:30:13 -07:00
jelveh 7277be75a8 Update ExecService.js 2025-08-14 23:25:24 -07:00
jelveh bcfb9accb1 Update ExecService.js 2025-08-14 23:22:48 -07:00
jelveh 3747365f9a send source app data to opened app 2025-08-14 23:17:50 -07:00
ProgrammerIn-wonderland aa4bd72b92 take DomainModule to be not DNSModule 2025-08-14 19:00:57 -04:00
ProgrammerIn-wonderland 1a9ff9e954 fix: (for node 18) import parse-domain as esmodule 2025-08-14 18:47:23 -04:00
ProgrammerIn-wonderland 686053a0fe dev: add verification for entri webhooks 2025-08-14 18:32:22 -04:00
ProgrammerIn-wonderland aac6ff14ac custom domains webhook 2025-08-14 18:32:22 -04:00
ProgrammerIn-wonderland d105b341d5 Entri token service 2025-08-14 18:32:22 -04:00
ProgrammerIn-wonderland 58800e5d19 rebase fixes 2025-08-14 18:32:22 -04:00
KernelDeimos 65b288d58d dev: enable DNSModule for local instances 2025-08-14 18:32:22 -04:00
KernelDeimos 4fadd26459 dev: add TXT record verification for domain names 2025-08-14 18:32:22 -04:00
KernelDeimos df602d5edb dev: continue work on custom domains
Adds service for querying controlling user for a domain. If no user is
verified as allowed to control the domain then we give control to the
'admin' user (to support local configurations of Puter).

After this point, I find myself a bit stuck because DNS queries are
incredibly difficult to test locally when you use tailscale.
2025-08-14 18:32:22 -04:00
KernelDeimos 49b0805014 dev: custom domain routing (the easy part)
With this commit alone, any user can specify "domain" on their
subdomains. This means they could affect the route for domains they
don't control, so this is not production-ready without further changes.
2025-08-14 18:32:22 -04:00
Nariman Jelveh 436f2d679f Update WebServerService.js 2025-08-14 12:04:47 -07:00
Nariman Jelveh 8e43fff19d Update WebServerService.js 2025-08-14 11:50:05 -07:00
Nariman Jelveh e225cb92f6 Update WebServerService.js 2025-08-14 11:41:41 -07:00
jelveh 2ddce7166f Add sentry-trace and baggage to allowed headers 2025-08-13 12:38:56 -07:00
KernelDeimos 4ba2f97da0 fix: move temp users to 'user' group when email is confirmed
Temporary users can go through email confirmation which effectively
makes these users registered/permanent users. When email is confirmed
they should be moved to the default group for registered users.
2025-08-13 15:15:36 -04:00
Xiaochen Cui ffc9246070 dev: consolidate fs.written to fs.write (#1392) 2025-08-13 13:21:07 -04:00
jelveh 1e720a7aca Add a subtle gap between maximized window and vertical taskbars 2025-08-08 23:46:59 -07:00
ProgrammerIn-wonderland 282acfb048 filter workers from hosting list 2025-08-08 15:00:40 -04:00
jelveh 478591b676 Update IPC.js 2025-08-08 00:58:22 -07:00
KernelDeimos 5b8c13c147 todo: does this break in different languages? 2025-08-07 18:16:57 -04:00
ProgrammerIn-wonderland 0deaaf4736 accept appName in place of appId 2025-08-07 16:15:20 -04:00
ProgrammerIn-wonderland 82c1f64b37 remove todo comment 2025-08-07 16:15:20 -04:00
ProgrammerIn-wonderland c8c7e22007 add check so workers can only be associated with the context's app 2025-08-07 16:15:20 -04:00
ProgrammerIn-wonderland 66288f798e add ability to specify app for worker 2025-08-07 16:15:20 -04:00
jelveh acc29a35c4 add gpt-5-chat-latest 2025-08-07 11:52:11 -07:00
jelveh c10e6ccd8f Update index.html 2025-08-07 11:48:04 -07:00
jelveh 3ba2c9d052 add gpt 5! 2025-08-07 11:28:26 -07:00
jelveh 312efb947d add Claude Opus 4.1 2025-08-06 23:56:04 -07:00
jelveh 9b1cba407e Update style.css 2025-08-06 22:35:27 -07:00
jelveh d647c7686d Create icon.png 2025-08-06 22:27:14 -07:00
jelveh 41a62326bf Improve Apps class to enforce required fields and improve title handling. Added validation for name and index URL, as they are mandatory for app creation. Updated title assignment to default to name if not provided. 2025-08-06 19:41:14 -07:00
Nariman Jelveh e8f6b06723 Add spinner visibility for worker creation process in dev center 2025-08-06 18:56:17 -07:00
Nariman Jelveh ac35dc55f0 Hide dev-center spinner at the correct time when refreshing lists 2025-08-06 15:41:37 -07:00
ProgrammerIn-wonderland 49d4cbc486 remove driver lsmod check 2025-08-06 15:43:32 -04:00
KernelDeimos 7b1fb5d9a6 fix: confirm email with code flow
It wasn't working:
- erroneously expected `email` parameter in request
- sqlite compatibility issue
- incorrect branching, fixed with guard clause
2025-08-06 14:58:33 -04:00
jelveh f06abf96b3 Update apps.js 2025-08-06 09:34:21 -07:00
Nariman Jelveh a73d10826c adjust website and worker counters in dev center after a deletion 2025-08-05 19:32:31 -07:00
Nariman Jelveh 5968da1202 Merge pull request #1417 from HeyPuter/workers-in-dev-center
Workers and websites in dev center
2025-08-05 19:06:44 -07:00
jelveh 23d2d504f0 Improve table heading visuals 2025-08-05 09:48:50 -07:00
jelveh 64a5de3cc4 fix dev docs link 2025-08-05 09:09:41 -07:00
jelveh 6bccf7dc7d Update style.css 2025-08-05 09:03:35 -07:00
jelveh 5ccdd627ee Add functionality to remove app, website, and worker cards with dedicated functions; streamline deletion process and improve UI updates for empty states. 2025-08-05 08:49:30 -07:00
jelveh 636bf6b8b3 Implement shift-click functionality for checkbox selection in apps, websites, and workers; improve UI responsiveness by updating row activation based on checkbox state. 2025-08-04 23:18:01 -07:00
jelveh 90f1232b87 Refactor dropped items handling in dev-center.js to use window scope and improve UI updates; minor UI adjustment in websites.js and handle empty file paths in workers.js 2025-08-04 22:47:17 -07:00
jelveh 162aa485d0 Add directory change functionality for websites and update UI alert handling 2025-08-04 22:27:07 -07:00
jelveh 59dade2736 fix the bug with directory picker selecting the current directory 2025-08-04 22:18:22 -07:00
jelveh b6fcb78f6e wip 2025-08-04 22:08:32 -07:00
jelveh 9f8c0d3227 Update index.html 2025-08-04 15:25:14 -07:00
jelveh a6db0f1092 Update style.css 2025-08-04 15:20:37 -07:00
jelveh 0d6423a8b1 Enforce email confirmation via GUI for deploying workers 2025-08-04 14:35:28 -07:00
jelveh ab8cdb2d57 Add requestEmailConfirmation to puter.ui 2025-08-04 14:11:55 -07:00
jelveh 39bd825866 fix search functionality by managing 'has-value' class for input fields in websites and workers search 2025-08-04 13:24:36 -07:00
jelveh dc8b7ecb34 update app count when a new app is created 2025-08-04 13:09:50 -07:00
jelveh 1d1b484bca Update workers.js 2025-08-04 00:04:11 -07:00
Nariman Jelveh a340c9a0b7 fix sorting in websites tab 2025-08-03 19:47:45 -07:00
Nariman Jelveh b59b19f8b3 Creating workers or websites start with selecting a file/folder 2025-08-03 19:25:18 -07:00
Nariman Jelveh 59c297db49 search is now isolated to the active tab 2025-08-03 19:06:45 -07:00
Nariman Jelveh 3df0bac9dc count websites and workers at start 2025-08-03 18:39:14 -07:00
Nariman Jelveh 2691818f6e Update index.html 2025-08-03 18:24:02 -07:00
Nariman Jelveh 1bc8de8112 make workers sortable by file path 2025-08-03 18:24:02 -07:00
Nariman Jelveh 12f574ed70 move libs back to original location 2025-08-03 18:24:02 -07:00
Nariman Jelveh 8f18a841b3 Add file column to worker table and enable file path launching 2025-08-03 18:24:02 -07:00
Nariman Jelveh 80ccb2d48b Update workers.js 2025-08-03 18:24:02 -07:00
Nariman Jelveh 4550e4f4fd remove unnecessary console.logs in Login 2025-08-03 18:24:02 -07:00
jelveh 2d0d253f96 Update apps.js 2025-08-03 18:24:02 -07:00
jelveh 30db54f062 Remove context menu from entries 2025-08-03 18:24:02 -07:00
jelveh 3b707c31a7 Search websites supports conenct directory matching 2025-08-03 18:24:02 -07:00
jelveh 99739173d6 Show connected directory on websites list 2025-08-03 18:24:02 -07:00
jelveh f0dba7ca60 Show connected directory for websites 2025-08-03 18:24:02 -07:00
jelveh 36a2f2f7b8 fix issue with deplot area not showing up 2025-08-03 18:24:02 -07:00
jelveh 615de5ec11 wip 2025-08-03 18:24:02 -07:00
jelveh bb7bb532ab wip 2025-08-03 18:24:01 -07:00
jelveh 7fceb804a7 better interaction when deleting websites etc 2025-08-03 18:24:01 -07:00
jelveh 82339b69a3 Add "No websites notice" 2025-08-03 18:24:01 -07:00
jelveh 7c30472bdf add websites tab 2025-08-03 18:24:01 -07:00
Nariman Jelveh e0d7a4aa17 Refactor app and worker management UI with context menus and improved delete functionality 2025-08-03 18:24:01 -07:00
Nariman Jelveh 2f30ce3d4d layout fix 2025-08-03 18:24:01 -07:00
Nariman Jelveh 4b43b24e50 multiple style improvements 2025-08-03 18:24:01 -07:00
Nariman Jelveh c5159a6da2 Update style.css 2025-08-03 18:24:01 -07:00
Nariman Jelveh 32bdd70ed0 improve worker counting 2025-08-03 18:24:01 -07:00
Nariman Jelveh 2d4b5984ed Implement 'Delete' and 'Delete Selected' for workers 2025-08-03 18:24:01 -07:00
Nariman Jelveh 970ba0bd77 enable checkboxes for workers table 2025-08-03 18:24:01 -07:00
Nariman Jelveh fab062b0fe Add the workers and websites tabs 2025-08-03 18:24:01 -07:00
Nariman Jelveh b2cf01e57c Add 'My Workers' tab 2025-08-03 18:24:01 -07:00
ProgrammerIn-wonderland 33629a7acd dev: migrate away from puter.drivers.call() 2025-08-03 17:21:35 -07:00
ProgrammerIn-wonderland 7d4ee75619 fix: return "null" for file_path and file_uid if backing file is nonexistent 2025-08-03 16:19:10 -07:00
ProgrammerIn-wonderland 94b6538851 dev: workers, return iso timestamp instead 2025-08-02 16:44:38 -07:00
ProgrammerIn-wonderland 15eefb1122 dev: expose file_uid in worker calls 2025-08-02 16:29:01 -07:00
ProgrammerIn-wonderland f8e95c4002 dev: query backend for workers.list() and workers.get() now to get path too 2025-08-02 16:24:07 -07:00
Neal Shah a586083b02 change worker API (#1411) 2025-08-02 15:30:45 -07:00
Nariman JelvehandProgrammerIn-wonderland 54aaed3459 Gui deploy workers (#1409)
* add deploy as worker context menu item

* Update UIWindowPublishWorker.js

* quick fix

* Update new_context_menu_item.js

* Show spinner when publishing workers

* Improve worker default file

* fix

---------

Co-authored-by: ProgrammerIn-wonderland <[email protected]>
2025-08-01 14:52:58 -07:00
Neal Shah 6578d4d91c remove sessionStorage params (#1408) 2025-07-31 16:06:37 -07:00
Nariman Jelveh b78e5c4444 Update initgui.js 2025-07-31 13:32:41 -07:00
Nariman Jelveh 26e9d9e0e3 Add the attempt_temp_user_creation option to puter.auth.signIn() 2025-07-31 13:05:40 -07:00
Prathamesh Wankhede d7b731a413 Update nb.js (#1404)
feat(i18n): completed missing Norwegian Bokmål translations in nb.js
2025-07-31 12:35:24 -07:00
Neal Shah 3d227e0798 Update worker limit (#1405)
* Update worker limit

* Handle error for when a mapping has no routes
2025-07-31 12:34:19 -07:00
Rohan Rawat 0f91503eb5 docs: added utils.js build script documentation (#1402) 2025-07-31 12:22:52 -07:00
Neal Shah 81ecb13370 Support a few more incoming and global objects in workers (#1401)
* no more global puter object in workers

* also support my as a global in workers

* support incoming user object in workers

* also support myself in puter workers
2025-07-30 19:39:34 -07:00
ProgrammerIn-wonderland 8e58fabb71 improve error handling, user specific worker limit 2025-07-30 15:43:16 -07:00
ProgrammerIn-wonderland 299e7b6e10 Make puter.workers.get() return more info 2025-07-30 12:21:24 -07:00
ProgrammerIn-wonderland 3e2e42fa53 Add coersion to JSON response in workers 2025-07-30 12:21:24 -07:00
ProgrammerIn-wonderland 616ddf8467 Supoport multiple domains to one worker 2025-07-30 11:53:03 -07:00
ProgrammerIn-wonderland d5f0137c0a Make worker names global && return improve error handling for APIError 2025-07-30 11:53:03 -07:00
XiaochenCui 85a0f71bfd hotfix: emit the missing event, fix check condition 2025-07-30 10:25:13 -07:00
Neal Shah 3016eb6363 ask user for auth if no token (#1389) 2025-07-29 20:45:40 -07:00
Neal Shah 402c407f81 Allow - in worker name
Sent from my iPhone
2025-07-29 20:03:13 -07:00
ProgrammerIn-wonderland a2126d5dd6 worker global s2w -> router 2025-07-29 22:03:58 -04:00
Karan Singhandjelveh a15fdd0b6d dev: Replaced human-readable text with i18n keys (#1382)
* dev: Replaced human-readable text with i18n keys

* Add two missing keys in UIDesktop.js

* more i18n keys!

* add more keys

* Update UIWindow.js

---------

Co-authored-by: jelveh <[email protected]>
2025-07-29 17:57:18 -07:00
Nariman Jelveh 9a7d34aec9 do not await kv when setting taskbar position 2025-07-29 17:43:07 -07:00
Emmanuel Ferdman 1d27fffb10 Fix issue in invalid social media url
Signed-off-by: Emmanuel Ferdman <[email protected]>
2025-07-29 20:26:09 -04:00
Emmanuel Ferdman 2c4da6f558 Fix issue in invalid social media url
Signed-off-by: Emmanuel Ferdman <[email protected]>
2025-07-29 20:26:09 -04:00
ProgrammerIn-wonderland 5b49e877d9 add protocol to URL returned by puter worker 2025-07-29 20:13:15 -04:00
XiaochenCui 27c1e62687 fs: ll_write -> provider.write 2025-07-29 19:29:35 -04:00
XiaochenCui 026a908a23 fs: ll_mkdir -> provider.mkdir 2025-07-29 19:29:35 -04:00
ProgrammerIn-wonderland 1b1d22e166 puter.workers.exec() 2025-07-29 18:42:33 -04:00
ProgrammerIn-wonderland f962a6a838 Allow relative paths for creating puter s2w workers 2025-07-29 16:18:14 -04:00
ProgrammerIn-wonderland 050ad0f785 add worker file limit 2025-07-29 16:18:14 -04:00
ProgrammerIn-wonderland ba0f4e3f86 remove unneeded logs 2025-07-29 16:18:14 -04:00
ProgrammerIn-wonderland 2fe52cb972 Filesystem backed web workers 2025-07-29 16:18:14 -04:00
ProgrammerIn-wonderland 173340e887 Move s2w workers to be backed by files and commit that information to subdomains database 2025-07-29 16:18:14 -04:00
ProgrammerIn-wonderland 27b9cb0b4c Add "coerce to response" if compatible type is returned by an s2w route 2025-07-29 16:18:14 -04:00
ProgrammerIn-wonderland 02e49a44be Making streaming drivers ReadableStreamable 2025-07-29 16:18:14 -04:00
KernelDeimos cbb833f3de Revert "sync: update OpenAI moderation to use new model"
This reverts commit 1b56bdc526.

OpenAI told us to switch to this model for moderation, but this model
clearly isn't ready for production use yet.
2025-07-29 16:08:05 -04:00
Nariman Jelveh 88011cfb1f Update README.md 2025-07-29 12:23:41 -07:00
KernelDeimos d4250d65aa fix: don't encrypt session UUID if there isn't one 2025-07-29 13:35:03 -04:00
Glenn Dmello ec586e834a modified nb.js (#1381) 2025-07-29 10:22:39 -07:00
XiaochenCui dea6069398 fs/stat: return_permissions -> return_shares, update tests as well 2025-07-29 13:17:55 -04:00
XiaochenCui 97eeadb3e4 fs: fix failed tests in move and stat 2025-07-29 13:17:55 -04:00
Nariman Jelveh f3b09cf170 Update index.js 2025-07-28 22:03:25 -07:00
Nariman Jelveh b5a1be6823 Update style.css 2025-07-28 21:02:29 -07:00
Nariman Jelveh 12f4c2c3d2 Fix the issue with Properties window not working in Explore 2025-07-28 20:08:11 -07:00
KernelDeimos 1b56bdc526 sync: update OpenAI moderation to use new model 2025-07-28 20:47:56 -04:00
Nariman Jelveh 1df1afca37 Update index.js 2025-07-28 16:17:35 -07:00
Nariman Jelveh 75fc436b54 add dividers in the taskbar 2025-07-28 16:17:23 -07:00
KernelDeimos 0257c1475e dev: add async getter for 'owner' on FSNodeContext 2025-07-28 18:30:02 -04:00
KernelDeimos 925b1ff4b4 dev: add fs.written event
Unlike fs.write, fs.written is only emitted after the contents of the
fily have been fully streamed and comitted to the delegate storage.
2025-07-28 18:23:00 -04:00
KernelDeimos f2a29d5228 fix: prevent entity mutation during upsert
In EntityStoreService, update and upsert both make use of the
detect_identifier utility function to get an identifier to pass through
to (eventually) SQLES.

For `update`, the `id` object is passed as the argument. Properties are
removed from this object when "redundant identifiers" are extracted to
create the update predicate.

For `upsert`, the `entity` object is passed and `id` is ignored. It is
suspected that this was done for reasons of improved developer
experience for developers using the API. The mutation behavior of
detect_identifier caused issues when trying to modify a property that
can also be used as an identifier, without having another identifier
available. (i.e. need to get UID of a subdomain to change the
`subdomain` property instead of just using `subdomain` to identify it).

This commit modifies the default behavior of detect_identifier to not
remove properties, then adds a flag to preserve the previous behavior
which is set TRUE by `update` since it's widelely used by puter.js and
has higher impact for potential regressions.
2025-07-28 17:41:46 -04:00
KernelDeimos 9f8cd18fd8 dev: add bypass for Entity Storage validation 2025-07-28 15:10:44 -04:00
jelveh 89ea1ae699 Update security.txt 2025-07-28 09:16:24 -07:00
Nariman Jelveh cfa7e23e84 Fix the selectable positioning and sizing issues in Explore. All set! 2025-07-27 20:20:19 -07:00
Nariman Jelveh e1f52ebd88 Update UIWindow.js 2025-07-27 20:09:34 -07:00
Nariman Jelveh 2e30f292f4 Improve selection visualization logic for Explore widnows.
This doesn't completely fix the misalignment of selection area but improves a lot of issues with it. A temporary, middle-ground solution until I implement the full-on selection area rendering
2025-07-27 18:52:37 -07:00
Nariman Jelveh 2cd3245b49 Update package-lock.json 2025-07-27 15:35:50 -07:00
jelveh bc842ad371 Update viselect.min.js 2025-07-27 11:32:37 -07:00
jelveh 783a0385d3 Remove Slider component 2025-07-27 11:04:45 -07:00
jelveh 8a697652d9 Use regular UIWindow component in UIWindowTaskManager 2025-07-25 23:59:29 -07:00
jelveh cadaff441c Remove unnecessary onAppend callbacks 2025-07-25 23:39:21 -07:00
jelveh dd76ac27ae Update UITaskbar.js 2025-07-25 20:22:38 -07:00
KernelDeimos d17b466e37 fix: properly update owner object in FSNodeContext 2025-07-25 22:12:19 -04:00
jelveh 01e4faa762 Update UITaskbar.js 2025-07-24 12:54:45 -07:00
jelveh 261bfd1c03 Adjust taskbar items' height and width based on number of items in the taskbar 2025-07-24 12:06:38 -07:00
Yasir Rafique e9184902ea chore: add Prettier config 2025-07-24 13:09:46 -04:00
Nariman Jelveh bfd1f8faab Configurable taskbar position (#1372)
* feat(gui): Enhance taskbar functionality and positioning

- Implement dynamic taskbar position management with options for left, bottom, and right placements.
- Update desktop dimensions and window positioning based on taskbar position.
- Add context menu options for changing taskbar position on desktop devices.
- Ensure mobile devices always display the taskbar at the bottom.
- Introduce CSS styles for taskbar positioning and adjust desktop padding accordingly.

* feat(gui): Reinitialize tooltips based on taskbar position

- Implement dynamic tooltip positioning for taskbar items based on the current taskbar location (left, right, bottom).
- Ensure tooltips are destroyed and recreated when the taskbar position is updated, enhancing user experience and consistency.

* feat(gui): Improve taskbar and tooltip positioning

- Add support for dynamic tooltip positioning for the 'top' taskbar location.
- Adjust CSS styles for arrow tooltips to enhance visual alignment and positioning.
- Refine taskbar item positioning for left and right placements to ensure consistent appearance.

* Improve popover positioning based on taskbar location

- Improve `UIPopover` positioning logic to account for left and right taskbar placements.
- Adjust Y position of popovers to ensure they appear correctly below toolbars for left/right taskbars.
- Update CSS styles for arrow tooltips to enforce consistent positioning with !important declarations.

* Refactor context menu positioning logic in UITaskbarItem

- Introduce a helper function to dynamically calculate context menu position based on the taskbar's location (top, bottom, left, right).
- Ensure context menus are positioned correctly relative to the taskbar item, improving usability across different taskbar placements.

* Fix UITaskbar window height calculation for consistent positioning

- Adjust the height calculation for windows in the UITaskbar to remove an unnecessary offset, ensuring accurate window sizing relative to the toolbar height.
- This change improves the visual consistency of maximized windows across different taskbar placements.

* Enhance window snapping and positioning based on taskbar location

- Introduce a new function to calculate snap dimensions and positions dynamically based on the taskbar's location (left, right, bottom).
- Update window snapping logic to ensure windows are positioned correctly relative to the taskbar, improving usability and visual consistency.
- Adjust boundary checks for window placement to account for taskbar height and position, enhancing the overall user experience.

* Update default taskbar position to 'left' and adjust CSS padding for desktop layout

- Change the default taskbar position from 'bottom' to 'left' in UITaskbar.
- Modify CSS to increase left padding for desktop taskbar positioning, enhancing layout consistency.

* Improve CSS for desktop layout with height adjustments

- Update CSS styles for input fields and desktop taskbar to set height to 100vh, ensuring consistent full-page layout across different screen sizes.
- This change improves the visual consistency and usability of the interface.

* Improve desktop selectable interactivity and taskbar tooltip behavior

- Add functionality to mark the desktop as selectable active, improving user interaction with desktop elements.
- Update tooltip display logic to only show when the desktop is not in a selectable state, enhancing usability.
- Adjust CSS styles for desktop layout, ensuring consistent behavior and appearance when the desktop is active or inactive.

* Update default taskbar position logic for first-time and existing users

- Set the taskbar position to 'left' for first-time visitors and default to 'bottom' for returning users without a saved preference.
- This change improves the user experience by providing a more intuitive initial layout for new users while maintaining consistency for existing users.
2025-07-23 15:48:23 -07:00
jelveh 5b46f0bcb1 use openrouter for qwen models 2025-07-22 16:21:56 -07:00
XiaochenCui fee100dddd fs/mkdir: add docs spec, update tests, update apitest 2025-07-22 12:46:03 -04:00
XiaochenCui 7e20039ef4 fs/mkdir: update check logic, update test cases 2025-07-22 12:46:03 -04:00
XiaochenCui f906c1ebad fs: adapt to different mkdir api, block write to root dir, add tests 2025-07-22 12:46:03 -04:00
Neal Shah 6d09566ba7 Allow multipage apps in puterjs (#1368)
* Allow multipage apps in puterjs

* Don't error on browsers which dont support sessionStorage
2025-07-21 14:02:46 -07:00
Nariman Jelveh e14e1acd95 Revert "feat(gui): Add animation effects to the taskbar (#1365)" (#1366)
This reverts commit 212bc88c8f.
2025-07-19 11:12:28 -07:00
GitHubliuzhijie 212bc88c8f feat(gui): Add animation effects to the taskbar (#1365)
- Add new animation functionality to the taskbar; icons will enlarge when the mouse hovers over them
- Introduce new CSS properties and styles to support the animation effects
- Implement mouse move and leave event handling in UITaskbar
- Add UITaskBarCreateCurve and UITask components
2025-07-19 11:11:57 -07:00
jelveh 1b1517d570 add subdomain middleware for extensions 2025-07-18 20:54:26 -07:00
jelveh b8ffc1ada0 Allow CORS on /extensions/ 2025-07-18 20:27:50 -07:00
Neal Shah 0858f9932b Support streaming drivers in XMLHTTPRequest-less platforms (nodejs, serviceworker) (#1364)
* xmlhttpreq partial support pt1

* XMLHTTPRequest shim cleanup

* fix check for x-ndjson

* change credit header at top of xhr shim
2025-07-18 14:35:08 -07:00
Josh Josephandjelveh f9995a219d Fixed issue: #1033 (Added app category display in Dev Center in main app list) (#1350)
* Update README.md

* Fixed issue:  #1033 (Added app category display in Dev Center in main app list)

* Fixed issue:  #1033  (Added app category display in Dev Center in main app list)

* test 1033

* Fixed issue: #1033 (Added app category display in Dev Center in main app list)

* Fixed issue: #1033 (Added app category display in Dev Center in main app list)

* Center the app checkbox

---------

Co-authored-by: jelveh <[email protected]>
2025-07-17 21:03:17 -07:00
Igor Moraes 17a11a3a8b Update Portuguese and Spanish translation README (#1363)
* Update Portuguese translation of README

* Update Portuguese and Spanish translation readme
2025-07-17 20:35:37 -07:00
Neal Shah 481210b6a6 event.puter//user puter and automatic cors exemption handling in puter workers (#1342)
* event.puter

* automatic opt out cors handling

* remove "starting puterjs initialization" log

* Set compatibility date

* remove body log
2025-07-17 15:37:34 -07:00
jelveh cc2670444c Reject promise in signIn is user closes auth window 2025-07-16 18:45:20 -07:00
jelveh 5a7ba5d4ad Do not show file operations in the context menu of root dir 2025-07-15 18:04:04 -07:00
Eric Dubé d5749691b3 doc: link related future work 2025-07-15 16:13:39 -04:00
XiaochenCui 0a8e4f985e mkdir: return 403 error for mkdir action in the root dir 2025-07-15 16:13:39 -04:00
jelveh c75d9b9544 use openrouter for grok 2025-07-13 13:08:18 -07:00
jelveh 05a74b3152 do not preselect tests 2025-07-11 17:03:33 -07:00
jelveh e387abe2f6 Make 'Signup' window draggable 2025-07-11 16:28:37 -07:00
jelveh ef95cd493c MORE TESTS!! 2025-07-11 16:27:14 -07:00
KernelDeimos 963b248582 fix: get sharp far away from bundlers as possible 2025-07-10 16:20:12 -04:00
KernelDeimos 4575b24c51 chore: update sharp because GH issue template 2025-07-10 14:30:00 -04:00
KernelDeimos e85a2703f4 sync: update XAi models 2025-07-09 23:27:24 -04:00
jelveh 3def1d4d7c feat: implement authentication UI in Puter.js's test UI
- Added login and logout functionality with corresponding UI elements.
- Enhanced layout for user information display and login button.
- Integrated authentication state checks to update UI based on user sign-in status.
- Improved button styles and interactions for better user experience.
2025-07-09 16:42:54 -07:00
jelveh 9c74e295bd style: enhance run.html layout and user interaction
- Added user-select: none to disable text selection for better UX.
- Adjusted margins for buttons and elements to improve spacing and alignment.
- Modified the layout of the navigation bar for a cleaner appearance.
2025-07-09 16:20:58 -07:00
jelveh 9ca1f0639a feat: implement settings management and modal in puter.js test framework
- Added a settings button to open a modal for configuring Puter.js URL and API Origin.
- Implemented functions to load and save settings to localStorage.
- Dynamically load the Puter.js script based on user-defined settings.
- Styled the modal and its components for better user experience.
2025-07-09 16:10:06 -07:00
Xiaochen Cui 0b6dbe587a feat(aws/polly): add new apis to puter-js, add new args to txt2speech (#1337) 2025-07-09 15:38:17 -04:00
KernelDeimos 50d520f099 fix: file cleanup for Claude when streaming 2025-07-09 15:12:15 -04:00
KernelDeimos 2c8da38db0 dev: add puter_path support for OpenAI 2025-07-09 15:12:15 -04:00
KernelDeimos ba3ff03569 dev: add finally_fn for cleanup tasks in AI impls 2025-07-09 15:12:15 -04:00
KernelDeimos 389967b659 clean: code does not need to announce it was updated
This broke the jsdoc comment for _init in OpenAICompletionService
2025-07-09 15:12:15 -04:00
jelveh 1573f1dd81 Add tests for puter.ai.txt2speech 2025-07-09 11:54:15 -07:00
KernelDeimos 71f298ea43 debug: make sure this stack trace gets logged 2025-07-08 19:39:53 -04:00
KernelDeimos 2158e8e8c6 dev: add puter file upload via ai.chat for Claude
This commit implements uploading Puter files through ai.chat using
Claude's beta "file inputs" feature. To use this, simply specify
`puter_path` in a content part, and that content part will be
transformed into the correct type of content part for the specified file
and the file will be uploaded.
2025-07-08 19:38:13 -04:00
Neal Shah d8a4180b4f Puter.js workers api (#1339) 2025-07-08 13:29:02 -07:00
Zac0511 858929a3b9 Add a basic Firebase Studio config file (#1338) 2025-07-08 08:32:19 -07:00
jelveh 1952549f5a Add new Mistral model coercions to puter.js 2025-07-07 23:07:32 -07:00
jelveh f50ac9e8f9 Update Mistral models 2025-07-07 22:50:47 -07:00
KernelDeimos cbfb9283d1 fix: add safeguard in case server response is wrong 2025-07-07 17:25:01 -04:00
KernelDeimos 405564f55f fix: update refresh_actor cache invalidation 2025-07-07 15:20:43 -04:00
jelveh 74a01a8752 Add reset results functionality to test UI
- Introduced a "Reset results" button to clear test container backgrounds and remove error messages.
- Implemented hover styles for the reset button to enhance user interaction.
- Ensured the reset functionality hides the progress panel and resets progress tracking.
2025-07-06 18:54:31 -07:00
jelveh 190f8352f0 Add performance tests for get and set methods in kv module
- Introduced two new tests: testGetPerformance and testSetPerformance.
- Each test measures the execution time of the respective method and asserts that it completes in under 100ms.
- Ensured correct value retrieval and performance metrics are logged for both tests.
2025-07-06 17:52:32 -07:00
jelveh 41cb7a06b7 Implement progress panel for test execution tracking
- Added a progress panel to display real-time test execution status, including current test, progress percentage, and elapsed time.
- Introduced styles for the progress panel and its components to enhance visibility and user experience.
- Implemented JavaScript functions to manage progress tracking, including starting and stopping timers, and updating the panel with test results.
- Ensured the progress panel is responsive to test selections and updates dynamically during test execution.
2025-07-06 15:42:02 -07:00
jelveh f23216b122 partially selected checkboxes should are reflected in the heading master checkbox 2025-07-06 15:20:12 -07:00
jelveh f06c13a427 Update test counter styles for improved visibility
- Adjusted the styles for the test counter to enhance its appearance.
- Removed inline styles from the test counter span for cleaner HTML structure.
- Ensured consistent font size and color for better readability.
2025-07-06 15:16:11 -07:00
jelveh a605ef42a1 Enhance test UI with navigation and counter display
- Added a fixed navigation bar for improved accessibility and layout.
- Introduced a test counter to display the number of selected tests.
- Updated styles for better alignment and spacing in the test UI.
- Ensured the counter updates dynamically based on checkbox selections.
2025-07-06 15:11:47 -07:00
jelveh b4143a6f39 Enhance test UI with master checkbox functionality
- Updated the test UI to include a master checkbox that controls the selection of individual test checkboxes.
- Implemented logic to update the master checkbox state based on the selection of individual checkboxes and group checkboxes.
- Adjusted the margin for h2 checkboxes for improved layout.
2025-07-06 14:59:51 -07:00
jelveh afa6333224 Merge branch 'main' of https://github.com/heyputer/puter 2025-07-06 14:55:03 -07:00
jelveh e58d6f0770 Enhance test UI with sticky headers and checkbox groups
- Added sticky positioning for h2 headers in the test section.
- Updated h2 elements to include checkboxes for grouping tests (File System, Key Value Store, AI).
- Implemented event listeners to synchronize individual test checkboxes with their respective group checkboxes.
- Simplified select/unselect all functionality to update group checkboxes accordingly.
2025-07-06 14:54:55 -07:00
KernelDeimos f6e6e8dff8 fix: shortcut KV permissions
All users have access to KV, however the permission system is used
because:
1. KV is a driver, and all drivers have access checks
2. The rate limit policy comes from the permission system

This change uses support for implicit permission shortcuts to prevent
any of the permission association tables from being read. It also
hard-codes the policy so that KV's rate-limit policy is not read from
the policy.json file.
2025-07-06 15:59:07 -04:00
KernelDeimos 3f0e7659f3 dev: add support to imply shortcut permissions
Permission implicators with the "shortcut" option will be checked prior
to concurrent permission scanning. If any of these permissions are
granted, then the concurrent phase of permission scanning will not be
invoked; instead, the user will only see the shortcut permission.

It may be useful to add an option in the future for a full permission
scan, which could be useful in such things as a user interface to help
with permission management.
2025-07-06 15:59:07 -04:00
KernelDeimos 3f483c5bf5 dev: add otel spans for permission scans and db 2025-07-06 15:59:07 -04:00
KernelDeimos fd956cb1cd fix: improvements to jaeger trace service
- migrate config location (legacy location still supported)
- allow passing additional otel options when creating spans
2025-07-06 15:59:07 -04:00
Neal Shah bddc872e00 feat: puter workers
* experimental Cloudflare Workers for Platforms support

* add support for the puter driver

* stop hardcoding api.puter.localhost

* support destroy from express route as well

* initial worker support

* xhrshim + fixes (incomplete)

* change order of readyState + load event

* remove some debug logs

* change worker/puterUtils into a cjs module

* Cloudflare workers eventtarget workaround

* worker preamble webpack

* edit worker readme to reflect reality

* allow a way to code in api endpoint instead of hardcoding it to api.puter.com

* move cloudflare eventtarget fix to puter-portable template

This is so it gets run before the rest of puter-js initializes

* remove express route for worker
2025-07-05 17:01:44 -04:00
jelveh 8fa8dd0987 Add tests for App Directory isolation 2025-07-05 12:24:45 -07:00
jelveh af9bf0980c Add puter.ai streaming test 2025-07-05 11:36:29 -07:00
jelveh a2d05af556 Add support for Uint8Array in puter.fs.write 2025-07-05 11:18:13 -07:00
jelveh b0a2590426 Remove redundant tests in puter.js 2025-07-05 10:53:14 -07:00
jelveh 779ee8d5d2 Add human-readable descriptions to Puter.js tests 2025-07-05 10:50:06 -07:00
jelveh 1fb1edd621 remove unused tests from GUI 2025-07-05 10:26:56 -07:00
jelveh 4ca7e852d8 fix toolbar showing scroll on disabling autohide 2025-07-05 09:41:00 -07:00
jelveh 7ccc704694 Use better font for the test UI 2025-07-04 19:14:18 -07:00
jelveh a02a228bf6 Add a 'test' button to each test in Puter.js's test suite 2025-07-04 19:12:06 -07:00
jelveh 6da8ebfe96 Fix the copy assertion rule in puter.js test suites 2025-07-04 19:05:04 -07:00
jelveh 9698761b2b AND MOOOAREEE AI tests 2025-07-04 19:01:16 -07:00
jelveh 3fdee779c7 MOAAAAREEE AI tests! 2025-07-04 18:43:10 -07:00
jelveh 478aed7bda Add basic tests for puter.ai 2025-07-04 18:20:31 -07:00
Nariman Jelveh 3eef18c578 Remove captcha from frotnend (#1335) 2025-07-04 16:31:42 -07:00
KernelDeimos f3c658c011 chore: sync package-lock.json 2025-07-04 18:30:00 -04:00
KernelDeimos 354b116b42 fix: make sharp optional 2025-07-04 18:29:29 -04:00
KernelDeimos 502204a7b7 test: update tests, migrate backend to vitest
Backend had tests written in mocha as well as a test written for jest
(created by an AI utility, wasn't compatible with mocha tests). The AI
generated test had merit so it was migrated to vitest along with all the
mocha tests, which supports conventions from both frameworks.

Vitest also has an excellent watcher cli.

The root repo package.json now runs unit tests in backend. Before it was
only running tests defined in the _test method of backend services.
2025-07-04 18:21:45 -04:00
Nariman Jelveh 87e15cac2d Update SECURITY.md to use the warning tag in the markdown 2025-07-04 06:51:48 -07:00
Xiaochen CuiandEric Dubé ade213b88b fix: return proper error message when the model is not found (#1331)
* fix: return proper error message when the model is not found

* use global source for the domain

Co-authored-by: Eric Dubé <[email protected]>

---------

Co-authored-by: Eric Dubé <[email protected]>

Closes #1326
2025-07-03 17:58:04 -04:00
KernelDeimos c7970fd1a8 fix: include base reserved words by default 2025-07-03 17:41:10 -04:00
jelveh b0b131f214 add expire mthod to puter.kv 2025-07-02 22:54:55 -07:00
jelveh 6df1d4d5f2 Fix puter.js test for incr and decr in KV 2025-07-02 22:31:25 -07:00
jelveh 2bad220602 Update KVStoreInterfaceService.js 2025-07-02 20:10:00 -07:00
jelveh 0947b90c87 Make puter.js tests print out error results 2025-07-02 20:06:25 -07:00
jelveh 37d09a63d4 Only support language and voice (ordered) in puter.js txt2speech 2025-07-02 18:08:54 -07:00
Nariman Jelveh aa3032da8e Add preliminary support for different voices (#1325) 2025-07-02 17:09:48 -07:00
jelveh 62e786faa6 Do not activate toolbar when desktop selectable is active 2025-07-02 16:14:18 -07:00
jelveh 7285a27be4 Fix toolbar autohide/hide timing 2025-07-01 22:42:50 -07:00
Nariman Jelveh 2103374854 Dynamic toolbar: allow users to customize toolbar sticky (#1330)
* close #1329
2025-07-01 18:37:36 -07:00
Nariman Jelveh 485f9a6f14 Don't hide the toolbar on mobile and tablet (#1328) 2025-06-30 17:18:56 -07:00
Nariman Jelveh 9700488aff Merge pull request #1324 from HeyPuter/dynamic-toolbar
Dynamic toolbar
2025-06-30 16:53:35 -07:00
jelveh edf00a5fd4 Update style.css 2025-06-30 10:24:24 -07:00
jelveh 278bb29ee5 better coloring and delay 2025-06-30 07:01:16 -07:00
jelveh 0864be054c When a window is being dragged don't activate toolbar (duh!) 2025-06-29 19:36:03 -07:00
jelveh 40260a9fb2 full support for fullpage mode 2025-06-29 19:17:58 -07:00
jelveh ad68ddeacc make window snap animation appear faster 2025-06-29 17:36:58 -07:00
jelveh 54ae9c1ca9 the first time toolbar is shown, keep it open until user hovers over it at least once 2025-06-29 16:57:24 -07:00
jelveh b1de89e1ec Update tr.js 2025-06-29 16:03:41 -07:00
jelveh 3db99aa67b Puter will now support only one type of menubar, and that's the in-window type 2025-06-29 15:58:53 -07:00
jelveh 0895418f0c Improve the logic behind hiding the toolbar after clicks and other interactions 2025-06-29 15:18:20 -07:00
jelveh b0fdf1f63d Implement the basics of a dynamic toolbar
Dynamic toolbar will hide and show automatically depending on user actions and state of the app. This is to save screen real estate.
2025-06-29 14:21:40 -07:00
jelveh 657a615d9e Update AI.js 2025-06-28 23:28:31 -07:00
Nariman Jelveh 2ddd26b13d Merge pull request #1319 from Krisss46/fixing-arrow-key-behaviour
fix: arrow key navigation in Explorer (#1089)
2025-06-28 20:44:56 -07:00
Krisss46 5fd5017080 fix: arrow keys unresponsive when selecting items with offset center points 2025-06-29 03:05:17 +01:00
jelveh 9a847760bc Fix #1231 2025-06-28 12:38:39 -07:00
Nariman Jelveh a135c354fb Merge pull request #1318 from XiaochenCui/xiaochen/dev
dev: extension prefix update, doc helper & docs update
2025-06-28 11:29:24 -07:00
Krisss46 ae07a5e316 fix: arrow key navigation 2025-06-28 16:12:12 +01:00
Nariman Jelveh 9b9733c9c2 Merge pull request #1219 from rodrick-mpofu/feature/desktop-shortcut-link
feat: add desktop link shortcuts (refs #682)
2025-06-27 23:27:51 -07:00
jelveh 06f5601a2e Update package.json 2025-06-27 23:10:53 -07:00
jelveh 75d22b010c Update package-lock.json 2025-06-27 23:09:25 -07:00
jelveh c4e32474b2 Remove some redundant checks and favicon handling logic 2025-06-27 23:05:53 -07:00
jelveh ad62182566 Update new_context_menu_item.js 2025-06-27 22:53:49 -07:00
jelveh 1df874c581 remove refresh_item_container since it's not used 2025-06-27 22:49:58 -07:00
jelveh aeac392a7c Remove mods and favicons 2025-06-27 22:46:34 -07:00
Nariman Jelveh 196f996435 Merge branch 'main' into feature/desktop-shortcut-link 2025-06-27 22:45:38 -07:00
XiaochenCui 0b7474340f dev: extension prefix update, doc helper & docs update 2025-06-27 16:29:16 -07:00
KernelDeimos 7f6b302636 fix: remaining issues with fake-chat/costly 2025-06-27 14:31:26 -04:00
KernelDeimos f46d47d2a8 fix: cost testing model 2025-06-27 14:19:03 -04:00
jelveh 1ad113bbbf Update package-lock.json 2025-06-26 22:59:02 -07:00
Nariman Jelveh c7f4df63da Merge pull request #1314 from bilalkhantanoli/nn-translation-completion
fix(i18n): Complete Norwegian Nynorsk translation
2025-06-26 22:45:56 -07:00
KernelDeimos ae4dc23c37 fix: incorrect pricing 2025-06-26 22:06:32 -04:00
KernelDeimos 60a9be12ba fix: update package-lock.json 2025-06-25 15:00:07 -04:00
Bilal 807d7bd698 fix: complete Norwegian Nynorsk translation 2025-06-22 12:25:22 +05:00
jelveh 7896c59ef8 Remove terminal and draw from Launch menu 2025-06-21 22:42:48 -07:00
KernelDeimos 2d9526ba40 fix: install 2025-06-21 22:00:26 -04:00
KernelDeimos 43122801bf fix: various AI fixes
- fix mis-handling of aliased models and DRY so it doesn't happen again
- fix where we try to get model details for a pseudo model
  (usage-limited)
- fix metering with non-streaming mistral requests
2025-06-21 21:39:52 -04:00
KernelDeimos ddfd11713e tweak: change default model to gpt-4.1-nano 2025-06-21 20:28:53 -04:00
KernelDeimos 52f79061ce dev: add cost-calculated event for AI chat 2025-06-21 20:21:49 -04:00
KernelDeimos d9a6a03740 tweak: update pricing for 4o-mini 2025-06-21 20:21:32 -04:00
jelveh c3d2ce5d0e Add max_tokens to all models' metadata 2025-06-21 16:13:50 -07:00
KernelDeimos ebefca2c24 dev: add some max_tokens values 2025-06-21 18:02:00 -04:00
jelveh 6f6bb5a484 Remove Convert, IPGeo, NewsData, Firebase, Mail, Analytics, and Weather 2025-06-21 14:57:58 -07:00
KernelDeimos 4b5955b459 fix: add missing unit conversion step 2025-06-21 17:12:55 -04:00
KernelDeimos 62d72676af dev: enable custom text and fix max_tokens for fake-chat 2025-06-21 05:13:59 -04:00
KernelDeimos 2e90e8dc96 fix: streaming in FakeChatService 2025-06-21 03:21:54 -04:00
KernelDeimos 9235ddd6f3 dev: change message in ai service 2025-06-21 02:19:04 -04:00
KernelDeimos 1a85eeca5c dev: add value to prompt validation event 2025-06-21 02:03:11 -04:00
KernelDeimos 3f5de6d493 fix: use correct path for openrouter max tokens 2025-06-21 01:43:54 -04:00
KernelDeimos 26fb2e704f dev: apparently LLM APIs can't do Math.min 2025-06-21 00:28:38 -04:00
KernelDeimos 52b778a2e7 dev: improve use metering 2025-06-20 23:04:46 -04:00
KernelDeimos a7d1bf0e99 fix: remove dormant condition operand from signup.js 2025-06-20 19:41:06 -04:00
Nariman Jelveh 0accd41e13 Merge pull request #1311 from Rohanpawar9921/docs/rohan-readme-hindi
docs(i18n): update Hindi translation of README
2025-06-19 21:05:56 -07:00
jelveh d3d7e38c3e Remove the Email, Exec, and Convert modules in Puter.js 2025-06-19 20:50:45 -07:00
KernelDeimos db960d585a fix: add support for new Endpoint usage 2025-06-19 23:46:23 -04:00
KernelDeimos 5903f1fb31 fix: incorrect call to APIError from configurable_auth 2025-06-19 23:44:45 -04:00
KernelDeimos 5b7b524080 fix: add one I missed previous commit 2025-06-19 23:37:03 -04:00
KernelDeimos e5e88073c1 dev: add some useapi exports to CoreModule 2025-06-19 23:27:57 -04:00
Rohanpawer9921 f97a23a181 docs(i18n): update Hindi translation of README 2025-06-18 10:29:24 +05:30
KernelDeimos 3918917f31 dev: add appdata_app property to stat response 2025-06-18 00:22:15 -04:00
KernelDeimos 659879812d fix: necessary updates happen for move save too 2025-06-18 00:21:23 -04:00
KernelDeimos 8b56d1131c clean: move handle_url_save for readability 2025-06-17 22:16:00 -04:00
KernelDeimos 771eb37c7f dev: add save file by moving from appdata 2025-06-17 22:14:40 -04:00
KernelDeimos 0eb436678b move: handle_same_name_exists to helpers.js 2025-06-17 21:11:44 -04:00
KernelDeimos a4b412dc46 refactor: IPC/showSaveFilePicker 2025-06-17 21:03:32 -04:00
KernelDeimos a8164c1108 doc: document event buses and http (unfinished) 2025-06-17 13:13:02 -04:00
KernelDeimos 352ec6d883 dev: allow apps to sign files in their AppData 2025-06-17 13:12:25 -04:00
KernelDeimos 6315020cc0 dev: regex rules for undefined origin allowed
This commit allows using a regex to specify a route that's allowed to
not have an "Origin" header specified. This is necessary for parametized
URLs.
2025-06-16 18:16:18 -04:00
KernelDeimos 24cae79291 dev: expose LLOWrite to Puter extensions 2025-06-16 17:26:03 -04:00
KernelDeimos 152a5578fc fix: issue using ll_write outside of hl_write
Using LLOWrite outside of HLWrite, which is useful inside a Puter
extension when a simple write operation is being invoked by the backend,
required passing a thumbnail. However, sometimes this is not necessary.
This commit makes it possible run an LLOWrite operation without passing
a thumbnail stream.
2025-06-16 17:23:40 -04:00
KernelDeimos 914b077e1a doc: document config and logging in services 2025-06-11 18:03:51 -04:00
Nariman Jelveh 1652fb496c Delete experiments directory 2025-06-10 15:13:12 -07:00
Nariman Jelveh 2bebc4ba9f Delete badges directory 2025-06-10 15:11:16 -07:00
Nariman Jelveh d34fc897fa Update README.md 2025-06-10 15:10:47 -07:00
Nariman Jelveh 8d6ed96fc7 Delete src/git directory 2025-06-10 15:08:44 -07:00
Nariman Jelveh af84f60f7b Delete awesome directory 2025-06-10 15:07:17 -07:00
Nariman Jelveh 5ed4a28495 Delete addlicense.yml 2025-06-10 15:06:08 -07:00
Nariman Jelveh 4ade2e3fb3 Delete index.html 2025-06-10 14:58:39 -07:00
KernelDeimos 5c2155491d dev: updates for extension-hosted apps
The following changes make it easier to host web apps from inside a
Puter extension:
- expose express module to prevent mixing versoins
- allow registration of URLs exempt from origin requirement
2025-06-06 15:52:21 -04:00
KernelDeimos ca84ed34bf dev: meta driver with usages method 2025-06-05 19:14:04 -04:00
KernelDeimos 20ba064181 dev: log actor uid with created wisp tokens 2025-06-03 16:28:13 -04:00
ATAG bdbe773ff2 doc: add freebsd-specific instructions to first-run-issues.md
Fix the missing 'sharp' dependency on FreeBSD, since it doesn't have prebuilt binaries for this OS.
2025-06-03 15:19:56 -04:00
Krishna d885ea5772 fix: enable and fix date command tests
Closes #796
2025-06-03 15:04:01 -04:00
KernelDeimos a402528018 dev: add explicit error for undefined auth token 2025-06-03 14:52:01 -04:00
jelveh 5bfd10f845 Enable fullpage_on_loading by default for new apps 2025-06-01 22:10:21 -07:00
KernelDeimos e9b249c74f doc: clarify formatting changes in PRs 2025-05-30 17:28:05 -04:00
Tanmay Patwary feb45d192f doc: clarify CostService usage and improve metered services discoverability 2025-05-28 02:52:49 -04:00
Nariman Jelveh a39af1884e Merge pull request #1286 from ProgrammerIn-wonderland/main 2025-05-27 13:37:39 -07:00
ProgrammerIn-wonderland 99cf2cad67 remove log 2025-05-27 16:36:23 -04:00
ProgrammerIn-wonderland 54ec707f7f support for request bodies 2025-05-27 16:34:58 -04:00
jelveh 345c628262 add the code option to puter.print 2025-05-26 15:38:38 -07:00
Nariman Jelveh e227b92f36 Merge pull request #1284 from ProgrammerIn-wonderland/main
Networking: dont sent authentication header if puter.authToken is undefined
2025-05-26 15:06:52 -07:00
ProgrammerIn-wonderland d1a9bed107 Networking: dont sent authentication header if puter.authToken is undefined 2025-05-26 18:05:59 -04:00
Neal Shah bcbf852f5c tweak: make auth UI not required for now (#1283) 2025-05-26 17:36:28 -04:00
KernelDeimos 1024fe28c3 dev: update wisp service for guest tokens 2025-05-26 17:28:50 -04:00
Tanmay Patwary 7831d12d42 chore: sync extension events documentation with backend changes 2025-05-26 17:03:38 -04:00
KernelDeimos ccdb678937 fix: save_account lock timeout
There was a setTimeout here that was supposed to be replaced with the
timeout feature on LockService, but it looks like that never happened.
2025-05-26 13:31:03 -04:00
KernelDeimos 1a0718028b dev: migrate toolbar labels to i18n 2025-05-26 13:04:10 -04:00
KernelDeimos 9c78c0d3f7 dev: rename 'puter.log' to 'puter.logger' 2025-05-26 11:31:16 -04:00
jelveh 951bc0ea7a Only show Puter Dialog when needed 2025-05-23 19:50:47 -07:00
KernelDeimos dbdebec635 dev: disable preauth for now 2025-05-23 17:50:14 -04:00
KernelDeimos 340871295e dev: pre-auth 2025-05-23 17:33:24 -04:00
KernelDeimos 6363f6307c dev: make it possible to handle requests from extension 2025-05-23 17:00:15 -04:00
KernelDeimos fde1a11515 dev: add request.will-be-handled event 2025-05-23 16:23:46 -04:00
KernelDeimos ca3acf13c1 fix: wrong symbol in previous commit 2025-05-22 15:42:43 -04:00
KernelDeimos 2cd5b3cb49 fix: prevent health check from surpressing traces
Stack traces aren't logged when a health check failure occurs. This was
caused by interfacing with AlarmService directly instead of using the
error service.
2025-05-22 15:20:05 -04:00
jelveh 5a6b299e78 Update AI.js 2025-05-22 11:13:01 -07:00
jelveh d2cc550c96 add claude sonnet 4 and claude opus 4 2025-05-22 10:45:26 -07:00
jelveh 491cf506de Update index.js 2025-05-21 19:51:30 -07:00
jelveh b703b60977 omg this is getting out of hand 2025-05-21 19:40:50 -07:00
jelveh f765180c1b well, puter.log is taken so going to change puter.print instead 2025-05-21 19:21:52 -07:00
jelveh f6786b8895 introduce the puter.log() method 2025-05-21 18:50:15 -07:00
jelveh 7f699302a4 Trying out the XSS-safe approach for puter.print 2025-05-21 18:11:51 -07:00
Nariman Jelveh bd8d141879 Merge pull request #1273 from ProgrammerIn-wonderland/main
Housekeeping: Get rid of puter.http/puter.https
2025-05-20 18:56:03 -07:00
ProgrammerIn-wonderland 6af0cddfc6 Housekeeping: Get rid of puter.http/puter.https 2025-05-20 21:38:34 -04:00
Nariman Jelveh cfdf2b304e Merge pull request #1272 from ProgrammerIn-wonderland/main
fix TLS stream premature close issue
2025-05-20 18:29:35 -07:00
ProgrammerIn-wonderland 75f0e043ea fix TLS stream premature close issue 2025-05-20 21:26:44 -04:00
Nariman Jelveh aeac68750b Merge pull request #1271 from ProgrammerIn-wonderland/main
Add support for chunked encoding in puter.net.fetch
2025-05-20 18:23:56 -07:00
ProgrammerIn-wonderland 0d48389c40 code formatting 2025-05-20 21:04:34 -04:00
ProgrammerIn-wonderland 7a6df9a63f change todo 2025-05-20 21:03:28 -04:00
ProgrammerIn-wonderland af2df13619 add support for chunked encoding 2025-05-20 21:01:09 -04:00
Nariman Jelveh 17e50243f9 Merge pull request #1270 from ProgrammerIn-wonderland/main
fix accidental checking of requestHead when responseHead should be checked
2025-05-20 15:03:36 -07:00
ProgrammerIn-wonderland 2a16a2502b fix accidental checking of requestHead when responseHead should be checked 2025-05-20 18:01:57 -04:00
Nariman Jelveh 9b3aa2508d Merge pull request #1269 from ProgrammerIn-wonderland/main
Puter.net.fetch -- cors exempt wisp based fetch
2025-05-20 14:29:29 -07:00
ProgrammerIn-wonderland 95f1656780 initial puter.net.fetch implementation 2025-05-20 17:27:10 -04:00
ProgrammerIn-wonderland 9fdca11070 fix auth flow on subsequent loads 2025-05-20 16:40:38 -04:00
KernelDeimos 8d371b9e7b dev: remove default token limit from Openrouter 2025-05-19 18:52:05 -04:00
KernelDeimos 76b973cd41 dev: add additional debugging for stream AI errors 2025-05-19 17:24:47 -04:00
KernelDeimos 8a0619af26 dev: reduce visible log output by default
- introduce concern-based log categories
- ensure debug-level logs aren't shown without DEBUG env variable
- remove some unnecessary/outdated logs
- add concern fields to services and log instantiations
2025-05-19 16:41:42 -04:00
KernelDeimos cecc9f23dc fix: pass dedupe_name to mkshortcut via batch 2025-05-18 21:00:58 -04:00
jelveh 93645cd0ae remove redundant console.logs 2025-05-18 17:37:40 -07:00
KernelDeimos 1c19086592 fix: add necessary supporting code for funding update 2025-05-17 22:15:21 -04:00
jelveh ea405e5cb6 Update style.css 2025-05-17 15:47:50 -07:00
jelveh 84e190cb59 Revert broken code for deleting profile picture 2025-05-17 15:20:59 -07:00
jelveh d7b9f1e866 Remove the Flexer component from the Security tab in settings 2025-05-17 14:30:57 -07:00
jelveh b23d8b504d Remove Spinner.js 2025-05-17 14:17:56 -07:00
jelveh 4862bac495 Remove StringView.js 2025-05-17 14:10:34 -07:00
jelveh 7d88a8b959 Update UIWindowTaskManager.js 2025-05-17 14:02:24 -07:00
jelveh ab1cbb257c Remove the Table component 2025-05-17 13:50:14 -07:00
jelveh dc399d8774 Update style.css 2025-05-17 13:18:05 -07:00
jelveh a28cb11c34 Make the sidebar in settings fixed 2025-05-17 13:16:52 -07:00
jelveh 17a77f97a1 add correct i18n keys for the professional subscription tier 2025-05-17 13:00:54 -07:00
jelveh a1b96b7130 Allow users to open Settings and specific tabs from a URL 2025-05-17 12:30:27 -07:00
KernelDeimos 7823fdfab0 dev: add lazy render option for UIElement 2025-05-17 15:23:14 -04:00
Nariman Jelveh da66b03163 Merge pull request #1268 from ProgrammerIn-wonderland/main
change initialization order to make wisp socket on first use of network
2025-05-16 14:19:51 -07:00
ProgrammerIn-wonderland f944d76261 change initialization order to make wisp socket on first use of networking 2025-05-16 17:18:28 -04:00
Nariman Jelveh 7f1f98ae70 Merge pull request #1267 from ProgrammerIn-wonderland/main
Add reauthentication for unauthenticated web clients when Socket api is called
2025-05-16 11:18:28 -07:00
ProgrammerIn-wonderland 73e6830b1f Add reauthentication for unauthenticated web clients 2025-05-16 13:45:55 -04:00
jelveh 39a59970bb remove startup chime 2025-05-15 23:26:10 -07:00
jelveh f942c13be0 Revert UIItem refactor and fix the position of Create Shortcut in the context menu 2025-05-15 23:21:11 -07:00
jelveh 0012fd3970 Remove unused imports all over the codebase 2025-05-15 22:34:14 -07:00
jelveh 8dcf75ba54 Update ui_item.js 2025-05-15 17:47:05 -07:00
KernelDeimos 5f14dc720b fix: build error 2025-05-15 20:44:54 -04:00
jelveh 9c14a21fdd Use i18n for "Share With..." 2025-05-15 17:12:13 -07:00
KernelDeimos 880760c602 ux: use financial units instead of SI for credits
Instead of K, M, G, T, P it's K, M, B, T, Q.
2025-05-15 14:05:35 -04:00
KernelDeimos 3290440f4b dev: document auth and permissions 2025-05-15 14:05:35 -04:00
jelveh 0e0bfd6d7c Update PuterDialog.js 2025-05-13 17:34:11 -07:00
KernelDeimos 3dbe89f3dc dev: migrate "Create Shortcut" to DRY multi/single 2025-05-12 17:34:04 -04:00
KernelDeimos aa049b2c5a dev: factor out menu items functions in UIItem
The large if...else block for single-item vs multi-item selection
context menu items makes it difficult to extract common behaviors
between the two. For example, the "create shortcut" menu item could be
added by the same code snippet in both cases, and that snippet might
have conditional logic for the number of items (with 1 as a special
case).

The reason to move branching logic to the code snippets that handle
individual menu items is because the previous change to fix shortcuts in
shared directories revealed cross-cutting concerns in branching logic.
Since both single-item and multi-item "create shortcut" options both
have branching to handle the shared directory case, they are now more
similar than different.
2025-05-12 16:39:21 -04:00
KernelDeimos 73ab4baa60 dev: SI suffix for usage meter 2025-05-12 15:18:02 -04:00
KernelDeimos 72a45500d5 fix: cannot create shortcut for shared file
Closes #1263
2025-05-12 13:25:38 -04:00
KernelDeimos 518449cfdd fix: share issue 2025-05-09 17:04:00 -04:00
KernelDeimos 9bf48e7289 fix: fallback behavior related to fake-chat service
Fallbacks from or to the fake-chat service should not be allowed.
Fallbacks to the "costly" model from fake-chat could result in
unintended charges and fallbacks to real models from fake-chat could
result in service abuse.
2025-05-05 16:10:52 -04:00
KernelDeimos 34787bbb0c fix: gone 2025-05-03 21:27:21 -04:00
KernelDeimos 77f3bf2177 fix: ui bug in settings window 2025-05-02 16:01:26 -04:00
KernelDeimos 75aebd6d35 fix: sqlite syntax inconsistency
The SQL statement for creating a group uses syntax that only works under
sqlite. This was caused by introducing anomaly detection when a user
creates a large number of groups in quick succession.
2025-05-02 14:34:46 -04:00
KernelDeimos 4647e2d9c0 dev: add experimental firebase authentication
This adds an experimental custom token authentication endpoint to Puter.
This is disabled unless the firebase-auth service is explicitly
configured, and is not yet ready for production use.
2025-05-01 17:14:25 -04:00
Nivedita Rani 284b89a5fd fix: iframe overlap issue (PR 1250)
* Removed css property overflow: hidden at the parent container which was interfering with the layout calculations and was forcefully clipping child elements

* Replace css property overflow: hidden  with contain: paint to fix stacking without masking border-radius

Fixes #1233
2025-05-01 13:55:17 -04:00
KernelDeimos ea241540b9 dev: add WeatherService
- adds weather service
- updates IdentificationService to add ip_user property
2025-04-29 13:43:53 -04:00
KernelDeimos 29dbf3a517 dev: URLs to files in public directories
Already existing was the functionality to go to puter.local/@username to
access the Public folder belonging to "username". This commit adds the
ability for relative paths such as puter.local/@username/document.md to
access /username/Public/document.md in the suggested app for handling
".md" files.
2025-04-28 17:40:02 -04:00
KernelDeimos 3856ddcc8f dev: add default parameters for driver interfaces 2025-04-25 16:03:22 -04:00
KernelDeimos c5c17bae3a dev: add cost calculation for NewsDataService 2025-04-25 14:14:58 -04:00
KernelDeimos 78ae6f6bf2 dev: begin implementing driver for newsdata.io 2025-04-24 17:04:30 -04:00
KernelDeimos 89b8c8de1d fix: add missing null check 2025-04-24 16:09:32 -04:00
KernelDeimos b7efa6f894 fix: handle problematic null or undefined case
This is the product of a couple hours of debugging. We can now remove
the uuid entry from the cache for a deleted user without the strange
lockup behavior that was being observed previously. However, it is still
explained exactly how this happened; while this commit addresses the
cause it does not represent an actual understanding of the issue.

What is known is the following:
- /delete-own-user can trigger a complete lockup
- this happens when invalidate_cached_user is called
- kv.del('users:uuid:<uuid of user>') triggers the issue
- ... because get_user returns null and
- configurable_auth middleware accepts the null value
- configurable_auth middleware DOES call next()
- it is unknown why a lockup occurs after this
2025-04-24 14:41:05 -04:00
KernelDeimos 210ecaba8f tmp: comment out user uuid del 2025-04-23 22:33:25 -04:00
KernelDeimos 2b0c8fcaf0 dev: expose Context and ready event to extensions 2025-04-23 15:51:28 -04:00
KernelDeimos abf5852b93 dev: better log support for extensions 2025-04-23 15:28:15 -04:00
KernelDeimos a3ae60861c dev: add injected logger support
This allows a logger to be specified in the execution context. If
LogService sees this, it will perform its usual logging but also call
the injected logger.
2025-04-23 14:49:18 -04:00
KernelDeimos 017328420d dev: add support for an "any" interface
Driver interfaces don't require specifying the structure of the return
value when it's a JSON object, but parameters require specifying what
parameters can be provided. This commit adds a special wildcard
parameter for interface definitions. When the wildcard parameter is set,
the entire input object is considered as if it were the value of one
parameter.
2025-04-22 16:29:55 -04:00
KernelDeimos 790e3bdffc dev: puter.call
Instead of puter.drivers.call, make it puter.call. This is accomplished
by allowing puter.js modules to mutate the `puter` object on
initialization. Support for an optional `_init` method, similar to
backend services, is added to Puter modules to help with this.
2025-04-22 15:21:36 -04:00
KernelDeimos 9935f5a0be dev: simplify calling drivers with matching names
This commit modifies puter.js to allow calling an
interface+service+method with matching names without redundantly
specifying. The 'ip-geo' service is also renamed to ipgeo to match its
method name and allow a simple:

puter.drivers.call('ipgeo', { ip: '1.2.3.4' })
2025-04-22 14:01:01 -04:00
KernelDeimos 1764b99c22 dev: add log messages for cost records 2025-04-22 13:14:41 -04:00
KernelDeimos 7e7e2897b2 dev: improve actor logs
This commit adds the concept of a toLogFields method on objects which
will determine how they're turned into log fields in LogService. This
method is now implemented on actor to prevent errors when the object is
passed to log functions without being stringified first.
2025-04-22 12:52:09 -04:00
KernelDeimos b80052f177 dev: add cost service integration to IPGeoService 2025-04-22 12:07:13 -04:00
KernelDeimos 7945586050 dev: ip geolocation driver (initial development) 2025-04-21 17:53:39 -04:00
KernelDeimos 8ff2e93e66 tweak: add limit to deleteUser file select
I wasn't able to reprod any memory leak from a user having a large
number of files locally, but it's showing up in logs and maybe could add
up with lots of temp users getting auto-removed. It's worth a shot.
2025-04-19 15:45:33 -04:00
KernelDeimos f7b302b024 fix: potential log error 2025-04-19 14:27:14 -04:00
KernelDeimos c254b39afe fix: consistent email check in confirm-email 2025-04-19 11:07:13 -04:00
KernelDeimos c959ef3b83 dev: add actor to log context when available 2025-04-18 16:55:11 -04:00
KernelDeimos fdfa4cbc7c dev: log memory info periodically 2025-04-18 16:26:52 -04:00
KernelDeimos cc72508b75 dev: remove default system prompt 2025-04-17 15:35:35 -04:00
jelveh 2cdcc5ffcd Add o3 and o4-mini models 2025-04-16 11:06:57 -07:00
jelveh b17dc58ca6 remove unused imported modules 2025-04-15 23:44:11 -07:00
jelveh 19574e5bb1 Update OpenAICompletionService.js 2025-04-15 23:33:03 -07:00
jelveh c732263958 Update AI.js 2025-04-15 23:24:53 -07:00
jelveh cab933f1c2 Update AI.js 2025-04-14 12:56:32 -07:00
jelveh 68860d8876 Update AI.js 2025-04-14 12:52:54 -07:00
jelveh 42f0ac5785 Use OpenAI for `o1-mini1 2025-04-14 12:44:58 -07:00
jelveh 90d16c35e2 Add missing openai models 2025-04-14 12:36:07 -07:00
jelveh 16b8adc4ed add new GPT models 2025-04-14 12:26:04 -07:00
jelveh 2d7ca7f2e1 better error message for invalid emails 2025-04-13 18:24:06 -07:00
jelveh 398b1578a5 Update signup.js 2025-04-13 17:56:56 -07:00
jelveh 2949e16be2 Update signup.js 2025-04-13 17:38:53 -07:00
jelveh c9c441210b Update signup.js 2025-04-13 17:08:58 -07:00
jelveh 4ea7754133 Update initgui.js 2025-04-13 16:52:23 -07:00
jelveh f14b0d1ac9 this didn't work, reverting 2025-04-13 16:39:31 -07:00
jelveh 1b83966c26 Update signup.js 2025-04-13 16:24:19 -07:00
KernelDeimos 107adce68b dev: disallow "auto" model
This model seems to cause us problems
2025-04-12 16:53:53 -04:00
jelveh daa95d8c39 Update AI.js 2025-04-10 20:17:35 -07:00
KernelDeimos dc2e406cc6 fix: use event service 2025-04-10 15:45:46 -04:00
KernelDeimos c7c7f78255 Revert "tmp: temporary timeout to test a theory"
This reverts commit d1e4ed7f63.
2025-04-10 01:40:21 -04:00
KernelDeimos d1e4ed7f63 tmp: temporary timeout to test a theory 2025-04-10 01:32:53 -04:00
KernelDeimos 3f0e990398 dev: polling in usage tab 2025-04-09 14:34:32 -04:00
KernelDeimos f0c06931bd fix: check funding with no args 2025-04-09 14:34:32 -04:00
KernelDeimos 2c9bc8f9e0 dev: instant update for usage in settings 2025-04-09 14:34:32 -04:00
KernelDeimos 0176a1f629 dev: update usages tab 2025-04-09 14:34:32 -04:00
KernelDeimos b5848012a9 delete: monthly usage limiting 2025-04-09 14:34:32 -04:00
KernelDeimos fc677ef61f dev: migrate judge0 and convertapi to cost service 2025-04-09 14:34:32 -04:00
KernelDeimos b57b907ba6 dev: migrate textract to use cost service 2025-04-09 14:34:32 -04:00
KernelDeimos 8d175bd3fa doc: test values for PermissiveCreditService 2025-04-09 14:34:32 -04:00
KernelDeimos c9d4eec018 dev: migrate polly to use cost service 2025-04-09 14:34:32 -04:00
KernelDeimos 82a4ab0884 dev: migrate image gen service to use cost service 2025-04-09 14:34:32 -04:00
KernelDeimos 14304143af dev: migrate image generation to use cost service 2025-04-09 14:34:32 -04:00
KernelDeimos b9b9c95f84 dev: minimum cost option 2025-04-09 14:34:32 -04:00
KernelDeimos 0201b93013 fix: redundant report-usage call in FakeChatService 2025-04-09 14:34:32 -04:00
KernelDeimos d0edb2c1f3 fix: async handling for events
There were issues with async handling in events which can make it
difficult to use event handlers to mutate values provided by an emitter.

This is not an optimal solution: this will await event listeners in
sequence. Ideally, event listeners should be awaited concurrently.
2025-04-09 14:34:32 -04:00
KernelDeimos 1f7073ef76 dev: add services property to extensions
A small change that adds ".services" to the "extension" global in an
extension, so extensions can more easily talk to other services.
2025-04-09 14:34:32 -04:00
KernelDeimos 21bd427cef refactor: generalize handling of costly services
Usage/cost tracking per user was over-fitted to LLM/AI services. This
commit adds CostService and updates AIChatService to use that instead of
updating the `ai_usage` table. The `ai_usage` table is now considered
deprecated.

A service called PermissiveCreditService is enabled by default in
SelfHostedModule. This is so users who host their own Puter instances
don't have to worry about usage limits, since they're providing their
own keys anyway.
2025-04-09 14:34:32 -04:00
KernelDeimos 0347a38136 fix: handle all temp user errors by reloading 2025-04-09 13:27:30 -04:00
KernelDeimos c8d52b3203 style: captcha refresh button 2025-04-08 16:54:36 -04:00
KernelDeimos d0e06e83c0 dev: add ip to captcha middleware event 2025-04-08 16:54:36 -04:00
jelveh 592acbcae6 remove "anthropic/" from model name 2025-04-08 12:34:23 -07:00
KernelDeimos 27fd7b3670 fix: broken model parameter 2025-04-08 13:27:56 -04:00
Nariman Jelveh fd910f36cf Merge pull request #1169 from shushannap/FAtranslation
tweak: reorder and fix Farsi translation of i18n keys
2025-04-08 08:41:16 -07:00
KernelDeimos 95ddfe3909 fix: error handling in ThreadService 2025-04-07 19:02:52 -04:00
KernelDeimos fc11eba070 fix: puter.js threads error handling 2025-04-07 18:43:21 -04:00
KernelDeimos 3e98d13f6b doc: document driver endpoint 2025-04-07 14:37:45 -04:00
KernelDeimos 9a12db2066 fix: .startsWith on undefined 2025-04-04 17:58:06 -04:00
jelveh 4fb772796f Update AI.js 2025-04-04 14:43:53 -07:00
EvaNtziou dad72c5bd7 feat: button to remove profile image #1245 (#1246)
* Restored and updated UITabAccount.js, style.css
* Update UITabAccount.js

Closes: 1245
2025-04-04 16:00:53 -04:00
jelveh 80060e863d Use openrouter for llama models 2025-04-03 17:23:26 -07:00
Nariman Jelveh ddb04431cc Update README.md 2025-04-02 18:48:22 -07:00
jelveh 590973f50d Update AI.js 2025-04-02 12:04:38 -07:00
KernelDeimos fb01bb474a fix: edge case during email change
Previous logic was:
- on email change, update temporary value
- send email to confirm new email
- temporary value is moved to real email

This doesn't work when an account has not yet confirmed their email
after signup (i.e. user's email_confirmed is still 0). Well, it actually
does work, but the user is only able to confirm the change to their
email and not set their account as having a confirmed email.

New logic has a branch for this case; IFF email_confirmed=0:
- change account confirm code
- send new account confirm email
2025-04-01 12:41:49 -04:00
KernelDeimos 7a3365a25c refactor: begin migrating utility code
I'm calling this approach a "re-core"; see src/backend-core-0/README.md
for more information about this.
2025-03-31 22:09:29 -04:00
KernelDeimos f2305ff289 fix: how did this get here 2025-03-31 20:22:13 -04:00
KernelDeimos e5f23e815d dev: disable textex by default
it's too verbose now
2025-03-31 20:07:19 -04:00
KernelDeimos f80105af6d fix: sure, but how 'bout a logo that isn't broken
A logo addition from another PR snuck in. This definitely makes it
consistent with signup, but this logo broken! This commit makes it be
not broken anymore.
2025-03-31 19:33:55 -04:00
Eric Dubé b7defab2d2 refactor: Migrate interfaces.js to new registration mechanism (#1239)
* refactor: migrate interfaces.js to new registration mechanism

- Created EntityStoreInterfaceService for crud-q interface\n- Created AnalyticsInterfaceService for puter-analytics interface\n- Added InterfacesModule to load these services\n- Removed interfaces.js\n\nCloses #1131

ai: true

* chore: remove interfaces.js file

ai: true

* fix: DRY CRUD interfaces

This comment is flagged as AI-generated, but Claude rate-limited before
it could actually make the commit so this commit was made by hand. Well,
while I'm writing this commit message I may as well mention that Claud's
rate limits are relentless and it has become impossible to use Claude
for some purposes as a result.

ai: true

* refactor: replace interfaces module with separate Module.js files for entitystore and analytics

- Removed interfaces module\n- Added EntityStoreModule.js to entitystore module\n- Added AnalyticsModule.js to analytics module\n- Updated main index.js to use the new modules directly\n\nai: true

ai: true

* fix: modules exported and registered incorrectly

* feat: add KVStoreModule for puter-kvstore interface

- Created KVStoreModule.js\n- Created KVStoreInterfaceService.js to register the puter-kvstore interface\n- Updated exports.js to include the new module\n\nai: true

* fix: remove index.js from kvstore module

- Removed unnecessary index.js file from kvstore module\n\nai: true

* fix: remove index.js files from analytics and entitystore modules

- Removed unnecessary index.js files from analytics and entitystore modules\n\nai: true

* fix: cleanup mycoder mistakes again

...because it actually threw out my previous commit where I already did
this.
2025-03-31 19:32:38 -04:00
Krista Vlastou 647ae35c84 Added a confirm password field and a show password option 2025-03-31 16:30:55 -04:00
KernelDeimos 6451f1b4e9 fix: error handling error in UIWindowSignup
Caused-By: ad4b3e7aeb
2025-03-31 13:22:31 -04:00
jelveh da2a8de307 Update UITabUsage.js 2025-03-29 16:51:24 -07:00
jelveh 1d1b4f81b5 clean up html and css 2025-03-29 12:31:23 -07:00
KernelDeimos a276a82e44 fix: put guard around startup chime 2025-03-29 14:57:45 -04:00
KernelDeimos 7c1fb4c3bf dev: improve puter.js convert interface 2025-03-28 22:39:28 -04:00
Jonathan Mahrt GuyouandEric Dubé ad4b3e7aeb feat: captcha
* Added Revis distributed cash to enhance our Captcha Verification system so that we prevent our system from replay attacks

* Fix: There was an error with the implementation of Redis, so I reverted to our previous version that uses in memory storage

* Integrated the captcha verification system into our sign in Form. The captcha verification system now works on both login and sign int

* Remove test files from captcha module

* Update src/backend/src/modules/captcha/middleware/captcha-middleware.js

Co-authored-by: Eric Dubé <[email protected]>

* Update src/backend/src/modules/captcha/middleware/captcha-middleware.js

Co-authored-by: Eric Dubé <[email protected]>

* Now the captcha can be requested on condition, this llaows extenstions to control wether a captcha should be required,
I fixed the code in CaptchaModule to use config
and got rid of the lines that made captcha middleware available since it wasn't used anywhre

* I split the middleware into two distinct parts, so that the frontend can now determine captach requirements. PuterHomePageService can set GUI parameters for captcha requirements. The /whoarewe endpoint provides captcha requirement information and the extensuo system integration is maintained

* Fix security issues with password handling in URL query parameters

* Made sure that the enter key, submits the login request instead of refreshing the captcha

* In development we can now disable the Captcha verification system by running it with CAPTCHA_ENABLED=false npm start

* Went back and modified checkCaptcha so that it checks at the start to check what CAPTCHA_ENABLED is equal to

* Refactor captcha system to use configuration values instead of environment variables

* Fix captcha verification and align with project standards

* Update src/backend/src/modules/captcha/README.md

Co-authored-by: Eric Dubé <[email protected]>

* fix: incorrect service name

* dev: use Endpoint for captcha endpoints

Use Endpoint class, which uses eggspress behind the scenes, which handles
async errors in handlers automatically.

* dev: add extension support and simplify captcha

- removed extra error handling
- removed dormant code
- no distinction between login and signup (for now)

* clean: remove local files

* fix: undefined edge case

---------

Co-authored-by: Eric Dubé <[email protected]>
2025-03-28 19:46:56 -04:00
rodrick-mpofu bf16e20447 fix: remove duplicate icons and hide .weblink extension 2025-03-28 05:17:02 -04:00
KernelDeimos f73958ee8c chore: update package-lock.json 2025-03-28 05:01:49 -04:00
Eric Dubé 45c072ff93 feat: add public endpoint for models list (#1228)
* feat: add public endpoint for models list

- Created ChatAPIService for public endpoints\n- Added /chat/models and /chat/models/details endpoints\n- Registered service in CoreModule\n- Added tests for the new service\n\nCloses #1227

ai: true

* Update src/backend/src/services/ChatAPIService.js
2025-03-27 17:12:09 -04:00
Ntwari Bruce 39048a9e2e dev: ai command tool use / function calling (#1194)
* Enhanced ai command to perfom other commands

* Enhance AI Command in Puter's shell

* Enahanced ai command to use tooling/function calling

* Fixed circular dependency and added list function to Builtincommand

* Fixed circular dependency and system prompt
2025-03-27 14:31:24 -04:00
KernelDeimos 9180261472 doc: add style doc for backend 2025-03-26 18:07:12 -04:00
Krista Vlastou 4b7e09e157 fix: npm install error on Windows (spawn EINVAL) (#1214) 2025-03-26 14:58:46 -04:00
rodrick-mpofu 94853d33bf Implement link shortcut feature (refs #682) 2025-03-25 02:24:20 -04:00
KernelDeimos 3d3af13979 feat: add startup chime feature
Added ability to play Puter chime sound at startup after login
with a toggle in personalization settings to enable/disable it.

ai: true
2025-03-24 23:19:36 -04:00
KernelDeimos bcd8d0cc82 tweak: clarify Nodemailer section in email testing documentation
- Clarified that the Nodemailer example is for testing MailHog setup\n- Added information about how Puter uses Nodemailer\n- Added references to the EmailService class

ai: true
2025-03-24 21:55:34 -04:00
KernelDeimos 71fd94131e tweak: improve email testing documentation formatting and flow
- Reorganized sections for better readability\n- Added clearer headings and instructions\n- Improved troubleshooting section\n- Enhanced overall document structure

ai: true
2025-03-24 21:50:36 -04:00
gautamthegozi 94d148430a doc: Documentation for Email Testing (#1204)
* Documentation for Email Testing

* Documentation fix

* Fix
2025-03-24 21:48:36 -04:00
KernelDeimos 7bd0c8e3f2 doc: add documentation for robots 2025-03-24 17:58:47 -04:00
Eric Dubé c683b812bc doc: Improve PuterAI module documentation structure (#1216)
* docs: improve PuterAI module documentation structure

- Update docmeta.md to describe top-level doc structure\n- Create README.md for PuterAI module documentation\n- Move requests.md content to api_examples.md\n- Add ai_usage_testing.md in contributors directory\n\nCloses #1215\n\nai: true

* docs: remove original requests.md after content migration

Content has been migrated to api_examples.md with improved organization and structure.\n\nai: true
2025-03-24 17:52:00 -04:00
KernelDeimos 6a3b20f0a8 fix: clarify variable names in puter.ai.chat method
- Renamed 'options' to 'requestParams' to clearly indicate parameters sent to the backend driver\n- Renamed 'settings' to 'userParams' to clearly indicate parameters provided by the user\n- Updated comments to be more descriptive about the purpose of each variable\n\nFixes #1212\n\nai: true
2025-03-24 16:17:58 -04:00
KernelDeimos 64d1b6e663 dev: allow specifying chat driver in puter.js 2025-03-24 15:58:32 -04:00
KernelDeimos 617fb49178 fix: allow fake-chat to report usage for costly model
Modified the event handler in AIChatService to only skip usage reporting for fake-chat when it's not using the costly model, allowing the costly model to properly report its usage and costs.

ai: true
2025-03-24 15:54:40 -04:00
KernelDeimos 7a2851d2cc fix: add _init method to register FakeChatService as a provider
Added _init method to FakeChatService to register itself as a provider with AIChatService, ensuring that the service and its models are properly recognized by the system.

ai: true
2025-03-24 15:54:40 -04:00
KernelDeimos 42c6f92048 feat: add costly model to FakeChatService
Added a new 'costly' model to FakeChatService that simulates incurring costs similar to real AI services. This model can be used for testing cost tracking without incurring actual external API costs.

ai: true
2025-03-24 15:54:40 -04:00
Eric Dubé 67a898ea33 fix: update check_usage_ to only consider past month usage (#1209)
This change modifies the SQL query in check_usage_ to only consider AI usage from the past month when checking against limits, rather than all historical usage.

ai: true
2025-03-24 13:40:01 -04:00
Eric Dubé 1266ef2179 fix(ux): Make it easier to add file extensions to an app in bulk (#1205)
* Add support for pasting multiple file extensions at once in Dev Center

* Fix bulk file extension paste functionality in Dev Center

* fix: add try-catch around tippy

* Fix issues with bulk file extension pasting and add comma key support

* Fix issue with duplicate red tags appearing temporarily

* Implement robust bulk file extension paste functionality in Dev Center

* Fix security issue with JSON.stringify to properly escape < characters
2025-03-23 23:00:17 -04:00
hisham-maarraoui b0efff7a4f feat: show/hide desktop icons option in context menu
* feat: hide icons/show icons feature added to the right-click/secondary click menu on the desktop

* Fix: Changes made to the hide/show desktop icons feature after receiving feedback in the first pull request

* CSS rule added to static CSS file instead of being implemented dynamically
2025-03-21 16:23:17 -04:00
kira-offgrid 868ef4e5a4 fix: cleanup example so bots don't flag it 2025-03-21 13:23:21 -04:00
Anuja Mishra 50817f601e dev: Standardized OpenAI config format and updated documentation issue #1180 (#1195)
* Standardized OpenAI config format and updated documentation issue #1180

* Addressed review comments
2025-03-20 12:50:51 -04:00
KernelDeimos 33a7811e8f fix: alerts being completely broken
PR 1175 introduced a bug that wasn't caught where alert messages are not
properly assigned. Additionally, the default alert type was "warning"
which is a regression. This commit makes "info" the default alert type
and ensures options.message is the first candidate for the alert message
contents.
2025-03-19 12:37:18 -04:00
KernelDeimos 5c3f447b4c dev: expose config path to root context 2025-03-18 15:23:50 -04:00
Franciszek 9cb6b13bb6 i18n: Polish Translation fix (#1193)
* Update README.pl.md

Things I would change:

Line 1: System Operacyjny Internetu -> System Operacyjny Internet
Line 25: system operacyjny internetu -> internetowy system operacyjny
(Original Translation is more like Internet's OS, not Internet OS)

Line 36: Rozwój Lokalny ->  Instalacja Lokalna
(Original does not mean programming, but more like growth or evolution)

Line 97: Połącz się z opiekunami -> Skontaktuj się z opiekunami 
(Original has meaning, like connecting by cable, not contacting)

* Update README.pl.md

Changed:
Instalacja Lokalna -> Lokalne Środowisko Programistyczne.
2025-03-18 12:13:34 -04:00
Het Savani dab5e0a281 fix: file manager sidebar headings contrast (#1191) 2025-03-17 14:05:25 -04:00
KernelDeimos be59f57d68 dev: update puter.js imports to work in cli
This is a step towards getting puter.js to run in node instead of just
in the browser. In node, all the relative imports need to end with the
file extension, and the "type" option in package.json needs to match the
import mechanism used. It was also necessary to migrate
webpack.config.js to ESM syntax, which I would not have done if the
tooling didn't force me to.
2025-03-17 13:21:15 -04:00
ajaykrishnaswamyandEric Dubé 782e858b3c Update (and automate) events docs (#1164)
* documentation: new documentation for emit features

* Update events documentation and doc_helper.js script

* Update package.json

Co-authored-by: Eric Dubé <[email protected]>

* added manual_overrides.json.js file

* Update doc_helper.js to resolve paths relative to project root and update events documentation

* created a new events.md generated file, differences can be seen.

* added and populated events.md file. Can now compare new and old versions

---------

Co-authored-by: Eric Dubé <[email protected]>
2025-03-16 12:41:14 -04:00
KernelDeimos 947dca96a2 chore: remove eslint.config.js
ESLint cannot support our preferred code style for backend without
writing custom plugins. On frontend, we already decided ESLint wasn't a
good fit several months ago. This commit removes the eslint config to
avoid other developer's editors making unwanted whitespace changes.

In backend, we use spaces within control structure parens. This really
does make the code easier to read. In the future, maybe we'll write our
own linter.
2025-03-16 00:52:56 -04:00
Arunabh Sharmaandavijh 004e47a4a9 feat: add API to get a list of all available models (#1160)
* add API to get a list of all available models

* modified listModels() and listModelProviders() for readability.

* remove dead code

---------

Co-authored-by: avijh <[email protected]>
2025-03-16 00:31:33 -04:00
Andrew ShiromaandRishabh Shinde bf3d63a083 feat: create and export UsageLimitedChatService (#1182)
* feat: create and export UsageLimitedChatService for when user exceeds usage limit

* tweak: change comment on usage-limited-chat to better explain action

* fixed whitespace

* tweak: remove test-app from gitignore

* tweak: remove extra spacing in AIChatService usage-limited-chat comment

* tweak: fixed whitespace

* tweak: remove tabbed whitespace in AIChatService

* tweak: remove .qodo from gitignore

* tweak: remove extra enter in AIChatService

* Revert "tweak: remove .qodo from gitignore"

tweak: correct mistake on removing extra enter

This reverts commit e066e294fa.

* tweak: add space at fallback and remove whitespace tabs

* tweak: remove whitespace on brackets

* tweak: remove .qodo and test-app from gitignore

* tweak: add accidentally deleted enter back in

---------

Co-authored-by: Rishabh Shinde <[email protected]>
2025-03-15 19:48:09 -04:00
Arunabh Sharma 9626175d3a chore: upgrade supported node version to 23.9 (#1184)
* upgrade node version to 23.9

* update package-lock.json
2025-03-15 16:03:46 -04:00
Tanveer Brar 3cdbcd83b3 feat: GUI Permission Dialog (#1177)
* Added requestPermission endpoint in SDK, updated IPC handler HeyPuter/puter#1150

* - Updated UIWindowRequestPermission.js to accept multiple permission types
- Updated dialog message for permission window in UIWindowRequestPermission.js
- Updated parameters for call to UIWindowRequestPermission in IPC.js
- Added search_uid.js endpoint to allow GUI searches for fsentry by file UUID HeyPuter#1150

* Updated body and header for Permission Request Dialog HeyPuter#1150
- Replace app uid with app name for header in UIWindowRequestPermission.js
- Added path for file permission request body in UIWindowRequestPermission.js
- Removed previously added search_uid.js api implementation previously as it is replaced by simpler call in gui

* Updated permission description generation in UIWindowRequestPermission.js HeyPuter#1150

* Removed incorrect web handling in IPC.js HeyPuter#1150

* Formatting fixes
2025-03-14 19:37:28 -04:00
Aman PurohitandEric Dubé a278a6140b feat: UIAlert with dynamic icon types and default button configurations (#1175)
* UIAlert with dynamic icon types and default button configurations

* Update src/gui/src/UI/UIAlert.js

Co-authored-by: Eric Dubé <[email protected]>

* Update src/gui/src/UI/UIAlert.js

Co-authored-by: Eric Dubé <[email protected]>

* fix: improve error handling in UIAlert component and reseting package-lock

* fix: update UIAlert to use 'type' for alert type selection

* fix: update UIAlert to use 'type' for button configuration

---------

Co-authored-by: Eric Dubé <[email protected]>
2025-03-14 19:18:38 -04:00
Saish Pawar 505e7abda2 fix: reposition clock to right (#1181) 2025-03-14 18:38:57 -04:00
KernelDeimos 5c50eb1f8b fix(gui): logo placement with no clock using margin
Flex isn't being used in the top bar correctly, which is causing
unpredictable issues when people implement new elements on the top bar.
The best solution for this is to use proper flex values but right now
it's important to get the layout back to normal for production so I'm
implementing this sub-par fix where we always include a spacer element.
2025-03-14 03:09:08 -04:00
KernelDeimos 8edcf7575d fix(gui): clock padding moving other elements 2025-03-13 14:54:46 -04:00
Saish Pawar 672e2e70ad dev: moved current datetime to toolbar as a widget (#1172)
* move current datetime to toolbar as a widget

* revert interval to 1000ms
2025-03-13 13:28:57 -04:00
Gautam Kumar 11043e9ba1 doc: make default URL easier to notice
* Update README.md

Without clear instructions it wasted a few hours just for setting up.
Atleast no one will face issues with domain name in localhost now

* Making LocalHost website visible

* Making LocalHost website visible v2
2025-03-13 12:09:15 -04:00
Saish Pawar 6236d00ea2 fix: made protocol dynamic in the publishURL displayed on 'Publish As Website' dialogbox (#1170)
* change https to http on UIWindowPublishWebsite

* fix: made protocol string dynamic in the publish as website dialogbox
2025-03-12 15:58:11 -04:00
KernelDeimos 3e74f42c4d fix: thread delete events 2025-03-12 14:57:53 -04:00
KernelDeimos 41d5dbc0da fix: incorrect addition of https prefix for peers 2025-03-12 14:57:42 -04:00
KernelDeimos ad7b7b9513 fix: don't show register when user signup is disabled
closes #1087
2025-03-12 14:52:23 -04:00
Shushanna 433f15bacd tweak: reorder and fix Farsi translation of i18n keys 2025-03-11 21:20:05 -07:00
KernelDeimos 76bedf5f8f fix: thread subscription updates across regions 2025-03-10 16:29:00 -04:00
KernelDeimos 252647cea6 fix: issues with thread subscriptions
I really screwed that up on my first attempt. Puter apps don't trigger
the user-connected websocket event, which rendered thread subscriptions
in apps useless. Furthermore, the uuid of the thread that was subscribed
too wasn't present in the event, which is also pretty useless.
2025-03-09 20:28:22 -04:00
KernelDeimos 26591e4171 fix: wrong parameter count 2025-03-09 16:48:35 -04:00
KernelDeimos 249d883592 dev: add missing constructors to new puter.js methods
- Also add subscribe() to threads module so I don't lose it in a git
  stash
2025-03-09 16:48:35 -04:00
KernelDeimos daa3449f29 dev: begin adding developer app permissions 2025-03-09 16:48:35 -04:00
Andy Cordero 33c304879a fix(gui): color of the UI on dark mode (e.g. windows control, active sidebar) (#1161)
* update theme service to improve color handling and SVG icon styling

* enhance sidebar item colors for better visibility

* Fix the whitespace
2025-03-09 16:30:16 -04:00
Ntwari Bruce 7ed779bbf3 feat: enhanced ai command to perfom other commands (#1156)
* Enhanced ai command to perfom other commands

* Enhance AI Command in Puter's shell
2025-03-08 17:47:53 -05:00
KernelDeimos 8c497935cf dev: thread subscriptions 2025-03-07 17:27:29 -05:00
KernelDeimos 60cecedc87 dev: add user information to threads 2025-03-07 15:31:40 -05:00
KernelDeimos 03045e2737 fix: temperature and max_tokens (interface + OpenAI) 2025-03-07 15:24:22 -05:00
Braulio Fernandes 2a288e6cf0 add temp and max_tokens to Gemini Service 2025-03-07 13:57:25 -05:00
Braulio Fernandes 1e6e70b553 add temperature and max_tokens parameters to complete method 2025-03-07 13:57:25 -05:00
Braulio Fernandes 2e90919424 add max_tokens and temperature for completion with Claude 2025-03-07 13:57:25 -05:00
Braulio Fernandes 986dc9ea1f add temp and max_tokens to options request obj 2025-03-07 13:57:25 -05:00
KernelDeimos 59da18f2a3 dev: expose shell to ANSIShell coreutil commands 2025-03-07 11:41:49 -05:00
jelveh f897eee3e7 Update RecommendedAppsService.js 2025-03-07 08:25:33 -08:00
KernelDeimos 96199cbb54 fix: small fixes for threads 2025-03-05 16:55:09 -05:00
KernelDeimos 53c865c973 dev: add group management SDK 2025-03-05 15:24:52 -05:00
KernelDeimos 7aa3cb7312 dev: puter.js support for group management 2025-03-04 16:43:23 -05:00
KernelDeimos f0a6e493a1 dev: register puter.perms module 2025-03-04 14:39:32 -05:00
KernelDeimos 1f05df68eb dev: add threads module for puter.js 2025-03-04 14:38:30 -05:00
KernelDeimos 01ba6168d9 dev: make thread endpoints more conventional 2025-03-04 14:38:30 -05:00
KernelDeimos 9f3ce50994 dev: add read and list endpoints 2025-03-04 14:38:30 -05:00
KernelDeimos fdf10ef549 dev: add threads delete endpoint 2025-03-04 14:38:30 -05:00
KernelDeimos 90d9b41ec3 dev: add threads API with create and edit 2025-03-04 14:38:30 -05:00
KernelDeimos 02ddfcc567 dev: add puter.perms module to puter.js 2025-03-04 14:37:41 -05:00
KernelDeimos 3276faa5f0 fix: permission request 500 errors
As far as I remember, PermissionService was not using APIError because
it was considered to be only for errors from API endpoints and not
internal calls. However, this never made very much sense: APIError is
really more like "error that Puter's backend actually knows how to
handle" at this point; everything should be APIError and APIError should
probably eventually be renamed.
2025-03-04 13:56:51 -05:00
KernelDeimos 1e86039cf5 dev: add PUT, DELETE to eggspress 2025-03-04 12:58:55 -05:00
Eric Dubé eca5da9c1f Update issue templates 2025-03-03 14:50:06 -05:00
KernelDeimos cfa5c7e715 fix: puter subdomain error response
We were sending a JSON error in what should have been an HTML response.
Additionally, the error message wasn't very clear about the nature of
the problem.
2025-03-03 13:06:14 -05:00
jelveh ae9f5efed0 send event after toolbar is ready and after account is saved 2025-02-28 10:28:40 -08:00
jelveh b56f5c5998 Revert "Remove the Button component from some UI components"
This reverts commit 1eb4c6034e.
2025-02-28 09:23:32 -08:00
jelveh 5c62742fa3 remove unnecessary console.log 2025-02-28 00:14:56 -08:00
jelveh 1eb4c6034e Remove the Button component from some UI components 2025-02-27 23:53:52 -08:00
jelveh c55a13dcd8 Update en.js 2025-02-27 23:19:00 -08:00
KernelDeimos ec0a721143 fix: message coercion bug affecting vision 2025-02-27 14:49:55 -05:00
KernelDeimos 18170f77e2 doc: link videos 2025-02-26 15:42:09 -05:00
KernelDeimos 4486490039 doc: document configuration 2025-02-26 14:59:13 -05:00
KernelDeimos 3666b9f3a2 feat: essential configuration options for deployers
This commit makes everything a ton easier for deployers, adding
configuration options to allow nip.io domains or all origins to access
Puter for ideal LAN or VPN configurations.
2025-02-26 14:18:28 -05:00
KernelDeimos d3da9da9c5 meta: update index.html 2025-02-26 11:35:07 -05:00
KernelDeimos 12a29275c0 meta: add index.html to test something
I'm going to see if a static GitHub Pages page can fetch our GitHub
issues, so I need to commit this file to the repo.
2025-02-26 11:28:45 -05:00
KernelDeimos 3bd12fb5f2 doc: document event core.fs.create.directory
issue: https://github.com/HeyPuter/puter/issues/1122
2025-02-25 18:18:55 -05:00
KernelDeimos e6b3cb3666 fix: get event docs back in sync
I used 'fix' for this instead of 'doc' because I am also adding a
package for code that generates markdown, so this doesn't have the
zero-risk nature typically associated with a "doc: " commit.
2025-02-25 17:52:54 -05:00
KernelDeimos 04f9225af3 chore: update package-lock.json 2025-02-25 17:48:03 -05:00
KernelDeimos 794778d665 fix: dev-center undefined error
I uploaded a video for this one but just realized I never made a commit
for it - it was hiding in my git stash.

So here will be a rare situation that the video link is able to be
placed inside the commit message: https://youtu.be/8XiFR1o5Vuk
2025-02-25 17:21:08 -05:00
KernelDeimos eda376b6cc doc: make first sidebar items make sense 2025-02-25 15:31:40 -05:00
KernelDeimos 2a7bd2ad8d doc: update doc/README.md and genwiki 2025-02-25 15:23:58 -05:00
KernelDeimos efe6f4cb80 doc: update doc/README.md 2025-02-25 15:20:11 -05:00
KernelDeimos 23e5d22439 doc: move el() documentation to gui/doc 2025-02-25 14:57:35 -05:00
KernelDeimos 99684d80e4 doc: generate wiki from repository docs 2025-02-25 14:56:12 -05:00
KernelDeimos 7f372fd1be doc: improve backend intro doc 2025-02-24 16:28:08 -05:00
KernelDeimos 7fd1f9aa5f doc: document backend key locations 2025-02-24 16:28:08 -05:00
KernelDeimos 34fdf3abd9 doc: improve docs organization
- Move extension docs back into this repo
- Add index README.md under `doc/`
- Improve documentation of project structure
2025-02-24 16:28:08 -05:00
KernelDeimos 8ed1f801b8 dev: attempt adding Claude 3.7
At this commit support is not tested. I was unable to get the AI module
in puter.js to call 3.7 instead of the old 3.5 model.
2025-02-24 14:13:43 -05:00
KernelDeimos 759c32ac72 fix: errors after stream starts 2025-02-24 11:42:30 -05:00
Nariman Jelveh ad5be196cc Update README.md 2025-02-24 01:28:37 -08:00
KernelDeimos d081c4f2fe fix(security): patch express via path-to-regexp
As far as I can tell from the block post:
https://blakeembrey.com/posts/2024-09-web-redos/
this vulnerability should not affect releases of Puter before this
update because we do not have any routes with multiple parameters where
the second parameter does not start with '.' or '/'.

However, for the sake of good security hygiene and so `npm audit` looks
nice, we're upgrading the package. (better late than never)
2025-02-21 23:42:47 -05:00
Nariman Jelveh 1cae7fc7d4 Update #DoesItRunPuter.md 2025-02-21 13:26:31 -08:00
KernelDeimos 2ee380ec16 fix: o3 tools with array parameters
Apparently the o3 model things items is a required property for array
types in JSON schema. This is not the case, but we fixed it anyway.
2025-02-20 15:57:50 -05:00
KernelDeimos 7e82c947b1 fix: path update in legacy rename behavior
Change username doesn't go through ll_move, and does not adhere to DRY
alongside the /rename operation. This led to an inconsistency where the
rename behavior in the change username operation didn't update the
cached fsentry path.
2025-02-20 14:10:22 -05:00
KernelDeimos 145d836b9f test: unit test tool calls 2025-02-20 09:41:59 -05:00
KernelDeimos d66e38cc66 fix: message coercion for tool call message
Some services can't tolerate a message with tool calls and an empty
array set on the content property, despite the fact that OpenAI does
seem to support this.
2025-02-19 15:32:07 -05:00
KernelDeimos 9d181741de dev: gemini function calling 2025-02-19 13:16:27 -05:00
Nariman Jelveh d8c49d8b2d Merge pull request #1121 from HeyPuter/revert-1072-fix/success-msg-deploy
Revert "Fix : the issue with the success message not displaying after deployment"
2025-02-17 19:29:54 -08:00
Nariman Jelveh e2d120d81f Revert "Fix : the issue with the success message not displaying after deployment" 2025-02-17 19:29:45 -08:00
Nariman Jelveh 96c4030541 Merge pull request #1072 from mariatouil/fix/success-msg-deploy
Fix : the issue with the success message not displaying after deployment
2025-02-17 19:29:40 -08:00
KernelDeimos 1b5a64043a dev: add openrouter implementation 2025-02-17 18:46:48 -05:00
KernelDeimos 7e76b657bb fix: recursive delete error 2025-02-17 15:31:54 -05:00
Nariman Jelveh d0f32ee2b8 Merge pull request #1119 from Zac0511/patch-4 2025-02-17 09:40:04 -08:00
KernelDeimos feb2ca126f dev: validate attachments 2025-02-17 10:46:02 -05:00
Zac0511 6d8b733cba Update fr.js
Modified 2 translations
2025-02-17 12:49:10 +01:00
Nariman Jelveh 4bc6bf242f Update README.md 2025-02-16 19:46:09 -08:00
jelveh fe5f7cb878 Fix window height when maximized in full page mode 2025-02-15 13:02:57 -08:00
KernelDeimos 870e4aa938 fix: move AppCommandProvider to the end 2025-02-14 16:05:36 -05:00
KernelDeimos 8828d03f86 dev: add gemini to puter.js 2025-02-14 12:15:13 -05:00
KernelDeimos 5513e1c93b dev: add godmode toggle command for apps 2025-02-14 11:16:41 -05:00
KernelDeimos fbd5ffd85d dev: fix cache refresh for invalid origins 2025-02-14 10:29:30 -05:00
ProgrammerIn-wonderland cfa1447df6 fix Uncaught TypeError: Cannot read properties of undefined (reading 'closeCallBack') 2025-02-13 23:22:58 -05:00
KernelDeimos 29834f02c0 release: 2.5.1 2025-02-13 21:50:39 -05:00
KernelDeimos 0bcbc8f784 fix: phoenix changelog 2025-02-13 17:48:21 -05:00
KernelDeimos abd66309c8 dev: update phoenix changelog 2025-02-13 16:57:00 -05:00
KernelDeimos a2413b12b0 dev: de-couple requiring a read from fallback read
IMPORTANT: requires update to database access implementations
2025-02-13 15:11:02 -05:00
Nariman Jelveh 7fca9b79ea Merge pull request #1113 from ProgrammerIn-wonderland/main
Added tab completion to PDEs
2025-02-12 13:43:44 -08:00
ProgrammerIn-wonderland ffaa91f849 Added tab compleition to PDEs 2025-02-12 16:42:24 -05:00
Nariman Jelveh b32011f10f Merge pull request #1111 from HeyPuter/revert-1109-add/browser-ides
Revert "Added Browser IDEs"
2025-02-11 19:37:49 -08:00
Nariman Jelveh 50d5713e8f Revert "Added Browser IDEs" 2025-02-11 19:37:36 -08:00
Nariman Jelveh 1133c4656a Merge pull request #1109 from mojafa/add/browser-ides
Added Browser IDEs
2025-02-11 19:37:18 -08:00
ProgrammerIn-wonderland fd387597bb PDE command provider 2025-02-11 17:49:31 -05:00
KernelDeimos 5169d4bb40 dev: add stream support to Gemini 2025-02-11 16:24:57 -05:00
KernelDeimos b74ec1f69c dev: add Gemini support (non-streaming) 2025-02-11 14:57:17 -05:00
KernelDeimos 74319b44af dev: add more information to lock logs 2025-02-11 14:40:38 -05:00
KernelDeimos c2c5d88336 fix: update package.json 2025-02-11 12:29:01 -05:00
KernelDeimos fa4b38cd02 fix: oops, no export (putility.libs.event) 2025-02-11 11:23:55 -05:00
KernelDeimos e49af481ba dev: make it easier to use putility emitter 2025-02-11 11:10:02 -05:00
KernelDeimos a803d55cfb fix: broken test in putility 2025-02-11 10:54:03 -05:00
mojafa ab704ce4d7 added browser IDE support
Signed-off-by: mojafa <[email protected]>
2025-02-11 03:23:34 +03:00
KernelDeimos 70fde95255 fix: parse body before auth for /down 2025-02-10 17:54:23 -05:00
KernelDeimos e5c3769bd8 fix: fix previous fix 2025-02-10 17:42:12 -05:00
KernelDeimos 390230c5a0 fix: potential fix for /down auth
This is a temporary  workaround for a bug de-syncing http session
cookies.
2025-02-10 17:35:19 -05:00
KernelDeimos 2000b8909f fix: allow command provider to not implement complete method 2025-02-10 17:22:10 -05:00
KernelDeimos ad2ed295b1 dev: fix app close messages from ExecService 2025-02-10 13:59:47 -05:00
jelveh a3513c22a2 do not repeat session picking in popup for file pickers 2025-02-07 18:07:02 -08:00
jelveh 4d380ffa8a remove unnecessary confirmation dialog for file/directory pickers in popups 2025-02-07 17:47:58 -08:00
KernelDeimos 6dcb3777ca dev: fix index_url issue 2025-02-07 15:57:29 -05:00
KernelDeimos ca17f38929 dev: normalize Mistral, get tool calls working
Mistral has a lot of unnecessary quirks because the SDK coerces to
snake_case. We should see if the OpenAI client works with Mistral, and
it it does we'll use that instead so we don't have to maintain all these
exceptional cases.
2025-02-07 15:27:28 -05:00
KernelDeimos 735f275e7c dev: normalize Groq (tool use works) 2025-02-07 14:01:34 -05:00
KernelDeimos 29cd14a01d dev: XAI streaming function calls 2025-02-07 12:55:34 -05:00
jelveh 84b2400650 it fixes it surely! 2025-02-06 19:52:54 -08:00
jelveh d4b4df06fd Use the fetch API in Puter.js's Convert module 2025-02-06 19:45:10 -08:00
jelveh 1e5deabcdb Update package-lock.json 2025-02-06 18:20:12 -08:00
jelveh 949d3ab17c add Convert modules to Puter.js 2025-02-06 18:19:12 -08:00
KernelDeimos 62cf10072a dev: include cost information in usage reports
This adds an incremental migration from models reporting input and
output tokens, to models reporting full token information. This means
AIChatService doesn't need to lookup the model details or know about the
different types of tokens supported by every model.
2025-02-06 17:34:57 -05:00
KernelDeimos f7147ab312 dev: generalize how OpenAIUtil handles usage
The current implementation would break for XAIService because it gets
cumulative usage reports as the stream goes on (whereas OpenAI and
DeepSeek only provide this at the end of the stream).
2025-02-06 17:34:57 -05:00
KernelDeimos 16e2729b1d dev: migrate XAIService to normalized messages 2025-02-06 17:34:57 -05:00
KernelDeimos ce0ab02f39 dev: add file output mode for convert 2025-02-06 17:34:57 -05:00
KernelDeimos 5e30958a14 tweak: enable convert module on selfhosted run 2025-02-06 17:34:57 -05:00
KernelDeimos 2b0e173975 dev: add convert module (and ConvertAPI) 2025-02-06 17:34:57 -05:00
ProgrammerIn-wonderland 12806a2395 only close TLS socket once 2025-02-06 17:13:04 -05:00
ProgrammerIn-wonderland 26666fe666 new API puter.net.generateWispV1URL() 2025-02-05 16:56:57 -05:00
KernelDeimos c8bed6eaee dev: add deepseek tool calls 2025-02-05 15:32:35 -05:00
KernelDeimos d4eff82d3c dev: add email attachments 2025-02-05 14:12:05 -05:00
KernelDeimos da4a1a182b dev: de-couple OpenAI SDK utilities from service
This change will be helpful for making behavior across OpenAI-compatible
APIs consistent.
2025-02-05 11:36:07 -05:00
KernelDeimos 50383aab59 dev: try this for now 2025-02-04 16:45:42 -05:00
KernelDeimos e6fc773706 fix: unfixed fix from earlier 2025-02-04 16:36:06 -05:00
KernelDeimos 9dbba292c4 dev: coerce semantics of tool calls/use in messages
If these APIs were standardized this would have been so much less
painful, but alas, tool calls are implemented completely differently
between Claude and OpenAI. Good job guys.
2025-02-04 16:15:47 -05:00
KernelDeimos 484bb5c201 fix: parser error for empty json buffer 2025-02-04 15:42:03 -05:00
KernelDeimos d2358d234b fix: fix name and id for openai tool calls 2025-02-04 14:36:30 -05:00
KernelDeimos 29c0241119 fix: let messages with tool_calls have content=null 2025-02-04 14:21:14 -05:00
KernelDeimos 8f27742038 fix: repair stream end 2025-02-04 14:09:28 -05:00
KernelDeimos e2797c38d0 fix: add type=text 2025-02-04 14:02:01 -05:00
KernelDeimos 747614c28b dev: integrate stream normalization for OpenAI 2025-02-04 13:57:10 -05:00
KernelDeimos 437467e0ce dev: integrate stream normalization for Claude 2025-02-04 13:10:14 -05:00
Nariman Jelveh 0ce8fdc9f6 Merge pull request #1037 from HeyPuter/Add-TRADEMARK.md
Create TRADEMARK.md
2025-02-03 14:23:24 -08:00
jelveh 4e17908664 Update TRADEMARK.md 2025-02-03 14:22:01 -08:00
KernelDeimos f54b7b7b3d dev: PoC for stream normalization 2025-02-03 16:57:13 -05:00
KernelDeimos f0434435c4 dev: option to normalize AI response (non-streaming) 2025-02-03 14:03:27 -05:00
KernelDeimos 57231d31e4 dev: add email module to run-selfhosted 2025-02-03 13:14:52 -05:00
KernelDeimos cfa3fde436 dev: error handling and text encoding 2025-02-03 13:11:29 -05:00
KernelDeimos 55d052cfc2 fix: various issues with Mail module 2025-02-03 12:25:22 -05:00
KernelDeimos e281dc92e3 dev: add mail module 2025-02-03 10:08:39 -05:00
KernelDeimos dc90999fee dev: enable gpt-o3-mini 2025-01-31 14:48:49 -05:00
KernelDeimos d88dedb66c dev: normalize Claude input
- add merging of same-role messages for all normalized inputs
- generalize Claude-specific system message extraction
- remove redundant behavior from Claude
2025-01-31 11:22:06 -05:00
KernelDeimos 40aa52225f dev: make ai fallback configurable 2025-01-31 10:32:36 -05:00
Nariman Jelveh e257dceb93 Merge pull request #1100 from Zac0511/patch-4
Update fr.js
2025-01-31 05:04:24 -08:00
Zac0511 6c2fa4d398 Update fr.js
Fixed some translations and deleted a copy of billing translations
2025-01-31 09:50:49 +01:00
KernelDeimos 2d12949a08 dev: improve user request error detection 2025-01-30 15:40:10 -05:00
KernelDeimos 60eef2fc67 fix: buffer incomplete JSON objects from AI stream
- simplify ndjson stream to get complete lines instead of chunks
- add buffering for incomplete lines
2025-01-30 15:21:05 -05:00
KernelDeimos af3d732fc4 dev: async await for puter-exec 2025-01-30 13:37:15 -05:00
KernelDeimos d0eca6dafb Revert "dev: remove redundant message adaption from claude"
This reverts commit 0c42613ff0.
2025-01-30 12:23:27 -05:00
KernelDeimos 760eb55b69 Revert "fix: mistake in 0c42613"
This reverts commit 8ffd0004b3.
2025-01-30 12:23:06 -05:00
KernelDeimos 8ffd0004b3 fix: mistake in 0c42613 2025-01-30 12:19:07 -05:00
KernelDeimos 05ced4e625 Revert "dev: remove max_tokens from Claude"
This reverts commit 3bce60893e.
2025-01-30 12:18:26 -05:00
KernelDeimos 3bce60893e dev: remove max_tokens from Claude 2025-01-30 12:09:35 -05:00
KernelDeimos 0c42613ff0 dev: remove redundant message adaption from claude 2025-01-30 10:11:52 -05:00
KernelDeimos babe9f8ede dev: remove now-redundant token count logic from openai service 2025-01-29 16:58:30 -05:00
KernelDeimos 7151723894 dev: use message normalization and clean up openai service 2025-01-29 16:45:15 -05:00
KernelDeimos 0009ededfa dev: implement generic extract_text for ai messages 2025-01-29 16:08:30 -05:00
KernelDeimos e9279ffb36 dev: implement message normalization 2025-01-29 15:28:14 -05:00
KernelDeimos e6ad54be19 dev: puterjs exec module (2) 2025-01-29 13:58:21 -05:00
KernelDeimos cbe02a4489 dev: puterjs exec module 2025-01-29 13:57:50 -05:00
KernelDeimos 77d6bb2d8c dev: always select highest version of the specified language 2025-01-29 10:31:58 -05:00
KernelDeimos dcd47bc4cf fix: fix microcents to USD conversion in AIChatService
This only affects a value sent to TrackSpendingService. Cost
calculations related to user's quotas / billing remain unaffected.
2025-01-28 16:45:48 -05:00
KernelDeimos 913c1b7836 test: add unit test for TimeWindow
TimeWindow is used by TrackSpendingService for two purposes:
- tracking cost within a time window
- preventing duplicate alarms within a cooldown period

It is important to test this to ensure alarms related to AI costs are
accurate.
2025-01-28 16:16:00 -05:00
KernelDeimos 1dad2e8716 dev: allow specifying runtime version 2025-01-28 14:25:45 -05:00
KernelDeimos c852a287e8 dev: push exec submission updates to client 2025-01-28 13:41:26 -05:00
KernelDeimos 4005e9667c dev: implement custom backoff strategy for judge0 2025-01-28 13:27:26 -05:00
KernelDeimos 5718071c08 dev: add judge0 exec and polling 2025-01-28 12:55:54 -05:00
KernelDeimos 0fac03a05a fix: claude duplicate messages in stream 2025-01-28 11:27:47 -05:00
KernelDeimos c96d3b546c dev: update selfhosted default modules 2025-01-28 10:37:39 -05:00
KernelDeimos 3451308e48 dev: tweak supported languages list 2025-01-28 10:20:31 -05:00
KernelDeimos 5b04d1afe1 dev: increase alarm threshold for ai use 2025-01-28 00:35:40 -05:00
KernelDeimos 97f86e564f dev: oh my Claude
Sometimes tool use requests are streamed as JSON, but sometimes they're
streamed as an empty string (causing the JSON parser to error). Had they
not streamed anything we actually would've responded correctly, but
what they stream implies "this empty string is the JSON input" which is
incorrect. Oh well.
2025-01-27 21:32:50 -05:00
KernelDeimos 3f99d975c0 dev: initial work on judge0 implementation 2025-01-27 16:19:16 -05:00
KernelDeimos 81ee52b00f dev: add puterexec module 2025-01-27 15:38:29 -05:00
KernelDeimos 4d826c0602 dev: process language information from judge0 2025-01-27 14:50:40 -05:00
KernelDeimos ecc89678d1 doc: add examples of streaming tool use 2025-01-27 14:13:01 -05:00
KernelDeimos 5ad53e061a dev: get streaming tool use to work in Claude 2025-01-27 13:53:56 -05:00
KernelDeimos d00061ae2f dev: improve accuracy of TrackSpendingService 2025-01-27 11:36:54 -05:00
jelveh 52c1adb7eb Update globals.js 2025-01-26 17:05:43 -08:00
jelveh bb348e4bd5 Update UIWindowMyWebsites.js 2025-01-26 11:20:07 -08:00
KernelDeimos 6083e3ac52 fix: skip request-count usage check via AIChatService 2025-01-24 17:58:04 -05:00
KernelDeimos db9597a7b5 doc: add example function calling requests 2025-01-24 16:35:46 -05:00
KernelDeimos aae18e6878 dev: support POST requests in puter.http 2025-01-24 15:38:19 -05:00
KernelDeimos c7f3e0b937 fix: remove log from InternetModule 2025-01-23 21:27:14 -05:00
KernelDeimos 1fde01aa04 dev: enable tool use for Claude 2025-01-23 20:21:14 -05:00
KernelDeimos e9f6266062 dev: add deepseek AI to backend 2025-01-23 20:07:41 -05:00
KernelDeimos 40030ebc94 dev: enable tool-use in Claude 2025-01-23 16:46:13 -05:00
KernelDeimos 54a104276b dev: add tools normalization/converting 2025-01-23 16:15:32 -05:00
KernelDeimos bcdec32ba2 doc: log some AI responses 2025-01-23 15:20:31 -05:00
KernelDeimos 06452f5283 fix: small workaround for duplicate close 2025-01-23 14:58:23 -05:00
KernelDeimos 36dc9664ad fix: race condition and buffer issue in puter.http
The call to sock.write() wasn't waiting for the 'open' event, which
worked fine over non-TLS sockets by chance. Also, responses with only
a single WISP packet were resulting in buffered response data not
being sent to the caller.
2025-01-23 14:14:13 -05:00
KernelDeimos 3f5b34cd34 fix: missing some buffer contents in no-keepalive 2025-01-23 13:43:21 -05:00
KernelDeimos ee136f4168 dev: add extra safeguards for system user 2025-01-23 11:46:36 -05:00
KernelDeimos 7909cae76e dev: check 'invalid_request_error' hint from openai 2025-01-23 11:46:36 -05:00
jelveh 6f7ab2ab17 Update RecommendedAppsService.js 2025-01-22 21:38:07 -08:00
jelveh bfdf815f61 Update RecommendedAppsService.js 2025-01-22 21:34:27 -08:00
jelveh 925077916e Update RecommendedAppsService.js 2025-01-22 21:29:30 -08:00
KernelDeimos 9cbb741a8a fix: new edge cases with function calls / tools 2025-01-22 19:55:33 -05:00
KernelDeimos 1256614ec2 dev: add support for tools 2025-01-22 19:28:05 -05:00
KernelDeimos cf7aa27543 fix: oops, we're passing negative values; let's just remove this 2025-01-22 18:13:41 -05:00
KernelDeimos 61824ea04b fix: oops we still need that 2025-01-22 18:04:56 -05:00
KernelDeimos 7f50da5082 dev: use Connection: close for http requests by default 2025-01-22 17:46:51 -05:00
KernelDeimos 8143e5700f fix: remove hard-coded token limit for OpenAI 2025-01-22 17:28:18 -05:00
KernelDeimos 2b505caf98 dev: implement puter.http 2025-01-22 16:16:36 -05:00
KernelDeimos 6f39365b24 fix: wisp relay authentication 2025-01-22 14:20:53 -05:00
KernelDeimos 591c6c0fd3 dev: add wisp relay service 2025-01-22 11:45:58 -05:00
KernelDeimos 4c72e9d285 dev: separate process management from DevWatcherService 2025-01-22 10:08:06 -05:00
KernelDeimos 44c6f57c7a dev: add system kv access for extensions 2025-01-20 13:33:02 -05:00
KernelDeimos e8f5450cb0 fix: reduce code paths for querystrings 2025-01-20 10:34:25 -05:00
jelveh 4e578e9b28 update copyright date 2025-01-19 22:27:31 -08:00
jelveh 55f3f07ee5 Implement puter.ui.wasLaunchedWithItems() 2025-01-19 22:20:19 -08:00
Nariman Jelveh f13fa2553c Merge pull request #1093 from AryanTavish/main
Complete the Norwegian Bokmål (Norsk Bokmål) translation of Puter
2025-01-19 16:34:45 -08:00
jelveh ed2eea7c6b Update nb.js 2025-01-19 16:34:28 -08:00
Aryan Tavish 967da6ba24 Update nb.js (removed object billing to make indivisual string keys )
For example, instead of:

billing = {
    change_payment_method: "Endre",
    // ...
}
changed to:

'billing.change_payment_method': "Endre",
// ...
2025-01-18 10:19:30 +05:30
KernelDeimos d03952b237 fix: icons 2025-01-17 18:28:19 -05:00
Nariman Jelveh f27ef665ee Merge pull request #1094 from ProgrammerIn-wonderland/main
more socket fixes
2025-01-17 14:08:14 -08:00
ProgrammerIn-wonderland 01fc301f1e replace hardcoded api.puter.com with puter.APIOrigin 2025-01-17 17:05:51 -05:00
ProgrammerIn-wonderland 5798fcd042 automatic reconnection on disconnect 2025-01-17 17:05:42 -05:00
KernelDeimos 17d0738d62 dev: no_temp_user event setting 2025-01-17 13:09:00 -05:00
Nariman Jelveh 7d24fa2b32 Update nb.js 2025-01-16 19:07:44 -08:00
aryantavish 3883af2e96 Complete the Norwegian Bokmål (Norsk Bokmål) translation of Puter 2025-01-17 07:40:08 +05:30
KernelDeimos 56ae760bea dev: extension support for request measurements 2025-01-15 11:59:30 -05:00
KernelDeimos 38ccc82c8e fix: subdomains to deleted files tried to deref fs node 2025-01-15 11:11:57 -05:00
KernelDeimos 37ca89228c fix: app icon empty string should be skipped 2025-01-15 11:11:57 -05:00
Nariman Jelveh 8cff90bdc3 Merge pull request #1092 from ProgrammerIn-wonderland/main
move try-catch outside of loop in TLS readstream
2025-01-15 08:00:31 -08:00
ProgrammerIn-wonderland f177732a0e move try-catch outside of loop in TLS readstream 2025-01-15 10:11:58 -05:00
Nariman Jelveh d638f371d0 Merge pull request #1091 from ProgrammerIn-wonderland/main
add 0x01 and 0x03 wisp messages
2025-01-14 21:03:21 -08:00
ProgrammerIn-wonderland b35cf776aa add 0x01 and 0x03 wisp messages 2025-01-15 00:01:43 -05:00
Nariman Jelveh 4fd6da9903 Merge pull request #1090 from ProgrammerIn-wonderland/main
TLS Support through rustls-wasm
2025-01-14 21:01:29 -08:00
ProgrammerIn-wonderland 98be5c1323 error handling on TLS handshake and reporting wisp errors to client 2025-01-14 23:54:47 -05:00
ProgrammerIn-wonderland 6261d7c90c WIP TLS support 2025-01-14 21:20:00 -05:00
Nariman Jelveh 365fac907c Merge pull request #1088 from ProgrammerIn-wonderland/main
add close to psocket
2025-01-14 14:52:46 -08:00
ProgrammerIn-wonderland a5e4840920 add close() 2025-01-14 17:51:24 -05:00
KernelDeimos 766c235cc7 fix: save_account case for disable_user_signup 2025-01-14 17:23:39 -05:00
Raiu 8d5860d733 feature: disable creation of temp_users and user signup through config 2025-01-14 17:06:14 -05:00
Raiu 78ac033a1c fix: use .get() for Map lookup. fix: correctly set url and url_paths. fix: null check to throw error. 2025-01-14 17:06:14 -05:00
KernelDeimos 7fa0822584 dev: measure response data amount 2025-01-14 16:17:55 -05:00
KernelDeimos 113ed31336 fix: ensure puter.signup emit resolves 2025-01-14 14:41:27 -05:00
KernelDeimos ca9e74ece4 dev: measure request transfer amount 2025-01-14 13:43:50 -05:00
KernelDeimos 4f3a6f7bbc dev: ll_rmdir,ll_rmnode -> provider.(rmdir,unlink) 2025-01-14 13:06:41 -05:00
KernelDeimos 5bf11adff3 dev: add utility to measure bytes in a stream 2025-01-14 10:45:23 -05:00
KernelDeimos 202e7f06e2 test: cleanup and tweak batch test
One of the test cases has been rendered redundant so it has been
removed. Another test was changed to overwrite a file as it's expected
to already exist.
2025-01-14 09:42:20 -05:00
KernelDeimos d9822a4f09 fix: --onlycase param broke cartesian tests 2025-01-14 09:18:33 -05:00
KernelDeimos f359ae193e fix: empty response when mkdir is a no-op 2025-01-13 15:27:02 -05:00
KernelDeimos 807c3ba5ec fix: mkdir with create_missing when some parents exist
There was an issue affecting mkdir requests with create_missing_parents
set to true which prevented the correct behavior if some of the listed
parents were already present. This commit ensures mkdir selects the
deepest existing node as the parent before proceeding.
2025-01-13 15:16:52 -05:00
KernelDeimos fb7025164e fix: possible out-or-order response objects from batch 2025-01-13 14:39:43 -05:00
KernelDeimos 5ef75e5df3 fix: app data check error in write 2025-01-13 14:11:26 -05:00
KernelDeimos 9215937064 test: remove tests for unsupported behavior in mkdir 2025-01-13 13:54:59 -05:00
KernelDeimos c9215d9e86 test: update outdated test cases 2025-01-13 11:38:00 -05:00
KernelDeimos 9d9d97fd00 fix: missing parent dirs created in move 2025-01-13 10:07:49 -05:00
KernelDeimos 6f4b1bf94a fix: missing changes to run-selfhosted.js 2025-01-13 09:11:39 -05:00
jelveh 706a2403e1 When navigating context menu using keyboard skip over item dividers 2025-01-11 14:59:03 -08:00
KernelDeimos d6bbba7bf0 fix: appease mocha's import requirements 2025-01-10 17:40:02 -05:00
KernelDeimos 6a6bfa034f fix: error msg for invalid puter-ocr urls 2025-01-10 17:37:44 -05:00
KernelDeimos 14cc8f7bc0 doc: notes about mountpoint hurdles 2025-01-10 16:44:46 -05:00
KernelDeimos e1bdee1abe dev: ability to run api tests from puter terminal 2025-01-10 16:24:08 -05:00
KernelDeimos 2993b887bd dev: experimental local-terminal service 2025-01-10 14:12:30 -05:00
KernelDeimos 7293fdbbfa dev: ll_move -> provider.move 2025-01-10 13:10:43 -05:00
KernelDeimos 28c5800d06 sync: package-lock.json 2025-01-10 10:27:40 -05:00
KernelDeimos 75aaaa66a8 fix: improper 500 in wisp token verify 2025-01-10 10:27:40 -05:00
KernelDeimos 7aa886d573 fix: actor param in legacy /write 2025-01-10 10:27:40 -05:00
jelveh a295420f58 fix: new desktop height calculation when resizing browser window 2025-01-09 16:15:32 -08:00
KernelDeimos 8fabf014a9 fix: circular imports 2025-01-09 19:07:31 -05:00
KernelDeimos eac2ddf8da sync: backend ver with puter ver 2025-01-09 19:07:31 -05:00
jelveh eb59c1a102 Don't console.log auth token 2025-01-09 15:32:33 -08:00
Nariman Jelveh d65ee6cfb1 Merge pull request #1085 from ProgrammerIn-wonderland/main
networking API beginnings
2025-01-09 15:25:40 -08:00
ProgrammerIn-wonderland 1ed3bccaa5 networking API beginnings 2025-01-09 18:11:28 -05:00
KernelDeimos d9a8ea095c dev: try removing npm registry from Dockerfile 2025-01-09 17:38:53 -05:00
KernelDeimos dd86724941 dev: add cartesian case selector 2025-01-09 16:36:37 -05:00
KernelDeimos 405d9b35aa move: api-tester to monorepo 2025-01-09 15:51:50 -05:00
KernelDeimos 44ad3c5781 fix: test and improve boolify 2025-01-09 15:45:15 -05:00
KernelDeimos f60c008158 fix: skip test files in mod lib loading 2025-01-09 15:41:40 -05:00
KernelDeimos 6d196d59f0 fix: shortcut issue 2025-01-09 11:51:26 -05:00
KernelDeimos 740fdb592e fix: test for get-launch-apps 2025-01-09 11:10:41 -05:00
KernelDeimos 3097b86597 fix: add package-lock.json 2025-01-09 10:24:12 -05:00
KernelDeimos 8963eb0c4f fix: try redundant npm install after build stage 2025-01-08 15:23:03 -05:00
KernelDeimos 686d3de518 fix: I'ma buy GitHub a coffee and spill it on their servers if this works 2025-01-08 14:47:49 -05:00
KernelDeimos a13af7e31a fix: oh, right; there's two of them 2025-01-08 12:20:05 -05:00
KernelDeimos 63b3376b48 dev: try upgrading docker node version 2025-01-08 12:11:43 -05:00
KernelDeimos 0cb1ca7989 chore: date and update version 2025-01-07 15:51:44 -05:00
KernelDeimos 691be3802b doc: update CHANGELOG.md 2025-01-07 15:50:26 -05:00
KernelDeimos 4085d508b0 dev: update release notes generator 2025-01-07 15:33:53 -05:00
KernelDeimos 803f440d55 fix: terminal not loading in self-hosted 2025-01-07 15:13:35 -05:00
KernelDeimos f5a7b06d40 doc: fix generated comment errors (batch 2) 2025-01-07 14:35:54 -05:00
KernelDeimos 7deb0c5692 fix: don't call /rao in gui 2025-01-06 21:20:13 -05:00
jelveh 6a184d52b4 Update copyright notice dates in license headers 2025-01-06 15:18:22 -08:00
KernelDeimos 540821c759 doc: fix generated comment errors (batch 1) 2025-01-06 16:47:30 -05:00
KernelDeimos 15898fe5b7 chore: update license headers 2025-01-06 11:55:17 -05:00
KernelDeimos 0fb05309c2 doc: miscellaneous comment fixes 2025-01-06 11:24:18 -05:00
KernelDeimos 57befd310d doc: fix comments for list(), models(), complete() 2025-01-06 10:04:54 -05:00
jelveh 9c181516fc lol there was an empty file in there! 2025-01-05 23:20:17 -08:00
jelveh 5f81299bf0 cleaned up as much as i could 2025-01-05 23:14:47 -08:00
jelveh f3f1a1f188 Copyright notice fix 2025-01-05 22:39:20 -08:00
Nariman Jelveh 737a3a0ebc Merge pull request #1082 from ahmadkani/main
English README translated to Persian language
2025-01-04 14:54:22 -08:00
Ahmad e633d11dbb English document translated to Persian language 2025-01-04 10:47:36 +03:30
jelveh a03314f8b8 Update dev-center.js 2025-01-03 21:05:55 -08:00
KernelDeimos 9b0f220556 dev: request /rao from sites 2025-01-03 14:32:24 -05:00
KernelDeimos 71f221dd07 dev: ll_copy -> provider.copy_tree 2025-01-03 14:32:24 -05:00
KernelDeimos 8a9164d7c5 fix: missing ll_copy import 2025-01-03 13:28:03 -05:00
jelveh 34fcae9c56 Update UIWindow.js 2025-01-03 09:48:00 -08:00
jelveh 3e3db2327e Update UIWindow.js 2025-01-03 09:42:15 -08:00
KernelDeimos 63401f2c83 dev: DRY base64 app icons from streams 2025-01-03 11:46:01 -05:00
KernelDeimos 06a67a3b22 dev: migrate /rao to actor-capable auth 2025-01-03 10:24:46 -05:00
jelveh cd5866dd6b Update UITaskbarItem.js 2025-01-02 18:48:24 -08:00
jelveh 6fbd00f2ec Update style.css 2025-01-02 18:14:49 -08:00
jelveh 1ef8c36135 quick fix 2025-01-02 18:05:38 -08:00
jelveh ddd1c254f0 Update style.css 2025-01-02 17:20:47 -08:00
jelveh 3a47bc69d9 Add tooltips to vague icons in Dev Center 2025-01-02 17:14:08 -08:00
KernelDeimos a8fc4669e8 dev: fix default origins in puter.js 2025-01-02 16:23:02 -05:00
jelveh f1d0f9cd1f Update style.css 2025-01-02 11:04:00 -08:00
KernelDeimos 3e4c8ab56b dev: add wisp auth endpoints 2025-01-02 12:45:52 -05:00
KernelDeimos 13003c486f fix: bad uuid reference to resourceService 2025-01-02 10:53:37 -05:00
jelveh 626c453f19 Add more sub-sections to ACCEPTABLE USES 2025-01-01 10:46:25 -08:00
jelveh 3856ec476d Update TRADEMARK.md 2025-01-01 10:16:06 -08:00
jelveh 0c5f780f59 Merge branch 'main' of https://github.com/heyputer/puter 2025-01-01 10:01:41 -08:00
Nariman Jelveh 314d373527 Merge pull request #1079 from HeyPuter/revert-1050-issue-1000-drag-drop-fix
Revert "Fix: drag-and-drop issue: files not appearing on desktop automatically"
2025-01-01 09:49:44 -08:00
Nariman Jelveh 774a75401a Revert "Fix: drag-and-drop issue: files not appearing on desktop automatically" 2025-01-01 09:49:33 -08:00
Nariman Jelveh 55687bb412 Merge pull request #1050 from mariatouil/issue-1000-drag-drop-fix
Fix: drag-and-drop issue: files not appearing on desktop automatically
2025-01-01 09:49:23 -08:00
jelveh 4691af3a6f Update AppInformationService.js 2024-12-31 21:27:42 -08:00
jelveh a0da1e06e3 Use puter.ui's spinner for all spinners in Dev Center 2024-12-31 20:46:05 -08:00
KernelDeimos ad8a3978c0 fix: allow localhost for development 2024-12-31 17:16:09 -05:00
KernelDeimos 29471a752f dev: ll_readdir -> provider.readdir 2024-12-31 15:43:04 -05:00
KernelDeimos 0ef1849013 dev: make puterfs a mountpoint 2024-12-31 15:43:04 -05:00
jelveh 5d8ccf8c9e Use the correct date formatting in get_stats depending on DB engine 2024-12-31 11:21:08 -08:00
jelveh 13e5f7f69f Replace non-existent timestamp column with ts in get_stats 2024-12-31 10:53:46 -08:00
KernelDeimos 9d578b8d1f dev: begin de-coupling FSNodeContext/PuterFS 2024-12-31 13:15:01 -05:00
KernelDeimos f7196991fc refactor: rm legacy FSAccessContext and systemfs 2024-12-31 10:33:39 -05:00
jelveh 539b31cc5b Don't allow dropping of Launcher icons after trash in taskbar. 2024-12-30 22:02:42 -08:00
jelveh 4da9f525da delete components that aren't used 2024-12-30 20:39:51 -08:00
KernelDeimos 2728761d3c dev: remove unnecessary filesystem methods
These used to serve a purpose but now they only cause a dependency loop
between LL*/HL* operations and FilesystemService itself, making it
difficult to strategize filesystem behavior.
2024-12-30 15:52:10 -05:00
KernelDeimos dacbbf033d fix: rewrite confusing log message 2024-12-30 15:34:12 -05:00
KernelDeimos 233260233c fix: AppInformationService initialization 2024-12-30 15:23:37 -05:00
KernelDeimos 47a4313d92 fix: dev center app icon SVG issue 2024-12-30 13:39:12 -05:00
KernelDeimos 23eab63776 fix: app icon double-encode bug
When getting a stream for an SVG icon from AppIconService with a
previously-fetched stored icon provided, a double-encoding bug was
preventing a valid image from being obtained.
2024-12-30 13:38:41 -05:00
KernelDeimos a6b9d33d27 fix: first read of recommended apps 2024-12-30 12:55:44 -05:00
KernelDeimos 055ba7d9df dev: move recommended apps to service with cache invalidation
Adds an event for app invalidation.

Moves iconify_apps to AppIconService and adds RecommenededAppsService,
which holds some logic that used to be in get-launch-apps. The event for
app invalidation is then used by RecommenededAppsService to determine
when to clear the recommended apps cache.
2024-12-30 12:38:51 -05:00
KernelDeimos c1961dd54e dev: move app services to apps module
Moves AppIconService, OldAppNameService, and ProtectedAppService to the
new apps module to keep things organized, and updates imports. There
were no interesting init errors. Services creating a database at init
were tested for failures but this wasn't an issue. It turns out
initializing with a database accessor before the db service inits is
okay, but using that database accessor at init is not.
2024-12-30 11:03:27 -05:00
KernelDeimos 2de442be92 dev: add apps module, migrate AppInformationService
There are now several services related to apps, and
RecommendedAppsService is about to be added, making this a good time to
create a separate module for these services and migrate the legacy
service AppInformationService.

During migration it was realized that most of the initialization needed
to occur at boot.consolidation rather than boot.init because the
database needs to be initialized first.
2024-12-30 10:19:02 -05:00
jelveh 3ffb3cbc74 Remove credentialless from Dev Center advanced section 2024-12-29 22:13:11 -08:00
jelveh a105192882 Update dev-center.js 2024-12-29 21:53:43 -08:00
jelveh 3b60e9913e Update dev-center.js 2024-12-29 19:25:13 -08:00
jelveh cc0abf9f3b Update style.css 2024-12-29 18:47:32 -08:00
jelveh 0d0f429bd8 Add icons to dev center sub tabs 2024-12-29 18:44:06 -08:00
jelveh c9fe08cea5 Update style.css 2024-12-29 18:00:12 -08:00
jelveh 5da8872315 Update dev-center.js 2024-12-29 17:20:59 -08:00
jelveh be24f2acec Update dev-center.js 2024-12-29 16:53:09 -08:00
jelveh bc0e7e12b5 Add better grouping and chart labeling for dev center analytics 2024-12-29 16:42:31 -08:00
jelveh 4f88ee37de Analytics for apps 😎 2024-12-29 14:55:59 -08:00
Nariman Jelveh 3b7a051d79 Add Ritesh Sahu to SECURITY-ACKNOWLEDGEMENTS.md 2024-12-29 10:24:33 -08:00
jelveh 2bdaac6177 Update fuzz.js 2024-12-28 16:49:26 -08:00
jelveh 14cb77d544 Update fuzz.js 2024-12-28 15:42:40 -08:00
jelveh c58788805d Update dev-center.js 2024-12-28 14:48:01 -08:00
jelveh 3eff05d97d add a little STYLE to analytics 2024-12-27 22:05:15 -08:00
jelveh 116c3d358a add simple analytics tab for Dev Center 2024-12-27 21:52:17 -08:00
jelveh ac8068a139 No need for params when passing params to Apps driver 2024-12-27 18:24:09 -08:00
jelveh d7aa08b345 Revert "if clichouse exists hit it in _refresh_app_stats"
This reverts commit 9867d26432.
2024-12-27 17:53:43 -08:00
jelveh 9867d26432 if clichouse exists hit it in _refresh_app_stats 2024-12-27 17:47:19 -08:00
jelveh 7252d2ef4f Check cache first when returning stats for the all period in the AppInformationService 2024-12-27 17:21:17 -08:00
jelveh 027f52d0fd Update AppInformationService.js 2024-12-27 16:55:31 -08:00
jelveh 9f5a138047 add analytics to the Apps driver 2024-12-27 14:39:51 -08:00
KernelDeimos c3fb0bca41 doc: document how to create a driver 2024-12-27 17:23:30 -05:00
KernelDeimos 396498f88a dev: try a different approach for trigger_download 2024-12-27 15:27:03 -05:00
KernelDeimos 5e844205b3 dev: update/cleanup PerformanceMonitor 2024-12-27 13:15:55 -05:00
KernelDeimos 33d094322f dev: change cache score for fs 2024-12-27 10:58:53 -05:00
jelveh 8daf1a5469 Update keyboard.js 2024-12-26 20:57:40 -08:00
jelveh c58c0facda Update get-launch-apps.js 2024-12-26 20:30:20 -08:00
jelveh 93aa83bdf7 change apps in taskbar and launcher 2024-12-26 20:21:46 -08:00
jelveh 5f5eeb2a06 Use alerts to show error message when signing up temp user 2024-12-26 17:28:46 -08:00
jelveh e74aa13187 Send puter.signup event before signup process starts 2024-12-26 17:14:11 -08:00
jelveh 76654e65de Fix the issue with contextmenu going completely nuts when opened near the right edge of the screen 2024-12-26 13:43:34 -08:00
jelveh 68fb7e8291 Update AppInformationService.js 2024-12-25 18:26:20 -08:00
jelveh e263c2be95 Update AppInformationService.js 2024-12-25 18:21:36 -08:00
jelveh 89eb6a80e1 AppInformationService can now use clickhouse to pull metrics 2024-12-25 17:57:22 -08:00
jelveh 3d32f4123b Send more infor in the puter.app_open event 2024-12-24 22:52:07 -08:00
KernelDeimos efd4730f75 fix: prefix peer addresses with protocol 2024-12-24 16:49:22 -05:00
KernelDeimos d386096467 feat: hash-based distributed cache inval 2024-12-24 16:19:58 -05:00
KernelDeimos eb7494ce55 dev: measure cache rate and fix an edge-case 2024-12-24 14:04:22 -05:00
KernelDeimos 7c29d7c16d dev: smaller readdir app icons 2024-12-24 13:11:39 -05:00
jelveh 0859543ca3 Update TRADEMARK.md 2024-12-23 21:51:15 -08:00
KernelDeimos 498d6ed3d8 clean: remove unnecessary additional method 2024-12-23 15:49:15 -05:00
KernelDeimos 728ecbfb03 fix: clone message object 2024-12-23 15:27:25 -05:00
jelveh 38adf9fce3 Update TRADEMARK.md 2024-12-23 12:13:29 -08:00
KernelDeimos 35cc83a560 dev: filter topic ARNs (and tweaks) 2024-12-23 14:58:39 -05:00
KernelDeimos 5ed2f39ec7 dev: add Amazon SNS integration
There were a few things which made this rather difficult:
- AWS SDK doesn't appear to have a utility to validate message
  signatures.
- The only available node.js module that does this is known to be
  unreliable.
- SNS sends 'text/plain' MIME type even though the data is in JSON
  format, so a middleware had to be added to account for this.
- We don't accept POST requests with no Origin header. Since SNS doesn't
  send the Origin header, an exception had to be made for this.
- The endpoint needs to be public and SNS doesn't seem to have a
  proxying utility for developers such as what Stripe has.
- Because of the above point, debugging time was affected by deployment
  time to the staging server.
2024-12-23 14:53:18 -05:00
KernelDeimos 2dc6c4737b fix: timing for PrefixLogger call to /whoami
This commit fixes the timing of the /whoami call used for the
PrefixLogger (a logger for puter.js that displays app names) to ensure
the API origin and token are available. This is done by waiting for a
service called 'api-access' to be initialized first.

This was discovered while testing changes for /whoami responses that
display icons, because the current behavior breaks the call for
non-puter.com instances.
2024-12-23 11:50:30 -05:00
KernelDeimos cb2653b84d dev: no icons form /whoami calls without icon_size
Calls to `/whoami` generally don't require app icons. Fetching icons of
the smallest size still incurs round-trip latency from the database and
S3, as well as additional delay for any retries due to failed icon
generation.

Although this is technically a regression in `/whoami`, the impact is
localized to Puter's desktop only because apps are not allowed to
receive taskbar icons.
2024-12-23 11:26:44 -05:00
KernelDeimos d1bec45df6 dev: fallback icon read 2024-12-23 10:45:04 -05:00
jelveh 665f5559e1 make email confirmation window responsive 2024-12-23 06:59:09 -08:00
KernelDeimos e56a62c539 fix: try catching icon read errors before stream
Current issue with get-launch-apps wasn't fixed by catching errors while
reading the stream so this next attempt catches errors from the call to
start reading.

If the error occurs asynchronously this may not work either.
2024-12-23 09:50:01 -05:00
jelveh e736e428d6 disable email confirmation digit input while confirming 2024-12-23 06:43:46 -08:00
KernelDeimos ada051b9b8 fix: try catching on stream_to_buffer 2024-12-23 09:40:22 -05:00
jelveh d922c848ce request 64x64 icon sizes when opening apps 2024-12-23 06:17:16 -08:00
Nariman Jelveh eb26eacdc2 Merge pull request #1078 from HeyPuter/revert-1076-patch-1
Revert "Create devcontainer.json"
2024-12-22 12:07:28 -08:00
Nariman Jelveh ce0b4b9394 Revert "Create devcontainer.json" 2024-12-22 12:07:17 -08:00
Nariman Jelveh 613c75f1ed Merge pull request #1076 from akamas/patch-1
Create devcontainer.json
2024-12-22 12:07:09 -08:00
jelveh 6c1226bc8c emit an event when an app is opened 2024-12-21 22:44:20 -08:00
jelveh 55073189bb cleanup 2024-12-21 21:30:32 -08:00
jelveh 0beb442fa6 remove unused imports in helpers.js 2024-12-21 21:10:08 -08:00
jelveh e5f8127e21 Update app.js 2024-12-21 18:40:17 -08:00
KernelDeimos 5d049e8f06 fix: check if row.timestamp is Date 2024-12-21 14:57:37 -05:00
SAnker f4d36a271d Create devcontainer.json 2024-12-21 08:52:16 +01:00
Nariman Jelveh 770b957b42 Merge pull request #1024 from HatemLamia/add-french-translation
feat: Complete the  French (Français) translation of Puter #975
2024-12-20 17:59:24 -08:00
jelveh 76fbe9b4ce request 64x64 icons for Taskbar via /whoami 2024-12-20 14:06:37 -08:00
KernelDeimos e732859ff8 dev: icon_size for taskbar items 2024-12-20 16:39:05 -05:00
jelveh 530db18bae request 64x64 icons for taskbar and launch menu 2024-12-20 13:29:01 -08:00
KernelDeimos ee3f0c6e08 dev: do base64 svg check outside of get-launch-apps 2024-12-20 16:09:49 -05:00
Nariman Jelveh 77db3da1cf Merge pull request #1075 from joswin18/add-malalayalam-translations
Complete Malayalam translation based on English file #754
2024-12-20 12:48:22 -08:00
KernelDeimos df10a7c332 dev: add icon_size query for get-launch-apps 2024-12-20 15:08:10 -05:00
joswin18 3921241c46 Add Malayalam translations for missing keys in ml.js 2024-12-21 01:23:06 +05:30
KernelDeimos f14e1fefcf fix: AppES PD alert
This happened because the return signature of get_app_icon was changed
so that the MIME type can be returned when the uploaded or default icon
is being used as a fallback. AppES was not updated to account for this
change.
2024-12-20 13:56:32 -05:00
KernelDeimos a504c6ba2a perf: optimize recommended apps 2024-12-20 13:16:00 -05:00
KernelDeimos 3da571c39a test: unit-test get-launch-apps 2024-12-20 12:07:34 -05:00
KernelDeimos c6c3844763 chore: update kv.js 2024-12-20 12:07:24 -05:00
KernelDeimos 2a5073687d perf: reorder get-launch-apps behavior
As the recommended app list is hard-coded, these apps should be fetched
first as they don't depend on a database request.
2024-12-20 12:07:24 -05:00
jelveh e6194f028d support icon_size in the apps module of Puter.js and Dev Center 2024-12-20 06:58:02 -08:00
KernelDeimos 648d6e036d fix: fix for previous fix 2024-12-20 09:25:30 -05:00
KernelDeimos 4f3a1618b1 fix: fix fallback icon behavior in get_icon_stream 2024-12-20 09:12:50 -05:00
jelveh b1833ce1d7 close #1073 2024-12-19 19:35:22 -08:00
Hatem Lamia 4a77c93ce6 Merge branch 'main' into add-french-translation 2024-12-19 23:10:22 +01:00
KernelDeimos 9c86614df5 fix: revert test change 2024-12-19 13:22:50 -05:00
KernelDeimos 0d53020739 dev: fix a timestamp bug in old name expiry 2024-12-19 13:22:00 -05:00
KernelDeimos 6d2966f314 dev: AppES predicate transform for old name retry lookup 2024-12-19 13:22:00 -05:00
KernelDeimos c775a2e860 dev: option to follow old app names in get_app 2024-12-19 13:22:00 -05:00
KernelDeimos 0ccb3b2eed dev: track old app names 2024-12-19 13:22:00 -05:00
maria touilzak 408631dce9 Bug: Success Message Not Displayed After Deployment 2024-12-19 11:39:03 +01:00
Nariman Jelveh 40abd568e3 Merge pull request #1067 from bill-c-law/explorer-table-too-wide
Fix explorer table extra white space on right
2024-12-18 16:06:36 -08:00
jelveh 7a98616c86 Restore package-lock.json from master 2024-12-18 15:39:11 -08:00
jelveh 8c9f92cb61 cleanup 2024-12-18 15:31:14 -08:00
KernelDeimos c69006e185 fix: acl check for subdomain on access 2024-12-18 14:51:30 -05:00
KernelDeimos 81ad3243b1 dev: entity storage parameters + app icon size 2024-12-18 14:12:42 -05:00
KernelDeimos f032faa06d dev: add fallback for missing icons 2024-12-18 13:04:52 -05:00
KernelDeimos 7ec6621111 dev: make code more compatible with migration branch 2024-12-18 12:20:47 -05:00
KernelDeimos 90967ab109 dev: add ico support 2024-12-18 12:05:11 -05:00
KernelDeimos 8a3d74d30c dev: add bmp support for app icons 2024-12-18 11:23:04 -05:00
KernelDeimos d67a6f0e0c doc: document and cleanup app icons 2024-12-17 15:17:31 -05:00
KernelDeimos fc87897a3d dev: parallelize app icon generation 2024-12-17 14:56:07 -05:00
KernelDeimos 925ebd5310 fix: attempt fix for prod issue with app icons 2024-12-17 13:51:33 -05:00
bill-c-law c5198a03fe Fix explorer table extra white space on right
Fix explorer table was always too wide with extra white space on right side causing an unnecessary horizontal scrollbar.  Changed width for both the header row and item rows from 100vw to 100%, and added min-width.
2024-12-17 13:25:42 -05:00
KernelDeimos 046ef3cb4f dev: add endpoint to read app icons 2024-12-17 12:57:24 -05:00
KernelDeimos 20d27d59bf dev: create pre-sized icons for apps 2024-12-17 12:57:03 -05:00
jelveh 905be23854 Larger launch icons 2024-12-17 09:17:38 -08:00
jelveh 453b7d9ac9 Enforce taskbar height 2024-12-17 09:13:43 -08:00
Nariman Jelveh 971383ef58 Merge pull request #1065 from bestlaw66/patch-1
Update README.zh.md
2024-12-17 09:01:40 -08:00
KernelDeimos 4a0e4d51b5 git: update .gitignore 2024-12-17 10:27:11 -05:00
KernelDeimos f87769b445 fix: remove redundant notification query 2024-12-17 10:23:20 -05:00
KernelDeimos 2336a62b4f fix: share only emails email_confirmed recipients 2024-12-17 10:00:43 -05:00
jelveh 63efee390a Fix login using QR code 2024-12-17 06:48:40 -08:00
jelveh 47908f01a9 Add that sweet sweet subtle shadow for taskbar 2024-12-16 16:17:35 -08:00
jelveh 3c9a6b9d19 swipe to scroll Explore on mobile 2024-12-16 16:01:43 -08:00
jelveh c9ab994042 Make progress window mobile friendly 2024-12-16 15:30:42 -08:00
jelveh 8019fd6b73 Update style.css 2024-12-16 15:21:17 -08:00
jelveh ec2cb250b8 Update initgui.js 2024-12-16 15:16:04 -08:00
jelveh 35059098c3 Update style.css 2024-12-16 15:08:37 -08:00
jelveh 08d23ffca9 Update style.css 2024-12-16 14:58:03 -08:00
jelveh a06f9c1ec1 Update style.css 2024-12-16 14:52:43 -08:00
jelveh 24ca4e6ad8 Update style.css 2024-12-16 14:44:55 -08:00
jelveh b1c057e3a6 Update style.css 2024-12-16 14:35:15 -08:00
jelveh 276c9aab96 allow smooth swipe-to-scroll on mobile 2024-12-16 14:29:43 -08:00
jelveh 4e964d82ad ok, apple is horrible. 2024-12-16 14:22:10 -08:00
jelveh 1c5d59da79 Update style.css 2024-12-16 14:19:05 -08:00
jelveh 07de2aba30 Update style.css 2024-12-16 14:13:53 -08:00
jelveh ba7247e75d More aggressive measures to disable pinch/pan zoom on touch devices 2024-12-16 14:05:17 -08:00
KernelDeimos fd6f8bf225 perf: single request for gui boot kv keys 2024-12-16 16:54:08 -05:00
KernelDeimos 7ba1b7656b fix: database issue with KBKV update 2024-12-16 16:54:08 -05:00
jelveh 7f036223f6 Update initgui.js 2024-12-16 13:35:18 -08:00
jelveh 380a4b45ef Add user-scalable=no to the desktop 2024-12-16 13:30:16 -08:00
jelveh 89aa02ccec allow web-share in iframes 2024-12-16 12:58:51 -08:00
KernelDeimos 5a68691290 perf: multiple kv keys 2024-12-16 15:38:30 -05:00
jelveh 29d4eefbae Update style.css 2024-12-16 07:25:11 -08:00
jelveh 6014b1ea36 append custom_script_tags_str to the HTML of homepage 2024-12-16 07:09:37 -08:00
jelveh 3d761f008b Emit add_script_tags_to_homepage_html event before building the HTML of homepage 2024-12-16 07:01:44 -08:00
jelveh 556258847a Fix sizing for windows snapping given the new taskbar 2024-12-15 21:49:31 -08:00
jelveh d7c6229aea update search position in both desktop and launcher 2024-12-15 21:39:05 -08:00
jelveh b893a47595 Update style.css 2024-12-15 19:28:46 -08:00
jelveh ab5bc17991 set correct size for home screen on mobile 2024-12-15 19:23:30 -08:00
jelveh 949f97eb2e add mobile responsiveness for otp, login, and password recovery 2024-12-15 17:52:57 -08:00
jelveh 66bcf8a296 Update style.css 2024-12-14 20:55:10 -08:00
jelveh 1266fb8a29 Update style.css 2024-12-14 20:44:20 -08:00
jelveh 37ef58eb04 make Launcher mobile-friendly 2024-12-14 20:32:34 -08:00
jelveh 5ba957b14a add smooth scrolling for mobile taskbar 2024-12-14 19:31:41 -08:00
jelveh a90beab0b1 show all taskbar items on mobile as well. 2024-12-14 19:18:56 -08:00
jelveh cfbf98efdd fix more mobile styles 2024-12-14 17:09:03 -08:00
jelveh 803f54dec2 Update style.css 2024-12-14 16:57:19 -08:00
jelveh 6565c740f3 fix minimize not working on mobile 2024-12-14 16:50:43 -08:00
jelveh 26b046b512 Fix multiple issues with mobile responsiveness 2024-12-14 16:39:12 -08:00
jelveh 1a99581d0e fix minor css issues 2024-12-14 13:39:23 -08:00
jelveh 2061d571b0 fix issue with empty file associations input breaking the save process in Dev Center 2024-12-14 13:26:52 -08:00
jelveh ce36a685fc new taskbar is here! 2024-12-14 10:52:53 -08:00
jelveh 94e7f5deb4 fix: taskbar items of apps should always appear before Trash 2024-12-13 20:42:56 -08:00
jelveh 134f9d2934 Update UIWindowPublishWebsite.js 2024-12-13 19:18:06 -08:00
jelveh 54b93cc349 add a copy button next to App UID in Dev Center 2024-12-13 18:37:43 -08:00
jelveh 65d918866e fix: fullpage mode 2024-12-13 16:10:44 -08:00
KernelDeimos 45f6bc12eb dev: move and simplify writeFile write 2024-12-13 16:49:04 -05:00
KernelDeimos 8045d60e88 clean: cleanup copy and move 2024-12-13 16:04:48 -05:00
KernelDeimos e208b99d21 fix(security): verify dest_node uid matches signature 2024-12-13 15:53:12 -05:00
KernelDeimos e840544ee0 dev: DRY destination node handling 2024-12-13 15:30:55 -05:00
KernelDeimos 6b6c295a87 dev: rewrite and move writeFile rename 2024-12-13 14:49:03 -05:00
KernelDeimos 298609c6e9 fix: bug in writeFile rename 2024-12-13 13:35:55 -05:00
KernelDeimos 96a5c3c213 dev: move and simplify writeFile trash and delete 2024-12-13 13:18:34 -05:00
KernelDeimos d23c33c377 dev: cleanup writeFile: copy, move, mkdir 2024-12-13 12:37:16 -05:00
KernelDeimos 4b3f71b25e dev: migrate listenerutil, remove duplicate 2024-12-13 10:20:31 -05:00
bestlaw66 05a7e28f55 Update README.zh.md
在国内有大部分用户都在使用宝塔面板管理服务器,因此增加使用宝塔面板部署的教程,可视化的部署方式可以帮助用户更加便捷的部署
2024-12-13 12:13:10 +08:00
jelveh c792f4a345 fix: remove unnecessary item_path definition in delete fs api 2024-12-12 18:07:50 -08:00
KernelDeimos 06aeae518b clean: miscellaneous cleanups 2024-12-12 16:42:16 -05:00
KernelDeimos 332939308e clean: remove test functions 2024-12-12 14:47:26 -05:00
KernelDeimos 168dbad295 dev: organize share sequence 2024-12-12 14:47:26 -05:00
KernelDeimos 69e9df1ae2 fix: add missing permissions 2024-12-12 14:46:25 -05:00
Nariman Jelveh b89cd9529d Merge pull request #1063 from charlottekatzmann/patch-1
Update da.js #875
2024-12-12 11:46:49 -08:00
Charlotte Katzmann 46365beb7b Update da.js #875 2024-12-12 20:36:19 +01:00
Nariman Jelveh 54076d9d7f Merge pull request #1060 from biocyberman/translation/danish
Finish Danish translation, resolve issue #875
2024-12-12 11:00:37 -08:00
Nariman Jelveh 0a18cbb19d Merge branch 'main' into translation/danish 2024-12-12 11:00:30 -08:00
Nariman Jelveh 1aaba0016a Merge pull request #1061 from MPiya/#875
#875 Complete the Danish (Dansk) translation of Puter
2024-12-12 10:58:56 -08:00
Nariman Jelveh a879c83369 Merge branch 'main' into #875 2024-12-12 10:58:47 -08:00
Nariman Jelveh 63c5aa2215 Merge pull request #1062 from lauritsbonde/laurits/danish-translation
add missing danish translations
2024-12-12 10:58:20 -08:00
lauritsbonde 5126571217 add missing danish translations 2024-12-12 19:48:34 +01:00
KernelDeimos 651076a39b doc: document permission scanning 2024-12-12 13:47:03 -05:00
Chris fb346807e7 Add Danish missing translation 2024-12-12 19:45:38 +01:00
Vang Le-Quy 78cf0f403f Finish Danish translation, resolve issue #875 2024-12-12 19:41:39 +01:00
KernelDeimos 4e47c8bf9d clean: cleanup utils directory 2024-12-12 13:02:22 -05:00
KernelDeimos d5ecac4d0f dev: update deprecated use of __proto__ 2024-12-12 12:23:58 -05:00
KernelDeimos 951fb32f57 dev: add another response to AIChatService 2024-12-12 10:51:08 -05:00
Nariman Jelveh ee85a6d5e2 Merge pull request #1055 from themermabrouk/feature/issue-#975/finish-French-translations
feature(issue #975) finish French translations
2024-12-12 07:42:58 -08:00
Nariman Jelveh 713226081e Merge branch 'main' into feature/issue-#975/finish-French-translations 2024-12-12 07:42:45 -08:00
Nariman Jelveh 07d8e3b229 Merge pull request #1058 from hexsproductions/update-fr-translation
Add missing French translations (#975)
2024-12-12 07:38:32 -08:00
hexsproductions 52d077cc19 Add missing French translations (#975) 2024-12-12 15:59:55 +01:00
KernelDeimos d4ca9d438c dev: fix issue with prompt validation 2024-12-12 09:51:43 -05:00
Nariman Jelveh 5f37f7f48f Merge pull request #1047 from dev-wonny/#966-korean-translation-update
Complete Korean translation for ko.js (#966)
2024-12-12 06:39:34 -08:00
Nariman Jelveh 4a6dfc31e8 Merge pull request #1057 from HeyPuter/revert-1043-patch-1
Revert "Resolved Issue #965: Completed Kurdish Translations"
2024-12-11 18:47:44 -08:00
Nariman Jelveh 1b71184b13 Revert "Resolved Issue #965: Completed Kurdish Translations" 2024-12-11 18:47:34 -08:00
Nariman Jelveh 3203159f59 Merge pull request #1043 from Abdulbasit0123/patch-1
Resolved Issue #965: Completed Kurdish Translations
2024-12-11 18:47:30 -08:00
Nariman Jelveh 3bd32bb13b Merge branch 'main' into patch-1 2024-12-11 18:46:52 -08:00
jelveh 51ad4e12d4 Update index.html 2024-12-11 18:40:38 -08:00
Nariman Jelveh d570c2fbff Merge pull request #1056 from alizargit/main
Update dev-center.js to improve UX
2024-12-11 18:39:45 -08:00
Ali Z 5412408538 Update dev-center.js 2024-12-11 18:36:13 -08:00
KernelDeimos 6ca701139a fix: logic from previous commit 2024-12-11 20:55:49 -05:00
KernelDeimos c6e814daa8 fix: add fallback moderation in case openai goes down 2024-12-11 20:51:23 -05:00
themer 0efac5c77e feature(issue #975) finish French translations 2024-12-12 00:43:55 +01:00
Nariman Jelveh 97a1616305 Merge pull request #1054 from landof/patch-1
Fix languages orders in translations.js
2024-12-11 15:16:36 -08:00
landof 56a5671488 Fix languages orders in translations.js 2024-12-11 15:06:33 -08:00
KernelDeimos 4ff5bec40e clean: remove spans on deprecated calls 2024-12-11 16:52:14 -05:00
KernelDeimos cbe15a42bd dev: update TelemetryService 2024-12-11 16:36:20 -05:00
KernelDeimos 08dbef7b8c dev: add a feature to hook tracing into context 2024-12-11 16:02:45 -05:00
KernelDeimos c2b094a351 dev: return otel/jaegar tracing to working state 2024-12-11 15:25:55 -05:00
KernelDeimos dac5458b2e dev: migrate DatabaseFSEntryFetcher to puterfs module 2024-12-11 13:35:37 -05:00
KernelDeimos 4e0ce06982 clean: remove unused caching mechanism 2024-12-11 13:35:37 -05:00
KernelDeimos df20cb8e6c clean: filesystem batch 2024-12-11 13:35:16 -05:00
Nariman Jelveh 04cc9c2e05 Merge branch 'main' into #966-korean-translation-update 2024-12-11 09:54:50 -08:00
Nariman Jelveh 658af1fff0 Update ko.js 2024-12-11 09:45:37 -08:00
Nariman Jelveh fb0a091506 Merge pull request #1053 from HeyPuter/revert-1051-fix/stuck-new-app-loading-983
Revert "fix: resolve issue #983 - Stuck on Creating new app loading s…
2024-12-11 09:45:04 -08:00
Nariman Jelveh 51ab24314e Revert "fix: resolve issue #983 - Stuck on Creating new app loading screen" 2024-12-11 09:44:31 -08:00
Nariman Jelveh f800cf2dc9 Merge pull request #1051 from mariatouil/fix/stuck-new-app-loading-983
fix: resolve issue #983 - Stuck on Creating new app loading screen
2024-12-11 09:44:27 -08:00
Nariman Jelveh 040a6a7513 Merge pull request #1052 from vasarmilan/feature-hun-translation
Add Hungarian translations
2024-12-11 09:43:42 -08:00
Nariman Jelveh 653f493d27 Merge branch 'main' into feature-hun-translation 2024-12-11 09:43:30 -08:00
Nariman Jelveh 5422a239e4 Merge pull request #1048 from phellinger/hungarian-translation-update-#972
Complete Hungarian translation of Puter #972
2024-12-11 09:41:30 -08:00
vasarmilan e148bcb909 Add Hungarian translations 2024-12-11 18:00:57 +01:00
KernelDeimos ed48a16ced clean: remove newly-unused imports 2024-12-11 12:00:42 -05:00
KernelDeimos 4d9cc9bd83 fix: permission strings for ES services 2024-12-11 11:25:29 -05:00
Nariman Jelveh 2cf959dc2c Merge pull request #1046 from nicola-laura/korean-translation
Korean translation improvement (#966)
2024-12-11 08:24:07 -08:00
Nariman Jelveh 74d95aa366 Update ko.js 2024-12-11 08:21:47 -08:00
Nariman Jelveh 530b7ac647 Merge pull request #1044 from ismailix/965
kurdish translate ismailix
2024-12-11 08:20:43 -08:00
Nariman Jelveh 13518d0ff6 Update ku.js 2024-12-11 08:20:24 -08:00
maria touilzak c75c9d0383 fix: resolve issue #983 - Stuck on Creating new app loading screen 2024-12-11 16:56:21 +01:00
maria touilzak 96c7576607 Fix: drag-and-drop issue: files not appearing on desktop automatically 2024-12-11 15:34:05 +01:00
phellinger 7d2787d26b feat: complete Hungarian translation of Puter #972 2024-12-11 13:08:01 +01:00
“devwonny” ca3d669a10 Complete Korean translation for ko.js (#966)
Complete Korean translation for ko.js (#966)
https://github.com/HeyPuter/puter/issues/966
2024-12-11 19:44:48 +09:00
Nicola fefc4ac304 added missing translations and suggested improvements to existing translations (#966) 2024-12-11 17:56:14 +09:00
Nariman Jelveh 5889e4c25c Merge pull request #1045 from rdsingh120/main
Added Spanish translations for all the missing translations.
2024-12-10 19:07:21 -08:00
Ripudaman Singh 4b454a8706 Added Spanish translations for all the missing translations. 2024-12-10 20:38:47 -05:00
jelveh df34ee048a fix bug with 'Show All' in taskbar items 2024-12-10 17:04:33 -08:00
KernelDeimos 1dc2a6af81 dev: simplify get-launch-apps 2024-12-10 17:10:53 -05:00
KernelDeimos 1beda5b23d clean: cleanup filesystem routes 2024-12-10 16:40:38 -05:00
KernelDeimos cd7755da6b clean: misc cleanups 2024-12-10 15:58:22 -05:00
KernelDeimos ff62d9009e refactor: allow service-specific API errors to be registered 2024-12-10 15:23:54 -05:00
igorunmek af3b6fd152 kurdish translate upwork ismailix 2024-12-10 22:41:27 +03:00
KernelDeimos 8557c54527 clean: cleanup log outputs 2024-12-10 14:19:01 -05:00
KernelDeimos 1b578019f9 fix: provide actor context to ws event 2024-12-10 14:06:14 -05:00
KernelDeimos 96008233ba fix: context error in user connected event 2024-12-10 13:45:31 -05:00
KernelDeimos 6bb9437268 clean: remove legacy driver support 2024-12-10 13:18:42 -05:00
KernelDeimos b9d53b77a2 refactor: migrate kv driver invocation 2024-12-10 12:54:13 -05:00
KernelDeimos 2fcc257ae1 refactor: migrate entity storage driver invocation 2024-12-10 11:40:49 -05:00
KernelDeimos 193833f4f9 clean: remove legacy driver module 2024-12-10 10:38:40 -05:00
Ken 9965f219d8 refactor: adjust max_tokens for specific models
fix: fix issue when there is an assistant role
2024-12-10 09:17:16 -05:00
KernelDeimos 01395f302e fix: signup 500 for temp user 2024-12-10 09:09:25 -05:00
Nariman Jelveh 192958e88b Merge pull request #1042 from saud-saeed/main
Update Swedish translations in sv.js
2024-12-10 05:44:27 -08:00
Nariman Jelveh 62f4318914 Update sv.js 2024-12-10 05:44:14 -08:00
Abdulbasit 9d97ee849d Resolved issue #965, completed Kurdish translations
I completed the translation for Kurdish and fixed some typos of the already translated phrases and sentences.
2024-12-10 13:42:38 +03:00
Saud Saeed 84c1efbf5f Update Swedish translations in sv.js
fix: Resolve issue #960 by adding missing Swedish (Svenska) translations
2024-12-10 11:21:18 +01:00
Nariman Jelveh 56f57e4ab9 Merge pull request #1039 from Agastya18/feat/add-Escape-key
feat: add Escape key functionality to UIPrompt for closing the prompt
2024-12-09 23:08:54 -08:00
Nariman Jelveh 13c34211ed Merge pull request #1040 from twuttiwat/patch-1
Add missing Thai translations in th.js
2024-12-09 22:04:28 -08:00
Nariman Jelveh cf845d3ac1 Update th.js 2024-12-09 22:03:45 -08:00
Teerawat Wuttiwat 529c5376e4 Add missing Thai translations in th.js 2024-12-10 11:58:01 +07:00
agastya gaur e1b6c83813 feat: add Escape key functionality to UIPrompt for closing the prompt 2024-12-10 08:26:55 +05:30
Nariman Jelveh dd43c0acfa Merge pull request #1038 from Exclusiveideas/igbo-translation-updates
fixed "Complete the Igbo translation of Puter #969" issue
2024-12-09 18:43:42 -08:00
Nariman Jelveh bc30012087 Merge branch 'main' into igbo-translation-updates 2024-12-09 18:43:31 -08:00
Exclusiveideas cb7d4eaaf9 fixed "Complete the Igbo translation of Puter #969" issue 2024-12-10 03:31:48 +01:00
jelveh f2e2473a7d Create TRADEMARK.md 2024-12-09 18:24:51 -08:00
jelveh 6eec8a821b Merge branch 'main' of https://github.com/heyputer/puter 2024-12-09 18:19:30 -08:00
jelveh 7aa056f1e3 remove Missing translations comment from ig.js 2024-12-09 16:50:52 -08:00
Nariman Jelveh cd472f30e7 Merge pull request #1036 from HeyPuter/revert-1035-main
Revert "Update missing translations for Igbo"
2024-12-09 16:45:03 -08:00
Nariman Jelveh b04b09042e Revert "Update missing translations for Igbo" 2024-12-09 16:44:23 -08:00
Nariman Jelveh 6dfa795423 Merge pull request #1035 from Nathaniyell/main
Update missing translations for Igbo
2024-12-09 16:44:00 -08:00
Nariman Jelveh 49d7ad8eaa Update ig.js 2024-12-09 16:41:37 -08:00
Nathaniel Essien 803377868c Merge branch 'main' into main 2024-12-10 01:38:57 +01:00
Nariman Jelveh 444950ef8d Merge pull request #1034 from Victor-Evogor/main
Complete Igbo translations for missing keys (#969)
2024-12-09 16:37:17 -08:00
Nathaniyell 6f4d57a3c6 fix: correct Igbo translation for "Free" in billing terms 2024-12-10 01:36:05 +01:00
Nathaniyell f0f19e727e feat: add missing Igbo translations for billing-related terms 2024-12-10 01:35:24 +01:00
Victor Evogor 6b15eaed1c Complete Igbo translations for missing keys (#969) 2024-12-10 01:16:57 +01:00
KernelDeimos acf8ae302e fix: bad import for TeePromise 2024-12-09 18:03:45 -05:00
KernelDeimos 7acb096add fix: sorting bug in AIChatService 2024-12-09 16:31:53 -05:00
KernelDeimos 0f2641b88f clean: remove some unused code/comments 2024-12-09 16:31:53 -05:00
Nguyễn Tuấn Anh b2ea8a3888 feat: set max token to 8096 2024-12-09 16:31:36 -05:00
KernelDeimos 6c0f04706d move: MountpointService 2024-12-09 16:03:18 -05:00
KernelDeimos 4917848c60 refactor: move SizeService and DRY capacity usage
This commit also fixes a but that was discovered in calculating the size
of files during a copy operation.
2024-12-09 15:50:44 -05:00
KernelDeimos db00f0ae67 dev: cleanup filesystem utilities 2024-12-09 14:42:14 -05:00
KernelDeimos 3f5bc7163f dev: cleanup config.js 2024-12-09 14:08:46 -05:00
KernelDeimos 537d0d47ec dev: cleanup RuntimeEnvironment.js 2024-12-09 13:49:40 -05:00
KernelDeimos 7839d52925 dev: address TODO comment in Kernel.js 2024-12-09 13:14:10 -05:00
KernelDeimos c36dd1b3d3 refactor: extension loading 2024-12-09 12:05:23 -05:00
KernelDeimos 070937c7e6 clean: remove some unused vars 2024-12-09 12:05:23 -05:00
KernelDeimos 7af8afb053 refactor: address TODO; de-couple some services from FilesystemService 2024-12-09 12:05:11 -05:00
Nariman Jelveh bec3a28d33 Merge pull request #1028 from loismbferraz/issue-963-complete-portuguese-translation
portuguese translations for #963 issue added
2024-12-09 08:41:22 -08:00
loismbferraz c614b8a789 portuguese translations for #963 issue added 2024-12-09 16:23:38 +00:00
Nariman Jelveh 4c3a053a0a Merge pull request #1026 from nathnapa88/patch-1
Update th.js
2024-12-09 07:58:49 -08:00
nathnapa88 0a746f1e32 Update th.js 2024-12-09 15:42:10 +00:00
Nariman Jelveh d075718bf2 Merge pull request #1025 from hoursing/main
feat: Complete the Vietnamese translation of Puter #954
2024-12-09 06:37:07 -08:00
Nariman Jelveh c7e0ce6dd1 Merge branch 'main' into main 2024-12-09 06:36:55 -08:00
Nariman Jelveh 333f0ea42f Merge pull request #1023 from lephuongnam22/main
(#954) Add Vietnamese translations for billing-related terms
2024-12-09 06:21:16 -08:00
Nariman Jelveh 4643e8a523 Merge branch 'main' into main 2024-12-09 06:21:07 -08:00
Nariman Jelveh 25d3bac454 Merge pull request #1021 from vulct174/main
feat: add Vietnamese translations for billing in vi.js
2024-12-09 06:18:25 -08:00
Nariman Jelveh 0197e1489c Merge branch 'main' into main 2024-12-09 06:18:16 -08:00
Nariman Jelveh a1858fb495 Merge pull request #1020 from lvluu/feature/issue-954
feat: (#954) Add Vietnamese translations for billing-related terms
2024-12-09 06:14:06 -08:00
Nariman Jelveh 6890935d01 Update vi.js 2024-12-09 06:13:43 -08:00
hoursing 56489c33f6 feat: Complete the Vietnamese translation of Puter #954 2024-12-09 17:33:28 +07:00
lamia c840bc8161 feat: Complete the French (Français) translation of Puter #975 2024-12-09 09:49:41 +01:00
Nam Le ba876745b3 Update translation 2024-12-09 19:04:58 +11:00
Nam Le bbd0183320 Update text translation 2024-12-09 18:59:16 +11:00
Nariman Jelveh 4477f8f6e8 Merge pull request #1022 from akuumaa/issue-952
feat: Complete the German (Deutsch) translation of Puter #952
2024-12-08 23:20:20 -08:00
Nam Le 2dfc58fc2d (#954) Add Vietnamese translations for billing-related terms 2024-12-09 18:13:15 +11:00
akuumaa 05fef6749e feat: Complete the German (Deutsch) translation of Puter 2024-12-09 07:17:31 +01:00
lvluu 267a55aae5 feat: (#954) Add Vietnamese translations for billing-related terms 2024-12-09 12:59:38 +07:00
VuLCT 3e26dbe6a0 feat: add vietnamese translations for billing in vi.js 2024-12-09 12:42:18 +07:00
Nariman Jelveh d98b6e385c Merge pull request #1010 from cprogrammer1209/PUTER-ta-dec8
Added to new Tamil Words to the ta.js file.
2024-12-08 20:14:46 -08:00
Nariman Jelveh 9104ac0bd9 Merge pull request #1019 from Elisassa/update-zhTW-translation
Added Traditional Chinese translations
2024-12-08 17:27:44 -08:00
Nariman Jelveh fc09a26277 Update zhtw.js 2024-12-08 17:27:29 -08:00
Elisassa 35f2a4f594 Added Traditional Chinese translations 2024-12-08 19:35:55 -05:00
Nariman Jelveh a16fd36ad3 Merge pull request #1018 from dmytro-nesteruk/main
tweak: update ua translations;
2024-12-08 15:50:55 -08:00
Nariman Jelveh 3ad7c8437f Merge pull request #1017 from RamiIbrahim2002/arabic-translation-issue-948
Update Arabic translations for issue #948
2024-12-08 15:49:23 -08:00
Nariman Jelveh 80e4d040c7 Merge branch 'main' into arabic-translation-issue-948 2024-12-08 15:49:01 -08:00
Nariman Jelveh 89819204c1 Merge pull request #1016 from hasanayoub/fix-ar-translation_issue_948
Completed Arabic translations for issue #948
2024-12-08 15:46:03 -08:00
jelveh 320278dfdf Update ar.js 2024-12-08 15:45:19 -08:00
Nariman Jelveh 183b8105f9 Update ar.js 2024-12-08 15:19:52 -08:00
Dmytro Nesteruk 118605f054 tweak: updated ua translations; 2024-12-09 00:34:55 +02:00
Dmytro Nesteruk 208a38603d tweak: update ua translations; 2024-12-08 23:17:35 +02:00
hasanayoub 4c1b78f73b Completed Arabic translations for issue #948 2024-12-09 00:11:59 +03:00
RamiIbrahim2002 3f0f3dab51 Update Arabic translations for issue #948 2024-12-08 22:07:51 +01:00
Nariman Jelveh 974feeade3 Merge pull request #1015 from nafisa45/main
Add Bengali translations for billing module strings
2024-12-08 13:00:09 -08:00
Nariman Jelveh 05ecd2547b Update bn.js 2024-12-08 12:59:23 -08:00
nafisa45 de6e5ddb25 I have updated the undefined part of the translation with the intact %strong% and (%%) 2024-12-09 01:32:19 -05:00
Nariman Jelveh c4931c30ee Merge pull request #1014 from gwyneblaidd/main
Complete the Ukrainian (Українська) translation of Puter · Issue #956 · HeyPuter/puter
2024-12-08 12:39:03 -08:00
jelveh ceaf6cb24a Update ua.js 2024-12-08 12:38:38 -08:00
gwyneblaidd 2bbf11f91b Update ua.js 2024-12-08 22:31:59 +02:00
gwyneblaidd 255f102d16 Update ua.js 2024-12-08 22:24:18 +02:00
Nariman Jelveh e7f3ac6fa8 Merge pull request #1013 from CriDM/add-italian-translations
Added missing Italian translations (#968)
2024-12-08 11:49:59 -08:00
Nariman Jelveh badd4c218e Merge branch 'main' into add-italian-translations 2024-12-08 11:48:32 -08:00
Nariman Jelveh 7e1766bbdc Merge pull request #1012 from danielpetrica/patch-2
Update it.js
2024-12-08 11:47:46 -08:00
Nariman Jelveh 77c7d347a4 Update it.js 2024-12-08 11:47:15 -08:00
Daniel, Petrica Andrei-Daniel 5d8854f628 Update it.js 2024-12-08 20:39:36 +01:00
CriDM c6fa98b3b7 Added missing Italian translations (#968) 2024-12-08 20:35:56 +01:00
Nariman Jelveh 996c8097b7 Merge pull request #1011 from HeyPuter/revert-1009-warning_dialog
Revert "Created test cases for issue #878 "
2024-12-08 11:32:04 -08:00
Nariman Jelveh 40ea2a3f02 Revert "Created test cases for issue #878 " 2024-12-08 11:31:47 -08:00
Nariman Jelveh 575b4bd34c Merge pull request #1009 from LeeMEow23/warning_dialog
Created test cases for issue #878
2024-12-08 11:31:42 -08:00
Nariman Jelveh c8894c7d4c Merge branch 'main' into warning_dialog 2024-12-08 11:29:52 -08:00
root 019a8c1d93 Added to new Tamil Words 2024-12-08 23:30:21 +05:30
e5z26 2ca1f71595 removed jsdom in test file
removed because wasn't being used
2024-12-07 19:09:22 -05:00
Nariman Jelveh 4c5f427ac2 Merge pull request #1008 from HeyPuter/revert-1007-patch-1
Revert "Update id.js"
2024-12-07 11:46:15 -08:00
Nariman Jelveh e6a171e8f1 Revert "Update id.js" 2024-12-07 11:46:05 -08:00
Nariman Jelveh 777ac3a8ca Merge pull request #1007 from zefta27/patch-1
Update id.js
2024-12-07 11:45:36 -08:00
Nariman Jelveh f97394ded1 Merge branch 'main' into patch-1 2024-12-07 11:45:17 -08:00
Nariman Jelveh 0b71e2a723 Merge pull request #1004 from wildanhkm/wildanhkm/feat/id-translations
update id translations
2024-12-07 11:21:23 -08:00
Nariman Jelveh 8fc570d076 Merge branch 'main' into wildanhkm/feat/id-translations 2024-12-07 11:21:15 -08:00
Nariman Jelveh e030cd3d03 Merge pull request #1006 from arrafi-ahmed/issue-970
Fix issue #970
2024-12-07 10:34:01 -08:00
Nariman Jelveh e9ac20b8b0 Update id.js 2024-12-07 10:30:28 -08:00
Nariman Jelveh aa82e06e14 Merge pull request #1005 from arthur-adriansens/main
Close apps by clicking on icons (issue #944) + awesome animations!
2024-12-07 10:27:11 -08:00
jelveh 383b4841ae fix the issue with windows losing focus right after they're opened 2024-12-07 10:16:25 -08:00
Zefta Adetya b3426b52d1 Update id.js
Replacing undefined text
2024-12-08 00:37:18 +07:00
raf 34ab6dbdff Fix issue #970: [updated undefined values for bahasa translation] 2024-12-07 23:47:58 +07:00
wildanhkm 1d6bc54ae6 update id translations 2024-12-07 23:20:47 +07:00
Arthur 6a2f5f0eee Added sattisfying taskbar icon animation 2024-12-07 16:20:22 +00:00
Arthur 90b7e449b7 Added "Toggling apps to minimize once it clicked" #944 feature 2024-12-07 15:46:01 +00:00
Nariman Jelveh 8ea6ac1b48 Merge pull request #1003 from sumi1239/feature/kr-translations
feat: added a few Korean translatations
2024-12-06 17:52:33 -08:00
William Shiozawa b23e800f4e feat: added a few Korean translatations 2024-12-06 17:36:21 -08:00
jelveh 71bb8ba881 remove "Missing translations" comment from Hebrew i18n file. 2024-12-06 14:09:32 -08:00
KernelDeimos b34b8efea9 clean: remove some unused variables 2024-12-06 17:03:16 -05:00
KernelDeimos cb4bcba7ec clean: cleanup helpers.js 2024-12-06 17:03:16 -05:00
KernelDeimos 7db3be5716 clean: remove unused variables in filesystem 2024-12-06 17:03:16 -05:00
Nariman Jelveh f93a754273 Merge pull request #1002 from Tristramit/Tristramit-patch-1
Update he.js
2024-12-06 14:02:50 -08:00
KernelDeimos c566d48433 clean: fix errors found by find-unused-exports 2024-12-06 15:40:59 -05:00
Amos Weislib 197be1c0bc Update he.js
Few corrections
2024-12-06 21:36:58 +01:00
KernelDeimos 7232406680 clean: remove unused imports from phoenix 2024-12-06 15:28:07 -05:00
jelveh 87f4f3d2dd fix unmatched double quote 2024-12-06 12:23:52 -08:00
KernelDeimos c87db23faa refactor: combine parsely and strataparse into @heyputer/parsers 2024-12-06 15:08:23 -05:00
KernelDeimos 62a010b1b2 doc: clarify the distinction between CoreModule and Core2Module 2024-12-06 13:05:03 -05:00
KernelDeimos 73f738c9d9 doc: add more extensions documentation 2024-12-06 13:05:03 -05:00
KernelDeimos 1679648780 doc: document the test kernel 2024-12-06 13:05:03 -05:00
KernelDeimos 1e0fb1c3c5 doc: document kernel behavior 2024-12-06 13:05:03 -05:00
KernelDeimos 9aeecb650a doc: generate and edit comments for tools 2024-12-06 13:05:03 -05:00
Amos Weislib 299a88103e Update he.js
referencing issue
#974
2024-12-06 19:05:00 +01:00
Nariman Jelveh c6455d53e4 Merge pull request #1001 from HeorhiiPavlovskyi/Issue-961
Issue #961, filled missing translations, Updating ru.js
2024-12-06 09:59:44 -08:00
Nariman Jelveh 0935c56842 Update ru.js 2024-12-06 09:58:01 -08:00
unknown 9d91649ca1 Update ru.js 2024-12-06 19:48:47 +02:00
KernelDeimos 545e7db5bd fix: test issues from contextlink removal
Apparently there were two things:
- had to remove contextlink from the test command (that was expected)
- can't import libs from putility in the test environment. The error
  produced for this doesn't really explain why.
2024-12-06 12:09:23 -05:00
Nariman Jelveh fad2c944ab Merge pull request #999 from JJooaa/finnish-translations
Fixes issue [#976]: Add missing Finnish translations.
2024-12-06 08:59:52 -08:00
Nariman Jelveh 741d8f0bb4 Update fi.js 2024-12-06 08:46:41 -08:00
KernelDeimos 2c24fe5532 doc: document tools directory (README.md) 2024-12-06 11:39:07 -05:00
KernelDeimos d1e8d51173 clean: remove contextlink
Updates references in phoenix shell to use context from putility.
2024-12-06 11:17:14 -05:00
Justin Oeni 540132cc71 Added two files to test hasGitDirectory and showGitWarningDialog 2024-12-06 10:42:44 -05:00
KernelDeimos 72c496df4b clean: remove early typescript trial 2024-12-06 10:38:55 -05:00
JJooaa 6abbf8440b update: add missing finnish translations 2024-12-06 16:55:05 +08:00
Nariman Jelveh 7f37c42219 Merge pull request #997 from bertsrl/patch-1
Update ro.js
2024-12-05 23:53:24 -08:00
Nariman Jelveh 50a2f3d275 Merge pull request #998 from smikayel/improvement/Armenian_localozation
add translation for missing sentancies
2024-12-05 23:46:26 -08:00
Nariman Jelveh e2fbe80cce Merge pull request #995 from kirney23/main
japanese translations
2024-12-05 23:44:41 -08:00
Nariman Jelveh 1e573b654a Merge branch 'main' into main 2024-12-05 23:44:23 -08:00
Nariman Jelveh aa00830168 Merge pull request #996 from hutajoullach/main
Japanese translation issue number 967
2024-12-05 23:40:19 -08:00
smikayel d6e20dcb20 add translation for missing sentancies 2024-12-06 11:39:09 +04:00
Berty 76308479c6 Update ro.js
Updated the romanian translations.

I kept the terms "Professional" and "Business" in English as they are commonly used this way in Romanian in IT services context

I adapted the forms of address to second person singular ("tu") instead of formal ("dumneavoastră") to maintain a friendly and modern tone

I maintained consistency with existing translations in the file
Placeholders (%strong%, %%) were kept in grammatically correct positions for Romanian language
2024-12-06 09:36:50 +02:00
HutaJoullach 0ed5aaed2c japanese-translation-issue-number-967 2024-12-06 16:24:14 +09:00
kirney23 b3ce0e93fb Update ja.js 2024-12-06 11:38:53 +09:00
Nariman Jelveh 984b5d617d Merge pull request #994 from samueldev900/samueldev900_brazillian_translation
feat: add brazillian translations for billing-related terms in br.js
2024-12-05 15:43:32 -08:00
Nariman Jelveh b41e8b09ad Update br.js 2024-12-05 15:40:32 -08:00
Samuel Oliveira fdfc90a931 feat: add brazillian translations for billing-related terms in br.js (revision) 2024-12-05 20:29:37 -03:00
Samuel Oliveira e66df14862 feat: add brazillian translations for billing-related terms in br.js 2024-12-05 20:18:41 -03:00
KernelDeimos e301247bfc dev: add an example module and service 2024-12-05 16:58:15 -05:00
KernelDeimos 82457fbc9f doc: document smol (SmolUtil) lib 2024-12-05 16:16:44 -05:00
KernelDeimos 7de23ce68d move: SmolUtil and ServerHealthService 2024-12-05 16:16:44 -05:00
Nariman Jelveh f9c6f82440 Merge pull request #993 from paulinek13/polish-translation
sync(i18n): add Polish translations for billing-related terms
2024-12-05 12:55:17 -08:00
Paulina Kalicka 15f9aded26 sync(i18n): add Polish translations for billing-related terms 2024-12-05 21:18:20 +01:00
KernelDeimos 09b0d744d5 clean: remove redundant promise.js 2024-12-05 15:08:33 -05:00
KernelDeimos 86a9c959e0 doc: document commonly-used putility libraries 2024-12-05 14:36:34 -05:00
KernelDeimos 58dea19cd9 move strutil and time.js to putility 2024-12-05 14:00:21 -05:00
KernelDeimos e279dc6e5f fix: add missing import 2024-12-05 13:56:08 -05:00
KernelDeimos 7424fd888d doc: update and generate docs 2024-12-05 13:29:10 -05:00
KernelDeimos 3df5f649a4 dev: migrate ExpectationService and PagerService 2024-12-05 13:20:06 -05:00
KernelDeimos a2072c5fac doc: move/clean ErrorService
Some documentation comments were missing or inaccurate so these were
also edited after moving.
2024-12-05 12:10:07 -05:00
KernelDeimos e5a7d1c1bb doc: edit/generate CoreModule2 docs 2024-12-05 12:10:07 -05:00
Nariman Jelveh f1ece26418 Merge pull request #990 from ICODER32/patch-1
Update ur.js
2024-12-05 08:59:03 -08:00
Nariman Jelveh f17a53018b Update ur.js 2024-12-05 08:57:31 -08:00
Nariman Jelveh a6b86c5947 Merge pull request #989 from arthur-adriansens/dutch
Added new Dutch translation
2024-12-05 08:56:16 -08:00
KernelDeimos 036016b20b dev: move/clean AlarmService and related utils 2024-12-05 11:41:41 -05:00
M Ibtisam Anwar d9a08de959 Update ur.js
Updated undefined urdu translations
2024-12-05 21:09:21 +05:00
Arthur f1d9ac5208 changed to single quotes 2024-12-05 16:41:38 +01:00
Arthur 18784b2677 completed Dutch translation #979 2024-12-05 16:33:03 +01:00
KernelDeimos 13a895b76b fix: fake_chat default model and usage errors 2024-12-05 09:34:51 -05:00
KernelDeimos 1e2f9df110 doc: remove comment error 2024-12-05 09:14:30 -05:00
Nariman Jelveh 9ddaab3010 Merge pull request #981 from rowin-C/filetype-association
feat: added tagify in Filetype-Association input in dev center
2024-12-04 18:13:46 -08:00
KernelDeimos a1c2226561 fix: update test kernel 2024-12-04 20:40:42 -05:00
Nariman Jelveh 223802f631 Merge pull request #986 from githubalexliu/translate_zh
Translated to Chinese
2024-12-04 16:53:10 -08:00
Nariman Jelveh 4653273d9a Update zh.js 2024-12-04 16:51:29 -08:00
githubalexliu c1aa637005 Translated to Chinese 2024-12-04 19:26:32 -05:00
jelveh 591cf0f45e tweak for fluid ux 2024-12-04 16:22:06 -08:00
jelveh 12ca609046 invalidate user cache when hitting /get-dev-profile 2024-12-04 15:13:54 -08:00
KernelDeimos 169c1aa3a7 doc: generate puterai docs and is a docgen bug 2024-12-04 16:58:45 -05:00
KernelDeimos 8848055f1b doc: update CONTRIBUTING.md 2024-12-04 16:33:45 -05:00
KernelDeimos 9992252083 doc: add file structure image 2024-12-04 16:32:30 -05:00
KernelDeimos 7eb5e59d94 dev: move some utils, LogService, to new module 2024-12-04 14:45:42 -05:00
KernelDeimos 5c3a65060d dev: include library functions in module docgen 2024-12-04 14:42:22 -05:00
KernelDeimos 5fa0a0263d dev: cleanup docgen and add method logging 2024-12-04 14:42:22 -05:00
KernelDeimos 0b36e72c80 doc: re-comment LogService 2024-12-04 14:42:22 -05:00
KernelDeimos 2453baa234 dev: make a module where utilities will go 2024-12-04 14:42:22 -05:00
Nariman Jelveh 5e7ea5f3b0 Merge pull request #985 from Agastya18/farsi-translation
Translate billing-related strings to Persian in fa.js
2024-12-04 10:20:35 -08:00
Nariman Jelveh a99ee51b00 Update fa.js 2024-12-04 10:19:09 -08:00
agastya gaur e395571256 Translate billing-related strings to Persian in fa.js 2024-12-04 22:32:45 +05:30
KernelDeimos 9e5429b9ab dev: improve module docgen
- fixes some bugs
- adds list of relative requires
2024-12-04 10:43:49 -05:00
jelveh b2dae896e6 expand support for more filestypes 2024-12-04 07:17:06 -08:00
Nariman Jelveh c0257c482f Merge pull request #982 from rowin-C/hindi-translation
tweak: added missing hindi translation
2024-12-04 07:00:23 -08:00
Nariman Jelveh cc7683a7fe Update hi.js 2024-12-04 06:59:59 -08:00
Nariman Jelveh b6e4f518fd Merge pull request #984 from ulaski/add-missing-turkish-translations
Add missing turkish translations
2024-12-04 06:53:04 -08:00
Nariman Jelveh 8cfefebfb6 Update tr.js 2024-12-04 06:52:36 -08:00
Ulas Kilicaslan e2f603d792 Add missing turkish translations 2024-12-04 15:12:25 +03:00
ron 4f82658d94 tweak: added missing hindi translation 2024-12-04 14:26:04 +05:30
ron 0cd1f151b5 feat: added tagify in Filetype-Association input in dev center 2024-12-04 12:35:36 +05:30
Nariman Jelveh 70c2fd6ee5 Merge pull request #980 from LeeMEow23/warning_dialog
Added the warning dialog
2024-12-03 19:17:32 -08:00
jelveh 59ac89db85 handle the return value of skipWarning 2024-12-03 19:10:14 -08:00
jelveh b4938659d1 disable copy/paste from local environment.
It never worked and has ruined the experience with regular copy/paste on Puter
2024-12-03 18:58:22 -08:00
Your Name 5302d3a62e Added the warning dialog
If the system detects any sensitive files, it will pop up the dialog showing the warning and provide the user with options of continuing or not.
2024-12-03 18:08:08 -05:00
jelveh 02e62f1625 wake up babe new i18n keys dropped 2024-12-03 14:18:19 -08:00
KernelDeimos c1bcd84715 chore: update package-lock.json 2024-12-03 17:07:37 -05:00
KernelDeimos 67ab8a1710 doc: first run of module documenter 2024-12-03 17:07:37 -05:00
KernelDeimos ac372204fa dev: move web service utilities 2024-12-03 17:07:37 -05:00
KernelDeimos 1922feab1e dev: add module documentation generator 2024-12-03 17:07:37 -05:00
Nariman Jelveh 46263cc1ad Update #DoesItRunPuter.md 2024-12-03 12:05:19 -08:00
KernelDeimos 10f6e5458e refactor: move WebServerService and socketio to module 2024-12-03 14:19:26 -05:00
KernelDeimos 3887ce05da dev: de-couple legacy mkdir and remove it
A legacy mkdir function was still being used by the
generate_system_fsentries function. However, it wasn't necessary because
we now associate fsentries by uuid, eliminating the requirement to
create the home directory separately from its subdirectories.

The old mkdir function was removed, and generate_system_fsentries was
moved to a new service called UserService, which is intended to
eventually hold all methods related creating, removing, and updating
users.
2024-12-03 13:04:12 -05:00
KernelDeimos 87db20de14 dev: add user.email-changed event 2024-12-03 10:05:24 -05:00
Nariman Jelveh e8d4408dca Revert "File association format (#946)" (#947)
This reverts commit f0d1de7e44.
2024-12-03 06:43:40 -08:00
Sauhbagya Prasad f0d1de7e44 File association format (#946)
* added validation function

* tagify implementation (incomplete)

* tagify implementation (completed)

* feat:implemented Tagify and filetype validation on filetype associaction in dev center

* tweak: removed unnessary tagify from dependency (its streamed from CDN)

* removed unnecessary tagify import
2024-12-03 06:43:16 -08:00
KernelDeimos 614f065e17 tweak: disable 4o-mini and mistral in comment writer 2024-12-02 12:18:46 -05:00
KernelDeimos b40d4534a7 fix: correct AI comment faults
Currently the AI comment writer is trusting the AI to write comment
markers. This means sometimes the syntax of a source file is broken by
comment generation. The instructions in the prompt were pretty clear, so
rather than --fixup'ing the previous commit I'm adding these changes
separately as an interesting case study of how different models behave.

Following this result, I am going to be removing mistral from the
comment writer. It is the most likely to misbehave.

I will also be removing gpt-4o-mini, which sometimes included source
lines despite the "no surrounding text" instruction.
2024-12-02 12:05:13 -05:00
KernelDeimos f75010b355 doc: (skip if using git bisect) ai comments 2024-12-02 11:47:47 -05:00
KernelDeimos 0a1be464d1 tweak: fix "all" option 2024-12-02 11:45:13 -05:00
KernelDeimos aadb261b29 dev: interactive prompt for file limit 2024-12-02 11:09:50 -05:00
KernelDeimos ac44aaf393 doc: make comment writer self-commented 2024-12-02 11:01:23 -05:00
KernelDeimos 7e4ae19aff dev: tweak comment writer to fix some problems 2024-12-02 11:00:50 -05:00
KernelDeimos 857718538b fix: update package-lock.json 2024-12-02 10:26:52 -05:00
KernelDeimos 7a8687cd2c doc: ai generated comments 2024-12-02 10:26:52 -05:00
KernelDeimos 2dfeeeda27 dev: update comment generator 2024-12-02 10:22:58 -05:00
Nariman Jelveh 67ee264239 Merge pull request #945 from MherFrangyan/patch-1
Update hy.js
2024-12-01 22:30:05 -08:00
jelveh 40dccb7741 Update en.js 2024-12-01 22:27:40 -08:00
Mher 1d217e2d59 Update hy.js
added translate
2024-12-02 10:24:09 +04:00
jelveh 6e6bd34463 Update en.js 2024-12-01 22:09:39 -08:00
jelveh 61f54369d7 add more i18n keys for billing 2024-12-01 19:20:25 -08:00
jelveh 9dda9c8dbf add more i18n keys 2024-12-01 19:13:51 -08:00
jelveh 349ae24636 add more keys for billing i18n 2024-12-01 18:51:47 -08:00
jelveh 5ced83195d add more i18n keys for billing 2024-12-01 16:45:53 -08:00
KernelDeimos ab4ba76433 fix: ignore two calls with undefined origin 2024-12-01 19:41:08 -05:00
KernelDeimos 340c7a821f fix: undefined APIOrigin 2024-12-01 19:29:47 -05:00
Nariman Jelveh ae42f6301f Merge pull request #938 from mithunmunsi/fix-issue-871
Fixes issue #871
2024-12-01 14:51:46 -08:00
Nariman Jelveh f0b5765cd7 Merge branch 'main' into fix-issue-871 2024-12-01 14:50:13 -08:00
KernelDeimos 3d2648e4ec chore: update package-lock.json 2024-12-01 15:29:35 -05:00
jelveh e056fafc50 clean up unsed imports 2024-12-01 10:10:30 -08:00
jelveh b874863986 Update signup.js 2024-11-30 23:01:04 -08:00
jelveh 88339c4044 add more billing keys for i18n 2024-11-30 17:40:54 -08:00
Nariman Jelveh a715cec1e6 Merge pull request #943 from enweazudaniel/patch-1
Update ig.js
2024-11-30 13:26:11 -08:00
enweazudaniel f672c28245 Update ig.js 2024-11-30 21:16:36 +01:00
jelveh badc654968 add i18n entries for billing and offerings 2024-11-30 11:13:01 -08:00
jelveh 67ca4ccf20 fix: add id to the setting menu item in user option menu 2024-11-29 19:40:54 -08:00
jelveh e662c782b7 fix: add an id to My Websites content menu item 2024-11-29 19:26:13 -08:00
Nariman Jelveh 73864c93cf Merge pull request #942 from Aliieeee/update-finnish-translations
Review Undefined Words and Correct it
2024-11-29 15:49:25 -08:00
Ali Hassan e9ba0833da Review Undefined Words and Correct it 2024-11-30 00:34:06 +02:00
jelveh 9b74a2e177 Update it.js 2024-11-29 14:22:56 -08:00
Nariman Jelveh 0223429e3b Merge pull request #940 from mkalevo/finnish-translation-#871
#871 added missing Finnish translations in fi.js
2024-11-29 13:48:11 -08:00
Nariman Jelveh c97d64da91 Update fi.js 2024-11-29 13:47:10 -08:00
Nariman Jelveh 489eba0423 Merge pull request #939 from danielpetrica/patch-1
Update it.js
2024-11-29 13:44:30 -08:00
Nariman Jelveh 5d5b20f40a Merge branch 'main' into patch-1 2024-11-29 13:44:01 -08:00
Nariman Jelveh ac21708c46 Merge pull request #937 from puyab91/italian_translation
PR_836_italian translation
2024-11-29 13:41:07 -08:00
Daniel, Petrica Andrei-Daniel 8c0c31cd09 Update it.js 2024-11-29 22:35:38 +01:00
mkalevo 60e87bdf92 #871 added missing Finnish translations in fi.js 2024-11-29 20:44:56 +00:00
Daniel, Petrica Andrei-Daniel cb70bb2b62 Update it.js 2024-11-29 21:28:56 +01:00
Mithun Munsi 57bdd39d7a Fixes issue #871 2024-11-29 22:25:06 +02:00
KernelDeimos 9f726b3e75 dev: add ai comment generator 2024-11-29 15:22:24 -05:00
puya.bahrani f2243859cf italian translation 2024-11-29 21:12:17 +01:00
Nariman Jelveh c3a042371c Merge pull request #936 from HeyPuter/revert-935-update-italian-translations
Revert "Update Italian translations"
2024-11-29 10:29:55 -08:00
Nariman Jelveh 4ac33675a3 Revert "Update Italian translations" 2024-11-29 10:29:46 -08:00
Nariman Jelveh f4e05440ae Merge pull request #935 from RidvanPlluzhina/update-italian-translations
Update Italian translations
2024-11-29 10:28:52 -08:00
RidvanPlluzhina d2bab8c7e8 Update Italian translations 2024-11-29 19:26:17 +01:00
Nariman Jelveh 1cfb3f5a75 Merge pull request #934 from ria147/ria147/update-dev-center
Enable Save button in Dev Center only when settings change and add a Reset button
2024-11-29 07:27:10 -08:00
jelveh 9ba0f2410c set correct base64 value for icon and socialImage 2024-11-29 07:16:59 -08:00
jelveh 92cd65261e also track icon and socialImage 2024-11-29 06:53:29 -08:00
ria147 3f1804eb2a dev: enable/disable reset button iff changes are made 2024-11-29 01:03:53 -05:00
ria147 e5788b6e47 dev: add functionality to reset edit button 2024-11-29 00:58:09 -05:00
ria147 55ffd801e0 feat: add reset edit changes button to dev-center 2024-11-29 00:47:40 -05:00
ria147 63a0053da8 feat: enable/disable save button in dev-center iff changes made 2024-11-29 00:30:57 -05:00
Nariman Jelveh 42378ecc4c Merge pull request #932 from kingflamez/polish-translation
Added missing Polish translation
2024-11-28 01:30:15 -08:00
kingflamez 09665a8d7b added missing polish translation 2024-11-28 08:16:34 +01:00
kingflamez bd35710548 added missing polish translation 2024-11-28 08:15:32 +01:00
jelveh 6bef127c24 Update de.js 2024-11-27 19:13:55 -08:00
Nariman Jelveh 061341db19 Merge pull request #929 from ahamiltonnn/German-translation
Added German translation
2024-11-27 19:12:09 -08:00
Austin Hamilton 80f3ffa5fa Added missing placeholders 2024-11-27 20:08:31 -07:00
jelveh c30f06b0f2 Update he.js 2024-11-27 19:08:05 -08:00
Nariman Jelveh 210e08b678 Merge pull request #930 from AmitMaymon/patch-1
Update he.js
2024-11-27 19:06:23 -08:00
AmitMaymon 8d846d3c37 Update he.js
Translated the unfinished hebrew translation
2024-11-28 05:01:16 +02:00
Austin Hamilton 73d7152652 Added german translation 2024-11-27 20:01:00 -07:00
jelveh 8dec78b090 fix: remove unnecessary integrity and crossorigin attributes in dev center when linking to jquery 2024-11-27 17:56:45 -08:00
KernelDeimos c5cd8cc219 dev: register PermissionUtil 2024-11-27 16:29:57 -05:00
KernelDeimos d014814c36 dev: allow services to register usage info 2024-11-27 16:19:50 -05:00
jelveh f94631949f tweak: return created timestamp of apps in query 2024-11-27 13:16:02 -08:00
KernelDeimos d2c1878ed4 dev: add usage check hook for ai services 2024-11-27 16:09:04 -05:00
Nariman Jelveh 237dc94377 Merge pull request #928 from Nathaniyell/main
Update Igbo translation of words #864
2024-11-27 11:41:56 -08:00
Nariman Jelveh 7c41396a62 Update ig.js 2024-11-27 11:40:21 -08:00
Nathaniyell 589ca4771e update ig.js 2024-11-27 20:31:22 +01:00
Nathaniyell 5ac5b8bd48 git add update translation of words 2024-11-27 20:27:26 +01:00
KernelDeimos 9ddc84e6cf dev: record token-based usages 2024-11-27 13:53:33 -05:00
Nariman Jelveh e96bae5b7d Merge pull request #927 from keimindev/feature/add-Korean
Issues #861-Add missing Korean translations
2024-11-27 06:19:52 -08:00
Nariman Jelveh f60834f043 Merge branch 'main' into feature/add-Korean 2024-11-27 06:19:29 -08:00
Nariman Jelveh a6e31ee7f5 Merge pull request #925 from Fumnanya92/Fumnanya92-update-igbo-translations
Update ig.js
2024-11-27 05:57:35 -08:00
Nariman Jelveh 1c4a66da44 Update ig.js 2024-11-27 05:53:36 -08:00
Nariman Jelveh 9397004b86 Merge pull request #926 from hpark75/korean-000861-ko-js-missing
KOREAN-000861: Missing translations done
2024-11-27 05:43:35 -08:00
Nariman Jelveh d7f31e91e1 Merge branch 'main' into korean-000861-ko-js-missing 2024-11-27 05:43:25 -08:00
Nariman Jelveh e9888c12ac Merge pull request #922 from anapimolodec/861-korean
added Korean translations
2024-11-27 05:40:43 -08:00
Nariman Jelveh 27f65e54c8 Update ko.js 2024-11-27 05:40:07 -08:00
keimindev 55e9fabf35 Add missing Korean translations 2024-11-27 19:05:58 +09:00
Hee b8e358b658 KOREAN-000861: Missing translations done 2024-11-27 06:58:16 -03:00
Fumnanya92 da3251d2cc Update ig.js
Complete missing Igbo translations in src/gui/src/i18n/translations/ig.js

- Translated all missing keys in the Igbo localization file.
- Ensured cultural appropriateness and accurate representation of English text.
- Carefully handled placeholders like %strong% for proper placement within the translated text.
2024-11-27 09:15:56 +01:00
Nariman Jelveh 6204ddd5c6 Merge pull request #924 from denisugiarto/update-id-translation
update id.js
2024-11-26 20:54:53 -08:00
Nariman Jelveh bc95875f2d Merge pull request #923 from monyxie/zh-translations
Update zh translations
2024-11-26 20:50:54 -08:00
deni sugiarto 0592d2709e update id.js 2024-11-27 11:18:52 +07:00
Aiaru 71e7a12b35 added translations 2024-11-27 13:00:19 +09:00
Max Xie 77eb1c0a3d Update zh translations 2024-11-27 11:54:06 +08:00
Nariman Jelveh 6d6e3e67ab Merge pull request #921 from junian/patch-1
Update id.js #865
2024-11-26 19:15:42 -08:00
Nariman Jelveh a4217ae169 Update id.js 2024-11-26 19:14:30 -08:00
Junian Triajianto 2f6d7323ca Update id.js 2024-11-27 10:08:28 +07:00
Junian Triajianto 2238b933a7 Update id.js #865 2024-11-27 10:04:10 +07:00
KernelDeimos 811732cb56 dev: switch xai to openai client, get streaming counts 2024-11-26 16:45:33 -05:00
KernelDeimos 0d90b588aa dev: get streaming token counts on everything (except xAI) 2024-11-26 16:45:33 -05:00
KernelDeimos 2dd9417234 dev: get token counts on all services 2024-11-26 16:45:33 -05:00
jelveh f3d270ccbc fix: remove inactive links in README 2024-11-26 13:39:42 -08:00
Nariman Jelveh bcf36491b4 Merge pull request #920 from gng92/patch-2
Update hy.js
2024-11-26 11:23:13 -08:00
Nariman Jelveh e4f2066bb4 Update hy.js 2024-11-26 11:22:52 -08:00
gng92 63660b004d Update hy.js
Missing translations added
2024-11-26 23:19:04 +04:00
Nariman Jelveh ecedba4120 Merge pull request #919 from Rebandradha/main
"Complete Kurdish Translation for ku.js"Completed missing Kurdish translations in ku.js
2024-11-26 10:22:26 -08:00
jelveh 4686e210c3 Update ku.js 2024-11-26 10:21:23 -08:00
KernelDeimos fe1a4cfd4d fix: improve backend mod error handling 2024-11-26 13:20:44 -05:00
Nariman Jelveh 885a58c97d Update ku.js 2024-11-26 10:19:13 -08:00
Nariman Jelveh f27c824682 Merge pull request #918 from HeyPuter/revert-917-main
Revert "Improve your word choice to make it easier for Indonesians to underst…"
2024-11-26 09:40:34 -08:00
Nariman Jelveh 2884fe7183 Revert "Improve your word choice to make it easier for Indonesians to underst…" 2024-11-26 09:40:02 -08:00
Nariman Jelveh 1c145119f0 Merge pull request #917 from rhecustein/main
Improve your word choice to make it easier for Indonesians to underst…
2024-11-26 09:39:55 -08:00
Bintang Wijaya d0642d7806 Merge branch 'main' into main 2024-11-27 00:04:12 +07:00
rebandradha 14cc4904bd Completed missing Kurdish translations in ku.js 2024-11-26 20:04:06 +03:00
jelveh 63450ccd49 Update id.js 2024-11-26 08:58:35 -08:00
Nariman Jelveh e424e905aa Merge pull request #916 from DigitalGenius-ui/update-transulation
new transulations are added
2024-11-26 08:56:24 -08:00
rhecustein ab1bceab06 Improve your word choice to make it easier for Indonesians to understand. 2024-11-26 23:37:58 +07:00
KernelDeimos b25d55e596 dev: configurable extension dirs 2024-11-26 11:10:28 -05:00
DigitalGenius-ui b3f5a7b846 new transulations are added 2024-11-26 23:54:51 +08:00
Nariman Jelveh a54f51db90 Merge pull request #915 from bestlucky123/fix_issue_862
Fix: Japanese Translation for i18n (Issue 862)
2024-11-26 06:19:07 -08:00
Nariman Jelveh 0cf9304683 Update ja.js 2024-11-26 06:18:44 -08:00
bestlucky123 fceaf714c3 Fix: Japanese Translation for i18n 2024-11-26 18:35:29 +09:00
KernelDeimos 871416f461 dev: migrate openai to new controller (last one) 2024-11-25 15:54:11 -05:00
KernelDeimos 3f4efb9948 dev: implement ai model fallback 2024-11-25 14:58:21 -05:00
KernelDeimos 0d86233b45 dev: migrate together-ai to new controller 2024-11-25 12:10:22 -05:00
KernelDeimos 5746c7156a dev: migrate Mistral to new controller 2024-11-25 12:10:22 -05:00
KernelDeimos e6928cf6c7 sync: add llama-3.1-70b-specdec 2024-11-25 12:10:22 -05:00
KernelDeimos 4015c531f5 dev: migrate Groq to new controller 2024-11-25 12:10:22 -05:00
KernelDeimos 2c3eb93d22 sync: model info 2024-11-25 12:10:22 -05:00
Nariman Jelveh 0b4adb6bc1 Merge pull request #914 from JessicaFredin/update-swedish-translations
Update Swedish translations in sv.js
2024-11-25 08:29:28 -08:00
Nariman Jelveh ecd6c4e781 Update sv.js 2024-11-25 08:27:02 -08:00
Nariman Jelveh c86b1175b3 Merge pull request #912 from BertramYe/BertramYe-patch-add-Chinese-(中文)-translation-of-Puter
Update zh.js
2024-11-25 08:14:03 -08:00
Nariman Jelveh d65828930a Merge branch 'main' into BertramYe-patch-add-Chinese-(中文)-translation-of-Puter 2024-11-25 08:13:49 -08:00
Nariman Jelveh 91b4ca77cb Merge pull request #913 from SoarUI/main
update issues/#845
2024-11-25 08:11:54 -08:00
Nariman Jelveh 0273192105 Update zh.js 2024-11-25 08:11:34 -08:00
JessicaFredin b734ed75b6 Update Swedish translations in sv.js 2024-11-25 17:10:09 +01:00
BertramYe 76faf79f5a Update zh.js
fix the issue of `Complete the Chinese (中文) translation of Puter #845`
2024-11-25 23:57:03 +08:00
Nariman Jelveh b51618d5aa Merge pull request #911 from mardax007/main
Updated nl.js with missing translations
2024-11-25 07:39:59 -08:00
Mardax d590f53c46 Update nl.js 2024-11-25 15:39:21 +00:00
jelveh e0a577f5a5 Update nl.js 2024-11-25 07:35:50 -08:00
soarui 957513737d update issues/#845 2024-11-25 10:35:31 -05:00
Mardax 638c805a95 Update nl.js 2024-11-25 15:32:08 +00:00
Nariman Jelveh 0c6e8ca4ed Merge pull request #910 from monish-j/fix-hindi-translations
Fix missing Hindi translations in hi.js
2024-11-25 06:57:51 -08:00
jelveh b73a3bbfd8 Update hi.js 2024-11-25 06:57:22 -08:00
Monish Jaiswal 5ec3bbcf24 Fix missing Hindi translations in hi.js 2024-11-25 14:07:19 +05:30
jelveh 9a0edc80e4 tweak: decrease the opacity of the overlay for showSpinner 2024-11-24 21:09:45 -08:00
jelveh 8817a25b65 Update UIWindowQR.js 2024-11-24 15:51:36 -08:00
KernelDeimos 7fa11a4ca0 dev: apply openai moderation to claude and xai 2024-11-24 18:14:50 -05:00
KernelDeimos ef7047ede4 dev: allow extensions to audit prompts 2024-11-24 18:14:50 -05:00
KernelDeimos df42d433c9 ops: don't allow no origin 2024-11-24 18:14:50 -05:00
Nariman Jelveh 39c7df9bb5 Merge pull request #909 from Zac0511/patch-3
Update fr.js
2024-11-24 15:06:00 -08:00
jelveh 66016b9db6 feat: record signup metadata for abuse prevention 2024-11-24 13:00:43 -08:00
KernelDeimos e0df5429ce dev: add validator middleware 2024-11-24 14:27:37 -05:00
KernelDeimos 78da140cd6 dev: add server id 2024-11-24 13:37:13 -05:00
KernelDeimos 86bf08ccc0 dev: add metadata column 2024-11-24 13:34:54 -05:00
Zac0511 6b90c3f44d Update fr.js 2024-11-24 09:23:54 +01:00
Nariman Jelveh 4ed0af7921 Merge pull request #908 from AmirH-Sal/patch-1
Update fa.js
2024-11-23 21:07:18 -08:00
jelveh ff0cbef37b Update fa.js 2024-11-23 21:05:49 -08:00
AmirH-Sal 3b3d8cb316 Update fa.js 2024-11-23 20:56:45 -08:00
jelveh 3cedd17b8e fix: app query should return app metadata 2024-11-23 19:08:40 -08:00
jelveh f77f05062f tweak: improve minor ux for dev center 2024-11-23 14:50:02 -08:00
jelveh 7cf215ab67 feat: add support for categories in the Dev Center 2024-11-23 14:35:46 -08:00
jelveh 10b2ae6542 style: improve the flow and code of the Save Account flow 2024-11-23 14:14:30 -08:00
jelveh fc5aca1f72 feat: puter.js's showSpinner() will keep the spinner active for at least 1200ms 2024-11-23 13:23:20 -08:00
jelveh 966d98e469 tweak: showWorking -> showSpinner 2024-11-23 13:04:53 -08:00
jelveh 0980f7c585 tweak: trim description in the output html for homepage 2024-11-23 11:03:54 -08:00
jelveh b6a9d957aa tweak: clean up some dead imports 2024-11-23 10:44:45 -08:00
jelveh 5ec2d8f6ba Merge branch 'main' of https://github.com/heyputer/puter 2024-11-23 08:48:34 -08:00
jelveh a2c7b379f8 fix: safe parsing of app metadata 2024-11-23 08:48:14 -08:00
Nariman Jelveh 06996d238b Merge pull request #907 from rsdribeiroIT/portuguese_language
Update pt.js
2024-11-23 08:32:57 -08:00
jelveh d35308fd04 Update pt.js 2024-11-23 08:25:59 -08:00
[email protected] f5fc234dbb Update pt.js 2024-11-23 16:17:35 +00:00
Nariman Jelveh 2e6f10bee9 Merge pull request #905 from yeldynov/main
update ru.js
2024-11-23 07:14:21 -08:00
jelveh 2adf836f8a Update ru.js 2024-11-23 07:09:56 -08:00
Nariman Jelveh b7ceacfb8d Merge pull request #906 from PeterZsigmond/complete-hungarian-translation
Complete the Hungarian (Magyar) translation of Puter (Issue #867)
2024-11-23 06:39:33 -08:00
Peter Zsigmond b84c6a04a7 Add missing Hungarian translations in hu.js 2024-11-23 12:39:46 +01:00
Nikita Yeldynov 5de3fe8b46 update ru.js 2024-11-23 11:02:05 +02:00
jelveh be36d31509 feat: allow developers to set social media images for their apps 2024-11-22 17:59:00 -08:00
KernelDeimos 791c6f11f4 dev: max tokens for claude 2024-11-22 17:42:01 -05:00
KernelDeimos 3ed1453939 tool: token count testing 2024-11-22 17:21:48 -05:00
Nariman Jelveh 4b5a3128f3 Merge pull request #904 from saltimbanc/main
Update ro.js
2024-11-22 14:05:46 -08:00
Titus 53e00bec4f Update ro.js 2024-11-22 23:50:30 +02:00
KernelDeimos aa3dcea462 refactor: central controller for all LLM services
Adds AIChatService, an implementor of puter-chat-completion which can
delegate to other implementors (implementors that have registered with
AIChatService at initialization) based on details of the request.

Makes AIChatService the test implementation. AIChatService then
delegates to FakeChatService when in test mode.

Adds `models()` method to puter-chat-completion. This method, instead of
returning only the names of supported models, includes other details
such as the cost and maximum output size.

Implements `models()` on Claude and XAI.

Registers Claude and XAI with AIChatService.
2024-11-22 15:52:37 -05:00
KernelDeimos 791f7748c7 fix: configuration for browser launch
Makes browser launch on startup configurable. Also, by default, users of
Arch Linux will not be subjected to this behavior (they won't like it).
2024-11-22 13:58:33 -05:00
KernelDeimos 960a9ec9ee dev: set claude back 2024-11-22 11:28:44 -05:00
Nariman Jelveh d77c5f40b2 Merge pull request #903 from Kumara2mahe/missing-translation-issue851-mahendra
Add missing tamil translations; issue #851
2024-11-22 08:07:18 -08:00
Nariman Jelveh 35e4089a6f Update ta.js 2024-11-22 08:02:43 -08:00
Kumara2mahe ae9317a9ed Add missing tamil translations 2024-11-22 21:20:50 +05:30
KernelDeimos ee7bedd558 fix: previous fix 2024-11-22 10:37:00 -05:00
KernelDeimos 56710e17f3 fix: always adapt model for ClaudeEnough 2024-11-22 10:34:21 -05:00
KernelDeimos 1e15696096 Eh, Claude enough...
Replaces Claude with Grok pretending to be Claude. This is in lieu of a
proper fallback system which will be implemented later.

Grok will always say it's pretending to be Claude rather than
identifying itself as Claude.
2024-11-22 10:13:49 -05:00
jelveh f500fb4706 fix: automatically open browser when starting only if in dev env 2024-11-22 07:11:05 -08:00
jelveh 70096a8d6f fix(deps): update multiple dependencies 2024-11-22 06:35:22 -08:00
KernelDeimos f533dca1a6 fix: image generation supports test mode 2024-11-22 09:22:24 -05:00
jelveh 2d4312972a feat: automatically open the browser when starting Puter 2024-11-21 22:51:43 -08:00
jelveh 1062363096 feat: spinner for the showWorking() overlay in puter.js 2024-11-21 19:41:39 -08:00
Nariman Jelveh 1811545818 Merge pull request #902 from DavidReque/feat/loading-overlay
Improved Work Overlay Behavior
2024-11-21 19:28:42 -08:00
David Requeno 0385a2b32d tweak: enhance working overlay behavior 2024-11-21 21:14:13 -06:00
Nariman Jelveh 93d7340cc0 Merge pull request #898 from kemal-akar/main
Turkish translations completed and missing parts fixed (Issue #849)
2024-11-21 16:07:20 -08:00
jelveh d36e63c519 Update tr.js 2024-11-21 16:06:55 -08:00
Nariman Jelveh 21c99a90eb Merge pull request #900 from HeyPuter/revert-715-main
Revert "Added installation instructions for public hosting to readme"
2024-11-21 16:02:42 -08:00
Nariman Jelveh 971aa4cd0a Revert "Added installation instructions for public hosting to readme" 2024-11-21 16:02:27 -08:00
Nariman Jelveh 3f34301fc5 Merge pull request #715 from decipher2k/main
Added installation instructions for public hosting to readme
2024-11-21 16:02:08 -08:00
Nariman Jelveh 90c3acdef5 Merge pull request #899 from pashak1207/main
Fix: Resolved issue #848 - Ukrainian translation
2024-11-21 15:26:11 -08:00
pashak1207 ee705e5c1c Fix: Resolved issue #848 - Ukrainian translation 2024-11-21 23:39:51 +02:00
Kemal Akar 325483c2ac Turkish translations completed and missing parts fixed (Issue #849) 2024-11-22 00:26:57 +03:00
KernelDeimos 7f30ec46e7 test: add more thumbnailer tests 2024-11-21 15:45:37 -05:00
Nariman Jelveh 41e28badcd Merge pull request #897 from mark10112/thai-translation
Update th.js
2024-11-21 12:08:41 -08:00
jelveh 73c66bebf7 Update th.js 2024-11-21 12:08:31 -08:00
DESKTOP-Q7DI747\User 7e888248d1 thai missing translations 2024-11-22 02:32:42 +07:00
KernelDeimos 03817cd5c7 dev: thumbnail tests and readings 2024-11-21 14:09:56 -05:00
Nariman Jelveh 415d39e86d Merge pull request #896 from afaq-karim/translation/urdu-847
feat(i18n): update Urdu localization with missing translations
2024-11-21 10:48:53 -08:00
jelveh c140cd158b Update ur.js 2024-11-21 10:48:37 -08:00
afaq-karim 0c4b994644 feat(i18n): update Urdu localization with missing translations 2024-11-21 23:42:18 +05:00
KernelDeimos 1363de7cbf text: add test for privacy_aware_path 2024-11-21 12:06:02 -05:00
KernelDeimos d30d62f558 fix: share issue with prefix usernames 2024-11-21 11:40:08 -05:00
KernelDeimos d93fd419e4 dev: add human_readable_age to /whoami 2024-11-21 11:03:40 -05:00
Nariman Jelveh 14f52bcd1f Merge pull request #892 from nlaburu/i18n_gui_french
fix french missing translations
2024-11-21 05:51:49 -08:00
jelveh 4ce0670370 Update fr.js 2024-11-21 05:51:35 -08:00
Noah 6992ce06cb Merge branch 'HeyPuter:main' into i18n_gui_french 2024-11-21 11:05:36 +01:00
nlaburu a998e4b4cc fix missing placeholders in fr.js 2024-11-21 11:04:58 +01:00
Nariman Jelveh dd11cc0256 Merge pull request #895 from kiwipix/patch-3
Update zhtw.js
2024-11-20 20:07:13 -08:00
jelveh 46053f3e7c Update zhtw.js 2024-11-20 20:04:00 -08:00
kiwipix 2f15d129b6 Update zhtw.js
add translation for missing items
2024-11-21 11:53:08 +08:00
Nariman Jelveh cf8bf308a7 Merge pull request #894 from tien0412/patch-1
finish translation for vi.js
2024-11-20 19:49:40 -08:00
Nariman Jelveh 4d0d8e125b Update vi.js 2024-11-20 19:49:26 -08:00
tien0412 12cc753903 finish translation for vi.js 2024-11-21 10:29:42 +07:00
KernelDeimos 16257a7b54 fix: permission grants in open_item 2024-11-20 21:00:03 -05:00
nlaburu 99cd9b2315 fix french missing translations 2024-11-21 00:48:36 +01:00
jelveh bfacfc2a4e fix: sharing notification click opening directories 2024-11-20 15:44:17 -08:00
Nariman Jelveh 505865f3bf Merge pull request #891 from LuizGribner/feature/br-translation
Translate completed to Portuguese-BR
2024-11-20 15:25:19 -08:00
Nariman Jelveh ca2f7b4326 Update br.js 2024-11-20 15:23:19 -08:00
jelveh 035de8e73e Update UIDesktop.js 2024-11-20 15:21:05 -08:00
Luiz Gribner f5247c9dfe Translate completed to Portuguese-BR 2024-11-20 19:55:38 -03:00
KernelDeimos 5e463e1db8 dev: validate metadata 2024-11-20 17:17:23 -05:00
KernelDeimos e6986d5216 dev: add share metadata and messages 2024-11-20 17:01:32 -05:00
Nariman Jelveh 9dff04f8d5 Merge pull request #890 from HeyPuter/revert-886-motabbir
Revert "Added missing translations for Bengali localization (#842)"
2024-11-20 12:55:42 -08:00
Nariman Jelveh 63d4a604fa Revert "Added missing translations for Bengali localization (#842)" 2024-11-20 12:53:02 -08:00
Nariman Jelveh 1b98f0486f Merge pull request #886 from motabbirhossain/motabbir
Added missing translations for Bengali localization (#842)
2024-11-20 12:52:54 -08:00
Nariman Jelveh 546a268ed9 Merge branch 'main' into motabbir 2024-11-20 12:52:44 -08:00
KernelDeimos c7419d18df dev: add /acl/set-user-user 2024-11-20 15:36:00 -05:00
KernelDeimos 70d8e837af dev: prevent sharing a file to the same user twice 2024-11-20 15:23:46 -05:00
KernelDeimos 4396630453 dev: add /acl/stat-user-user
This new endpoint shows permissions granted by the current user to the
specified user in the scope of a specified filesystem node, including
permissions on the affecting parent nodes.

This is related to two future tasks:
- prevent users from sharing a file with the same user twice
- add an endpoint to modify the access mode of a shared file
2024-11-20 14:57:20 -05:00
Nariman Jelveh ea4cde82fc Merge pull request #889 from Barkatzx/update-bn.js
issue #842
2024-11-20 11:37:43 -08:00
Nariman Jelveh b76ab955b1 Merge branch 'main' into update-bn.js 2024-11-20 11:37:35 -08:00
Nariman Jelveh cedde40cd4 Merge pull request #887 from kazi331/patch-2
Update bn.js
2024-11-20 11:27:38 -08:00
jelveh d0bf94c5d0 Update bn.js 2024-11-20 11:18:59 -08:00
Nariman Jelveh 3bb4de4f90 Merge pull request #888 from NadaAly56/fix-arabic-translation
fixixng arabic translation
2024-11-20 10:27:15 -08:00
jelveh ac4cc95be5 Update ar.js 2024-11-20 10:26:21 -08:00
Nariman Jelveh 0abddf5fea Merge branch 'main' into patch-2 2024-11-20 10:24:44 -08:00
Barkatzx b0046ceb26 issue #842 2024-11-21 00:23:25 +06:00
Nariman Jelveh dc5f699ec6 Merge pull request #885 from FahimFBA/issue-842
Filled the missing Bengali translation and updated the old translation
2024-11-20 10:15:47 -08:00
jelveh be566cb7c1 Update bn.js 2024-11-20 10:15:30 -08:00
nada f0012fdf87 fixixng arabic translation 2024-11-20 19:30:26 +02:00
KernelDeimos d911754e2b dev: fix test_mode flag 2024-11-20 12:03:39 -05:00
Kazi Shariful Islam 4ca1bddbd1 Update bn.js
updated with manual translation
2024-11-20 22:57:27 +06:00
motabbirhossain d43e79243a Added missing translations for Bengali localization (#842) 2024-11-20 22:46:17 +06:00
FahimFBA 0d1e676ce1 update translation: login2fa_otp_instructions 2024-11-20 22:22:53 +06:00
FahimFBA 98e2331a56 update translation: setup2fa_4_instructions 2024-11-20 22:22:33 +06:00
FahimFBA af7be2c917 update translation: setup2fa_3_step_heading 2024-11-20 22:21:59 +06:00
FahimFBA f85adbe7ec update translation: setup2fa_1_instructions 2024-11-20 22:21:46 +06:00
FahimFBA 43a2afc843 update translation: undo 2024-11-20 22:20:49 +06:00
FahimFBA d2eae20223 update translation:two_factor_enabled 2024-11-20 22:20:26 +06:00
FahimFBA 16e6307bca update translation: two_factor_disabled 2024-11-20 22:20:11 +06:00
FahimFBA 9fd977761c update translation: skip 2024-11-20 22:19:15 +06:00
FahimFBA fdd0c67b1d update translation: reset_colors 2024-11-20 22:18:28 +06:00
FahimFBA 7a8da04634 update translation: replace_all 2024-11-20 22:17:50 +06:00
FahimFBA b89a5ad523 update translation: refer_friends_social_media_c2a 2024-11-20 22:17:27 +06:00
FahimFBA eb19ec0c48 update translation: refer_friends_c2a 2024-11-20 22:17:11 +06:00
FahimFBA 26250800de update translation: personalization 2024-11-20 22:16:08 +06:00
FahimFBA fd7e762850 update translation: passwords_do_not_match 2024-11-20 22:15:51 +06:00
FahimFBA 47717f1d41 update translation: password_reset_sent 2024-11-20 22:15:33 +06:00
FahimFBA 90a2a44c45 update translation: password_requirements 2024-11-20 22:15:10 +06:00
FahimFBA 90fa5f184c update translation: password_recovery_rate_limit 2024-11-20 22:14:45 +06:00
FahimFBA 38fec34d56 update translation: open_with 2024-11-20 22:14:12 +06:00
FahimFBA af2e1687ca update translation: open_in_new_window 2024-11-20 22:13:57 +06:00
FahimFBA 88efa1c89c update translation: lightness 2024-11-20 22:13:11 +06:00
FahimFBA c6a734896d update translation: items_in_trash_cannot_be_renamed 2024-11-20 22:12:43 +06:00
FahimFBA f6a4a7864a update translation: hide_all_windows 2024-11-20 22:12:23 +06:00
FahimFBA b8adacabc1 update translation: force_quit 2024-11-20 22:11:44 +06:00
FahimFBA 9314b949ff update translation: feedback_sent_confirmation 2024-11-20 22:11:04 +06:00
FahimFBA 9e918042b1 update translation: email_invalid 2024-11-20 22:09:31 +06:00
FahimFBA faf5a48ee1 update translation: email_change_confirmation_sent 2024-11-20 22:09:11 +06:00
FahimFBA 67cc5b03ad update translation: dont_allow 2024-11-20 22:08:45 +06:00
FahimFBA 3bbacdeaea update translation: disable_2fa_instructions 2024-11-20 22:08:21 +06:00
FahimFBA 451b23eb4c update translation: disable_2fa_confirm 2024-11-20 22:08:06 +06:00
FahimFBA a7f032a325 update translation: disable_2fa 2024-11-20 22:07:52 +06:00
FahimFBA b267547ea7 update translation: deploy_as_app 2024-11-20 22:07:23 +06:00
FahimFBA c2da4527b7 update translation: date_modified 2024-11-20 22:06:59 +06:00
FahimFBA 6bef43468a update translation: close_all 2024-11-20 22:06:34 +06:00
FahimFBA 20c49b6a05 update translation: clock_visible_auto 2024-11-20 22:06:14 +06:00
FahimFBA 127a241b84 update translation: confirm_delete_user 2024-11-20 22:05:30 +06:00
FahimFBA 4555a21fa1 update translation: confirm_code_2fa_instruction 2024-11-20 22:04:54 +06:00
FahimFBA e5229f4c7e update translation: confirm_code_2fa_instruction 2024-11-20 22:04:32 +06:00
FahimFBA 3114eb2dd5 update translation: confirming too many request
confirm_code_generic_too_many_requests
2024-11-20 22:04:12 +06:00
FahimFBA 3c07c30933 update translation: confirmation for referral
confirm_account_for_free_referral_storage_c2a
2024-11-20 22:03:17 +06:00
FahimFBA 41ec3a9698 update translation: confirm_2fa_recovery 2024-11-20 22:02:34 +06:00
FahimFBA 3c31791fe6 update translation: confirm 2024-11-20 22:01:58 +06:00
FahimFBA d9d5c09f15 update translation: confirm 2024-11-20 22:01:14 +06:00
FahimFBA c6a01e3060 update translation: change_always_open_with 2024-11-20 22:00:05 +06:00
FahimFBA 0d75306379 update translation: close_all_windows_and_log_out 2024-11-20 21:58:59 +06:00
FahimFBA ea1d46e27d update translation: change_ui_colors 2024-11-20 21:57:59 +06:00
FahimFBA 8ade96a54d update translation: change_email 2024-11-20 21:57:42 +06:00
FahimFBA 7b15d804df update translation: change_desktop_background 2024-11-20 21:57:22 +06:00
FahimFBA ede6ed4a0c add translation: This user already has access to this item 2024-11-20 21:54:25 +06:00
FahimFBA b76d2922c3 add translation: You can't share with yourself. 2024-11-20 21:53:25 +06:00
FahimFBA 3bd07dfabd add translation: Owner 2024-11-20 21:52:59 +06:00
FahimFBA 712852b3aa add translation: Share With… 2024-11-20 21:52:39 +06:00
FahimFBA e43e646f54 add translation: People with access 2024-11-20 21:52:20 +06:00
FahimFBA efbe0e0f7e add translation: Viewer 2024-11-20 21:51:48 +06:00
FahimFBA 6ac6870b9a add translation: Editor 2024-11-20 21:51:29 +06:00
FahimFBA f468c172f4 add translation: zipping 2024-11-20 21:51:10 +06:00
FahimFBA 84a68a3688 add translation: sequencing 2024-11-20 21:50:42 +06:00
FahimFBA f9b2a81d00 add translation: unzipping 2024-11-20 21:49:45 +06:00
FahimFBA 27da49dcd3 add translation: writing 2024-11-20 21:49:21 +06:00
FahimFBA be7d651f7f add translation: reading 2024-11-20 21:48:59 +06:00
FahimFBA a820721f74 add translation: password_strength_error 2024-11-20 21:47:09 +06:00
FahimFBA da2dee842a add translation: password_required 2024-11-20 21:45:49 +06:00
FahimFBA ae20fd5afa add translation: password_recovery_unknown_error 2024-11-20 21:45:19 +06:00
FahimFBA 86a54b9415 add translation: password_recovery_token_invalid 2024-11-20 21:43:36 +06:00
FahimFBA 1fa0bebfd5 update translation for: Clock Visibility 2024-11-20 21:42:44 +06:00
FahimFBA e3782f7b42 add translation for: clock_visibility 2024-11-20 21:41:41 +06:00
FahimFBA 2d522537ee add translation for: change 2024-11-20 21:41:07 +06:00
Nariman Jelveh 5ab87979bc Merge pull request #882 from Abhinav-Bansal751/main
Update es.js
2024-11-19 21:45:34 -08:00
jelveh 2c86240399 fix: add placeholders 2024-11-19 21:42:29 -08:00
Bansal b2afeb162a Update es.js 2024-11-20 11:02:54 +05:30
jelveh 35fd15854a fix: capitalize Hindi in i18n 2024-11-19 17:54:28 -08:00
jelveh f693211348 add: missing translation keys to different language files 2024-11-19 17:02:47 -08:00
KernelDeimos 36ca7f63aa dev: update referral and share notifs 2024-11-19 16:47:41 -05:00
KernelDeimos 0fa3be9d43 clean: cleanup backend logs 2024-11-19 15:00:04 -05:00
KernelDeimos dca7892fca sync: update CoreModule 2024-11-19 14:39:17 -05:00
KernelDeimos e0f4c527f4 dev: migrate referral service and use user.email-confirmed event 2024-11-19 14:31:33 -05:00
jelveh 65e6d6c09f fix: give camera and recorder write permission to Desktop 2024-11-19 10:52:42 -08:00
KernelDeimos 01725ffebf fix: potential null-or-undefined in DriverService 2024-11-19 13:08:58 -05:00
KernelDeimos 7ed557f375 dev: add fake chat service, for testing 2024-11-19 13:08:39 -05:00
KernelDeimos 86789920c4 dev: apply all relevant shares on verified email 2024-11-19 12:40:03 -05:00
KernelDeimos 0fd3b1e611 fix: usage bug 2024-11-19 11:08:54 -05:00
KernelDeimos 7e7234b2f3 fix: update share email 2024-11-19 10:28:42 -05:00
jelveh 4cc63b2580 Update UIWindowShare.js 2024-11-18 11:29:15 -08:00
jelveh 905b5d851e fix: allow scrolling of user list in share window 2024-11-18 10:40:15 -08:00
jelveh 0e45132c05 feat: show profile pics in sharing notifications 2024-11-18 07:22:13 -08:00
jelveh b11016dab3 fix: mobile detection 2024-11-17 11:33:42 -08:00
jelveh 7a7c14fb04 fix: mobile-friendly taskbar 2024-11-17 11:06:10 -08:00
jelveh 0885937f03 feat: Implement profile pictures 2024-11-16 19:07:09 -08:00
KernelDeimos 59fa600f2b dev: edge rate limit for email share 2024-11-16 20:04:23 -05:00
KernelDeimos e0128aa88c fix: prevent permission cycles 2024-11-15 18:47:47 -05:00
jelveh e482b00a30 fix: launchApp on explorer supports ~ now 2024-11-15 15:38:59 -08:00
jelveh 8fefd4a61f feat: allow launchApp to open explorer at a specific path 2024-11-15 15:29:23 -08:00
jelveh cdd1a8c4e3 feat: Require email confirmation before sharing 2024-11-15 12:07:48 -08:00
Eric Dubé 98bd10c82b Revert "added a chime playback"
This reverts commit 2eaf1080d6.
2024-11-15 13:41:31 -05:00
Eric Dubé 5fd11cc607 Revert "added event listener to play chime on the first click"
This reverts commit 4885a76a75.
2024-11-15 13:41:31 -05:00
Eric Dubé fa5d731641 Revert "."
This reverts commit 1919cb3d99.
2024-11-15 13:41:31 -05:00
Eric Dubé f8ac0dbdb7 Revert "play chime only once"
This reverts commit edeb79d92c.
2024-11-15 13:41:31 -05:00
KernelDeimos 08779ac455 dev: make share feature flag reflect user state 2024-11-15 13:40:24 -05:00
KernelDeimos 14b962b459 dev: add function-flag feature flag type 2024-11-15 13:34:56 -05:00
4nshuman edeb79d92c play chime only once 2024-11-15 12:43:17 -05:00
4nshuman 1919cb3d99 . 2024-11-15 12:43:17 -05:00
4nshuman 4885a76a75 added event listener to play chime on the first click 2024-11-15 12:43:17 -05:00
4nshuman 2eaf1080d6 added a chime playback 2024-11-15 12:43:17 -05:00
KernelDeimos 69bfa60199 fix: only allow UserActorType for ShareService 2024-11-15 12:09:31 -05:00
jelveh 045259cefb feat: show unread notification count in the browser tab's title 2024-11-14 17:19:21 -08:00
KernelDeimos b1ffb8eca1 fix: new sessions miss notifications 2024-11-14 19:26:15 -05:00
jelveh d0f16c8105 fix: don't allow sharing with recipient just shared with 2024-11-14 15:38:26 -08:00
KernelDeimos 085d808817 fix: add username to comments 2024-11-14 18:09:46 -05:00
jelveh d91435db57 Merge branch 'main' of https://github.com/heyputer/puter 2024-11-14 14:45:43 -08:00
jelveh cf4b6aa1c2 feat: in Share window, display access level next to recipient 2024-11-14 14:45:35 -08:00
KernelDeimos db79a72daa feat(backend): add comments for fsentries 2024-11-14 17:45:20 -05:00
jelveh 0cbe0139d7 feat: when sharing, users can choose between 'viewer' and 'editor' for permissions 2024-11-14 14:08:49 -08:00
jelveh a6650ee2d8 feat: handle notif.ack in desktop 2024-11-14 12:52:15 -08:00
KernelDeimos 9e303a2f7c fix: occasional db error from notics 2024-11-14 15:18:28 -05:00
KernelDeimos 00e0fb350a dev: add notif.ack message 2024-11-14 15:18:28 -05:00
KernelDeimos 3f3f4e6cb9 fix: un-awked notif check in wrong place 2024-11-14 15:18:28 -05:00
jelveh 9d40ad9b4e Update UIWindow.js 2024-11-14 09:55:39 -08:00
jelveh 9d7987fae5 fix: disabled sortable on sharing section in the sidebar 2024-11-14 09:37:06 -08:00
KernelDeimos 665471f9f0 fix: add mixxing context to BroadcastService 2024-11-13 23:25:44 -05:00
KernelDeimos 22dd42ef7f fix: attempt at fixing broadcast 2024-11-13 23:13:45 -05:00
KernelDeimos cd22425a3d fix: replace ll_readshares with better approach
Recursively checking for files with 'see' permission? What was I
thinking? This replaces the disasterously awful approach of scanning a
user's entire file tree to find shares, with an approach which instead
selects on the permissions table and extracts file UUIDs from
permissions.
2024-11-13 22:44:54 -05:00
KernelDeimos 34836e374f fix: only add enabled_logs when not empty 2024-11-13 22:15:09 -05:00
KernelDeimos caf8d2a055 dev: track ll_readshares depth 2024-11-13 21:14:56 -05:00
KernelDeimos 249dc06201 fix: don't check share permission anymore 2024-11-13 20:39:58 -05:00
jelveh 94b10c78b7 tweak: sharing style 2024-11-13 17:30:03 -08:00
jelveh b5bb95e2d7 feat: add error handling to the share flow 2024-11-13 15:59:29 -08:00
jelveh 9a311058ef tweak: disable sidebar_items polling 2024-11-13 15:45:02 -08:00
jelveh 599c7ad0a1 Update UIElement.js 2024-11-13 14:43:30 -08:00
jelveh 622205ae51 tweak: enable sharing 2024-11-13 13:49:17 -08:00
KernelDeimos 27cc07e985 fix: files shared array in notification 2024-11-13 15:02:10 -05:00
KernelDeimos 89aab03905 tweak: enable share 2024-11-13 13:15:22 -05:00
KernelDeimos 8f59c2614d tweak: put groups manager behind a flag 2024-11-13 12:54:54 -05:00
KernelDeimos 5725bd8c66 fix: report path for broken files as /-void/ 2024-11-13 12:11:48 -05:00
Nariman Jelveh c53107db67 Merge pull request #830 from Zac0511/patch-2
Update README.fr.md
2024-11-12 22:28:23 -08:00
jelveh 7ca0a02fa4 tweak: safe data URI strings for icons in search 2024-11-12 20:45:53 -08:00
jelveh 55d2af189e feat: search 2024-11-12 20:20:43 -08:00
KernelDeimos b589512c9d feat: search endpoint 2024-11-12 17:58:43 -05:00
jelveh ac3317aea9 fix: issue with popover closing when clicked 2024-11-12 13:27:29 -08:00
jelveh 1adfe5c709 feat: the socialLink UI component 2024-11-12 12:40:14 -08:00
jelveh 45ecce4653 Update style.css 2024-11-11 20:49:49 -08:00
jelveh a70cb49a30 tweak: style improvement 2024-11-11 17:31:43 -08:00
jelveh 27c01c9bd9 feat: Reaload App option in the window title bar context menu 2024-11-11 11:46:28 -08:00
KernelDeimos a08e9758fe fix: groups manager location 2024-11-11 14:40:50 -05:00
jelveh a9679910c6 Update style.css 2024-11-10 10:46:13 -08:00
KernelDeimos 402ffb0fd1 fix: don't show kvstore in usages 2024-11-10 13:33:41 -05:00
KernelDeimos 4f9d9a54ef fix: add missing id for task_manager menu item 2024-11-10 12:46:42 -05:00
Nariman Jelveh 6c44032293 fix: Update security.txt canonical URL 2024-11-10 08:55:51 -08:00
Nariman Jelveh d6307cc389 Create FUNDING.yml 2024-11-10 08:48:12 -08:00
KernelDeimos fc0cb2dde4 tweak: usage endpoint 2024-11-09 17:41:16 -05:00
KernelDeimos 85020109b3 dev: add virtual groups for computed permissions 2024-11-09 17:40:47 -05:00
KernelDeimos a324c91560 dev: add quick window to see what groups a user is in
I need this for development/debugging purposes. I figure I may as well
start developing the system dialog we'll eventually have to create
rather than make a temporary debugging element. This window could
eventually become a full-featured group manager, and can easily be moved
to a settings tab.
2024-11-09 15:57:28 -05:00
KernelDeimos 59984bb930 dev: recursive log toggle for puter.js 2024-11-09 15:14:37 -05:00
KernelDeimos 6f5f11da09 dev: allow other backend services to set gui_params 2024-11-08 16:04:55 -05:00
jelveh e8f67da9a3 fix: update apps cache by reading from primary db 2024-11-08 10:56:00 -08:00
KernelDeimos 164d5ef167 test: update TestKernel 2024-11-08 12:13:30 -05:00
Zac0511 acfa912cde Update README.fr.md 2024-11-08 10:17:55 +01:00
Zac0511 bb3b38c9ed Update README.fr.md
Added a link to Puter.com
2024-11-08 10:12:58 +01:00
KernelDeimos 28adcf533f feat(ai): add xAI grok-beta 2024-11-07 15:01:13 -05:00
KernelDeimos d613c5fc83 log: when app is launched 2024-11-07 14:27:02 -05:00
KernelDeimos 5caa2c0e3a fix: logging in AppConnection 2024-11-07 14:26:30 -05:00
KernelDeimos 5d416e2316 refactor: simplify module constructors
This was a really small refactor - about 30mins - that moves the concern
of common constructor args for modules outside of each individual call.

A Context object is now used for common constructor arguments. Some of
the values on this object - such as APIOrigin and authToken - are
following values on the instance of the Puter class. This means that for
some modules it is already possible to eliminate the setAuthToken and
setAPIOrigin listeners (out of scope for this commit). Any which remain
could eventually be replaced with a listener on the Context object
itself.

This commit also moves the initSubmodules method to the top of the class
so that it's easier for new devs to find, in case they're looking into
an issue on a specific module rather than the Puter class itself.
2024-11-07 13:29:18 -05:00
Nariman Jelveh 63d6573fba docs: add link to Self-Hosting Documentation in README.md 2024-11-06 17:34:32 -08:00
jelveh 1a6d648a6e fix: persist clock visibility change 2024-11-05 18:31:03 -08:00
KernelDeimos ba2eb716f5 dev: add prefix logger 2024-11-05 15:57:55 -05:00
KernelDeimos da0022abf0 feat: add puter.auth.whoami() 2024-11-05 15:49:51 -05:00
KernelDeimos 755736edee feat: add puter.log 2024-11-05 15:31:44 -05:00
KernelDeimos e71fe11e32 dev: add toggle logging, and fix issues in logger 2024-11-05 15:31:17 -05:00
KernelDeimos b0cbcdf743 dev: add logger to putility 2024-11-05 15:03:21 -05:00
KernelDeimos fe8d6af1b5 sync: update claude model (take 2) 2024-11-04 22:46:57 -05:00
KernelDeimos 52a54d2248 sync: update claude model 2024-11-04 22:28:34 -05:00
jelveh 9263cbaedd Merge branch 'main' of https://github.com/heyputer/puter 2024-11-04 17:33:13 -08:00
jelveh 9590bbdad1 fix: don't access metadata.credentialless if it doesn't exist 2024-11-04 17:33:08 -08:00
KernelDeimos 16b9f09e66 fix: reinitialize settings tabs for DOM events 2024-11-04 19:25:04 -05:00
KernelDeimos 856688f884 dev: add database and config access for extensions 2024-11-04 16:42:42 -05:00
jelveh c44b9ab8d5 fix: use correct cursor when hovering over sidebar items 2024-11-04 10:08:11 -08:00
jelveh 79cff7ba29 Update style.css 2024-11-04 09:33:48 -08:00
jelveh 4e7979b50e Update style.css 2024-11-03 20:57:53 -08:00
jelveh 1056231004 feat: collapsible sidebar menu in Dev Center 2024-11-03 20:50:46 -08:00
jelveh 06d5dd763d tweak: dev center table visible when overflowing 2024-11-03 20:13:35 -08:00
jelveh 666912a8a3 revert style update 2024-11-03 17:20:09 -08:00
jelveh 452e3383e8 Update style.css 2024-11-03 17:18:12 -08:00
jelveh 05950b0fc3 tweak: automatically update sidebar_items every 2 seconds 2024-11-03 17:13:24 -08:00
jelveh 2e122c2cab Update style.css 2024-11-03 16:16:00 -08:00
jelveh ff30de1d69 feat: customize the order of Explorer sidebar items 2024-11-03 16:00:39 -08:00
jelveh 121043d312 fix: issue with context menu divider item stealing the event from previous item 2024-11-02 18:54:30 -07:00
jelveh 0315cb3337 fix: issue with non-scrollable window body and document Context Menu 2024-11-02 17:51:07 -07:00
KernelDeimos 05573dad51 tweak: load mods from extensions directory 2024-11-01 19:29:16 -04:00
KernelDeimos f836ac30a9 fix: temporary fix because .on can't call ensure_service 2024-11-01 18:21:05 -04:00
KernelDeimos 84989367a7 dev: hook extensions into service event bus 2024-11-01 17:42:12 -04:00
KernelDeimos 58f34b948a dev: simplify module/extension setup 2024-11-01 16:13:00 -04:00
KernelDeimos 7569e8a703 tweak: endpoints are authorized by default 2024-11-01 15:43:40 -04:00
KernelDeimos 4b6c70fa5e dev: expose more core definitions to extensions 2024-11-01 15:43:27 -04:00
KernelDeimos a614145250 dev: run npm install after copying extensions 2024-11-01 15:26:39 -04:00
KernelDeimos d958c01111 dev: add support for single-file extensions 2024-11-01 14:42:42 -04:00
KernelDeimos 3f6900f26b dev: add get() and post() to extension API 2024-11-01 14:41:29 -04:00
KernelDeimos d1ebbbe3c7 chore: update kdmod package.json to avoid confusion 2024-10-31 18:20:00 -04:00
KernelDeimos 0a47daa289 fix: issues in kdmod
The kdmod module was broken since we renamed packages/ to src/. Also,
the update to mod loading for some unknown reason now requires each call
to require to end with `.js`. As far as I know, this was working
previously.
2024-10-31 18:15:41 -04:00
KernelDeimos 14d45a27ed feat: add extension API for modules
Allows modules to register a listener to the 'install' event without
creating a Module class. This changes how external modules are
installed.

External modules are now referred to as "extensions"; this commit does
not update the term but does use 'extension' as the name of the global.
2024-10-31 18:08:27 -04:00
KernelDeimos f36718005f sync: add wiki as a submodule 2024-10-31 18:08:30 -04:00
Zac0511 f2fc8ba5cf Edit "Puter version" title and description in the bug report template
A quick edit to replace "Puter version (if accessible)" by "Puter version" and a new description to say that its not required.
2024-10-31 13:54:42 -04:00
KernelDeimos 9a0c5b4f74 dev: support no-response endpoints in Collector
The no_response option is added to Collector::post. If an endpoint
returns an empty response, this option must be set to avoid a JSON parse
error.
2024-10-30 18:52:47 -04:00
Nariman Jelveh 96b64f6b53 Merge pull request #817 from djelacik/main
minor documentation fixes
2024-10-30 08:26:35 -07:00
DeveloperDaniell 05169e9e1e minor documentation fixes 2024-10-30 16:36:43 +02:00
jelveh dc478382fb tweak: don't break if contact_us is not found 2024-10-29 23:44:54 -07:00
jelveh fc5e15f2a6 feat: first extension that implements a custom user options menu 2024-10-29 22:55:26 -07:00
jelveh b018571a86 feat: add support for extensions 2024-10-29 18:37:32 -07:00
KernelDeimos 14f477a633 fix: Collector bug on undefined body 2024-10-29 18:56:11 -04:00
KernelDeimos b9625945ae dev: expose save account and email confirm 2024-10-29 18:56:11 -04:00
KernelDeimos 463c96c69a fix: hyphenize_confirm_code bug 2024-10-29 18:56:11 -04:00
KernelDeimos 38adb5741b fix: app close issue in phoenix 2024-10-29 16:19:58 -04:00
KernelDeimos b30de5bf78 fix: reading JSON string from service_usage_monthly
This was hilariously difficult to debug. This isn't the first time an
issue like this occurred; this happens because of a deviation between
mysql and sqlite, where a JSON-typed column in mysql will return as a
native object in queries, whereas a JSON-typed column in sqlite is a
string column and will therefore return as an un-parsed JSON string in
queries.
2024-10-29 13:18:53 -04:00
KernelDeimos 7ba16d1c21 fix: recently broke counting service sql 2024-10-28 19:14:15 -04:00
KernelDeimos f1087953b5 fix: ignore invalid entries from service_usage_monthly 2024-10-28 19:09:17 -04:00
KernelDeimos 193da63304 fix: service usage screen
This fixes service monthly usage counts as shown in Settings.
2024-10-28 18:47:40 -04:00
KernelDeimos c0b109d4d2 dev: add get_proxy_object to util/context 2024-10-28 15:11:26 -04:00
KernelDeimos 3649dff9aa dev: add module lib installation to useapi 2024-10-28 15:11:26 -04:00
jelveh 3d85edf537 Update UIWindow.js 2024-10-27 21:33:08 -07:00
jelveh 54ae69b7b7 feat: add an 'Upload' button at the bottom of OpenFilePicker 2024-10-27 21:32:39 -07:00
jelveh cd8a080d72 tweak: user-friendly badges for apps in Dev Center 2024-10-27 21:09:18 -07:00
Nariman Jelveh b7c50fc2bb docs: add Garry's Mod to #DoesItRunPuter 2024-10-27 15:58:54 -07:00
jelveh af511c05e3 feat: Allow apps to toggle credentialless via Dev Center 2024-10-27 14:44:06 -07:00
KernelDeimos 4dc1e01682 fix: continue work on blocked_email_domains (2) 2024-10-27 15:46:21 -04:00
jelveh 161be7fe6b remove 'About' from taskbar apps 2024-10-26 09:56:57 -07:00
KernelDeimos 515051dabf fix: continue work on blocked_email_domains 2024-10-26 03:28:45 -04:00
KernelDeimos c22a69ffb1 fix: errors thrown by launch_app
Fixes errors that were noticed being thrown by launch_app, specifically
in the branch of logic when launch_app is called NOT via ExecService.
This branch of logic was added to fix an issue where notepad wasn't
prompting to save unsaved changes on close because data-appusessdk was
not properly set to true. The fix still worked, despite throwing these
errors, because setting data-appUsesSDK to true is the first thing it
does. However, broadcast messages to apps launched with launch_app NOT
via ExecService would have been broken.
2024-10-26 03:07:02 -04:00
jelveh a9bbcf908d Update style.css 2024-10-25 11:36:50 -07:00
KernelDeimos f3a9e784a3 dev: add can iterate check 2024-10-25 14:27:42 -04:00
KernelDeimos b98c5a349e dev: make anti-csrf more convenient 2024-10-24 23:11:07 -04:00
KernelDeimos f55b7ac0b8 dev: ensure existing app tokens don't break (for now) 2024-10-24 19:54:29 -04:00
KernelDeimos 6b8fbda14c dev: allow app tokens to identify user sessions 2024-10-24 19:51:54 -04:00
KernelDeimos bc51d4bd52 fix: notepad save issue 2024-10-24 02:28:19 -04:00
KernelDeimos 87f7fc0265 tweak: clarify blocked domain message 2024-10-24 00:57:21 -04:00
KernelDeimos 955b087297 feat: add config for blocked email domains 2024-10-24 00:38:40 -04:00
KernelDeimos 988039eade dev: src prop for images 2024-10-23 22:59:18 -04:00
KernelDeimos 25e9ed8227 dev: make el() yet more convenient 2024-10-23 01:08:16 -04:00
KernelDeimos 5965ab5de0 dev: allow UIElement to be used as settings tab 2024-10-22 23:55:42 -04:00
KernelDeimos 0bb80d2933 doc: add todo regarding /whoami 2024-10-22 21:54:48 -04:00
KernelDeimos 37bb98b965 dev(gui): add UIElement 2024-10-22 21:54:48 -04:00
jelveh 37aa2b1d06 tweak: improve the usage bar visibility 2024-10-22 17:39:38 -07:00
jelveh 4e8c7455aa tweak: Move clock settings to the 'Personalization' tab of 'Settings' 2024-10-22 17:18:16 -07:00
jelveh 6f702c3927 Going to /settings will open the Settings in full page mode 2024-10-22 16:46:06 -07:00
KernelDeimos c6bc42f551 fix: height 100% on flexer and step view 2024-10-22 18:10:16 -04:00
KernelDeimos 368c20cf57 dev: updates and URL collector 2024-10-21 22:57:25 -04:00
KernelDeimos 12e0cecf02 fix: wait no 2024-10-21 18:12:08 -04:00
KernelDeimos c8f913d710 fix: phoenix incorrect lookup order 2024-10-21 18:07:45 -04:00
ProgrammerIn-wonderland 891e799e5e WIP symlink, net_device virtio, move fixes, upload binary fixes 2024-10-21 17:04:57 -04:00
jelveh 13248a99bf feat: add support for fadeIn effect for UIWindow 2024-10-21 07:48:06 -07:00
jelveh 99ce3bde19 fix: turns out we don't support utm_source I learn something new about Puter every day! 2024-10-20 20:42:34 -07:00
jelveh 5e27055215 tweak: add utm_source to GitHub link 2024-10-20 20:26:31 -07:00
jelveh 920a2f2427 tweak: make backdrop darker to increase focus on active window 2024-10-20 20:15:19 -07:00
KernelDeimos 60fdce9052 sync: put app-center in the taskbar 2024-10-20 20:30:35 -04:00
KernelDeimos 8b1a935c93 sync: developer is in /dist now 2024-10-20 20:30:11 -04:00
KernelDeimos e0b9072129 fix: issue with service scripts that use TestView 2024-10-19 21:17:57 -04:00
Nariman Jelveh 90e7098cc7 Merge pull request #787 from 4nshuman/issue/zip-operation
Issue/zip operation
2024-10-19 15:45:39 -07:00
KernelDeimos b5535ae3ca dev: add dev2 env 2024-10-19 18:22:09 -04:00
KernelDeimos 0fb4f73d76 chore: remove noisy logs 2024-10-19 17:31:46 -04:00
4nshuman 63b4da5be8 connected upload's inbuilt progress counter 2024-10-20 02:07:07 +05:30
4nshuman fabc21ecf7 fixed sorting logic on directory list 2024-10-20 02:00:58 +05:30
4nshuman a646b02e45 provide incremental directories to mkdir 2024-10-20 02:00:35 +05:30
jelveh c29122c23f tweak: use different icons for system directories in the sidebar 2024-10-19 12:59:24 -07:00
4nshuman 4fdea7db66 offloaded write operations to Upload module 2024-10-20 00:06:30 +05:30
4nshuman f32b1cfce8 added option to create parent directories for programmatic file drops 2024-10-20 00:05:40 +05:30
4nshuman fc461c8735 added absolute file path processing 2024-10-20 00:04:36 +05:30
4nshuman d39b7a8972 record unique directory list 2024-10-19 23:52:21 +05:30
jelveh 74baab49f4 tweak: improve welcome window footer link color 2024-10-19 10:35:56 -07:00
jelveh 564ff65363 feat: welcome screen to quickly explain what Puter is 2024-10-19 10:28:03 -07:00
KernelDeimos 480d996279 dev: proof-of-concept for fs postMessage relay
Adds a filesystem relay service to GUI-side which currently reports an
exmaple fsentry for /stat and /readdir. Added filesystem services for
both sides. Moved filesystem implementations from src/modules to src/lib
since they're being called by services now rather than modules.

This functionality is effectively disabled unless
src/puter-js/src/services/Filesystem.js is updated to use init_app_fs_()
when the environment is 'app'.
2024-10-19 03:46:47 -04:00
KernelDeimos 6e5d5c2021 dev: clone property descriptors in Context 2024-10-19 03:45:41 -04:00
KernelDeimos c2a475f3c0 dev: lay the groundwork for client FS relay
Adds XDIncomingService to manage messages from another window. IPC now
registers with XDIncoming and reports whether it was handled, that way
messages intended to reach GUI can be reliably ignored.

On GUI-side, XDIncomingService will be used by FSRelayService (not yet
implemented) to handle requests for filesystem operations from another
window.

On App-side, XDIncomingService might be used by the PostMessageFS
client-side filesystem implementation terminal to listen for filesystem
events that were relayed by GUI (after a permission check) from their
original websocket source. Either that, or we'll open a filesystem
socket for each app using that app's token.

NoPuterYetService was added because IPC.js is loaded before
globalThis.puter exists, and was the easiest way to still allow IPC's
listener to be registered with XDIncomingService.

APIAccessService was added. This service currently holds auth_token and
api_token and does nothing else. FilesystemService listens to this to
maintain a websocket connection. APIAccessService will help to manage
the complexity of all further code dependent on being informed about
changes to the auth token or origin. Currently in puter.js these are
passed around to several modules which manage the same piece of state
information independantly.
2024-10-18 23:10:19 -04:00
KernelDeimos bc5d09fe31 dev: hooks and sequencing functions for ServiceManager 2024-10-18 23:10:19 -04:00
jelveh 2f6f2b7d7c Set autoDedupe to true for creating new apps in Dev Center 2024-10-18 18:44:06 -07:00
KernelDeimos 143cfb5654 fix: 1954f8-related issue #2
mkdir operation was passing user instead if actor. I really think I
changed this already; getting a crazy deja-vu feeling about it. Maybe a
commit was lost somewhere along the road, but not sure.
2024-10-18 21:24:05 -04:00
jelveh b1411cd622 Add dedupeName for to puter.apps and Dev Center 2024-10-18 18:02:37 -07:00
jelveh 8ed5db1734 Merge branch 'main' of https://github.com/heyputer/puter 2024-10-18 17:50:25 -07:00
jelveh 14fc963dd4 Show approval badges and lock in Dev Center 2024-10-18 17:48:14 -07:00
KernelDeimos b9c157b28e tweak: start from 1 2024-10-18 20:48:09 -04:00
KernelDeimos 66e8b37f70 dev: add dedupe_name option for app creation 2024-10-18 20:42:41 -04:00
KernelDeimos 4ce2dccc76 dev: update app approved_for props visibility
Allows owner users to read the approved_for properties on their own apps
2024-10-18 20:12:19 -04:00
KernelDeimos f5865daede fix: 1954f8-related issue
get-user-app-token was calling ll_mkdir with 'user' instead of 'actor'
2024-10-18 19:58:44 -04:00
KernelDeimos 1954f86680 fix(security): always use actor 2024-10-18 19:15:40 -04:00
KernelDeimos 94e15dbfa8 test: fix topics test and ServiceManager 2024-10-18 19:13:06 -04:00
jelveh 598a08ec45 Allow users to cancel a deploy operation before start 2024-10-18 16:07:01 -07:00
KernelDeimos 3c5d2af8c8 fix: small issue in Service.js 2024-10-18 15:53:40 -04:00
jelveh 29f5820129 Fix settings sidebar margin 2024-10-18 12:45:27 -07:00
KernelDeimos fb1216d488 fix: prevent code from breaking just because it was bundled 2024-10-18 15:06:08 -04:00
KernelDeimos 7922314840 dev: add generic pub/sub system for use anywhere
Dispatching and listening to events is non-trivial. The apparent
triviality is in implementing a list of listeners and calling them. The
non-triviality is in the nature of what happens to a system when it has
multiple different interfaces to register listeners and publish events.

This commit adds TopicsFeature, which allows any class extending
AdvancedBase to declare topics. A topic is a simple pub/sub channel.
TopicsFeature will manage the state of listeners so the class doesn't
need to. A GC-friendly mechanism for detaching listeners is also provided.
2024-10-17 22:56:00 -04:00
KernelDeimos 9b1f1817f5 dev: move service interface to trait 2024-10-17 22:56:00 -04:00
KernelDeimos 273a51fc53 dev: add ServiceManager
The ServiceManager will replace manual management of services within
initgui, and will also be used within puter.js. Eventually Puter's
backend might use this instead of the existing Container class, although
this will be a large change that needs to be done incrementally.

The difference between ServiceManager and Container is the logic behind
when initialization occurs. Rather than have all services initialized at
once when Container's init() method is called, services are initialized
as soon as their dependencies have been initialized.
2024-10-17 22:56:00 -04:00
jelveh 2a81825a6b Update default apps in the Launch menu 2024-10-17 16:14:24 -07:00
KernelDeimos 9535100c85 doc: add brainstorming for mountpoints 2024-10-17 03:00:35 -04:00
KernelDeimos 7980aafbd9 doc: add devlog from puter.js 2024-10-17 01:19:06 -04:00
ProgrammerIn-wonderland f0b7214a07 working persistence 2024-10-15 18:30:08 -04:00
ProgrammerIn-wonderland aae6fff340 adding locking to puter-save 2024-10-15 18:30:08 -04:00
ProgrammerIn-wonderland f0bc10f1e8 WIP persistence 2024-10-15 18:30:08 -04:00
KernelDeimos 1ea6d270f8 dev: add endpoint for GUI to query app file access 2024-10-15 16:19:11 -04:00
KernelDeimos fd7bd339ca dev: add Context to putility 2024-10-15 16:17:37 -04:00
Nariman Jelveh a2216aaea2 Merge pull request #805 from lohitkotni/patch-1
Update README.te.md
2024-10-14 20:53:37 -07:00
Surya Lohith Kotni a8e843297e Update README.te.md
fixed typo
2024-10-15 09:20:10 +05:30
Ibrahim H. 12a38b8258 Show a badge on README 2024-10-14 22:18:36 -04:00
Ibrahim H. f9b9565dab Create test workflow
basic test workflow setup, this allows checking that everything is fine on node v18 up to v22.
2024-10-14 22:18:36 -04:00
Zac0511 40f8634f24 Update bug_report.yaml 2024-10-14 22:16:04 -04:00
Zac0511 a22d9199f3 Update bug_report.yaml 2024-10-14 22:16:04 -04:00
Zac0511 551aed30be Update bug_report.yaml 2024-10-14 22:16:04 -04:00
Zac0511 0cd8404e87 Update and rename bug_report.md to bug_report.yaml 2024-10-14 22:16:04 -04:00
KernelDeimos 149684de01 dev: allow emulator app to access user files 2024-10-14 15:46:19 -04:00
KernelDeimos 9e88096e7e clean: remove a console.log 2024-10-14 15:19:52 -04:00
KernelDeimos e011df1a20 move: PuterAPIFilesystem 2024-10-14 15:19:18 -04:00
Nariman Jelveh 0f5f8bc591 Merge pull request #803 from lohitkotni/main
added telugu language translation
2024-10-14 09:20:57 -07:00
KernelDeimos 6d23369512 sync: add new page 2024-10-14 12:18:04 -04:00
loko 14bd643d4f added telugu language translation 2024-10-14 21:40:57 +05:30
KernelDeimos 3762037576 dev: oops 2024-10-12 00:01:33 -04:00
KernelDeimos 11fbcb27b0 dev: cache readdir 2024-10-11 23:51:38 -04:00
KernelDeimos 77f6bdcd6d dev: make puter.fs cache togglable 2024-10-11 18:39:58 -04:00
KernelDeimos 6ee7caaee1 dev: apply TTL cache for stat entries
Adds CachedFilesystem layer to client filesystem chain. Currently only
stat is implemented. The stat implementation will hold onto an entry for
3 seconds as per hardcoded configuration. Eventually, once invalidation
via websockets is working, this TTL should be extended.
2024-10-11 18:39:58 -04:00
KernelDeimos fc9a371e09 dev: add more to NariMethodsFeature 2024-10-11 18:39:58 -04:00
KernelDeimos 43c5402b7c feat(putility): trait method override support
Support for trait method overrides will make it possible to use putility
traits with the decorator pattern while using a proxy class to avoid
redundant re-implementation of proxy methods.

Use of the pattern described above will occur in the implementation of
client-side filesystem caching.
2024-10-11 18:39:58 -04:00
KernelDeimos c12ae2a923 dev: prepare puter.js fs for decorator pattern
- de-coupled xhr callback passing from the interface of the underlying
  filesystem implementation.
- This makes the interface to delegate calls more suitable for use with
  the decorator pattern.
- The decorator pattern will be used to manage the complexity of the
  caching layer by separating the concerns of different caching methods.
2024-10-11 18:39:58 -04:00
ProgrammerIn-wonderland 4f8304ec15 switch ne2k_pci to virtio 2024-10-11 18:14:38 -04:00
ProgrammerIn-wonderland d9805c0cab delete prompt-path 2024-10-11 17:06:32 -04:00
ProgrammerIn-wonderland fb41d2a51c change PWD to not use prompt-path and fix unicode issues 2024-10-11 17:06:32 -04:00
KernelDeimos 010282edf2 fix: don't display all apps for extensionless files
This hides database entries with empty types from the list of suggested
apps for files that have no extension. These entries should also be
removed from the database and the bug causing them should be fixed in
dev center.
2024-10-11 14:51:52 -04:00
KernelDeimos 38dcb60d3f fix: creating app shortcut in self-hosted
For some reason ll_write has an undefined `actor` when clicking "Add
Shortcut to Desktop" from Dev Center. This should be investigated
further.
2024-10-11 14:50:35 -04:00
Nariman Jelveh 3157186f4f close #798 2024-10-10 17:40:17 -07:00
KernelDeimos d4b96a17c8 dev: add RWLock to putility 2024-10-10 18:47:07 -04:00
KernelDeimos 37e7b6ad70 fix: disable thumbnails for AppData uploads 2024-10-10 15:03:22 -04:00
KernelDeimos 823ab28448 test: update test invocation 2024-10-10 03:19:28 -04:00
ProgrammerIn-wonderland b8490248c5 update 9p-puter driver with error handling 2024-10-09 20:36:03 -04:00
ProgrammerIn-wonderland 1e7e516d73 change submodule url 2024-10-09 20:36:03 -04:00
ProgrammerIn-wonderland 979bd06d70 9p automounting 2024-10-09 20:36:03 -04:00
ProgrammerIn-wonderland b145e30a90 feat: v86 9p server support 2024-10-09 20:36:03 -04:00
Nariman Jelveh d449367db5 Update loading.svg 2024-10-09 10:04:09 -07:00
Nariman Jelveh 9890e3a8be close #771 2024-10-08 19:51:57 -07:00
Nariman Jelveh d0940ccd21 close #776 2024-10-08 18:59:14 -07:00
KernelDeimos 0b9a9eec99 doc: oops 2024-10-08 18:41:01 -04:00
KernelDeimos 57d6da0858 doc: add scratch.md 2024-10-08 18:39:55 -04:00
KernelDeimos 7f1b870d30 feat: support readdir for directory symlinks 2024-10-08 18:31:39 -04:00
KernelDeimos c2a9506b48 fix: thumbnail service updates 2024-10-08 01:41:18 -04:00
ProgrammerIn-wonderland ed0a83ca9d dev: update v86, switch twisp to epoxy-server with twisp feature 2024-10-07 22:04:41 -04:00
4nshuman 857c3b88b3 added fflate to lint check 2024-10-06 21:27:03 +05:30
4nshuman 822d850513 purge JSZip 2024-10-06 21:25:46 +05:30
4nshuman e252567c88 Added progress dialog details 2024-10-06 21:19:42 +05:30
4nshuman f0f8e454f9 added Promises to handle multiple file creation and closing progress dialog 2024-10-06 20:27:12 +05:30
4nshuman a09dd29416 added empty directory check and file creation 2024-10-06 20:25:40 +05:30
4nshuman e992e4d5d4 unzipped directory creation 2024-10-06 20:25:10 +05:30
4nshuman 2a82579eb8 added unzip error handler 2024-10-06 20:23:10 +05:30
4nshuman a79cc040e8 implemented fflate unzip operation 2024-10-06 20:22:50 +05:30
4nshuman e5f0f46633 added blob to uInt8Array conversion 2024-10-06 20:22:07 +05:30
4nshuman 9a2e701683 eleminate JSZip invocation 2024-10-06 20:21:29 +05:30
4nshuman 00f2dbdcf0 added window hide delay config 2024-10-06 20:18:30 +05:30
4nshuman b9d7a1d2a1 added zip support for empty directories 2024-10-06 17:33:30 +05:30
4nshuman b9b8229099 fixed comments phrasing 2024-10-06 16:19:46 +05:30
4nshuman 5b477c2cac fixed module name 2024-10-06 16:10:40 +05:30
4nshuman 09d10cb29b rectified progress window for unzip operation 2024-10-06 16:03:09 +05:30
4nshuman f6541fc793 convention implemented definition header 2024-10-06 16:01:18 +05:30
4nshuman deb8c4e13b added status message terms 2024-10-06 16:00:01 +05:30
4nshuman a93236118f redirected unzip to helper method 2024-10-06 15:32:31 +05:30
4nshuman a9bebdd7f0 fixed typo 2024-10-06 15:26:26 +05:30
4nshuman dfe71d5965 modified zipping operationand integrated fflate 2024-10-05 23:47:22 +05:30
4nshuman f05f7454e9 added helper method to convert binary large object to uInt8Array for zipping operations 2024-10-05 23:45:54 +05:30
4nshuman 582c411c00 added fflate min js to the library 2024-10-05 23:44:04 +05:30
4nshuman f3625ed907 added terms for status message on zip operation 2024-10-05 23:43:43 +05:30
4nshuman 4c7b75ed67 added fflate on static asset and libPath 2024-10-05 23:43:15 +05:30
4nshuman 1929aaf5ef added fflate on libPath on puter-gui 2024-10-05 23:42:43 +05:30
4nshuman 01aaa07e87 added zip progress counter configurations 2024-10-05 23:41:45 +05:30
KernelDeimos c7b08d1b5e doc: tweak 2024-10-04 16:09:02 -04:00
KernelDeimos 1e0b8cfe7c doc: add troubleshooting steps for no build-essentials 2024-10-04 16:02:05 -04:00
KernelDeimos c135649551 move: notes.md 2024-10-03 18:20:51 -04:00
KernelDeimos 196531d118 dev: update handling of duplicate emails 2024-10-03 17:04:47 -04:00
KernelDeimos 822f3b8c45 dev: add notes and some updates to email logic 2024-10-03 14:54:40 -04:00
KernelDeimos 2c3065a70f test: register test for CleanEmailService 2024-10-02 21:30:14 -04:00
KernelDeimos 054b9c2864 dev: add service for cleaning email addresses 2024-10-02 17:51:43 -04:00
KernelDeimos 9db55fc5f7 fix: remove redundant openai model fallback 2024-10-02 15:14:46 -04:00
KernelDeimos 29fd595cf9 dev: rootfs-v0.2.0 2024-10-02 15:13:57 -04:00
KernelDeimos 9985996686 fix: app pseudonym in wrong conditional block 2024-09-30 20:38:25 -04:00
KernelDeimos 4febd81169 dev: app pseudonyms 2024-09-30 19:35:34 -04:00
KernelDeimos 8bc4122bea tweak: change phoenix help text when launched with -c 2024-09-30 19:16:10 -04:00
KernelDeimos 5ed8823a16 tidy: remove a console log 2024-09-30 18:11:25 -04:00
KernelDeimos 5317adf8a4 feat: allow passing cli args via url 2024-09-30 18:09:28 -04:00
KernelDeimos b6c0cb6abc feat: add -c flag for phoenix 2024-09-30 16:50:18 -04:00
KernelDeimos 6e1ed7ab04 dev: update emu load indicator 2024-09-30 16:50:03 -04:00
KernelDeimos 04c05a5bb8 fix: properly add owner object to fsentries 2024-09-27 16:30:13 -04:00
KernelDeimos a70d0dd088 fix: add progress bar fix 2024-09-27 15:08:19 -04:00
KernelDeimos eab2721f89 dev: use streaming decompression 2024-09-26 18:49:29 -04:00
KernelDeimos 545ac0097f tweak: ascii tux (important) 2024-09-26 18:28:13 -04:00
KernelDeimos 45cd3b79bb tweak: disable grace period by default 2024-09-26 15:47:47 -04:00
KernelDeimos 259877b677 fix: allow ETX to propagate to bash 2024-09-26 15:47:35 -04:00
KernelDeimos 08601ae2af feat: progress indicator for emulator 2024-09-25 23:47:10 -04:00
KernelDeimos d0535cf10b dev: add wasm bench 2024-09-25 21:45:03 -04:00
KernelDeimos fff8993200 fix: error deleting entry from My Websites window
This could not be tested locally due to another but only affecting
self-hosted installations. This will be tested in staging in the
meantime while the other bug is being fixed.
2024-09-23 17:55:54 -04:00
KernelDeimos b1b725a2eb tweak: image from CDN (for real this time) 2024-09-23 15:07:26 -04:00
KernelDeimos 68c4274dc3 tweak: image from CDN 2024-09-23 14:54:01 -04:00
Nariman Jelveh 288411c377 Update style.css 2024-09-22 15:46:48 -07:00
KernelDeimos 27b66254e3 dev: compress default image with brotli 2024-09-22 17:49:00 -04:00
Nariman Jelveh 3ce8da37eb close #772 2024-09-22 12:40:38 -07:00
KernelDeimos 07d3592d88 tweak: don't auto-start puter-linux for now 2024-09-21 15:39:19 -04:00
Nariman Jelveh 18fed60341 Merge pull request #770 from ruthwikchikoti/issue#736
feat: translate README.md to Dutch
2024-09-21 12:15:48 -07:00
Ruthwik Chikoti 31e2773743 feat: translate README.md to Dutch 2024-09-21 18:21:27 +05:30
Nariman Jelveh bd91839551 Don't allow background processes to change the browser's URL 2024-09-19 17:41:37 -07:00
KernelDeimos 4311b482fd fix: second half of connectToInstance 2024-09-18 21:02:51 -04:00
KernelDeimos cb324cc125 fix: error in process.handle_connection 2024-09-18 20:55:00 -04:00
KernelDeimos f4dd195245 dev: fix previous commit 2024-09-18 17:04:48 -04:00
KernelDeimos afc0ac8548 dev: attempt to fix process select issue 2024-09-18 17:01:02 -04:00
KernelDeimos 439653458e fix: quick patch to avoid columnify error 2024-09-18 16:22:26 -04:00
KernelDeimos 0456893789 dev: add emulator prod deployment 2024-09-18 16:21:07 -04:00
KernelDeimos f2acd83b72 fix: upsert subdomain check to insert only 2024-09-18 16:21:07 -04:00
KernelDeimos e3431cd7f5 dev: add build script for relay 2024-09-18 16:21:07 -04:00
KernelDeimos 48873b6d23 git: add epoxy-tls submodule 2024-09-18 16:21:07 -04:00
KernelDeimos 8aed3d9454 dev: prep for network build 2024-09-18 16:21:07 -04:00
KernelDeimos 25817bf6a2 dev: add puter-linux app to db migrations 2024-09-18 16:21:07 -04:00
KernelDeimos 4589ed95be dev: handle pty close
Return to phoenix shell when a pty stream is closed by twisp.

Pipes in phoenix with commands from the emulator do not appear to be
working properly, but something in there is working.
2024-09-18 16:21:07 -04:00
KernelDeimos 404fbaa4cb dev: add terminal multiplexing
This involves establishing the protocol through which phoenix instances
run a command on the emulator. The pty is able to communicate with the
terminal in both directions. This commit adds logs to be removed later.

There are a few things left that this commit does not address:
- handling close of delegate process
- handling sigint from phoenix to delegate process
- closing the connection to twisp
2024-09-18 16:21:07 -04:00
KernelDeimos bc83e90e33 tweak: use virtualization-optimized kernel 2024-09-18 16:21:07 -04:00
KernelDeimos e3d4a5f3b3 dev: multi-instance many-to-many app-to-app comms
I'll elaborate here because the commit name is confusing. Any time an
app gets a connection to another app, either because it launched that
app (or was launched by that app) or requested a connection to that app,
the ID the app gets to represent the app it's communicating with is now
a pseudo app id rather than the app instance ID. This accomplishes two
things:

1. It's more secure. There are multiple places where GUI assumes that
   knowing an app's instance ID means you can do things as that app.
2. Between the same two apps, there may now be more than one connection.
   This is useful for situations like Phoenix shell talking to the
   emulator in multiple separate instances to pipe commands. (this is
   coming later)
2024-09-18 16:21:07 -04:00
KernelDeimos 62634b0afe feat: add connectToInstance method to puter.ui 2024-09-18 16:21:07 -04:00
KernelDeimos e2cb6194bb dev: add startup apps, start emulator by default 2024-09-18 16:21:07 -04:00
KernelDeimos e1ec84877a dev: resize handling 2024-09-18 16:21:07 -04:00
KernelDeimos db3e0b5ce8 fix: simplify callback listener and fix async bug 2024-09-18 16:21:07 -04:00
KernelDeimos 21383eec3c dev: get basic PTY integration working 2024-09-18 16:21:07 -04:00
KernelDeimos 28adc4e5d5 dev: add emulator page 2024-09-18 16:21:07 -04:00
KernelDeimos 41e7526372 dev: add twisp submodule 2024-09-18 16:21:07 -04:00
KernelDeimos 2c0b8428c5 dev: add emulator image build 2024-09-18 16:21:07 -04:00
Nariman Jelveh 95112a9de6 Merge pull request #765 from 4nshuman/issue/737
Added Swedish translation | Other fixes
2024-09-14 09:32:10 -07:00
4nshuman cadd7453c4 added german translation link to the list 2024-09-14 20:17:02 +05:30
4nshuman 50c6e74f99 added swedish translation to the list 2024-09-14 20:16:35 +05:30
4nshuman a45def27a5 fixed translation list alphabetical order 2024-09-14 20:15:59 +05:30
4nshuman 8f6b3c07a9 added swedish translation file 2024-09-14 20:15:09 +05:30
4nshuman cc794fb70b added translation for german alt on image tag 2024-09-14 20:14:52 +05:30
Nariman Jelveh 480a1c440c Merge pull request #763 from bibekp-dev/Issue670/EnglishToGerman
Issue670/english to german
2024-09-12 09:48:08 -07:00
Bibek Panda c204cd366a Created and updated README.de.md for English To German Translation
German translation changes are committed in README.de.md file
2024-09-12 13:03:07 +05:30
Bibek Panda c0b3010192 Create README.de.md 2024-09-12 12:58:03 +05:30
Nariman Jelveh 58040c7596 Merge pull request #762 from the-heidi/patch-1 2024-09-11 20:35:20 -07:00
the-heidi 0743189ddb Update README.ko.md to fix phrasing issues 2024-09-11 20:30:38 -07:00
KernelDeimos 33de98107f fix: email change on account with unverified email
Changing the email address on an account that did not already have a
confirmed email would result in the email_confirmed column never being
set. This commit fixes that.

Additionally, an SQL statement using the unconfirmed email to identify a
row was changed so it now uses the user ID instead, which is safer.

Resolves: 759
2024-09-10 14:04:32 -04:00
Nariman Jelveh d38fb9f0e1 Update README.md 2024-09-10 08:59:41 -07:00
Nariman Jelveh 351b8cca3b Merge pull request #760 from gyarfasB/huntext
feat: hungarian readme translation
2024-09-10 08:53:59 -07:00
Gyárfás Balázs 89d11e3b0f translation-hun-readme 2024-09-10 14:02:10 +02:00
Nariman Jelveh a4a349a64a Update README.md 2024-09-07 09:50:04 -07:00
Nariman Jelveh 11ddbf70c8 Add link to Ukrainian README from the English README 2024-09-07 09:49:40 -07:00
Nariman Jelveh 6e7def5a66 Merge pull request #757 from SergiyZyuzko/translation/ukrainian
Ukrainian Translation added
2024-09-07 09:47:02 -07:00
Sergiy abb44b6d68 Ukrainian Translation added 2024-09-07 16:41:31 +00:00
KernelDeimos cc4ab1cb36 fix: html-webpack-plugin dev dep 2024-09-04 23:56:23 -04:00
KernelDeimos 6bdcae769d fix: double-echo in phoenix 2024-09-04 23:56:23 -04:00
KernelDeimos a33d721e21 fix phoenix WINSZ handling 2024-09-04 23:56:23 -04:00
Nariman Jelveh 7139d29749 Add link to Malayalam README in the English README 2024-09-04 22:03:26 -04:00
Nariman Jelveh 9e988eb012 Merge pull request #753 from rinogodson/malayalam-translation
Add Malayalam translation to README.md
2024-09-04 21:59:43 -04:00
Rino Godson 72c90778e8 Add Malayalam translation to README.md 2024-09-05 07:12:27 +05:30
Nariman Jelveh 64597e28fb temporarily remove lang files for further testing 2024-09-03 14:56:14 -04:00
Nariman Jelveh 1c5f48d451 Merge pull request #741 from Pulkitxm/translation_Ukrainian
translate README.md to Ukrainian
2024-09-03 14:52:59 -04:00
Nariman Jelveh 43eb614499 Merge pull request #743 from Pulkitxm/translation_Dutch
Add Dutch Readme content
2024-09-03 14:52:34 -04:00
Nariman Jelveh 25bb0652b8 Merge pull request #742 from Pulkitxm/translation_Swedish
Add Swedish Readme content
2024-09-03 14:52:24 -04:00
KernelDeimos 4910838ab1 fix: webpack error reporting + unintentional whitespace changes 2024-09-03 14:44:51 -04:00
Nariman Jelveh 57c2d72e21 Update UIWindow.js 2024-09-03 14:24:58 -04:00
Nariman Jelveh 8e56ac5ec7 Update UIWindow.js 2024-09-03 14:14:19 -04:00
Nariman Jelveh 9528cb0614 Add link to Armenian README in the English README 2024-09-03 11:55:05 -04:00
Nariman Jelveh 377c9f04b1 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-09-03 11:54:03 -04:00
Nariman Jelveh 9411f994e3 Merge pull request #751 from gng92/patch-1
Create README.hy.md
2024-09-03 11:53:36 -04:00
gng92 e8713dc5a5 Create README.hy.md
Added Armenian translation for ./doc/i18n/README.en.md (issue #735 )
2024-09-03 19:44:42 +04:00
KernelDeimos ed7d6dcbfb fix: dist 2024-09-02 21:30:22 -04:00
KernelDeimos d35026467e fix: use jq el for focus 2024-09-02 20:52:46 -04:00
KernelDeimos cd39bb5aa0 fix: fix sourcemap 2024-09-02 20:50:15 -04:00
KernelDeimos d07929da1b dev: add v86 submodule and app 2024-09-02 20:49:48 -04:00
Nariman Jelveh 1f7a4782d8 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-09-02 17:44:24 -04:00
Nariman Jelveh 94ec23b4c7 Remove fa.js temporarily 2024-09-02 17:44:17 -04:00
KernelDeimos 5ab3d88393 cleanup 2024-09-02 17:37:38 -04:00
KernelDeimos 18a24f614f dev: update ipc ready and app launched events 2024-09-02 17:37:38 -04:00
Nariman Jelveh 65c23ecd93 Merge pull request #748 from Sky-De/FarsiReadme
README.en.md translated to Farsi and added to project
2024-09-02 16:02:03 -04:00
skyDe 512f22857a README.en.md translated to Farsi and added to project 2024-09-01 06:18:06 -08:00
Nariman Jelveh 8e5711bf38 add link to Hebrew README 2024-08-31 14:41:49 -04:00
Nariman Jelveh 9acbd09da9 Merge pull request #747 from OrelsProjects/issue-732-translate-readme.md-from-english-to-hebrew
Create README.he.md
2024-08-31 14:41:00 -04:00
Orelsgit 4c936197e7 Create README.he.md 2024-08-31 21:00:25 +03:00
Nariman Jelveh e58de0db84 Merge pull request #746 from fauzipadlaw/main
No need word repetition for gambar  in Indonesian
2024-08-31 13:46:09 -04:00
Muhammad Fauzi 3acabc6c79 Merge branch 'HeyPuter:main' into main 2024-08-31 23:46:25 +07:00
Muhammad Fauzi ddbb4207f2 Update Pictures translation to Gambar, no word repetition for plural
The literal translation for Pictures IS Gambar-gambar, but after reviewing how it looks on live demo Puter, this translation seems a bit off, since other word like Videos is not Video-video, documents is not Dokumen-dokumen.

So, I think it's better to just translate Pictures to Gambar only. Indonesian actually does not care about singular and plural. If we really need to emphasize it plural, we just repeat the word. Which in this context, it is not that necessary to emphasize it.
2024-08-31 23:46:06 +07:00
Pulkit 4d1dd7a6db Add Dutch Readme content 2024-08-31 12:15:07 +05:30
Pulkit 194b150636 Add Swedish Readme content 2024-08-31 12:10:07 +05:30
Pulkit fe5ee39584 Add Ukrainian Readme content 2024-08-31 12:02:58 +05:30
Nariman Jelveh e295f64a90 Update README.md 2024-08-31 00:19:04 -04:00
Nariman Jelveh bb787a9ffc Merge pull request #740 from Pulkitxm/main
translate README.md to finnish
2024-08-30 21:14:52 -07:00
Pulkit ee0f063e22 Add finnish Readme content 2024-08-31 07:50:48 +05:30
KernelDeimos c9d09a78b6 fix: remove now-redundant loadScript call 2024-08-30 15:24:01 -07:00
KernelDeimos 46a0f714d1 fix: env for dev build 2024-08-30 15:24:01 -07:00
KernelDeimos 3092300a01 fix: mistakes 2024-08-30 15:24:01 -07:00
KernelDeimos 4b8910169a fix: add env to EmitPlugin config 2024-08-30 15:24:01 -07:00
KernelDeimos 72946f920c fix: remove accidentally left-over code 2024-08-30 15:24:01 -07:00
KernelDeimos 8ad435a0ea dev: bundle gui in dev 2024-08-30 15:24:01 -07:00
Nariman Jelveh 0d01d1f800 Update package-lock.json 2024-08-29 19:45:05 -07:00
KernelDeimos a4e9c7bdd7 rename folder 2024-08-29 22:24:55 -04:00
KernelDeimos cf24c3dd2a rename 2024-08-29 22:21:07 -04:00
KernelDeimos 3361043b9d chore: rename putil 2024-08-29 14:14:35 -07:00
KernelDeimos 5f7d1f589a fix: don't var when no var 2024-08-29 17:03:51 -04:00
Nariman Jelveh d43fc62d89 Remove menu-aim from the list of statically linked libs 2024-08-29 13:33:37 -07:00
KernelDeimos 1cd21ee658 tweak: cleanup and comment 2024-08-28 19:10:35 -07:00
KernelDeimos c86df11abd dev: launchApp as registered ipc handler
Add launchApp as a registered ipc handler, which will allow communication
between iframes (apps/puter.js) to be simplified.
2024-08-28 19:10:35 -07:00
KernelDeimos 813ee95cee fix: fallback to read access in /sign 2024-08-28 17:53:36 -04:00
Nariman Jelveh fa4bef8873 Update README.md 2024-08-28 14:35:39 -07:00
Nariman Jelveh 2c3d30d119 Merge pull request #727 from EngrAdnanAhmad/README-URDU
Translated README section to Urdu with correct clickable links
2024-08-28 14:34:30 -07:00
EngrAdnanAhmad a17f8408eb Translated README section to Urdu with correct clickable links 2024-08-29 02:26:52 +05:00
Nariman Jelveh f11dd8609d Merge pull request #726 from Zac0511/main
Update README.md
2024-08-28 13:09:24 -07:00
pikagaufre 8e4962beed Update README.md 2024-08-28 20:07:12 +00:00
Nariman Jelveh 18cfef65b8 Attempt to open apps from URL only if user is authenticated and desktop is loaded 2024-08-27 20:02:01 -07:00
KernelDeimos d1d0a9cccc tweak: update license for puter-wisp 2024-08-27 22:40:27 -04:00
KernelDeimos a4766278e4 tweak: package name for @heyputer/puter-wisp 2024-08-27 22:37:22 -04:00
KernelDeimos 2d1cb0050d dev: puter-wisp 2024-08-27 22:20:32 -04:00
Nariman Jelveh 2385457d12 Remove the redundant image/ prefix in base64 encoded app icons in dev center 2024-08-27 18:04:04 -07:00
Nariman Jelveh d285c2097f use flexbox for app navbar in dev center 2024-08-27 17:34:09 -07:00
Nariman Jelveh b1c91758da Fix sort bug in dev center 2024-08-27 17:27:40 -07:00
Nariman Jelveh 45925bacb6 Improve the usability of the Settings tab in Dev Center 2024-08-27 17:11:48 -07:00
KernelDeimos aa61c3009c fix: typo in a default file 2024-08-26 17:43:33 -04:00
KernelDeimos d2c7477b3b fix(docker): ensure temp admin pass shows 2024-08-26 17:42:15 -04:00
Nariman Jelveh 683c20ca7f Add links to Korean and Polish READMEs in the English README 2024-08-26 09:22:39 -07:00
Nariman Jelveh 4eda3244de Merge pull request #719 from VinayakPaka/issue-688
translated README.en.md from English to Polish
2024-08-26 09:19:27 -07:00
Nariman Jelveh 262cbc8de2 Merge pull request #718 from yomalbalooshi/main
Added README.ar.md
2024-08-26 08:51:52 -07:00
VinayakPaka 11304d82c3 translated README.en.md from English to Polish 2024-08-26 20:34:51 +05:30
Yasmeen Albalooshi 577e0d4ed9 Update README.md to have Arabic Translation 2024-08-26 10:54:05 +03:00
Yasmeen 5857248651 Add Arabic Translation file 2024-08-26 10:49:51 +03:00
decipher 155aab57d3 Removed else statement for closing registration in signup.js 2024-08-26 04:59:08 +02:00
Nariman Jelveh da5635b576 Show an error if file containing puter.js is loaded using the file: protocol 2024-08-25 14:38:19 -07:00
KernelDeimos 9a622004ea fix: fix 500 when check-app has bad url 2024-08-25 16:54:19 -04:00
Eric Dubé d8dc3ac122 Update instructions.md 2024-08-25 16:21:48 -04:00
Nariman Jelveh cd2eb656a1 Add link to Thai README in the English README 2024-08-25 12:30:42 -07:00
Nariman Jelveh dd5eff9780 Merge pull request #717 from Panyakornk/patch-1
Create README.th.md
2024-08-25 12:21:39 -07:00
Panyakornk 28a7f0ba1f Create README.th.md 2024-08-26 01:00:44 +07:00
decipher 222d7dede3 Added configuration option for closing registration
Set config.registration_closed=true; in ./src/backend/src/config.js to close registration
2024-08-25 19:28:12 +02:00
decipher 56b73b385d Update README.md 2024-08-25 18:06:21 +02:00
decipher 9c7dc53fc9 Update README.md
Added "Installation on public server"
2024-08-25 18:03:15 +02:00
Nariman Jelveh b43ecb490a Place github link and icon in the toolbar 2024-08-24 11:41:42 -07:00
Nariman Jelveh 3a82d13985 Merge pull request #712 from catalin-lungu/feature/english-to-romanian
Fixes issue #677: Translate README.md from English to Romanian
2024-08-24 10:46:59 -07:00
Catalin ea87223c46 Fixes issue #677: Translate README.md from English to Romanian 2024-08-24 20:31:47 +03:00
Nariman Jelveh 852f2ea944 Update README.md 2024-08-23 23:09:04 -07:00
Nariman Jelveh 9b0bd4f820 Add link to Romanian README in the English README 2024-08-23 23:08:15 -07:00
Nariman Jelveh 5af56a64c1 Merge pull request #711 from Atharva089/main
Added the README.ro.md file
2024-08-23 23:06:53 -07:00
Nariman Jelveh b5e4962e71 Update README.ro.md 2024-08-23 23:06:10 -07:00
Atharva Chavan 02c2801891 Added the README.ro.md file
Translated the README.en.md file from English to Romanian language.
2024-08-24 10:50:37 +05:30
KernelDeimos eb18550f41 fix(puterai): close streams 2024-08-23 19:42:53 -04:00
KernelDeimos 5a616f67dd fix(puterjs): fix settings object check 2024-08-23 16:39:30 -04:00
KernelDeimos 7f9d1e90b1 chore(puterai): update model 2024-08-23 16:09:22 -04:00
KernelDeimos 6cf7d0ae27 doc: update CONTRIBUTING.md 2024-08-23 15:09:25 -04:00
Nariman Jelveh cdc3947585 Merge pull request #709 from fauzipadlaw/main
Add link to Indonesian in main readme
2024-08-23 10:47:06 -07:00
Muhammad Fauzi c1ac30820d Merge branch 'main' of github.com:fauzipadlaw/puter 2024-08-24 00:29:06 +07:00
Muhammad Fauzi 194d0bcc6d Add link to Indonesian Readme in the English Readme 2024-08-24 00:28:27 +07:00
Nariman Jelveh 48324735ee Merge pull request #708 from fauzipadlaw/main
Add README.id.md
2024-08-23 10:18:51 -07:00
Muhammad Fauzi a549fc86bc Add README.id.md 2024-08-24 00:05:28 +07:00
KernelDeimos 53e7a91f18 feat(puterai): add groq 2024-08-23 00:16:29 -04:00
KernelDeimos 937528f767 fix(security): signing in public folders 2024-08-22 23:48:30 -04:00
Nariman Jelveh 2d39b9be77 Update index.js 2024-08-22 20:47:02 -07:00
KernelDeimos 055c628afd feat(puterai): add mistral 2024-08-22 23:28:08 -04:00
KernelDeimos fd86934bc9 feat: add method to list models 2024-08-22 22:24:03 -04:00
Nariman Jelveh 702618f81d Add link to Tamil Readme in the English Readme 2024-08-22 12:52:17 -07:00
Nariman Jelveh 617d7d7f55 Merge pull request #706 from yanniro2/main
Add Tamil readme file
2024-08-22 12:50:50 -07:00
Nariman Jelveh ff02b7bb9f Delete .vscode/settings.json 2024-08-22 12:50:29 -07:00
Nariman Jelveh d4e955a9e0 Add link to French README in the English README 2024-08-22 11:57:53 -07:00
Nariman Jelveh 9de4067e33 Merge pull request #707 from Morraycage/feat/fr-readme
feat(readme): add french readme respecting format and styling
2024-08-22 11:56:28 -07:00
Niroyan Kugaruban 2b507d1dd0 change 2024-08-22 14:47:24 -04:00
Nariman Jelveh 766a388660 fix badge url 2024-08-22 11:45:28 -07:00
Nariman Jelveh d36ef2d770 Fix image tag for the badge 2024-08-22 11:38:19 -07:00
Sayf Roumane 02e7e27796 feat(readme): add french readme respecting format and styling 2024-08-22 20:30:43 +02:00
KernelDeimos 7600d9b07c feat: add streaming to XHR driver client 2024-08-22 14:28:43 -04:00
Niroyan Kugaruban bdd24c69a5 Add Tamil readme file 2024-08-22 13:44:12 -04:00
Nariman Jelveh fa96c6d146 Add link to Bengali README to English README 2024-08-22 08:22:18 -07:00
Nariman Jelveh 502b346039 Merge pull request #705 from Priyanshu1035/readme
Added README.bn.md
2024-08-22 08:16:23 -07:00
Nariman Jelveh 07ca9ff6ea Fix license link 2024-08-22 08:15:27 -07:00
Priyanshu1035 ae1469e760 Merge branch 'readme' of https://github.com/Priyanshu1035/puter into readme 2024-08-22 19:29:49 +05:30
Priyanshu1035 4415e76a0b readmeinbengali 2024-08-22 19:29:10 +05:30
Nariman Jelveh 67e5219639 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-08-21 20:59:51 -07:00
Nariman Jelveh 6135054b3b add stream flag to the chat() method of puter.ai 2024-08-21 20:59:42 -07:00
KernelDeimos c08b897d4a fix(puterai): adapt message role for claude 2024-08-21 23:50:09 -04:00
Nariman Jelveh 3bface8c66 if first args in puter.chat is a string, it's the prompt 2024-08-21 20:38:03 -07:00
Nariman Jelveh dadaf5e8b1 Merge branch 'main' of https://github.com/HeyPuter/puter into main 2024-08-21 20:19:34 -07:00
Nariman Jelveh 43c18377eb Add support for multiple AI drivers via puter.js 2024-08-21 20:19:26 -07:00
KernelDeimos 21539a1651 tweak: let driver be called service 2024-08-21 23:18:12 -04:00
KernelDeimos bdfdf2331b feat(puterai): add togetherai 2024-08-21 23:17:02 -04:00
KernelDeimos 7b254e8676 tweak(puerai): add model parameter 2024-08-21 23:15:53 -04:00
KernelDeimos 439f52b5a3 feat(puterjs): add drivers module 2024-08-21 18:31:16 -04:00
KernelDeimos 32f0edb93a feat(api): add /lsmod 2024-08-21 18:31:16 -04:00
KernelDeimos d009cd0aaf feat(puterai): add claude 2024-08-21 18:31:16 -04:00
KernelDeimos 9d5963cdf5 feat(puterai): add streaming 2024-08-21 18:31:16 -04:00
Nariman Jelveh 2678679ab7 Correct the order of README translation links 2024-08-21 14:11:16 -07:00
Nariman Jelveh 7024e2ec91 Add ketboards.js to prod dependencies 2024-08-20 19:51:21 -07:00
Nariman Jelveh 921f522732 Remove redundant console.log 2024-08-20 19:37:35 -07:00
Nariman Jelveh 0b97bff1a2 Open public folders via URL only if deskotp has finished loading 2024-08-20 19:29:11 -07:00
Nariman Jelveh 5caf59f1bc make logger return empty string 2024-08-20 19:05:34 -07:00
KernelDeimos a002ad08e5 fix(security): remove unconfirmed_email from /whoami for apps 2024-08-20 21:42:42 -04:00
Nariman Jelveh b737570f73 Merge pull request #703 from FabioDePalma/ita
added readme file in Italian
2024-08-20 00:19:18 -07:00
FabioDePalma aa610befb1 added readme file in Italian 2024-08-20 09:05:13 +02:00
Nariman Jelveh 45d35eec72 Merge pull request #702 from Sam-SSTU/main
add Chinese, add language tag
2024-08-19 19:36:37 -07:00
Nariman Jelveh a3eb52702d Remove language badges and add link to the Chinese README inside the English README 2024-08-19 19:36:20 -07:00
Sam-SSTU fca88a82cc add Chinese, add language tag 2024-08-20 09:56:16 +08:00
KernelDeimos a7cdb70251 fix: ll_write 2024-08-19 21:27:53 -04:00
Nariman Jelveh 0705c2919f Remove redundant console.log()s 2024-08-19 15:21:51 -07:00
KernelDeimos cb4cab529a fix: don't try to sanitize null owners 2024-08-19 16:46:49 -04:00
KernelDeimos 3d92d0c619 tweak: show full scan in dev console 2024-08-19 14:50:32 -04:00
KernelDeimos 14820481b9 fix: missing key for feature flag perm check 2024-08-19 14:49:17 -04:00
KernelDeimos 6b4a19e12a fix: implicit app permissions bug 2024-08-19 00:58:23 -04:00
KernelDeimos 48fea77a20 fix: share services and features with apps 2024-08-18 22:44:27 -04:00
KernelDeimos 3819584d11 fix: admin user public folder 2024-08-18 15:55:01 -04:00
KernelDeimos 2386d87229 feat: add writable attribute to fs items 2024-08-18 15:55:01 -04:00
Nariman Jelveh fc26f88e60 Add link to the Vietnamese README in the English README 2024-08-18 11:22:17 -07:00
Nariman Jelveh d6c0af0b88 Merge pull request #700 from Priyanshu1035/readme
Added Readme in Vietnamese
2024-08-18 11:19:33 -07:00
Nariman Jelveh 625ae0eade Fix URL encoding of Vietnamese string 2024-08-18 11:18:42 -07:00
Priyanshu1035 380e946bbf updated PR to revert accidental changes 2024-08-18 23:23:58 +05:30
KernelDeimos b6b64d3bcc fix: add anti-csrf token for /revoke-session 2024-08-18 01:07:04 -04:00
KernelDeimos 9fa12d43fc fix: only show 2fa when available 2024-08-18 00:42:58 -04:00
KernelDeimos 6e325fa000 fix: requirement for email_confirmed in backend 2024-08-18 00:42:58 -04:00
Nariman Jelveh 38a6793c16 Merge pull request #698 from jsdmas/korean-language 2024-08-17 20:12:35 -07:00
JinHo Jang 11fb02c67b Create README.ko.md 2024-08-18 11:55:53 +09:00
KernelDeimos ef245b70df fix: do primary read of user after setting email_confirmed 2024-08-17 17:20:31 -04:00
KernelDeimos 0519b4a71b fix: require confirmed email for public folder 2024-08-17 16:36:59 -04:00
Nariman Jelveh 3f520e13f3 remove cover iframe for public folders 2024-08-17 12:29:32 -07:00
KernelDeimos ceecf54357 chore: sync versions 2024-08-17 15:13:12 -04:00
Nariman Jelveh 4e37064f47 fix issues public folder paths 2024-08-17 11:34:53 -07:00
Nariman Jelveh 88e8e33dc2 take into account feature flags for sharing 2024-08-17 11:11:36 -07:00
Nariman Jelveh 54d248e40b Add link to Turkish README in the English Readme 2024-08-17 09:53:38 -07:00
Nariman Jelveh 933ff7f1d0 Merge pull request #695 from emrhngngr/turkish-language
Created Read.me in Turkish.
2024-08-17 09:22:39 -07:00
Nariman Jelveh f43b52b0e1 fix the markdown link for the license 2024-08-17 09:15:00 -07:00
Emirhan 1c0adfc89a Created Read.me in Turkish. 2024-08-17 13:50:52 +03:00
KernelDeimos 4561b8937d feat: report feature flags in /whoami 2024-08-15 19:14:59 -04:00
Nariman Jelveh 8e39f41dd4 Encode Japanese string in the badge URL in README 2024-08-15 15:11:23 -07:00
Nariman Jelveh 8cb415675b Add link to Japanese README in the English Readme 2024-08-15 15:06:55 -07:00
Nariman Jelveh 276ace9f51 Merge pull request #691 from calreed-prof/main
Translate README.md to japanese
2024-08-15 15:04:24 -07:00
calreed-prof ac673cfae5 Created README.jp.md 2024-08-15 15:58:07 -06:00
Nariman Jelveh ada4bf9bbd Merge pull request #690 from abhishekpaturkar/issue-666-readme-hindi
added readme translation into hindi
2024-08-15 12:15:28 -07:00
abhishekpaturkar 70bf4bdfa1 translate README.md into hindi 2024-08-15 23:01:29 +05:30
Nariman Jelveh c5d112248a Merge pull request #689 from eltociear/patch-4
chore: update SystemFSEntryService.js
2024-08-15 08:38:46 -07:00
Ikko Eltociear Ashimine 959a0f4e39 chore: update SystemFSEntryService.js
propery -> property
2024-08-16 00:25:30 +09:00
KernelDeimos d032ab7d24 chore: update tiktoken 2024-08-14 21:08:29 -04:00
KernelDeimos a821dc67d5 tweak: add driver to implicit admin permissions 2024-08-14 19:42:57 -04:00
Nariman Jelveh 471514ea43 Add link to Spanish README in the English Readme 2024-08-14 15:05:51 -07:00
Nariman Jelveh 81cba63ea8 Merge pull request #685 from juank0205/issue-664-readme-spanish
translate README.md to spanish
2024-08-14 15:04:03 -07:00
KernelDeimos 209555c1d9 feat: make public folders a config opt-in 2024-08-14 17:20:49 -04:00
KernelDeimos 461ea3eae6 feat: add feature flag for /share 2024-08-14 17:20:49 -04:00
KernelDeimos d4319ea072 fix: sqlite condition in MonthlyUsageService 2024-08-14 17:20:09 -04:00
juank0205 0d3af0048f translate README.md to spanish 2024-08-14 16:09:26 -05:00
Nariman Jelveh bf4ba3f1d6 Update README.md 2024-08-14 12:38:00 -07:00
Nariman Jelveh df8ec416cd Merge pull request #683 from NFFY88/fix-readme-links
fix broken links in readme
2024-08-14 12:18:03 -07:00
Danil Buslaev 11695846fa fix broken links in readme 2024-08-14 21:34:44 +03:00
Nariman Jelveh 4cd94df90c Use the correct local dev address in README files 2024-08-14 10:54:09 -07:00
Nariman Jelveh 4a553ca67c Merge pull request #681 from NFFY88/russian-readme 2024-08-14 10:13:38 -07:00
Danil Buslaev 82dec20c07 added translation link to readme 2024-08-14 19:45:14 +03:00
Danil Buslaev 93d475b6b3 added readme translation into Russian 2024-08-14 19:20:18 +03:00
Nariman Jelveh c98d1ca25e Add link to the Portuguese README in the English README 2024-08-14 08:23:09 -07:00
Nariman Jelveh eea26207af Merge pull request #680 from TatianaMagnus/672-add-readme-portuguese-translation
672 Adding readme portuguese translation
2024-08-14 08:20:51 -07:00
Tatiana Magnus Vianna 3dd3ae02ae Adding readme portuguese translation 2024-08-14 11:51:38 -03:00
Nariman Jelveh 4f8786fc8f Add link to Danish README in the English Readme 2024-08-14 07:40:37 -07:00
Nariman Jelveh 94124eb576 Merge pull request #679 from JesHansen/issue/678-translate-readme-to-danish
Add Danish translation of README.en.md
2024-08-14 07:30:20 -07:00
Jes Bak Hansen ebaec99741 Add Danish translation of README.en.md 2024-08-14 15:40:45 +02:00
Nariman Jelveh f7924f30bc Create README.en.md 2024-08-14 00:59:58 -07:00
Nariman Jelveh f00e0cf4a6 Add YouTube link to README.md 2024-08-13 20:42:40 -07:00
Nariman Jelveh 448da65366 Merge pull request #662 from looz0/patch-1
Add security email to contact section
2024-08-12 19:33:24 -07:00
looz0 902bde3c2d Add security email to contact section 2024-08-12 19:20:21 -07:00
Nariman Jelveh e44d3d8133 Merge pull request #661 from Ranegg/Ranegg-fi-translations
Added Finnish translations related to issue #536
2024-08-12 10:04:01 -07:00
Ranegg cb8d0fa011 Added Finnish translations related to issue #536 2024-08-12 19:35:41 +03:00
Nariman Jelveh 5c7701d5de Merge pull request #659 from JoelSjogren/fix-548
completed translation english to swedish in sv.js
2024-08-11 09:59:42 -07:00
Joel Sjögren 0c4690e39c completed translation english to swedish in sv.js 2024-08-11 10:54:57 +02:00
Nariman Jelveh 37edb78fe9 Merge pull request #658 from NGunjyal01/fix/533/Translation-English-To-Danish
completed translation english to danish in da.js
2024-08-10 16:30:46 -07:00
KernelDeimos 3f07ead1b9 fix: add context to event listener aiife 2024-08-09 16:50:39 -04:00
unknown 00e8b81d16 completed translation english to danish in da.js 2024-08-09 23:16:52 +05:30
Nariman Jelveh 2898ff681f Merge pull request #657 from NGunjyal01/fix/531-Translatio-English-To-Portuguese
Completed Translation of English To Portuguese(Portugal)
2024-08-09 09:37:36 -07:00
unknown 200cc4680b Completed Transaltion of English To Portuguese from Portugal 2024-08-09 20:34:23 +05:30
KernelDeimos e60632343b sync: cross origin + small gui updates 2024-08-08 21:24:10 -04:00
KernelDeimos 783cf57934 sync: update hardcoded permissions 2024-08-08 17:23:30 -04:00
KernelDeimos 5b74b4affa fix: missing method in SLink 2024-08-08 17:22:34 -04:00
KernelDeimos e2f35b4844 dev: CLink and SLink classes 2024-08-08 15:13:32 -04:00
KernelDeimos c213b21bee move: BroadcastService to [+] BroadcastModule 2024-08-08 15:13:32 -04:00
KernelDeimos cea29645fe feat: add message encryption between Puter peers 2024-08-08 15:13:32 -04:00
KernelDeimos 476acae0e0 fix: disable unconfigured ai services 2024-08-05 16:04:25 -04:00
KernelDeimos c97688706e tweak: add boot error help 2024-08-05 15:59:09 -04:00
KernelDeimos 7aece26f4b tweak: add default driver mapping 2024-08-03 21:07:56 -04:00
KernelDeimos 9a9bd5eaf0 feat: add test_mode flag 2024-08-03 21:07:56 -04:00
KernelDeimos 78fa77d920 feat: add tts driver to puterai module 2024-08-03 21:07:56 -04:00
KernelDeimos fb26fdbc56 feat: add image generation driver to puterai module 2024-08-03 21:07:56 -04:00
KernelDeimos 4e3bd1831e feat: add chat completions driver to puterai module 2024-08-03 21:07:56 -04:00
KernelDeimos ef6671da18 feat: add --overwrite-config and configurable uuid masking
This is in preparation for the chat completions driver. OpenAI asks that
a user ID be provided in requests when service is being provided to
other users, so we deterministically generate different UUIDs for this
purpose to prevent user information from being exposed.
2024-08-03 21:07:56 -04:00
KernelDeimos f924d48b02 feat: add textract driver to puterai module 2024-08-03 21:07:56 -04:00
KernelDeimos b520783bf4 fix: add missing driver parameter to /call endpoint 2024-08-03 21:07:56 -04:00
KernelDeimos 1f059c330c dev: update FileFacade to use LLRead 2024-08-03 21:07:56 -04:00
Nariman Jelveh 475eb13fb3 add checkmark to selected language in the settings window 2024-08-02 14:00:44 -07:00
Nariman Jelveh 5db00abeaf Merge pull request #654 from Razy-F/Hebrew-translation 2024-08-02 08:01:06 -07:00
Nariman Jelveh fcb38aee87 Update translations.js to add Hebrew files 2024-08-01 23:53:56 -07:00
Razy F fa2702183c Add the new he.js translation filee 2024-08-02 09:06:34 +03:00
Nariman Jelveh a2255521f2 Escape rootItems in Dev Center before printing 2024-08-01 18:54:10 -07:00
Nariman Jelveh 09289b5004 Update README.md 2024-08-01 17:04:45 -07:00
Nariman Jelveh 53b67b3631 Merge pull request #650 from de1eb/main
Updated Korean translation file
2024-08-01 00:14:15 -07:00
Nariman Jelveh 11658beb18 Merge branch 'main' into main 2024-08-01 00:03:03 -07:00
Nariman Jelveh ed4d74d27d Merge pull request #648 from ljyamada/issue514
Complete Korean translation #541
2024-07-31 23:53:54 -07:00
Noru V e8b57debe9 Updated plural suffix problem related to showing the number of items when you use Explorer 2024-08-01 11:09:18 +09:00
Noru V 1063b6c1ab Updated Korean translation file 2024-08-01 10:28:24 +09:00
haruto eeda878554 Complete Korean translation #541
Complete Korean translation based on English file #541
2024-08-01 10:00:19 +09:00
Nariman Jelveh b35428ddd3 Merge pull request #646 from RandomStrangerOnTheInternet/main
Update Dutch translations
2024-07-31 17:07:16 -04:00
KernelDeimos 8b11937365 dev: fix incomplete support for multipart driver requests 2024-07-31 17:06:50 -04:00
KernelDeimos 7a09c5c47a doc: add example requests 2024-07-31 17:06:50 -04:00
KernelDeimos c28f2cb4df dev: add service to test images through drivers 2024-07-31 17:06:50 -04:00
Nariman Jelveh ade66bd1da escape unescaped single quote causing syntax error 2024-07-31 17:04:22 -04:00
RandomStrangerOnTheInternet c7ab7e04a6 Update Dutch translations (fixes https://github.com/HeyPuter/puter/issues/543) 2024-07-31 22:56:36 +02:00
Nariman Jelveh 1e753843d2 Remove some of the unused component imports 2024-07-28 12:41:52 -07:00
KernelDeimos 02504690cf test: add database migration tests 2024-07-28 04:02:16 -04:00
KernelDeimos d0e461e206 fix: sqlite migrations error
This issue was caused by an INSERT statement which adds the admin user
to the admin group. The admin user is created at initialization, so for
new installs it does not exist at the time migration scripts are run.
Additionally, new javascript-coded migrations (.mig.js) would not have
run for new installs because of redundant (WET; not DRY) code for
initial setup.

This commit also improves error handling of the migration service, which
was necessary to diagnose this issue.

In the future, setup always needs to be tested after updating migration
scripts, even though migration of existing databases is where most of
the issues will happen.

Resolves: #639
2024-07-27 18:54:17 -04:00
Nariman Jelveh 1c5ef01668 Merge pull request #640 from BryarGh/edit-kurdish-template
Update Kurdish language template
2024-07-27 14:47:04 -07:00
Nariman Jelveh c717746646 Use the english version of the license header but retain the credit to Bryar Ghafoor 2024-07-27 14:07:24 -07:00
Bryar Ghafoor fe119756b5 Update Kurdish language template 2024-07-27 23:19:24 +03:00
KernelDeimos 70787ffa2c tweak: print new password when resetting pass via server console 2024-07-26 22:43:11 -04:00
Nariman Jelveh 840436a04c Merge pull request #638 from fauzipadlaw/main
Add Indonesian Translation for i18n
2024-07-26 12:54:05 -07:00
Muhammad Fauzi 033643b0e7 feat: Add Indonesian Translation for i18n 2024-07-27 02:45:05 +07:00
KernelDeimos 654e0b9333 move: move selfhosting-related services to a module 2024-07-26 01:23:22 -04:00
KernelDeimos 6213806aba dev: move driver arg types to a registry 2024-07-25 23:19:54 -04:00
KernelDeimos af3180a57f dev: add monthly usage to new call method 2024-07-25 23:19:54 -04:00
KernelDeimos 8be7a7d219 dev: add logical rate-limit to new call method 2024-07-25 23:19:54 -04:00
KernelDeimos 780a993465 dev: move policy selection to call_new_ 2024-07-25 23:19:54 -04:00
KernelDeimos ea409d1578 dev: begin using Invoker for driver calls 2024-07-25 23:19:54 -04:00
KernelDeimos 20b58ddcb5 dev: add Invoker 2024-07-25 23:19:54 -04:00
KernelDeimos 9e38e048c1 dev: prepare to implement policy enforcer 2024-07-25 23:19:54 -04:00
KernelDeimos e514dfcf50 fix: prevent large logs from service events (2) 2024-07-25 23:19:54 -04:00
KernelDeimos d5ec40078f dev: begin adding new driver call method 2024-07-25 23:19:54 -04:00
KernelDeimos e0d30f041b dev: move implied system perms 2024-07-25 23:19:54 -04:00
KernelDeimos 984ae9e6a2 feat: add password reset from server console 2024-07-25 23:19:54 -04:00
KernelDeimos 580fbdb113 tweak: record time for permission scans 2024-07-25 23:19:54 -04:00
KernelDeimos cca19ad495 dev: remove svc_permission.check 2024-07-25 23:19:54 -04:00
KernelDeimos 191be84e32 dev: migrate svc_permission check() to scan() 2024-07-25 23:19:54 -04:00
KernelDeimos 3b85e4eeba dev: migrate ACLService to use scan() 2024-07-25 23:19:54 -04:00
KernelDeimos a0f0151446 dev: improve permission scan reading 2024-07-25 23:19:54 -04:00
KernelDeimos 4a6055d239 dev: add user-app to permission scanning 2024-07-25 23:19:54 -04:00
KernelDeimos 54471fada9 feat: add server command to scan permissions 2024-07-25 23:19:54 -04:00
KernelDeimos c9ded89b22 feat: grant user driver perms from admin 2024-07-25 23:19:54 -04:00
KernelDeimos f0c36a1cdf feat: replace default_user with admin 2024-07-25 23:19:54 -04:00
KernelDeimos d1261460ba dev: obtain driver permission from system user 2024-07-25 23:19:54 -04:00
KernelDeimos ab156297a7 feat: add system user 2024-07-25 23:19:54 -04:00
KernelDeimos 2cd68100d2 refactor: add traits and services as drivers 2024-07-25 23:19:54 -04:00
KernelDeimos 8beda66328 data: add extra sound 2024-07-25 18:28:16 -04:00
KernelDeimos 5fee393b67 data: add startup and shutdown chimes 2024-07-25 18:01:10 -04:00
Nariman Jelveh f30bbbd375 Add translation template for Kurdish 2024-07-25 14:48:12 -07:00
Nariman Jelveh e7c72e079b Merge pull request #633 from Zac0511/main
Add badges
2024-07-25 10:36:35 -07:00
Zac0511 6cfea963a0 Add badges
Added install badges, Puter.js badges, and source Figma files
2024-07-25 17:33:10 +02:00
Nariman Jelveh a28df490ba Merge pull request #632 from Zac0511/patch-2
Update README.md
2024-07-25 08:07:41 -07:00
Zac0511 5c49e83378 Update README.md
Added the license shield
2024-07-25 13:00:28 +02:00
Zac0511 d22abb36cb Update README.md
Added two shields displaying the repo size and latest version, and gets updated automatically
2024-07-25 12:22:24 +02:00
Nariman Jelveh 8a5302c8e2 Merge pull request #619 from secondtruth/issue-template-meta
Add issue template for meta suggestions
2024-07-24 16:34:46 -07:00
Nariman Jelveh 9250e23d96 Update meta.md 2024-07-24 16:34:33 -07:00
Zac0511 bef38dfc96 meta: Create config.yml to add Puter Discord to the issue screen (#631)
This adds a config file which will show the Puter Discord Server in the issue menu, allowing users to quickly ask help on the Puter Discord
2024-07-24 16:24:19 -04:00
Nariman Jelveh 22d7134802 Pass window.crossOriginIsolated value to the popup 2024-07-24 12:36:19 -07:00
KernelDeimos 48c819ac73 chore: update SLA for chat model
Resolves: #630
2024-07-24 13:35:26 -04:00
KernelDeimos fa9cc8efcf fix: prevent large logs from service events (1) 2024-07-24 02:31:45 -04:00
KernelDeimos 5d5f5660b4 feat: add options to disable winston and devwatch 2024-07-24 01:52:07 -04:00
Nariman Jelveh cc0800d60a Remove unnecessary console.log calls 2024-07-22 19:43:50 -07:00
Christian Neff fe63839bbb Add issue template for meta suggestions 2024-07-20 19:38:22 +02:00
3026 changed files with 562827 additions and 208448 deletions

No files matched your search

+36
View File
@@ -1,4 +1,40 @@
.dockerignore
Dockerfile
docker-compose.yml
# Dev / build artifacts (recreated inside the build stage)
node_modules
dist
src/gui/dist
src/puter-js/dist
*.tsbuildinfo
# Local runtime data
volatile
config.json
config.dev.json
/puter
# OS / editor
.DS_Store
.vscode
.idea
# Git / CI
.git
.github
# Logs
*.log
npm-debug.log*
.npm
# Tests / coverage
coverage
.nyc_output
# Secrets
.env
.env.*
creds*
*.pem
+18 -1
View File
@@ -1 +1,18 @@
PORT=4000
# Copy this file to `.env`, fill in the secrets, and `docker compose -f
# docker-compose.full.yml up -d`. None of the defaults below are safe for
# anything beyond a local laptop test.
# ── Public-facing ports (Caddy) ---------------------------------------
HTTP_PORT=80
# HTTPS_PORT=443 # uncomment after you enable TLS in caddy/Caddyfile
# ── MariaDB ------------------------------------------------------------
MARIADB_ROOT_PASSWORD=replace-with-strong-password
MARIADB_DATABASE=puter
MARIADB_USER=puter
MARIADB_PASSWORD=replace-with-strong-password
# ── S3 (RustFS) --------------------------------------------------------
S3_ACCESS_KEY=puter
S3_SECRET_KEY=replace-with-strong-secret
S3_BUCKET=puter-local
+61
View File
@@ -0,0 +1,61 @@
# Default owner, including backend and SDK areas without a specialist below.
# The last matching rule takes precedence.
* @Salazareo
# GUI
/src/gui/ @jelveh @Salazareo
# Documentation, developer site, and CLI
/doc/ @reynaldichernando
/src/docs/ @reynaldichernando
/src/dev-center/ @reynaldichernando
/src/cli/ @reynaldichernando
# Backend: AI, hosting, workers, networking, and WebDAV
/src/backend/controllers/puterai/ @ProgrammerIn-wonderland
/src/backend/controllers/hosting/ @ProgrammerIn-wonderland
/src/backend/controllers/webdav/ @ProgrammerIn-wonderland
/src/backend/controllers/wisp/ @ProgrammerIn-wonderland
/src/backend/drivers/ai-*/ @ProgrammerIn-wonderland
/src/backend/drivers/util/ @ProgrammerIn-wonderland
/src/backend/drivers/workers/ @ProgrammerIn-wonderland
/src/backend/services/localworker/ @ProgrammerIn-wonderland
/src/backend/stores/subdomain/ @ProgrammerIn-wonderland
/extensions/workerSandbox* @ProgrammerIn-wonderland
/src/worker/ @ProgrammerIn-wonderland
/src/worker-types/ @ProgrammerIn-wonderland
/src/backend/controllers/peer/ @ProgrammerIn-wonderland
# Backend: sharing, permissions, and teams
/src/backend/controllers/share/ @jfcastro92
/src/backend/controllers/team/ @jfcastro92
/src/backend/services/share/ @jfcastro92
/src/backend/services/permission/ @jfcastro92
/src/backend/services/acl/ @jfcastro92
/src/backend/services/team/ @jfcastro92
/src/backend/services/apps/AppPermissionService* @jfcastro92
/src/backend/stores/share/ @jfcastro92
/src/backend/stores/permission/ @jfcastro92
/src/backend/stores/group/ @jfcastro92
/src/backend/stores/team/ @jfcastro92
# SDK: AI, hosting, workers, and networking
/src/puter-js/src/modules/ai/ @ProgrammerIn-wonderland
/src/puter-js/src/modules/hosting/ @ProgrammerIn-wonderland
/src/puter-js/src/modules/Workers* @ProgrammerIn-wonderland
/src/puter-js/src/modules/networking/ @ProgrammerIn-wonderland
/src/puter-js/src/lib/networkUtils* @ProgrammerIn-wonderland
/src/puter-js/tests/api/suites/ai.suite.ts @ProgrammerIn-wonderland
/src/puter-js/tests/api/suites/hosting.suite.ts @ProgrammerIn-wonderland
/src/puter-js/tests/api/suites/workers.suite.ts @ProgrammerIn-wonderland
/src/puter-js/tests/api/suites/net.suite.ts @ProgrammerIn-wonderland
/src/puter-js/src/modules/Peer* @ProgrammerIn-wonderland
# SDK: sharing and permissions
/src/puter-js/src/modules/perms/ @jfcastro92
/src/puter-js/src/modules/FileSystem/operations/share* @jfcastro92
/src/puter-js/src/modules/FileSystem/operations/unshare* @jfcastro92
/src/puter-js/src/modules/FileSystem/operations/getShares* @jfcastro92
/src/puter-js/src/modules/FileSystem/operations/listShared* @jfcastro92
/src/puter-js/tests/api/suites/perms.suite.ts @jfcastro92
/src/puter-js/tests/api/suites/sharing.suite.ts @jfcastro92
+1
View File
@@ -0,0 +1 @@
github: ['HeyPuter']
-11
View File
@@ -1,11 +0,0 @@
---
name: App idea
about: Suggest a potential app for Puter
title: ''
labels:
- app-request
assignees: ''
---
-25
View File
@@ -1,25 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Issue Description**
**Steps to Reproduce**
**Expected & Actual Behavior**
**Addition Information or Screenshots (if applicable)**
**Deployment**
- [ ] Production (puter.com)
- [ ] Development (`npm run start`)
- [ ] Docker (via `docker run`)
- [ ] Docker (via `docker-compose`)
**Puter version (if accessible)**
> Click the profile button on the top-right, then "Settings". The version number will be printed at the bottom
-10
View File
@@ -1,10 +0,0 @@
---
name: Feature request
about: Suggest an idea for Puter
title: ''
labels: idea
assignees: ''
---
@@ -1,10 +0,0 @@
---
name: Idea for Improvement
about: An enhancement for an existing feature on Puter
title: ''
labels: enhancement
assignees: ''
---
+20
View File
@@ -0,0 +1,20 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
ignore:
- dependency-name: "*"
update-types: ["version-update:semver-major", "version-update:semver-minor"]
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
@@ -0,0 +1,49 @@
name: AI Provider Integration Tests
# Hits real provider APIs with cheap models, so this workflow is
# manually triggered only. Each provider's test reads its credential
# from PUTER_TEST_AI_<PROVIDER>_API_KEY and skips itself silently if
# the secret is missing.
on:
workflow_dispatch:
permissions:
contents: read
jobs:
ai-test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: '24'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run AI provider integration tests
# Vitest treats positional args as filename substring filters.
# The pattern matches every `*.integration.test.ts` file and
# nothing else — the regular backend test suite stays out.
run: npm run test:backend -- integration.test
env:
CI: 'true'
PUTER_TEST_AI_CLAUDE_API_KEY: ${{ secrets.PUTER_TEST_AI_CLAUDE_API_KEY }}
PUTER_TEST_AI_OPENAI_API_KEY: ${{ secrets.PUTER_TEST_AI_OPENAI_API_KEY }}
PUTER_TEST_AI_GEMINI_API_KEY: ${{ secrets.PUTER_TEST_AI_GEMINI_API_KEY }}
PUTER_TEST_AI_GROQ_API_KEY: ${{ secrets.PUTER_TEST_AI_GROQ_API_KEY }}
PUTER_TEST_AI_MISTRAL_API_KEY: ${{ secrets.PUTER_TEST_AI_MISTRAL_API_KEY }}
PUTER_TEST_AI_DEEPSEEK_API_KEY: ${{ secrets.PUTER_TEST_AI_DEEPSEEK_API_KEY }}
PUTER_TEST_AI_XAI_API_KEY: ${{ secrets.PUTER_TEST_AI_XAI_API_KEY }}
PUTER_TEST_AI_OPENROUTER_API_KEY: ${{ secrets.PUTER_TEST_AI_OPENROUTER_API_KEY }}
PUTER_TEST_AI_TOGETHER_API_KEY: ${{ secrets.PUTER_TEST_AI_TOGETHER_API_KEY }}
PUTER_TEST_AI_MOONSHOT_API_KEY: ${{ secrets.PUTER_TEST_AI_MOONSHOT_API_KEY }}
PUTER_TEST_AI_ZAI_API_KEY: ${{ secrets.PUTER_TEST_AI_ZAI_API_KEY }}
PUTER_TEST_AI_ELEVENLABS_API_KEY: ${{ secrets.PUTER_TEST_AI_ELEVENLABS_API_KEY }}
+149
View File
@@ -0,0 +1,149 @@
name: Backend Tests
# Always triggers so it can be a required PR check; the `changes` job below
# decides whether backend/extension paths actually changed (test-only changes
# match the same globs, since tests are co-located with the code), and every
# other job is skipped — not absent — when they didn't, which still satisfies
# a required check. puter.js SDK changes are covered by puterjs-tests.yaml.
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
changes:
runs-on: ubuntu-latest
outputs:
backend: ${{ steps.filter.outputs.backend }}
steps:
- uses: actions/checkout@v7
- uses: dorny/paths-filter@v4
id: filter
with:
filters: |
backend:
- 'src/backend/**'
- 'extensions/**'
- 'tools/**'
- 'package.json'
- 'package-lock.json'
- 'tsconfig.json'
- 'tsconfig.build.json'
- '.github/workflows/backend-tests.yaml'
# `tsconfig.build.json` builds with `noCheck: true`, so nothing else in CI
# runs the type checker and a missing export compiles to `undefined`,
# surfacing only when the call is finally reached at runtime. This diffs
# against tools/typecheck-baseline.json and fails only on *new* errors.
#
# The consuming repo runs an equivalent gate, but only once someone bumps the
# submodule pointer — too late to keep the error off this repo's default
# branch. Hence a gate here, on this repo's own pull requests.
#
# Its own job rather than a step in `test`: that one runs a base/PR matrix for
# coverage comparison, and the check only needs the PR ref, once.
typecheck:
needs: changes
if: needs.changes.outputs.backend == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: '24'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Type check (new errors only)
run: npm run typecheck
# `needs.changes` gates the steps below, not this job, on purpose: a
# job-level `if` on a matrix job skips the whole job as one unexpanded
# check ("test (${{ matrix.artifact }})", literally, since there's no
# matrix context to fill it in) instead of the two real per-artifact
# checks a required rule pins to ("test (base)" / "test (pr)") — so the
# required check never gets reported and the PR blocks forever. Letting
# the matrix always expand keeps the check names stable either way.
test:
needs: changes
# Overrides the default matrix naming, which would otherwise bake the
# base/head branch name (matrix.ref) into the check name — making it a
# different string on every PR and impossible to pin as a required check.
name: test (${{ matrix.artifact }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- ref: ${{ github.base_ref }}
artifact: base
- ref: ${{ github.head_ref }}
artifact: pr
steps:
- name: Checkout ${{ matrix.ref }}
if: needs.changes.outputs.backend == 'true'
uses: actions/checkout@v7
with:
ref: ${{ matrix.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Set up Node.js
if: needs.changes.outputs.backend == 'true'
uses: actions/setup-node@v7
with:
node-version: '24'
cache: 'npm'
- name: Install dependencies
if: needs.changes.outputs.backend == 'true'
run: npm ci
- name: Run backend tests with coverage
if: needs.changes.outputs.backend == 'true'
run: npm run test:backend -- --coverage
env:
CI: 'true'
- name: Upload coverage artifact
if: needs.changes.outputs.backend == 'true' && !cancelled()
uses: actions/upload-artifact@v7
with:
name: backend-coverage-${{ matrix.artifact }}
path: src/backend/coverage/
retention-days: 14
report-coverage:
needs: [changes, test]
if: always() && needs.changes.outputs.backend == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Download PR coverage
uses: actions/download-artifact@v8
with:
name: backend-coverage-pr
path: src/backend/coverage
- name: Download base coverage
uses: actions/download-artifact@v8
with:
name: backend-coverage-base
path: coverage-base
- name: Report coverage on PR
uses: davelosert/vitest-coverage-report-action@v2
with:
json-summary-path: src/backend/coverage/coverage-summary.json
json-final-path: src/backend/coverage/coverage-final.json
json-summary-compare-path: coverage-base/coverage-summary.json
@@ -0,0 +1,25 @@
name: Dependabot auto-merge
on: pull_request
permissions:
contents: write
pull-requests: write
jobs:
automerge:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v3
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Enable auto-merge for patch updates
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+89 -70
View File
@@ -1,84 +1,103 @@
#
name: Docker Image CI
# Configures this workflow to run every time a change is pushed to the
# branch called `main`.
# Two ways in:
# - push of a calver tag (YY.MM or YY.MM.p) → publishes <version>, latest, main
# - workflow_dispatch → publishes latest + main from whichever ref the user
# picks in the Actions UI. Used to fast-forward :latest/:main when the
# branch has moved ahead of the most recent release tag.
on:
push:
tags:
- '*.*.*'
branches:
- 'main'
push:
tags:
- '[0-9][0-9].[0-9][0-9]'
- '[0-9][0-9].[0-9][0-9].[0-9]*'
workflow_dispatch:
inputs:
push_latest:
description: 'Push :latest tag'
type: boolean
default: true
push_main:
description: 'Push :main tag'
type: boolean
default: true
# Defines two custom environment variables for the workflow. These are used
# for the Container registry domain, and a name for the Docker image that
# this workflow builds.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
# There is a single job in this workflow. It's configured to run on the
# latest available version of Ubuntu.
jobs:
build-and-push-image:
runs-on: ubuntu-latest
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions
# in this job.
permissions:
contents: read
packages: write
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
steps:
- name: Validate calver tag
if: github.event_name == 'push'
env:
REF_NAME: ${{ github.ref_name }}
run: |
if ! [[ "$REF_NAME" =~ ^[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]; then
echo "Tag '$REF_NAME' does not match YY.MM or YY.MM.p calver format."
exit 1
fi
# Uses the `docker/login-action` action to log in to the Container
# registry using the account and password that will publish the packages.
# Once published, the packages are scoped to the account defined here.
- name: Log in to GitHub Package Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Log in to GitHub Package Container registry
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about)
# to extract tags and labels that will be applied to the specified image.
# The `id` "meta" allows the output of this step to be referenced in
# a subsequent step. The `images` value provides the base name for the
# tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
tags: |
type=semver,pattern={{version}}
type=ref,event=branch
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
# This step uses the `docker/build-push-action` action to build the
# image, based on your repository's `Dockerfile`. If the build succeeds,
# it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the
# set of files located in the specified path. For more information, see
# "[Usage](https://github.com/docker/build-push-action#usage)" in the
# README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image
# with the output from the "meta" step.
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v6
with:
images: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
heyputer/puter
# type=ref,event=tag only emits on tag pushes, so manual runs skip
# the calver tag and just publish whichever of latest / main the
# dispatch inputs asked for. On a tag push, both default to true.
tags: |
type=ref,event=tag
type=raw,value=latest,enable=${{ github.event_name == 'push' || inputs.push_latest }}
type=raw,value=main,enable=${{ github.event_name == 'push' || inputs.push_main }}
- name: Build and push Docker image
uses: docker/build-push-action@v7
with:
platforms: linux/amd64,linux/arm64
context: .
push: true
provenance: mode=max
sbom: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Sync README to Docker Hub
uses: peter-evans/dockerhub-description@v5
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: heyputer/puter
readme-filepath: ./README.md
+27
View File
@@ -0,0 +1,27 @@
name: Docs Build
on:
pull_request:
paths:
- 'src/docs/**'
jobs:
build-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: '24'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build docs
run: npm run build
working-directory: src/docs
+3 -3
View File
@@ -9,7 +9,7 @@ jobs:
update-release-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v7
- name: Setup Git
run: |
git config user.name github-actions
@@ -20,7 +20,7 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
branch: release
- uses: actions/checkout@v4
- uses: actions/checkout@v7
if: steps.find-pr.outputs.number == ''
with:
ref: release
@@ -31,7 +31,7 @@ jobs:
git reset --hard main
- name: Create/Update PR
if: steps.find-pr.outputs.number == ''
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Update release branch
+18
View File
@@ -0,0 +1,18 @@
name: Notify HeyPuter
on:
push:
branches:
- main
jobs:
notify:
runs-on: ubuntu-latest
steps:
- name: Trigger heyputer build
run: |
curl -X POST \
-H "Authorization: token ${{ secrets.HEYPUTER_DISPATCH_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/HeyPuter/heyputer/dispatches \
-d '{"event_type":"puter-main-updated","client_payload":{"puter_ref":"main"}}'
+206
View File
@@ -0,0 +1,206 @@
name: Puter.js API Tests
# Always triggers so it can be a required PR check; the `changes` job below
# decides whether puter.js-relevant paths actually changed (the suites live
# in src/puter-js/tests, so test-only changes are covered by the same glob,
# plus the pieces the runners depend on: the worker preamble, the in-memory
# test env in testUtil, and the backend vitest config the API-tests config
# extends), and every other job is skipped — not absent — when they didn't,
# which still satisfies a required check. Backend and extension changes run
# backend-tests.yaml instead.
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
changes:
runs-on: ubuntu-latest
outputs:
puterjs: ${{ steps.filter.outputs.puterjs }}
steps:
- uses: actions/checkout@v7
- uses: dorny/paths-filter@v4
id: filter
with:
filters: |
puterjs:
- 'src/puter-js/**'
- 'src/worker/**'
- 'src/backend/testUtil.ts'
- 'src/backend/vitest.config.ts'
- 'tools/**'
- 'package.json'
- 'package-lock.json'
- '.github/workflows/puterjs-tests.yaml'
# The JSDoc in src/puter-js/src is the source of truth for the SDK's public
# types. The declarations shipped to npm are generated from it at build time
# and never committed, so what needs guarding is the JSDoc itself: this
# generates the declarations and type-checks the published surface without
# skipLibCheck, which is how broken re-exports used to go unnoticed.
#
# Its own job rather than a step in `test`: that one builds bundles and
# installs a browser, and this needs neither.
types:
needs: changes
if: needs.changes.outputs.puterjs == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: '24'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Check the puter.js JSDoc produces declarations that type-check
run: npm run check:puterjs:types
test:
needs: changes
if: needs.changes.outputs.puterjs == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: '24'
cache: 'npm'
- name: Install dependencies
run: npm ci
# The runners exercise the built artifacts: the SDK bundle
# (src/puter-js/dist) for node + browser, and the worker preamble
# (src/worker/dist) for workerd.
- name: Build puter.js SDK and worker preamble
run: npm run build:workerLib
- name: Install Playwright chromium
run: npx playwright install --with-deps chromium
- name: Run puter.js API tests (node, browser, workerd)
run: npm run test:puterjs
env:
CI: 'true'
# SDK coverage on both refs, reported as a PR comment — same shape as
# backend-tests.yaml. This run uses the istanbul-instrumented bundle
# (the `test` job above keeps exercising the production build).
# `needs.changes` gates the steps below, not this job, on purpose: a
# job-level `if` on a matrix job skips the whole job as one unexpanded
# check ("coverage (${{ matrix.artifact }})", literally, since there's no
# matrix context to fill it in) instead of two real per-artifact checks —
# confusing to read, and unusable if this ever gets pinned as a required
# check. Letting the matrix always expand keeps the check names stable.
coverage:
needs: changes
# Overrides the default matrix naming, which would otherwise bake the
# base/head branch name (matrix.ref) into the check name — making it a
# different string on every PR and impossible to pin as a required check.
name: coverage (${{ matrix.artifact }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- ref: ${{ github.base_ref }}
artifact: base
- ref: ${{ github.head_ref }}
artifact: pr
steps:
- name: Checkout ${{ matrix.ref }}
if: needs.changes.outputs.puterjs == 'true'
uses: actions/checkout@v7
with:
ref: ${{ matrix.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Set up Node.js
if: needs.changes.outputs.puterjs == 'true'
uses: actions/setup-node@v7
with:
node-version: '24'
cache: 'npm'
- name: Install dependencies
if: needs.changes.outputs.puterjs == 'true'
run: npm ci
- name: Install Playwright chromium
if: needs.changes.outputs.puterjs == 'true'
run: npx playwright install --with-deps chromium
# The base leg is best-effort — it only enriches the PR comment with
# a comparison, and the base ref may predate the coverage script.
- name: Run puter.js API tests with coverage
if: needs.changes.outputs.puterjs == 'true'
continue-on-error: ${{ matrix.artifact == 'base' }}
run: npm run test:puterjs:coverage
env:
CI: 'true'
- name: Upload coverage artifact
if: needs.changes.outputs.puterjs == 'true' && !cancelled()
uses: actions/upload-artifact@v7
with:
name: puterjs-coverage-${{ matrix.artifact }}
path: src/puter-js/coverage/coverage-*.json
retention-days: 14
if-no-files-found: ignore
report-coverage:
needs: [changes, coverage]
if: always() && needs.changes.outputs.puterjs == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Download PR coverage
uses: actions/download-artifact@v8
with:
name: puterjs-coverage-pr
path: src/puter-js/coverage
# May not exist (base ref without the coverage script, or a failed
# base run) — then report without the comparison column.
- name: Download base coverage
id: base-coverage
continue-on-error: true
uses: actions/download-artifact@v8
with:
name: puterjs-coverage-base
path: coverage-base
- name: Report coverage on PR
if: steps.base-coverage.outcome == 'success'
uses: davelosert/vitest-coverage-report-action@v2
with:
name: puter.js SDK
json-summary-path: src/puter-js/coverage/coverage-summary.json
json-final-path: src/puter-js/coverage/coverage-final.json
json-summary-compare-path: coverage-base/coverage-summary.json
- name: Report coverage on PR (no base comparison)
if: steps.base-coverage.outcome != 'success'
uses: davelosert/vitest-coverage-report-action@v2
with:
name: puter.js SDK
json-summary-path: src/puter-js/coverage/coverage-summary.json
json-final-path: src/puter-js/coverage/coverage-final.json
+72
View File
@@ -0,0 +1,72 @@
name: Tag Alias
# Retags an existing image in GHCR under a custom name, without rebuilding.
# Uses `docker buildx imagetools create` so the multi-arch manifest is preserved.
# Re-running with the same name updates the alias to point at a different source tag.
on:
workflow_dispatch:
inputs:
name:
description: "Alias name (e.g., potato)"
required: true
source_tag:
description: "Source tag to alias from"
required: false
default: "latest"
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
alias:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Validate alias name
env:
NAME: ${{ inputs.name }}
run: |
if ! [[ "$NAME" =~ ^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$ ]]; then
echo "Invalid alias name '$NAME' (allowed: [A-Za-z0-9_.-], must start with [A-Za-z0-9_], max 128 chars)."
exit 1
fi
if [[ "$NAME" == "latest" || "$NAME" == "main" ]]; then
echo "Alias name '$NAME' is reserved by the build workflow."
exit 1
fi
if [[ "$NAME" =~ ^[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]; then
echo "Alias name '$NAME' looks like a calver tag — pick a non-version name."
exit 1
fi
- name: Log in to GitHub Package Container registry
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Create alias tag
env:
IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
NAME: ${{ inputs.name }}
SOURCE_TAG: ${{ inputs.source_tag }}
run: |
SRC="${IMAGE}:${SOURCE_TAG}"
DST="${IMAGE}:${NAME}"
echo "Aliasing $DST -> $SRC"
docker buildx imagetools create -t "$DST" "$SRC"
{
echo "### 🏷️ Tag Alias"
echo ""
echo "- Source: \`$SRC\`"
echo "- Alias: \`$DST\`"
} >> "$GITHUB_STEP_SUMMARY"
+47 -1
View File
@@ -16,13 +16,59 @@ dist/
.vscode/**/*
!.vscode/extensions.json
!.vscode/launch.json
!.vscode/settings.json
!.vscode/tasks.json
# Local env files
.env
!.env.example
# Per-developer / deployment config override. `config.default.json` ships in
# the repo and is the authoritative source; `config.json` (if present) wins
# at runtime for the local machine only.
config.json
# this is for jetbrain IDEs
.idea/
/puter
# Local Netlify folder
.netlify
src/emulator/release/
# ======================================================================
# vscode
# ======================================================================
# vscode configuration
.vscode/
# JS language server, ref: https://code.visualstudio.com/docs/languages/jsconfig
jsconfig.json
# ======================================================================
# playwright test (currently only test the file-system)
# ======================================================================
tests/client-config.yaml
# ======================================================================
# python
# ======================================================================
__pycache__/
# ======================================================================
# other
# ======================================================================
# AI STUFF
AGENTS.md
.roo
# source maps
*.map
coverage/
*.log
undefined
servers.json
config.*.json
volatile/
File renamed without changes.
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/env sh
files=$(git diff --cached --name-only --diff-filter=ACMR | \
grep -E '^(src/backend|extensions)/.*\.(js|mjs|cjs|ts)$' || true)
if [ -z "$files" ]; then
exit 0
fi
echo "$files" | xargs npx eslint --fix --no-warn-ignored
status=$?
echo "$files" | xargs git add
exit $status
+1
View File
@@ -0,0 +1 @@
engine-strict=true
+4
View File
@@ -0,0 +1,4 @@
node_modules
dist
build
**/*.dbmig.js
+5
View File
@@ -0,0 +1,5 @@
{
"tabWidth": 4,
"singleQuote": true,
"plugins": ["prettier-plugin-jsdoc"]
}
+154
View File
@@ -0,0 +1,154 @@
# AGENTS.md
Guidance for AI coding agents working in this repository. Read this before making changes. FOLLOW GUIDANCE AS CLOSELY AS POSSIBLE. If you think the guidance is wrong, raise an issue or flag a maintainer — don't just do what you think is right. This is the source of truth for how we write code, tests, and docs in this repo.
## Documentation Index
Use these as the source of truth before exploring further:
- [README.md](README.md) — project overview and quickstart.
- [doc/architecture.md](doc/architecture.md) — backend layered stack (controllers → drivers → services → stores → clients), `PuterServer` wiring, `Context` (ALS), and extensions.
- [doc/contributing-apis.md](doc/contributing-apis.md) — adding and maintaining public APIs end to end (backend surface → puter.js → types → docs → tests). Follow it for any API work.
- [doc/pagination.md](doc/pagination.md) — the one pagination convention for list APIs (limit/cursor/offset/includeTotal, envelope shape, cursor semantics).
- [doc/alarms.md](doc/alarms.md) — raising alarms and picking a severity (what pages, what only gets recorded), plus the config that routes them.
- [doc/self-hosting.md](doc/self-hosting.md) — running Puter outside hosted infra.
- [CONTRIBUTING.md](CONTRIBUTING.md) — testing, security, AI-assisted code, PR conventions, Boy Scout Rule.
- [SECURITY.md](SECURITY.md) — how to report vulnerabilities (do not file them publicly).
- [BUG-BOUNTY.md](BUG-BOUNTY.md) — bounty program scope.
- [TRADEMARK.md](TRADEMARK.md) — trademark usage.
---
## Repo-wide conventions
These apply everywhere — backend, puter.js, and GUI.
### Language & files
- Write ES modules, not CommonJS — we transpile and build as needed.
- TypeScript preferred for new files in the backend and extensions; convert existing JS there opportunistically when you're already touching a file. The GUI and puter.js are plain JavaScript — don't introduce TypeScript files in them. In puter.js, type with JSDoc instead (see the puter.js section for what must be typed).
- **Reuse before adding.** Search for an existing type, helper, or implementation and extend it; only add a new one when nothing suitable exists.
- Make new types findable: descriptive `PascalCase` names, exported from the obvious entry point. A type used from many places belongs in the owning module's `types.ts` (e.g. [src/backend/controllers/types.ts](src/backend/controllers/types.ts)) rather than bloating a logic file; a type with a single consumer can stay next to it.
- Naming: `camelCase` for variables/functions, `PascalCase` for classes and files containing a class (`AuthService.ts`). **Prefer `camelCase` for all new code** — new local variables, parameters, functions, and internal object properties. `snake_case` is reserved for identifiers that are part of an external contract: wire/JSON keys sent to or received from the backend, stable API error codes, public option names that already ship as `snake_case`, and established `puter_*` namespaced fields. Don't rename those (it's a breaking change), but don't introduce new `snake_case` alongside them either — a camelCase local can carry a value into a `snake_case` wire key (`{ operation_id: operationId }`).
### Comments
Keep comments light; prefer self-documenting code. Comment only when the _why_ is non-obvious or a usage detail would trip the next reader. Use `//` for single lines and `/** ... */` JSDoc when it genuinely needs more — if a comment runs long, it's probably too long. Don't restate the code and don't reference the current task, PR, or version — those rot. **No ticket references** (`PUT-1234`, `// fix for FOO-99`) in code, comments, or test names; describe the why in domain terms, not project-management terms. Use plain ASCII `-` in comment section dividers (`// -- Section --`), never box-drawing characters.
**Be concise — a comment is a sentence or two, not a paragraph block.** One or two lines for `//`, a few for JSDoc. Don't narrate the history ("used to swallow the failure, which meant…"), don't argue the design at length, and don't explain each parameter when the signature already does. State the constraint and stop. If the reasoning genuinely needs paragraphs, it belongs in a design doc, not above the function.
### Security & privacy
Before opening a PR, scan the diff for:
- Logs, error messages, or responses leaking internal paths, secrets, tokens, env vars, or other users' data.
- Debug routes, test credentials, commented-out auth checks.
- Endpoints returning more than the caller actually needs.
When in doubt, return less. Auth-, permission-, or data-export-related changes deserve an explicit callout in the PR description.
### Working rules of thumb
- **Run it, don't just compile it.** "It type-checks" is not "it works." Exercise the code path end-to-end at least once.
- **Read the neighbors before writing.** Match the shape of similar things already in the tree. If you think the existing pattern is wrong, raise it — don't quietly diverge.
- **Test new behavior.** Every new function, endpoint, driver method, or logic branch gets a test; every bug fix gets a regression test that fails before the fix. If something is genuinely hard to test, skip it but say so in the PR.
- **Boy Scout Rule, proportional to the change.** Fix the obvious typo or dead import in files you're already touching; don't ride a refactor along with a bug fix.
- **Understand what you commit.** AI assistance is fine; shipping code you couldn't defend in review is not.
- **A limit change is not done until the docs change with it.** Every rate limit, concurrency cap, quota, and allowance in the code is published in [src/docs/src/rate-limits-and-quotas.md](src/docs/src/rate-limits-and-quotas.md) — an undisclosed limit is one developers discover as a service failure. If a PR moves any of these numbers, the same PR updates that page. The numbers live in `src/backend/controllers/fs/limits.ts` (filesystem), `src/backend/drivers/util/aiLimits.ts` (all AI drivers), per-driver `rateLimit`/`concurrent` configs, and `src/backend/data/subPolicies/` (free-tier allowances).
---
## Backend
A layered stack with explicit dependency injection: each layer depends only on the layers beneath it, receives them through its constructor, and `PuterServer` ([src/backend/server.ts](src/backend/server.ts)) wires the whole thing together. [doc/architecture.md](doc/architecture.md) is the full reference.
| Layer (top → bottom) | Lives in | Responsibility |
| -------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Controllers** | [src/backend/controllers/](src/backend/controllers/) | Route handlers: parse/validate input, per-route gates via `RouteOptions` (auth, subdomain, rate limit, body parsers), call services, format responses. |
| **Drivers** | [src/backend/drivers/](src/backend/drivers/) | Optional RPC-style handlers on `/drivers/*`; thin shells that validate inputs and call services/stores. |
| **Services** | [src/backend/services/](src/backend/services/) | Business logic. Assume the caller is already authenticated/authorized. |
| **Stores** | [src/backend/stores/](src/backend/stores/) | Persistence; wraps clients in the domain shapes services consume. |
| **Clients** | [src/backend/clients/](src/backend/clients/) | Adapters for external/internal services (sql, redis, s3, email, event bus). Protocols, not domain concepts. |
| **Config** | `config.*.json` → `IConfig` | Flat, typed config object every layer receives at construction. |
A public API can be exposed through either a controller or a driver — both are supported; prefer a controller when you need fine-grained control over routes and gates. [doc/contributing-apis.md](doc/contributing-apis.md) has the decision guide with links to the decorators and middleware for each.
Cross-layer rules:
- **Don't reach across layers.** Controllers don't poke clients; services don't register routes. If you want to, the abstraction is wrong — fix the abstraction.
- **Don't call sideways within a layer for code reuse.** Two services needing the same logic means a util/helper, not a service-to-service dependency.
- **Prefer explicit arguments over `Context` (ALS).** Reach for [Context](src/backend/core/context.ts) only for genuinely request-scoped values that would otherwise thread through many layers — today mostly `actor` and `req`.
### Extensions
[extensions/](extensions/) parallels the layered stack and is for **non-crucial parts of the system** — Puter still works with the extension removed. If core needs to call it, it belongs in core, not an extension (see [whoami](extensions/whoami.ts) as the cautionary example). The `extension` global ([src/backend/extensions.ts](src/backend/extensions.ts)) exposes:
- `extension.registerClient/Store/Service/Driver/Controller(name, Class)` for first-class additions.
- `extension.on(event, handler)` and `extension.get/post/put/delete/patch/use(path, opts?, handler)` for the lightweight common case. `opts` is the same `RouteOptions` controllers use.
- `extension.import('client' | 'store' | 'service' | 'controller' | 'driver')` — lazy proxy to instantiated core objects. `extension.config` exposes live config.
Follow the same layered structure inside an extension — unless it only needs a few route handlers, in which case the lightweight helpers are enough on their own.
### Backend tests
- Vitest; test files sit next to the code they test (`*.test.ts` / `*.test.js`). Run with `npm run test:backend`.
- **Mock data, not methods.** Stub inputs (fixtures, fake rows, payloads), not the function under test or the layer beneath it — over-mocking produces tests that pass while production breaks. If you must mock, mock at a real boundary (a client/external service).
- **Prefer the test server over mocking deps.** `setupPuterTestEnv()` in [src/backend/testUtil.ts](src/backend/testUtil.ts) boots a fully in-memory backend; hit a real database/client shape where reasonable — integration shapes catch what mocked unit tests miss.
- **Test code, not docs.** Never write a test that reads a file under `src/docs/` and asserts on its wording or numbers. Docs are kept in step by the PR (see the limits rule above) and checked in review; a test that greps a markdown page fails on every rewording and verifies nothing about behavior.
---
## puter.js (the SDK)
[src/puter-js/](src/puter-js/) is the public SDK. It ships live from `https://js.puter.com/v2/` with no version pinning — every existing app picks up changes immediately. Treat every observable behavior (signatures, response fields, error codes) as something a production app depends on.
Layout: SDK modules in [src/puter-js/src/modules/](src/puter-js/src/modules/) (one file or directory per area — `FileSystem/`, `kv/`, `ai/`, …), shared plumbing in [src/puter-js/src/lib/](src/puter-js/src/lib/), generated (gitignored) type declarations in `src/puter-js/types/`, API tests in [src/puter-js/tests/api/](src/puter-js/tests/api/), UI e2e tests in [src/puter-js/tests/e2e/](src/puter-js/tests/e2e/), developer docs in [src/docs/](src/docs/).
Language & typing: puter.js source is plain JavaScript — never TypeScript files — typed via JSDoc. **The JSDoc is the source of truth for the SDK's types.** `src/puter-js/types/` is `tsc --emitDeclarationOnly` output: the SDK build (`npm run build` in `src/puter-js`) generates it, the npm tarball ships it so TypeScript consumers get declarations, and git ignores it — it is never committed and never edited by hand. `npm run check:puterjs:types` generates it in CI and type-checks the result without `skipLibCheck`. The one hand-written declaration file is [src/puter-js/index.d.ts](src/puter-js/index.d.ts), which decides what is public and re-exports the generated names.
Declare a shape where it belongs, and reference it with an `import(...)` type from elsewhere. A shape more than one file needs lives in the module's `types.js`; a shape shared across modules lives in [src/puter-js/src/lib/types.js](src/puter-js/src/lib/types.js); a shape with one consumer can stay next to it:
```js
/** @typedef {import('./types.js').KVOptConfig} KVOptConfig */
```
Use `@typedef {Object}` + `@property` for any shape whose fields need documenting — it is the only JSDoc form that carries a doc comment per field into the generated declaration. Keep the inline object-literal form for small internal shapes with nothing to say about each field, and prefer `unknown` over `*`:
```js
/** @typedef {{ key: string; value: unknown }} KVEntry */
```
Public (exposed) methods must carry JSDoc types — parameters and return value — with one `@overload` block per accepted call form, since those overloads _are_ the published signature. Unexposed/private helpers are typed at the contributor's discretion: annotate where it helps the next reader, and either way keep them clean. Members tagged `@internal` are stripped from the generated declarations, so use that tag rather than `@private` to keep something off the public surface.
Typing in JS files is encouraged: annotate with JSDoc `@type`/`@param`/`@returns` using the TypeScript type system, and define shared shapes with `@typedef`. API types must not be `unknown` or untyped `...args` — spell out the real parameter and return shapes; the only exception is values passed through transparently to an upstream layer that owns their type. For example:
```js
/** @typedef {{ key: string; value: unknown }} KVEntry */
/** @type {KVEntry[]} */
let entries = [];
```
Every SDK change carries all five of the following — a puter.js PR missing one is incomplete:
1. **Backward compatibility.** Mandatory unless a maintainer explicitly signs off on a break. Existing call signatures keep working (including both positional and options-object forms where a method supports them); new parameters are optional with defaults that preserve old behavior; never rename or repurpose existing params, response fields, or error codes. New parameter names are `camelCase` (existing `snake_case` stays for compatibility). Say in the PR how existing callers are unaffected.
2. **Tests.** Add or extend a suite in [tests/api/suites/](src/puter-js/tests/api/suites/) (`<area>.suite.ts`; register new suites in `suites/index.ts` — no globbing). One suite runs unchanged on node, browser, and workerd via `npm run test:puterjs`; never write a per-platform test. The runners execute the **built** bundle — run `npm run build:workerLib` after SDK changes or the suite silently tests stale code. For `puter.ui.*` methods rendered by the desktop, use the Playwright e2e harness instead — see [src/puter-js/TESTING.md](src/puter-js/TESTING.md).
3. **Docs.** New or changed APIs update [src/docs/src/](src/docs/src/): the method page (`<Area>/<method>.md`, with frontmatter and a runnable example) and the area overview when the surface changes. Docs are the contract users code against — signatures, defaults, and return shapes must match the implementation exactly.
4. **Types.** Type the change in JSDoc on the implementation, then run `npm run check:puterjs:types` to confirm it still produces declarations that type-check. Name any new type in [src/puter-js/index.d.ts](src/puter-js/index.d.ts) if consumers should be able to import it. Declarations must match runtime behavior exactly — a wrong type is worse than a missing one.
5. **Error handling.** Reject/throw `{ message, code }` objects with stable `snake_case` codes, matching the existing modules (see `KV.js`). Validate cheap preconditions client-side before making the network call; pass backend errors through unchanged rather than swallowing or re-wrapping them. Error codes are API surface — changing one is a breaking change.
[doc/contributing-apis.md](doc/contributing-apis.md) walks the full lifecycle of adding an API across backend + SDK.
---
## GUI
[src/gui/](src/gui/) is the Puter desktop: deliberately plain JavaScript + jQuery with HTML-string templates. Don't introduce a UI framework or a new rendering pattern.
The guiding rule here is **conformity over novelty** — match the existing design and code structure even where you'd personally choose differently. A visually or structurally divergent addition is a defect even when it works.
- **Reuse existing UI primitives before writing new ones.** Windows and dialogs are `UIWindow*` functions in [src/gui/src/UI/](src/gui/src/UI/); generic pieces already exist (`UIAlert`, `UIPrompt`, `UIContextMenu`, `UINotification`, `UIPopover`, widgets in [UI/Components/](src/gui/src/UI/Components/)). A new window should read like its neighbors: an async function taking an options object, composing an HTML string, wiring behavior with jQuery, delegating to `UIWindow(...)`.
- **Match the visual language.** Use existing CSS classes (`button`, `button-primary`, window chrome, form styles) and copy the layout patterns of neighboring windows; new styles go in [src/gui/src/css/](src/gui/src/css/) following existing conventions. Verify anything positional (menus, overlays, z-index) on both desktop and mobile viewports.
- **i18n every user-facing string.** No hardcoded UI text — use `i18n('key')` and add the key to [src/gui/src/i18n/translations/en.js](src/gui/src/i18n/translations/en.js). Run `npm run check-translations` before opening the PR.
- **Shared logic goes in helpers/services.** Reusable non-UI logic belongs in [src/gui/src/helpers/](src/gui/src/helpers/) or [src/gui/src/services/](src/gui/src/services/), not copy-pasted between windows.
- **Tests.** Vitest is wired for the GUI (`src/**/*.test.js`; see [appOrder.test.js](src/gui/src/UI/Dashboard/appOrder.test.js) for the shape). Extract pure logic into functions and test those. Desktop behavior driven through puter.js (`puter.ui.*`) is covered by the Playwright harness in [src/puter-js/tests/e2e/](src/puter-js/tests/e2e/) — add a spec there when you change how the desktop renders SDK-driven UI.
+110
View File
@@ -0,0 +1,110 @@
# Puter Bug Bounty Program
We at **Puter** are committed to maintaining a secure experience for our users and community. We greatly value the contributions of security researchers and welcome responsible disclosure of security issues.
## Scope
The following are in scope for this program:
- **The Puter open-source project** (available at [github.com/HeyPuter/puter](https://github.com/HeyPuter/puter))
- **`puter.com`**
- **`api.puter.com`**
Out-of-scope:
- Third-party services, applications, or libraries not maintained by Puter.
- Social engineering attacks (e.g., phishing against staff).
- Denial of Service (DoS), spam, or volumetric attacks.
- Physical security issues.
## Known Non-Issues (Please Check Before Submitting)
The following have already been reviewed and determined **not to be vulnerabilities**. Reports that only re-describe one of these are **not eligible for a reward** and will be closed as non-issues — even if they include new code references. Please review this list before submitting:
- **XSS / CORS / token issues scoped to `api.puter.com`.** The primary user session cookie lives on `puter.com`, not on the API origin, so reflected/stored XSS, CORS, or token handling on `api.puter.com` is out of scope. This explicitly includes **missing `Content-Security-Policy: sandbox` on any endpoint that serves a file inline** — `/token-read`, `/file`, `/fs/read`, WebDAV, and any MIME type the `applyInlineContentSecurity` allow-list does not cover (`text/xsl`, `image/svg+xml`, `application/xhtml+xml`, …). Script execution on the API origin has nothing to reach: there is no session cookie, no `localStorage`, and no ambient credential there. WebDAV additionally has to return an accurate MIME type for real WebDAV clients. The one exception we _do_ evaluate on its merits is anything that abuses the app-scoped `puter_token_v2` companion cookie set on the API host — if your report does not name a specific credential that is actually reachable from the API origin, it is this non-issue.
- **SSRF via `secureFetch`.** Production routes outbound requests through an isolated proxy that has no access to internal/SSRF-sensitive resources.
- **Attacks that depend on guessing an `appInstanceID` or app UID.** These are random 128-bit secret values and are not considered guessable.
- **Apps invoking drivers, creating workers, or using KV.** Applications are intended to do this; worker permissions are scoped to the owning app. This is by design.
- **App metadata or app user-count "leaks".** This information is currently public by design. This covers **private apps** too: private apps are an unreleased, admin-only beta for paid listings in the Puter App Center. Their `index_url` and other metadata are not secret, the flag is not user-settable, and no production app relies on it. Reports that a private app's metadata is reachable through a sibling route (taskbar items, `/get-launch-apps`, `index_url` drift on the hosting gate, etc.) are normalization work, not vulnerabilities.
- **Worker hot-reload driven by a share recipient.** Sharing a worker's source file with write access is how you let a collaborator change that worker's code and have it deploy live. The redeploy running as the file owner, with the owner's worker credentials, is the intended behavior of that grant — the owner chose to hand out write access to executable code. If you do not want that, do not share the source file with write access.
- **Share-mode downgrades that do not cascade.** Demoting a delegate does not retroactively revoke the grants that delegate already issued downstream. Shares are independent grants once issued, not a live-evaluated chain. Revoking the downstream grant is a separate, supported action.
- **Concurrency / TOCTOU overspend of credits or storage quota.** Firing concurrent requests to exceed an AI credit hold or a storage quota by some margin is known and accepted; the per-account concurrency and rate-limit gates are the control we rely on, and the residual overage is bounded and billed. Report these only if you can demonstrate _unbounded_ overspend.
- **Session and credential lifecycle around 2FA enrollment.** Enrolling in 2FA is not a credential-revocation event: existing authenticated sessions stay valid, and outstanding password-reset links stay valid. Likewise, account-management actions behind the `/user-protected/*` gate are password-gated by design, not TOTP-gated. A recovery code that stops being accepted fails _closed_ — it denies access rather than granting it, so it is a bug report, not a vulnerability.
- **Group permissions** (`/auth/revoke-user-group` and siblings). The group-permission surface is unfinished and not exposed anywhere in the product. Findings there are not reachable by any user.
- **Correctness bugs with no security boundary crossed.** For example, an API that reports success while silently leaving data behind. We want these reported — please open a GitHub issue — but they are not bounty-eligible.
- **Missing Subresource Integrity (SRI) on external scripts/styles.** Accepted as hardening, not as a vulnerability, absent a demonstrated compromise of the CDN in question.
- **General "token in a URL" / token-lifetime / token-storage designs** — signed directory URLs exposing children, a write signature implying read, app tokens outliving a web session, or the session token being held in `localStorage` on `puter.com`. These are current intended behaviors. Shorter-lived tokens with a refresh flow are on the roadmap; their absence is not a vulnerability on its own. Show a reproducible attack that does not already presuppose script execution on `puter.com`.
- **Missing PKCE, unverified `id_token` signatures, or other OIDC hardening.** Provider tokens are obtained through a server-to-server authorization-code exchange with the provider's token endpoint over TLS, so the resulting `id_token` / userinfo claims are trusted from that channel rather than from local JWKS signature verification — the callback never accepts a caller-supplied `id_token`. Adding local signature / `aud` / `iss` / `exp` checks is welcome defense-in-depth (please open a GitHub issue/PR), but their absence is not an account-takeover vector on its own.
- **JWT "algorithm confusion" / unpinned `algorithms` in `jwt.verify`.** Puter's session tokens are HMAC-signed (HS256) with a server-side secret, and there is no asymmetric public key anywhere in the verification path, so `alg`-substitution attacks do not apply. Explicitly pinning `algorithms` is a fine hardening PR, but it is not a vulnerability.
- **Static-source "SQL injection" in internal pagination.** Findings such as `LIMIT ${limit}` in list/notification queries: the limit is numerically coerced and clamped before it reaches the query, so it is not reachable with attacker-controlled string input. Hardening PRs to the internal stores are welcome, but these are not exploitable as reported.
- **Deprecated `saveTo*` GUI app messages.** The legacy `saveToDesktop` / `saveToDocuments` / etc. app-IPC handlers can create — never overwrite — new files in standard user folders. The behavior is non-destructive, path-traversal-safe, and deprecated (slated for removal); it is not treated as a sandbox escape.
- **Best-practice suggestions** such as login/registration username enumeration (kept intentionally for UX) or unauthenticated unsubscribe links (industry norm).
- **Rate-limiting suggestions for TURN credential issuance** (intentional; not billed per tunnel).
If you believe you have a **genuinely new** exploit chain that defeats one of these rationales (for example, demonstrating a sensitive credential that really is reachable on `api.puter.com`), say so explicitly and show why the reasoning above does not apply.
## Rules of Engagement
To participate, you must:
1. **Report responsibly**: Provide detailed steps to reproduce the issue, including proof-of-concept code, screenshots, or a screen recording (see _Proof of Reproduction_ below).
2. **Do no harm**: Do not exfiltrate, modify, or delete data. Only access your own account or test data.
3. **Respect availability**: Do not perform denial-of-service attacks or automated scans that degrade service.
4. **Follow disclosure policy**: Do not publicly disclose vulnerabilities until we have confirmed and patched the issue.
5. **Act in good faith**: Make every effort to avoid privacy violations, destruction of data, and interruption or degradation of services.
6. **Check the Known Non-Issues list**: Reports matching an item in the "Known Non-Issues" section above are not eligible and will be closed.
Reports that do not meet these guidelines may not be eligible for a reward.
## Proof of Reproduction
Reports **MUST** demonstrate a **working, reproducible exploit with real impact** — not a theoretical or static-source-review finding. Please include:
- Exact steps to reproduce, the relevant request/response or code path, and the commit or version you tested.
- The **observed** result versus the **expected** result.
- For client-side, UI, or authentication-flow bugs: a short screen recording (≤ 2 minutes) showing the exploit working end-to-end on a real Puter instance.
- For server-side bugs: a runnable proof-of-concept and screenshot or video showing the attack process.
Reports based solely on reading the source ("source review only, not tested") or unverified AI/LLM-generated reports are the **lowest triage priority and not eligible for bounty**.
If you used an AI tool to help find an issue, you must personally verify that it actually reproduces before submitting.
Please submit **one issue per report**.
Bundled "audit packs" of many speculative findings will not be elligible for bounty; send each confirmed issue separately.
Additionally please **DO NOT** submit too many issues at once; these will be treated as a bundled report, and will not be elligible for bounty.
## Reporting Process
To report a vulnerability, email us at: **[[email protected]](mailto:[email protected])**.
Include:
- A description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested remediation (if available)
- Paypal id where we can send the bounty (if eligible)
We aim to acknowledge receipt within **72 hours** and provide a resolution timeline.
## Reward Structure
We offer monetary rewards based on the severity of the vulnerability, as determined by our internal assessment (using CVSS as a guide).
- **Critical: \$1,000 – \$2,000**
- **High: \$500 – \$1,000**
- **Medium: \$200 – \$500**
- **Low: \$50 – \$100**
Non-security issues, suggestions, and best practices feedback are always welcome, but may not qualify for a reward.
If multiple researchers report the same issue, the bounty will be awarded to the first eligible report we receive.
## Payments Disclaimer
All reward amounts are **guidelines only**. Final decisions about eligibility, severity classification, and payout amount are made at the sole discretion of the Puter security team. We reserve the right to determine whether a report qualifies for a bounty, and whether any payment will be issued at all. Submitting a report does not guarantee compensation.
### Payment Method Requirement
At this time, **payments will only be made via PayPal**. To be eligible to receive a bounty, researchers must have a valid PayPal account capable of receiving payments. We are unable to process payments through other services or methods at this time.
## Legal Safe Harbor
If you make a good-faith effort to comply with this policy, we will consider your research to be authorized. If you inadvertently access data outside your own account, stop immediately and include details in your report so we can investigate and remediate.
-304
View File
@@ -1,304 +0,0 @@
# Changelog
## v2.4.2 (2024-07-22)
### Puter
#### Features
- add new file templates ([1f7f094](https://github.com/HeyPuter/puter/commit/1f7f094282fae915a2436701cfb756444cd3f781))
- add cross_origin_isolation option ([e539932](https://github.com/HeyPuter/puter/commit/e53993207077aecd2c01712519251993bb2562bc))
- add option to disable temporary users ([f9333b3](https://github.com/HeyPuter/puter/commit/f9333b3d1e05bd0dffaecd2e29afd08ea61559fc))
- add some default groups ([ba50d0f](https://github.com/HeyPuter/puter/commit/ba50d0f96d58075abec067d24e6532bd874093f0))
- Add support for dropping multiple Puter items onto Dev Center (close #311) ([8e7306c](https://github.com/HeyPuter/puter/commit/8e7306c23be01ee6c31cdb4c99f2fb1f71a2247f))
#### Translations
- Update ig.js ([382fb24](https://github.com/HeyPuter/puter/commit/382fb24dbb1737a8a54ed2491f80b2e2276cde61))
- feat: add vietnamese localization-a ([c2d3d69](https://github.com/HeyPuter/puter/commit/c2d3d69dbe33f36fcae13bcbc8e2a31a86025af9))
- Update zhtw.js, Complete Traditional Chinese translation based on English file #550 ([b9e73b7](https://github.com/HeyPuter/puter/commit/b9e73b7288aebb14e6bbf1915743e9157fc950b1))
- update zhtw.js to match en.js ([37fd666](https://github.com/HeyPuter/puter/commit/37fd666a9a6788d5f0c59311499f29896b48bc82))
- Add Tamil translation to translations.js ([8a3d043](https://github.com/HeyPuter/puter/commit/8a3d0430f39f872b8a460c344cce652c340b700b))
- Move Tamil translation to the rest of translations ([333d6e3](https://github.com/HeyPuter/puter/commit/333d6e3b651e460caca04a896cbc8c175555b79b))
- Translation improvements, mainly style and context-based ([8bece96](https://github.com/HeyPuter/puter/commit/8bece96f6224a060d5b408e08c58865fadb8b79c))
- update translation file es.js to be up to date with the file en.js ([1515278](https://github.com/HeyPuter/puter/commit/151527825f1eb4b060aaf97feb7d18af4fcddbf2))
- Translate en.js as of 2024-07-10 ([8e297cd](https://github.com/HeyPuter/puter/commit/8e297cd7e30757073e2f96593c363a273b639466))
- Create hu.js hungarian language ([69a80ab](https://github.com/HeyPuter/puter/commit/69a80ab3d2c94ee43d96021c3bcbdab04a4b5dc6))
- Update translations.js to Hungarian lang ([56820cf](https://github.com/HeyPuter/puter/commit/56820cf6ee56ff810a6b495a281ccbb2e7f9d8fb))
- Tamil translation ([81781f8](https://github.com/HeyPuter/puter/commit/81781f80afc07cd1e6278906cdc68c8092fbfedf))
- Update it.js ([84e31ef](https://github.com/HeyPuter/puter/commit/84e31eff2f58584d8fab7dd10606f2f6ced933a2))
- Update Armenian translation file ([3b8af7c](https://github.com/HeyPuter/puter/commit/3b8af7cc5c1be8ed67be827360bbfe0f0b5027e9))
#### Bug Fixes
- fix templates ([5d2a6fc](https://github.com/HeyPuter/puter/commit/5d2a6fce305a3dcd4857f52ebb75f529dffe4790))
- popup login in co isolation mode ([8f87770](https://github.com/HeyPuter/puter/commit/8f87770cebab32c00cb10133979d426306685292))
- add necessary iframe attributes for co isolation ([2a5cec7](https://github.com/HeyPuter/puter/commit/2a5cec7ee914c9c97ae90b85464f9fc5332ad2fb))
- chore: fix confirm for type_confirm_to_delete_account ([02e1b1e](https://github.com/HeyPuter/puter/commit/02e1b1e8f5f8e22d7ab39ebff99f7dd8e08a4221))
- syntax error and formatting issue ([3a09e84](https://github.com/HeyPuter/puter/commit/3a09e84838fe8b74bd050641620eec87d9f59dfc))
- #432 ([f897e84](https://github.com/HeyPuter/puter/commit/f897e844989083b0b369ba0ce4d2c5a9f3db5ad8))
- `launch_app` not considering `explorer` as a special case ([98e6964](https://github.com/HeyPuter/puter/commit/98e69642d027a83975a0b2b825317213098bb689))
- well kinda (HOSTNAME in phoenix) ([7043b94](https://github.com/HeyPuter/puter/commit/7043b9400c63842c4c54d82724167666708d3119))
- it was github actions the entire time ([602a198](https://github.com/HeyPuter/puter/commit/602a19895c05b45a7d283470e7af3ae786be1bf2))
- fix CI attempt #7 ([614f2c5](https://github.com/HeyPuter/puter/commit/614f2c5061525f230ccd879bfb047434ac46a9ba))
- fix CI attempt #6 ([9d549b1](https://github.com/HeyPuter/puter/commit/9d549b192d149eac96c316ded645bf7c2e96153d))
- fix CI attempt #5 ([74adcdd](https://github.com/HeyPuter/puter/commit/74adcddc1d60e0a513408a0716ed2b301126225d))
- fix CI attempt #4 ([84b993b](https://github.com/HeyPuter/puter/commit/84b993bce913c3ad99127063bcfaae19331b199c))
- fix CI attempt #3 ([3bca973](https://github.com/HeyPuter/puter/commit/3bca973f5f4e65a2bd24c634c347fbd681a7458b))
- fix CI attempt #2 ([aebe89a](https://github.com/HeyPuter/puter/commit/aebe89a1acb070764551e8e89e325325ffbed8f9))
- run mocha within packages in monorepo ([58c199c](https://github.com/HeyPuter/puter/commit/58c199c15356ac087a04b16dd18e8fe0f1aea359))
- make webpack output not look like errors ([ad3d318](https://github.com/HeyPuter/puter/commit/ad3d318d07377c78c0429247225655e489b68be4))
- No scrollbar for session list ([45f131f](https://github.com/HeyPuter/puter/commit/45f131f8eaf94cf3951ca7ffeb6f311590233b8a))
- fix path issues under win32 platform ([d80f2fa](https://github.com/HeyPuter/puter/commit/d80f2fa847bfaef98dc8d482898f5c15f268e4bd))
- remove abnoxious debug file ([5c636d4](https://github.com/HeyPuter/puter/commit/5c636d4fd25e14ba3813f7fca3b70ff7bd6860e7))
- read_only fields in ES ([e8f4c32](https://github.com/HeyPuter/puter/commit/e8f4c328bff5c36b95fe460b80803e12e619f8ee))
### Security
#### Bug Fixes
- hoist acl check in ll_read ([6a2fbc1](https://github.com/HeyPuter/puter/commit/6a2fbc1925952ecceed741afe138270d1eeda7b7))
## v2.4.1 (2024-07-11)
### Puter
#### Features
- update BR translation ([42a6b39](https://github.com/HeyPuter/puter/commit/42a6b3938a588b8b4d1bd976c37e9c6e58408c75))
- JSON support for kv driver ([3ed7916](https://github.com/HeyPuter/puter/commit/3ed7916856f03eafbe0891f2ab39c34d20d2bd24))
#### Translations
- Update bn.js file formatting ([cff488f](https://github.com/HeyPuter/puter/commit/cff488f4f4378ca6c7568a585a665f2a3b87b89c))
- Issue#530 - Update bengali translations ([92abc99](https://github.com/HeyPuter/puter/commit/92abc9947f811f94f17a5ee5a4b73ee2b210900a))
- Added missing Romanian translations. ([8440f56](https://github.com/HeyPuter/puter/commit/8440f566b91c9eb4f01addcb850061e3fbe3afc7))
- Add 2FA Romanian translations ([473b651](https://github.com/HeyPuter/puter/commit/473b6512c697854e3f3badae1eb7b87742954da5))
- Add Japanese Translation ([47ec74f](https://github.com/HeyPuter/puter/commit/47ec74f0aa6adb3952e6460909029a4acb0c3039))
- Completing Italian translation based on English file ([f5a8ee1](https://github.com/HeyPuter/puter/commit/f5a8ee1c6ab950d62c90b6257791f026a508b4e4))
- Completing Italian translation based on English file. ([a96abb5](https://github.com/HeyPuter/puter/commit/a96abb5793528d0dc56d75f95d771e1dcf5960d1))
- Completing Arabic translation based on English file ([78a0ace](https://github.com/HeyPuter/puter/commit/78a0acea6980b6d491da4874edbd98e17c0d9577))
- Update Arabic translations in src/gui/src/i18n/translations/ar.js to match English version in src/gui/src/i18n/translations/en.js ([fe5be7f](https://github.com/HeyPuter/puter/commit/fe5be7f3cf7f336730137293ba86a637e8d8591d))
- Update Arabic translations in src/gui/src/i18n/translations/ar.js to match English version in src/gui/src/i18n/translations/en.js ([bffa192](https://github.com/HeyPuter/puter/commit/bffa192805216fc17045cd8d629f34784dca7f3f))
- Ukrainian updated ([e61039f](https://github.com/HeyPuter/puter/commit/e61039faf409b0ad85c7513b0123f3f2e92ebe32))
- Update ru.js issue #547 ([17145d0](https://github.com/HeyPuter/puter/commit/17145d0be6a9a1445947cc0c4bec8f16a475144c))
- Russian translation fixed ([8836011](https://github.com/HeyPuter/puter/commit/883601142873f10d69c84874499065a7d29af054))
#### Bug Fixes
- remove flag that breaks puter-js webpack ([7aadae5](https://github.com/HeyPuter/puter/commit/7aadae58ce1a51f925bf64c3d65ac1fa6971b164))
- Improve `getMimeType` to remove trailing dot in the extension if preset ([535475b](https://github.com/HeyPuter/puter/commit/535475b3c36a37e3319ed067a24fb671790dcda3))
## 2.4.0 (2024-07-08)
### Features
* add (pt-br) translation for system settings. ([77211c4](https://github.com/HeyPuter/puter/commit/77211c4f71b0285fb3060f7e5c8d493b4d7c4f0c))
* add /group/list endpoint ([d55f38c](https://github.com/HeyPuter/puter/commit/d55f38ca68899c3574cfe328d2b206b1143ff0d4))
* add /share/file-by-username endpoint ([5d214c7](https://github.com/HeyPuter/puter/commit/5d214c7b52887b594af6be497f1892baf7d77679))
* add /sharelink/request endpoint ([742f625](https://github.com/HeyPuter/puter/commit/742f625309f9f4cfa70cf7d2fe5b03fd164913ea))
* add /show urls ([079e25a](https://github.com/HeyPuter/puter/commit/079e25a9fe8e179f26d72378856058eb656e2314))
* add app metadata ([f7216b9](https://github.com/HeyPuter/puter/commit/f7216b95672b38802b288ef5b022e947017ff311))
* add appdata permission (if applicable) on app share ([9751fd9](https://github.com/HeyPuter/puter/commit/9751fd92a50e75385cffed0ca847d5076ba98c92))
* add cookie for site token ([a813fbb](https://github.com/HeyPuter/puter/commit/a813fbbb88bcfb8b9a61976e2a4fc4aab943fc88))
* add cross-server event broadcasting ([1207a15](https://github.com/HeyPuter/puter/commit/1207a158bdc88a90b14d31d03387ce353c176a9c))
* add debug mod ([16b1649](https://github.com/HeyPuter/puter/commit/16b1649ff62fd87a4dda5d2e1c68941c864c5da4))
* add endpoints for share tokens ([301ffaf](https://github.com/HeyPuter/puter/commit/301ffaf61dbb4fca1a855650ab80707ae6d9f602))
* Add exit status code to apps ([7674da4](https://github.com/HeyPuter/puter/commit/7674da4cd225bcad34079251c5600fc32e32248b))
* add external mod loading ([eb05fbd](https://github.com/HeyPuter/puter/commit/eb05fbd2dc4877553b5118a069a9afdc32bea137))
* add group management endpoints ([4216346](https://github.com/HeyPuter/puter/commit/4216346384d90dcba429dbcb175e6f86482d19f4))
* add group permission endpoints ([c374b0c](https://github.com/HeyPuter/puter/commit/c374b0cbca761e7c8a47d56a09551f2e9378066a))
* add mark-read endpoint ([0101f42](https://github.com/HeyPuter/puter/commit/0101f425d480705c20df4919a76f66e987f5790f))
* add permission rewriter for app by name ([16c4907](https://github.com/HeyPuter/puter/commit/16c4907be592dae31ed3c1aa3fac3b9655255d6f))
* add protected apps ([f2f3d6f](https://github.com/HeyPuter/puter/commit/f2f3d6ff460932698fb8da7309fbce3e96132950))
* add protected subdomains ([86fca17](https://github.com/HeyPuter/puter/commit/86fca17fb17c0c24397c29b49b133deadea1de8b))
* add querystring-informed errors ([e7c0b83](https://github.com/HeyPuter/puter/commit/e7c0b8320a6829315d9154d6d513bab4491c47ea))
* add readdir delegate for shares in a user directory ([8424d44](https://github.com/HeyPuter/puter/commit/8424d446099ac30ccf829c57d43eef1f235618e4))
* add readdir delegate for sharing user homedirs ([19a5eb0](https://github.com/HeyPuter/puter/commit/19a5eb00763f3ac31df8483fb59cb7a96c448745))
* add service for notifications ([a1e6887](https://github.com/HeyPuter/puter/commit/a1e6887bf93da21b9482040b3e30ee083fb23477))
* add service to test file share logic ([332371f](https://github.com/HeyPuter/puter/commit/332371fccb198462948a440419adc7a26d671a23))
* add share list to stat ([8c49ba2](https://github.com/HeyPuter/puter/commit/8c49ba2553ce6bee20eb5b6f2721bc80f639e98a))
* add share service and share-by-email to /share ([db5990a](https://github.com/HeyPuter/puter/commit/db5990a98935817c0e16d30e921bb99c57a98fc8))
* add subdomain permission (if applicable) on app share ([13e2f72](https://github.com/HeyPuter/puter/commit/13e2f72c9f33f485570f13f45341246b1a05879f))
* add user-group permission check ([0014940](https://github.com/HeyPuter/puter/commit/00149402e041443aa3ac571fbe97a9a85f95564b))
* **backend:** add script service ([30550fc](https://github.com/HeyPuter/puter/commit/30550fcddda18469735499546de502d29b85e2ad))
* **backend:** Add tab completion to server console command arguments ([fa81dca](https://github.com/HeyPuter/puter/commit/fa81dca9507b7fa0f82099b75f2ab89c865626ac))
* **backend:** Add tab-completion to server console command names ([e1e76c6](https://github.com/HeyPuter/puter/commit/e1e76c6be71fdeb3b6246307b626734d8dc26f86))
* **backend:** add tip of day ([2d8e624](https://github.com/HeyPuter/puter/commit/2d8e6240c61dc6301f49cbdcd1c3b04736f9ca93))
* **backend:** allow services to provide user properties ([522664d](https://github.com/HeyPuter/puter/commit/522664d415c33342500defec309c2ff15bc94804))
* **backend:** allow services to provide whoami values ([fccabf1](https://github.com/HeyPuter/puter/commit/fccabf1bc0c4418f3599222616dd63bf98c14fe1))
* **backend:** improve logger and reduce logs ([4bdad75](https://github.com/HeyPuter/puter/commit/4bdad75766d0617a164024b39b79bf5373c495a6))
* Display app icon and description in embeds ([ef298ce](https://github.com/HeyPuter/puter/commit/ef298ce3aa3ce90224e883fb0ba33f9cd3a3da44))
* get first test working on share-test service ([88d6bee](https://github.com/HeyPuter/puter/commit/88d6bee9546f36d689c53ec7fe95f01f772f5211))
* **git:** Add --color and --no-color options ([d6dd1a5](https://github.com/HeyPuter/puter/commit/d6dd1a5bb0a2b2bba2cfe86d2e51ff2a6e42841c))
* **git:** Add a --debug option, which sets the DEBUG global ([fa3df72](https://github.com/HeyPuter/puter/commit/fa3df72f6ed2d45a440ebc2aacbbae67bf042478))
* **git:** Add authentication to clone, fetch, and pull. ([364d580](https://github.com/HeyPuter/puter/commit/364d580ff896691ee70d3735f495c720651a9f41))
* **git:** Add diff display to `show` and `log` subcommands ([3cad1ec](https://github.com/HeyPuter/puter/commit/3cad1ec436f99a78f782ab9576325d4341284964))
* **git:** Add start-revision and file arguments to `git log` ([49c2f16](https://github.com/HeyPuter/puter/commit/49c2f163515d2130c17a6f6a6a16bc27ea69336a))
* **git:** Allow checking out a commit instead of a branch ([057b3ac](https://github.com/HeyPuter/puter/commit/057b3acf00af49c005b9bf7069c5d22983a32e1e))
* **git:** Color output for `git status` files ([bab5204](https://github.com/HeyPuter/puter/commit/bab5204209aa2efc0c053643677a78db6ede0929))
* **git:** Display file contents as a string for `git show FILE_OID` ([a680371](https://github.com/HeyPuter/puter/commit/a68037111a04580cfa2688694a68ef6ac7a495fa))
* **git:** Display ref names in `git log` and `git show` ([45cdfcb](https://github.com/HeyPuter/puter/commit/45cdfcb5bfa66937b33054a127e0b17001f3faa4))
* **git:** Format output closer to canonical git ([60976b1](https://github.com/HeyPuter/puter/commit/60976b1ed61984d9d290f3a0ae99dd97632e9909))
* **git:** Handle detached HEAD in `git status` and `git branch --list` ([2c9b1a3](https://github.com/HeyPuter/puter/commit/2c9b1a3ffc3d5e282ffe5b83a86314e99445bbc6))
* **git:** Implement `git branch` ([ad4f132](https://github.com/HeyPuter/puter/commit/ad4f13255d52f8226f22800c16b388cf0e6384d7))
* **git:** Implement `git checkout` ([35e4453](https://github.com/HeyPuter/puter/commit/35e4453930bc4e151887f83c97efec19cc15da70))
* **git:** Implement `git cherry-pick` ([2e4259d](https://github.com/HeyPuter/puter/commit/2e4259d267b3cfafd5cefc57a02643c6432fec4d))
* **git:** Implement `git clone` ([95c8235](https://github.com/HeyPuter/puter/commit/95c8235a4a1fea39a46c40df04cb1004a2fe7b23))
* **git:** Implement `git diff` ([622b6a9](https://github.com/HeyPuter/puter/commit/622b6a9b921c3c03efc0b519c9a26c6701d80e50))
* **git:** Implement `git fetch` ([98a4b9e](https://github.com/HeyPuter/puter/commit/98a4b9ede39b94c0c6b6b8345d7551359961186a))
* **git:** Implement `git pull` ([eb2b6a0](https://github.com/HeyPuter/puter/commit/eb2b6a08b03cee0612885412cd4b03c9564044e3))
* **git:** Implement `git push` ([8c70229](https://github.com/HeyPuter/puter/commit/8c70229a188b743220db076a740a992fd7971301))
* **git:** Implement `git remote` ([43ce0d5](https://github.com/HeyPuter/puter/commit/43ce0d5b45d4eb4f296afcaaa1ecadc125c53e89))
* **git:** Implement `git restore` ([4ba8a32](https://github.com/HeyPuter/puter/commit/4ba8a32b45d395f28433572db5644d630776789e))
* **git:** Make `git add` work for deleted files ([9551544](https://github.com/HeyPuter/puter/commit/955154468f48e45028dad2e916708d6a763affad))
* **git:** Make shorten_hash() guaranteed to produce a unique hash ([dd10a37](https://github.com/HeyPuter/puter/commit/dd10a377493c0d8f10a1ac8779dc27f3f3bf6c37))
* **git:** Resolve more forms of commit reference ([b6906bb](https://github.com/HeyPuter/puter/commit/b6906bbcaaa50fc8a8c60beb6d2d38bcb7dda758))
* **git:** Understand references like `HEAD^` and `main~3` ([711dbc0](https://github.com/HeyPuter/puter/commit/711dbc0d2fde9c2ddc6c86f64fb4caa7837c9dcb))
* implicit access from apps to shared appdata dirs ([31d4eb0](https://github.com/HeyPuter/puter/commit/31d4eb090efb340fdfb7cb6b751145e859624eeb))
* introduce notification selection via driver ([c5334b0](https://github.com/HeyPuter/puter/commit/c5334b0e19cf9762f536ec482c3ff872e9c12399))
* multi-recipient multi-file share endpoint ([846fdc2](https://github.com/HeyPuter/puter/commit/846fdc20d4a887a1f8a4f3bda4fafe41efab2733))
* **parsely:** Add a fail() parser ([5656d9d](https://github.com/HeyPuter/puter/commit/5656d9d42f76202a534ad640d3a4e287e0e40418))
* **parsely:** Add stringUntil() parser ([d46b043](https://github.com/HeyPuter/puter/commit/d46b043c5d16f1205d61de3f3ba43ed8ad7bff93))
* **phoenix:** Add --dump and --file options to sed ([f250f86](https://github.com/HeyPuter/puter/commit/f250f86446a506f24fa2ad396328e3a2212a68d0))
* **phoenix:** Add more commands to sed, including labels and branching ([306014a](https://github.com/HeyPuter/puter/commit/306014adc77a7ca155feb95d1146cb46ee075b52))
* **phoenix:** Expose parsed arg tokens to apps that request them ([4067c82](https://github.com/HeyPuter/puter/commit/4067c82486c99cad20f41927ad39ebea438b717f))
* **phoenix:** Implement an `exit` builtin ([3184d34](https://github.com/HeyPuter/puter/commit/3184d3482c7b95c0fd1fc0745555ff82fc9a8c99))
* **phoenix:** Implement parsing of sed scripts ([0d4f907](https://github.com/HeyPuter/puter/commit/0d4f907b6675b15bd50a55f50aa28f0803b18b7b))
* **phoenix:** Make `clear` clear scrollback unless `-x` is given ([75a989a](https://github.com/HeyPuter/puter/commit/75a989a7b69bfdfdf69e5f0365027c5b27d8bfc6))
* **Phoenix:** Pass command line arguments and ENV when launching apps ([8f1c4fc](https://github.com/HeyPuter/puter/commit/8f1c4fcda98e72a7b970e8c6fc2fe39a5e012264))
* **phoenix:** Respond to exit status codes ([5de3052](https://github.com/HeyPuter/puter/commit/5de305202656a172b187dac87543d6c1c69a2958))
* **phoenix:** Show actual host name in prompt and neofetch ([4539408](https://github.com/HeyPuter/puter/commit/4539408a218a50244dc615cf7de56c29dcac53e6))
* rate-limit for excessive groups ([4af279a](https://github.com/HeyPuter/puter/commit/4af279a72fc9de89ddc3ba51806ca3760a36265d))
* re-send unreads on login ([02fc4d8](https://github.com/HeyPuter/puter/commit/02fc4d86b7166fb4803be5d28e2a593d6b7d9785))
* register dev center to apps ([10f4d7d](https://github.com/HeyPuter/puter/commit/10f4d7d50ce9314f9c3888c74cb17c8ebbecee98))
* send notification when file gets shared ([2f6c428](https://github.com/HeyPuter/puter/commit/2f6c428a403a006f7878861d2f0356c3294519be))
* start directory index frame ([fb1e2f2](https://github.com/HeyPuter/puter/commit/fb1e2f21fb67aefe0602f6c978199c7cd019bbf7))
* support canonical puter.js url in dev ([fd41ae2](https://github.com/HeyPuter/puter/commit/fd41ae217c7a9f7229326f62a829471580a744bd))
* **ui:** add new components ([577bd59](https://github.com/HeyPuter/puter/commit/577bd59b6cc94810e851ad544f8234e25a4e6e27))
* **ui:** add new components ([38ba425](https://github.com/HeyPuter/puter/commit/38ba42575ce9f3506f8ce219b9580202b3ed9993))
* **ui:** allow component-based settings tabs ([1245960](https://github.com/HeyPuter/puter/commit/124596058a286241b51dd87ce2fc1a68478cb5b8))
* update share endpoint to support more things ([dd5fde5](https://github.com/HeyPuter/puter/commit/dd5fde5130c1840ab598e6622766ae835142e58a))
### Bug Fixes
* add app_uid param to kv interface ([f7a0549](https://github.com/HeyPuter/puter/commit/f7a054956b8739a3bc305a49faee929ea0da1e15))
* add missing columns for public directory update ([b10302a](https://github.com/HeyPuter/puter/commit/b10302ad744fd9c58f9735743e075815183c772c))
* Add missing file extension to 0009_app-prefix-fix.sql in DB init ([a8160a8](https://github.com/HeyPuter/puter/commit/a8160a8cdcdd6aff98728a6f1643d93386e6bb5a))
* add permission implicator for file modes ([e63ab3a](https://github.com/HeyPuter/puter/commit/e63ab3a67f6555eb13d6af477a8da9f1b54d6608))
* add stream limit ([ceba309](https://github.com/HeyPuter/puter/commit/ceba309dbd4df89f310d1a530f939a5b7991f4c7))
* **backend:** remove a bad thing that really doesn't work ([8d22276](https://github.com/HeyPuter/puter/commit/8d22276f13106f7642d11da30b1500817a20ad43))
* bug introduced when refactoring /share to Sequence ([ecb9978](https://github.com/HeyPuter/puter/commit/ecb997885c1efb766827c84d2ffb8dc6ddabe992))
* check subdomain earlier for /apps ([4e3a24e](https://github.com/HeyPuter/puter/commit/4e3a24e6093e279e210765e07e436f4e63b74072))
* column nullability blunder ([1429d6f](https://github.com/HeyPuter/puter/commit/1429d6f57c67dff51fc41ca0c2868f8d000845f1))
* Correct APIError imports ([062e23b](https://github.com/HeyPuter/puter/commit/062e23b5c9673db1f8b0ff0469289d52dd1e3f99))
* correct shown flag behavior ([632c536](https://github.com/HeyPuter/puter/commit/632c5366161ff8fbbd4d60c61dfbe52dad488a2c))
* database migration ([9b39309](https://github.com/HeyPuter/puter/commit/9b39309e18a2927d25fe794d91da4e4d068c4bca))
* do not delegate to select on read like ever that is really dumb ([a2a10b9](https://github.com/HeyPuter/puter/commit/a2a10b94be59403e03fb08bec5d7c056ce5b554f))
* docker runtime fail because stdout columns ([94c0449](https://github.com/HeyPuter/puter/commit/94c0449437ce4cb26d00a15a3f277bc7b09367b4))
* fix issues with apps in /share endpoint ([0cf90ee](https://github.com/HeyPuter/puter/commit/0cf90ee39af6548d271dec45ed8ee9e6df1cd14d))
* fix owner ids for default apps ([283f409](https://github.com/HeyPuter/puter/commit/283f409a662d126e7f3ce811f1467ac6fab9a522))
* fix permission cascade properly this time ([de58866](https://github.com/HeyPuter/puter/commit/de5886698e1eae2b250baac174b57029f3244e96))
* Fix phoenix app prefix and TokenService test ([afb9d86](https://github.com/HeyPuter/puter/commit/afb9d866b5091058711db931cde904947e661c15))
* fix that fix ([b126b67](https://github.com/HeyPuter/puter/commit/b126b670940a0e20cfe7bd0eba3db891bab5c142))
* fix typo ([ce328b7](https://github.com/HeyPuter/puter/commit/ce328b7245ad741b64c5885f64f806fc98a55d84))
* **git:** Make git commit display detached HEAD correctly ([73d0f5a](https://github.com/HeyPuter/puter/commit/73d0f5a90cb5dcbadfc6d0fd22f14e8bc0e61f86))
* group permission audit table ([7d2f6d2](https://github.com/HeyPuter/puter/commit/7d2f6d256f56e30d752e9999c6e8bde68f9d9637))
* handle subpaths under another user ([d128cee](https://github.com/HeyPuter/puter/commit/d128ceed6f4928fa0793815feb2e2715cd273ff8))
* handling of batch requests with zero files ([c0063a8](https://github.com/HeyPuter/puter/commit/c0063a871fd891a1774f1bee00e86170fed249fa))
* i forgot to test reloading ([7eabb43](https://github.com/HeyPuter/puter/commit/7eabb43bd4257b4129d67eaeda2aa27e8268dc78))
* improve console experience on mac ([15465bf](https://github.com/HeyPuter/puter/commit/15465bfc5035a64762f7c86a3d38af8be6be5b59))
* incorrect error from suggested_apps ([b648817](https://github.com/HeyPuter/puter/commit/b648817f2743c2b6214ebe4177d921c9b9027594))
* Make polyfilled import.meta.filename getter a valid function ([85c6798](https://github.com/HeyPuter/puter/commit/85c679844869b6b05fcbda231d8dc7026a66da97))
* null email in request to /share ([bf63144](https://github.com/HeyPuter/puter/commit/bf63144f7a79c48bd650ae851ddd0c8a10d748c3))
* Only run Component initialization functions once ([5b43358](https://github.com/HeyPuter/puter/commit/5b43358219402bee3eadf4a0f184a4b924d3293b))
* oops ([a136ee5](https://github.com/HeyPuter/puter/commit/a136ee5edd3149798a0d82f494f423f503b65f00))
* **parsely:** Make Repeat parser work when no separator is given ([9b4d16f](https://github.com/HeyPuter/puter/commit/9b4d16fbe9d5698c57f9da725a22b528a7d7cac2))
* peers array assumption ([10cbf08](https://github.com/HeyPuter/puter/commit/10cbf08233620440aa39f5302deaac4f59f02247))
* **phoenix:** Add missing newlines to sed command output ([e047b0b](https://github.com/HeyPuter/puter/commit/e047b0bf302284da61e677432e4cc25b531b24f2))
* **phoenix:** Gracefully handle completing a non-existent path ([d76e713](https://github.com/HeyPuter/puter/commit/d76e7130cba9f0ca05940abafe4fd1a41464aa83))
* property validation on some permission endpoints ([0855f2b](https://github.com/HeyPuter/puter/commit/0855f2b36eca3bbdaa8429cbde3aa1242e8e96ee))
* readdir on file ([a72ec97](https://github.com/HeyPuter/puter/commit/a72ec9799ac3bd76ceafa22cce149e373a13f3b9))
* remove last component when share URL is file ([1166e69](https://github.com/HeyPuter/puter/commit/1166e69c76688d1811701c56cd4df9d38e286793))
* remove legacy permission check in stat ([f2c6e01](https://github.com/HeyPuter/puter/commit/f2c6e01296e4214336e63bc2d69bcbf17f59890f))
* Remove null or duplicate app entries from suggest_app_for_fsentry() ([6900233](https://github.com/HeyPuter/puter/commit/6900233c5aaa2d1a49f495e9f9a060796757a91e))
* **security:** Move token for socket.io to request body ([49b257e](https://github.com/HeyPuter/puter/commit/49b257ecffbb1e12090b86a67528a5ad09da69db))
* switch share notif username to sender ([cd65217](https://github.com/HeyPuter/puter/commit/cd65217f5cda1c986ee231e2eeeef5abefa36ecb))
* **Terminal:** Accept input from Chrome on Android ([4ef3e53](https://github.com/HeyPuter/puter/commit/4ef3e53de34f0097950a7e707ca2483863beafb5))
* Throw an error when readdir is called on a non-directory ([46eb4ed](https://github.com/HeyPuter/puter/commit/46eb4ed2b96c235e10e15645a30d2f192a1af0de))
* type error in puter-site ([d96f924](https://github.com/HeyPuter/puter/commit/d96f924cad7a13ea6e9084bb0ebb79ecc5fcb8a3))
* ui color input attributes ([d9c4fbb](https://github.com/HeyPuter/puter/commit/d9c4fbbd1dcce12ee05ee33652a5fa518196463d))
* **ui:** improve Component base class ([f8780d0](https://github.com/HeyPuter/puter/commit/f8780d032b10138851c22af53b8610c578139acc))
* update email share object ([9033f6f](https://github.com/HeyPuter/puter/commit/9033f6f8c74ef8739294d640ac1c7eba95519bbd))
* update PD alert custom details ([2f16322](https://github.com/HeyPuter/puter/commit/2f163221bdde09425cae11ef7f8e4eb0b10c7103))
* update test kernel ([55c609b](https://github.com/HeyPuter/puter/commit/55c609b3fec4ef018febc6e88c44a6277960d728))
* validate size metadata ([2008db0](https://github.com/HeyPuter/puter/commit/2008db08524259264a0c8186a34fc75d7a133f5f))
## 2.3.0 (2024-05-22)
### Features
* add /healthcheck endpoint ([c166560](https://github.com/HeyPuter/puter/commit/c166560ff4ab5a453d3ec4f97326c995deb7f522))
* Add command names to phoenix tab-completion ([cf0eee1](https://github.com/HeyPuter/puter/commit/cf0eee1fa35328e05aefc8a425b5977efe5f4ec9))
* add option to change desktop background to default ([03f05f3](https://github.com/HeyPuter/puter/commit/03f05f316f11e8afe5fcee40b2b80a0de5e6826f))
* allow apps to add a menubar via puter.js ([331d9e7](https://github.com/HeyPuter/puter/commit/331d9e75428ec7609394f59b1755374c7340f83e))
* Allow querying puter-apps driver by partial app names ([dc5b010](https://github.com/HeyPuter/puter/commit/dc5b010d0913d2151b4851f8da5df72d2c8f42e7))
* Display upload errors in UIWindowProgress dialog ([edebbee](https://github.com/HeyPuter/puter/commit/edebbee9e7e9efbb33bf709b637c103be40d15a8))
* Implement 'Like' predicate in entity storage ([a854a0d](https://github.com/HeyPuter/puter/commit/a854a0dc0aa79a31695db833184c5ca3698632a9))
* improve password recovery experience ([04432df](https://github.com/HeyPuter/puter/commit/04432df5540811710ce1cc47ce6c136e5453bccb))
* **security:** add ip rate limiting ([ccf1afc](https://github.com/HeyPuter/puter/commit/ccf1afc93c24ee7f9a126216209a185d6b4d9fe4))
* Show "Deleting /foo" in progress window when deleting files ([f07c13a](https://github.com/HeyPuter/puter/commit/f07c13a50cee790eec44bce2f6e56fbcbf73f9b0))
### Bug Fixes
* Add missing file extension to 0009_app-prefix-fix.sql in DB init ([a8160a8](https://github.com/HeyPuter/puter/commit/a8160a8cdcdd6aff98728a6f1643d93386e6bb5a))
* Add missing TextEncoder to PTT ([8d4a1e0](https://github.com/HeyPuter/puter/commit/8d4a1e0ed3872e2c82b9e4be9b6d8b359e9cea09))
* Correct APIError imports ([062e23b](https://github.com/HeyPuter/puter/commit/062e23b5c9673db1f8b0ff0469289d52dd1e3f99))
* Correct grep output when asking for line numbers ([c8a20ca](https://github.com/HeyPuter/puter/commit/c8a20cadbfd539d185d32f4558916825fcf265ba))
* Correct inverted instanceof check in SignalReader.read() ([d4c2b49](https://github.com/HeyPuter/puter/commit/d4c2b492ef4864804776d3cb7d24797fdc536886))
* Correct variables used in errors in sign.js ([fa7c6be](https://github.com/HeyPuter/puter/commit/fa7c6bee9699527028be0ae9759155bc67c52324))
* Eliminates duplicate translation keys ([5800350](https://github.com/HeyPuter/puter/commit/5800350b253994dea410afff64e3df2a171e7775))
* fix error handling for outdated node versions ([4c1d5a4](https://github.com/HeyPuter/puter/commit/4c1d5a4b6d009ce075897d499d3517219bd745a4))
* Fix phoenix app prefix and TokenService test ([afb9d86](https://github.com/HeyPuter/puter/commit/afb9d866b5091058711db931cde904947e661c15))
* increase QR code size ([d2de46e](https://github.com/HeyPuter/puter/commit/d2de46edfbc05d132d5c929f6935b82515fbbda0))
* Make PathCommandProvider reject queries with path separators ([d733119](https://github.com/HeyPuter/puter/commit/d73311945610417a1ebc7bb0723ced0a599594b4))
* Make url variable accessible to all users of it ([2f30ae7](https://github.com/HeyPuter/puter/commit/2f30ae7a825adcd8da95888c38fe39c34acee0ff))
* Only run Component initialization functions once ([5b43358](https://github.com/HeyPuter/puter/commit/5b43358219402bee3eadf4a0f184a4b924d3293b))
* Parse octal echo escapes ([6ad8f5e](https://github.com/HeyPuter/puter/commit/6ad8f5e06abd050d319271f818d72debf5bc8e44))
* reduce token lengths ([5a76bad](https://github.com/HeyPuter/puter/commit/5a76bad28dfd8ec89a309941e410a54927fae22d))
* reliability issue :bug: ([1d546d9](https://github.com/HeyPuter/puter/commit/1d546d9ef70ef9066ad5838e9782ae330d289f29))
* Remove null or duplicate app entries from suggest_app_for_fsentry() ([6900233](https://github.com/HeyPuter/puter/commit/6900233c5aaa2d1a49f495e9f9a060796757a91e))
* **security:** always use application/octet-stream ([74e213a](https://github.com/HeyPuter/puter/commit/74e213a534dbf2844c8cebeee7eb59ec70de306e))
* **security:** Fix session revocation ([eb166a6](https://github.com/HeyPuter/puter/commit/eb166a67a9f0caf4fd77f9e27dc8209c2fc51f4c))
* **security:** Move token for socket.io to request body ([49b257e](https://github.com/HeyPuter/puter/commit/49b257ecffbb1e12090b86a67528a5ad09da69db))
* **security:** Prevent email enumeration ([ed70314](https://github.com/HeyPuter/puter/commit/ed703146863f896df76c98fad7127c6748c0ef9b))
* **security:** skip cache when checking old passwd ([7800ef6](https://github.com/HeyPuter/puter/commit/7800ef61029c8d1ba47491b4028a0cb972298725))
* **Terminal:** Accept input from Chrome on Android ([4ef3e53](https://github.com/HeyPuter/puter/commit/4ef3e53de34f0097950a7e707ca2483863beafb5))
* test release-please action [#3](https://github.com/HeyPuter/puter/issues/3) ([8fb0a66](https://github.com/HeyPuter/puter/commit/8fb0a66ef21921990e564e5f61c0e80e7f929dc7))
* test release-please action [#4](https://github.com/HeyPuter/puter/issues/4) ([f392de7](https://github.com/HeyPuter/puter/commit/f392de722a5232b622ed91b656a31cdc443c2e84))
* typographical error :bug: ([2949f71](https://github.com/HeyPuter/puter/commit/2949f71691eb0a258888c5d2a5bb496d2fe64a23))
* typographical errors :bug: ([4d30740](https://github.com/HeyPuter/puter/commit/4d30740198402cd1cc61b9ea4c45e006b69ec87e))
* Use correct variable for version number ([52d5299](https://github.com/HeyPuter/puter/commit/52d52993744dffa9f7f59a232da5df9077560731))
* use primary read in signup ([30f17ad](https://github.com/HeyPuter/puter/commit/30f17ade3a893d2283316e581836607e2029f9b9))
## [2.2.0](https://github.com/HeyPuter/puter/compare/v2.1.1...v2.2.0) (2024-04-23)
### Features
* add /healthcheck endpoint ([c166560](https://github.com/HeyPuter/puter/commit/c166560ff4ab5a453d3ec4f97326c995deb7f522))
* allow apps to add a menubar via puter.js ([331d9e7](https://github.com/HeyPuter/puter/commit/331d9e75428ec7609394f59b1755374c7340f83e))
## [2.1.1](https://github.com/HeyPuter/puter/compare/v2.1.0...v2.1.1) (2024-04-22)
### Bug Fixes
* test release-please action [#3](https://github.com/HeyPuter/puter/issues/3) ([8fb0a66](https://github.com/HeyPuter/puter/commit/8fb0a66ef21921990e564e5f61c0e80e7f929dc7))
* test release-please action [#4](https://github.com/HeyPuter/puter/issues/4) ([f392de7](https://github.com/HeyPuter/puter/commit/f392de722a5232b622ed91b656a31cdc443c2e84))
+1
View File
@@ -0,0 +1 @@
FOLLOW ./AGENTS.md
+29 -76
View File
@@ -1,101 +1,54 @@
# Contributing to Puter
# Contributing to Puter Backend
Welcome to Puter, the open-source distributed internet operating system. We're excited to have you contribute to our project, whether you're reporting bugs, suggesting new features, or contributing code. This guide will help you get started with contributing to Puter in different ways.
Thanks for contributing. These rules aren't strictly enforced — but following them makes every PR easier. If anything's unclear, ping a core maintainer or open the PR and ask.
<br>
New to the backend? Start with [doc/architecture.md](doc/architecture.md).
# Report bugs
---
Before reporting a bug, please check our [the issues on our GitHub repository](https://github.com/HeyPuter/puter/issues) to see if the bug has already been reported. If it has, you can add a comment to the existing issue with any additional information you have.
## 1. Test it. Run it.
If you find a new bug in Puter, please [open an issue on our GitHub repository](https://github.com/HeyPuter/puter/issues/new). We'll do our best to address the issue as soon as possible. When reporting a bug, please include as much information as possible, including:
Run the affected code path end-to-end before opening a PR. "It builds" is not "it works."
- A clear and descriptive title
- A description of the issue
- Steps to reproduce the bug
- Expected behavior
- Actual behavior
- Screenshots, if applicable
- Your host operating system and browser
- Your Puter version, location, ...
Add tests for new behavior, endpoints, or bug fixes. If something's genuinely hard to test, say so in the PR.
Please open a separate issue for each bug you find.
## 2. Follow existing patterns
Maintainers will apply the appropriate labels to your issue.
Match the shape of similar code already in the repo. [doc/architecture.md](doc/architecture.md) is the source of truth for layers, wiring, and naming. If you think a pattern is wrong, raise it — don't quietly diverge.
<br>
In plain-JS files, typing is encouraged via JSDoc `@type` annotations using the TypeScript type system, with `@typedef` for shared shapes. Don't type API surfaces as `unknown` or untyped `...args` unless the values are passed through transparently to an upstream layer that owns their type.
# Suggest new features
## 3. Don't expose system or user information
If you have an idea for a new feature in Puter, please open a new discussion thread on our [GitHub repository](https://github.com/HeyPuter/puter/discussions) to discuss your idea with the community. We'll do our best to respond to your suggestion as soon as possible.
Scan your diff for stray logs, debug routes, internal paths, secrets, tokens, or user data in errors/responses. When in doubt, return less. Flag any auth, permission, or data-export changes in the PR description.
When suggesting a new feature, please include as much information as possible, including:
For private security reports, see [SECURITY.md](SECURITY.md).
- A clear and descriptive title
- A description of the feature
- The problem the feature will solve
- Any relevant screenshots or mockups
- Any relevant links or resources
## 4. AI-assisted code is fine — understood code is required
<br>
Don't commit code you couldn't have written, debugged, or defended yourself. Read the diff, run it, and be ready to explain it in review.
# Contribute code
## 5. Adding or changing APIs
If you'd like to contribute code to Puter, you need to fork the project and submit a pull request. If this is your first time contributing to an open-source project, we recommend reading this short guide by GitHub on [how to contribute to a project](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project).
If you add or change a public API (an endpoint, driver method, or puter-js method), follow [doc/contributing-apis.md](doc/contributing-apis.md) — backward compatibility, [developer docs](src/docs/), types, and tests all move in the same PR.
We'll review your pull request and work with you to get your changes merged into the project.
The same rule applies to limits: rate limits, concurrency caps, quotas, and allowances are published in [src/docs/src/rate-limits-and-quotas.md](src/docs/src/rate-limits-and-quotas.md), and a PR that changes one of those numbers updates that page in the same PR. A limit nobody published is a limit developers only discover as a service failure.
## Your first code contribution
## 6. Boy Scout Rule — leave it 1% better
We maintain a list of issues that are good for first-time contributors. You can find these issues by searching for the [`good first issue`](https://github.com/HeyPuter/puter/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label in our [GitHub repository](https://github.com/HeyPuter/puter). These issues are designed to be relatively easy to fix, and we're happy to help you get started. Pick an issue that interests you, and leave a comment on the issue to let us know you're working on it.
![Boy Scout Rule](https://imgs.search.brave.com/DMmIWl5-NuZVtrR9kXBb06AKF8kturkgSW9UMb2-6m4/rs:fit:860:0:0:0/g:ce/aHR0cHM6Ly9sYXdz/b2Zzb2Z0d2FyZWVu/Z2luZWVyaW5nLmNv/bS9pbWFnZXMvbGF3/cy9ib3ktc2NvdXQt/cnVsZS5wbmc)
<br>
Fix the typo, the dead import, the missing test, the bit you had to read twice. Keep cleanup proportional to the change — no refactors riding along on bug fixes.
## Documentation for Contributors
---
See [doc/contributors/index.md](./doc/contributors/index.md) for more information.
## Opening a PR
<br>
- One thing per PR where possible.
- Describe **what** and **why**; the diff shows how.
- Mention how you tested user-visible changes.
- Drafts welcome.
## Commit Messages
---
Use the imperative, as is the convention in the Linux kernel:
- correct: `Improve performance of readdir`
- incorrect: `Improved readdir`
- incorrect: `Improving readdir`
We have the following exceptions to this rule:
- If the commit message is in _past tense_, it's a shorthand for the following:
- `Apply changes that would be applied after one had <past tense message>`
- If the commit message is in _present tense_, it's shorthand for the following:
- `Apply changes that would be applied after <present-tense message>`
For example, the following are correct:
- `Improved readdir`
- interpret this as: `Apply changes that would be applied after one had improved readdir`
- `Improving readdir`
- interpret this as: `Apply changes that would be applied after improving readdir`
<br>
## Code Review
Once you've submitted your pull request, the project maintainers will review your changes. We may suggest some changes or improvements. This is a normal part of the process, and your contributions are greatly appreciated!
<br>
## Contribution License Agreement (CLA)
Like many open source projects, we require contributors to sign a Contribution License Agreement (CLA) before we can accept your code. When you open a pull request for the first time, a bot will automatically add a comment with a link to the CLA. You can sign the CLA electronically by following the link and filling out the form.
<br>
# Getting Help
If you have any questions about Puter, please feel free to reach out to us through the following channels:
- [Discord](https://discord.com/invite/PQcx7Teh8u)
- [Reddit](https://www.reddit.com/r/Puter/)
- [Twitter](https://twitter.com/HeyPuter)
- [Email](mailto:[email protected])
Questions? Message a core maintainer. Welcome aboard.
+69 -55
View File
@@ -1,74 +1,88 @@
# /!\ NOTICE /!\
# syntax=docker/dockerfile:1.7
#
# OSS Puter image — multi-arch (linux/amd64, linux/arm64).
#
# Build & push:
# docker buildx build --platform linux/amd64,linux/arm64 \
# -t ghcr.io/heyputer/puter:latest --push .
#
# Local single-arch build:
# docker build -t puter .
#
# Self-hosters inject configuration by mounting a config.json at
# /etc/puter/config.json. It is deep-merged over the bundled
# config.default.json, so partial overrides work. Absent file = defaults.
# Many of the developers DO NOT USE the Dockerfile or image.
# While we do test new changes to Docker configuration, it's
# possible that future changes to the repo might break it.
# When changing this file, please try to make it as resiliant
# to such changes as possible; developers shouldn't need to
# worry about Docker unless the build/run process changes.
# ---- Build stage ----
FROM node:24-slim AS build
# Build stage
FROM node:21-alpine AS build
WORKDIR /opt/puter
# Install build dependencies
RUN apk add --no-cache git python3 make g++ \
&& ln -sf /usr/bin/python3 /usr/bin/python
# Build toolchain needed for native deps (bcrypt, sharp, better-sqlite3, …).
RUN apt-get update && \
apt-get install -y --no-install-recommends python3 make g++ git && \
rm -rf /var/lib/apt/lists/*
# Set up working directory
WORKDIR /app
ENV HUSKY=0
ENV npm_config_fund=false
ENV npm_config_audit=false
# Copy package.json and package-lock.json
COPY package*.json ./
# ---- Dependency layer ---------------------------------------------------
# Copy ONLY package manifests + lockfile first so the npm-install layer
# stays cached when only source files change.
COPY package.json package-lock.json ./
COPY src/backend/package.json src/backend/
COPY src/gui/package.json src/gui/
COPY src/puter-js/package.json src/puter-js/package-lock.json src/puter-js/
COPY src/worker/package.json src/worker/
COPY src/docs/package.json src/docs/
# Copy the source files
# extensionSetup.mjs runs as the postinstall hook during npm ci. (No-ops
# unless any packages/puter/extensions/* gain a package.json.)
COPY tools/extensionSetup.mjs tools/extensionSetup.mjs
RUN --mount=type=cache,target=/root/.npm \
npm ci
# ---- Source layer -------------------------------------------------------
COPY . .
# Install mocha
RUN npm install -g mocha
# Compile backend TS, then build GUI + puter-js webpack bundles in
# parallel. The GUI/puter-js bundles are how /dist/bundle.min.{js,css}
# and /sdk/puter.js fall back to local assets when the kernel-config
# CDN keys are unset.
RUN npm run build:ts
RUN set -e; \
(cd src/gui && node ./build.js) & gui_pid=$!; \
(cd src/puter-js && npm run build) & pjs_pid=$!; \
wait $gui_pid; \
wait $pjs_pid
# Install node modules
RUN npm cache clean --force && \
for i in 1 2 3; do \
npm ci && break || \
if [ $i -lt 3 ]; then \
sleep 15; \
else \
exit 1; \
fi; \
done
# ---- Runtime stage (slim — no build tools) ----
FROM node:24-slim
# Run the build command if necessary
RUN cd src/gui && npm run build && cd -
WORKDIR /opt/puter
# Production stage
FROM node:21-alpine
# git: runtime version probe. wget: HEALTHCHECK.
RUN apt-get update && \
apt-get install -y --no-install-recommends git wget && \
rm -rf /var/lib/apt/lists/*
# Set labels
LABEL repo="https://github.com/HeyPuter/puter"
LABEL license="AGPL-3.0,https://github.com/HeyPuter/puter/blob/master/LICENSE.txt"
LABEL version="1.2.46-beta-1"
COPY --from=build --chown=node:node /opt/puter .
# Install git (required by Puter to check version)
RUN apk add --no-cache git
RUN mkdir -p /etc/puter /var/puter && \
chown -R node:node /etc/puter /var/puter
# Set up working directory
RUN mkdir -p /opt/puter/app
WORKDIR /opt/puter/app
# Copy built artifacts and necessary files from the build stage
COPY --from=build /app/src/gui/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY . .
# Set permissions
RUN chown -R node:node /opt/puter/app
USER node
# Self-hosters mount their override at this exact path. The v2 loader
# deep-merges it over config.default.json (see backend/index.ts).
ENV PUTER_CONFIG_PATH=/etc/puter/config.json
ENV NODE_OPTIONS=--enable-source-maps
EXPOSE 4100
HEALTHCHECK --interval=30s --timeout=3s \
USER node
HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://puter.localhost:4100/test || exit 1
ENV NO_VAR_RUNTUME=1
CMD ["npm", "start"]
CMD ["node", "-r", "./dist/src/backend/telemetry.js", "./dist/src/backend/index.js"]
+64 -48
View File
@@ -1,37 +1,35 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">The Internet OS! Free, Open-Source, and Self-Hostable.</h3>
<h3 align="center">The Open-Source Internet Computer!</h3>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
<a href="https://puter.com/?ref=github.com"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
<a href="https://puter.com/?ref=github.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
<a href="https://apps.puter.com/">App Store</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
<a href="https://developer.puter.com" target="_blank">Developers</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
·
<a href="https://hackerone.com/puter_h1b">Bug Bounty</a>
<a href="https://twitter.com/HeyPuter">X</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot.webp"></h3>
<br/>
## Puter
Puter is an advanced, open-source internet operating system designed to be feature-rich, exceptionally fast, and highly extensible. Puter can be used as:
Puter is an advanced, open-source, self-hostable internet computer designed to be feature-rich, fast, and highly extensible.
- A privacy-first personal cloud to keep all your files, apps, and games in one secure place, accessible from anywhere at any time.
- A platform for building and publishing websites, web apps, and games.
- An alternative to Dropbox, Google Drive, OneDrive, etc. with a fresh interface and powerful features.
- A remote desktop environment for servers and workstations.
- A friendly, open-source project and community to learn about web development, cloud computing, distributed systems, and much more!
### For Users
Puter's goal is to provide you with every app and feature you need to work, create, and play under one roof. From a simple [Notepad](https://online-notepad.com) and [Voice Recorder](https://voice-recorder.com) to [Spreadsheet](https://apps.puter.com/app/spreadsheet) and [Camera](https://online-camera.com), Puter wants to be the all-in-one solution for your digital life.
### For Developers
Puter provides everything you need to build and publish web apps and games. From [AI](https://developer.puter.com/ai/) to [Cloud Storage](https://developer.puter.com/object-storage/) and [Database](https://developer.puter.com/key-value-database/) to [Serverless Workers](https://developer.puter.com/serverless-workers/), Puter has you covered. Puter also helps you get users! Once you build your app, you can publish it on our [App Store](https://apps.puter.com/) to reach and monetize users.
<br/>
@@ -46,44 +44,27 @@ cd puter
npm install
npm start
```
**→** This should launch Puter at http://puter.localhost:4100
This will launch Puter at http://localhost:4000 (or the next available port).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
### 🚀 Self-Hosting
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
curl -fsSL https://puter.com/selfhost | sh
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
irm https://puter.com/selfhost?os=windows | iex
```
**→** For more details, see [Self-Hosting Puter](./doc/self-hosting.md).
<br/>
### ☁️ Puter.com
@@ -96,20 +77,55 @@ Puter is available as a hosted service at [**puter.com**](https://puter.com).
Connect with the maintainers and community through these channels:
- Bug report or feature request? Please [open an issue](github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- Bug report or feature request? Please [open an issue](https://github.com/HeyPuter/puter/issues/new/choose).
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Security issues or abuse reports? [[email protected]](mailto:security@puter.com)
- Email maintainers at [[email protected]](mailto:[email protected])
We are always happy to help you with any questions you may have. Don't hesitate to ask!
<br/>
## License
## License
This repository, including all its contents, sub-projects, modules, and components, is licensed under [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) unless explicitly stated otherwise. Third-party libraries included in this repository may be subject to their own licenses.
<br/>
## Translations
- [Arabic / العربية](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ar.md)
- [Armenian / Հայերեն](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hy.md)
- [Bengali / বাংলা](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.bn.md)
- [Chinese / 中文](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.zh.md)
- [Danish / Dansk](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.da.md)
- [English](https://github.com/HeyPuter/puter/blob/main/README.md)
- [Farsi / فارسی](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fa.md)
- [Finnish / Suomi](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fi.md)
- [French / Français](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fr.md)
- [German / Deutsch](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.de.md)
- [Hebrew/ עברית](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.he.md)
- [Hindi / हिंदी](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hi.md)
- [Hungarian / Magyar](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hu.md)
- [Indonesian / Bahasa Indonesia](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.id.md)
- [Italian / Italiano](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.it.md)
- [Japanese / 日本語](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.jp.md)
- [Korean / 한국어](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ko.md)
- [Malay / Bahasa Malaysia](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.my.md)
- [Malayalam / മലയാളം](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ml.md)
- [Dutch / Nederlands](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.nl.md)
- [Polish / Polski](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pl.md)
- [Odia / ଓଡ଼ିଆ](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.od.md)
- [Portuguese / Português](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pt.md)
- [Punjabi / ਪੰਜਾਬੀ](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pa.md)
- [Romanian / Română](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ro.md)
- [Russian / Русский](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ru.md)
- [Spanish / Español](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.es.md)
- [Swedish / Svenska](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.sv.md)
- [Tamil / தமிழ்](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ta.md)
- [Telugu / తెలుగు](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.te.md)
- [Thai / ไทย](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.th.md)
- [Turkish / Türkçe](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.tr.md)
- [Ukrainian / Українська](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ua.md)
- [Urdu / اردو](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ur.md)
- [Vietnamese / Tiếng Việt](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.vi.md)
+2 -1
View File
@@ -3,6 +3,7 @@ We would like to thank the following security researchers for their responsible
# 2024
- Ritesh Sahu [GitHub](https://github.com/riteshs4hu/) | [X](https://x.com/riteshs4hu) | [Website](https://medium.com/@riteshs4hu)
- Tim Suess: [GitHub](https://github.com/blackfortresslabs) | [Email]([email protected]) | [Website](https://www.blackfortresslabs.com)
- xyzeva: [Github](https://github.com/xyzeva) | [Email](mailto:[email protected]) | [Website](https://kibty.town/)
- Yusuf Kelany: [GitHub](https://github.com/YusufYaser) | [Twitter](https://x.com/RealYusufYaser) | [Website](https://yusufyaser.xyz)
- Yusuf Kelany: [GitHub](https://github.com/YusufYaser) | [X](https://x.com/RealYusufYaser) | [Website](https://yusufyaser.xyz)
+2 -2
View File
@@ -14,7 +14,8 @@ If you believe you've found a security issue in software that is maintained in t
To submit a vulnerability report, please contact us at security@puter.com. Your submission will be reviewed and validated by a member of our team.
**⚠ Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests. ⚠**
> [!WARNING]
> Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.
<br>
@@ -37,4 +38,3 @@ Please submit a report to us before engaging in conduct that may be inconsistent
* Please provide detailed reports with reproducible steps and a clearly defined impact.
* Include the version number of the vulnerable package in your report
* Social engineering (e.g. phishing, vishing, smishing) is prohibited.
+214
View File
@@ -0,0 +1,214 @@
# Trademark Guidelines
Version 1.0 dated January 1, 2025
<img src="https://puter.com/images/logo.png" alt="Puter Technologies Inc. Logo" width="150"/>
<br>
This trademark policy was prepared to help you understand how to use the Puter trademarks, service marks and logos with Puter Technologies Inc.'s Puter software.
While some of our software is available under a free and open source software license, that copyright license does not include a license to use our trademark, and this Policy is intended to explain how to use our marks consistent with background law and community expectation.
This Policy covers:
1. Our **word** trademarks and service marks: Puter Technologies Inc., Puter, Puter.com
2. Our **logos**: The Puter Technologies Inc. logo at the top of this policy
This policy encompasses all trademarks and service marks, whether they are registered or not.
<br>
<br>
## 1. GENERAL GUIDELINES
Whenever you use one of our marks, you must always do so in a way that does not mislead anyone about what they are getting and from whom. For example, you cannot say you are providing the Puter software when you're providing a modified version of it, because recipients may not understand the differences between your modified versions and our own.
You also cannot use our logo on your website in a way that suggests that your website is an official website or that we endorse your website.
You can, though, say you like the Puter software, that you participate in the Puter community, that you are providing an unmodified version of the Puter software.
You may not use or register our marks, or variations of them as part of your own trademark, service mark, domain name, company name, trade name, product name or service name.
Trademark law does not allow your use of names or trademarks that are too similar to ours. You therefore may not use an obvious variation of any of our marks or any phonetic equivalent, foreign language equivalent, takeoff, or abbreviation for a similar or compatible product or service. We would consider the following too similar to one of our Marks:
- MyPuter
- PuterFooBar
<br>
<br>
## 2. ACCEPTABLE USES
<br>
### Distribution of Unmodified Software
When you redistribute an unmodified copy of Puter software, you must retain all trademarks, logos, and notices we have placed on the software to identify its origin. This includes:
* Binary distributions exactly as we provide them
* Source code distributions exactly as we provide them
* Documentation and other materials directly from our official repositories
<br>
### Distribution of Modified Software
If you distribute a modified version of Puter software, you:
* Must remove all Puter logos from the modified software
* May use our word marks (but not logos) to accurately describe the software's origin
* Must clearly indicate that the software has been modified
* Must include a notice stating: "This software is a modified version of Puter software and is not endorsed by Puter Technologies Inc."
Example of acceptable description: "This software is derived from Puter software and includes modifications for [describe your changes]."
<br>
### Compatibility Statements
You may use our word marks (but not logos) to accurately describe your software's compatibility with Puter software under these conditions:
* Your statements about compatibility must be accurate and not misleading
* You must include the following notice: "Puter is a trademark of Puter Technologies Inc. This [product/service] is not affiliated with or endorsed by Puter Technologies Inc."
* You may not suggest that Puter Technologies Inc. has certified or approved your software
<br>
### Products Built for Puter
You may describe your product as working with or being built for Puter if:
* Your product is fully compatible with the documented Puter APIs
* Your product name follows this format: "[Your Product Name] for Puter"
* You include this notice in all materials: "Puter is a trademark of Puter Technologies Inc. [Your Product Name] is not affiliated with or endorsed by Puter Technologies Inc."
* Your branding and marketing materials do not create confusion about the source of your product
<br>
### Open Source Projects
For open source projects that interact with or extend Puter software:
* You may use "puter" as part of your project name only if:
* The name is in the format "[descriptor]-puter" (e.g., "auth-puter", "backup-puter")
* The project's README clearly states it's not officially associated with Puter
* The project maintains compatibility with current Puter APIs
* You must not use our logos without explicit permission
* You must include appropriate trademark attribution notices
<br>
### Community Activities
You may use our word marks (but not logos) for non-commercial community activities:
* User groups and meetups focused on Puter software
* Educational content about Puter software
* Blog posts, videos, articles, or tutorials about Puter software
Conditions for community use:
* Activities must be non-commercial
* Any fees charged must only cover actual costs
* You must include appropriate trademark attribution
* You must not suggest official endorsement without explicit permission
<br>
### Merchandise and Promotional Items
You may not create merchandise or promotional items bearing our marks without explicit written permission from Puter Technologies Inc.
<br>
### Academic and Research Use
You may use our word marks (but not logos) in:
* Academic papers
* Research publications
* Technical documentation
* Educational materials
Include appropriate citations and trademark attributions in such uses.
<br>
### Online Content and Social Media
When using our marks in online content:
* You may use our word marks in hashtags, handles, or usernames if:
* The content is clearly about Puter software
* You don't imply official status
* You include appropriate trademark attribution
* You must not register social media accounts that could be confused with official Puter accounts
<br>
### APIs and Development
When developing with Puter APIs:
* You may use our word marks to accurately describe your integration
* You must not use our marks in a way that suggests your API or service is endorse by
Puter or provided by Puter
* You must include appropriate trademark attribution
All uses described above must also comply with the General Guidelines section of this policy and maintain the integrity of our marks as described in the How to Display Our Marks section.
<br>
### No Domain Names
You must not register any domain that includes our word marks or any variant or combination of them.
<br>
<br>
## 3. HOW TO DISPLAY OUR MARKS
When you have the right to use our mark, here is how to display it.
<br>
### Trademark marking and legends
The first or most prominent mention of a mark on a webpage, document, or documentation should be accompanied by a symbol indicating whether the mark is a registered trademark ("®") or an unregistered trademark ("™"). If you don't know which applies, contact us.
Place the following notice at the foot of the page where you have used the mark: "Puter is trademark of Puter Technologies Inc."
<br>
### Use of trademarks in text
**Always use trademarks in their exact form with the correct spelling, neither abbreviated, hyphenated, or combined with any other word or words.**
Unacceptable: Puter-DB
**Don't pluralize a trademark.**
Unacceptable: I have seventeen Puters running in my lab.
**Always use a trademark as an adjective modifying a noun.**
Unacceptable: This is a Puter.
Acceptable: This is a Puter software application.
<br>
### Use of Logos
You may not change any logo except to scale it. This means you may not add decorative elements, change the colors, change the proportions, distort it, add elements, or combine it with other logos.
However, when the context requires the use of black-and-white graphics and the logo is color, you may reproduce the logo in a manner that produces a black-and-white image.
<br>
<br>
## This Document
These guidelines are based on the Model Trademark Guidelines, available at http://www.modeltrademarkguidelines.org., used under a Creative Commons Attribution 3.0 Unported license: https://creativecommons.org/licenses/by/3.0/deed.en_US.
-1
View File
@@ -1 +0,0 @@
header: doc/license_header.txt
-14
View File
@@ -1,14 +0,0 @@
# #DoesItRunPuter
- [Minecraft](https://twitter.com/HeyPuter/status/1771957571496092036) | [video](https://www.youtube.com/watch?v=GIowZUXkg5g)
- [Samsung Watch](https://twitter.com/CharmunkDev/status/1781501714543030554)
- [PlayStation 4](https://twitter.com/HeyPuter/status/1767978053014270059)
- [Skyworth TV](https://twitter.com/ericalexdube/status/1767983049277411564)
- [A Fridge!](https://twitter.com/HeyPuter/status/1778890003797745842)
- [Oculus Quest 2](https://twitter.com/HeyPuter/status/1768664081756754012)
- [Tesla Model 3](https://twitter.com/EricLighthall/status/1781479732997214501)
- [Tesla Model S](https://twitter.com/HeyPuter/status/1767971178864587057)
- [Tesla Model Y](https://twitter.com/HeyPuter/status/1772858333751636310)
- [Nintendo Switch](https://twitter.com/HeyPuter/status/1780645795240538518)
- [Steam Deck](https://twitter.com/everythingSung/status/1782162352403828793)
- [Ladybird Browser](https://x.com/HeyPuter/status/1810783504503800035)
+73
View File
@@ -0,0 +1,73 @@
# Reverse proxy in front of Puter — mirrors what the prod ALB does:
# accepts every Host header, forwards to the Puter container, and lets
# the Puter app handle subdomain-based routing internally (api.*,
# site.*, app.*, dev.*, plus the per-user subdomains under those).
#
# To enable TLS:
# 1. Drop a wildcard fullchain.pem + privkey.pem into ./puter/tls/
# (see "Step 3 — TLS" in doc/self-hosting.md).
# 2. Uncomment the `:443` block at the bottom of this file, and swap the
# `:80` block for the redirect shown alongside it.
# 3. Uncomment the `443:443` port mapping under the `caddy` service in
# docker-compose.yml, and HTTPS_PORT in .env.
# 4. Set `"protocol": "https"` and `"pub_port": 443` in config.json.
{
# Certs are supplied by the operator, not issued by Caddy. Puter serves
# per-user sites and apps on dynamic subdomains (<name>.site.<domain>,
# <name>.app.<domain>) — only a DNS-01 wildcard cert covers those, and
# DNS-01 needs a provider plugin that isn't in the stock caddy image.
# `off` stops Caddy attempting ACME on boot (it would fail and leave the
# site unreachable) and stops it inventing its own http→https redirects.
auto_https off
}
# Shared handling, imported by the HTTP and HTTPS site blocks below so the
# two can't drift apart.
(puter_routes) {
# Rough size cap that mirrors prod ALB defaults; tune for your uploads.
# Puter chunks large uploads, so 1 GiB per request is plenty.
request_body {
max_size 1024MiB
}
# RustFS — see the `s3` service in docker-compose.yml. Browsers PUT/GET
# here for presigned-URL uploads / downloads. Matched on the `s3.`
# subdomain of whatever the install domain is, so signature verification
# works (Caddy preserves the original Host end-to-end) and HTTPS stays
# clean — no mixed content from a port-9000 host publish.
@s3 header_regexp Host ^s3\.
handle @s3 {
reverse_proxy s3:9000
}
# Everything else, on every Host, goes to Puter — which routes on that
# Host internally. Caddy forwards it unchanged and adds X-Forwarded-For
# / -Proto / -Host, which is what `trust_proxy` in config.json counts.
handle {
reverse_proxy puter:4100 {
# Stream responses through unbuffered — Puter uses SSE and
# socket.io. WebSocket upgrades need no config of their own;
# Caddy proxies them by default.
flush_interval -1
}
}
}
# ── HTTP (port 80) ─────────────────────────────────────────────────────
# A site address with no hostname is the catch-all: it answers for every
# Host, which is what Puter's subdomain routing requires.
:80 {
import puter_routes
}
# ── HTTPS (port 443) — uncomment after dropping certs in ./puter/tls/ ──
# Replace the `:80` block above with a redirect to force HTTPS everywhere:
#
# :80 {
# redir https://{host}{uri} permanent
# }
#
# :443 {
# tls /etc/caddy/tls/fullchain.pem /etc/caddy/tls/privkey.pem
# import puter_routes
# }
+48
View File
@@ -0,0 +1,48 @@
{
"config_name": "oss-default",
"env": "dev",
"port": 4100,
"protocol": "http",
"domain": "puter.localhost",
"cookie_name": "puter_auth_token",
"jwt_secret_v2": "dev-jwt-secret-v2-change-me",
"url_signature_secret": "dev-url-signature-secret-change-me",
"allow_all_host_values": true,
"allow_no_host_header": true,
"no_devwatch": false,
"enable_public_folders": true,
"is_storage_limited": false,
"min_pass_length": 6,
"static_hosting_domain": "site.puter.localhost",
"static_hosting_domain_alt": "host.puter.localhost",
"private_app_hosting_domain": "app.puter.localhost",
"private_app_hosting_domain_alt": "dev.puter.localhost",
"captcha": { "enabled": false },
"default_user_group": "78b1b1dd-c959-44d2-b02c-8735671f9997",
"default_temp_group": "b7220104-7905-4985-b996-649fdcdb3c8f",
"storage_capacity": 104857600,
"disable_user_signup": false,
"teams_enabled": false,
"max_teams_per_user": 1,
"max_seats_per_team_free": 4,
"max_seats_per_team_paid": 40,
"strict_email_verification_required": false,
"gui_assets_root": "./src/gui",
"puterjs_root": "./src/puter-js/dist",
"builtin_apps": {
"dev-center": "./src/dev-center"
},
"extensions": [
"./extensions"
],
"database": {
"engine": "sqlite",
"path": "volatile/runtime/puter-database.sqlite"
},
"s3": {
"localConfig": {
"dataDir": "volatile/runtime/fauxqs-data",
"s3StorageDir": "volatile/runtime/fauxqs-s3-data"
}
}
}
+541
View File
@@ -0,0 +1,541 @@
{
// Comprehensive template — every key the OSS backend or shipped (non-prod)
// extensions read. Copy to `config.json` and trim what you don't need;
// unset keys fall back to documented defaults. See
// `src/backend/types.ts` for the per-field source of truth.
//
// Each setting lives at exactly one canonical key — there are no fallback
// aliases. Values shown are illustrative, not production secrets.
//
// Keys consumed only by closed-source / hosted-prod extensions (clickhouse,
// cacheUpdateHandler, pages, prodMeteringAndBilling, …) are intentionally
// omitted.
// ── Environment / identity ──────────────────────────────────────────
"config_name": "template",
// `dev` opens a browser on boot, skips blocked-email checks, and runs the
// dev-time webpack watcher; `prod` serves pre-built bundles.
"env": "dev",
// Console output format. `json` replaces the global console so every call
// emits one structured JSON line (level, timestamp, msg, and the active
// request's trace id) — one event per call, so a line-oriented log
// collector can't split stack traces across events and level filtering
// works. Unset (the default) leaves console output human-readable.
"log_format": "text",
"version": "0.0.0",
// Stable identity for this server node — used by pager alerts and
// graceful-shutdown coordination.
"serverId": "node-1",
// ── Networking / URLs ───────────────────────────────────────────────
// Port Puter listens on internally.
"port": 4100,
// Externally-visible port (set this when behind a reverse proxy on 80/443).
"pub_port": 4100,
"protocol": "http",
"domain": "puter.localhost",
// Fully-qualified externally-visible URL. Computed from protocol/domain/
// pub_port if unset.
"origin": "http://puter.localhost:4100",
// Public base URL for the API subdomain (used to build signed URLs and
// surfaced to the client by the `installedApps` and `whoami` extensions).
"api_base_url": "http://api.puter.localhost:4100",
// Subdomains Puter routes on. Wildcard DNS (`*.<domain>`) must point at
// this server for site/app hosting to work.
"static_hosting_domain": "site.puter.localhost",
"static_hosting_domain_alt": "host.puter.localhost",
"private_app_hosting_domain": "app.puter.localhost",
"private_app_hosting_domain_alt": "dev.puter.localhost",
// Host-header / domain handling. Defaults below are the dev-friendly
// settings; tighten for any public install.
"allow_all_host_values": true,
"allow_no_host_header": true,
"allow_nipio_domains": false,
"custom_domains_enabled": false,
"enable_ip_validation": false,
// Express `trust proxy` setting — set to the number of reverse-proxy
// hops in front of the server (1 = nginx/Cloudflare, 2 = CF→ALB→app),
// or to a CIDR / IP / list. `false` (safe default) makes `req.ip` the
// direct socket peer. NEVER set to `true` in prod — it trusts every hop
// and makes X-Forwarded-For forgeable.
"trust_proxy": false,
"no_browser_launch": false,
// ── Dev watcher (devWatcher extension) ──────────────────────────────
// Rebuilds GUI + puter.js on file changes when running from source.
// Ignored when `env: "prod"` unless `devwatch.enabled: true`.
"no_devwatch": false,
"devwatch": {
// Delay after watcher startup before boot continues. Lets webpack
// emit its first build so the homepage doesn't 404 on bundle.min.js.
"ready_delay_ms": 5000
},
// ── Auth / session ──────────────────────────────────────────────────
// ALWAYS replace these for any public install — `openssl rand -hex 64`.
"jwt_secret_v2": "change-me",
"url_signature_secret": "change-me",
"cookie_name": "puter_auth_token",
"min_pass_length": 6,
// When true, anonymous users must log in instead of creating temp or
// permanent accounts.
"disable_user_signup": false,
"allow_system_login": false,
"strict_email_verification_required": false,
"captcha": {
"enabled": false,
"difficulty": "medium"
},
"oidc": {
"providers": {
// Google uses OIDC discovery — only ids are required.
"google": {
"client_id": "",
"client_secret": "",
"scopes": "openid email profile"
},
// Custom OIDC providers must also supply the three endpoints.
"custom-oidc": {
"client_id": "",
"client_secret": "",
"authorization_endpoint": "",
"token_endpoint": "",
"userinfo_endpoint": "",
"scopes": "openid email profile"
}
}
},
// ── Groups / provisioning ───────────────────────────────────────────
// UIDs of the persistent groups new users are auto-enrolled in.
"default_user_group": "78b1b1dd-c959-44d2-b02c-8735671f9997",
"default_temp_group": "b7220104-7905-4985-b996-649fdcdb3c8f",
// When true, ACL grants read/list on `/<user>/Public` to any actor.
"enable_public_folders": true,
// ── Storage / S3 ────────────────────────────────────────────────────
"s3": {
// Local fauxqs (in-process S3-compatible) — used in dev and the
// bundled-defaults Docker mode. Files land under `dataDir`.
"localConfig": {
"inMemory": false,
"host": "127.0.0.1",
"port": 4566,
"dataDir": "volatile/runtime/fauxqs-data",
"s3StorageDir": "volatile/runtime/fauxqs-s3-data"
},
// For real / external S3, replace `localConfig` above with `s3Config`.
"_remote_example": {
"s3Config": {
"useCredentialChain": false,
"endpoint": "https://s3.example.com",
// Endpoint used in presigned URLs handed to the browser. Set
// this when the server-side endpoint isn't reachable from the
// browser (e.g. docker-internal `http://s3:9000`).
"publicEndpoint": "",
"accessKeyId": "",
"secretAccessKey": "",
"region": "us-west-2",
// Set true for RustFS / MinIO / fauxqs (path-style URLs).
// Real AWS S3 wants virtual-hosted — leave unset / false.
"forcePathStyle": false
}
}
},
"s3_bucket": "puter-local",
"s3_region": "us-west-2",
"region": "us-west-2",
// Default per-user storage cap (bytes). 100 MB.
"storage_capacity": 104857600,
"is_storage_limited": false,
"available_device_storage": 0,
// ── Thumbnails (thumbnails extension) ───────────────────────────────
// Optional dedicated S3-compatible bucket for generated thumbnails.
// When unset (or `endpoint` empty), the extension falls back to the
// main S3 client / bucket above.
"thumbnailStore": {
"name": "puter-local",
"endpoint": "",
"credentials": {
"accessKeyId": "",
"secretAccessKey": ""
}
},
// ── Database ────────────────────────────────────────────────────────
"database": {
// `sqlite` for single-node/dev, `mysql` for MariaDB/MySQL,
// or `postgres` for PostgreSQL.
//
// NOTE: `postgres` support is a community contribution and is not
// exercised by Puter.com production. It boots, passes its own
// integration tests against pgmock, and runs the common user/app/
// fsentry/session/permission/OIDC flows — but less-traveled code
// paths may surface MySQL/SQLite-isms that haven't been ported yet.
// Expect rough edges and please file issues if you hit one. For
// production self-hosting today, `mysql` (MariaDB) and `sqlite` are
// the supported defaults.
"engine": "sqlite",
// sqlite — file path on disk
"path": "volatile/runtime/puter-database.sqlite",
"targetVersion": 0,
// mysql/postgres — connection details. PostgreSQL defaults to port
// 5432 when `engine` is `postgres`; MySQL/MariaDB normally use 3306.
"host": "",
"port": 3306,
"user": "",
"password": "",
"database": "",
// postgres may also use a URL instead of host/user/password fields:
// "connectionString": "postgres://puter:secret@localhost:5432/puter",
// Optional read-replica pool. Reads route here when populated.
"replica": {
"host": "",
"port": 3306,
"user": "",
"password": "",
"database": ""
}
// mysql/postgres self-host bootstrap: set `migrationPaths` to apply the
// bundled schema on first boot. Idempotent — safe to leave on.
// "migrationPaths": ["./src/backend/clients/database/migrations/mysql"]
// "migrationPaths": ["./src/backend/clients/database/migrations/postgres"]
},
// ── DynamoDB (KV store) ─────────────────────────────────────────────
"dynamo": {
// Local emulator (dynamodb-local) endpoint. Drop this field for real
// AWS DynamoDB.
"endpoint": "http://localhost:8000",
// Set true when pointing at a local emulator so Puter creates the KV
// table on boot. NEVER set against real AWS — provision via IaC.
// "bootstrapTables": true,
"path": "",
// Credentials. NOTE: snake_case here, unlike `s3.s3Config` below.
// For dynamodb-local, any non-empty values work.
"aws": {
"access_key": "",
"secret_key": "",
"region": "us-west-2"
}
},
// ── Redis / Valkey (cache + cross-node rate limit) ──────────────────
"redis": {
// True → in-process redis-mock (dev / single-node).
"useMock": true,
// Cluster nodes for ioredis. For a single Valkey/Redis container,
// run it in cluster mode (one node, all slots).
"startupNodes": [
{
"host": "127.0.0.1",
"port": 7000
}
]
// Defaults to true (matches prod ElastiCache). Set false for plain-TCP
// self-host Valkey/Redis.
// "tls": false
},
// ── Email (transactional) ───────────────────────────────────────────
// Nodemailer transport — used for password resets, email confirmation, etc.
"email": {
"from": "\"Puter\" <[email protected]>",
"host": "smtp.example.com",
"port": 587,
"secure": false,
"service": "",
"auth": {
"user": "",
"pass": ""
}
},
// ── Sharing ─────────────────────────────────────────────────────────
// Email a recipient who already has an account about a new share. On
// unless set to false; they opt out via the unsubscribe link, or by
// blocking a sender. An invite to an address with no account always goes.
// "share_email_notifications": false,
//
// New shares one account may create per UTC day. Default 200.
// "share_daily_limit": 200,
//
// How often a share may interrupt its recipient — the notification pushed
// to their screen and the email with it. Over budget the share still
// succeeds and their notification is still brought up to date; only the
// interruption is dropped. The recipient bounds are what stop many senders
// burying one person between them. A non-positive value removes a bound.
// "share_notify_limits": {
// "pairWindowSeconds": 900,
// "pairDaily": 20,
// "recipientHourly": 10,
// "recipientDaily": 50,
// "emailBatchSeconds": 90
// },
// ── Teams / teams ──────────────────────────────────────────────
// Off by default, and off is the state every existing install stays in.
// The tables ship either way and sit inert; this gates whether `/teams`
// is registered at all, so with it off the paths do not exist rather than
// existing and refusing. It is also the backout: turning it off removes
// the feature without touching data.
"teams_enabled": false,
//
// Live teams one user may own. Soft-deleted ones do not count, so
// deleting yours frees the slot. Default 1.
"max_teams_per_user": 1,
//
// Seats one team may provision. Each seat is a real Puter account taking a
// name from the global username pool, so this is what bounds a team's blast
// radius. The owner's plan decides which of the two applies; defaults are 4
// and 40. Lowering either below a team's current seat count blocks new
// provisioning and disables nobody. Deployments upgrading from the old flat
// default of 50: without a billing extension every owner reads as free, so
// set `max_seats_per_team` to keep the old behavior.
"max_seats_per_team_free": 4,
"max_seats_per_team_paid": 40,
//
// One flat cap for every team, whatever the owner pays. Setting it
// overrides both of the above, so a deployment that does not sell seats can
// ignore plans entirely. Unset by default — leave it that way to keep the
// free cap meaningful.
// "max_seats_per_team": 50,
//
// Staged rollout: only these email domains may create a team, and the tab
// renders for them even with `gui_params.teams_ui` off. Members of an
// existing team always pass. Unset means everyone, gated by `teams_ui`.
// "teams_allowed_email_domains": ["puter.com"],
// ── Notifications ───────────────────────────────────────────────────
// How long a notification is kept, in days from creation. Acknowledged or
// not, a row past this is swept. Off by default; any value above 0 arms
// the sweep.
// "notificationRetentionDays": 14,
// ── Alarms / alerting ───────────────────────────────────────────────
// Where system alarms go. Severity is the routing decision — each
// transport takes everything at or above its own `minSeverity`:
//
// critical — an unhandled server error; pages on-call.
// error — pages as well; prefer critical or warning.
// warning — look at it today; no page.
// info — a record in the chat channel only.
//
// Both transports are off unless enabled, so a self-hosted node just
// logs its alarms to the console.
"pager": {
// Severity for call sites that don't pick one. Default "critical".
"defaultSeverity": "critical",
// Retier or silence an alarm without a deploy. Keys are alarm ids,
// or a prefix ending in `*`; the exact id wins over a pattern, and
// the longest matching pattern wins among patterns. Values are a
// severity or "mute". This is applied last, so it overrides both the
// call site and any known-error rule.
"severityOverrides": {
// "cronMonitor:*": "info",
// "http_500:GET:/some/flapping/route:*": "mute"
},
"pagerduty": {
"enabled": false,
"routingKey": "",
// Lowest severity that reaches PagerDuty. Default "warning",
// which keeps `info` out of the paging system entirely.
"minSeverity": "warning"
},
// Slack incoming webhook — the low-noise destination for everything
// that shouldn't page.
"slack": {
"enabled": false,
"webhookUrl": "",
// Optional; defaults to the channel the webhook was created for.
"channel": "#alerts",
"username": "puter-alarms",
// Severity window posted to Slack. The ceiling defaults to
// "info" when PagerDuty is configured — what pages belongs in
// the pager, not in chat — and to "critical" when Slack is the
// only transport.
"minSeverity": "info",
"maxSeverity": "info",
// Don't repost the same alarm id within this window. The first
// occurrence always posts; the next post that gets through
// reports how many occurrences piled up. 0 disables throttling.
"repeatThrottleMs": 900000
}
},
// ── Rate limiting ───────────────────────────────────────────────────
// `memory` for single-node, `redis` for multi-node (default), `kv` for
// dynamo-backed counters.
"rate_limit": {
"backend": "redis"
},
// ── AI / integration providers ──────────────────────────────────────
// All AI drivers (chat, image, video, TTS, OCR, STT) read from here.
// Provider id == driver-side identifier. Leave empty / omit to disable.
"providers": {
// ─ Chat / completion ─
"claude": { "apiKey": "" },
"openai-completion": { "apiKey": "" },
"azure-openai": {
"apiKey": "",
"apiURL": ""
},
"gemini": { "apiKey": "" },
// Meta Model API (Muse Spark). `muse-spark-1.2-contributor`
// trades a ~12x discount for Meta training on its prompts and
// completions, so it is only served to callers that name it.
"meta": { "apiKey": "" },
"groq": { "apiKey": "" },
"deepseek": { "apiKey": "" },
"mistral": { "apiKey": "" },
"xai": { "apiKey": "" },
"moonshot": { "apiKey": "" },
"minimax": {
"apiKey": "",
"apiBaseUrl": "https://api.minimax.io/v1"
},
"openrouter": {
"apiKey": "",
"apiBaseUrl": "https://openrouter.ai/api/v1"
},
"infron": {
"apiKey": "",
"apiBaseUrl": "https://llm.onerouter.pro/v1"
},
// BytePlus ModelArk. One key powers chat (Seed/GLM/DeepSeek), image
// generation (Seedream) and video generation (Seedance); `apiBaseUrl`
// selects the region; see
// https://docs.byteplus.com/en/docs/ModelArk/1330310 for options.
"byteplus": {
"apiKey": "",
"apiBaseUrl": "https://ark.ap-southeast.bytepluses.com/api/v3"
},
"zai": { "apiKey": "" },
"alibaba": { "apiKey": "" },
"hoonify": {
"apiKey": "",
"apiBaseUrl": "https://api.hoonify.ai/v1"
},
"together-ai": { "apiKey": "" },
// Local Ollama. `enabled: false` skips the auto-probe at startup
// (otherwise Puter logs ECONNREFUSED on every boot when no Ollama
// is running).
"ollama": {
"enabled": false,
"apiBaseUrl": "http://localhost:11434"
},
// ─ Image generation ─
"openai-image-generation": { "apiKey": "" },
"gemini-image-generation": { "apiKey": "" },
"together-image-generation": { "apiKey": "" },
"cloudflare-image-generation": {
"apiToken": "",
"accountId": "",
"apiBaseUrl": "https://api.cloudflare.com/client/v4"
},
"xai-image-generation": { "apiKey": "" },
// ─ Video generation ─
"together-video-generation": { "apiKey": "" },
"gemini-video-generation": { "apiKey": "" },
// ─ Speech / OCR ─
"openai": { "apiKey": "" },
"elevenlabs": {
"apiKey": "",
"apiBaseUrl": "https://api.elevenlabs.io",
"defaultVoiceId": "",
"speechToSpeechModelId": ""
},
"aws-polly": {
"access_key": "",
"secret_key": "",
"region": "us-west-2"
},
"speechify": { "apiKey": "" },
"aws-textract": {
"access_key": "",
"secret_key": "",
"region": "us-west-2"
},
"mistral-ocr": { "apiKey": "" }
},
// ── GUI / static mounts ─────────────────────────────────────────────
"gui_assets_root": "./src/gui",
"gui_profile": "development",
"builtin_apps": {
"dev-center": "./src/dev-center"
},
// Force the bundled GUI even in dev — set true when running from a
// pre-built tree without webpack-dev-server.
"use_bundled_gui": false,
"gui_bundle": "/dist/bundle.min.js",
"gui_css": "/dist/bundle.min.css",
"gui_puterjs_bundle": "https://js.puter.com/v2/",
"gui_params": {
"title": "Puter",
"short_description": "Your personal cloud computer",
"social_media_image": ""
},
// Optional roots for native app bundles and custom puter.js builds.
"native_apps_root": "",
"client_libs_root": "",
"puterjs_root": "./src/puter-js/dist",
// ── Feature flags (whoami extension) ────────────────────────────────
// Flat `{ flag_name: boolean }` bag. Server-only by default — flags are
// only surfaced to the client if their key is on the allowlist in
// `extensions/whoami.ts` (CLIENT_VISIBLE_FEATURE_FLAGS).
"feature_flags": {
"example_flag": false
},
// ── Misc / safety ───────────────────────────────────────────────────
// TLDs / domains rejected at signup (prod only).
"blockedEmailDomains": [],
"support_email": "[email protected]",
// Worker / subdomain names users can't claim.
"reserved_words": [],
"max_subdomains_per_user": 10,
"server_health": {
"db_liveness_latency_fail_ms": 1500,
"stale_health_loop_fail_ms": 0
},
// ── Extensions ──────────────────────────────────────────────────────
// Directories scanned for extension entrypoints (`*.ts` / subdirs).
"extensions": [
"./extensions"
],
// ── Metering ────────────────────────────────────────────────────────
// When true, every account resolves to an unlimited policy: usage is still
// recorded, but nothing is ever refused for lack of budget. This is the
// setting for a deployment with no way to buy more — without it, accounts
// are held to the free monthly allowance and start getting 402s from the AI
// surfaces, file transfers and KV once they pass it.
"unlimitedMetering": false,
// Whether an account that has spent its whole allowance is refused the
// operations that spend it — file transfers, KV calls. Recording is
// unaffected either way. `workers` extends the same refusal to
// worker-driven calls, which are exempt by default because a deployed
// worker has nowhere to surface a payment prompt. `subscriptions` covers
// the separate question of surfaces reserved for paid plans (the
// vendor-compatible AI endpoints): turn it off on a deployment with no
// paid plans, or every account is refused them.
// "meteringEnforcement": { "enabled": true, "workers": false, "subscriptions": true },
// Fleet-wide spend rate, in micro-cents per minute, past which metering
// raises the `metering:excessiveGlobalUsageRate` alarm. Omit it (the
// default) to leave the check off: the only useful value is a multiple of
// what this deployment's normal traffic costs, so it has to be measured
// rather than guessed, and a stale number here alarms on healthy growth.
// "maxGlobalUsagePerMinute": 200000000
}
+139
View File
@@ -0,0 +1,139 @@
# Alarms
`clients.alarm` is the one way code reports that something is wrong. It
de-dupes by alarm id, counts occurrences, and routes each alarm to alert
transports by **severity**.
```ts
this.clients.alarm.create(
`metering_write_failed:${userUuid}`, // de-dupe key
'Metering write failed', // what a human reads
{ userUuid, appId, error }, // context fields
'info', // severity
);
```
## Severity is the routing decision
| Severity | Meaning | Goes to |
| ---------- | ------------------------------------------------------ | ----------- |
| `critical` | An unhandled server error. Someone gets woken up. | Pager |
| `error` | Same urgency as critical; prefer one of the other two. | Pager |
| `warning` | Worth a look today. Nobody is paged. | Pager (low) |
| `info` | A record of something expected-but-notable. | Chat |
Each transport declares the severity window it accepts, so the value a call
site passes is what decides where the alarm lands. The two windows don't
overlap by default: anything that pages lives in the paging system, and chat
is the record of what didn't. The bar for `critical` is
deliberately high: an unhandled 5xx out of the HTTP error handler is the main
thing that still pages. Anything a human can look at tomorrow is `warning`,
and anything that's just worth recording is `info`.
Omitting the severity takes `pager.defaultSeverity` (itself `critical`), so
pass one explicitly unless you really mean "page someone".
### Choosing one
- Did the server fail to do its job in a way nobody expected? → `critical`
- Is a background job, rate, or dependency degraded? → `warning`
- Is this a user doing something notable (tripping an abuse heuristic,
overspending)? → `info`
- Did one of *our own* limits reject a caller — a rate limit, a concurrency
cap, a quota? → don't alarm at all. The limit doing its job is not an
event; the 429 is the whole signal, and alarming on it only produces noise
proportional to traffic. An *upstream provider* rate-limiting us is the
opposite case and still alarms (`upstream_rate_limited`, `info`) — that one
is not something we chose. The exception is a free model: nothing is billed,
nothing is actionable, and the throttling is the price of the model, so the
AI chat driver marks those `noAlarm` and only paid models still record.
`noAlarm` is the code-level mute: an `HttpError` carrying it skips the
terminal gate entirely, no matter its status or code. It is for failures the
call site *already knows* are expected and traffic-proportional — reach for it
there, not as a way to quiet an alarm you haven't diagnosed
(`severityOverrides` below is the knob for that).
An extension whose signals are all one tier can default its own local
`raiseAlarm` helper to that tier instead of repeating it at every call site —
see [extensions/cronMonitor](../../../extensions/cronMonitor/index.js).
## One incident per occurrence, unless you say otherwise
Alarms always de-dupe *in process* — repeats of an id bump its occurrence
count rather than creating a second alarm. What that means for the pager is a
separate decision, and by default every occurrence opens its own PagerDuty
incident: two failed scans an hour apart are two things that happened, and
closing one shouldn't hide the other.
Pass `{ dedup: true }` as a fifth argument when repeats of the id really are
one recurring fault, and they collapse onto a single incident carrying the
occurrence count:
```ts
this.clients.alarm.create(alarmId, message, fields, 'critical', {
dedup: true,
});
```
The HTTP error handler uses it: its id is route + error signature, so a hot
loop of the same crash is one incident with N occurrences instead of N pages.
Dedup and Slack's repeat throttle mean a responder sees only the latest
occurrence, so the handler attaches the `HttpError`'s `fields` to the alarm as
`details` — put what a responder needs (which upstreams failed, and how)
there. Everything in `fields` is also returned to the client in the response
body, so it has to be safe to show the caller.
Reach for it anywhere else only when the id is that specific — otherwise a
per-request alarm can flood the pager.
## Configuration
Everything lives under `pager` in config (see
[config.template.jsonc](../config.template.jsonc) for the annotated version).
Both transports are off unless enabled, so a self-hosted node just logs
alarms to the console.
```jsonc
"pager": {
"defaultSeverity": "critical",
"severityOverrides": { "cronMonitor:*": "info" },
"pagerduty": { "enabled": true, "routingKey": "…", "minSeverity": "warning" },
"slack": {
"enabled": true,
"webhookUrl": "…",
"channel": "#alerts",
"minSeverity": "info",
"maxSeverity": "info",
"repeatThrottleMs": 900000,
},
}
```
Slack's `maxSeverity` defaults to `info` whenever PagerDuty is configured, and
to `critical` when it isn't — a node with only a webhook still sees
everything. Raise it to have chat mirror the paging tiers as well.
### Retiering without a deploy
`severityOverrides` is the escape hatch for an alarm that turns out to be
noisier or more serious than its call site assumed. Keys are alarm ids or a
prefix ending in `*`; the exact id beats a pattern, and the longest matching
prefix wins among patterns. Values are a severity, or `mute` to drop the
alarm before any transport sees it.
It is applied *after* the call site's severity and any known-error rule, so
config always has the last word.
### Repeat throttling
Two levels, and they stack.
The client itself backs off before a repeat is reported at all: every
occurrence is reported up to a small burst, then one per interval. A fault
recurring hundreds of times a second still counts every occurrence, but it
does not write a log line or build an alert payload for each one.
Below that, the chat transport won't repost the same alarm id within
`repeatThrottleMs` (default 15 minutes). The first occurrence always posts,
and the next one that gets through reports how many piled up in between —
so a hot loop reads as one message with a count, not a wall of them.
-5
View File
@@ -1,5 +0,0 @@
# API Documentation
Note that this documentation is different from the [puter.js docs](https://docs.puter.com).
The scope of the documentation in this directory includes both stable API endpoints that
are used by **puter.js**, as well as API endpoints that may be subject to future changes.
-9
View File
@@ -1,9 +0,0 @@
# Share Links
A **share link** is a link to Puter's origin which contains a token
in the query string (the key is `share_token`; ex:
`http://puter.localhost:4100?share_token=...`).
This token can be used to apply permissions to the user of the
current session **if and only if** this user's email is confirmed
and matches the share link's associated email.
-219
View File
@@ -1,219 +0,0 @@
# Group Endpoints
## POST `/group/create` (auth required)
### Description
Creates a group and returns a UID (UUID formatted).
Groups do not have names, or any other descriptive attributes.
Instead they are always identified with a UUID, and they have
a `metadata` property.
The `metadata` property will always be given back to the client
in the same way it was provided. The `extra` property, also an
object, may be changed by the backend. The behavior of setting
any property on `extra` is currently undefined as all properties
are reserved for future use.
### Parameters
- **metadata:** _- optional_
- **accepts:** `object`
- **description:** arbitrary metadata to describe the group
- **extra:** _- optional_
- **accepts:** `object`
- **description:** extra parameters (server may change these)
### Request Example
```javascript
await fetch(`${window.api_origin}/group/create`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
metadata: { title: 'Some Title' }
}),
"method": "POST",
});
// { uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6' }
```
### Response Example
```json
{
"uid": "9c644a1c-3e43-4df4-ab67-de5b68b235b6"
}
```
## POST `/group/add-users`
### Description
Adds one or more users to a group
### Parameters
- **uid:** _- required_
- **accepts:** `string`
UUID of an existing group
- **users:** `Array<string>`
usernames of users to add to the group
### Request Example
```javascript
await fetch(`${window.api_origin}/group/add-users`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6',
users: ['first_user', 'second_user'],
}),
"method": "POST",
});
```
## POST `/group/remove-users`
### Description
Remove one or more users from a group
### Parameters
- **uid:** _- required_
- **accepts:** `string`
UUID of an existing group
- **users:** `Array<string>`
usernames of users to remove from the group
### Request Example
```javascript
await fetch(`${window.api_origin}/group/add-users`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6',
users: ['first_user', 'second_user'],
}),
"method": "POST",
});
```
## GET `/group/list`
### Description
List groups associated with the current user
### Parameters
_none_
### Response Example
```json
{
"owned_groups": [
{
"uid": "c3bd4047-fc65-4da8-9363-e52195890de4",
"metadata": {},
"members": [
"default_user"
]
}
],
"in_groups": [
{
"uid": "c3bd4047-fc65-4da8-9363-e52195890de4",
"metadata": {},
"members": [
"default_user"
]
}
]
}
```
# Group Permission Endpoints
## POST `/grant-user-group`
Grant permission from the current user to a group.
This creates an association between the user and the
group for this permission; the group will only have
the permission effectively while the user who granted
permission has the permission.
### Parameters
- **group_uid:** _- required_
- **accepts:** `string`
UUID of an existing group
- **permission:** _- required_
- **accepts:** `string`
A permission string
### Request Example
```javascript
await fetch("http://puter.localhost:4100/auth/grant-user-group", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
group_uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6',
permission: 'fs:/someuser/somedir/somefile:read'
}),
"method": "POST",
});
```
## POST `/revoke-user-group`
Revoke permission granted from the current user
to a group.
### Parameters
- **group_uid:** _- required_
- **accepts:** `string`
UUID of an existing group
- **permission:** _- required_
- **accepts:** `string`
A permission string
### Request Example
```javascript
await fetch("http://puter.localhost:4100/auth/grant-user-group", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
group_uid: '9c644a1c-3e43-4df4-ab67-de5b68b235b6',
permission: 'fs:/someuser/somedir/somefile:read'
}),
"method": "POST",
});
```
- > **TODO** figure out how to manage documentation that could
reasonably show up in two files. For example: this is a group
endpoint as well as a permission system endpoint.
(architecturally it's a permission system endpoint, and
the permissions feature depends on the groups feature;
at least until a time when PermissionService is refactored
so a service like GroupService can mutate the permission
check sequences)
-112
View File
@@ -1,112 +0,0 @@
# Notification Endpoints
Endpoints for managing notifications.
## POST `/notif/mark-ack` (auth required)
### Description
The `/notif/mark-ack` endpoint marks the specified notification
as "acknowledged". This indicates that the user has chosen to either
dismiss or act on this notification.
### Parameters
| Name | Description | Default Value |
| ---- | ----------- | -------- |
| uid | UUID associated with the notification | **required** |
### Response
This endpoint responds with an empty object (`{}`).
## POST `/notif/mark-read` (auth required)
### Description
The `/notif/mark-read` endpoint marks that the specified notification
has been shown to the user. It will not "pop up" as a new notification
if they load the gui again.
### Parameters
| Name | Description | Default Value |
| ---- | ----------- | -------- |
| uid | UUID associated with the notification | **required** |
### Response
This endpoint responds with an empty object (`{}`).
### Request Example
```javascript
await fetch("https://api.puter.local/notif/mark-read", {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
body: JSON.stringify({
uid: 'a14ea3d5-828b-42f9-9613-35f43b0a3cb8',
}),
method: "POST",
});
```
## ENTITY STORAGE `puter-notifications`
The `puter-notifications` driver is an Entity Storage driver.
It is read-only.
### Request Examples
#### Select Unread Notifications
```javascript
await fetch("http://api.puter.localhost:4100/drivers/call", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
interface: 'puter-notifications',
method: 'select',
args: { predicate: ['unread'] }
}),
"method": "POST",
});
```
#### Select First 200 Notifications
```javascript
await fetch("http://api.puter.localhost:4100/drivers/call", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
interface: 'puter-notifications',
method: 'select',
args: {}
}),
"method": "POST",
});
```
#### Select Next 200 Notifications
```javascript
await fetch("http://api.puter.localhost:4100/drivers/call", {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
interface: 'puter-notifications',
method: 'select',
args: { offset: 200 }
}),
"method": "POST",
});
```
-367
View File
@@ -1,367 +0,0 @@
# Share Endpoints
Share endpoints allow sharing files with other users.
## POST `/share` (auth required)
### Description
The `/share` endpoint shares 1 or more filesystem items
with one or more recipients. The recipients will receive
some notification about the shared item, making this
different from calling `/grant-user-user` with a permission.
When users are **specified by email** they will receive
a [share link](./concepts/share-link.md).
Each item specified in the `shares` property is a tag-typed
object of type `fs-share` or `app-share`.
#### File Shares (`fs-share`)
File shares grant permission to a file or directory. By default
this is read permission. If `access` is specified as `"write"`,
then write permission will be granted.
#### App Shares (`app-share`)
App shares grant permission to read a protected app.
##### subdomain permission
If there is a subdomain associated with the app, and the owner
of the subdomain is the same as the owner of the app, then
permission to access the subdomain will be granted.
Note that the subdomain is only associated if the subdomain
entry has `associated_app_id` set according to the app's id,
and will not be considered "associated" if only the index_url
happens to match the subdomain url.
##### appdata permission
If the app has `shared_appdata` set to `true` in its metadata
object, the recipient of the share will also get write permission
to the app owner's corresponding appdata directory. The appdata
directory must exist for this to work as expected
(otherwise the permission rewrite rule fails since the uuid
can't be determined).
### Example
```json
{
"recipients": [
"user_that_gets_shared_to",
"[email protected]"
],
"shares": [
{
"$": "app-share",
"name": "some-app-name"
},
{
"$": "app-share",
"uid": "app-SOME-APP-UID"
},
{
"$": "fs-share",
"path": "/some/file/or/directory"
},
{
"$": "fs-share",
"path": "SOME-FILE-UUID"
}
]
}
```
### Parameters
- **recipients** _- required_
- **accepts:** `string | Array<string>`
- **description:**
recipients for the filesystem entries being shared.
- **notes:**
- validation on `string`: email or username
- requirement of at least one value
- **shares:** _- required_
- **accepts:** `object | Array<object>`
- object is [type-tagged](./type-tagged.md)
- type is either [file-share](./types/file-share.md)
or [app-share](./types/app-share.md)
- **notes:**
- requirement that file/directory or app exists
- requirement of at least one entry
- **dry_run:** _- optional_
- **accepts:** `bool`
- **description:**
when true, only validation will occur
### Response
- **$:** `api:share`
- **$version:** `v0.0.0`
- **status:** one of: `"success"`, `"mixed"`, `"aborted"`
- **recipients:** array of: `api:status-report` or
`heyputer:api/APIError`
- **paths:** array of: `api:status-report` or
`heyputer:api/APIError`
- **dry_run:** `true` if present
### Request Example
```javascript
await fetch("http://puter.localhost:4100/share", {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
body: JSON.stringify({
recipients: [
"user_that_gets_shared_to",
"[email protected]"
],
shares: [
{
$: "app-share",
name: "some-app-name"
},
{
$: "app-share",
uid: "app-SOME-APP-UID"
},
{
$: "fs-share",
path: "/some/file/or/directory"
},
{
$: "fs-share",
path: "SOME-FILE-UUID"
}
]
}),
method: "POST",
});
```
### Success Response
```json
{
"$": "api:share",
"$version": "v0.0.0",
"status": "success",
"recipients": [
{
"$": "api:status-report",
"status": "success"
}
],
"paths": [
{
"$": "api:status-report",
"status": "success"
}
],
"dry_run": true
}
```
### Error response (missing file)
```json
{
"$": "api:share",
"$version": "v0.0.0",
"status": "mixed",
"recipients": [
{
"$": "api:status-report",
"status": "success"
}
],
"paths": [
{
"$": "heyputer:api/APIError",
"code": "subject_does_not_exist",
"message": "File or directory not found.",
"status": 404
}
],
"dry_run": true
}
```
### Error response (missing user)
```json
{
"$": "api:share",
"$version": "v0.0.0",
"status": "mixed",
"recipients": [
{
"$": "heyputer:api/APIError",
"code": "user_does_not_exist",
"message": "The user `non_existing_user` does not exist.",
"username": "non_existing_user",
"status": 422
}
],
"paths": [
{
"$": "api:status-report",
"status": "success"
}
],
"dry_run": true
}
```
## POST `/sharelink/check` (no auth)
### Description
The `/sharelink/check` endpoint verifies that a token provided
by a share link is valid.
### Example
```javascript
await fetch(`${config.api_origin}/sharelink/check`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
token: '...',
}),
"method": "POST",
});
```
### Parameters
- **token:** _- required_
- **accepts:** `string`
The token from the querystring parameter
### Response
A type-tagged object, either of type `api:share` or `api:error`
### Success Response
```json
{
"$": "api:share",
"uid": "836671d4-ac5d-4bd3-bc0a-ec357e0d8f02",
"email": "[email protected]"
}
```
### Error Response
```json
{
"$": "api:error",
"message":"Field `token` is required.",
"key":"token",
"code":"field_missing"
}
```
## POST `/sharelink/apply` (no auth)
### Description
The `/sharelink/apply` endpoint applies a share to the current
user **if and only if** that user's email is confirmed and matches
the email associated with the share.
### Example
```javascript
await fetch(`${config.api_origin}/sharelink/apply`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
uid: '836671d4-ac5d-4bd3-bc0a-ec357e0d8f02',
}),
"method": "POST",
});
```
### Parameters
- **uid:** _- required_
- **accepts:** `string`
The uid of an existing share, received using `/sharelink/check`
### Response
A type-tagged object, either of type `api:status-report` or `api:error`
### Success Response
```json
{"$":"api:status-report","status":"success"}
```
### Error Response
```json
{
"message": "This share can not be applied to this user.",
"code": "can_not_apply_to_this_user"
}
```
## POST `/sharelink/request` (no auth)
### Description
The `/sharelink/request` endpoint requests the permissions associated
with a share link to the issuer of the share (user that sent the share).
This can be used when a user is logged in, but that user's email does
not match the email associated with the share.
### Example
```javascript
await fetch(`${config.api_origin}/sharelink/request`, {
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${puter.authToken}`,
},
"body": JSON.stringify({
uid: '836671d4-ac5d-4bd3-bc0a-ec357e0d8f02',
}),
"method": "POST",
});
```
### Parameters
- **uid:** _- required_
- **accepts:** `string`
The uid of an existing share, received using `/sharelink/check`
### Response
A type-tagged object, either of type `api:status-report` or `api:error`
### Success Response
```json
{"$":"api:status-report","status":"success"}
```
### Error Response
```json
{
"message": "This share is already valid for this user; POST to /apply for access",
"code": "no_need_to_request"
}
```
-79
View File
@@ -1,79 +0,0 @@
# Type-Tagged Objects
```js
{
"$": "some-type",
"$version": "0.0.0",
"some_property": "some value",
}
```
## What's a Type-Tagged Object?
Type-Tagged objects are a convention understood by Puter's backend
to communicate meta information along with a JSON object.
The key feature of Type-Tagged Objects is the type key: `"$"`.
## Why Type-Tagged Objects?
The primary reason: to have a consistent convention we can use
anywhere.
- Since other services rarely use `$` in their property names,
we can safely use this without introducing reserved words and
re-mapping property names.
- Some places we use this convention might not need it, but
staying consistent means API end-users can
[do more with less code](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself).
## Specification
- The `"$"` key indicates a type (or class) of object
- Any other key beginning with `$` is a **meta-key**
- Other keys are not allowed to contain `$`
- `"$version"` must follow [semver](https://semver.org/)
- Keys with multiple `"$"` symbols are reserved for future use
## Alternative Representations
Puter's API will always send results in the format described
above, which is called the "Standard Representation"
Any endpoint which accepts a Type-Tagged Object will also
accept these alternative representations:
### Structured Representation
Depending on the architecture of your client, this format
may be more convenient to work with:
```json
{
"$": "$meta-body",
"type": "some-type",
"meta": { "version": "0.0.0" },
"body": { "some_property": "some value" }
}
```
### Array Representation
In the array representation, meta values go at the end.
```json
["some-type",
{ "some_property": "some value" },
{ "version": "0.0.0" }
]
```
If the second element of the list is not an object, it
will implicitly be placed in a property called value.
The following are equivalent:
```json
["some-type", "hello"]
```
```json
["some-type", { "value": "hello" }]
```
-26
View File
@@ -1,26 +0,0 @@
# `{"$": "app-share"}` - File Share
## Structure
- **name:** name of the app
- **uid:** name of the app
## Notes
- One of `name` or `uid` **must** be specified
## Examples
Share app by name
```json
{
"$": "app-share",
"name": "some-app-name"
}
```
Share app by uid
```json
{
"$": "app-share",
"uid": "app-0a7337f7-0f8a-49ca-b71a-38d39304fe04"
}
```
-32
View File
@@ -1,32 +0,0 @@
# `{"$": "file-share"}` - File Share
## Structure
- **path:** file or directory's path or uuid
- **access:** one of: `"read"`, `"write"` (default: `"read"`)
## Examples
Share with read access
```json
{
"$": "file-share",
"path": "/some/path"
}
```
Share with write access
```json
{
"$": "file-share",
"path": "/some/path",
"access": "write"
}
```
Using a UUID
```json
{
"$": "file-share",
"path": "b912c381-0c0b-466c-95a6-f9a4fc680a7d"
}
```
+126
View File
@@ -0,0 +1,126 @@
# Backend Architecture
Loosely inspired by the Controller–Service–Repository pattern with dependency injection. The backend is organized as a stack of layers where each layer only depends on the layers beneath it, and `PuterServer` ([src/backend/server.ts](../src/backend/server.ts)) instantiates each layer in order and hands the instances down to the next.
## Layers
```mermaid
block-beta
columns 1
REQ["HTTP request"]
CTRL["Controllers — route handlers, gates, I/O shaping"]
DRV["Drivers (optional) — RPC handlers on /drivers/*"]
SVC["Services — business logic, no auth"]
STR["Stores — persistence / domain shapes"]
CLI["Clients — sql, redis, s3, dynamo, email, …"]
CFG["Config — IConfig"]
REQ --> CTRL
CTRL --> DRV
DRV --> SVC
SVC --> STR
STR --> CLI
CLI --> CFG
style REQ fill:#0ea5e9,stroke:#0369a1,color:#fff
style CTRL fill:#1d4ed8,stroke:#1e3a8a,color:#fff
style DRV fill:#2563eb,stroke:#1e40af,color:#fff
style SVC fill:#4f46e5,stroke:#3730a3,color:#fff
style STR fill:#7c3aed,stroke:#5b21b6,color:#fff
style CLI fill:#9333ea,stroke:#6b21a8,color:#fff
style CFG fill:#334155,stroke:#1e293b,color:#fff
```
Each layer only depends on the layers beneath it, and every dependency is injected through the constructor by `PuterServer`. Extensions sit alongside this stack and can register into any layer — see [Extensions](#extensions) below.
| Layer | Lives in | Responsibility |
| --- | --- | --- |
| **Controllers** | [src/backend/controllers/](../src/backend/controllers/) | Route handlers. Parse + validate input, apply per-route gates (auth, subdomain, rate limit, body parsers — see `RouteOptions`), call into services, format responses. |
| **Drivers** | [src/backend/drivers/](../src/backend/drivers/) | Optional. RPC-style handlers exposed over the `/drivers/*` surface (`puter-kvstore`, `puter-chat-completion`, …). A driver is a thin shell that validates RPC inputs and calls into services/stores; controllers can hold a typed reference to drivers when they need the same logic over HTTP. |
| **Services** | [src/backend/services/](../src/backend/services/) | Business logic. Assume the caller is already authenticated/authorized — services do not run auth gates themselves. |
| **Stores** | [src/backend/stores/](../src/backend/stores/) | Persistence and storage logic. Wraps clients with the domain shape services consume (rows, entities, KV namespaces). |
| **Clients** | [src/backend/clients/](../src/backend/clients/) | Adapters for external/internal services (sql, redis, s3, dynamodb, email, event bus, …). Knows protocols, not domain concepts. |
| **Config** | `config.*.json` → `IConfig` | The flat, typed config object every layer receives at construction. |
Each layer receives the layers beneath it through its constructor, so dependencies are explicit and traceable from `PuterServer`. A controller does not reach into a client directly; if it needs one, the right move is usually a service.
## Entry point: `PuterServer`
`PuterServer` is the bootstrap. It:
1. Loads any configured extension directories (`config.extensions`) so extensions can register before instantiation begins.
2. Instantiates each layer in order — clients → stores → services → drivers → controllers — merging in anything extensions have registered for that layer.
3. Wires global middleware, mounts controller routes through `PuterRouter` (which translates `RouteOptions` into the gate/parser middleware chain), and mounts extension routes through the same materializer.
4. Fires `onServerStart` hooks across every layer once HTTP is listening, and `onServerPrepareShutdown` / `onServerShutdown` on the way down.
## Context (ALS)
We use [`Context`](../src/backend/core/context.ts) — backed by `AsyncLocalStorage` — to carry per-request state without threading it through every function signature. It is used **sparingly**, mostly for `actor` and `req`. The request-context middleware opens a scope per request after the auth probe runs; anything inside a request handler can call `Context.get('actor')` / `Context.get('req')` instead of plumbing it as an argument.
Prefer explicit arguments. Reach for `Context` only when the value is truly request-scoped and would otherwise need to thread through many layers.
## Actors
An [`Actor`](../src/backend/core/actor.ts) is who a request is acting as. It has two app-shaped fields and they are not interchangeable: `app` is the app the actor carries *directly* (an app-under-user token), while `effectiveApp` is the app it ultimately acts as — its own, or the one that issued its access token. An access-token actor has no `app` of its own, so a gate that reads `app` answers "no app" for it and falls open.
`makeActor` resolves `effectiveApp` once at construction, and `assertResolvedActor` at the request edge rejects any actor that skipped it — so reading `effectiveApp` needs no fallback. Reach for `app` only where the direct app genuinely is the question, and say why in a comment.
- `actor.effectiveApp` — which app is acting. This is the default; nearly every scoping rule, namespace key and attribution wants it.
- `isAppActor(actor)` — a direct app actor specifically. Use it where a token must *not* be treated as its issuer, e.g. the permission scanners that read an app's own grant rows.
- `isPlainUserActor(actor)` — the account acting through nothing at all; `isAccountContext(actor)` for the wider "the account's own reach", which also admits a full-access token.
## Extensions
Extensions live alongside core ([packages/puter/extensions/](../extensions/)) and parallel the layered stack. They are meant for **non-crucial parts of the system** — things Puter still works without if removed.
- **Good extensions**: [thumbnails](../extensions/thumbnails.ts), [serverInfo](../extensions/serverInfo.ts), [devWatcher](../extensions/devWatcher.ts) — opt-in features cleanly bolted on.
- **Should probably be core**: [metering](../extensions/metering.ts), [appTelemetry](../extensions/appTelemetry.ts) — clients now expect these to be present, so the "extension" framing is misleading.
- **Shouldn't have been an extension**: [whoami](../extensions/whoami.ts) — it's load-bearing for every authenticated client. Keep this one in mind as a cautionary example when deciding whether something belongs in an extension.
### Extension API
The `extension` global ([src/backend/extensions.ts](../src/backend/extensions.ts)) exposes:
- **Layer registration** for first-class additions:
- `extension.registerClient(name, ClientClass)`
- `extension.registerStore(name, StoreClass)`
- `extension.registerService(name, ServiceClass)`
- `extension.registerDriver(name, DriverClass)`
- `extension.registerController(name, ControllerClass)`
- **Lightweight wrappers** for the common case where a full class isn't worth it:
- `extension.on(event, handler)` — subscribe to event-bus events.
- `extension.get(path, opts?, handler)` / `.post` / `.put` / `.delete` / `.patch` / `.head` / `.options` / `.all` / `.use` — register routes. The `opts` shape is the same `RouteOptions` controllers use, so `subdomain`, `requireAuth`, `adminOnly`, body parsers, etc. all work identically.
- **Cross-layer access**: `extension.import('client' | 'store' | 'service' | 'controller' | 'driver')` returns a lazy proxy to instantiated objects, and `extension.config` exposes the live config.
```ts
import { extension } from '@heyputer/backend/src/extensions';
const services = extension.import('service');
extension.get('/healthcheck/deep', { subdomain: 'api', adminOnly: true }, async (_req, res) => {
res.json({ ok: await services.health.runDeepCheck() });
});
extension.on('user.signup', (_key, data) => {
console.log('new user', data.user.username);
});
```
The `app.recommended` event lets extensions customize desktop recommendations.
Its `appNames` array starts as a fresh copy of the default ordered names on each
call. Listeners may mutate or replace it, including setting it to an empty array.
Async listeners are awaited before names are resolved to app summaries; names
that do not exist are skipped.
```ts
extension.on('app.recommended', (_key, data) => {
data.appNames = ['editor', 'camera'];
});
```
## Conventions
- **TypeScript preferred** in new code where feasible. Existing JS is fine; convert opportunistically when you're already touching a file.
- **`camelCase`** for variable/function names; **`PascalCase`** for classes and for files that contain a class (`AuthService.ts`, `KVStoreDriver.ts`).
- **Deduplicate**. If two services need the same logic, lift it into a util/helper rather than calling sideways across the same layer — services should not depend on other services for code reuse.
- **Don't reach across layers.** Controllers do not poke clients directly; services do not register routes. If you find yourself wanting to, that's usually a signal the abstraction is wrong.
+115
View File
@@ -0,0 +1,115 @@
# Contributing APIs
How to add a new public API to Puter, and how to maintain one that already exists. "Public API" means anything applications can call: HTTP endpoints, `/drivers/*` methods, and the puter.js methods that wrap them. This guide is written for human contributors and AI agents alike — [AGENTS.md](../AGENTS.md) defers to it for API work.
Companion docs: [architecture.md](architecture.md) (backend layering), [pagination.md](pagination.md) (list APIs), [src/puter-js/tests/api/README.md](../src/puter-js/tests/api/README.md) (SDK test environment).
## Rule zero: don't break callers
puter.js is served live from `https://js.puter.com/v2/` with no version pinning — every app in existence picks up your change the moment it deploys, and the backend endpoints underneath have the same property. Assume every observable behavior (parameter handling, response fields, error codes, ordering) has someone depending on it.
Every change is backward compatible unless a maintainer has explicitly agreed to a break beforehand.
## Core or extension?
The first decision is where the API lives.
If the API is **not crucial to core functionality — nothing in core will call it — prefer an extension** over wiring it into core. Extensions live in [extensions/](../extensions/), parallel the core layered stack, and reach core through `extension.import(...)`:
```js
const services = extension.import('service');
const stores = extension.import('store');
extension.registerDriver('myFeature', MyFeatureDriver); // first-class driver
extension.post('/my-feature/frobnicate', opts, handler); // or plain routes
```
Follow the same layered structure inside the extension (driver/controller → service → store) unless it genuinely only needs a couple of route handlers — then the lightweight `extension.get/post/...` helpers are enough on their own.
The test is the direction of dependency: Puter must still work with the extension removed. The moment core needs to call your API, it belongs in core — see [whoami](../extensions/whoami.ts) for the cautionary example of a load-bearing "extension".
## Adding a new API
Work through all seven steps; the PR is complete when every one is.
### 1. Design the surface first
- Sketch the signature, options, return shape, and error cases before writing code. Find the two or three most similar existing APIs and match their conventions.
- New parameter and field names are `camelCase`. (Existing `snake_case` names stay where they already exist.)
- Anything returning a list follows the [pagination convention](pagination.md): `limit`/`cursor` in, `{ items, cursor, total }` envelope out.
- Prefer an options object over a growing list of positional parameters, but keep the common case callable with a single argument where siblings do.
### 2. Backend
Follow the layered stack ([architecture.md](architecture.md)): a controller or driver at the edge, business logic in a service, persistence in a store. The edge parses and validates input and applies gates; services assume the caller is already authorized. Return exactly what the caller needs and no more — every response field you ship is permanent — and use stable `snake_case` error codes.
#### Controller or driver?
Both are supported ways to define an API. **Prefer a controller when you need fine-grained control** — URL shape, HTTP verbs, per-route gates, response and streaming formats. A **driver** fits when the API is a set of RPC methods implementing one of the named interfaces on `/drivers/*` (`puter-kvstore`, `puter-chat-completion`, …) and the generic driver plumbing — one call envelope, interchangeable implementations, per-method policies — covers what you need.
- **Controller:** extend `PuterController` ([src/backend/controllers/types.ts](../src/backend/controllers/types.ts)) and declare routes with the `@Controller(prefix)` class decorator plus `@Get`/`@Post`/… method decorators ([src/backend/core/http/decorators.ts](../src/backend/core/http/decorators.ts)), each taking `(path, routeOptions)` — or override `registerRoutes(router)` imperatively. Core controllers register in [src/backend/controllers/index.ts](../src/backend/controllers/index.ts); extensions use `extension.registerController(...)` or the plain route helpers.
- **Driver:** extend `PuterDriver` ([src/backend/drivers/types.ts](../src/backend/drivers/types.ts)) and mark it with the `@Driver(interfaceName, opts)` decorator ([src/backend/drivers/decorators.ts](../src/backend/drivers/decorators.ts)), which also declares its policies. Core drivers register in [src/backend/drivers/index.ts](../src/backend/drivers/index.ts); extensions use `extension.registerDriver(...)`.
#### Middleware and gates
- **Controller routes** (and extension routes — same options) take [`RouteOptions`](../src/backend/core/http/types.ts): auth gates (`requireAuth`, `requireUserActor`, `noUserSession`, `adminOnly`, `allowedAppIds`, and the access-token controls), `subdomain` routing, per-route `rateLimit`, body parsers, and arbitrary extra `middleware`. The auth flavors are subtle and default-deny — read the JSDoc on each field before picking.
- **Driver methods** get their policies from the `@Driver` options: per-method `rateLimit` (limit/window/backend), `concurrent` in-flight caps (optionally `bySubscription`), `requireSubscription`, `requireReputation`, and `noUserSession`. The `/drivers/call` surface enforces them.
- **A surface only paying accounts should reach** declares `requireSubscription` — the route option on a controller endpoint, the per-method `@Driver({ requireSubscription })` block on a driver (`/drivers/call` is one shared route, so a driver's requirement can't live in route options). `true` accepts any plan that isn't free, so a plan registered by an extension counts without core naming it; an array of policy ids (`['business', 'pro']`) accepts only those; `false` is "no requirement", the same as leaving it out. An empty array is a boot error rather than a silent no-op — it reads as subscribers-only while admitting everyone. Off unless asked for, and answered from the metering service's cached per-actor subscription, so it costs a map lookup. Distinct from `requireCredits`: this asks which plan the account is on, not whether it has budget left. Deployments with no paid plans (self-hosted installs) turn the whole thing off with `meteringEnforcement.subscriptions: false`.
- **A surface only a trusted-enough account should reach** declares `requireReputation` — the route option on a controller endpoint, the per-method `@Driver({ requireReputation })` block on a driver. The value names a tier; what that tier takes is `reputationGate.tiers` in config, so the score a surface is worth is a deployment call and can be retuned without editing the surface. A tier the running config doesn't define is inert and everyone passes — an install that doesn't score its accounts must not start turning traffic away on a score it never computed — and `reputationGate.enabled: false` stops every declared gate at once. Opt-in, implies `requireAuth`, and denies with a bare 403 `reputation_required` that names neither the score nor the tier. Nothing in the tree declares one yet: the mechanism ships ahead of the enrollment.
- **An account must have verified a specific factor** — `requireVerified` (email, and only under `strict_email_verification_required`), `requirePhoneVerified`, `requireCardVerified`. These are opt-in and require the factor to have actually been verified, unlike the default-on gate that turns away accounts still carrying a pending verification the abuse harness asked for. `requireAnyVerified: ['phone', 'card']` is the OR of the last two: any listed factor verified at any point passes, as does a paid plan where `card` is listed (a paying account has a card on file already); otherwise only the factors the deployment can verify are asked for (an SMS provider configured, a card gate an extension reports on), and with none verifiable the gate is inert rather than locking the route on a self-hosted install. It denies with the first verifiable factor's code plus `factors`, the verifiable ones in the route's order, so a client can lead with one flow and offer the other. `verifiedFactorGate.enabled: false` in config stops every declared gate at once, for an SMS-provider outage.
- **An endpoint that spends metered resources** on the caller's behalf — moving file content, making object-store requests, anything else the account is billed for — also declares `requireCredits: true`, which turns an account with nothing left of its budget away with a 402 before the handler runs. Endpoints that only describe or delete things deliberately don't: an account that has run out still has to be able to see what it has, clear it, and reach its billing pages. Drivers have no route options to declare this on, so they call `assertActorHasCredits` themselves ([src/backend/services/metering/enforcement.ts](../src/backend/services/metering/enforcement.ts)) — see `KVStoreDriver`, which does it once for every method.
### 3. puter.js
- Add the method to the matching module in [src/puter-js/src/modules/](../src/puter-js/src/modules/), matching the calling conventions of its siblings (promise-returning; positional shortcut plus options form where that's the local pattern).
- Validate cheap preconditions client-side and throw `{ message, code }` objects; pass backend errors through unchanged rather than swallowing or re-wrapping them.
### 4. Types
- Type the method where you wrote it, in JSDoc: `@param`/`@returns` on the implementation, one `@overload` block per accepted call form, and `@typedef {Object}` + `@property` for any new shape. The JSDoc is the source of truth — declarations are generated from it, so there is nothing to keep in sync by hand.
- Put a shape more than one file needs in the module's `types.js` (e.g. [src/puter-js/src/modules/kv/types.js](../src/puter-js/src/modules/kv/types.js)); anything shared across modules goes in [src/puter-js/src/lib/types.js](../src/puter-js/src/lib/types.js). A shape with one consumer can stay next to it.
- Run `npm run check:puterjs:types` — it generates the declarations and type-checks the published surface without `skipLibCheck`. **Never edit anything under `src/puter-js/types/`**: it is gitignored build output, produced by the SDK build and shipped in the npm tarball, and the next build overwrites it.
- Name the new type in [src/puter-js/index.d.ts](../src/puter-js/index.d.ts) if consumers should be able to import it. That file is the one hand-written declaration in the package: it decides what is public and re-exports nothing else.
### 5. Docs
- Add the method page at [src/docs/src/](../src/docs/src/)`<Area>/<method>.md` — frontmatter (`title`, `description`, `platforms`), syntax, parameters, return value, and at least one runnable example — and update the area overview (`<Area>.md`). Copy the structure of an existing page.
### 6. Tests
- **Backend:** colocated Vitest tests; prefer the in-memory test server (`setupPuterTestEnv` in [src/backend/testUtil.ts](../src/backend/testUtil.ts)) over mocking.
- **SDK:** add cases to [src/puter-js/tests/api/suites/](../src/puter-js/tests/api/suites/)`<area>.suite.ts` (register new suites in `suites/index.ts`). One suite runs on node, browser, and workerd via `npm run test:puterjs` — never write per-platform tests, and rebuild first with `npm run build:workerLib` since the runners execute the built bundle.
- **Desktop-rendered UI** (`puter.ui.*`): add a Playwright spec per [src/puter-js/TESTING.md](../src/puter-js/TESTING.md).
### 7. Security pass
Scan the diff before opening the PR: no internals leaked in errors or logs, no over-broad responses, auth gates present. Flag anything auth-, permission-, or data-export-related in the PR description.
## Maintaining an existing API
Changes are **additive by default**:
- New parameters are optional, with defaults that reproduce the old behavior exactly.
- Never rename, repurpose, or remove existing parameters, response fields, or error codes. Don't change types, ordering guarantees, or which fields are present when.
- New behavior that could surprise existing callers goes behind an opt-in flag.
- Docs, types, and tests move in the same PR as the behavior. A signature change with stale docs is a bug — the docs are the contract users code against.
- Bug fixes come with a regression test that fails before the fix. Be suspicious of fixes that change observable behavior: someone may depend on the bug. When in doubt, ask a maintainer.
### Breaking changes
Rare and deliberate. In order: explicit maintainer sign-off, a documented migration path, and a rollout plan — typically new surface added first, old surface deprecated, old surface removed much later, if ever. Never break as a side effect of a refactor.
### Deprecating
The old surface keeps working. Mark it `@deprecated` in the type declarations, note the replacement on its docs page, and stop using it in examples. Removal is a separate, maintainer-approved decision.
## Definition of done
- [ ] Backward compatible (or the break was explicitly approved)
- [ ] Right home: extension if core never calls it; layered structure either way
- [ ] puter.js method matches sibling conventions; errors are `{ message, code }` with stable codes
- [ ] Types updated and matching runtime behavior
- [ ] Docs page + area overview updated, with a runnable example
- [ ] Tests: backend + three-platform SDK suite (+ e2e for desktop-rendered UI)
- [ ] Security pass on the diff
- [ ] You ran it end to end
-30
View File
@@ -1,30 +0,0 @@
# Comment Prefixes
Comments have prefixes using
[Conventional: Comments](https://conventionalcomments.org/)
as a **loose** guideline, and using this markdown file as a
the actual guideline.
This document will be updated on an _as-needed_ basis.
## The rules
- A comment line always looks like this:
- A whitespace character
- Optional prefix matching `/[a-z-]+\([a-z-]a+\):/`
- A whitespace character
- The comment
- Formalized prefixes must follow the rules below
- Any other prefix can be used. After some uses it
might be good to formalize it, but that's not a hard rule.
## Formalized prefixes
- `todo:` is interchangable with the famous `TODO:`, **except:**
when lowercase (`todo:`) it can include a scope: `todo(security):`.
- `track:` is used to track common patterns.
- Anything written after `track:` must be registered in
[track-comments.md](../devmeta/track-comments.md)
- `wet:` is usesd to track anything that doesn't adhere
to the DRY principle; the following message should describe
where similar code is
-2
View File
@@ -1,2 +0,0 @@
### `vscode`
- `es6-string-html`
-25
View File
@@ -1,25 +0,0 @@
# Contributing to Puter
## Essential / General Knowledge
### Repository Dichotomy
- Puter's GUI is at the root; `/src` is the GUI
- Puter's backend is a workspace npm package;
it resides in `packages/backend(/src)`
The above may seem counter-intuitive; backend and frontend are siblings, right?
Consider this: by a different intuition, the backend is at a "deeper" level
of function; this directory structure better adheres to soon-to-be contributors
sifting around through the files to discover "what's what".
The directory `volatile` exists _for your convenience_ to simplify running
Puter for development. When Puter is run
run with the backend with this repository as its working directory, it
will use `volatile/config` and `volatile/runtime` instead of
`/etc/puter` and `/var/puter`.
## See Next
- [Backend Documentation](../../packages/backend/doc/contributors/index.md)
<!-- - [Frontend Documentation](./frontend.md) -->
-59
View File
@@ -1,59 +0,0 @@
# Track Comments
Comments beginning with `// track:`. See
[comment_prefixes.md](../contributors/comment_prefixes.md)
## Track Comment Registry
- `track: type check`:
A condition that's used to check the type of an imput.
- `track: adapt`
A value can by adapted from another type at this line.
- `track: bounds check`:
A condition that's used to check the bounds of an array
or other list-like entity.
- `track: ruleset`
A series of conditions that early-return or `continue`
- `track: object description in comment`
A comment above the creation of some object which
could potentially have a `description` property.
This is especially relevant if the object is stored
in some kind of registry where multiple objects
could be listed in the console.
- `track: slice a prefix`
A common pattern where a prefix string is "sliced off"
of another string to obtain a significant value, such
as an indentifier.
- `track: actor type`
The sub-type of an Actor object is checked.
- `track: scoping iife`
An immediately-invoked function expression specifically
used to reduce scope clutter.
- `track: good candidate for sequence`
Some code involves a series of similar steps,
or there's a common behavior that should happen
in between. The Sequence class is good for this so
it might be a worthy migration.
- `track: opposite condition of sibling`
A sibling class, function, method, or other construct of
source code has a boolean expression which always evaluates
to the opposite of the one below this track comment.
- `track: null check before processing`
An object could be undefined or null, additional processing
occurs after a null check, and the unprocessed object is not
relevant to the rest of the code. If the code for obtaining
the object and processing it is moved to a function outside,
then the null check should result in a early return of null;
this code with the track comment may have additional logic
for the null/undefined case.
- `track: manual safe object`
This code manually creates a new "client-safe" version of
some object that's in scope. This could be either to pass
onto the browser or to pass to something like the
notification service.
- `track: common operations on multiple items`
A patterm which emerges when multiple variables have
common operations done upon them in sequence.
It may be applicable to write an iterator in the
future, or something will come up that require
these to be handled with a modular approach instead.
-12
View File
@@ -1,12 +0,0 @@
# Meta Documentation
## Notes
- > This document is a work-in-progress
## Rules
### "is" and "is not"
- When "A is B", always bold "is": "A **is** B" (`A **is** B`)
- When "A is not B", always bold "not": "A is **not** B" (`A is **not** B`)
+129
View File
@@ -0,0 +1,129 @@
<h3 align="center"><img width="80" alt="Puter.com، الحاسوب السحابي الشخصي: جميع ملفاتك وتطبيقاتك وألعابك في مكان واحد يمكن الوصول إليه من أي مكان في أي وقت." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">نظام تشغيل الإنترنت! مجاني ومفتوح المصدر وقابل للاستضافة الذاتية.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« عرض توضيحي مباشر »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">مجموعة أدوات التطوير</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">ديسكورد</a>
·
<a href="https://reddit.com/r/puter">ريديت</a>
·
<a href="https://twitter.com/HeyPuter">إكس (تويتر)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="لقطة شاشة" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## بيوتر
<div dir="rtl">
<p>بيوتر هو نظام تشغيل إنترنت متقدم ومفتوح المصدر، مصمم ليكون غنيًا بالميزات وسريعًا بشكل استثنائي وقابلًا للتوسع بدرجة كبيرة. يمكن استخدام بيوتر كـ:</p>
<ul>
<li>سحابة شخصية تعطي الأولوية للخصوصية لحفظ جميع ملفاتك وتطبيقاتك وألعابك في مكان آمن واحد، يمكن الوصول إليه من أي مكان وفي أي وقت.</li>
<li>منصة لبناء ونشر المواقع الإلكترونية وتطبيقات الويب والألعاب</li>
<li>بديل لـ Dropbox وGoogle Drive وOneDrive وغيرها، مع واجهة جديدة وميزات قوية.</li>
<li>بيئة سطح مكتب عن بُعد للخوادم ومحطات العمل.</li>
<li>مشروع ومجتمع ودود ومفتوح المصدر للتعلم عن تطوير الويب والحوسبة السحابية والأنظمة الموزعة والكثير غير ذلك!</li>
</ul>
</div>
<br/>
## البدء
### 💻 التطوير المحلي
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
سيؤدي هذا إلى تشغيل Puter على http://puter.localhost:4100 (أو المنفذ التالي المتاح).
<br/>
### 🐳 دوكر
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 دوكر كومبوز
#### لينكس/ماك
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### ويندوز
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ موقع Puter.com
متاح Puter كخدمة مستضافة على[**puter.com**](https://puter.com)الموقع
<br/>
## متطلبات النظام
- **Operating Systems:** لينكس، ماك، ويندوز
- **RAM** ٢ جيجابايت كحد أدنى (يوصى بـ ٤ جيجابايت)
- **Disk Space:** ١ جيجابايت مساحة حرة
- **Node.js:** الإصدار ١٦+ (يوصى بالإصدار ٢٢+)
- **npm:** أحدث إصدار مستقر
<br/>
## الدعم
تواصل مع المشرفين والمجتمع من خلال هذه القنوات:
- تقرير عن خطأ أو طلب ميزة؟ الرجاء [فتح مشكلة](https://github.com/HeyPuter/puter/issues/new/choose)
- دسكورد: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- إكس (تويتر): [x.com/HeyPuter](https://x.com/HeyPuter)
- ريديت: [/reddit.com/r/puter](https://www.reddit.com/r/puter/)
- ماستودون: [mastodon.social/@puter](https://mastodon.social/@puter)
- مشاكل أمنية؟ [[email protected]](mailto:[email protected])
- البريد الإلكتروني للمشرفين [[email protected]](mailto:[email protected])
نحن دائمًا سعداء لمساعدتك في أي أسئلة قد تكون لديك. لا تتردد في السؤال!
<br/>
## الترخيص
هذا المستودع، بما في ذلك جميع محتوياته ومشاريعه الفرعية ووحداته ومكوناته، مرخص تحت [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) ما لم ينص على خلاف ذلك صراحةً. قد تخضع المكتبات الخارجية المدرجة في هذا المستودع لتراخيصها الخاصة.
<br/>
+124
View File
@@ -0,0 +1,124 @@
<h3 align="center"><img width="80" alt="Puter.com, ব্যক্তিগত ক্লাউড কম্পিউটার: আপনার সমস্ত ফাইল, অ্যাপস, এবং গেম এক জায়গায়, যেকোনো সময়, যেকোনো স্থান থেকে অ্যাক্সেসযোগ্য।" src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">ইন্টারনেট ওএস! ফ্রি, ওপেন-সোর্স, এবং সেল্ফ-হোস্টেবল।</h3>
<p align="center">
<img alt="GitHub রেপোর আকার " src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub রিলিজ" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub লাইসেন্স" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« লাইভ ডেমো »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">এসডিকে</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">ডিসকর্ড</a>
·
<a href="https://reddit.com/r/puter">রেডিট</a>
·
<a href="https://twitter.com/HeyPuter">X (টুইটার)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="স্ক্রিনশট" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter একটি উন্নত, ওপেন-সোর্স ইন্টারনেট অপারেটিং সিস্টেম যা বৈশিষ্ট্যপূর্ণ, অত্যন্ত দ্রুত এবং উচ্চ মাত্রায় সম্প্রসারণযোগ্য। Puter ব্যবহার করা যেতে পারে:
- একটি প্রাইভেসি-প্রথম পার্সোনাল ক্লাউড হিসাবে যা আপনার সমস্ত ফাইল, অ্যাপস এবং গেমসকে এক জায়গায় নিরাপদে রাখে, যেকোনো সময় যেকোনো স্থান থেকে অ্যাক্সেসযোগ্য।
- ওয়েবসাইট, ওয়েব অ্যাপ এবং গেম তৈরি ও প্রকাশ করার একটি প্ল্যাটফর্ম হিসাবে।
- ড্রপবক্স, গুগল ড্রাইভ, ওয়ানড্রাইভ ইত্যাদির বিকল্প হিসাবে একটি নতুন ইন্টারফেস এবং শক্তিশালী বৈশিষ্ট্য সহ।
- সার্ভার এবং ওয়ার্কস্টেশনের জন্য একটি রিমোট ডেস্কটপ এনভায়রনমেন্ট হিসাবে।
- ওয়েব ডেভেলপমেন্ট, ক্লাউড কম্পিউটিং, ডিস্ট্রিবিউটেড সিস্টেম এবং আরও অনেক কিছু শিখতে একটি বন্ধুত্বপূর্ণ, ওপেন-সোর্স প্রকল্প এবং কমিউনিটি হিসাবে!
<br/>
## শুরু করার জন্য
## 💻 লোকাল ডেভেলপমেন্ট
```bash
Copy code
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
এটি Puter কে http://puter.localhost:4100 (অথবা পরবর্তী উপলব্ধ পোর্টে) চালু করবে।
<br/>
## 🐳 ডকার
```bash
Copy code
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
## 🐙 ডকার কম্পোজ
## লিনাক্স/ম্যাকওএস
```bash
Copy code
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
## উইন্ডোজ
```powershell
Copy code
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
## ☁️ Puter.com
Puter [**puter.com**](https://puter.com) এ হোস্টেড সার্ভিস হিসেবে উপলব্ধ।
<br/>
## সিস্টেম রিকোয়ারমেন্টস
- **অপারেটিং সিস্টেম:** লিনাক্স, ম্যাকওএস, উইন্ডোজ
- **র‍্যাম:** ২জিবি ন্যূনতম (৪জিবি প্রস্তাবিত)
- **ডিস্ক স্পেস:** ১জিবি ফ্রি স্পেস
- **Node.js:** সংস্করণ ১৬+ (সংস্করণ ২২+ প্রস্তাবিত)
- **npm:** সর্বশেষ স্থিতিশীল সংস্করণ
<br/>
## সাপোর্ট
মেইনটেইনার এবং কমিউনিটির সাথে এই চ্যানেলগুলির মাধ্যমে সংযোগ করুন:
- বাগ রিপোর্ট বা ফিচার রিকোয়েস্ট? অনুগ্রহ করে একটি ইস্যু খুলুন।
- ডিসকর্ড: discord.com/invite/PQcx7Teh8u
- X (টুইটার): x.com/HeyPuter
- রেডিট: reddit.com/r/puter/
- মাস্টডন: mastodon.social/@puter
- সিকিউরিটি ইস্যু? security@puter.com
- মেইনটেইনারদের ইমেইল করুন hi@puter.com এ
আপনার যেকোনো প্রশ্নের জন্য আমরা সবসময় সাহায্য করতে প্রস্তুত। জিজ্ঞাসা করতে দ্বিধা করবেন না!
<br/>
## লাইসেন্স
এই রিপোজিটরি, এর সমস্ত বিষয়বস্তু, সাব-প্রকল্প, মডিউল, এবং কম্পোনেন্ট সহ [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) লাইসেন্সের অধীনে লাইসেন্সকৃত, যদি অন্যথায় স্পষ্টভাবে উল্লেখ না করা হয়। এই রিপোজিটরিতে অন্তর্ভুক্ত তৃতীয় পক্ষের লাইব্রেরিগুলি তাদের নিজস্ব লাইসেন্সের অধীনে হতে পারে।
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, Den Personlige Cloudcomputer: Alle dine filer, apps og spil på ét sted tilgængelige fra hvor som helst til enhver tid." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Internet OS'et! Gratis, Open-Source og kan selvhostes.</h3>
<p align="center">
<img alt="GitHub repo størrelse" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Udgivelse" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub Licens" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="skærmbillede" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter er et avanceret, open-source internetoperativsystem designet til at være funktionsrigt, exceptionelt hurtigt og meget udvideligt. Puter kan bruges som:
- En privatlivsfokuseret personlig sky til at opbevare alle dine filer, apps og spil på ét sikkert sted, tilgængeligt hvor som helst og når som helst.
- En platform til at bygge og publicere hjemmesider, webapplikationer og spil.
- Et alternativ til Dropbox, Google Drive, OneDrive osv. med et friskt interface og kraftfulde funktioner.
- Et fjernskrivebordsmiljø for servere og arbejdsstationer.
- Et venligt, open-source projekt og fællesskab til at lære om webudvikling, cloud computing, distribuerede systemer og meget mere!
<br/>
## Kom godt i gang
### 💻 Lokal Udvikling
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Dette vil starte Puter på http://puter.localhost:4100 (eller den næste tilgængelige port).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter er tilgængelig som en hosted tjeneste på [**puter.com**](https://puter.com).
<br/>
## Systemkrav
- **Operativsystemer:** Linux, macOS, Windows
- **RAM:** 2GB minimum (4GB anbefales)
- **Diskplads:** 1GB fri plads
- **Node.js:** Version 16+ (Version 22+ anbefales)
- **npm:** Seneste stabile version
<br/>
## Support
Kom i kontakt med vedligeholderne og fællesskabet gennem disse kanaler:
- Bugrapport eller funktionønske? Åbn [venligst en sag](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Sikkerhedsspørgsmål? [[email protected]](mailto:[email protected])
- Send email til vedligeholdere på [[email protected]](mailto:[email protected])
Vi er altid glade for at hjælpe dig med eventuelle spørgsmål, du måtte have. Tøv ikke med at spørge!
<br/>
## Licens
Dette repository, inklusive alt dets indhold, underprojekter, moduler og komponenter, er licenseret under [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt), medmindre andet er udtrykkeligt angivet. Tredjepartsbiblioteker inkluderet i dette repository kan være underlagt deres egne licenser.
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, Der persönliche Cloud-Computer: Alle Ihre Dateien, Apps und Spiele an einem Ort, jederzeit und überall zugänglich." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Das Internet-Betriebssystem! Kostenlos, Open-Source und selbst hostbar.</h3>
<p align="center">
<img alt="GitHub Repo-Größe" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Veröffentlichung" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=neueste%20Version"> <img alt="GitHub Lizenz" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="Bildschirmfoto" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter ist ein fortschrittliches, Open-Source-Internet-Betriebssystem, das funktionsreich, außergewöhnlich schnell und hochgradig erweiterbar konzipiert wurde. Puter kann verwendet werden als:
- Eine datenschutzfreundliche persönliche Cloud, um alle Ihre Dateien, Apps und Spiele an einem sicheren Ort aufzubewahren, jederzeit und überall zugänglich.
- Eine Plattform zum Erstellen und Veröffentlichen von Websites, Webanwendungen und Spielen.
- Eine Alternative zu Dropbox, Google Drive, OneDrive usw. mit einer frischen Benutzeroberfläche und leistungsstarken Funktionen.
- Eine Remote-Desktop-Umgebung für Server und Workstations.
- Ein freundliches, Open-Source-Projekt und eine Community, um mehr über Webentwicklung, Cloud Computing, verteilte Systeme und vieles mehr zu lernen!
<br/>
## Erste Schritte
### 💻 Lokale Entwicklung
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Dies startet Puter unter http://puter.localhost:4100 (oder dem nächsten verfügbaren Port).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter ist als gehosteter Dienst unter [**puter.com**](https://puter.com) verfügbar.
<br/>
## Systemanforderungen
- **Betriebssysteme:** Linux, macOS, Windows
- **RAM:** Mindestens 2GB (4GB empfohlen)
- **Festplattenspeicher:** 1GB freier Speicherplatz
- **Node.js:** Version 16+ (Version 22+ empfohlen)
- **npm:** Neueste stabile Version
<br/>
## Unterstützung
Verbinden Sie sich mit den Maintainern und der Community über diese Kanäle:
- Fehlerbericht oder Funktionsanfrage? Bitte [öffnen Sie ein Issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Sicherheitsprobleme? [[email protected]](mailto:[email protected])
- E-Mail an die Maintainer: [[email protected]](mailto:[email protected])
Wir helfen Ihnen gerne bei allen Fragen, die Sie haben könnten. Zögern Sie nicht zu fragen!
<br/>
## Lizenz
Dieses Repository, einschließlich aller Inhalte, Unterprojekte, Module und Komponenten, ist unter [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) lizenziert, sofern nicht ausdrücklich anders angegeben. In diesem Repository enthaltene Bibliotheken von Drittanbietern können ihren eigenen Lizenzen unterliegen.
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">The Internet OS! Free, Open-Source, and Self-Hostable.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter is an advanced, open-source internet operating system designed to be feature-rich, exceptionally fast, and highly extensible. Puter can be used as:
- A privacy-first personal cloud to keep all your files, apps, and games in one secure place, accessible from anywhere at any time.
- A platform for building and publishing websites, web apps, and games.
- An alternative to Dropbox, Google Drive, OneDrive, etc. with a fresh interface and powerful features.
- A remote desktop environment for servers and workstations.
- A friendly, open-source project and community to learn about web development, cloud computing, distributed systems, and much more!
<br/>
## Getting Started
### 💻 Local Development
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
This will launch Puter at http://puter.localhost:4100 (or the next available port).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter is available as a hosted service at [**puter.com**](https://puter.com).
<br/>
## System Requirements
- **Operating Systems:** Linux, macOS, Windows
- **RAM:** 2GB minimum (4GB recommended)
- **Disk Space:** 1GB free space
- **Node.js:** Version 16+ (Version 22+ recommended)
- **npm:** Latest stable version
<br/>
## Support
Connect with the maintainers and community through these channels:
- Bug report or feature request? Please [open an issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Security issues? [[email protected]](mailto:[email protected])
- Email maintainers at [[email protected]](mailto:[email protected])
We are always happy to help you with any questions you may have. Don't hesitate to ask!
<br/>
## License
This repository, including all its contents, sub-projects, modules, and components, is licensed under [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) unless explicitly stated otherwise. Third-party libraries included in this repository may be subject to their own licenses.
<br/>
+171
View File
@@ -0,0 +1,171 @@
<h3 align="center"><img width="80" alt="Puter.com, El Computador Personal en Nube: Todos tus archivos, apps y juegos en un solo lugar accesible desde cualquier lugar en cualquier momento" src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">El Sistema Operativo de Internet! Gratis, de Código abierto, y Autohospedable.</h3>
<p align="center">
<a href="https://puter.com/"><strong>« DEMO EN VIVO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://apps.puter.com/">App Store</a>
·
<a href="https://developer.puter.com" target="_blank">Developers</a>
·
<a href="https://github.com/heyputer/puter-cli" target="_blank">CLI</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://x.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter es un sistema operativo en internet avanzado y de código abierto, diseñado para ser rico en funcionalidades, excepcionalmente rápido y altamente extensible. Puter puede ser usado como:
- Una nube personal privada para almacenar todos tus archivos, aplicaciones y juegos en un lugar seguro, accesible y desde cualquier lugar en cualquier momento.
- Una plataforma para construir y publicar páginas web, aplicativos sobre la web y juegos.
- Una alternativa a Dropbox, Google Drive, OneDrive, etc. con una interfaz fresca y llena de funcionalidades.
- Un entorno de escritorio remoto para servidores y estaciones de trabajo.
- Un proyecto y comunidad abiertas y amigables para aprender sobre desarrollo web, computación en la nube, sistemas distribuidos y mucho más!
<br/>
## Primeros Pasos
### 💻 Desarrollo Local
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
✨ Esto ejecutará Puter en http://puter.localhost:4100 (o el siguiente puerto disponible).
Si esto no funciona, consulta [First Run Issues](./doc/self-hosters/first-run-issues.md) para obtener pasos de solución de problemas.
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
✨ Esto ejecutará Puter en http://puter.localhost:4100 (o el siguiente puerto disponible).
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
✨ Esto ejecutará Puter en http://puter.localhost:4100 (o el siguiente puerto disponible).
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
✨ Esto ejecutará Puter en http://puter.localhost:4100 (o el siguiente puerto disponible).
<br/>
### 🚀 Auto-Hospedaje
Para guías detalladas sobre cómo auto-hospedar Puter, incluyendo opciones de configuración y mejores prácticas, consulta nuestra [Documentación de Auto-Hospedaje](https://github.com/HeyPuter/puter/blob/main/doc/self-hosters/instructions.md).
### ☁️ Puter.com
Puter está disponible como servicio alojado en [**puter.com**](https://puter.com).
<br/>
## Requerimientos del sistema
- **Sistemas operativos:** Linux, macOS, Windows
- **RAM:** 2GB mínimo (4GB recomendados)
- **Almacenamiento:** 1GB de espacio libre
- **Node.js:** Versión 16+ (Versión 23+ recomendada)
- **npm:** Última version estable
<br/>
## Soporte
Conéctate con los mantenedores y la comunidad a través de estos canales:
- Reporte de bug o solicitud de funcionalidad? Por favor [abrir un issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Problemas de seguridad? [[email protected]](mailto:[email protected])
- Envia un email a los mantenedores en [[email protected]](mailto:[email protected])
Estamos siempre felices de ayudar con cualquier pregunta que puedas tener. No dudes en preguntar!
<br/>
## Licencia
Este repositorio, incluyendo todo su contenido, sub-proyectos, modulos y componentes, esta licenciado bajo [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) a menos que se indique explícitamente lo contrario. Librerías de terceros incluidos en este repositorio pueden estar sujetas a sus propias licencias.
<br/>
## Traducciones
- [Arabic / العربية](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ar.md)
- [Armenian / Հայերեն](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hy.md)
- [Bengali / বাংলা](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.bn.md)
- [Chinese / 中文](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.zh.md)
- [Danish / Dansk](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.da.md)
- [English](https://github.com/HeyPuter/puter/blob/main/README.md)
- [Farsi / فارسی](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fa.md)
- [Finnish / Suomi](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fi.md)
- [French / Français](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fr.md)
- [German/ Deutsch](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.de.md)
- [Hebrew/ עברית](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.he.md)
- [Hindi / हिंदी](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hi.md)
- [Hungarian / Magyar](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hu.md)
- [Indonesian / Bahasa Indonesia](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.id.md)
- [Italian / Italiano](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.it.md)
- [Japanese / 日本語](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.jp.md)
- [Korean / 한국어](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ko.md)
- [Malayalam / മലയാളം](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ml.md)
- [Polish / Polski](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pl.md)
- [Portuguese / Português](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pt.md)
- [Romanian / Română](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ro.md)
- [Russian / Русский](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ru.md)
- [Spanish / Español](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.es.md)
- [Swedish / Svenska](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.sv.md)
- [Tamil / தமிழ்](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ta.md)
- [Telugu / తెలుగు](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.te.md)
- [Thai / ไทย](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.th.md)
- [Turkish / Türkçe](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.tr.md)
- [Ukrainian / Українська](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ua.md)
- [Urdu / اردو](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ur.md)
- [Vietnamese / Tiếng Việt](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.vi.md)
+133
View File
@@ -0,0 +1,133 @@
<h3 align="center"><img width="80" alt="Puter.com، رایانش ابری شخصی: همه فایل‌ها، برنامه‌ها و بازی‌های شما در یک مکان قابل دسترسی از هر جا و در هر زمان." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">سیستم‌عامل اینترنت! رایگان، متن‌باز، و قابل میزبانی شخصی.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« نسخه نمایشی زنده »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">مستندات توسعه‌دهندگان</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">دیسکورد</a>
·
<a href="https://reddit.com/r/puter">ردیت</a>
·
<a href="https://twitter.com/HeyPuter">ایکس (توییتر)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="عکس صفحه" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## پیوتر
<div dir="rtl">
<p>پیوتر یک سیستم عامل تحت وب پیشرفته‌ی متن‌باز است که به منظور ایجاد ویژگی‌های متنوع، سرعت بسیار بالا، و مقیاس‌پذیری طراحی شده است. از پیوتر می‌توان به‌عنوان:</p>
<ul>
<li>یک فضای ابری شخصی که بر حریم خصوصی تمرکز دارد و تمام فایل‌ها، برنامه‌ها، و بازی‌های شما را در یک مکان امن ذخیره می‌کند، قابل دسترسی از هر جا و در هر زمان.</li>
<li>پلتفرمی برای ساخت و انتشار وب‌سایت‌ها، اپلیکیشن‌های وب، و بازی‌ها.</li>
<li>جایگزینی برای Dropbox، Google Drive، OneDrive، و سایر موارد، با یک رابط کاربری مدرن و قابلیت‌های قدرتمند.</li>
<li>یک محیط دسکتاپ از راه دور برای سرورها و ایستگاه‌های کاری.</li>
<li> یک پروژه و جامعه‌ی متن‌باز دوستانه برای یادگیری توسعه وب، رایانش ابری، سیستم‌های توزیع‌شده، و موارد دیگر نام برد!</li>
</ul>
</div>
<br/>
## نحوه‌ی استفاده
### 💻 توسعه‌ی محلی
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
این کار پیوتر را در http://puter.localhost:4100 (یا پورت در دسترس بعدی) اجرا می‌کند.
<br/>
### 🐳 داکر
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 داکر کامپوز
#### لینوکس/مک
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### ویندوز
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ وبگاه Puter.com
پیوتر به‌عنوان یک سرویس میزبانی‌شده در وبگاه [**puter.com**](https://puter.com) موجود است.
## پیش‌نیازهای سیستم
- **سیستم‌عامل‌ها:** لینوکس، مک، ویندوز
- **RAM** حداقل ۲ گیگابایت (پیشنهاد: ۴ گیگابایت)
- **فضای دیسک:** ۱ گیگابایت فضای خالی
- **Node.js:** نسخه ۱۶+ (پیشنهاد: نسخه ۲۲+)
- **npm:** آخرین نسخه پایدار
<br/>
## پشتیبانی
با مدیران و انجمن از طریق این کانال‌ها در تماس باشید:
- گزارش اشکال یا درخواست ویژگی؟ لطفاً [Isuue باز کنید](https://github.com/HeyPuter/puter/issues/new/choose)
- دیسکورد: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- ایکس (توییتر): [x.com/HeyPuter](https://x.com/HeyPuter)
- ردیت: [/reddit.com/r/puter](https://www.reddit.com/r/puter/)
- ماستودون: [mastodon.social/@puter](https://mastodon.social/@puter)
- مشکلات امنیتی؟ [[email protected]](mailto:[email protected])
- ایمیل مدیران: [[email protected]](mailto:[email protected])
ما همیشه از پاسخگویی به سوالات شما خرسند هستیم. در سوال پرسیدن درنگ نکنید!
## گواهی
این مخزن، شامل تمام محتویات، پروژه‌های فرعی، ماژول‌ها و اجزای آن، تحت مجوز [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) است مگر آنکه خلاف آن به‌طور صریح ذکر شده باشد. کتابخانه‌های خارجی ممکن است گواهی‌های جداگانه داشته باشند.
<br/>
+126
View File
@@ -0,0 +1,126 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Internetin käyttöjärjestelmä! Ilmainen, avoimen lähdekoodin ja itse isännöitävä.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=viimeisin%20versio"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="näyttökuva" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter on kehittynyt, avoimen lähdekoodin internetin käyttöjärjestelmä, joka on suunniteltu olemaan ominaisuuksiltaan rikas, poikkeuksellisen nopea ja erittäin laajennettava. Puteria voidaan käyttää:
- Yksityisyyttä kunnioittavana henkilökohtaisena pilvenä, johon voit tallentaa kaikki tiedostosi, sovelluksesi ja pelisi turvallisesti yhdessä paikassa, josta ne ovat saatavilla missä tahansa ja milloin tahansa.
- Alustana verkkosivustojen, web-sovellusten ja pelien rakentamiseen ja julkaisemiseen.
- Vaihtoehtona Dropboxille, Google Drivelle, OneDrivelle jne. tuoreella käyttöliittymällä ja tehokkailla ominaisuuksilla.
- Etätyöpöytäympäristönä palvelimille ja työasemille.
- Ystävällisenä, avoimen lähdekoodin projektina ja yhteisönä, jossa voit oppia verkkokehityksestä, pilvipalveluista, hajautetuista järjestelmistä ja paljon muusta!
<br/>
## Aloittaminen
### 💻 Paikallinen kehitys
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Tämä käynnistää Puterin osoitteessa http://puter.localhost:4100 (tai seuraavassa vapaassa portissa).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter on saatavilla isännöitynä palveluna osoitteessa [**puter.com**](https://puter.com).
<br/>
## Järjestelmävaatimukset
- **Käyttöjärjestelmät:** Linux, macOS, Windows
- **RAM:** Vähintään 2GB (Suositeltu 4GB)
- **Levytila:** 1GB vapaata tilaa
- **Node.js:** Versio 16+ (Suositeltu versio 22+)
- **npm:** Uusin vakaa versio
<br/>
## Tuki
Ota yhteyttä ylläpitäjiin ja yhteisöön näiden kanavien kautta:
- Onko sinulla virheraportti tai ominaisuuspyyntö? Ole hyvä ja [avaa uusi issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Turvallisuusongelmat? [[email protected]](mailto:[email protected])
- Ota yhteyttä ylläpitäjiin sähköpostitse osoitteessa [[email protected]](mailto:[email protected])
Olemme aina valmiita auttamaan sinua kaikissa kysymyksissäsi. Älä epäröi kysyä!
<br/>
## Lisenssi
Tämä repository, mukaan lukien kaikki sen sisältö, aliprojektit, moduulit ja komponentit, on lisensoitu [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt)-lisenssillä, ellei toisin mainita. Tämän repositoryn mukana tulevat kolmannen osapuolen kirjastot voivat olla omien lisenssiensä alaisia.
<br/>
+125
View File
@@ -0,0 +1,125 @@
<h3 align="center"><img width="80" alt="Puter.com, L'ordinateur cloud personnel : Tous vos fichiers, applications et jeux en un seul endroit accessible de partout à tout moment." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">L'OS Internet ! Gratuit, open-source et auto-hébergeable.</h3>
<p align="center">
<img alt="Taille du dépôt GitHub" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="Version GitHub" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=derni%C3%A8re%20version"> <img alt="Licence GitHub" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« DÉMO EN DIRECT »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="capture d'écran" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter est un système d'exploitation internet avancé, open-source, conçu pour être riche en fonctionnalités, extrêmement rapide et hautement extensible. Puter peut être utilisé comme :
- Un cloud personnel axé sur la confidentialité pour garder tous vos fichiers, applications et jeux en un seul endroit sécurisé, accessible de partout à tout moment.
- Une plateforme pour créer et publier des sites web, des applications web et des jeux.
- Une alternative à Dropbox, Google Drive, OneDrive, etc. avec une interface renouvelée et des fonctionnalités puissantes.
- Un environnement de bureau à distance pour serveurs et stations de travail.
- Un projet et une communauté open-source accueillants pour apprendre le développement web, l'informatique en nuage, les systèmes distribués, et bien plus encore !
<br/>
## Démarrage
### 💻 Développement Local
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Cela lancera Puter à http://puter.localhost:4100 (ou au port disponible suivant).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter est disponible en tant que service hébergé sur [**puter.com**](https://puter.com).
<br/>
## Configuration système requise
- **Systèmes d'exploitation:** Linux, macOS, Windows
- **RAM:** Minimum 2 Go (4 Go recommandés)
- **Espace disque:** 1 Go d'espace libre
- **Node.js:** Version 16+ (Version 22+ recommandée)
- **npm:** Dernière version stable
<br/>
## Support
Connectez-vous avec les mainteneurs et la communauté via ces canaux :
- Un bug ou une demande de fonctionnalité ? Veuillez [ouvrir une issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Problèmes de sécurité ? [[email protected]](mailto:[email protected])
- Email des mainteneurs à [[email protected]](mailto:[email protected])
Nous sommes toujours heureux de vous aider avec toutes les questions que vous pourriez avoir. N'hésitez pas à nous demander !
<br/>
## License
Ce dépôt, y compris tout son contenu, sous-projets, modules et composants, est licencié sous [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) sauf indication contraire explicite. Les bibliothèques tierces incluses dans ce dépôt peuvent être soumises à leurs propres licences.
<br/>
+130
View File
@@ -0,0 +1,130 @@
<h3 align="center"><img width="80" alt="Puter.com,
הענן הפרטי: כל הקבצים, האפליקציות והמשחקים שלך במקום אחד נגיש מכל מקום ובכל זמן." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center" dir="rtl">מערכת ההפעלה של האינטרנט! חינמית, קוד פתוח וניתנת לאחסון עצמאי.</h3>
<p align="center">
<img alt="GitHub גודל ספרית" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub גרסא" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub רישיון" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« הדגמה לייב »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="צילום מסך" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
<div dir="rtl">
<p div="rtl">
מערכת ההפעלה Puter הינה ספרית קוד פתוח, מתקדמת, עשירה בתכנים, מהירה במיוחד וניתנת להרחבה.
אפשר להישתמש ב Puter כ:</p>
<ul>
<li>ענן אישי עם פרטיות מקסימלית, לשמירת הקבצים, האפליקציות והמשחקים שלך במקום מאובטח אחד, נגיש מכל מקום ובכל זמן.</li>
<li>פלטפורמה לבניית ופרסום אתרים, אפליקציות ומשחקים.</li>
<li>אלטרנטיבה ל-Dropbox, Google Drive, OneDrive וכו' עם ממשק מרענן ותכנים חזקים.</li>
<li>סביבה לעבודה מרחוק לשרתים ותחנות עבודה.</li>
<li>פרוייקט ידידותי, קוד פתוח וקהילה ללמידה על פיתוח אינטרנט, פיתוח בענן, מערכות מבוזרות ועוד הרבה!</li>
<ul>
</div>
<br/>
## בוא נתחיל
### 💻 פיתוח מקומי (Localhost)
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
פקודה זו תפעיל את Puter בכתובת http://puter.localhost:4100 (או בפורט הפנוי הבא).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
מערכת ההפעלה Puter זמינה כשירות אחסון ב- [**puter.com**](https://puter.com).
<br/>
## דרישות מערכת
- **מערכות הפעלה:** Linux, macOS, Windows
- **RAM:** לפחות 2GB, מומלץ 4GB
- **מקום פנוי בדיסק:** 1GB
- **Node.js:** גרסה 16+ (מומלץ גרסה 22+)
- **npm:** הגרסה היציבה האחרונה
<br/>
## תמיכה
צור קשר עם המפתחים והקהילה דרך הערוצים הבאים:
- דיווח על באג או בקשה לתוכן? אנא [פתח פניה](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter](https://www.reddit.com/r/puter.)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- בעיות אבטחה? [[email protected]](mailto:[email protected])
- שלח אימייל למפתחים ב [[email protected]](mailto:[email protected])
אנחנו תמיד שמחים לעזור עם כל שאלה שיש. אל תהסס לשאול!
<br/>
## רישיון
ספריה זו, כולל כל התכנים שלה, תתי הפרויקטים, המודולים והרכיבים שלה, מורשית תחת [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) אלא אם נאמר אחרת במפורש. לספריות צד שלישי הכלולות בספרייה זו עשויות להיות רישיונות משלהן.
<br/>
+182
View File
@@ -0,0 +1,182 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: आपकी सारी फाइलें, ऐप्स, और गेम एक ही जगह, जिसे कहीं से भी कभी भी एक्सेस किया जा सकता है।" src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">इंटरनेट ओएस! फ्री, ओपन-सोर्स, और सेल्फ-होस्टेबल।</h3>
<p align="center">
<a href="https://puter.com/?ref=github.com"><strong>« लाइव डेमो »</strong></a>
<br />
<br />
<a href="https://puter.com/?ref=github.com">Puter.com</a>
·
<a href="https://apps.puter.com/">ऐप स्टोर</a>
·
<a href="https://developer.puter.com" target="_blank">डेवलपर्स</a>
·
<a href="https://github.com/heyputer/puter-cli" target="_blank">CLI</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter क्या है?
Puter एक एडवांस्ड, ओपन-सोर्स इंटरनेट ऑपरेटिंग सिस्टम है जिसे फीचर-रिच, तेज़ और एक्सटेंडेबल बनाने के लिए डिज़ाइन किया गया है। Puter का उपयोग आप निम्नलिखित चीजों के लिए कर सकते हैं:
- एक प्राइवेसी-फर्स्ट पर्सनल क्लाउड, जो आपकी सभी फाइलों, ऐप्स और गेम्स को एक सेफ जगह पर रखता है, जिसे आप कहीं से भी कभी भी एक्सेस कर सकते हैं।
- वेबसाइट्स, वेब ऐप्स और गेम्स बनाने और पब्लिश करने का एक प्लेटफ़ॉर्म।
- Dropbox, Google Drive, OneDrive आदि का एक शानदार और पावरफुल इंटरफ़ेस वाला विकल्प।
- सर्वर और वर्कस्टेशन के लिए एक रिमोट डेस्कटॉप एनवायरनमेंट।
- एक फ्रेंडली ओपन-सोर्स प्रोजेक्ट और कम्युनिटी, जहां आप वेब डेवलपमेंट, क्लाउड कंप्यूटिंग, डिस्ट्रीब्यूटेड सिस्टम्स और बहुत कुछ सीख सकते हैं।
<br/>
## शुरुआत कैसे करें?
### 💻 लोकल डेवलपमेंट
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
✨ यह Puter को
<font color="red"> http://puter.localhost:4100 </font> (या अगले उपलब्ध पोर्ट) पर लॉन्च करेगा।
अगर यह काम नहीं करता, तो [First Run Issues](./doc/self-hosters/first-run-issues.md) देखें।
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
✨ यह Puter को
<font color="red"> http://puter.localhost:4100</font> (या अगले उपलब्ध पोर्ट) पर लॉन्च करेगा।
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
✨ यह <font color="red"> http://puter.localhost:4100 </font>
(या अगले उपलब्ध पोर्ट) पर उपलब्ध होगा।
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
✨ यह Puter को
<font color="red"> http://puter.localhost:4100 (or the next available port). </font> (या अगले उपलब्ध पोर्ट) पर लॉन्च करेगा।
<br/>
### 🚀 सेल्फ-होस्टिंग
सेल्फ-होस्टिंग के लिए विस्तृत गाइड, कॉन्फ़िगरेशन ऑप्शन्स और बेस्ट प्रैक्टिसेज जानने के लिए हमारी [Self-Hosting Documentation](https://github.com/HeyPuter/puter/blob/main/doc/self-hosters/instructions.md) देखें।
<br/>
### ☁️ Puter.com
Puter [**puter.com**](https://puter.com) पर एक होस्टेड सर्विस के रूप में भी उपलब्ध है।
<br/>
## सिस्टम आवश्यकताएँ
* **ऑपरेटिंग सिस्टम्स:** Linux, macOS, Windows
* **RAM:** कम से कम 2GB (4GB रिकमेंडेड)
* **डिस्क स्पेस:** 1GB फ्री स्पेस
* **Node.js:** वर्जन 16+ (वर्जन 23+ रिकमेंडेड)
* **npm:** लेटेस्ट स्टेबल वर्जन
<br/>
## सपोर्ट
नीचे दिए गए माध्यमों से आप मेंटेनर्स और कम्युनिटी से जुड़ सकते हैं:
* बग रिपोर्ट या फीचर रिक्वेस्ट? [यहाँ issue खोलें](https://github.com/HeyPuter/puter/issues/new/choose)।
* Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
* X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
* Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
* Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
* सिक्योरिटी इशूज़? [[email protected]](mailto:[email protected])
* ईमेल करें: [[email protected]](mailto:[email protected])
आपके किसी भी सवाल में मदद करने के लिए हम हमेशा तैयार हैं!
<br/>
## लाइसेंस
यह रिपॉज़िटरी और इसके सभी कंटेंट्स [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) लाइसेंस के अंतर्गत आते हैं जब तक कि कुछ और स्पष्ट रूप से ना लिखा हो। इसमें शामिल थर्ड-पार्टी लाइब्रेरीज़ अपने-अपने लाइसेंस के अधीन हो सकती हैं।
<br/>
## अनुवाद
Puter के डॉक्यूमेंटेशन कई भाषाओं में उपलब्ध हैं, जिनमें शामिल हैं:
- [Arabic / العربية](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ar.md)
- [Armenian / Հայերեն](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hy.md)
- [Bengali / বাংলা](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.bn.md)
- [Chinese / 中文](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.zh.md)
- [Danish / Dansk](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.da.md)
- [English](https://github.com/HeyPuter/puter/blob/main/README.md)
- [Farsi / فارسی](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fa.md)
- [Finnish / Suomi](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fi.md)
- [French / Français](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fr.md)
- [German/ Deutsch](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.de.md)
- [Hebrew/ עברית](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.he.md)
- [Hindi / हिंदी](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hi.md)
- [Hungarian / Magyar](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hu.md)
- [Indonesian / Bahasa Indonesia](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.id.md)
- [Italian / Italiano](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.it.md)
- [Japanese / 日本語](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.jp.md)
- [Korean / 한국어](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ko.md)
- [Malayalam / മലയാളം](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ml.md)
- [Polish / Polski](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pl.md)
- [Portuguese / Português](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pt.md)
- [Romanian / Română](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ro.md)
- [Russian / Русский](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ru.md)
- [Spanish / Español](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.es.md)
- [Swedish / Svenska](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.sv.md)
- [Tamil / தமிழ்](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ta.md)
- [Telugu / తెలుగు](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.te.md)
- [Thai / ไทย](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.th.md)
- [Turkish / Türkçe](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.tr.md)
- [Ukrainian / Українська](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ua.md)
- [Urdu / اردو](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ur.md)
- [Vietnamese / Tiếng Việt](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.vi.md)
+128
View File
@@ -0,0 +1,128 @@
<h3 align="center"><img width="80" alt="Puter.com, A személyi felhő számítógép: Minden fájl, alkalmazás és játék egy helyen elérhető bárhonnan, bármikor." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Az internetes oprendszer! Ingyenes, nyílt-forráskódú, saját szerveren futtatható.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« ÉLŐ DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
A Puter egy fejlett, nyílt forráskódú internetes operációs rendszer, amelyet úgy terveztek, hogy funkciókban gazdag, kivételesen gyors és nagymértékben bővíthető legyen. A Puter a következőképpen használható:
- Egy adatvédelmet előtérbe helyező személyes felhő, amely minden fájlt, alkalmazást és játékot egy biztonságos helyen tart. Bárhonnan és bármikor elérhető.
- Egy platform weboldalak, web-appok, és játékok készítéséhez/közzétételéhez.
- A Dropbox, Google Drive, OneDrive (stb.) alternatívája megújult felülettel és hatékony funkciókkal.
- Egy távoli desktop-környezet szervereknek és workstation-öknek.
- Egy barátságos, nyílt forráskódú projekt és közösség, amely a webfejlesztéssel, a felhőalapú számítástechnikával, elosztott rendszerekkel és sok más érdekes témával foglalkozik!
<br/>
## Első lépések
### 💻 Helyi (lokális) fejlesztés
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Ezzel a http://puter.localhost:4100 -on futtatjuk Putert. (vagy a legközelebbi elérhető porton).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
A Puter elérhető hostolt szolgáltatásként a [**puter.com**](https://puter.com) címen.
<br/>
## Rendszerkövetelmények
- **Operációs rendszerek:** Linux, macOS, Windows
- **RAM:** 2GB minimum (4GB ajánlott)
- **Tárhely:** 1GB szabad tárhely
- **Node.js:** 16+ (22+ verzió ajánlott)
- **npm:** legújabb stabil verzió
<br/>
## Támogatás
Lépj kapcsolatba a fejlesztőkkel és a közösséggel az alábbi platformokon:
- Észrevételeid/javaslataid vannak? Az [alábbi linken](https://github.com/HeyPuter/puter/issues/new/choose) megoszthatod velünk.
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Biztonsági hibák? [[email protected]](mailto:[email protected])
- A fejlesztőket a [[email protected]](mailto:[email protected]) email címen érheted el.
Mindig örömmel segítünk bármilyen felmerülő kérdésben. Bátran kérdezz tőlünk!
<br/>
## License
Ez a repo, beleértve annak minden tartalmát, alprojektjeit, moduljait és komponenseit, az [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) licenc alatt áll, hacsak másképp nem rendelkeznek róla. A repoban szereplő harmadik fél által fejlesztett könyvtárak saját licencfeltételek alá eshetnek.
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Ինտերնետ ՕՀ! Անվճար, բաց կոդով և ինքնահոսթ հնարավորությամբ։</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« Օնլայն դեմո »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter-ը առաջադեմ, բաց կոդով ինտերնետային օպերացիոն համակարգ է, որը նախագծված է լինել ֆունկցիոնալ հարուստ, բացառիկ արագ և բարձր ընդլայնելի։ Puter-ը կարող է օգտագործվել հետևյալ կերպ․
- Անձնական ամպային համակարգ՝ առաջնային գաղտնիությամբ, որը թույլ է տալիս պահել ձեր բոլոր ֆայլերը, հավելվածները և խաղերը մեկ անվտանգ վայրում, որը հասանելի է ցանկացած վայրից և ցանկացած ժամանակ։
- Պլատֆորմ կայքերի, վեբ հավելվածների և խաղերի ստեղծման և հրապարակման համար։
- Dropbox, Google Drive, OneDrive և այլ ծառայությունների այլընտրանք՝ նոր ինտերֆեյսով և հզոր գործառույթներով։
- Հեռավոր աշխատասեղանի միջավայր սերվերների և աշխատանքային կայանների համար։
- Պարզ, բաց կոդով նախագիծ և համայնք՝ վեբ ծրագրավորման, ամպային հաշվարկների, բաշխված համակարգերի և այլ թեմաների մասին սովորելու համար։
<br/>
## Սկսել
### 💻 Լոկալ ծրագրավորում
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Սա կգործակի Puter-ը հետևյալ հասցեով՝ http://puter.localhost:4100 (կամ հաջորդ հասանելի պորտով)։
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter-ը հասանելի է որպես հյուրընկալվող ծառայություն [**puter.com**](https://puter.com).
<br/>
## System Requirements
- **Օպերացիոն համակարգ:** Linux, macOS, Windows
- **Օպերատիվ հիշողություն:** 2GB նվազագույնը (4GB խորհուրդ է տրվում)
- **Համակարգչի հիշողություն:** 1GB ազատ տարածություն
- **Node.js:** Տարբերակ 16+ (Տարբերակ 22+ խորհուրդ է տրվում)
- **npm:** Վերջին կայուն տարբերակը
<br/>
## Աջակցություն
Կապվեք համակարգողների և համայնքի հետ այս կայքերի միջոցով՝
- Սխալների կամ գործառույթի հարցում՝ (https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Անվտանգության խնդիրներ՝ [[email protected]](mailto:[email protected])
- Email maintainers at [[email protected]](mailto:[email protected])
Մենք միշտ ուրախ ենք օգնել ձեզ ցանկացած հարցում։ Մի կաշկանդվեք հարցնել։
<br/>
## Լիցենզիա
Այս պահոցարանը, ներառյալ բոլոր իր բովանդակությունը, ենթա-պրոյեկտները, մոդուլները և բաղադրիչները, լիցենզավորվում են [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) լիցենզիայի տակ, եթե այլ կերպ հստակ նշված չէ։ Այս պահոցարանում ներառված երրորդ կողմի գրադարանները կարող են ենթարկվել իրենց սեփական լիցենզիաներին։
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, Komputer Cloud Pribadi: Semua file, aplikasi, dan permainan Anda berada di satu tempat yang dapat diakses dari mana saja kapan saja." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Sistem Operasi Internet! Gratis, Sumber Terbuka, dan Dapat Dihosting Sendiri.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter adalah sistem operasi internet canggih, open-source, yang dirancang untuk menjadi kaya fitur, sangat cepat, dan sangat dapat diperluas. Puter dapat digunakan sebagai:
- Cloud pribadi yang mengutamakan privasi untuk menyimpan semua file, aplikasi, dan permainan Anda di satu tempat yang aman, yang dapat diakses dari mana saja kapan saja.
- Platform untuk membangun dan mempublikasikan situs web, aplikasi web, dan permainan.
- Alternatif untuk Dropbox, Google Drive, OneDrive, dll. Dengan antarmuka baru dan fitur-fitur canggih.
- Lingkungan desktop jarak jauh untuk server dan workstation.
- Proyek dan komunitas open-source yang ramah untuk belajar tentang pengembangan web, komputasi gemawan (cloud), sistem terdistribusi, dan banyak lagi!
<br/>
## Memulai
### 💻 Pengembangan Lokal
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Ini akan menjalankan Puter di http://puter.localhost:4100 (atau di port berikutnya yang tersedia)
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter tersedia sebagai layanan yang telah dihosting di [**puter.com**](https://puter.com).
<br/>
## Persyaratan Sistem
- **Sistem Operasi:** Linux, macOS, Windows
- **RAM:** 2GB minimal (rekomendasi 4GB)
- **Penyimpanan:** 1GB ruang tersedia
- **Node.js:** Version 16+ (rekomendasi versi 22+)
- **npm:** Versi stabil termutakhir
<br/>
## Dukuangan
Terhubung dengan maintainer dan komunitas melalui saluran-saluran berikut:
- Laporan bug atau permintaan fitur? Silakan [buat issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Isu keamanan? [[email protected]](mailto:[email protected])
- Email pengelola di [[email protected]](mailto:[email protected])
Kami selalu senang membantu Anda dengan pertanyaan apa pun yang Anda miliki. Jangan ragu untuk bertanya!
<br/>
## Lisensi
Repositori ini, termasuk semua isinya, sub-proyek, modul, dan komponen, dilisensikan di bawah [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) kecuali dinyatakan sebaliknya secara eksplisit. Perpustakaan pihak ketiga yang termasuk dalam repositori ini mungkin tunduk pada lisensinya sendiri.
<br/>
+128
View File
@@ -0,0 +1,128 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Il sistema operativo di Internet! Gratuito, Open-Source e Auto-Hostabile.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter è un sistema operativo di Internet avanzato e open-source, progettato per essere ricco di funzionalità, eccezionalmente veloce e altamente estensibile. Puter può essere utilizzato come:
- Un cloud personale che tiene conto della privacy per conservare tutti i file, le app e i giochi in un luogo sicuro, accessibile da qualsiasi luogo e in qualsiasi momento.
- Una piattaforma per creare e pubblicare siti web, app e giochi.
- Un'alternativa a Dropbox, Google Drive, OneDrive, ecc. con un'interfaccia nuova e funzioni potenti.
- Un ambiente desktop remoto per server e workstation.
- Un progetto e una comunità open-source amichevole per imparare lo sviluppo web, il cloud computing, i sistemi distribuiti e molto altro ancora!
<br/>
## Getting Started
### 💻 Local Development
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
In questo modo Puter verrà avviato all'indirizzo http://puter.localhost:4100 (o alla prossima porta disponibile).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter è disponibile come servizio in hosting su [**puter.com**](https://puter.com).
<br/>
## Requisiti di Sistema
- **Sistema Operativo:** Linux, macOS, Windows
- **RAM:** 2GB minimi (4GB raccomandati)
- **Spazio su Disco:** 1GB liberi
- **Node.js:** Versione 16+ (Versione 22+ raccomandati)
- **npm:** Ultima versione stabile
<br/>
## Supporto
Collegatevi con i maintainers e la comunità attraverso questi canali:
- Segnalazione di bug o richiesta di funzionalità? Perfavore [aprire una issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Problemi di sicurezza? [[email protected]](mailto:[email protected])
- Email maintainers a [[email protected]](mailto:[email protected])
Siamo sempre felici di aiutarvi con qualsiasi domanda. Non esitate a chiedere!
<br/>
## Licenza
Questo repository, compresi tutti i suoi contenuti, sottoprogetti, moduli e componenti, è concesso in licenza [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt), a meno che non sia esplicitamente indicato diversamente. Le librerie di terze parti incluse in questo repository possono essere soggette alle loro licenze.
<br/>
+123
View File
@@ -0,0 +1,123 @@
<h3 align="center"><img width="80" alt="Puter.com, あなたのファイル、アプリ、ゲームをどこからでもアクセス可能にするパーソナルクラウドコンピュータ" src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">インターネットOS!無料、オープンソース、セルフホスト可能。</h3>
<p align="center">
<img alt="GitHub リポジトリサイズ" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub リリース" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=%E6%9C%80%E6%96%B0%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3"> <img alt="GitHub ライセンス" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« ライブデモ »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="スクリーンショット" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puterは、機能豊富で非常に高速、そして高い拡張性を持つ、先進的なオープンソースのインターネットオペレーティングシステムです。Puterは以下の用途に利用できます:
- プライバシーを最優先するパーソナルクラウドとして、あなたのファイル、アプリ、ゲームを一か所で安全に管理し、どこからでもアクセス可能に。
- ウェブサイト、ウェブアプリ、ゲームの作成と公開のためのプラットフォーム。
- Dropbox、Google Drive、OneDriveなどの代替として、新しいインターフェースと強力な機能を提供。
- サーバーやワークステーションのためのリモートデスクトップ環境。
- ウェブ開発、クラウドコンピューティング、分散システムなどを学ぶための、フレンドリーでオープンなコミュニティとプロジェクト。
<br/>
## はじめに
### 💻 ローカル開発
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
これでPuterが http://puter.localhost:4100 (または次に利用可能なポート)で起動します。
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puterは[**puter.com**](https://puter.com)でホストサービスとして利用可能です。
<br/>
## システム要件
- **オペレーティングシステム:** Linux, macOS, Windows
- **RAM:** 最小2GB(推奨4GB)
- **ディスクスペース:** 1GBの空き容量
- **Node.js:** バージョン16以上(推奨バージョン22以上)
- **npm:** 最新の安定バージョン
<br/>
## サポート
メンテナーやコミュニティと以下のチャンネルを通じてつながりましょう:
- バグ報告や機能リクエストは [新規Issue](https://github.com/HeyPuter/puter/issues/new/choose) まで
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- セキュリティの問題? [[email protected]](mailto:[email protected])
- メンテナーへのメールは [[email protected]](mailto:[email protected]) まで
質問があれば、いつでもお気軽にお問い合わせください!
<br/>
## ライセンス
このリポジトリ、ならびにそのすべてのコンテンツ、サブプロジェクト、モジュール、コンポーネントは、[AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt)の下でライセンスされています。明示的に異なるライセンスが示されている場合を除きます。このリポジトリに含まれるサードパーティのライブラリは、それぞれのライセンスが適用される場合があります。
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Puter: 인터넷 OS! 무료이고 오픈소스이며 자체 호스팅이 가능합니다.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« 시연 영상 »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter는 오픈소스 인터넷 운영 체제로, 매우 빠르고 확장성이 뛰어나며 새로운 인터페이스와 다양한 기능을 갖추고 있습니다. Puter는 다음과 같이 사용될 수 있습니다:
- 모든 파일, 앱, 게임을 한 곳에 안전하게 보관하고 언제 어디서나 접근할 수 있는 프라이버시 중심의 개인 클라우드로 사용할 수 있습니다.
- 웹사이트, 웹 앱, 게임을 구축하고 배포하는 플랫폼으로 활용할 수 있습니다.
- Dropbox, Google Drive, OneDrive 등의 대안으로 사용할 수 있으며 보다 발전된 기능과 인터페이스를 제공합니다.
- 서버와 워크스테이션을 위한 원격 데스크톱 환경으로 활용할 수 있습니다.
- 웹 개발, 클라우드 컴퓨팅, 분산 시스템 등에 대해 배울 수 있는 친근한 오픈소스 프로젝트이자 커뮤니티입니다!
<br/>
## 시작하기
### 💻 로컬 환경 개발
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
위처럼 실행할 시 Puter는 http://puter.localhost:4100 (또는 사용 가능한 다음 포트)에서 실행됩니다.
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter는 [**puter.com**](https://puter.com)에서 호스팅 서비스로 이용할 수 있습니다.
<br/>
## 시스템 요구사항
- **Operating Systems:** Linux, macOS, Windows
- **RAM:** 2GB minimum (4GB recommended)
- **Disk Space:** 1GB free space
- **Node.js:** Version 16+ (Version 22+ recommended)
- **npm:** Latest stable version
<br/>
## 지원
다음 채널을 통해 관리자 및 커뮤니티와 소통하세요:
- 버그 신고나 기능 요청이 있으신가요? [이슈를 열어주세요.](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- 보안 관련 문제는 [[email protected]](mailto:[email protected]) 으로 연락주세요.
- 관리자에게 이메일 보내기: [[email protected]](mailto:[email protected])
어떤 질문이든 기꺼이 도와드리겠습니다. 언제든 물어보세요!
<br/>
## 라이선스
이 저장소는 모든 내용, 하위 프로젝트, 모듈 및 구성 요소를 포함하여 명시적으로 달리 명시되지 않는 한 [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) 라이선스 하에 제공됩니다. 이 저장소에 포함된 제3자 라이브러리는 해당 라이브러리의 고유 라이선스를 따를 수 있습니다.
<br/>
+128
View File
@@ -0,0 +1,128 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">ഇന്റർനെറ്റ് ഓപ്പറേറ്റിംഗ് സിസ്റ്റം!<br> സൗജന്യവും, ഓപ്പൺ സോഴ്സും സ്വയം ഹോസ്റ്റ് ചെയ്യാൻ പറ്റുന്നതും</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« ലൈവ് ഡെമോ »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## പ്യൂട്ടർ (Puter)
ഫീച്ചറുകളാൽ സമ്പുഷ്ടവും അസാധാരണമാംവിധം വേഗതയേറിയതും,വളരെ വിപുലീകരിക്കാവുന്നതുമായ ഒരു നൂതന, ഓപ്പൺ സോഴ്‌സ് ഇന്റർനെറ്റ് ഓപ്പറേറ്റിംഗ് സിസ്റ്റമാണ് പ്യൂട്ടർ. പ്യൂട്ടർ ഇനിപ്പറയുന്ന രീതിയിൽ ഉപയോഗിക്കാം:
- നിങ്ങളുടെ എല്ലാ ഫയലുകളും ആപ്പുകളും ഗെയിമുകളും ഒരു സുരക്ഷിത സ്ഥലത്ത് സൂക്ഷിക്കുന്നതിനുള്ള, സ്വകാര്യതയ്ക്ക് മുൻഗണന കൊടുക്കുന്ന ആദ്യത്തെ വ്യക്തിഗത ക്ലൗഡ്, എവിടെ നിന്നും എപ്പോൾ വേണമെങ്കിലും ആക്‌സസ് ചെയ്യാൻ കഴിയും.
- വെബ്‌സൈറ്റുകൾ, വെബ് ആപ്പുകൾ, ഗെയിമുകൾ എന്നിവ നിർമ്മിക്കുന്നതിനും പ്രസിദ്ധീകരിക്കുന്നതിനുമുള്ള ഒരു പ്ലാറ്റ്ഫോം.
- പുതിയ ഇന്റർഫേസും, ശക്തമായ ഫീച്ചറുകളും അടങ്ങിയ, ഡ്രോപ്പ്‌ബോക്‌സ്, ഗൂഗിൾ ഡ്രൈവ്, വൺഡ്രൈവ് മുതലായവയ്‌ക്കുള്ള ബദൽ.
- സെർവറുകൾക്കും വർക്ക്സ്റ്റേഷനുകൾക്കും, ഒരു വിദൂര ഡെസ്ക്ടോപ്പ് പരിസ്ഥിതി.
- വെബ് ഡെവലപ്മെന്റ്, ക്ലൗഡ് കംപ്യൂട്ടിംഗ്, ഡിസ്ട്രിബ്യൂട്ടഡ് സിസ്റ്റങ്ങൾ എന്നിവയെ കുറിച്ചും, അതിലേറെ കാര്യങ്ങളെ കുറിച്ചും അറിയാനുള്ള സൗഹൃദപരവും ഓപ്പൺ സോഴ്സുമായ പ്രോജക്റ്റും കമ്മ്യൂണിറ്റിയും!
<br/>
## തുടങ്ങാനായി
### 💻 ലോക്കൽ ഡെവലപ്മെന്റ്
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
ഇത് http://puter.localhost:4100 (അല്ലെങ്കിൽ അടുത്ത ലഭ്യമായ പോർട്ടിൽ) എന്നതിൽ Puter സമാരംഭിക്കും
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
പ്യൂട്ടർ [**puter.com**](https://puter.com) എന്നതിൽ ഹോസ്റ്റ് ചെയ്‌ത സേവനമായി ലഭ്യമാണ്.
<br/>
## സിസ്റ്റത്തിന്റെ ആവശ്യകതകൾ
- **ഓപ്പറേറ്റിംഗ് സിസ്റ്റങ്ങൾ:** ലിനക്സ്, മാക്ക് ഒഎസ്, വിൻഡോസ്
- **RAM:** 2GB കുറഞ്ഞത് (4GB ശുപാർശ ചെയ്യുന്നു)
- **ഡിസ്ക് സ്പേസ്:** 1GB ഒഴിഞ്ഞ ഇടം
- **Node.js:** Version 16+ (Version 22+ ശുപാർശ ചെയ്യുന്നു)
- **npm:** ഏറ്റവും പുതിയ സ്ഥിരതയുള്ള പതിപ്പ്
<br/>
## പിന്തുണ
ഈ ചാനലുകളിലൂടെ പരിപാലിക്കുന്നവരുമായും കമ്മ്യൂണിറ്റിയുമായും ബന്ധപ്പെടുക:
- ബഗ്ഗ് റിപ്പോർട്ടോ, ഫീച്ചർ റിക്ക്വസ്റ്റോ ഉണ്ടോ? ദയവുചെയ്ത് [ഒരു ഇഷ്യൂ തുടങ്ങുക](https://github.com/HeyPuter/puter/issues/new/choose).
- ഡിസ്കോർഡ്: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- എക്സ് (ട്വിറ്റർ): [x.com/HeyPuter](https://x.com/HeyPuter)
- റെഡ്ഡിറ്റ്: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- മാസ്റ്റഡൺ: [mastodon.social/@puter](https://mastodon.social/@puter)
- സുരക്ഷാ പ്രശ്നങ്ങളുണ്ടോ? [[email protected]](mailto:[email protected])
- ഇമെയിൽ മെയിന്റൈനർമാർ: [[email protected]](mailto:[email protected])
നിങ്ങൾക്ക് ഉണ്ടായേക്കാവുന്ന ഏത് ചോദ്യങ്ങളിലും നിങ്ങളെ സഹായിക്കുന്നതിൽ ഞങ്ങൾക്ക് എപ്പോഴും സന്തോഷമുണ്ട്. ചോദിക്കാൻ മടിക്കേണ്ട!
<br/>
## ലൈസൻസ്
ഈ ശേഖരം, അതിന്റെ എല്ലാ ഉള്ളടക്കങ്ങളും, ഉപപദ്ധതികളും, മൊഡ്യൂളുകളും, ഘടകങ്ങളും ഉൾപ്പെടെ, [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) എന്നതിന് കീഴിൽ ലൈസൻസുള്ളതാണ്. ഈ ശേഖരത്തിൽ ഉൾപ്പെടുത്തിയിരിക്കുന്ന മൂന്നാം കക്ഷി ലൈബ്രറികൾ അവരുടെ സ്വന്തം ലൈസൻസുകൾക്ക് വിധേയമായിരിക്കാം.
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: Semua fail, apl, dan permainan anda di satu tempat yang boleh diakses dari mana sahaja pada bila-bila masa." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Sistem Operasi Internet! Percuma, Sumber Terbuka, dan Boleh Dihoskan Sendiri.</h3>
<p align="center">
<img alt="Saiz repo GitHub" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="Terbitan GitHub" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="Lesen GitHub" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« DEMO SECARA LANGSUNG »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter ialah sistem operasi internet sumber terbuka yang maju dan direka untuk kaya dengan ciri kefungsian, kepantasan luar biasa dan kebolehluasan yang tinggi. Puter boleh digunakan sebagai:
- Storan awan peribadi yang mendahulukan privasi untuk menyimpan semua fail, aplikasi dan permainan anda di satu tempat yang selamat dan boleh diakses dari mana sahaja pada bila-bila masa.
- Platform untuk membina dan menerbitkan laman web, aplikasi web dan permainan.
- Alternatif kepada Dropbox, Google Drive, OneDrive, dan lain-lain dengan antara muka yang baharu dan ciri kefungsian berkuasa tinggi.
- Persekitaran desktop awan untuk server dan stesen kerja.
- Projek dan komuniti sumber terbuka yang mesra untuk mempelajari pembangunan laman web, pengkomputeran awan, sistem teragih, dan banyak lagi!
<br/>
## Mulakan
### 💻 Pembangunan Lokal
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Ini akan melancarkan Puter di http://puter.localhost:4100 (atau port seterusnya yang tersedia).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter tersedia sebagai perkhidmatan terhos di [**puter.com**](https://puter.com).
<br/>
## Keperluan Sistem
- **Sistem Operasi:** Linux, macOS, Windows
- **RAM:** Minimum 2GB (sebaiknya 4GB)
- **Ruang Storan:** 1GB ruang kosong
- **Node.js:** Versi 16+ (sebaiknya Versi 22+)
- **npm:** Versi stabil yang terkini
<br/>
## Sokongan
Berhubung dengan penyelenggara dan komuniti melalui saluran berikut:
- Laporan pepijat atau permintaan ciri? Sila [buka isu baharu](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Isu keselamatan? [[email protected]](mailto:[email protected])
- Emel penyelenggara melalui [[email protected]](mailto:[email protected])
Kami sentiasa gembira untuk membantu anda dengan apa-apa soalan. Jangan takut untuk bertanya!
<br/>
## Lesen
Repositori ini, termasuklah kandungannya, subprojek, modul dan komponen, dilesenkan di bawah [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) melainkan dinyatakan sebaliknya. *Library* pihak ketiga yang terkandung dalam repositori ini tertakluk kepada lesen mereka sendiri.
<!-- The word `Library` is kept as is to avoid confusion since the direct translation `Perpustakaan/Pustaka` is never used in the tech context and doesn't convey the same meaning among Malay community if used in this situation -->
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, De Persoonlijke Cloud Computer: Al je bestanden, apps en games op één plek, overal en altijd toegankelijk." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Het Internet OS! Gratis, Open-Source en Zelf te Hosten.</h3>
<p align="center">
<img alt="GitHub repo grootte" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=laatste%20versie"> <img alt="GitHub Licentie" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter is een geavanceerd, open-source internetbesturingssysteem ontworpen om functierijk, uitzonderlijk snel en zeer uitbreidbaar te zijn. Puter kan worden gebruikt als:
- Een privacy-gerichte persoonlijke cloud om al je bestanden, apps en games op één veilige plek te bewaren, overal en altijd toegankelijk.
- Een platform voor het bouwen en publiceren van websites, web-apps en games.
- Een alternatief voor Dropbox, Google Drive, OneDrive, etc. met een frisse interface en krachtige functies.
- Een externe desktopomgeving voor servers en werkstations.
- Een vriendelijk, open-source project en gemeenschap om te leren over webontwikkeling, cloud computing, gedistribueerde systemen en veel meer!
<br/>
## Aan de slag
### 💻 Lokale Ontwikkeling
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Dit zal Puter starten op http://puter.localhost:4100 (of de eerstvolgende beschikbare poort).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter is beschikbaar als een gehoste service op [**puter.com**](https://puter.com).
<br/>
## Systeemvereisten
- **Besturingssystemen:** Linux, macOS, Windows
- **RAM:** 2GB minimum (4GB aanbevolen)
- **Schijfruimte:** 1GB vrije ruimte
- **Node.js:** Versie 16+ (Versie 22+ aanbevolen)
- **npm:** Laatste stabiele versie
<br/>
## Ondersteuning
Verbind met de onderhouders en de gemeenschap via deze kanalen:
- Bug rapport of functieverzoek? [Open een issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Beveiligingsproblemen? [[email protected]](mailto:[email protected])
- E-mail onderhouders op [[email protected]](mailto:[email protected])
We helpen je graag met al je vragen. Aarzel niet om te vragen!
<br/>
## Licentie
Deze repository, inclusief alle inhoud, subprojecten, modules en componenten, is gelicentieerd onder [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) tenzij expliciet anders vermeld. Bibliotheken van derden die in deze repository zijn opgenomen, kunnen onderworpen zijn aan hun eigen licenties.
<br/>
+148
View File
@@ -0,0 +1,148 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">ଇଣ୍ଟରନେଟ OS! ନିଶୁଳ୍କ, ଖୋଲା-ମୂଳ (Open-Source), ଏବଂ ସ୍ୱୟଂ-ହୋଷ୍ଟ କରିପାରିବା।</h3>
<p align="center">
<a href="https://puter.com/?ref=github.com"><strong>« LIVE ଡେମୋ »</strong></a>
<br />
<br />
<a href="https://puter.com/?ref=github.com">Puter.com</a>
·
<a href="https://apps.puter.com/">App Store</a>
·
<a href="https://developer.puter.com" target="_blank">Developers</a>
·
<a href="https://github.com/heyputer/puter-cli" target="_blank">CLI</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter ହେଉଛି ଗୋଟିଏ ଉନ୍ନତ, ଖୋଲା-ମୂଳ ଇଣ୍ଟରନେଟ ଅପରେଟିଂ ସିଷ୍ଟମ, ଯାହାକି ବିଶେଷତାସମୃଦ୍ଧ, ଶୀଘ୍ର ଏବଂ ଏକ୍ସଟେନ୍ସିବଲ ଭାବେ ଡିଜାଇନ୍ କରାଯାଇଛି। Puter କୁ ନିମ୍ନ ପ୍ରକାରେ ବ୍ୟବହାର କରିପାରିବେ:
- ଗୋଟିଏ ପ୍ରାଇଭେସି-ପ୍ରଥମ (privacy-first) ପର୍ସନାଲ କ୍ଲାଉଡ୍ ଭାବେ — ଯେଉଁଠାରେ ଆପଣଙ୍କ ସମସ୍ତ ଫାଇଲ୍, ଆପ୍ସ ଏବଂ ଗେମ୍ସ ଗୋଟିଏ ସୁରକ୍ଷିତ ସ୍ଥାନରେ ରହିବ, ଯାହାକୁ କେଉଁଠୁ ସମୟରେ ଆକ୍ସେସ୍ କରିପାରିବେ।
- ୱେବସାଇଟ୍, ୱେବ ଆପ୍ସ, ଏବଂ ଗେମ୍ ତିଆରି ଏବଂ ପ୍ରକାଶ ପାଇଁ ଗୋଟିଏ ପ୍ଲାଟଫର୍ମ।
- Dropbox, Google Drive, OneDrive ଇତ୍ୟାଦିଙ୍କ ବିକଳ୍ପ ଭାବେ — ଏକ ସୁନ୍ଦର ଇଣ୍ଟରଫେସ୍ ଏବଂ ଶକ୍ତିଶାଳୀ ବୈଶିଷ୍ଟ ସହିତ।
- ସର୍ଭର ଏବଂ ଓର୍କସ୍ଟେସନ୍ ପାଇଁ ଗୋଟିଏ ରିମୋଟ୍ ଡେସ୍କଟପ୍ ଇନ୍ଭାୟରମେଣ୍ଟ।
- ୱେବ୍ ଡିଭେଲପମେଣ୍ଟ, କ୍ଲାଉଡ୍ କମ୍ପ୍ୟୁଟିଙ୍ଗ, ବିତରିତ ସିଷ୍ଟମ (distributed systems) ଇତ୍ୟାଦି ଶିଖିବା ପାଇଁ ଗୋଟିଏ ସହଜ-ମନୋଭାବୀ ଖୋଲା-ମୂଳ ସମୁଦାୟ।
<br/>
## ପ୍ରାରମ୍ଭ (Getting Started)
### 💻 Local Development
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
**→** ଏହା Puter କୁ ଲଞ୍ଚ କରିବ:
<font color="red"> http://puter.localhost:4100 (ଅଥବା ଅନ୍ୟ ଉପଲବ୍ଧ ପୋର୍ଟ୍) </font>
ଯଦି ଏହା କାମ କରୁନାହିଁ, ତେବେ [First Run Issues](./doc/self-hosters/first-run-issues.md) କୁ ଦେଖନ୍ତୁ।
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
**→** ଏହା Puter କୁ ଲଞ୍ଚ କରିବ:
<font color="red"> http://puter.localhost:4100 (ଅଥବା ଅନ୍ୟ ଉପଲବ୍ଧ ପୋର୍ଟ୍) </font>
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
**→** ଏହା ଉପଲବ୍ଧ ହେବ:
<font color="red"> http://puter.localhost:4100 (ଅଥବା ଅନ୍ୟ ଉପଲବ୍ଧ ପୋର୍ଟ୍) </font>
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
**→** ଏହା Puter କୁ ଲଞ୍ଚ କରିବ:
<font color="red"> http://puter.localhost:4100 (ଅଥବା ଅନ୍ୟ ଉପଲବ୍ଧ ପୋର୍ଟ୍) </font>
<br/>
### 🚀 Self-Hosting
Self-Hosting ପାଇଁ ବିସ୍ତୃତ ଗାଇଡ୍, କନଫିଗୁରେସନ୍ ଅପ୍ସନ୍ ଏବଂ ବେଷ୍ଟ-ପ୍ରାକ୍ଟିସ୍ ପାଇଁ ଏଠାରେ ଯାଆନ୍ତୁ:
[Self-Hosting Documentation](https://github.com/HeyPuter/puter/blob/main/doc/self-hosters/instructions.md)
<br/>
### ☁️ Puter.com
Puter ହୋଷ୍ଟେଡ୍ ସର୍ଭିସ୍ ଭାବେ ଉପଲବ୍ଧ ଅଛି: [**puter.com**](https://puter.com)
<br/>
## ସିଷ୍ଟମ ଆବଶ୍ୟକତା (System Requirements)
- **Operating Systems:** Linux, macOS, Windows
- **RAM:** ଅନ୍ୟୁନ 2GB (ପରାମର୍ଶ 4GB)
- **Disk Space:** 1GB ଖାଲି ସ୍ଥାନ
- **Node.js:** ସଂସ୍କରଣ 20.19.5+ (ପରାମର୍ଶ 23+)
- **npm:** ନବୀନତମ ସ୍ଥିର ସଂସ୍କରଣ
<br/>
## ସହଯୋଗ (Support)
ମେଣ୍ଟେନର୍ ଏବଂ ସମୁଦାୟ ସହିତ ଯୋଡ଼ିବା ପାଇଁ:
- Bug report କିମ୍ବା ନୂଆ feature ବାବଦରେ? [open an issue](https://github.com/HeyPuter/puter/issues/new/choose)
- Discord: https://discord.com/invite/PQcx7Teh8u
- X (Twitter): https://x.com/HeyPuter
- Reddit: https://www.reddit.com/r/puter/
- Mastodon: https://mastodon.social/@puter
- Security issues? [[email protected]](mailto:[email protected])
- Maintain­er Email: [[email protected]](mailto:[email protected])
ଆମେ ସମସ୍ତେ ସହାୟତା ପାଇଁ ସଦା ପ୍ରସ୍ତୁତ।
<br/>
## ଲାଇସେନ୍ସ (License)
ଏହି ରିପୋଜିଟୋରୀ, ସମସ୍ତ ସବ୍-ପ୍ରୋଜେକ୍ଟ, ମୋଡ୍ୟୁଲ୍ ଏବଂ କମ୍ପୋନେଣ୍ଟ ସହିତ **AGPL-3.0** ଲାଇସେନ୍ସ ଅଧୀନରେ ରହିଛି।
ତୃତୀୟ ପକ୍ଷ ଲାଇବ୍ରେରି ନିଜସ୍ୱ ଲାଇସେନ୍ସ ଅଧୀନରେ ଥାଇପାରେ।
<br/>
## ଅନ୍ୟ README ଲିଙ୍କ୍ (Links to Other READMEs)
### Backend
- [PuterAI Module](./src/backend/doc/modules/puterai/README.md)
- [Metering Service](./src/backend/src/services/MeteringService/README.md)
- [Extensions Development Guide](./extensions/README.md)
+182
View File
@@ -0,0 +1,182 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">ਇੰਟਰਨੇਟ ਓਐਸ! ਮੁਫ਼ਤ, ਖੁੱਲ੍ਹੇ ਸਰੋਤ ਵਾਲਾ, ਅਤੇ ਆਪ ਸਵੈ-ਹੋਸਟ ਕਰ ਸਕਦੇ ਹੋ।</h3>
<p align="center">
<a href="https://puter.com/?ref=github.com"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com/?ref=github.com">Puter.com</a>
·
<a href="https://apps.puter.com/">ਐਪ ਸਟੋਰ</a>
·
<a href="https://developer.puter.com" target="_blank">ਡਿਵੈਲਪਰ</a>
·
<a href="https://github.com/heyputer/puter-cli" target="_blank">CLI</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter ਇੱਕ ਵਿਕਸਤ, ਖੁੱਲ੍ਹਾ-ਸਰੋਤ ਇੰਟਰਨੇਟ ਓਪਰੇਟਿੰਗ ਸਿਸਟਮ ਹੈ ਜੋ ਫੀਚਰ-ਭਰਪੂਰ, ਬਹੁਤ ਤੇਜ਼, ਅਤੇ ਵਧੀਆ ਤਰੀਕੇ ਨਾਲ ਵਧਾਏ ਜਾਣ ਵਾਲਾ ਬਣਾਇਆ ਗਿਆ ਹੈ। Puter ਇਸ ਤਰ੍ਹਾਂ ਵਰਤਿਆ ਜਾ ਸਕਦਾ ਹੈ:
- ਇੱਕ ਪਰਾਈਵੇਸੀ-ਪਹਿਲਾਂ ਨਿੱਜੀ ਕਲਾਊਡ ਵਜੋਂ ਜਿੱਥੇ ਤੁਹਾਡੀਆਂ ਸਾਰੀਆਂ ਫਾਈਲਾਂ, ਐਪਸ, ਅਤੇ ਗੇਮਜ਼ ਇੱਕ ਸੁਰੱਖਿਅਤ ਜਗ੍ਹਾ 'ਤੇ, ਕਿਸੇ ਵੀ ਸਮੇਂ-ਕਿਤੇ ਵੀ ਤੋਂ ਪਹੁੰਚਯੋਗ।
- ਵੈਬਸਾਈਟਾਂ, ਵੈਬ ਐਪਸ, ਅਤੇ ਗੇਮ ਬਣਾਉਣ ਅਤੇ ਪ੍ਰਕਾਸ਼ਿਤ ਕਰਨ ਲਈ ਇੱਕ ਪਲੇਟਫਾਰਮ।
- Dropbox, Google Drive, OneDrive ਆਦਿ ਦਾ ਇੱਕ ਆਧੁਨਿਕ ਵਿਕਲਪ, ਨਵੀਂ ਇੰਟਰਫੇਸ ਅਤੇ ਸ਼ਕਤੀਸ਼ਾਲੀ ਫੀਚਰਾਂ ਨਾਲ।
- ਸਰਵਰਾਂ ਅਤੇ ਵਰਕਸਟੇਸ਼ਨਾਂ ਲਈ ਰਿਮੋਟ ਡੈਸਕਟਾਪ Environment।
- ਵੈਬ ਡਿਵੈਲਪਮੈਂਟ, ਕਲਾਊਡ ਕੰਪਿਊਟਿੰਗ, ਡਿਸਟ੍ਰੀਬਿਊਟਡ ਸਿਸਟਮ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ ਸਿੱਖਣ ਲਈ ਇੱਕ ਮਿੱਤਰਤਾਪੂ, ਖੁੱਲ੍ਹੇ-ਸਰੋਤ ਵਾਲਾ ਪ੍ਰੋਜੈਕਟ ਅਤੇ ਸਮੂਹ!
<br/>
## Getting Started
### 💻 Local Development
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
**→** ਇਹ Puter ਨੂੰ ਇਸ ਪਤੇ 'ਤੇ ਚਲਾਉਣਾ ਚਾਹੀਦਾ ਹੈ
<font color="red"> http://puter.localhost:4100 (ਜਾਂ ਅਗਲਾ ਉਪਲਬਧ ਪੋਰਟ). </font>
ਜੇ ਇਹ ਕੰਮ ਨਹੀਂ ਕਰਦਾ, ਤਾੰ [First Run Issues](./doc/self-hosters/first-run-issues.md) ਵੇਖੋ
ਟ੍ਰਬਲਸ਼ੂਟਿੰਗ ਲਈ।
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
**→** ਇਹ Puter ਨੂੰ ਇਸ ਪਤੇ 'ਤੇ ਚਲਾਉਣਾ ਚਾਹੀਦਾ ਹੈ
<font color="red"> http://puter.localhost:4100 (ਜਾਂ ਅਗਲਾ ਉਪਲਬਧ ਪੋਰਟ). </font>
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
**→** ਇਹ ਇਸ ਪਤੇ 'ਤੇ ਉਪਲਬਧ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ
<font color="red"> http://puter.localhost:4100 (ਜਾਂ ਅਗਲਾ ਉਪਲਬਧ ਪੋਰਟ). </font>
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
**→** ਇਹ Puter ਨੂੰ ਇਸ ਪਤੇ 'ਤੇ ਚਲਾਉਣਾ ਚਾਹੀਦਾ ਹੈ
<font color="red"> http://puter.localhost:4100 (ਜਾਂ ਅਗਲਾ ਉਪਲਬਧ ਪੋਰਟ). </font>
<br/>
### 🚀 Self-Hosting
Puter ਨੂੰ ਖੁਦ ਹੋਸਟ ਕਰਨ ਲਈ, ਕਨਫਿਗੁਰੇਸ਼ਨ ਵਿਕਲਪ ਅਤੇ ਬਿਹਤਰੀਨ ਕਾਇਦੇ, ਸਾਰੇ ਵਿਸਥਾਰ ਲਈ ਸਾਡੇ [Self-Hosting Documentation](https://github.com/HeyPuter/puter/blob/main/doc/self-hosters/instructions.md) ਵੇਖੋ।
<br/>
### ☁️ Puter.com
Puter [**puter.com**](https://puter.com) 'ਤੇ ਇੱਕ ਹੋਸਟ ਕੀਤੀ ਸੇਵਾ ਵਜੋਂ ਉਪਲਬਧ ਹੈ।
<br/>
## System Requirements
- **Operating Systems:** Linux, macOS, Windows
- **RAM:** ਘੱਟੋ-ਘੱਟ 2GB (4GB ਸਿਫ਼ਾਰਸ਼ੀ)
- **Disk Space:** 1GB ਖਾਲੀ ਜਗ੍ਹਾ
- **Node.js:** Version 24+
- **npm:** ਨਵੀਨਤਮ ਸਥਿਰ ਵਰਜਨ
<br/>
## Support
ਮੈਂਟੇਨਰਾਂ ਅਤੇ ਕਮਿਊਨਿਟੀ ਨਾਲ ਇੱਥੇ ਸੰਪਰਕ ਕਰੋ:
- ਬੱਗ ਜਾਂ ਫੀਚਰ ਰਿਕਵੇਸਟ? ਕਿਰਪਾ ਕਰਕੇ [issue ਖੋਲ੍ਹੋ](https://github.com/HeyPuter/puter/issues/new/choose)।
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- ਸੁਰੱਖਿਆ ਮਸਲੇ? [[email protected]](mailto:[email protected])
- ਮੇਂਟੇਨਰਾਂ ਨੂੰ ਈਮੇਲ ਕਰੋ [[email protected]](mailto:[email protected])
ਅਸੀਂ ਹਮੇਸ਼ਾ ਤੁਹਾਡੀਆਂ ਕਿਸੇ ਵੀ ਪ੍ਰਸ਼ਨਾਂ ਵਿੱਚ ਮਦਦ ਕਰਨ ਲਈ ਤਿਆਰ ਹਾਂ। ਬੇਝਿਝਕ ਪੁੱਛੋ!
<br/>
## License
ਇਹ ਰਿਪੋਜ਼ਟਰੀ, ਆਪਣੇ ਸਾਰੇ ਸਮੱਗਰੀ, ਸਬ-ਪ੍ਰੋਜੈਕਟ, ਮੋਡੀਊਲ, ਅਤੇ ਕੰਪੋਨੈਂਟ ਸਮੇਤ, [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) ਅਧੀਨ ਲਾਇਸੈਂਸਡ ਹੈ ਜੇ ਤਕ ਹੋਰ ਸਪਸ਼ਟ ਤੌਰ 'ਤੇ ਨਹੀਂ ਕਿਹਾ ਗਿਆ। ਤੀਜੀ ਪੱਖ ਦੀਆਂ ਲਾਇਬ੍ਰੇਰੀਆਂ ਆਪਣੇ ਲਾਇਸੈਂਸਾਂ ਅਨੁਸਾਰ ਹੋ ਸਕਦੀਆਂ ਹਨ।
<br/>
## Translations
- [Arabic / العربية](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ar.md)
- [Armenian / Հայերեն](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hy.md)
- [Bengali / বাংলা](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.bn.md)
- [Chinese / 中文](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.zh.md)
- [Danish / Dansk](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.da.md)
- [English](https://github.com/HeyPuter/puter/blob/main/README.md)
- [Farsi / فارسی](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fa.md)
- [Finnish / Suomi](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fi.md)
- [French / Français](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fr.md)
- [German / Deutsch](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.de.md)
- [Hebrew/ עברית](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.he.md)
- [Hindi / हिंदी](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hi.md)
- [Hungarian / Magyar](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hu.md)
- [Indonesian / Bahasa Indonesia](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.id.md)
- [Italian / Italiano](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.it.md)
- [Japanese / 日本語](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.jp.md)
- [Korean / 한국어](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ko.md)
- [Malay / Bahasa Malaysia](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.my.md)
- [Malayalam / മലയാളം](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ml.md)
- [Punjabi / ਪੰਜਾਬੀ](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pa.md)
- [Polish / Polski](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pl.md)
- [Portuguese / Português](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pt.md)
- [Romanian / Română](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ro.md)
- [Russian / Русский](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ru.md)
- [Spanish / Español](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.es.md)
- [Swedish / Svenska](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.sv.md)
- [Tamil / தமிழ்](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ta.md)
- [Telugu / తెలుగు](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.te.md)
- [Thai / ไทย](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.th.md)
- [Turkish / Türkçe](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.tr.md)
- [Ukrainian / Українська](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ua.md)
- [Urdu / اردو](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ur.md)
- [Vietnamese / Tiếng Việt](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.vi.md)
## Links to Other READMEs
### Backend
- [PuterAI Module](./src/backend/doc/modules/puterai/README.md)
- [Metering Service](./src/backend/src/services/MeteringService/README.md)
- [Extensions Development Guide](./extensions/README.md)
+119
View File
@@ -0,0 +1,119 @@
<h3 align="center"><img width="80" alt="Puter.com, Osobisty Komputer Chmurowy: Wszystkie twoje pliki, aplikacje i gry w jednym miejscu, dostępne z dowolnego miejsca o dowolnej porze." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center"> System Operacyjny Internet! Darmowy, Open-Source i Możliwy do Samodzielnego Hostowania.</h3>
<p align="center">
<img alt="Rozmiar repozytorium GitHub" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="Wydanie GitHub" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="Licencja GitHub" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« DEMO NA ŻYWO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="zrzut ekranu" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter to zaawansowany, open-source'owy internetowy system operacyjny, zaprojektowany tak, aby był bogaty w funkcje, wyjątkowo szybki i wysoce rozszerzalny. Puter może być używany jako:
- Prywatna chmura osobista do przechowywania wszystkich plików, aplikacji i gier w jednym bezpiecznym miejscu, dostępnym z dowolnego miejsca o dowolnej porze.
- Platforma do budowania i publikowania stron internetowych, aplikacji webowych i gier.
- Alternatywa dla Dropbox, Google Drive, OneDrive itp. ze świeżym interfejsem i potężnymi funkcjami.
- Zdalne środowisko pulpitu dla serwerów i stacji roboczych.
- Przyjazny, open-source'owy projekt i społeczność do nauki o tworzeniu stron internetowych, chmurze obliczeniowej, systemach rozproszonych i wielu innych!
<br/>
## Rozpoczęcie pracy
## 💻 Lokalne środowisko developerskie
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
To uruchomi Puter na http://puter.localhost:4100 (lub na następnym dostępnym porcie).
<br/>
## 🐳 Docker
```bash
Copy code
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
## 🐙 Docker Compose
## Linux/macOS
```bash
Copy code
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
## Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
## ☁️ Puter.com
Puter jest dostępny jako usługa hostowana na [**puter.com**](https://puter.com).
<br/>
## Wymagania systemowe
- **Systemy operacyjne:** Linux, macOS, Windows
- **RAM:** Minimum 2GB (zalecane 4GB)
- **Przestrzeń dyskowa:** 1GB wolnego miejsca
- **Node.js:** Wersja 16+ (zalecana wersja 22+)
- **npm:** Najnowsza stabilna wersja
<br/>
## Wsparcie
Skontaktuj się z opiekunami i społecznością przez te kanały:
- Raport o błędzie lub prośba o funkcję? Proszę otworzyć zgłoszenie.
- Discord: discord.com/invite/PQcx7Teh8u
- X (Twitter): x.com/HeyPuter
- Reddit: reddit.com/r/puter/
- Mastodon: mastodon.social/@puter
- Problemy z bezpieczeństwem? security@puter.com
- Email do opiekunów: hi@puter.com
Zawsze chętnie pomożemy Ci z wszelkimi pytaniami, jakie możesz mieć. Nie wahaj się pytać!
<br/>
## Licencja
To repozytorium, w tym cała jego zawartość, podprojekty, moduły i komponenty, jest licencjonowane na podstawie [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt), chyba że wyraźnie zaznaczono inaczej. Biblioteki stron trzecich zawarte w tym repozytorium mogą podlegać własnym licencjom.
<br/>
+173
View File
@@ -0,0 +1,173 @@
<h3 align="center"><img width="80" alt="Puter.com, O Computador Pessoal em Nuvem: Todos os seus arquivos, aplicativos e jogos em um único lugar, acessíveis de qualquer lugar e a qualquer hora." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">O Sistema Operacional da Internet! Gratuito, de Código Aberto e Auto-Hospedável.</h3>
<p align="center">
<a href="https://puter.com/"><strong>« DEMONSTRAÇÃO AO VIVO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://apps.puter.com/">App Store</a>
·
<a href="https://developer.puter.com" target="_blank">Developers</a>
·
<a href="https://github.com/heyputer/puter-cli" target="_blank">CLI</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://x.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter é um sistema operacional de internet avançado e de código aberto, projetado para ser rico em recursos, excepcionalmente rápido e altamente extensível. Puter pode ser usado como:
- Um serviço de nuvem pessoal com foco na privacidade para manter todos os seus arquivos, aplicativos e jogos em um local seguro, acessível de qualquer lugar e a qualquer hora.
- Uma plataforma para construir e publicar websites, aplicativos web e jogos.
- Uma alternativa ao Dropbox, Google Drive, OneDrive, etc., com uma interface renovada e recursos poderosos.
- Um ambiente de desktop remoto para servidores e estações de trabalho.
- Um projeto e comunidade de código aberto e amigável para aprender sobre desenvolvimento web, computação em nuvem, sistemas distribuídos e muito mais!
<br/>
## Iniciando o Projeto
### 💻 Desenvolvimento Local
```
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
✨ Isso iniciará o Puter em http://puter.localhost:4100 (ou na próxima porta disponível).
Se isso não funcionar, consulte [First Run Issues](./doc/self-hosters/first-run-issues.md) para solucionar os problemas.
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
✨ Isso iniciará o Puter em http://puter.localhost:4100 (ou na próxima porta disponível).
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
✨ Isso iniciará o Puter em http://puter.localhost:4100 (ou na próxima porta disponível).
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
✨ Isso iniciará o Puter em http://puter.localhost:4100 (ou na próxima porta disponível).
<br/>
### 🚀 Auto-Hospedagem
Para guia detalhados sobre como auto-hospedar o Puter, incluindo opções de configuração e melhores práticas, consulte nossa [Documentação de Auto-Hospedagem](https://github.com/HeyPuter/puter/blob/main/doc/self-hosters/instructions.md).
### ☁️ Puter.com
O Puter está disponível como um serviço hospedado em [**puter.com**](https://puter.com).
<br/>
## Requerimentos do sistema
- **Sistema operacional:** Linux, macOS, Windows
- **RAM:** 2GB mínimo (4GB recomendado)
- **Espaço de disco:** 1GB de espaço disponível
- **Node.js:** Versão 16+ (Versão 23+ recomendada)
- **npm:** Última versão estável
<br/>
## Suporte
Conecte-se com os mantenedores e a comunidade através destes canais:
- Relato de bug ou solicitação de recurso? Por favor, [abra um tópico](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Problemas de segurança? [[email protected]](mailto:[email protected])
- Envie um email para os mantenedores em [[email protected]](mailto:[email protected])
Estamos sempre felizes em ajudá-lo com quaisquer perguntas que você possa ter. Não hesite em perguntar!
<br/>
## Licença
Este repositório, incluindo todos os seus conteúdos, subprojetos, módulos e componentes, está licenciado sob [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) a menos que explicitamente indicado de outra forma. Bibliotecas de terceiros incluídas neste repositório podem estar sujeitas às suas próprias licenças.
<br/>
## Traduções
- [Arabic / العربية](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ar.md)
- [Armenian / Հայերեն](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hy.md)
- [Bengali / বাংলা](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.bn.md)
- [Chinese / 中文](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.zh.md)
- [Danish / Dansk](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.da.md)
- [English](https://github.com/HeyPuter/puter/blob/main/README.md)
- [Farsi / فارسی](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fa.md)
- [Finnish / Suomi](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fi.md)
- [French / Français](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fr.md)
- [German/ Deutsch](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.de.md)
- [Hebrew/ עברית](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.he.md)
- [Hindi / हिंदी](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hi.md)
- [Hungarian / Magyar](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hu.md)
- [Indonesian / Bahasa Indonesia](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.id.md)
- [Italian / Italiano](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.it.md)
- [Japanese / 日本語](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.jp.md)
- [Korean / 한국어](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ko.md)
- [Malayalam / മലയാളം](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ml.md)
- [Polish / Polski](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pl.md)
- [Portuguese / Português](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pt.md)
- [Romanian / Română](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ro.md)
- [Russian / Русский](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ru.md)
- [Spanish / Español](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.es.md)
- [Swedish / Svenska](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.sv.md)
- [Tamil / தமிழ்](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ta.md)
- [Telugu / తెలుగు](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.te.md)
- [Thai / ไทย](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.th.md)
- [Turkish / Türkçe](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.tr.md)
- [Ukrainian / Українська](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ua.md)
- [Urdu / اردو](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ur.md)
- [Vietnamese / Tiếng Việt](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.vi.md)
+129
View File
@@ -0,0 +1,129 @@
<h3 align="center"><img width="80" alt="Puter.com, calculatorul personal în cloud: toate fișierele, aplicațiile și jocurile tale într-un singur loc, accesibile de oriunde și oricând." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Sistemul de operare al internetului! Gratuit, open-source și găzduibil autonom.</h3>
<p align="center">
<img alt="Dimensiunea repoului GitHub" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="Versiunea de pe GitHub" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=ultima%20versiune"> <img alt="Licență GitHub" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« DEMO LIVE »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://www.youtube.com/@EricsPuterVideos">YouTube</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
·
<a href="https://hackerone.com/puter_h1b">Program de recompense pentru identificarea bugurilor</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="captură de ecran" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter este un sistem de operare pe internet, avansat, open-source, conceput să fie bogat în funcționalități, excepțional de rapid și foarte extensibil. Puter poate fi folosit ca:
* Un cloud personal cu accent pe confidențialitate, pentru a-ți păstra toate fișierele, aplicațiile și jocurile într-un singur loc securizat, accesibil de oriunde și oricând.
* O platformă pentru a construi și publica site-uri, aplicații web și jocuri.
* O alternativă la Dropbox, Google Drive, OneDrive etc., cu o interfață nouă și funcționalități puternice.
* Un mediu desktop la distanță pentru servere și stații de lucru.
* Un proiect și o comunitate, open-source și prietenoase, pentru a învăța despre dezvoltare web, cloud computing, sisteme distribuite și multe altele!
<br/>
## Fă primii pași
### 💻 Dezvoltare locală
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Aceasta va porni Puter la [http://puter.localhost:4100](http://puter.localhost:4100) (sau pe următorul port disponibil).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter este disponibil ca serviciu găzduit la adresa [**puter.com**](https://puter.com).
<br/>
## Cerințe de sistem
* **Sisteme de operare:** Linux, macOS, Windows
* **RAM:** minimum 2GB (recomandat 4GB)
* **Spațiu pe disc:** 1GB spațiu liber
* **Node.js:** versiunea 16+ (versiunea 22+ recomandată)
* **npm:** ultima versiune stabilă
<br/>
## Suport
Ia legătura cu cei care asigură mentenanța proiectului și cu comunitatea prin aceste canale:
* Vrei să raportezi un bug sau să ceri o funcționalitate? Te rugăm să [deschizi o problemă](https://github.com/HeyPuter/puter/issues/new/choose).
* Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
* X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
* Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
* Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
* Probleme de securitate? [[email protected]](mailto:[email protected])
* Trimite un e-mail celor care asigură mentenanța proiectului la [[email protected]](mailto:[email protected])
Suntem întotdeauna bucuroși să te ajutăm cu orice întrebări ai. Nu ezita să ne pui întrebări!
<br/>
## Licență
Acest repository, inclusiv tot conținutul său, subproiectele, modulele și componentele, este licențiat sub [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt), cu excepția cazurilor în care se menționează explicit altfel. Bibliotecile terțe incluse în acest repository pot fi supuse propriilor lor licențe.
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, персональный облачный компьютер: все ваши файлы, приложения и игры в одном месте, доступные из любой точки мира в любое время." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Интернет ОС! Бесплатная, с открытым исходным кодом и возможностью самостоятельной установки.</h3>
<p align="center">
<img alt="Размер репозитория GitHub" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="Релиз GitHub" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="Лицензия GitHub" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« ЖИВОЕ ДЕМО »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter — это передовая операционная система с открытым исходным кодом, разработанная для обеспечения широкого функционала, исключительной скорости и высокой масштабируемости. Puter можно использовать как:
- Персональное облако с приоритетом конфиденциальности для хранения всех ваших файлов, приложений и игр в одном безопасном месте, доступном из любой точки мира в любое время.
- Платформа для создания и публикации веб-сайтов, веб-приложений и игр.
- Альтернатива Dropbox, Google Drive, OneDrive и т. д. с новым интерфейсом и мощными функциями.
- Удаленное рабочее окружение для серверов и рабочих станций.
- Дружественный проект с открытым исходным кодом и сообщество для изучения веб-разработки, облачных вычислений, распределенных систем и многого другого!
<br/>
## Начало работы
### 💻 Локальная разработка
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Это запустит Puter по адресу http://puter.localhost:4100 (или на следующем доступном порту).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter доступен как облачный сервис на [**puter.com**](https://puter.com).
<br/>
## Системные требования
- **Операционные системы:** Linux, macOS, Windows
- **ОЗУ:** минимум 2 ГБ (рекомендуется 4 ГБ)
- **Место на диске:** 1 ГБ свободного места
- **Node.js:** Версия 16+ (рекомендуется версия 22+)
- **npm:** Последняя стабильная версия
<br/>
## Поддержка
Свяжитесь с разработчиками и сообществом этими способами:
- Отчет об ошибке или запрос функции? Пожалуйста, [откройте вопрос](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Проблемы безопасности? [[email protected]](mailto:[email protected])
- Свяжитесь с разработчиками по адресу [[email protected]](mailto:[email protected])
Мы всегда рады помочь вам с любыми вопросами. Не стесняйтесь спрашивать!
<br/>
## Лицензия
Этот репозиторий, включая все его содержимое, подпроекты, модули и компоненты, лицензирован в соответствии с [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt), если явно не указано иное. Сторонние библиотеки, включенные в этот репозиторий, могут подпадать под действие их собственных лицензий.
<br/>
+125
View File
@@ -0,0 +1,125 @@
<h3 align="center"><img width="80" alt="Puter.com, Den personliga molndatorn: Alla dina filer, appar och spel på ett ställe tillgängliga var som helst när som helst." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Internet OS! Gratis, öppen källkod och självhostad.</h3>
<p align="center">
<img alt="GitHub repo storlek" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Utgåva" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=senaste%20versionen"> <img alt="GitHub Licens" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="skärmdump" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter är ett avancerat, öppen källkod internetoperativsystem designat för att vara funktionsrikt, exceptionellt snabbt och mycket utbyggbart. Puter kan användas som:
- Ett integritetsfokuserat personligt moln för att hålla alla dina filer, appar och spel på ett säkert ställe, tillgängligt var som helst när som helst.
- En plattform för att bygga och publicera webbplatser, webbappar och spel.
- Ett alternativ till Dropbox, Google Drive, OneDrive, etc. med ett fräscht gränssnitt och kraftfulla funktioner.
- En fjärrskrivbordsmiljö för servrar och arbetsstationer.
- Ett vänligt, öppen källkod-projekt och gemenskap för att lära sig om webbutveckling, molndatorer, distribuerade system och mycket mer!
<br/>
## Komma igång
### 💻 Lokal Utveckling
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Detta kommer att starta Puter på http://puter.localhost:4100 (eller nästa lediga port).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter är tillgängligt som en värdtjänst på [**puter.com**](https://puter.com).
<br/>
## Systemkrav
- **Operating Systems:** Linux, macOS, Windows
- **RAM:** 2GB minimum (4GB recommended)
- **Disk Space:** 1GB free space
- **Node.js:** Version 16+ (Version 22+ recommended)
- **npm:** Latest stable version
<br/>
## Support
Anslut med underhållarna och gemenskapen genom dessa kanaler:
- Buggrapport eller funktionsförfrågan? Vänligen [öppna ett ärende](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Säkerhetsproblem? [[email protected]](mailto:[email protected])
- E-posta underhållarna på [[email protected]](mailto:[email protected])
Vi hjälper dig gärna med eventuella frågor du kan ha. Tveka inte att fråga!
<br/>
## Licens
Detta arkiv, inklusive allt dess innehåll, delprojekt, moduler och komponenter, är licensierat under [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) om inte annat uttryckligen anges. Tredjepartsbibliotek som ingår i detta arkiv kan vara föremål för sina egna licenser.
<br/>
+123
View File
@@ -0,0 +1,123 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: உங்கள் கோப்புகள், ஆப்ஸ் மற்றும் கேம்கள் அனைத்தும் ஒரே இடத்தில் எங்கிருந்தும் எந்த நேரத்திலும் அணுகலாம்." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">இன்டர்நெட் OS! இலவசம், ஓப்பன் சோர்ஸ் மற்றும் Self-Hostable</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub உரிமம்" src="https://img.shields.io/github/license/HeyPuter/puter" >
</p>
<p align="center">
<a href="https://puter.com/"><strong>« லைவ் டெமோ »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## புட்டர் (Putter)
புட்டர்(putter) என்பது ஒரு மேம்பட்ட, திறந்த மூல இலவசமாக இணைய இயக்க முறைமையாகும், இது அம்சம் நிறைந்ததாகவும், விதிவிலக்காக வேகமாகவும், அதிக விரிவாக்கக்கூடியதாகவும் வடிவமைக்கப்பட்டுள்ளது. புட்டரை இவ்வாறு பயன்படுத்தலாம்:
- உங்கள் கோப்புகள், பயன்பாடுகள் மற்றும் கேம்கள் அனைத்தையும் ஒரே பாதுகாப்பான இடத்தில் வைத்திருக்க, எந்த நேரத்திலும் எங்கிருந்தும் அணுகக்கூடிய தனியுரிமை-முதல் தனிப்பட்ட கிளவுட்.
- இணையதளங்கள், இணைய பயன்பாடுகள் மற்றும் கேம்களை உருவாக்கி வெளியிடுவதற்கான தளம் இதுவாகும்.
- புதிய இடைமுகம் மற்றும் சக்திவாய்ந்த அம்சங்களுடன் Dropbox, Google Drive, OneDrive போன்றவற்றுக்கு மாற்றீடாக உபயோகிக்க கூடியது.
- சர்வர்கள் மற்றும் பணிநிலையங்களுக்கான தொலைநிலை டெஸ்க்டாப்(desktop) சூழல்.
- வலை மேம்பாடு, கிளவுட் கம்ப்யூட்டிங், விநியோகிக்கப்பட்ட அமைப்புகள் மற்றும் பலவற்றைப் பற்றி அறிந்து ஒரு நட்பு ரீதியான, திறந்த மூல திட்டம் மற்றும் சமூக அறிவியலில் சார்ந்த ஒன்று.
<br/>
## தொடங்குதல்
### 💻 உள்ளூர் வளர்ச்சி
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
``` தொடக்கம்
```
இது புட்டரை <http://puter.localhost:4100> இல் தொடங்கும் (அல்லது அடுத்து கிடைக்கும் இடம்).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 டோக்கர் கம்போஸ்
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
புட்டர் ஹோஸ்ட் செய்யப்பட்ட சேவையாக [**puter.com**](https://puter.com) இல் கிடைக்கிறது.
<br/>
## கணினி தேவைகள்
- **இயக்க முறைமைகள்:** Linux, macOS, Windows
- **ரேம்:** குறைந்தபட்சம் 2 ஜிபி (4 ஜிபி பரிந்துரைக்கப்படுகிறது)
- **வட்டு இடம்:** 1GB இலவச இடம்
- **Node.js:** Version 16+ (Version 22+ recommended)
- **npm:** சமீபத்திய நிலையான பதிப்பு(Latest stable version)
<br/>
## ஆதரவு
இந்த சேனல்கள் மூலம் பராமரிப்பாளர்கள் மற்றும் சமூகத்துடன் சமூக இணைப்பாளர்:
- பிழை அறிக்கை அல்லது மாற்றுதல் கோரிக்கை? தயவுசெய்து [சிக்கலைத் திறக்கவும்](https://github.com/HeyPuter/puter/issues/new/choose).
- கருத்து வேறுபாடு: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- பாதுகாப்பு பிரச்சினைகள்? [[email protected]](mailto:[email protected])
- மின்னஞ்சல் பராமரிப்பாளர்களுக்கு [[email protected]](mailto:[email protected])
உங்களுக்கு ஏதேனும் கேள்விகள் இருந்தால் உங்களுக்கு உதவ நாங்கள் எப்போதும் மகிழ்ச்சியடைகிறோம். தயங்காமல் கேளுங்கள்!
<br/>
## உரிமம்
இந்தக் களஞ்சியமானது, அதன் அனைத்து உள்ளடக்கங்கள், துணைத் திட்டங்கள், தொகுதிகள் மற்றும் கூறுகள் உட்பட, வெளிப்படையாகக் கூறப்படாவிட்டால், [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) இன் கீழ் உரிமம் பெற்றுள்ளது. . இந்தக் களஞ்சியத்தில் சேர்க்கப்பட்டுள்ள மூன்றாம் தரப்பு நூலகங்கள் அவற்றின் சொந்த உரிமங்களுக்கு உட்பட்டதாக இருக்கும்.
<br/>
+161
View File
@@ -0,0 +1,161 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: మీ అన్ని ఫైల్‌లు, యాప్‌లు మరియు గేమ్‌లను ఒకే స్థలంలో ఎక్కడి నుండైనా ఎప్పుడైనా యాక్సెస్ చేయవచ్చు." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center"> ఇంటర్నెట్ OS! ఉచిత, ఓపెన్ సోర్స్, and Self-Hostable.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« ప్రత్యక్ష ప్రదర్శన »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## పుటర్ (Puter)
పుటర్ అనేది అధునాతన, ఓపెన్ సోర్స్ ఇంటర్నెట్ ఆపరేటింగ్ సిస్టమ్, ఇది ఫీచర్-రిచ్, అనూహ్యంగా వేగవంతమైన మరియు అత్యంత విస్తరించదగినదిగా రూపొందించబడింది. పుటర్‌ను ఇలా ఉపయోగించవచ్చు:
- మీ అన్ని ఫైల్‌లు, యాప్‌లు మరియు గేమ్‌లను ఒకే సురక్షిత స్థలంలో ఉంచడానికి గోప్యత-మొదటి వ్యక్తిగత క్లౌడ్, ఎప్పుడైనా ఎక్కడి నుండైనా యాక్సెస్ చేయవచ్చు.
- వెబ్‌సైట్‌లు, వెబ్ యాప్‌లు మరియు గేమ్‌లను రూపొందించడానికి మరియు ప్రచురించడానికి ఒక వేదిక.
- తాజా ఇంటర్‌ఫేస్ మరియు శక్తివంతమైన ఫీచర్‌లతో Dropbox, Google Drive, OneDrive మొదలైన వాటికి ప్రత్యామ్నాయం.
- సర్వర్లు మరియు వర్క్‌స్టేషన్‌ల కోసం రిమోట్ డెస్క్‌టాప్ వాతావరణం.
- వెబ్ డెవలప్‌మెంట్, క్లౌడ్ కంప్యూటింగ్, డిస్ట్రిబ్యూట్ సిస్టమ్‌లు మరియు మరిన్నింటి గురించి తెలుసుకోవడానికి స్నేహపూర్వక, ఓపెన్ సోర్స్ ప్రాజెక్ట్ మరియు కమ్యూనిటీ!
<br/>
## ప్రారంభించడం
### లోకల్ డెవలప్మెంట్
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
ఇది http://puter.localhost:4100 (లేదా తదుపరి అందుబాటులో ఉన్న పోర్ట్) వద్ద పుటర్‌ని ప్రారంభిస్తుంది.
ఇది పని చేయకపోతే, దీని కోసం [మొదటి రన్ సమస్యలు](./doc/first-run-issues.md) చూడండి
ట్రబుల్షూటింగ్ దశలు.
<br/>
### 🐳 డోకర్
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 డోకర్ Compose
#### లినక్స్/ macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### విండోస్
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
పుటర్ [**puter.com**](https://puter.com)లో హోస్ట్ చేయబడి ఉంది.
<br/>
## System Requirements
- **ఆపరేటింగ్ సిస్టమ్స్:** లినక్స్, macOS, విండోస్
- **RAM:** 2GB కనీసం(4GB recommended)
- **Disk Space:** 1GB ఖాళీ
- **Node.js:** Version 16+ (Version 22+ recommended)
- **npm:** Latest stable version
<br/>
## Support
ఈ ఛానెల్‌ల ద్వారా నిర్వాహకులు మరియు సంఘంతో కనెక్ట్ అవ్వండి:
- బగ్ నివేదిక లేదా ఫీచర్ అభ్యర్థన? దయచేసి [open an issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Security issues? [[email protected]](mailto:[email protected])
- Email maintainers at [[email protected]](mailto:[email protected])
మీకు ఏవైనా సందేహాలు ఉంటే మీకు సహాయం చేయడానికి మేము ఎల్లప్పుడూ సంతోషిస్తాము. అడగడానికి సంకోచించకండి!
<br/>
## లైసెన్సు
ఈ రిపోజిటరీ, దాని మొత్తం కంటెంట్‌లు, ఉప-ప్రాజెక్ట్‌లు, మాడ్యూల్స్ మరియు కాంపోనెంట్‌లతో సహా, [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) కింద లైసెన్స్‌ని కలిగి ఉంటుంది. . ఈ రిపోజిటరీలో చేర్చబడిన థర్డ్-పార్టీ లైబ్రరీలు వాటి స్వంత లైసెన్స్‌లకు లోబడి ఉండవచ్చు.
<br/>
## అనువాదాలు
- [Arabic / العربية](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ar.md)
- [Armenian / Հայերեն](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hy.md)
- [Bengali / বাংলা](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.bn.md)
- [Chinese / 中文](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.zh.md)
- [Danish / Dansk](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.da.md)
- [English](https://github.com/HeyPuter/puter/blob/main/README.md)
- [Farsi / فارسی](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fa.md)
- [Finnish / Suomi](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fi.md)
- [French / Français](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fr.md)
- [German/ Deutsch](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.de.md)
- [Hebrew/ עברית](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.he.md)
- [Hindi / हिंदी](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hi.md)
- [Hungarian / Magyar](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hu.md)
- [Indonesian / Bahasa Indonesia](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.id.md)
- [Italian / Italiano](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.it.md)
- [Japanese / 日本語](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.jp.md)
- [Korean / 한국어](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ko.md)
- [Malayalam / മലയാളം](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ml.md)
- [Polish / Polski](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pl.md)
- [Portuguese / Português](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pt.md)
- [Romanian / Română](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ro.md)
- [Russian / Русский](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ru.md)
- [Spanish / Español](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.es.md)
- [Swedish / Svenska](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.sv.md)
- [Tamil / தமிழ்](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ta.md)
- [Telugu / తెలుగు](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.te.md)
- [Thai / ไทย](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.th.md)
- [Turkish / Türkçe](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.tr.md)
- [Ukrainian / Українська](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ua.md)
- [Urdu / اردو](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ur.md)
- [Vietnamese / Tiếng Việt](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.vi.md)
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">ระบบปฏิบัติการอินเทอร์เน็ต ฟรี, โอเพ่นซอร์ส, และสามารถโฮสต์ได้ด้วยตนเอง</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« การสาธิตสด »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">ชุดพัฒนาโปรแกรม</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">ดิสคอร์ด</a>
·
<a href="https://reddit.com/r/puter">เรดดิท</a>
·
<a href="https://twitter.com/HeyPuter">X (ทวิตเตอร์)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## พิวเตอร์
พิวเตอร์ เป็นระบบปฏิบัติการอินเทอร์เน็ตขั้นสูงแบบโอเพ่นซอร์สที่ออกแบบมาให้มีฟีเจอร์ครบถ้วน ความเร็วสูง และมีความสามารถที่จะขยายได้สูง. พิวเตอร์ สามารถใช้ได้เป็น:
- คลาวด์ส่วนตัว เพื่อเก็บไฟล์, แอพพลิเคชัน, และเกมทั้งหมดของคุณในที่เดียวที่ปลอดภัยและสามารถเข้าถึงได้ทุกที่ทุกเวลา
- แพลตฟอร์มสำหรับการสร้างและเผยแพร่เว็บไซต์, เว็บแอปพลิเคชัน, และเกม
- ทางเลือกอีกหนึ่งทางที่สามารถใช้แทน Dropbox, Google Drive, OneDrive ฯลฯ โดยที่มีอินเทอร์เฟซใหม่และฟีเจอร์ที่ทรงพลัง
- สภาพแวดล้อมสำหรับเดสก์ท็อประยะไกลที่ใช้กับเซิร์ฟเวอร์และสถานีทำงาน
- โครงการโอเพ่นซอร์สและชุมชนที่เป็นมิตรที่คุณสามารถเรียนรู้เกี่ยวกับการพัฒนาเว็บ, คลาวด์คอมพิวติ้ง, ระบบกระจาย, และอีกมากมาย
<br/>
## การเริ่มต้นใช้งาน
### 💻 การพัฒนาภายในเครื่อง
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
พิวเตอร์ จะถูกเปิดใช้งานที่ http://puter.localhost:4100 (หรือพอร์ตถัดไปที่ว่าง).
<br/>
### 🐳 ด็อกเกอร์
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 ด็อกเกอร์ คอมโพส
#### ลินุกซ์/แมคโอเอส
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### วินโดวส์
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
สามารถใช้งาน พิวเตอร์ ได้ในรูปแบบบริการโฮสต์ที่ [**puter.com**](https://puter.com).
<br/>
## ข้อกำหนดของระบบ
- **ระบบปฏิบัติการ:** ลินุกซ์ แมคโอเอส วินโดวส์
- **แรม:** อย่างน้อย 2GB (แนะนำ 4GB)
- **พื้นที่เก็บข้อมูล:** พื้นที่ว่าง 1GB
- **Node.js:** เวอร์ชัน 16+ (แนะนำเวอร์ชัน 22+)
- **npm:** เวอร์ชันล่าสุดที่เสถียร
<br/>
## การช่วยเหลือ
ติดต่อกับผู้ดูแลระบบและชุมชนผ่านช่องทางเหล่านี้:
- พบข้อผิดพลาดหรือขอฟีเจอร์ใหม่? กรุณา [เปิดปัญหา](https://github.com/HeyPuter/puter/issues/new/choose).
- ดิสคอร์ด: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (ทวิตเตอร์): [x.com/HeyPuter](https://x.com/HeyPuter)
- เรดดิท: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- มาสตอดอน: [mastodon.social/@puter](https://mastodon.social/@puter)
- ปัญหาด้านความปลอดภัย [[email protected]](mailto:[email protected])
- ส่งอีเมลถึงผู้ดูแลระบบได้ที่ [[email protected]](mailto:[email protected])
เรายินดีเสมอที่จะช่วยเหลือคุณกับทุกทุกคำถามที่คุณมี อย่าลังเลที่จะถาม
<br/>
## ลิขสิทธิ์
ที่เก็บข้อมูลนี้ รวมถึงเนื้อหาทั้งหมด, โครงการย่อย, โมดูล, และส่วนประกอบต่างๆ ได้รับใบอนุญาตภายใต้ [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) เว้นแต่จะมีการระบุไว้เป็นอย่างอื่นอย่างชัดเจน ไลบรารีจากบุคคลที่สามที่รวมอยู่ในที่เก็บข้อมูลนี้อาจอยู่ภายใต้ใบอนุญาตของตนเอง
<br/>
+127
View File
@@ -0,0 +1,127 @@
<h3 align="center"><img width="80" alt="Puter.com, Kişisel Bulut Bilgisayar: Tüm dosyalarınız, uygulamalarınız ve oyunlarınız her zaman her yerden erişilebilen tek bir yerde." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">İnternet İşletim Sistemi! Ücretsiz, Açık Kaynaklı ve Kendi Kendine Barındırılabilir</h3>
<p align="center">
<img alt="GitHub Depo Boyutu" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Yayınlamak" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub Lisans" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« CANLI DEMO »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter, zengin özelliklere sahip, son derece hızlı ve son derece genişletilebilir olacak şekilde tasarlanmış gelişmiş, açık kaynaklı bir internet işletim sistemidir. Puter şu şekilde kullanılabilir:
- Tüm dosyalarınızı, uygulamalarınızı ve oyunlarınızı tek bir güvenli yerde tutmak için gizlilik öncelikli bir kişisel bulut, her yerden her zaman erişilebilir.
- Web siteleri, web uygulamaları ve oyunlar oluşturmak ve yayınlamak için bir platform.
- Yeni bir arayüz ve güçlü özelliklerle Dropbox, Google Drive, OneDrive vb. uygulamalara bir alternatif.
- Sunucular ve iş istasyonları için bir uzak masaüstü ortamı.
- Web geliştirme, bulut bilişim, dağıtık sistemler ve çok daha fazlası hakkında bilgi edinmek için dost canlısı, açık kaynaklı bir proje ve topluluk!
<br/>
## Başlarken
### 💻 Yerel Geliştirme
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Bu, Puter'ı http://puter.localhost:4100 adresinde (veya bir sonraki kullanılabilir portta) başlatacaktır.
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter, [**puter.com**](https://puter.com) adresinde barındırılan bir hizmet olarak kullanılabilir.
<br/>
## Sistem Gereksinimleri
- **İşletim Sistemleri:** Linux, macOS, Windows
- **RAM:** 2GB Minimum (4GB önerilir)
- **Disk Alanı:** 1GB boş alan
- **Node.js:** Sürüm 16+ (Sürüm 22+ önerilir)
- **npm:** En son stabil sürüm
<br/>
## Destek
Bakımcılarla ve toplulukla şu kanallar aracılığıyla iletişim kurabilirsiniz:
- Hata raporu veya özellik isteği? Lütfen [yeni bir issue açın](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Güvenlik sorunları? [[email protected]](mailto:[email protected])
- Bakımcılara şu adresten e-posta gönderin [[email protected]](mailto:[email protected])
Sorularınız varsa size her zaman yardımcı olmaktan mutluluk duyarız. Sormaktan çekinmeyin!
<br/>
## Lisans
Bu depo, tüm içeriği, alt projeleri, modülleri ve bileşenleri dahil olmak üzere, aksi açıkça belirtilmedikçe [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) altında lisanslanmıştır. Bu depoda yer alan üçüncü taraf kütüphaneler kendi lisanslarına tabi olabilir.
<br/>
+125
View File
@@ -0,0 +1,125 @@
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: Всі ваші файли, додатки та ігри в одному місці, доступні з будь-якого куточка світу в будь-який час." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Інтернет ОС! Безкоштовна, відкрита та self-hosted.</h3>
<p align="center">
<img alt="Розмір репозиторію на GitHub" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="Остання версія на GitHub" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="Ліцензія GitHub" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« Онлайн ДЕМО »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="скріншот" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter — це просунута, інтернет-ОС, з відкритим кодом, створена для того, щоб бути багатофункціональною, надзвичайно швидкою та розширюваною. Puter може використовуватися як:
- Приватний хмарний сервіс для збереження всіх ваших файлів, додатків і ігор у безпечному місці, доступному в будь-який час з будь-якого місця.
- Платформа для створення та публікації вебсайтів, вебдодатків і ігор.
- Альтернатива Dropbox, Google Drive, OneDrive і тд, з свіженьким інтерфейсом та потужними функціями.
- Віддалене робоче середовище для серверів і робочих станцій.
- Дружній, відкритий проєкт та спільнота для вивчення веброзробки, хмарних обчислень, розподілених систем і багато іншого!
<br/>
## Початок роботи
### Локальна розробка
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Це запустить Puter на http://puter.localhost:4100 (або на наступному доступному порті).
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter доступний як hosted service на [**puter.com**](https://puter.com).
<br/>
## Системні вимоги
- **Операційні Системи:** Linux, macOS, Windows
- **RAM:** 2GB мінімум (4GB рекомендовано)
- **Місце на диску:** 1GB вільного місця
- **Node.js:** Version 16+ (Version 22+ рекомендовано)
- **npm:** остання "stable" версія
<br/>
## Підтримка
Зв'язатися з розробниками та спільнотою можна через такі канали:
- Повідомити про помилку, або запит щодо нової фічі? Будь ласка, [створіть issue](https://github.com/HeyPuter/puter/issues/new/choose).
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- Питання щодо Security? [[email protected]](mailto:[email protected])
- Написати розробникам [[email protected]](mailto:[email protected])
Ми завжди готові допомогти Вам з будь-якими питаннями, що можуть виникнути. Не соромтеся ставити нам питання!
<br/>
## License
Цей репорзиторій, включаючи увесь його контент, дочірні проєкти, модулі, і компоненти, ліцензовано за [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt), якщо явно не вказано інше. Сторонні бібліотеки, включені в цей репозиторій, можуть підпадати під дію інших ліцензій.
<br/>
+121
View File
@@ -0,0 +1,121 @@
<h3 align="center"><img width="80" alt="Puter.com, ذاتی کلاؤڈ کمپیوٹر: آپ کی تمام فائلیں، ایپس، اور کھیل ایک جگہ پر، کہیں سے بھی اور کسی بھی وقت قابل رسائی۔" src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">انٹرنیٹ OS! مفت، اوپن سورس، اور خود میزبان.</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« لائیو ڈیمو »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">ڈسکورڈ</a>
·
<a href="https://reddit.com/r/puter">ریڈڈٹ</a>
·
<a href="https://twitter.com/HeyPuter">ایکس (ٹوئٹر)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="اسکرین شاٹ" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
ایک جدید، اوپن سورس انٹرنیٹ آپریٹنگ سسٹم ہے جو کہ خصوصیات سے بھرپور، بہت تیز، اور انتہائی توسیع پذیر ہے۔ Puter
: کو استعمال کیا جا سکتا ہے Puter
- ایک پرائیویسی فرسٹ ذاتی کلاؤڈ کے طور پر تاکہ آپ کی تمام فائلیں، ایپس، اور کھیل ایک محفوظ جگہ پر رکھی جا سکیں، کہیں سے بھی اور کسی بھی وقت قابل رسائی ہوں۔
- ویب سائٹس، ویب ایپس، اور کھیل بنانے اور شائع کرنے کے لئے ایک پلیٹ فارم کے طور پر۔
- وغیرہ کا متبادل، نئے انٹرفیس اور طاقتور خصوصیات کے ساتھ۔ Dropbox، Google Drive، OneDrive
- سرورز اور ورک اسٹیشنز کے لیے ایک ریموٹ ڈیسک ٹاپ ماحول کے طور پر۔
- ویب ڈویلپمنٹ، کلاؤڈ کمپیوٹنگ، تقسیم شدہ نظاموں، اور بہت کچھ سیکھنے کے لیے ایک دوستانہ، اوپن سورس پروجیکٹ اور کمیونٹی!
<br/>
## شروع کرنے کا طریقہ
### 💻 مقامی ترقی
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
یہ Puter کو http://puter.localhost:4100 (یا اگلے دستیاب پورٹ) پر لانچ کرے گا۔
<br/>
🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
🐙 Docker Compose
Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
### ☁️ Puter.com
Puter کو [**puter.com**](https://puter.com) پر میزبان سروس کے طور پر دستیاب ہے۔
<br/>
## نظام کی ضروریات
- **آپریٹنگ سسٹمز:** لینکس، macOS، ونڈوز
- **RAM:** کم از کم 2GB (4GB تجویز کردہ)
- **ڈسک کی جگہ:** 1GB خالی جگہ
- **Node.js:** ورژن 16+ (ورژن 22+ تجویز کردہ)
- **npm:** تازہ ترین مستحکم ورژن
<br/>
## سپورٹ
منتظمین اور کمیونٹی سے جڑنے کے لیے یہ چینلز استعمال کریں:
- بگ رپورٹ یا فیچر درخواست؟ براہ کرم [ایک مسئلہ کھولیں](https://github.com/HeyPuter/puter/issues/new/choose).
- ڈسکورڈ: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- ایکس (ٹوئٹر): [x.com/HeyPuter](https://x.com/HeyPuter)
- ریڈڈٹ: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- ماسٹڈون: [mastodon.social/@puter](https://mastodon.social/@puter)
- سیکیورٹی کے مسائل؟ [[email protected]](mailto:[email protected])
- منتظمین کو ای میل کریں [[email protected]](mailto:[email protected])
ہم ہمیشہ آپ کی مدد کے لیے خوش ہیں۔ سوالات پوچھنے میں ہچکچاہٹ نہ کریں
!
<br/>
## لائسنس
اس ریپوزٹری، بشمول اس کے تمام مواد، ذیلی پروجیکٹس، ماڈیولز، اور کمپوننٹس، کو [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) کے تحت لائسنس کیا گیا ہے جب تک کہ واضح طور پر کہیں اور نہ کہا گیا ہو۔ اس ریپوزٹری میں شامل تھرڈ پارٹی لائبریریاں اپنی لائسنس کے تابع ہو سکتی ہیں۔
<br/>
+125
View File
@@ -0,0 +1,125 @@
<h3 align="center"><img width="80" alt="Puter.com, Máy Tính Đám Mây Cá Nhân: Tất cả các tệp, ứng dụng, và trò chơi của bạn ở một nơi, có thể truy cập từ bất cứ đâu vào bất kỳ lúc nào." src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">Hệ điều hành Internet! Miễn phí, Mã nguồn mở và Có thể tự lưu trữ.</h3>
<p align="center">
<img alt="Kích thước repo GitHub" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="Phiên bản phát hành GitHub" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=Phi%C3%AAn%20b%E1%BA%A3n%20ph%C3%A1t%20h%C3%A0nh%20GitHub"> <img alt="Giấy phép GitHub" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« DEMO TRỰC TIẾP »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="chụp màn hình" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter là một hệ điều hành internet tiên tiến, mã nguồn mở được thiết kế để có nhiều tính năng, tốc độ vượt trội và khả năng mở rộng cao. Puter có thể được sử dụng như:
- Một đám mây cá nhân ưu tiên quyền riêng tư để lưu trữ tất cả các tệp, ứng dụng và trò chơi của bạn ở một nơi an toàn, có thể truy cập từ bất cứ đâu, bất cứ lúc nào.
- Một nền tảng để xây dựng và xuất bản các trang web, ứng dụng web và trò chơi.
- Một sự thay thế cho Dropbox, Google Drive, OneDrive, v.v. với giao diện mới mẻ và nhiều tính năng mạnh mẽ.
- Một môi trường máy tính từ xa cho các máy chủ và máy trạm.
- Một dự án thân thiện, mã nguồn mở và cộng đồng để học hỏi về phát triển web, điện toán đám mây, hệ thống phân tán và nhiều hơn nữa!
<br/>
## Bắt Đầu
## 💻 Phát Triển Cục Bộ
```bash
Copy code
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
Điều này sẽ khởi chạy Puter tại http://puter.localhost:4100 (hoặc cổng kế tiếp có sẵn).
<br/>
### 🐳 Docker
```bash
Copy code
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
## 🐙 Docker Compose
## Linux/macOS
``` bash
Copy code
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
## Windows
```powershell
Copy code
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
## ☁️ Puter.com
Puter có sẵn dưới dạng dịch vụ lưu trữ tại [**puter.com**](https://puter.com).
<br/>
## Yêu Cầu Hệ Thống
- **Hệ Điều Hành:** Linux, macOS, Windows
- **RAM:** Tối thiểu 2GB (Khuyến nghị 4GB)
- **Dung Lượng Ổ Cứng:** Còn trống 1GB
- **Node.js:** Phiên bản 16+ (Khuyến nghị phiên bản 22+)
- **npm:** Phiên bản ổn định mới nhất
<br/>
## Hỗ Trợ
Kết nối với các nhà bảo trì và cộng đồng thông qua các kênh sau:
- Báo cáo lỗi hoặc yêu cầu tính năng? Vui lòng mở một vấn đề.
- Discord: discord.com/invite/PQcx7Teh8u
- X (Twitter): x.com/HeyPuter
- Reddit: reddit.com/r/puter/
- Mastodon: mastodon.social/@puter
- Vấn đề bảo mật? security@puter.com
- Email các nhà bảo trì tại hi@puter.com
Chúng tôi luôn sẵn sàng giúp đỡ bạn với bất kỳ câu hỏi nào bạn có. Đừng ngần ngại hỏi!
<br/>
## Giấy Phép
Kho lưu trữ này, bao gồm tất cả nội dung, dự án con, mô-đun và thành phần của nó, được cấp phép theo [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt), trừ khi được tuyên bố rõ ràng khác. Các thư viện của bên thứ ba được bao gồm trong kho lưu trữ này có thể phải tuân theo các giấy phép riêng của chúng.
<br/>
+138
View File
@@ -0,0 +1,138 @@
<h3 align="center"><img width="80" alt="Puter.com,个人云计算机:所有文件、应用程序和游戏在一个地方,随时随地可访问。" src="https://assets.puter.site/puter-logo.png"></h3>
<h3 align="center">互联网操作系统!免费、开源且可自行托管。</h3>
<p align="center">
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
</p>
<p align="center">
<a href="https://puter.com/"><strong>« 在线演示 »</strong></a>
<br />
<br />
<a href="https://puter.com">Puter.com</a>
·
<a href="https://docs.puter.com" target="_blank">SDK</a>
·
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
·
<a href="https://reddit.com/r/puter">Reddit</a>
·
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
</p>
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
<br/>
## Puter
Puter 是一个先进的开源互联网操作系统,设计为功能丰富、速度极快且高度可扩展。Puter 可用作:
- 一个以隐私为优先的个人云,将所有文件、应用程序和游戏保存在一个安全的地方,随时随地可访问。
- 构建和发布网站、Web 应用程序和游戏的平台。
- Dropbox、Google Drive、OneDrive 等的替代品,具有全新的界面和强大的功能。
- 服务器和工作站的远程桌面环境。
- 一个友好的开源项目和社区,学习 Web 开发、云计算、分布式系统等更多内容!
<br/>
## 入门指南
### 💻 本地开发
```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
这将会在 http://puter.localhost:4100(或下一个可用端口)启动 Puter。
<br/>
### 🐳 Docker
```bash
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
```
<br/>
### 🐙 Docker Compose
#### Linux/macOS
```bash
mkdir -p puter/config puter/data
sudo chown -R 1000:1000 puter
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
docker compose up
```
<br/>
#### Windows
```powershell
mkdir -p puter
cd puter
New-Item -Path "puter\config" -ItemType Directory -Force
New-Item -Path "puter\data" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
docker compose up
```
<br/>
## 宝塔面板Docker一键部署(推荐)
1. 安装宝塔面板9.2.0及以上版本,前往 [宝塔面板](https://www.bt.cn/new/download.html?r=dk_puter) 官网,选择正式版的脚本下载安装
2. 安装后登录宝塔面板,在左侧菜单栏中点击 `Docker`,首次进入会提示安装`Docker`服务,点击立即安装,按提示完成安装
3. 安装完成后在应用商店中搜索`puter`,点击安装,配置域名等基本信息即可完成安装
### ☁️ Puter.com
Puter 可以作为托管服务使用,访问 [**puter.com**](https://puter.com)。
<br/>
## 系统要求
- **操作系统:** Linux, macOS, Windows
- **内存:** 最低 2GB(推荐 4GB)
- **磁盘空间:** 1GB 可用空间
- **Node.js:** 版本 16+(推荐 22+)
- **npm:** 最新稳定版本
<br/>
## 支持
通过以下渠道与维护者和社区联系:
- 有 Bug 报告或功能请求?请 [提交问题](https://github.com/HeyPuter/puter/issues/new/choose)。
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
- 安全问题?请联系 [[email protected]](mailto:[email protected])
- 电子邮件维护者 [[email protected]](mailto:[email protected])
我们随时乐意帮助您解答任何问题,欢迎随时联系!
<br/>
## 许可证
本仓库,包括其所有内容、子项目、模块和组件,除非另有明确说明,否则均遵循 [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) 许可证。 本仓库中包含的第三方库可能受其各自的许可证约束。
<br/>
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (C) 2024 Puter Technologies Inc.
Copyright (C) 2024-present Puter Technologies Inc.
This file is part of Puter.
+100
View File
@@ -0,0 +1,100 @@
# Pagination convention for list APIs
Every list endpoint follows one wire contract. This document is the source of
truth for adding pagination to a new or existing list surface.
## Wire contract
Requests accept:
| Param | Type | Meaning |
| --- | --- | --- |
| `limit` | number | Maximum items per page. Each endpoint documents its cap and default. |
| `cursor` | string \| null | Opaque continuation token. `null` (or any presence of the key) requests the first page. |
| `offset` | number | Skip N items. Legacy/discouraged — see below. Cannot be combined with `cursor`. |
| `includeTotal` | boolean | Adds `total` to the response. |
Paginated responses are an envelope:
```json
{ "items": [...], "cursor": "…", "total": 123 }
```
- `cursor` is present only while more pages exist. Clients iterate until it
is absent.
- `total` is present only when the request set `includeTotal`.
- **Pages may be short.** Post-query filtering (TTL expiry, permission
checks) can shrink a page below `limit` — or even to zero — while a
`cursor` is still returned. Never use `items.length < limit` as an
end-of-list signal.
New request params are camelCase (`includeTotal`, `fetchUntilFull`).
Pre-existing snake_case params stay for compatibility.
## Backward compatibility
Requests without pagination params keep returning the full result in the
legacy shape (bare array) forever — old clients never break.
The envelope trigger depends on the endpoint's history:
- Endpoints where `limit` pre-dates the convention (readdir, subdomain
`select`) return the envelope only when the request contains `cursor`
(including `null`) or `includeTotal`; `limit`/`offset`-only requests keep
the bare array.
- Endpoints where every pagination param is new (kv `list`, workers
`getFilePaths`) return the envelope when any pagination param is present.
## Cursors
Cursors are opaque base64-encoded JSON, produced and consumed only by the
backend (`src/backend/util/pagination.ts`). What a cursor wraps is an
implementation detail per store:
- DynamoDB-backed lists wrap `LastEvaluatedKey`.
- SQL-backed lists wrap a keyset position — `(sortValue, id)` of the last
row — and the query seeks past it (`WHERE (col, id) > (?, ?) ORDER BY col,
id`). Any SQL list gaining a cursor must have a deterministic `ORDER BY`
ending in a unique tiebreaker (`id`).
Cursors that carry a sort also pin it: a request that passes a cursor plus a
conflicting sort is rejected with 400.
## Offset
SQL-backed endpoints support `offset` natively. DynamoDB-backed endpoints
(kv) emulate it by advancing past skipped items with `Select: COUNT` queries
— no item data is transferred, but read capacity is still consumed for
everything skipped, and the caller is metered for it. **Offset is supported
for parity, not recommended** — cost grows linearly with the offset, so it is
capped (kv: 5000). Use cursors.
## Totals (`includeTotal`)
- SQL: `SELECT COUNT(*)` with the same WHERE clause as the listing.
- DynamoDB: a `Select: COUNT` loop over the query (TTL-filtered), metered to
the caller. Cost is proportional to the total item count — request the
total on the first page only, not every page.
- Where visibility is decided per-actor after the query (protected apps in
the catalog listing), `total` approximates the visible set: it counts
non-protected plus caller-owned rows, and misses rows visible only through
explicit permission grants.
## fetchUntilFull (kv only)
DynamoDB applies `Limit` before its filter expression, so TTL-filtered pages
are structurally short. `fetchUntilFull: true` makes the backend keep
fetching (bounded number of continuation queries) until the page holds
`limit` items or the keyset is exhausted. Requires `limit`. If the bound is
hit, the response simply carries a cursor — still convention-legal.
## Adding pagination to a new endpoint
1. Use `encodeCursor`/`decodeCursor`/`normalizeLimit`/`normalizeOffset` from
`src/backend/util/pagination.ts`.
2. Push equality filters into the query so pages and counts operate on the
true result set; only genuinely per-actor filtering may remain post-query
(short-pages rule covers it).
3. Fetch `limit + 1` rows to detect whether a next page exists (SQL), or use
`LastEvaluatedKey` (DynamoDB).
4. Keep the no-params request returning the legacy full result.
-136
View File
@@ -1,136 +0,0 @@
### Problem
When sending metadata along with arbitrary JSON objects,
a collision of property names may occur. For example, the
driver system can't place a "type" property on an arbitrary
response coming from a driver because that might also be
the name of a property in the response.
#### Example:
```json
{
"type": "api:thing",
"version": "v1.0.0",
"some": "info"
}
```
#### Awful Solution
Reserved words. Drivers need to know their response can't have
keys like `type` or `version`. If we'd like to add more meta
keys in the future we need to verify that no existing drivers
use the new key we'd like to reserve. If we have have such features
as user-submitted drivers this will be impossibe.
A `meta` key as a single reserved word could work, which is one
of the solutions discussed below.
#### Obvious Solution:
The obvious solution is to return an object with a
`head` property and a `body` propery:
```json
{
"head": {
"type": "api:thing",
"version": "v1.0.0"
},
"body": {
"some": "info"
}
}
```
I don't mind this solution. I've come up with some alternatives though,
because this solution has a couple drawbacks:
- it looks a little verbose
- it's not backwards-compatible with arbitrary JSON-object responses
## Solutions
### Dollar-Sign Convention
- Objects have two classes of keys:
- "meta" keys begin with "$"
- other keys must validate against the
usual identifier rules: `/[A-Za-z_][A-Za-z0-9_]*/`
- The meta key `$` indicates the schema or class of
the object.
- Example:
```json
{
"$": "api:thing",
"$version": "v1.0.0",
"some": "info"
}
```
- what sucks about it:
- `$` might be surprising or confusing
- response is a subset of valid JSON keys
(those not including `$`)
- what's nice about it:
- backwards-compatible with arbitrary JSON-object responses
which don't already use `$`
### Underscore Convention
- Same as above, but `_` instead of `$`
```json
{
"_": "api:thing",
"_version": "v1.0.0",
"some": "info"
}
```
- what sucks about it:
- `_` might be confusing
- response is a subset of valid JSON keys
(those not including `_`)
- what's nice about it:
- `_` is conventionally used for private property names,
so this might be a little less surprising
- backwards-compatible with arbitrary JSON-object responses
which don't already use `_`
### Nesting Convention, simplified
- Similar to the "obvious solution" except
metadata fields are lifted up a level.
It's relatively inconsequential if meta keys
have reserved words compared to value keys.
```json
{
"type": "api:thing",
"version": "v1.0.0",
"value": {
"some": "info"
}
}
```
### Modified Dollar/Underscore convention
- Using `_` in this example, but instead of prefixing
meta properties they all go under one key.
```json
{
"_": {
"type": "api:thing",
"version": "v1.0.0"
},
"some": "info"
}
```
- what sucks about it:
- `_` might be confusing
- response is a subset of valid JSON keys
(those not **exactly** `_`)
- what's nice about it:
- `_` is conventionally used for private property names,
so this might be a little less surprising
- backwards-compatible with arbitrary JSON-object responses
which don't already use `_` as an exact key
- only one reserved key
-12
View File
@@ -1,12 +0,0 @@
# Micro Modules
**CoreModule** has a large number of services. Each service handles
a general concern, like "notifications", but increasing this granularity
a little put more could allow a lot more code re-use.
One specific example that comes to mind is services that provide
CRUD operations for a database table. The **EntityStoreService** can
be used for a lot of these even though right now it's specifically
used for drivers. Having a common class of service like this can also
allow quickly configuring the equivalent service for providing those
CRUD operations through an API.
-149
View File
@@ -1,149 +0,0 @@
# Puter in Production
## Building
```bash
npm run build
```
## Usage
Will build Puter in the `dist` directory. Include the generated `./dist/gui.js` file in your HTML page and call `gui()` when the page is loaded:
```html
<script type="text/javascript" src="./dist/gui.js"></script>
<script type="text/javascript">
window.addEventListener('load', function() {
// Initialize the GUI. All options are optional!
gui({
// The origin of the app. This is the base URL of the GUI.
gui_origin: "https://puter.com",
// The origin of the API. This is the base URL of the API endpoints that the GUI will call for all its operations.
api_origin: "https://api.puter.com",
// The domain under which user websites are hosted.
hosting_domain: "puter.site",
// The maximum length of file/directory names.
max_item_name_length: 500,
// If GUI has to enforce email verification before allowing user to publish a website.
require_email_verification_to_publish_website: true,
})
});
</script>
```
## Full Production Example
Assuming the following directory structure in production:
```
.
├── dist/
│ ├── favicons/
│ ├── images/
│ ├── bundle.min.css
│ ├── bundle.min.js
│ ├── gui.js
│ └── ...
└── index.html
```
The `index.html` file below will load Puter and all the necessary meta tags, favicons, and branding assets:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Puter</title>
<meta name="author" content="Puter Technologies Inc.">
<meta name="description" content="Puter is a privacy-first personal cloud to keep all your files, apps, and games in one private and secure place, accessible from anywhere at any time.">
<meta name="facebook-domain-verification" content="e29w3hjbnnnypf4kzk2cewcdaxym1y" />
<link rel="canonical" href="https://puter.com">
<!-- Meta meta tags -->
<meta property="og:url" content="https://puter.com">
<meta property="og:type" content="website">
<meta property="og:title" content="Puter">
<meta property="og:description" content="Puter is a privacy-first personal cloud to keep all your files, apps, and games in one private and secure place, accessible from anywhere at any time.">
<meta property="og:image" content="./dist/images/screenshot.png">
<!-- Twitter meta tags -->
<meta name="twitter:card" content="summary_large_image">
<meta property="twitter:domain" content="puter.com">
<meta property="twitter:url" content="https://puter.com">
<meta name="twitter:title" content="Puter">
<meta name="twitter:description" content="Puter is a privacy-first personal cloud to keep all your files, apps, and games in one private and secure place, accessible from anywhere at any time.">
<meta name="twitter:image" content="./dist/images/screenshot.png">
<!-- favicons -->
<link rel="apple-touch-icon" sizes="57x57" href="./dist/favicons/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="./dist/favicons/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="./dist/favicons/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="./dist/favicons/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="./dist/favicons/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="./dist/favicons/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="./dist/favicons/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="./dist/favicons/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="./dist/favicons/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="./dist/favicons/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="./dist/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="./dist/favicons/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="./dist/favicons/favicon-16x16.png">
<link rel="manifest" href="./dist/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="./dist/favicons/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<!-- Preload images when applicable -->
<link rel="preload" as="image" href="./dist/images/wallpaper.webp">
</head>
<body>
<!-- Load the GUI script -->
<script type="text/javascript" src="./dist/gui.js"></script>
<!-- Initialize GUI when document is loaded -->
<script type="text/javascript">
window.addEventListener('load', function() {
gui()
});
</script>
</body>
</html>
```
### Server settings
The GUI is a single page application (SPA) and as best practice any route under root (`/*`) should preferably load the `index.html` file. However, there are situations where we want to load a custom page for a specific route: for example, the `/privacy` route may need to load a page that contains your privacy policy and has nothing to do with the GUI application. In these cases it is ok to load a custom page as long as the following essential GUI routes are loaded with the GUI (i.e. `index.html` file):
- `/app/*`
- `/action/*`
In other words, consider the routes above as "reserved" for Puter.
### Publish My Website
Right-click anywhere on the desktop to display options
From the options menu, select "New".
Then, choose "Folder".
Give the folder a name according to your preference.
After creating the folder:
Right-click on the folder.
Select the option "Publish as Website".
### Best Practices
- The `title` tags and meta tags (`<title></title>`, `<meta property="og:title"`, `<meta name="twitter:title"`, ...) should be dynamically set by the server. For example, if the URL is of an app (e.g. `https://puter.com/app/editor`) the `title` tags and meta tags should contain the app's title rather than the generic Puter title.
- The `description` meta tags (`<meta name="description"`, `<meta property="og:description"`, `<meta name="twitter:description"`, ...) should be dynamically set by the server. For example, if the URL is of an app (e.g. `https://puter.com/app/editor`) the `description` meta tags should contain the app's description rather than the generic Puter description.
- Make sure to escape any HTML code that is dynamically added to the HTML page. For example, if the app's description is `Puter is a <b>privacy-first</b> personal cloud to keep all your files, apps, and games in one private and secure place, accessible from anywhere at any time.` the `<b>` tag should be escaped to `&lt;b&gt;` so that the browser doesn't interpret it as an HTML tag.
- Make sure to replace all new line characters with space when dynamically adding text to the HTML page.
- Generally, for UX and SEO reasons make sure that the tags are filled with relevant information about the state the URL is representing. E.g. is the user on the desktop or an app?
-72
View File
@@ -1,72 +0,0 @@
# Configuring Domains for Self-Hosted Puter
## Local Network Configuration
### Prerequisite Conditions
Ensure the hosting device has a static IP address to prevent potential connectivity issues due to IP changes. This setup will enable seamless access to Puter and its services across your local network.
### Using Hosts Files
The hosts file is a straightforward way to map domain names to IP addresses on individual devices. It's simple to set up but requires manual changes on each device that needs access to the domains.
#### Windows
1. Open Notepad as an administrator.
2. Open the file located at `C:\Windows\System32\drivers\etc\hosts`.
3. Add lines for your domain and subdomain with the server's IP address, in the
following format:
```
192.168.1.10 puter.local
192.168.1.10 api.puter.local
```
#### For macOS and Linux:
1. Open a terminal.
2. Edit the hosts file with a text editor, e.g., `sudo nano /etc/hosts`.
3. Add lines for your domain and subdomain with the server's IP address, in the
following format:
```
192.168.1.10 puter.local
192.168.1.10 api.puter.local
```
4. Save and exit the editor.
### Using Router Configuration
Some routers allow you to add custom DNS rules, letting you configure domain names network-wide without touching each device.
1. Access your router’s admin interface (usually through a web browser).
2. Look for DNS or DHCP settings.
3. Add custom DNS mappings for `puter.local` and `api.puter.local` to the hosting device's IP address.
4. Save the changes and reboot the router if necessary.
This method's availability and steps may vary depending on your router's model and firmware.
### Using Local DNS
Setting up a local DNS server on your network allows for flexible and scalable domain name resolution. This method works across all devices automatically once they're configured to use the DNS server.
#### Options for DNS Software:
- **Pi-hole**: Acts as both an ad-blocker and a DNS server. Ideal for easy setup and maintenance.
- **BIND9**: Offers comprehensive DNS server capabilities for complex setups.
- **dnsmasq**: Lightweight and suitable for smaller networks or those new to running a DNS server.
**contributors note:** feel free to add any software you're aware of
which might help with this to the list. Also, feel free to add instructions here for specific software; our goal is for Puter to be easy to setup with tools you're already familiar with.
#### General Steps:
1. Choose and install DNS server software on a device within your network.
2. Configure the DNS server to resolve `puter.local` and `api.puter.local` to the IP address of your Puter hosting device.
3. Update your router's DHCP settings to distribute the DNS server's IP address to all devices on the network.
By setting up a local DNS server, you gain the most flexibility and control over your network's domain name resolution, ensuring that all devices can access Puter and its API without manual configuration.
## Production Configuration
Please note the self-hosting feature is still in alpha and a public production
deployment is not recommended at this time. However, if you wish to host
publicly you can do so following the same steps you normally would to configure
a domain name and ensuring the `api` subdomain points to the server as well.
-58
View File
@@ -1,58 +0,0 @@
# Self-Hosting Puter
> [!WARNING]
> The self-hosted version of Puter is currently in alpha stage and should not be used in production yet. It is under active development and may contain bugs, other issues. Please exercise caution and use it for testing and evaluation purposes only.
### Self-Hosting Differences
Currently, the self-hosted version of Puter is different in a few ways from [Puter.com](https://puter.com):
- There is no built-in way to install or create other apps (see below)
- Several "core" apps are missing, such as **Code** or **Draw**, because we can't include them in this repository
- Some icons are different
Work is ongoing to improve the **App Center** and make it available on self-hosted.
Until then, it's possible to add other apps by manually editing the database file.
This process is not recommended unless you know what you are doing.
The file will appear after you first launch Puter, and should be found in `puter/data/puter-database.sqlite` for Docker,
or `volatile/runtime/puter-database.sqlite` otherwise.
You will need a database tool that can understand SQLite databases.
<br/>
## Configuration
Running the server will generate a configuration file in one of these locations:
- `config/config.json` when [Using Docker](#using-docker)
- `volatile/config/config.json` in [Local Development](#local-development)
- `/etc/puter/config.json` on a server (or within a Docker container)
### Domain Name
To access Puter on your device, you can simply go to the address printed in
the server console (usually `puter.localhost:4100`).
To access Puter from another device, a domain name must be configured, as well as
an `api` subdomain. For example, `example.local` might be the domain name pointing
to the IP address of the server running puter, and `api.example.com` must point to
this address as well. This domain must be specified in the configuration file
(usually `volatile/config/config.json`) as well.
See [domain configuration](./domains.md) for more information.
### Configure the Port
- You can specify a custom port by setting `http_port` to a desired value
- If you're using a reverse-proxy such as nginx or cloudflare, you should
also set `pub_port` to the public (external) port (usually `443`)
- If you have HTTPS enabled on your reverse-proxy, ensure that
`protocol` in config.json is set accordingly
### Default User
By default, Puter will create a user called `default_user`.
This user will have a randomly generated password, which will be printed
in the development console.
A warning will persist in the dev console until this user's
password is changed. Please login to this user and change the password as
your first step.
<br/>
-39
View File
@@ -1,39 +0,0 @@
## Puter Support Levels for Repository Updates
This document describes issues requiring repository changes;
which issues will be fixed by Puter's core team, and which ones
will be fixed if the community makes a contribution.
This document is not "law". It is provided only as a helpful guide
on what to expect.
### Level Glossary
| Name | Description |
| ---- | ----------- |
| Core | Core developers will fix this |
| Community | We will accept contributions to fix this |
| Mixed | Core developers will fix this if it's currently a priority |
### Issues and their Levels
| Issue | Priority |
| ----- | -------- |
| Security vulnerability | Core |
| Breaking change to SDK or API | Core |
| Bug in service in CoreModule | Core |
| Bug in a built-in app | Core |
| Login/init failure in Docker on `release` branch | Core |
| Login/init failure in Linux or OSX | Core |
| Login/init failure in Docker on `main` branch | Mixed |
| Login/init failure with specific configuration | Mixed |
| Login/init failure in Windows | Community |
## Puter Support for a Particular Deployment
If you experience issues on a self-hosted deployment we're here to
help. Some issues are related to configuration or environment, so
we may only be able to help in a limited capacity. Issues related
to data loss, data corruption, or security will have higher priority
over other issues with particular deployments.
+537
View File
@@ -0,0 +1,537 @@
# Self-Hosting Puter
`docker-compose.yml` brings up Puter **plus every external service it needs** — MariaDB, Valkey, DynamoDB-local, RustFS S3, Caddy — wired together. Closest thing to a production deployment you can self-manage on a single host.
## One-line installer (recommended)
```bash
curl -fsSL https://raw.githubusercontent.com/HeyPuter/puter/main/install.sh | sh
```
Generates secrets, writes `.env` + `puter/config/config.json`, downloads `docker-compose.yml` + `caddy/Caddyfile` from the OSS repo, and runs `docker compose up -d`. Re-running is safe — it won't overwrite existing config (set `PUTER_FORCE=1` to rotate). Use the manual steps below if you want to inspect or tweak each step yourself.
## Requirements
- **Docker** with the `compose` plugin.
- A **domain** with DNS access — you need a wildcard record (`*.your-domain.com` → server IP). Puter routes by subdomain (`api.<domain>`, `site.<domain>`, `app.<domain>`).
- Optional: **TLS certs** (or `certbot` to grab them — see Step 3).
## What's running
| Container | Image | Role |
| --------------- | ------------------------ | ---------------------------------------------------------- |
| `puter-caddy` | `caddy:2.11-alpine` | Reverse proxy on 80 (and 443 if TLS); forwards to Puter |
| `puter` | `ghcr.io/heyputer/puter` | The app |
| `puter-mariadb` | `mariadb:11` | SQL database — schema applied automatically on first boot |
| `puter-valkey` | `valkey/valkey:8-alpine` | Redis-compatible cache + rate-limiter |
| `puter-dynamo` | `amazon/dynamodb-local` | KV store — table auto-created on first boot |
| `puter-s3` | `rustfs/rustfs` | S3-compatible object storage (MinIO drop-in noted in file) |
| `puter-s3-init` | `amazon/aws-cli` | One-shot — creates the bucket on first boot, then exits |
Optional services (compose profile `ai`, opt-in):
| Container | Image | Role |
| ------------------- | --------------- | -------------------------------------------------------------- |
| `puter-ollama` | `ollama/ollama` | Local LLM provider (CPU; GPU passthrough opt-in) |
| `puter-ollama-init` | `ollama/ollama` | One-shot — pulls the default model (`tinyllama`) on first boot |
State lives under `./puter/data/<service>/`.
---
## Step 1 — Create `.env` and `puter/config/config.json`
> ⚠️ **Run this whole block in one shell session.** It generates secrets once and writes them into both `.env` (read by docker compose) and `config.json` (read by Puter). The two files **must** agree on the MariaDB password and the S3 secret — if they drift, MariaDB initialises with one password and Puter tries to log in with another, and you get `ER_ACCESS_DENIED_ERROR`.
```bash
MARIADB_ROOT_PASSWORD=$(openssl rand -hex 32)
MARIADB_PASSWORD=$(openssl rand -hex 32)
S3_SECRET_KEY=$(openssl rand -hex 32)
JWT_SECRET_V2=$(openssl rand -hex 64)
URL_SIGNATURE_SECRET=$(openssl rand -hex 64)
cat > .env <<EOF
HTTP_PORT=80
# HTTPS_PORT=443 # uncomment after enabling TLS in Step 3
MARIADB_ROOT_PASSWORD=$MARIADB_ROOT_PASSWORD
MARIADB_DATABASE=puter
MARIADB_USER=puter
MARIADB_PASSWORD=$MARIADB_PASSWORD
S3_ACCESS_KEY=puter
S3_SECRET_KEY=$S3_SECRET_KEY
S3_BUCKET=puter-local
EOF
mkdir -p puter/config puter/data puter/data/caddy puter/tls
cat > puter/config/config.json <<EOF
{
"domain": "puter.localhost",
"protocol": "http",
"pub_port": 80,
"env": "prod",
"static_hosting_domain": "site.puter.localhost",
"static_hosting_domain_alt": "host.puter.localhost",
"private_app_hosting_domain": "app.puter.localhost",
"private_app_hosting_domain_alt": "dev.puter.localhost",
"jwt_secret_v2": "$JWT_SECRET_V2",
"url_signature_secret": "$URL_SIGNATURE_SECRET",
"database": {
"engine": "mysql",
"host": "mariadb",
"port": 3306,
"user": "puter",
"password": "$MARIADB_PASSWORD",
"database": "puter",
"migrationPaths": ["/opt/puter/dist/src/backend/clients/database/migrations/mysql"]
},
"redis": {
"startupNodes": [{ "host": "valkey", "port": 6379 }],
"tls": false
},
"dynamo": {
"endpoint": "http://dynamo:8000",
"bootstrapTables": true,
"aws": {
"access_key": "fake",
"secret_key": "fake",
"region": "us-east-1"
}
},
"s3": {
"s3Config": {
"endpoint": "http://s3:9000",
"publicEndpoint": "http://s3.puter.localhost",
"accessKeyId": "puter",
"secretAccessKey": "$S3_SECRET_KEY",
"region": "us-east-1",
"forcePathStyle": true
}
},
"s3_bucket": "puter-local",
"s3_region": "us-east-1",
"providers": {
"ollama": { "enabled": false }
},
"meteringEnforcement": {
"subscriptions": false
},
"trust_proxy": 1
}
EOF
```
Replace `puter.localhost`, `site.puter.localhost`, `host.puter.localhost`, `dev.puter.localhost` and `app.puter.localhost` with your actual domain (or leave it for a localhost-only trial).
Why these knobs:
- `jwt_secret_v2` — the HMAC secret Puter signs and verifies auth tokens with (`kid: 'v2'` JWT header). The pre-v2 token format is retired: a token signed with the old `jwt_secret` no longer verifies, and holders are asked to sign in again. If you are upgrading from a release that had `jwt_secret`, drop it from your config — it is ignored.
- `env: "prod"` — the bundled `config.default.json` ships with `env: "dev"` (matches the source-tree `npm run start:gui` workflow, which expects webpack-dev-server emitting a CSS manifest). Self-host runs against pre-built static bundles, so `env: "prod"` makes the homepage emit the `/dist/bundle.min.css` `<link>` tag instead of waiting on a manifest that doesn't exist.
- `database.migrationPaths` — Puter applies the bundled MySQL/MariaDB schema on boot. The migration files are idempotent, so it is safe to leave this configured across restarts.
- `dynamo.bootstrapTables: true` — Puter creates its KV table on boot. **Only set against a local emulator**, never real AWS.
- `dynamo.aws` keys are dummies; DynamoDB-local doesn't validate them but the AWS SDK requires _something_. **Note:** DynamoDB uses `access_key` / `secret_key` (snake_case); S3 below uses `accessKeyId` / `secretAccessKey` (camelCase). Not interchangeable.
- `meteringEnforcement.subscriptions: false` — a few surfaces (the OpenAI/Anthropic-compatible AI endpoints) are declared paid-plan-only. A self-hosted install has no paid plans, so every account sits on the free policy and those routes would answer `402 subscription_required` for everyone. Turning the plan gates off opens them; nothing else about metering changes.
- `providers.ollama.enabled: false` — Puter auto-probes a local Ollama at `127.0.0.1:11434` by default; without one running you'd see `ECONNREFUSED` on every boot. To run a bundled Ollama, see [Optional: local LLM (Ollama)](#optional-local-llm-ollama) below.
- `s3.s3Config.forcePathStyle: true` — RustFS / MinIO / fauxqs need path-style URLs (`<endpoint>/<bucket>`). Real AWS S3 wants virtual-hosted (`<bucket>.<endpoint>`) — drop this flag (or set `false`) when you swap to real S3.
- `s3.s3Config.publicEndpoint` — `endpoint` (`http://s3:9000`) only resolves inside the docker network; presigned upload/download URLs handed to the browser need a host-reachable URL. Caddy routes the `s3.<domain>` subdomain to RustFS internally and preserves the Host header end-to-end (required for S3 signature validation), so the browser hits the same port/protocol as the rest of the app — no separate published port, no mixed-content surprises when you turn on TLS. Switch to `https://s3.<your-domain>` once you enable TLS in Step 3. Real AWS S3 doesn't need this — its endpoint is already public; drop the field entirely.
- `trust_proxy: 1` — Caddy terminates TLS and forwards `X-Forwarded-For`. Without this, `req.ip` is the docker-network address of the Caddy container instead of the real client IP, which breaks rate limiting and IP-based audit logs. `1` = one trusted hop (Caddy). Bump to `2` if you put Cloudflare in front of Caddy; never set `true` (it trusts every hop and makes XFF forgeable).
> If you ever change `MARIADB_PASSWORD` after first boot, `.env` alone won't update MariaDB — its credentials are baked into `./puter/data/mariadb/` on first init. Either rotate the password inside MariaDB by hand or `docker compose down && rm -rf ./puter/data/mariadb` to start fresh.
## Step 2 — Point DNS at the server \[Optional\]
In your DNS provider, add records for the main domain plus the subdomains Puter and Caddy route on (`api.*`, `site.*`, `app.*`, `s3.*`):
```
A puter.localhost → <your server's public IP>
A *.puter.localhost → <your server's public IP>
A site.puter.localhost → <your server's public IP>
A *.site.puter.localhost → <your server's public IP>
A host.puter.localhost → <your server's public IP>
A *.host.puter.localhost → <your server's public IP>
A app.puter.localhost → <your server's public IP>
A *.app.puter.localhost → <your server's public IP>
A dev.puter.localhost → <your server's public IP>
A *.dev.puter.localhost → <your server's public IP>
```
The wildcards are required — Puter routes via subdomains (`api.*`, `app.*`, etc.) and Caddy routes browser S3 traffic via `s3.*` to RustFS.
## Step 3 — TLS (recommended for public installs) \[Optional\]
Skip this for a quick local demo. Don't skip it for users typing passwords.
**Get a wildcard cert.** Easiest path with Let's Encrypt + DNS-01 (works for wildcards):
```bash
sudo certbot certonly --manual --preferred-challenges dns \
-d puter.localhost -d "*.puter.localhost" \
-d site.puter.localhost -d "*.site.puter.localhost" \
-d host.puter.localhost -d "*.host.puter.localhost" \
-d app.puter.localhost -d "*.app.puter.localhost" \
-d dev.puter.localhost -d "*.dev.puter.localhost"
```
The cert needs to cover `*.puter.localhost` so that `s3.puter.localhost` (browser S3 endpoint), plus Puter's own `api.*` / `app.*` subdomains, all validate.
> **Why not Caddy's automatic HTTPS?** Caddy issues certs over ACME by itself, but only for hostnames it knows up front, and only over HTTP-01 with the stock image. Puter serves every user's site and app on a subdomain it invents at runtime (`<name>.site.<domain>`, `<name>.app.<domain>`), which needs a **wildcard** cert — and wildcards require DNS-01, which requires a DNS-provider plugin that isn't in `caddy:2.11-alpine`. So `caddy/Caddyfile` sets `auto_https off` and reads the cert you supply below. If you'd rather have Caddy manage certs, build an image with the plugin for your DNS provider (`xcaddy build --with github.com/caddy-dns/<provider>`) and swap the `tls` line for a `tls { dns <provider> … }` block.
Drop the resulting `fullchain.pem` and `privkey.pem` into `./puter/tls/`.
**Wire Caddy to use them:**
1. Open [caddy/Caddyfile](../caddy/Caddyfile) and uncomment the `# :443 { … }` block at the bottom.
2. (Optional but recommended) Replace the plain `:80 { import puter_routes }` block with the `redir` version shown alongside it, to force HTTPS everywhere.
3. In [docker-compose.yml](../docker-compose.yml), uncomment the `443:443` port mapping under the `caddy` service.
4. In `.env`, uncomment `HTTPS_PORT=443`.
5. In `config.json`, switch:
```json
{ "protocol": "https", "pub_port": 443 }
```
…and update the S3 public endpoint:
```json
"s3": { "s3Config": { "publicEndpoint": "https://s3.puter.local", ... } }
```
## Running behind your own reverse proxy
The bundled `puter-caddy` mirrors production and is the supported default — it terminates TLS (Step 3) and forwards every Host to Puter. But plenty of self-hosters already run their own edge proxy (Traefik, nginx, HAProxy, a cloud load balancer, another Caddy). You can put Puter behind it instead; Puter doesn't terminate TLS itself in any setup, so "your proxy does TLS" is just a matter of pointing it at the Puter container and getting a handful of details right.
You can keep the bundled Caddy as the single hop your proxy talks to, or bypass it and forward straight to the Puter container on port `4100` (uncomment the `4100:4100` mapping under the `puter` service in [docker-compose.yml](../docker-compose.yml), or attach your proxy to the compose network). Either works — what matters is the rules below.
**The rules that actually matter** (getting any of these wrong is what causes the redirect loops and "Invalid Host header" failures people hit):
1. **Don't rewrite the `Host` header.** Puter routes entirely on Host — `api.<domain>`, `site.<domain>`, `app.<domain>` are all distinguished by the incoming host. Forward the original host through unchanged. Do **not** rewrite external hostnames to an internal name like `puter.local`; that forces you to remap every subdomain by hand and still breaks signed-URL and CORS checks. Most proxies preserve Host by default — just don't override it.
2. **The external domain must equal `domain` in your `config.json`.** If users reach the box at `puter.example.com`, then `domain` must be `puter.example.com` and the hosting domains must be its real subdomains (`site.puter.example.com`, `app.puter.example.com`, …) — exactly as the installer/`config.json` lays them out. Puter rejects hosts it doesn't recognize with `Invalid Host header`.
3. **Set `protocol` to match the public scheme.** When your proxy terminates TLS, set `"protocol": "https"` (installer: `PUTER_PROTOCOL=https`). Puter builds its origins, redirects, signed S3 URLs, and OIDC callback URLs from this — leave it `http` behind an HTTPS proxy and you get redirect loops, broken logins, and mixed-content errors.
4. **Forward the standard proxy headers.** Puter needs:
- `Host` — the original request host (rule 1).
- `X-Forwarded-Proto` — the **external** scheme (`https`), so Puter knows TLS was terminated upstream.
- `X-Forwarded-For` — the real client IP (rate limiting + audit logs).
- `Upgrade` / `Connection` — passed through for WebSocket / socket.io upgrades, or the realtime connection silently fails.
5. **Set `trust_proxy` to the number of hops in front of Puter.** One external proxy talking directly to Puter → `"trust_proxy": 1` (installer: `PUTER_TRUST_PROXY=1`). A second proxy in front (e.g. Cloudflare → your proxy → Puter) → `2`. This is the count of proxies between the client and Puter, **including** the bundled Caddy if you keep it. Too low and `req.ip` becomes a proxy address (breaks rate limiting); never set `true` (it trusts every hop and makes `X-Forwarded-For` forgeable).
6. **Route the wildcard to Puter.** Your proxy must forward `*.<domain>` (covering `api.*`, `app.*`, and `s3.<domain>`) and `*.site.<domain>` (and any other hosting domains) to Puter — same wildcard DNS as Step 2. Puter does the per-subdomain routing internally; the proxy just needs to hand it the traffic with the Host intact.
With those in place the rest of the stack is unchanged — `docker compose up -d` as below.
## Step 4 — Bring it up
Both [docker-compose.yml](../docker-compose.yml) and [caddy/Caddyfile](../caddy/Caddyfile) need to sit next to your `.env` — clone the repo, or copy those two paths out of it. The Caddyfile is bind-mounted read-only; if it's missing, Docker creates a *directory* at that path and `puter-caddy` dies with "not a directory".
```bash
docker compose up -d
```
First boot takes ~30s while MariaDB initialises and Puter applies the schema + default apps. Watch:
```bash
docker compose logs -f puter
```
Healthy startup:
```
[config] override from /etc/puter/config.json
[mysql] running migrations from /opt/puter/dist/src/backend/clients/database/migrations/mysql: 2 file(s)
[mysql] applied mysql_mig_1.sql (...)
[mysql] applied mysql_mig_2.sql (9 statements)
```
Then open **<https://puter.local>** (or `http://` if you skipped TLS). Login is `admin` — the temp password is printed once in the puter container logs on first boot:
```bash
docker compose logs puter | grep tmp_password
```
Change it in Settings after first login.
## Additional configuration
All optional. Drop any of the blocks below into `puter/config/config.json` and `docker compose restart puter`. See [config.template.jsonc](../config.template.jsonc) for the full list. Per-key documentation lives in [src/backend/types.ts](../src/backend/types.ts).
### PostgreSQL database
> **Community contribution — expect rough edges.** PostgreSQL support was contributed by the community and is not run by Puter.com production. It boots, applies the bundled schema, and exercises the common user/app/fsentry/session/permission/OIDC flows in the integration tests, but less-traveled SQL call sites may still need porting. If you hit a query that doesn't work on Postgres, please open an issue. For production self-hosting today, MariaDB/MySQL and SQLite are the supported defaults.
The bundled Docker Compose stack still defaults to MariaDB. To use PostgreSQL instead, run a PostgreSQL service yourself, point Puter at it, and use the PostgreSQL migration path:
```json
"database": {
"engine": "postgres",
"host": "postgres",
"port": 5432,
"user": "puter",
"password": "...",
"database": "puter",
"migrationPaths": ["/opt/puter/dist/src/backend/clients/database/migrations/postgres"]
}
```
You may use `"connectionString": "postgres://puter:...@postgres:5432/puter"` instead of the host/user/password fields. Puter only needs normal PostgreSQL connection details and the migration path; CloudNativePG is one possible Kubernetes operator, but no operator-specific manifests are required by Puter.
### Email (SMTP)
Used for password resets, email confirmation, and notifications. Without it those flows silently fail.
```json
"email": {
"from": "\"Puter\" <[email protected]>",
"host": "smtp.example.com",
"port": 587,
"secure": false,
"auth": { "user": "...", "pass": "..." }
}
```
To require email confirmation before login, also set `"strict_email_verification_required": true`.
To read the mail yourself instead of sending it, point the transport at a local SMTP sink — [MailHog](https://github.com/mailhog/MailHog) catches everything and serves it at `http://localhost:8025`. Publish both ports; a container that only exposes them is unreachable from the host:
```sh
docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
```
```json
"email": { "from": "\"Puter\" <[email protected]>", "host": "127.0.0.1", "port": 1025, "secure": false, "ignoreTLS": true }
```
Share email is on once a transport exists: a recipient who already has an account is emailed as well as notified in-app, and they opt out with the unsubscribe link the mail carries. Set `"share_email_notifications": false` to keep those in the app only — an address with no account is still emailed, since there is nothing else to reach them with.
### Sign in with Google (or another OIDC provider)
```json
"oidc": {
"providers": {
"google": {
"client_id": "...apps.googleusercontent.com",
"client_secret": "...",
"scopes": "openid email profile"
}
}
}
```
Add `https://puter.<your-domain>/auth/oidc/callback/login` to the OAuth client's authorized redirect URIs in the Google Cloud Console. For non-Google providers, replace `google` with a custom id and supply `authorization_endpoint` / `token_endpoint` / `userinfo_endpoint` explicitly.
### Sign in with Apple
```json
"oidc": {
"providers": {
"apple": {
"client_id": "com.example.your-service-id",
"team_id": "YOUR_TEAM_ID",
"key_id": "YOUR_KEY_ID",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
}
}
}
```
The `client_id` is your Apple Services ID. `team_id`, `key_id`, and `private_key` come from the Apple Developer Portal (Keys section — create a key with "Sign in with Apple" enabled). The `private_key` is the contents of the `.p8` file Apple provides. Add `https://puter.<your-domain>/auth/oidc/callback/login` and `https://puter.<your-domain>/auth/oidc/callback/signup` as return URLs in the Apple Services ID configuration.
### Sign in with Microsoft
```json
"oidc": {
"providers": {
"microsoft": {
"client_id": "YOUR_APPLICATION_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET_VALUE",
"tenant_id": "YOUR_TENANT_ID"
}
}
}
```
Register an app in the Azure Portal (Microsoft Entra ID → App registrations). The `client_id` is the Application (client) ID, `client_secret` is a client secret value, and `tenant_id` is the Directory (tenant) ID. Use `common` as `tenant_id` to allow any Microsoft account (personal and organizational); omit it to default to `common`. Add `https://puter.<your-domain>/auth/oidc/callback/login` and `https://puter.<your-domain>/auth/oidc/callback/signup` as redirect URIs under Authentication in the app registration.
### AI providers
Any provider with a key set is auto-enabled. Same shape as `ollama` above:
```json
"providers": {
"claude": { "apiKey": "sk-ant-..." },
"openai-completion": { "apiKey": "sk-..." },
"gemini": { "apiKey": "..." },
"openai-image-generation": { "apiKey": "sk-..." }
}
```
Full provider list (chat, image, video, TTS, OCR) is in the template.
### Per-user storage quota
Default is 100 MB per user.
```json
"storage_capacity": 5368709120, // 5 GB
"is_storage_limited": true
```
Set `is_storage_limited: false` for unlimited (bounded by host disk).
### Usage metering and budgets
Puter meters what an account costs to serve — bytes sent back, object-store
requests, KV capacity, AI tokens — against a monthly budget, and refuses the
operations that spend it once that budget is gone. The refusal is a `402` with
code `insufficient_funds`; reads that only describe things, and every kind of
deletion, stay available so an account can always see what it has and clear it.
On a self-hosted install this is almost certainly not what you want. There is
nowhere to buy more, so accounts are held to the free monthly allowance
(US$0.25 of measured cost — roughly 2 GiB of downloads) and start being refused
after that. Turn it off:
```json
"unlimitedMetering": true
```
Every account then resolves to an unlimited policy. Usage is still recorded, so
the dashboard still shows what is being consumed; nothing is ever refused for
lack of budget.
To keep the budgets but stop them blocking anything — recording only:
```json
"meteringEnforcement": { "enabled": false }
```
Calls driven by a deployed worker are exempt from enforcement by default,
because a worker has no prompt to show and nobody watching it fail. Set
`"meteringEnforcement": { "workers": true }` to include them.
### Captcha on signup / login
Built-in proof-of-work captcha — no external service needed.
```json
"captcha": { "enabled": true, "difficulty": "medium" }
```
`difficulty` is one of `easy` / `medium` / `hard`.
### Disable new signups
Force visitors to log in with an existing account instead of creating a
temporary or permanent one.
```json
"disable_user_signup": true
```
### Block disposable email TLDs
Only enforced when `env: "prod"`.
```json
"blockedEmailDomains": ["mailinator.com", "tempmail.com", "guerrillamail.com"]
```
### Password policy
```json
"min_pass_length": 12
```
### Contact-form recipient
Where the in-app contact form posts. Defaults to `support@puter.com`.
```json
"support_email": "[email protected]"
```
## Optional: local LLM (Ollama)
The `ollama` and `ollama-init` services live behind a compose profile so they don't run unless you ask for them. By default, `puter/config/config.json` has `"ollama": { "enabled": false }` — Puter skips the auto-probe entirely. To run a local model:
1. Flip the config:
```json
"providers": {
"ollama": { "apiBaseUrl": "http://ollama:11434" }
}
```
2. (Optional) Pick a model in `.env`:
```bash
OLLAMA_DEFAULT_MODEL=tinyllama # default — 1.1B, ~640 MB on disk, ~700 MB RAM
# Other tiny picks: qwen2.5:0.5b, llama3.2:1b
# Larger / better: phi3.5, llama3.2, mistral
```
3. Bring up with the `ai` profile:
```bash
docker compose --profile ai up -d
docker compose logs -f ollama-init
```
`ollama-init` exits 0 once the model is pulled. Subsequent boots find the model already on disk and the pull is a fast no-op.
Without `--profile ai`, the `ollama` containers stay down and Puter (with `enabled: false`) doesn't try to reach them — the rest of the stack runs identically.
For GPU acceleration (NVIDIA), uncomment the `deploy:` block under the `ollama` service in [docker-compose.yml](../docker-compose.yml). Requires `nvidia-container-toolkit` on the host.
## Building from source instead of pulling
If you want to test local Dockerfile changes against the full stack, uncomment the `build:` block in [docker-compose.yml](../docker-compose.yml) under the `puter` service, change `pull_policy: always` → `pull_policy: never`, then:
```bash
docker compose up -d --build
```
---
## Managing running backend
```bash
# update
docker compose pull
docker compose up -d
# logs
docker compose logs -f puter
# stop, keep data
docker compose down
# stop, NUKE all state (irreversible)
docker compose down
rm -rf puter/data
```
Migrations re-apply idempotently across pulls. Volumes are preserved.
## Troubleshooting
**Site loads but I get a 502 / "Bad Gateway" from Caddy.**
The puter container failed to come up. `docker compose logs puter` will tell you which dependency rejected it (most often DB password mismatch between `.env` and `config.json`).
**Login screen says "admin password not set".**
First-boot temp password is logged once. Find it: `docker compose logs puter | grep "tmp_password"`. After login, change it in Settings.
**Healthcheck reports unhealthy but the site works.**
The healthcheck hits `puter.localhost:4100/test` from inside the container. If you changed `domain` or `port`, the check still uses defaults. The site itself is fine.
**Nothing resolves at `puter.example.com` after DNS changes.**
DNS propagates slowly. `dig puter.example.com` and `dig api.puter.example.com` should both return your server IP. If not, give it 5–60 minutes.
**`docker compose up` hangs at "waiting for service to be healthy".**
`docker compose ps` shows which container is unhealthy. MariaDB takes ~20–30s on a cold boot; everything else under 5s. If something stays unhealthy, `logs <service>` will tell you why.
**`Error: DynamoDB aws config requires both access_key and secret_key`.**
You wrote `accessKeyId` / `secretAccessKey` under `dynamo.aws`. That config block uses snake_case (`access_key` / `secret_key`). Only the `s3.s3Config` block uses camelCase.
-31
View File
@@ -1,31 +0,0 @@
# Testing with Email
Testing anything involving email is really simple using [mailhog](https://github.com/mailhog/MailHog)
### Step 1: Configure email service
In your `config.json` for Puter (`volatile/config/config.json` usually, `/var/puter/config.json` in containers),
add this entry to the `"services`" map:
```javascript
"services": {
// ... there are probably other service configs
"email": {
"host": "localhost",
"port": 1025
}
}
```
### Step 2: Install and run mailhog
Follow the instructions on [MailHog](https://github.com/mailhog/MailHog)'s
repository, or install through your distro's package manager.
Run the command: `mailhog`.
You should now have an inbox at [http://127.0.0.1:8025](http://127.0.0.1:8025).
Every email that Puter sends will show up on this page.
Loaded 100 of 3026 files, more files were not shown because too many files have changed in this diff. Show more