Full Code of HeyPuter/puter for AI

main b526c08ffe7f cached
1698 files
10.9 MB
3.0M tokens
4551 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (11,776K chars total). Download the full file to get everything.
Repository: HeyPuter/puter
Branch: main
Commit: b526c08ffe7f
Files: 1698
Total size: 10.9 MB

Directory structure:
gitextract_iu1nqdoe/

├── .dockerignore
├── .env.example
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── docker-image.yaml
│       ├── main.yml
│       ├── notify-prod.yaml
│       ├── release-please.yml
│       └── test.yml
├── .gitignore
├── .gitmodules
├── .husky/
│   └── pre-commit
├── .idx/
│   └── dev.nix
├── .is_puter_repository
├── .npmrc
├── .prettierignore
├── BUG-BOUNTY.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE.txt
├── README.md
├── SECURITY-ACKNOWLEDGEMENTS.md
├── SECURITY.md
├── TRADEMARK.md
├── doc/
│   ├── AI.md
│   ├── File Structure.drawio
│   ├── README.md
│   ├── RFCS/
│   │   └── 20250826_captcha_cloudflare_turnstile.md
│   ├── api/
│   │   ├── README.md
│   │   ├── concepts/
│   │   │   └── share-link.md
│   │   ├── drivers.md
│   │   ├── group.md
│   │   ├── notifications.md
│   │   ├── share.md
│   │   ├── type-tagged.md
│   │   └── types/
│   │       ├── app-share.md
│   │       └── file-share.md
│   ├── contributors/
│   │   ├── comment_prefixes.md
│   │   ├── email_testing.md
│   │   ├── extensions/
│   │   │   ├── README.md
│   │   │   ├── definitions.md
│   │   │   ├── dev-console.md
│   │   │   ├── events.json.js
│   │   │   ├── events.md
│   │   │   ├── gen.js
│   │   │   └── manual_overrides.json.js
│   │   ├── extensions.md
│   │   ├── structure.md
│   │   └── vscode.md
│   ├── devlog.md
│   ├── devmeta/
│   │   └── track-comments.md
│   ├── docmeta.md
│   ├── i18n/
│   │   ├── README.ar.md
│   │   ├── README.bn.md
│   │   ├── README.da.md
│   │   ├── README.de.md
│   │   ├── README.en.md
│   │   ├── README.es.md
│   │   ├── README.fa.md
│   │   ├── README.fi.md
│   │   ├── README.fr.md
│   │   ├── README.he.md
│   │   ├── README.hi.md
│   │   ├── README.hu.md
│   │   ├── README.hy.md
│   │   ├── README.id.md
│   │   ├── README.it.md
│   │   ├── README.jp.md
│   │   ├── README.ko.md
│   │   ├── README.ml.md
│   │   ├── README.my.md
│   │   ├── README.nl.md
│   │   ├── README.od.md
│   │   ├── README.pa.md
│   │   ├── README.pl.md
│   │   ├── README.pt.md
│   │   ├── README.ro.md
│   │   ├── README.ru.md
│   │   ├── README.sv.md
│   │   ├── README.ta.md
│   │   ├── README.te.md
│   │   ├── README.th.md
│   │   ├── README.tr.md
│   │   ├── README.ua.md
│   │   ├── README.ur.md
│   │   ├── README.vi.md
│   │   └── README.zh.md
│   ├── license_header.txt
│   ├── planning/
│   │   ├── 2025-10-21_puter-fs-extension.md
│   │   ├── alternatives-to-$.md
│   │   └── micro-modules.md
│   ├── prod.md
│   ├── self-hosters/
│   │   ├── config-vals.json.js
│   │   ├── config.md
│   │   ├── config_values.md
│   │   ├── domains.md
│   │   ├── first-run-issues.md
│   │   ├── gen.js
│   │   ├── instructions.md
│   │   └── support.md
│   ├── test/
│   │   └── playwright-test.md
│   ├── testing_with_email.md
│   └── uncategorized/
│       ├── README.md
│       ├── es6-note.md
│       └── puter-mods.md
├── docker-compose.yml
├── eslint/
│   ├── bang-space-if.js
│   ├── control-structure-spacing.js
│   ├── mandatory.eslint.config.js
│   └── space-unary-ops-with-exception.js
├── eslint.config.js
├── exports.js
├── extensions/
│   ├── .gitkeep
│   ├── README.md
│   ├── api.d.ts
│   ├── app-telemetry/
│   │   ├── app-user-count.ts
│   │   ├── index.d.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   ├── data.js
│   ├── example-kv.js
│   ├── example_gui_extension.js
│   ├── exports_something.js
│   ├── extension-util.js
│   ├── extensionController/
│   │   ├── package.json
│   │   ├── puter.json
│   │   ├── src/
│   │   │   ├── ExtensionController.ts
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── hellodriver/
│   │   ├── config.json
│   │   ├── hellodriver.js
│   │   └── package.json
│   ├── imports_something.js
│   ├── metering/
│   │   ├── config.json
│   │   ├── controllers/
│   │   │   └── UsageController.ts
│   │   ├── eventListeners/
│   │   │   └── subscriptionEvents.ts
│   │   ├── main.ts
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   └── types.ts
│   ├── puterfs/
│   │   ├── PuterFSProvider.js
│   │   ├── fsentries/
│   │   │   ├── BaseOperation.js
│   │   │   ├── Delete.js
│   │   │   ├── FSEntryController.js
│   │   │   ├── Insert.js
│   │   │   └── Update.js
│   │   ├── lib/
│   │   │   └── objectfn.js
│   │   ├── main.js
│   │   ├── package.json
│   │   └── storage/
│   │       ├── LocalDiskStorageController.js
│   │       └── ProxyStorageController.js
│   ├── serverInfo/
│   │   ├── config.json
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   └── types.ts
│   ├── tsconfig.json
│   ├── utilities.js
│   ├── whoami/
│   │   ├── main.js
│   │   ├── package.json
│   │   └── routes.js
│   └── worker-sandbox.js
├── install.md
├── mod_packages/
│   └── testex/
│       └── package.json
├── mods/
│   ├── README.md
│   ├── mods_available/
│   │   ├── dev-socket/
│   │   │   ├── main.js
│   │   │   └── package.json
│   │   ├── example/
│   │   │   ├── main.js
│   │   │   └── package.json
│   │   ├── example-singlefile.js
│   │   ├── kdmod/
│   │   │   ├── CustomPuterService.js
│   │   │   ├── README.md
│   │   │   ├── ShareTestService.js
│   │   │   ├── data/
│   │   │   │   └── sharetest_scenarios.js
│   │   │   ├── gui/
│   │   │   │   └── main.js
│   │   │   ├── module.js
│   │   │   └── package.json
│   │   ├── test-actions/
│   │   │   ├── main.js
│   │   │   └── package.json
│   │   └── testex.js
│   └── mods_enabled/
│       └── .gitignore
├── package.json
├── rust-toolchain.toml
├── scripts/
│   └── gen.sh
├── src/
│   ├── backend/
│   │   ├── .gitignore
│   │   ├── CONTRIBUTING.md
│   │   ├── README.md
│   │   ├── doc/
│   │   │   ├── A-and-A/
│   │   │   │   ├── auth.md
│   │   │   │   └── permission.md
│   │   │   ├── Kernel.md
│   │   │   ├── README.md
│   │   │   ├── contributors/
│   │   │   │   ├── boot-sequence.md
│   │   │   │   ├── coding-style.md
│   │   │   │   ├── modules.md
│   │   │   │   └── structure.md
│   │   │   ├── dev_socket.md
│   │   │   ├── extensions/
│   │   │   │   ├── README.md
│   │   │   │   ├── builtins/
│   │   │   │   │   └── data.md
│   │   │   │   └── pages/
│   │   │   │       ├── core-devs.md
│   │   │   │       ├── drivers.md
│   │   │   │       ├── import-and-export.md
│   │   │   │       └── runtime-modules.md
│   │   │   ├── features/
│   │   │   │   ├── batch-and-symlinks.md
│   │   │   │   ├── protected-apps.md
│   │   │   │   └── service-scripts.md
│   │   │   ├── howto_make_driver.md
│   │   │   ├── license_header.txt
│   │   │   ├── lists-of-things/
│   │   │   │   ├── list-of-permissions.md
│   │   │   │   └── list-of-tto-types.md
│   │   │   ├── log_config.md
│   │   │   ├── modules/
│   │   │   │   ├── filesystem/
│   │   │   │   │   └── API_SPEC.md
│   │   │   │   └── puterai/
│   │   │   │       └── README.md
│   │   │   ├── notes/
│   │   │   │   └── 2024-10-03_email_in_use_checks.md
│   │   │   └── services/
│   │   │       ├── config.md
│   │   │       ├── event_buses.md
│   │   │       ├── http.md
│   │   │       └── log.md
│   │   ├── exports.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── CoreModule.js
│   │   │   ├── DatabaseModule.js
│   │   │   ├── Extension.js
│   │   │   ├── ExtensionModule.js
│   │   │   ├── ExtensionService.js
│   │   │   ├── Kernel.js
│   │   │   ├── LocalDiskStorageModule.js
│   │   │   ├── MemoryStorageModule.js
│   │   │   ├── annotatedobjects.js
│   │   │   ├── api/
│   │   │   │   ├── APIError.js
│   │   │   │   ├── PathOrUIDValidator.js
│   │   │   │   ├── api_error_handler.js
│   │   │   │   ├── eggspress.js
│   │   │   │   └── filesystem/
│   │   │   │       ├── FSNodeParam.js
│   │   │   │       ├── FlagParam.js
│   │   │   │       ├── StringParam.js
│   │   │   │       └── UserParam.js
│   │   │   ├── boot/
│   │   │   │   ├── BootLogger.js
│   │   │   │   ├── RuntimeEnvironment.js
│   │   │   │   └── default_config.js
│   │   │   ├── clients/
│   │   │   │   ├── dynamodb/
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── DDBClient.ts
│   │   │   │   │   └── DDBClientWrapper.ts
│   │   │   │   └── redis/
│   │   │   │       ├── .gitignore
│   │   │   │       ├── cacheUpdate.ts
│   │   │   │       ├── deleteRedisKeys.ts
│   │   │   │       ├── redisSingleton.test.ts
│   │   │   │       └── redisSingleton.ts
│   │   │   ├── codex/
│   │   │   │   ├── CodeUtil.js
│   │   │   │   ├── README.md
│   │   │   │   └── Sequence.js
│   │   │   ├── config/
│   │   │   │   ├── ConfigLoader.js
│   │   │   │   ├── deep_proto_merge.js
│   │   │   │   └── reserved_words.js
│   │   │   ├── config.d.ts
│   │   │   ├── config.js
│   │   │   ├── consts/
│   │   │   │   └── app-icons.js
│   │   │   ├── data/
│   │   │   │   └── hardcoded-permissions.js
│   │   │   ├── definitions/
│   │   │   │   └── SimpleEntity.js
│   │   │   ├── entities/
│   │   │   │   └── Group.js
│   │   │   ├── env
│   │   │   ├── errors/
│   │   │   │   ├── TechnicalError.js
│   │   │   │   └── error_help_details.js
│   │   │   ├── extension/
│   │   │   │   ├── RuntimeModule.js
│   │   │   │   └── RuntimeModuleRegistry.js
│   │   │   ├── filesystem/
│   │   │   │   ├── ECMAP.js
│   │   │   │   ├── FSNodeContext.js
│   │   │   │   ├── FilesystemService.js
│   │   │   │   ├── batch/
│   │   │   │   │   ├── BatchExecutor.js
│   │   │   │   │   └── commands.js
│   │   │   │   ├── definitions/
│   │   │   │   │   ├── capabilities.js
│   │   │   │   │   ├── proto/
│   │   │   │   │   │   └── fsentry.proto
│   │   │   │   │   └── ts/
│   │   │   │   │       ├── fsentry.js
│   │   │   │   │       └── fsentry.ts
│   │   │   │   ├── hl_operations/
│   │   │   │   │   ├── definitions.js
│   │   │   │   │   ├── hl_copy.js
│   │   │   │   │   ├── hl_data_read.js
│   │   │   │   │   ├── hl_mkdir.js
│   │   │   │   │   ├── hl_mklink.js
│   │   │   │   │   ├── hl_mkshortcut.js
│   │   │   │   │   ├── hl_move.js
│   │   │   │   │   ├── hl_name_search.js
│   │   │   │   │   ├── hl_read.js
│   │   │   │   │   ├── hl_readdir.js
│   │   │   │   │   ├── hl_remove.js
│   │   │   │   │   ├── hl_stat.js
│   │   │   │   │   └── hl_write.js
│   │   │   │   ├── lib/
│   │   │   │   │   └── PuterPath.js
│   │   │   │   ├── ll_operations/
│   │   │   │   │   ├── definitions.js
│   │   │   │   │   ├── ll_copy.js
│   │   │   │   │   ├── ll_copy_idea.js
│   │   │   │   │   ├── ll_listusers.js
│   │   │   │   │   ├── ll_mkdir.js
│   │   │   │   │   ├── ll_move.js
│   │   │   │   │   ├── ll_read.js
│   │   │   │   │   ├── ll_readdir.js
│   │   │   │   │   ├── ll_readshares.js
│   │   │   │   │   ├── ll_rmdir.js
│   │   │   │   │   ├── ll_rmnode.js
│   │   │   │   │   └── ll_write.js
│   │   │   │   ├── node/
│   │   │   │   │   ├── selectors.js
│   │   │   │   │   └── states.js
│   │   │   │   ├── storage/
│   │   │   │   │   └── UploadProgressTracker.js
│   │   │   │   ├── strategies/
│   │   │   │   │   ├── README.md
│   │   │   │   │   └── storage_a/
│   │   │   │   │       ├── LocalDiskStorageStrategy.js
│   │   │   │   │       └── README.md
│   │   │   │   ├── validation.bench.js
│   │   │   │   └── validation.js
│   │   │   ├── helpers.js
│   │   │   ├── index.js
│   │   │   ├── kernel/
│   │   │   │   └── modutil.js
│   │   │   ├── loadTestConfig.js
│   │   │   ├── middleware/
│   │   │   │   ├── abuse.js
│   │   │   │   ├── anticsrf.js
│   │   │   │   ├── auth.js
│   │   │   │   ├── auth2.js
│   │   │   │   ├── configurable_auth.js
│   │   │   │   ├── featureflag.js
│   │   │   │   ├── measure.js
│   │   │   │   ├── subdomain.js
│   │   │   │   └── verified.js
│   │   │   ├── modules/
│   │   │   │   ├── ai/
│   │   │   │   │   └── PuterAIChatModule.js
│   │   │   │   ├── apps/
│   │   │   │   │   ├── AppIconService.js
│   │   │   │   │   ├── AppIconService.test.js
│   │   │   │   │   ├── AppInformationService.js
│   │   │   │   │   ├── AppPermissionService.js
│   │   │   │   │   ├── AppRedisCacheSpace.js
│   │   │   │   │   ├── AppsModule.js
│   │   │   │   │   ├── OldAppNameService.js
│   │   │   │   │   ├── ProtectedAppService.js
│   │   │   │   │   ├── RecommendedAppsRedisCacheSpace.js
│   │   │   │   │   ├── RecommendedAppsService.js
│   │   │   │   │   ├── default-app-icon.js
│   │   │   │   │   ├── lib/
│   │   │   │   │   │   └── IconResult.js
│   │   │   │   │   └── privateLaunchAccess.js
│   │   │   │   ├── broadcast/
│   │   │   │   │   ├── BroadcastModule.js
│   │   │   │   │   ├── BroadcastService.js
│   │   │   │   │   └── BroadcastService.redisPubSub.test.js
│   │   │   │   ├── captcha/
│   │   │   │   │   ├── CaptchaModule.js
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── middleware/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   └── captcha-middleware.js
│   │   │   │   │   └── services/
│   │   │   │   │       └── CaptchaService.js
│   │   │   │   ├── core/
│   │   │   │   │   ├── AlarmService.d.ts
│   │   │   │   │   ├── AlarmService.js
│   │   │   │   │   ├── ContextService.js
│   │   │   │   │   ├── Core2Module.js
│   │   │   │   │   ├── ErrorService.js
│   │   │   │   │   ├── ExpectationService.js
│   │   │   │   │   ├── LogService.js
│   │   │   │   │   ├── PagerService.js
│   │   │   │   │   ├── ParameterService.js
│   │   │   │   │   ├── ProcessEventService.js
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── ServerHealthService/
│   │   │   │   │   │   ├── ServerHealthRedisCacheKeys.js
│   │   │   │   │   │   └── ServerHealthService.js
│   │   │   │   │   └── lib/
│   │   │   │   │       ├── __lib__.js
│   │   │   │   │       ├── expect.js
│   │   │   │   │       ├── identifier.js
│   │   │   │   │       ├── linux.js
│   │   │   │   │       ├── log.js
│   │   │   │   │       └── stdio.js
│   │   │   │   ├── data-access/
│   │   │   │   │   ├── AppRepository.js
│   │   │   │   │   ├── AppService.comp.test.js
│   │   │   │   │   ├── AppService.js
│   │   │   │   │   ├── AppService.test.js
│   │   │   │   │   ├── DEV.md
│   │   │   │   │   ├── DataAccessModule.js
│   │   │   │   │   └── lib/
│   │   │   │   │       ├── coercion.js
│   │   │   │   │       ├── error.js
│   │   │   │   │       ├── filter.js
│   │   │   │   │       ├── sqlutil.js
│   │   │   │   │       └── validation.js
│   │   │   │   ├── development/
│   │   │   │   │   ├── DevelopmentModule.js
│   │   │   │   │   └── LocalTerminalService.js
│   │   │   │   ├── dns/
│   │   │   │   │   ├── DNSModule.js
│   │   │   │   │   └── DNSService.js
│   │   │   │   ├── domain/
│   │   │   │   │   ├── DomainModule.js
│   │   │   │   │   ├── DomainVerificationService.js
│   │   │   │   │   └── TXTVerifyService.js
│   │   │   │   ├── entitystore/
│   │   │   │   │   ├── EntityStoreInterfaceService.js
│   │   │   │   │   └── EntityStoreModule.js
│   │   │   │   ├── filesystem/
│   │   │   │   │   └── roadmap.md
│   │   │   │   ├── hostos/
│   │   │   │   │   ├── HostOSModule.js
│   │   │   │   │   └── ProcessService.js
│   │   │   │   ├── internet/
│   │   │   │   │   ├── InternetModule.js
│   │   │   │   │   └── WispRelayService.js
│   │   │   │   ├── kvstore/
│   │   │   │   │   ├── KVStoreInterfaceService.js
│   │   │   │   │   └── KVStoreModule.js
│   │   │   │   ├── perfmon/
│   │   │   │   │   └── TelemetryService.js
│   │   │   │   ├── puterfs/
│   │   │   │   │   ├── MountpointService.js
│   │   │   │   │   ├── PuterFSModule.js
│   │   │   │   │   ├── ResourceService.js
│   │   │   │   │   ├── SizeService.js
│   │   │   │   │   └── customfs/
│   │   │   │   │       ├── MemoryFSProvider.js
│   │   │   │   │       ├── MemoryFSService.js
│   │   │   │   │       └── README.md
│   │   │   │   ├── selfhosted/
│   │   │   │   │   ├── DefaultUserService.js
│   │   │   │   │   ├── DevCreditService.js
│   │   │   │   │   ├── DevWatcherService.js
│   │   │   │   │   ├── SelfHostedModule.js
│   │   │   │   │   ├── SelfhostedService.js
│   │   │   │   │   ├── ServeSingeFileService.js
│   │   │   │   │   └── ServeStaticFilesService.js
│   │   │   │   ├── template/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── TemplateModule.js
│   │   │   │   │   ├── TemplateService.js
│   │   │   │   │   └── lib/
│   │   │   │   │       ├── __lib__.js
│   │   │   │   │       └── hello_world.js
│   │   │   │   ├── test-config/
│   │   │   │   │   ├── TestConfigModule.js
│   │   │   │   │   ├── TestConfigReadService.js
│   │   │   │   │   └── TestConfigUpdateService.js
│   │   │   │   ├── test-core/
│   │   │   │   │   └── TestCoreModule.js
│   │   │   │   ├── test-drivers/
│   │   │   │   │   ├── TestAssetHostService.js
│   │   │   │   │   ├── TestDriversModule.js
│   │   │   │   │   ├── TestImageService.js
│   │   │   │   │   └── doc/
│   │   │   │   │       └── requests.md
│   │   │   │   └── web/
│   │   │   │       ├── APIErrorService.js
│   │   │   │       ├── README.md
│   │   │   │       ├── SocketioService.js
│   │   │   │       ├── WebModule.js
│   │   │   │       ├── WebServerService.d.ts
│   │   │   │       ├── WebServerService.js
│   │   │   │       └── lib/
│   │   │   │           ├── __lib__.js
│   │   │   │           ├── api_error_handler.js
│   │   │   │           └── eggspress.js
│   │   │   ├── om/
│   │   │   │   ├── IdentifierUtil.js
│   │   │   │   ├── definitions/
│   │   │   │   │   ├── Mapping.js
│   │   │   │   │   ├── PropType.js
│   │   │   │   │   ├── PropType.test.js
│   │   │   │   │   └── Property.js
│   │   │   │   ├── docs/
│   │   │   │   │   └── DESIGN.md
│   │   │   │   ├── entitystorage/
│   │   │   │   │   ├── AppES.js
│   │   │   │   │   ├── AppLimitedES.js
│   │   │   │   │   ├── BaseES.js
│   │   │   │   │   ├── ESBuilder.js
│   │   │   │   │   ├── Entity.js
│   │   │   │   │   ├── MaxLimitES.js
│   │   │   │   │   ├── NotificationES.js
│   │   │   │   │   ├── OwnerLimitedES.js
│   │   │   │   │   ├── ProtectedAppES.js
│   │   │   │   │   ├── ReadOnlyES.js
│   │   │   │   │   ├── SQLES.js
│   │   │   │   │   ├── SetOwnerES.js
│   │   │   │   │   ├── SubdomainES.js
│   │   │   │   │   ├── ValidationES.js
│   │   │   │   │   ├── WriteByOwnerOnlyES.js
│   │   │   │   │   └── consts.js
│   │   │   │   ├── mappings/
│   │   │   │   │   ├── __all__.js
│   │   │   │   │   ├── access-token.js
│   │   │   │   │   ├── app.js
│   │   │   │   │   ├── notification.js
│   │   │   │   │   └── subdomain.js
│   │   │   │   ├── proptypes/
│   │   │   │   │   ├── __all__.js
│   │   │   │   │   └── __all__.test.js
│   │   │   │   └── query/
│   │   │   │       ├── query.js
│   │   │   │       └── query.test.js
│   │   │   ├── polyfill/
│   │   │   │   └── to-string-higher-radix.js
│   │   │   ├── public/
│   │   │   │   └── assets/
│   │   │   │       ├── css/
│   │   │   │       │   ├── admin.css
│   │   │   │       │   └── style.css
│   │   │   │       ├── img/
│   │   │   │       │   ├── logo-bold.psd
│   │   │   │       │   └── logo.psd
│   │   │   │       └── js/
│   │   │   │           └── app.js
│   │   │   ├── routers/
│   │   │   │   ├── _default.js
│   │   │   │   ├── apps.js
│   │   │   │   ├── auth/
│   │   │   │   │   ├── app-uid-from-origin.js
│   │   │   │   │   ├── check-app-acl.endpoint.js
│   │   │   │   │   ├── check-app.js
│   │   │   │   │   ├── check-permissions.js
│   │   │   │   │   ├── configure-2fa.js
│   │   │   │   │   ├── create-access-token.js
│   │   │   │   │   ├── get-user-app-token.js
│   │   │   │   │   ├── grant-dev-app.js
│   │   │   │   │   ├── grant-user-app.js
│   │   │   │   │   ├── grant-user-group.js
│   │   │   │   │   ├── grant-user-user.js
│   │   │   │   │   ├── list-permissions.js
│   │   │   │   │   ├── list-sessions.js
│   │   │   │   │   ├── oidc.js
│   │   │   │   │   ├── request-app-root-dir.js
│   │   │   │   │   ├── revoke-access-token.js
│   │   │   │   │   ├── revoke-dev-app.js
│   │   │   │   │   ├── revoke-session.js
│   │   │   │   │   ├── revoke-user-app.js
│   │   │   │   │   ├── revoke-user-group.js
│   │   │   │   │   └── revoke-user-user.js
│   │   │   │   ├── change_email.js
│   │   │   │   ├── change_username.js
│   │   │   │   ├── confirmEmail/
│   │   │   │   │   ├── ConfirmEmailRedisCacheSpace.js
│   │   │   │   │   └── confirm-email.js
│   │   │   │   ├── contactUs.js
│   │   │   │   ├── delete-site.js
│   │   │   │   ├── df.js
│   │   │   │   ├── down.js
│   │   │   │   ├── drivers/
│   │   │   │   │   ├── call.js
│   │   │   │   │   ├── list-interfaces.js
│   │   │   │   │   ├── usage.js
│   │   │   │   │   └── xd.js
│   │   │   │   ├── file.js
│   │   │   │   ├── filesystem_api/
│   │   │   │   │   ├── batch/
│   │   │   │   │   │   ├── PathResolver.js
│   │   │   │   │   │   └── all.js
│   │   │   │   │   ├── cache.js
│   │   │   │   │   ├── copy.js
│   │   │   │   │   ├── delete.js
│   │   │   │   │   ├── mkdir.js
│   │   │   │   │   ├── move.js
│   │   │   │   │   ├── read.js
│   │   │   │   │   ├── readdir-subdomains.mjs
│   │   │   │   │   ├── readdir.js
│   │   │   │   │   ├── rename.js
│   │   │   │   │   ├── search.js
│   │   │   │   │   ├── stat.js
│   │   │   │   │   ├── token-read.js
│   │   │   │   │   ├── touch.js
│   │   │   │   │   ├── update.js
│   │   │   │   │   └── write.js
│   │   │   │   ├── get-dev-profile.js
│   │   │   │   ├── get-launch-apps.js
│   │   │   │   ├── get-launch-apps.test.js
│   │   │   │   ├── healthcheck.js
│   │   │   │   ├── hosting/
│   │   │   │   │   ├── puter-site-config.js
│   │   │   │   │   ├── puter-site-config.test.js
│   │   │   │   │   ├── puterSiteMiddleware.js
│   │   │   │   │   └── puterSiteMiddleware.test.js
│   │   │   │   ├── itemMetadata.js
│   │   │   │   ├── kvstore/
│   │   │   │   │   ├── clearItems.js
│   │   │   │   │   ├── getItem.js
│   │   │   │   │   ├── listItems.js
│   │   │   │   │   └── setItem.js
│   │   │   │   ├── login.js
│   │   │   │   ├── logout.js
│   │   │   │   ├── open_item.js
│   │   │   │   ├── passwd.js
│   │   │   │   ├── puterai/
│   │   │   │   │   └── openai/
│   │   │   │   │       ├── chat_completions.js
│   │   │   │   │       └── completions.js
│   │   │   │   ├── query/
│   │   │   │   │   └── app.js
│   │   │   │   ├── recentAppOpens/
│   │   │   │   │   ├── RecentAppOpensRedisCacheSpace.js
│   │   │   │   │   └── rao.js
│   │   │   │   ├── remove-site-dir.js
│   │   │   │   ├── removeItem.js
│   │   │   │   ├── save_account.js
│   │   │   │   ├── send-confirm-email.js
│   │   │   │   ├── send-pass-recovery-email.js
│   │   │   │   ├── set-desktop-bg.js
│   │   │   │   ├── set-pass-using-token.js
│   │   │   │   ├── set_layout.js
│   │   │   │   ├── set_sort_by.js
│   │   │   │   ├── sign.js
│   │   │   │   ├── signup.js
│   │   │   │   ├── signup_create_new_user.js
│   │   │   │   ├── sites.js
│   │   │   │   ├── suggest_apps.js
│   │   │   │   ├── test.js
│   │   │   │   ├── update-taskbar-items.js
│   │   │   │   ├── user-protected/
│   │   │   │   │   ├── change-email.js
│   │   │   │   │   ├── change-password.js
│   │   │   │   │   ├── change-username.js
│   │   │   │   │   ├── delete-own-user.js
│   │   │   │   │   └── disable-2fa.js
│   │   │   │   ├── verify-pass-recovery-token.js
│   │   │   │   ├── version.js
│   │   │   │   ├── writeFile/
│   │   │   │   │   ├── copy.js
│   │   │   │   │   ├── delete.js
│   │   │   │   │   ├── mkdir.js
│   │   │   │   │   ├── move.js
│   │   │   │   │   ├── rename.js
│   │   │   │   │   ├── trash.js
│   │   │   │   │   ├── write.js
│   │   │   │   │   └── writeFile_handlers.js
│   │   │   │   └── writeFile.js
│   │   │   ├── server
│   │   │   ├── services/
│   │   │   │   ├── AWSSecretsPopulator.js
│   │   │   │   ├── AnomalyService.js
│   │   │   │   ├── AnomalyService.test.ts
│   │   │   │   ├── BaseService.d.ts
│   │   │   │   ├── BaseService.js
│   │   │   │   ├── BootScriptService.js
│   │   │   │   ├── ChatAPIService.js
│   │   │   │   ├── ChatAPIService.test.js
│   │   │   │   ├── CleanEmailService.js
│   │   │   │   ├── CleanEmailService.test.ts
│   │   │   │   ├── ClientOperationService.js
│   │   │   │   ├── ClientOperationService.test.ts
│   │   │   │   ├── CommandService.js
│   │   │   │   ├── CommandService.test.ts
│   │   │   │   ├── ConfigurableCountingService.js
│   │   │   │   ├── ConfigurableCountingService.test.ts
│   │   │   │   ├── Container.js
│   │   │   │   ├── ContextInitService.js
│   │   │   │   ├── ContextInitService.test.ts
│   │   │   │   ├── DetailProviderService.js
│   │   │   │   ├── DetailProviderService.test.ts
│   │   │   │   ├── DynamoKVStore/
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── DynamoKVStore.test.ts
│   │   │   │   │   ├── DynamoKVStore.ts
│   │   │   │   │   ├── DynamoKVStoreWrapper.ts
│   │   │   │   │   └── tableDefinition.ts
│   │   │   │   ├── EmailService.js
│   │   │   │   ├── EngPortalService.js
│   │   │   │   ├── EntityStoreService.js
│   │   │   │   ├── EntriService.js
│   │   │   │   ├── EventService.js
│   │   │   │   ├── EventService.test.ts
│   │   │   │   ├── FeatureFlagService.js
│   │   │   │   ├── FeatureFlagService.test.ts
│   │   │   │   ├── FilesystemAPIService.js
│   │   │   │   ├── GetUserService.js
│   │   │   │   ├── HelloWorldService.js
│   │   │   │   ├── HelloWorldService.test.ts
│   │   │   │   ├── HostDiskUsageService.js
│   │   │   │   ├── HostnameService.js
│   │   │   │   ├── HostnameService.test.ts
│   │   │   │   ├── KernelInfoService.js
│   │   │   │   ├── LocalDiskStorageService.js
│   │   │   │   ├── LockService.js
│   │   │   │   ├── LockService.test.ts
│   │   │   │   ├── MakeProdDebuggingLessAwfulService.js
│   │   │   │   ├── MemoryStorageService.js
│   │   │   │   ├── MemoryStorageService.test.ts
│   │   │   │   ├── MeteringService/
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── MeteringService.test.ts
│   │   │   │   │   ├── MeteringService.ts
│   │   │   │   │   ├── MeteringServiceWrapper.mjs
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── consts.ts
│   │   │   │   │   ├── costMaps/
│   │   │   │   │   │   ├── awsPollyCostMap.ts
│   │   │   │   │   │   ├── awsTextractCostMap.ts
│   │   │   │   │   │   ├── claudeCostMap.ts
│   │   │   │   │   │   ├── deepSeekCostMap.ts
│   │   │   │   │   │   ├── elevenlabsCostMap.ts
│   │   │   │   │   │   ├── fileSystemCostMap.ts
│   │   │   │   │   │   ├── geminiCostMap.ts
│   │   │   │   │   │   ├── groqCostMap.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── kvCostMap.ts
│   │   │   │   │   │   ├── mistralCostMap.ts
│   │   │   │   │   │   ├── openAiCostMap.ts
│   │   │   │   │   │   ├── openaiImageCostMap.ts
│   │   │   │   │   │   ├── openaiVideoCostMap.ts
│   │   │   │   │   │   ├── openrouterCostMap.ts
│   │   │   │   │   │   ├── togetherCostMap.ts
│   │   │   │   │   │   └── xaiCostMap.ts
│   │   │   │   │   ├── subPolicies/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── registeredUserFreePolicy.ts
│   │   │   │   │   │   └── tempUserFreePolicy.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── NotificationService.js
│   │   │   │   ├── NotificationService.test.ts
│   │   │   │   ├── OperationTraceService.js
│   │   │   │   ├── PeerService.js
│   │   │   │   ├── PermissionAPIService.js
│   │   │   │   ├── PuterAPIService.js
│   │   │   │   ├── PuterHomepageService.js
│   │   │   │   ├── PuterSiteService.js
│   │   │   │   ├── PuterVersionService.js
│   │   │   │   ├── PuterVersionService.test.ts
│   │   │   │   ├── ReferralCodeService.js
│   │   │   │   ├── ReferralCodeService.test.js
│   │   │   │   ├── RefreshAssociationsService.js
│   │   │   │   ├── RegistrantService.js
│   │   │   │   ├── RegistryService.js
│   │   │   │   ├── RegistryService.test.ts
│   │   │   │   ├── RequestMeasureService.js
│   │   │   │   ├── SNSService.js
│   │   │   │   ├── SNSService.test.ts
│   │   │   │   ├── SUService.js
│   │   │   │   ├── ScriptService.js
│   │   │   │   ├── ScriptService.test.ts
│   │   │   │   ├── ServeGUIService.js
│   │   │   │   ├── ServicePatch.js
│   │   │   │   ├── SessionService.js
│   │   │   │   ├── SessionService.test.js
│   │   │   │   ├── ShareService.js
│   │   │   │   ├── ShutdownService.js
│   │   │   │   ├── ShutdownService.test.ts
│   │   │   │   ├── StorageService.js
│   │   │   │   ├── StrategizedService.js
│   │   │   │   ├── SystemDataService.js
│   │   │   │   ├── SystemValidationService.js
│   │   │   │   ├── SystemValidationService.test.ts
│   │   │   │   ├── TestService.js
│   │   │   │   ├── TestService.test.ts
│   │   │   │   ├── User.d.ts
│   │   │   │   ├── UserRedisCacheSpace.js
│   │   │   │   ├── UserService.d.ts
│   │   │   │   ├── UserService.js
│   │   │   │   ├── VerifiedGroupService.js
│   │   │   │   ├── WSPushService.js
│   │   │   │   ├── WebDAV/
│   │   │   │   │   ├── WebDAVService.js
│   │   │   │   │   ├── lockStore.mjs
│   │   │   │   │   ├── methodHandlers/
│   │   │   │   │   │   ├── COPY.mjs
│   │   │   │   │   │   ├── DELETE.mjs
│   │   │   │   │   │   ├── HEAD_GET.mjs
│   │   │   │   │   │   ├── LOCK.mjs
│   │   │   │   │   │   ├── MKCOL.mjs
│   │   │   │   │   │   ├── MOVE.mjs
│   │   │   │   │   │   ├── OPTIONS.mjs
│   │   │   │   │   │   ├── PROPFIND.mjs
│   │   │   │   │   │   ├── PROPPATCH.mjs
│   │   │   │   │   │   ├── PUT.mjs
│   │   │   │   │   │   ├── UNLOCK.mjs
│   │   │   │   │   │   ├── method.mjs
│   │   │   │   │   │   └── methodMap.mjs
│   │   │   │   │   └── utils.mjs
│   │   │   │   ├── WispService.js
│   │   │   │   ├── abuse-prevention/
│   │   │   │   │   ├── AuthAuditService.js
│   │   │   │   │   ├── EdgeRateLimitService.js
│   │   │   │   │   ├── IdentificationService.js
│   │   │   │   │   └── concurrentRequestLimiter/
│   │   │   │   │       ├── .gitignore
│   │   │   │   │       ├── ConcurrentRequestLimiter.test.ts
│   │   │   │   │       ├── ConcurrentRequestLimiter.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── types.ts
│   │   │   │   ├── ai/
│   │   │   │   │   ├── AIInterfaceService.js
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── chat/
│   │   │   │   │   │   ├── .gitignore
│   │   │   │   │   │   ├── AIChatRedisCacheSpace.ts
│   │   │   │   │   │   ├── AIChatService.ts
│   │   │   │   │   │   └── providers/
│   │   │   │   │   │       ├── ChatProvider.ts
│   │   │   │   │   │       ├── ClaudeProvider/
│   │   │   │   │   │       │   ├── ClaudeProvider.test.ts
│   │   │   │   │   │       │   ├── ClaudeProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── DeepSeekProvider/
│   │   │   │   │   │       │   ├── DeepSeekProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── FakeChatProvider.ts
│   │   │   │   │   │       ├── GeminiProvider/
│   │   │   │   │   │       │   ├── GeminiChatProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── GroqAiProvider/
│   │   │   │   │   │       │   ├── GroqAIProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── MistralAiProvider/
│   │   │   │   │   │       │   ├── MistralAiProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── OllamaProvider.ts
│   │   │   │   │   │       ├── OpenAiProvider/
│   │   │   │   │   │       │   ├── OpenAiChatCompletionsProvider.ts
│   │   │   │   │   │       │   ├── OpenAiChatResponsesProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── OpenRouterProvider/
│   │   │   │   │   │       │   ├── OpenRouterProvider.ts
│   │   │   │   │   │       │   └── modelOverrides.ts
│   │   │   │   │   │       ├── TogetherAiProvider/
│   │   │   │   │   │       │   └── TogetherAIProvider.ts
│   │   │   │   │   │       ├── XAIProvider/
│   │   │   │   │   │       │   ├── XAIProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       └── types.ts
│   │   │   │   │   ├── docs/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   ├── ai-services-config.md
│   │   │   │   │   │   ├── api_examples.md
│   │   │   │   │   │   └── config.md
│   │   │   │   │   ├── image/
│   │   │   │   │   │   ├── .gitignore
│   │   │   │   │   │   ├── AIImageGenerationService.ts
│   │   │   │   │   │   └── providers/
│   │   │   │   │   │       ├── CloudflareImageGenerationProvider/
│   │   │   │   │   │       │   ├── CloudflareImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── GeminiImageGenerationProvider/
│   │   │   │   │   │       │   ├── GeminiImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── OpenAiImageGenerationProvider/
│   │   │   │   │   │       │   ├── OpenAiImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── TogetherImageGenerationProvider/
│   │   │   │   │   │       │   ├── TogetherImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── XAIImageGenerationProvider/
│   │   │   │   │   │       │   ├── XAIImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       └── types.ts
│   │   │   │   │   ├── moderation/
│   │   │   │   │   │   └── AsModeration.js
│   │   │   │   │   ├── ocr/
│   │   │   │   │   │   ├── AWSTextractService.js
│   │   │   │   │   │   └── MistralOCRService.js
│   │   │   │   │   ├── sts/
│   │   │   │   │   │   └── ElevenLabsVoiceChangerService.js
│   │   │   │   │   ├── stt/
│   │   │   │   │   │   └── OpenAISpeechToTextService.js
│   │   │   │   │   ├── tts/
│   │   │   │   │   │   ├── AWSPollyService.js
│   │   │   │   │   │   ├── ElevenLabsTTSService.js
│   │   │   │   │   │   ├── OpenAITTSService.js
│   │   │   │   │   │   └── PollyRedisCacheKeys.js
│   │   │   │   │   ├── utils/
│   │   │   │   │   │   ├── FunctionCalling.js
│   │   │   │   │   │   ├── Messages.js
│   │   │   │   │   │   ├── OpenAIUtil.d.ts
│   │   │   │   │   │   ├── OpenAIUtil.js
│   │   │   │   │   │   ├── Streaming.js
│   │   │   │   │   │   └── messages.test.js
│   │   │   │   │   └── video/
│   │   │   │   │       ├── OpenAIVideoGenerationService/
│   │   │   │   │       │   └── OpenAIVideoGenerationService.js
│   │   │   │   │       └── TogetherVideoGenerationService/
│   │   │   │   │           ├── TogetherVideoGenerationService.js
│   │   │   │   │           └── models.js
│   │   │   │   ├── auth/
│   │   │   │   │   ├── ACLService.js
│   │   │   │   │   ├── Actor.d.ts
│   │   │   │   │   ├── Actor.js
│   │   │   │   │   ├── AntiCSRFService.js
│   │   │   │   │   ├── AntiCSRFService.test.ts
│   │   │   │   │   ├── AuthService.js
│   │   │   │   │   ├── AuthService.privateAssetToken.test.ts
│   │   │   │   │   ├── GroupRedisCacheSpace.js
│   │   │   │   │   ├── GroupService.js
│   │   │   │   │   ├── OIDCService.js
│   │   │   │   │   ├── OTPService.js
│   │   │   │   │   ├── PermissionScanRedisCacheSpace.js
│   │   │   │   │   ├── PermissionScanRedisCacheSpace.test.js
│   │   │   │   │   ├── PermissionService.js
│   │   │   │   │   ├── PermissionShortcutService.js
│   │   │   │   │   ├── PreAuthService.js
│   │   │   │   │   ├── SignupService.js
│   │   │   │   │   ├── TokenService.js
│   │   │   │   │   ├── TokenService.test.ts
│   │   │   │   │   ├── VirtualGroupService.js
│   │   │   │   │   ├── permissionConts.mjs
│   │   │   │   │   ├── permissionUtils.bench.js
│   │   │   │   │   └── permissionUtils.mjs
│   │   │   │   ├── database/
│   │   │   │   │   ├── BaseDatabaseAccessService.js
│   │   │   │   │   ├── SqliteDatabaseAccessService.js
│   │   │   │   │   ├── constructs.js
│   │   │   │   │   ├── consts.js
│   │   │   │   │   └── sqlite_setup/
│   │   │   │   │       ├── 0001_create-tables.sql
│   │   │   │   │       ├── 0002_add-default-apps.sql
│   │   │   │   │       ├── 0003_user-permissions.sql
│   │   │   │   │       ├── 0004_sessions.sql
│   │   │   │   │       ├── 0005_background-apps.sql
│   │   │   │   │       ├── 0006_update-apps.sql
│   │   │   │   │       ├── 0007_sessions.sql
│   │   │   │   │       ├── 0008_otp.sql
│   │   │   │   │       ├── 0009_app-prefix-fix.sql
│   │   │   │   │       ├── 0010_add-git-app.sql
│   │   │   │   │       ├── 0011_notification.sql
│   │   │   │   │       ├── 0012_appmetadata.sql
│   │   │   │   │       ├── 0013_protected-apps.sql
│   │   │   │   │       ├── 0014_share.sql
│   │   │   │   │       ├── 0015_group.sql
│   │   │   │   │       ├── 0016_group-permissions.sql
│   │   │   │   │       ├── 0017_publicdirs.sql
│   │   │   │   │       ├── 0018_fix-0003.sql
│   │   │   │   │       ├── 0019_fix-0016.sql
│   │   │   │   │       ├── 0020_dev-center.sql
│   │   │   │   │       ├── 0021_app-owner-id.sql
│   │   │   │   │       ├── 0022_dev-center-max.sql
│   │   │   │   │       ├── 0023_fix-kv.sql
│   │   │   │   │       ├── 0024_default-groups.sql
│   │   │   │   │       ├── 0025_system-user.dbmig.js
│   │   │   │   │       ├── 0026_user-groups.dbmig.js
│   │   │   │   │       ├── 0027_emulator-app.dbmig.js
│   │   │   │   │       ├── 0028_clean-email.sql
│   │   │   │   │       ├── 0029_emulator_priv.sql
│   │   │   │   │       ├── 0030_comments.sql
│   │   │   │   │       ├── 0031_audit-meta.sql
│   │   │   │   │       ├── 0032_signup_metadata.sql
│   │   │   │   │       ├── 0033_ai-usage.sql
│   │   │   │   │       ├── 0034_app-redirect.sql
│   │   │   │   │       ├── 0035_threads.sql
│   │   │   │   │       ├── 0036_dev-to-app.sql
│   │   │   │   │       ├── 0037_cost.sql
│   │   │   │   │       ├── 0038_custom-domains.sql
│   │   │   │   │       ├── 0039_add-expireAt-to-kv-store.sql
│   │   │   │   │       ├── 0040_add_user_metadata.sql
│   │   │   │   │       ├── 0041_add_unique_constraint_user_uuid.sql
│   │   │   │   │       ├── 0042_add_cloudflare_d1.sql
│   │   │   │   │       ├── 0043_add_dt.sql
│   │   │   │   │       ├── 0044_dev-center-godmode.sql
│   │   │   │   │       ├── 0045_user_oidc_providers.sql
│   │   │   │   │       └── 0046_is-private-apps.sql
│   │   │   │   ├── drivers/
│   │   │   │   │   ├── CoercionService.js
│   │   │   │   │   ├── DriverError.js
│   │   │   │   │   ├── DriverService.js
│   │   │   │   │   ├── DriverUsagePolicyService.js
│   │   │   │   │   ├── FileFacade.js
│   │   │   │   │   ├── meta/
│   │   │   │   │   │   ├── Construct.js
│   │   │   │   │   │   └── Runtime.js
│   │   │   │   │   └── types.js
│   │   │   │   ├── file-cache/
│   │   │   │   │   ├── FileTracker.bench.js
│   │   │   │   │   └── FileTracker.js
│   │   │   │   ├── fs/
│   │   │   │   │   └── FSLockService.js
│   │   │   │   ├── periodic/
│   │   │   │   │   └── FSEntryMigrateService.js
│   │   │   │   ├── sla/
│   │   │   │   │   ├── RateLimitRedisCacheSpace.js
│   │   │   │   │   ├── RateLimitService.js
│   │   │   │   │   └── SLAService.js
│   │   │   │   ├── web/
│   │   │   │   │   └── UserProtectedEndpointsService.js
│   │   │   │   └── worker/
│   │   │   │       ├── .gitignore
│   │   │   │       ├── README.md
│   │   │   │       ├── WorkerService.js
│   │   │   │       ├── package.json
│   │   │   │       ├── src/
│   │   │   │       │   ├── index.js
│   │   │   │       │   └── s2w-router.js
│   │   │   │       ├── template/
│   │   │   │       │   └── puter-portable.js
│   │   │   │       ├── webpack.config.js
│   │   │   │       └── workerUtils/
│   │   │   │           ├── cloudflareDeploy.js
│   │   │   │           ├── nameUtils.js
│   │   │   │           └── puterUtils.js
│   │   │   ├── structured/
│   │   │   │   ├── README.md
│   │   │   │   └── sequence/
│   │   │   │       ├── scan-permission.mjs
│   │   │   │       ├── share/
│   │   │   │       │   ├── process_recipients.js
│   │   │   │       │   ├── process_shares.js
│   │   │   │       │   └── validate.js
│   │   │   │       └── share.js
│   │   │   ├── traits/
│   │   │   │   ├── AssignableMethodsFeature.js
│   │   │   │   ├── AsyncProviderFeature.js
│   │   │   │   ├── ChannelFeature.js
│   │   │   │   ├── ContextAwareFeature.js
│   │   │   │   ├── OtelFeature.js
│   │   │   │   ├── SyncFeature.js
│   │   │   │   └── WeakConstructorFeature.js
│   │   │   ├── unstructured/
│   │   │   │   ├── permission-scan-lib.js
│   │   │   │   └── permission-scanners.js
│   │   │   ├── user-mig.js
│   │   │   ├── util/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── CircularQueue.bench.js
│   │   │   │   ├── CircularQueue.js
│   │   │   │   ├── asyncutil.js
│   │   │   │   ├── configutil.js
│   │   │   │   ├── consolelog.js
│   │   │   │   ├── context.bench.js
│   │   │   │   ├── context.d.ts
│   │   │   │   ├── context.js
│   │   │   │   ├── datautil.bench.js
│   │   │   │   ├── datautil.js
│   │   │   │   ├── debugutil.js
│   │   │   │   ├── errorutil.js
│   │   │   │   ├── esmcontext.js
│   │   │   │   ├── expressutil.js
│   │   │   │   ├── fnutil.js
│   │   │   │   ├── fuzz.js
│   │   │   │   ├── gcutil.js
│   │   │   │   ├── hl_types.js
│   │   │   │   ├── hl_types.test.js
│   │   │   │   ├── identifier.bench.js
│   │   │   │   ├── identifier.js
│   │   │   │   ├── kvSingleton.js
│   │   │   │   ├── lockutil.bench.js
│   │   │   │   ├── lockutil.js
│   │   │   │   ├── multivalue.js
│   │   │   │   ├── objutil.js
│   │   │   │   ├── opmath.bench.js
│   │   │   │   ├── opmath.js
│   │   │   │   ├── opmath.test.js
│   │   │   │   ├── otelutil.js
│   │   │   │   ├── outcomeutil.ts
│   │   │   │   ├── pathutil.bench.js
│   │   │   │   ├── pathutil.js
│   │   │   │   ├── retryutil.js
│   │   │   │   ├── safety.js
│   │   │   │   ├── securehttp.js
│   │   │   │   ├── stdioutil.js
│   │   │   │   ├── streamutil.js
│   │   │   │   ├── structutil.bench.js
│   │   │   │   ├── structutil.js
│   │   │   │   ├── urlutil.js
│   │   │   │   ├── uuidfpe.bench.js
│   │   │   │   ├── uuidfpe.js
│   │   │   │   ├── validutil.js
│   │   │   │   ├── validutil.test.js
│   │   │   │   ├── versionutil.js
│   │   │   │   ├── versionutil.test.js
│   │   │   │   └── workutil.js
│   │   │   └── validation.js
│   │   ├── test/
│   │   │   └── modules/
│   │   │       └── captcha/
│   │   │           └── integration/
│   │   │               └── extension-integration.test.js
│   │   ├── tools/
│   │   │   ├── .test-webhook-config.json
│   │   │   ├── README.md
│   │   │   ├── test-webhook.js
│   │   │   └── test.mjs
│   │   ├── vitest.bench.config.js
│   │   ├── vitest.bench.config.ts
│   │   └── vitest.config.ts
│   ├── dev-center/
│   │   ├── LICENSE.txt
│   │   ├── README.md
│   │   ├── coming-soon.html
│   │   ├── css/
│   │   │   ├── normalize.css
│   │   │   └── style.css
│   │   ├── index.html
│   │   └── js/
│   │       ├── apps.js
│   │       ├── dev-center.js
│   │       ├── images.js
│   │       ├── libs/
│   │       │   ├── html-entities.js
│   │       │   ├── jquery.dragster.js
│   │       │   └── slugify.js
│   │       ├── websites.js
│   │       └── workers.js
│   ├── docs/
│   │   ├── CREDITS.md
│   │   ├── LICENSE-CODE.txt
│   │   ├── LICENSE.txt
│   │   ├── README.md
│   │   ├── build.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── AI/
│   │       │   ├── chat.md
│   │       │   ├── img2txt.md
│   │       │   ├── listModelProviders.md
│   │       │   ├── listModels.md
│   │       │   ├── speech2speech.md
│   │       │   ├── speech2txt.md
│   │       │   ├── txt2img.md
│   │       │   ├── txt2speech.md
│   │       │   └── txt2vid.md
│   │       ├── AI.md
│   │       ├── Apps/
│   │       │   ├── create.md
│   │       │   ├── delete.md
│   │       │   ├── get.md
│   │       │   ├── list.md
│   │       │   └── update.md
│   │       ├── Apps.md
│   │       ├── Auth/
│   │       │   ├── getDetailedAppUsage.md
│   │       │   ├── getMonthlyUsage.md
│   │       │   ├── getUser.md
│   │       │   ├── isSignedIn.md
│   │       │   ├── signIn.md
│   │       │   └── signOut.md
│   │       ├── Auth.md
│   │       ├── Drivers/
│   │       │   └── call.md
│   │       ├── Drivers.md
│   │       ├── FS/
│   │       │   ├── copy.md
│   │       │   ├── delete.md
│   │       │   ├── getReadURL.md
│   │       │   ├── mkdir.md
│   │       │   ├── move.md
│   │       │   ├── read.md
│   │       │   ├── readdir.md
│   │       │   ├── rename.md
│   │       │   ├── space.md
│   │       │   ├── stat.md
│   │       │   ├── upload.md
│   │       │   └── write.md
│   │       ├── FS.md
│   │       ├── Hosting/
│   │       │   ├── create.md
│   │       │   ├── delete.md
│   │       │   ├── get.md
│   │       │   ├── list.md
│   │       │   └── update.md
│   │       ├── Hosting.md
│   │       ├── KV/
│   │       │   ├── MAX_KEY_SIZE.md
│   │       │   ├── MAX_VALUE_SIZE.md
│   │       │   ├── add.md
│   │       │   ├── decr.md
│   │       │   ├── del.md
│   │       │   ├── expire.md
│   │       │   ├── expireAt.md
│   │       │   ├── flush.md
│   │       │   ├── get.md
│   │       │   ├── incr.md
│   │       │   ├── list.md
│   │       │   ├── remove.md
│   │       │   ├── set.md
│   │       │   └── update.md
│   │       ├── KV.md
│   │       ├── Networking/
│   │       │   ├── Socket.md
│   │       │   ├── TLSSocket.md
│   │       │   └── fetch.md
│   │       ├── Networking.md
│   │       ├── Objects/
│   │       │   ├── AppConnection.md
│   │       │   ├── app.md
│   │       │   ├── chatresponse.md
│   │       │   ├── chatresponsechunk.md
│   │       │   ├── createappresult.md
│   │       │   ├── detailedappusage.md
│   │       │   ├── fsitem.md
│   │       │   ├── kvlistpage.md
│   │       │   ├── kvpair.md
│   │       │   ├── monthlyusage.md
│   │       │   ├── signinresult.md
│   │       │   ├── spaceinfo.md
│   │       │   ├── speech2txtresult.md
│   │       │   ├── subdomain.md
│   │       │   ├── toolcall.md
│   │       │   ├── user.md
│   │       │   ├── workerdeployment.md
│   │       │   └── workerinfo.md
│   │       ├── Objects.md
│   │       ├── Peer/
│   │       │   ├── connect.md
│   │       │   ├── ensureTurnRelays.md
│   │       │   └── serve.md
│   │       ├── Peer.md
│   │       ├── Perms/
│   │       │   ├── request.md
│   │       │   ├── requestEmail.md
│   │       │   ├── requestManageApps.md
│   │       │   ├── requestManageSubdomains.md
│   │       │   ├── requestReadApps.md
│   │       │   ├── requestReadDesktop.md
│   │       │   ├── requestReadDocuments.md
│   │       │   ├── requestReadPictures.md
│   │       │   ├── requestReadSubdomains.md
│   │       │   ├── requestReadVideos.md
│   │       │   ├── requestWriteDesktop.md
│   │       │   ├── requestWriteDocuments.md
│   │       │   ├── requestWritePictures.md
│   │       │   └── requestWriteVideos.md
│   │       ├── Perms.md
│   │       ├── UI/
│   │       │   ├── alert.md
│   │       │   ├── authenticateWithPuter.md
│   │       │   ├── contextMenu.md
│   │       │   ├── createWindow.md
│   │       │   ├── exit.md
│   │       │   ├── getLanguage.md
│   │       │   ├── hideSpinner.md
│   │       │   ├── hideWindow.md
│   │       │   ├── launchApp.md
│   │       │   ├── notify.md
│   │       │   ├── on.md
│   │       │   ├── onItemsOpened.md
│   │       │   ├── onLaunchedWithItems.md
│   │       │   ├── onWindowClose.md
│   │       │   ├── parentApp.md
│   │       │   ├── prompt.md
│   │       │   ├── setMenubar.md
│   │       │   ├── setWindowHeight.md
│   │       │   ├── setWindowPosition.md
│   │       │   ├── setWindowSize.md
│   │       │   ├── setWindowTitle.md
│   │       │   ├── setWindowWidth.md
│   │       │   ├── setWindowX.md
│   │       │   ├── setWindowY.md
│   │       │   ├── showColorPicker.md
│   │       │   ├── showDirectoryPicker.md
│   │       │   ├── showFontPicker.md
│   │       │   ├── showOpenFilePicker.md
│   │       │   ├── showSaveFilePicker.md
│   │       │   ├── showSpinner.md
│   │       │   ├── showWindow.md
│   │       │   ├── socialShare.md
│   │       │   └── wasLaunchedWithItems.md
│   │       ├── UI.md
│   │       ├── Utils/
│   │       │   ├── appID.md
│   │       │   ├── env.md
│   │       │   ├── print.md
│   │       │   └── randName.md
│   │       ├── Utils.md
│   │       ├── Workers/
│   │       │   ├── create.md
│   │       │   ├── delete.md
│   │       │   ├── exec.md
│   │       │   ├── get.md
│   │       │   ├── list.md
│   │       │   └── router.md
│   │       ├── Workers.md
│   │       ├── assets/
│   │       │   ├── css/
│   │       │   │   └── style.css
│   │       │   ├── favicon/
│   │       │   │   ├── browserconfig.xml
│   │       │   │   └── manifest.json
│   │       │   └── js/
│   │       │       ├── context-menu.js
│   │       │       ├── example.js
│   │       │       ├── index.js
│   │       │       ├── router.js
│   │       │       ├── search.js
│   │       │       └── sidebar.js
│   │       ├── examples.js
│   │       ├── examples.md
│   │       ├── frameworks.md
│   │       ├── getting-started.md
│   │       ├── index.md
│   │       ├── menu.js
│   │       ├── playground/
│   │       │   ├── assets/
│   │       │   │   ├── css/
│   │       │   │   │   └── style.css
│   │       │   │   └── js/
│   │       │   │       └── app.js
│   │       │   └── examples/
│   │       │       ├── ai-chat-claude-3-7-sonnet.html
│   │       │       ├── ai-chat-claude.html
│   │       │       ├── ai-chat-deepseek.html
│   │       │       ├── ai-chat-gemini.html
│   │       │       ├── ai-chat-openai-o3-mini.html
│   │       │       ├── ai-chat-stream.html
│   │       │       ├── ai-chatgpt.html
│   │       │       ├── ai-function-calling.html
│   │       │       ├── ai-gpt-vision.html
│   │       │       ├── ai-img2txt.html
│   │       │       ├── ai-list-model-providers.html
│   │       │       ├── ai-list-models.html
│   │       │       ├── ai-resume-analyzer.html
│   │       │       ├── ai-speech2speech-elevenlabs.html
│   │       │       ├── ai-speech2speech-file.html
│   │       │       ├── ai-speech2speech-url.html
│   │       │       ├── ai-speech2txt.html
│   │       │       ├── ai-streaming-function-calling.html
│   │       │       ├── ai-txt2img-image-to-image.html
│   │       │       ├── ai-txt2img-options.html
│   │       │       ├── ai-txt2img.html
│   │       │       ├── ai-txt2speech-elevenlabs.html
│   │       │       ├── ai-txt2speech-engines.html
│   │       │       ├── ai-txt2speech-openai.html
│   │       │       ├── ai-txt2speech-options.html
│   │       │       ├── ai-txt2speech.html
│   │       │       ├── ai-txt2vid-options.html
│   │       │       ├── ai-txt2vid.html
│   │       │       ├── ai-web-search.html
│   │       │       ├── ai-xai.html
│   │       │       ├── app-ai-chat.html
│   │       │       ├── app-camera.html
│   │       │       ├── app-create.html
│   │       │       ├── app-delete.html
│   │       │       ├── app-get.html
│   │       │       ├── app-list.html
│   │       │       ├── app-summarizer.html
│   │       │       ├── app-todo.html
│   │       │       ├── app-update.html
│   │       │       ├── auth-get-monthly-usage.html
│   │       │       ├── auth-get-user.html
│   │       │       ├── auth-is-signed-in.html
│   │       │       ├── auth-sign-in.html
│   │       │       ├── auth-sign-out.html
│   │       │       ├── fs-copy.html
│   │       │       ├── fs-delete-directory.html
│   │       │       ├── fs-delete.html
│   │       │       ├── fs-mkdir-create-missing-parents.html
│   │       │       ├── fs-mkdir-dedupe.html
│   │       │       ├── fs-mkdir.html
│   │       │       ├── fs-move-create-missing-parents.html
│   │       │       ├── fs-move.html
│   │       │       ├── fs-read.html
│   │       │       ├── fs-readdir.html
│   │       │       ├── fs-rename.html
│   │       │       ├── fs-stat.html
│   │       │       ├── fs-upload.html
│   │       │       ├── fs-write-create-missing-parents.html
│   │       │       ├── fs-write-dedupe.html
│   │       │       ├── fs-write-from-input.html
│   │       │       ├── fs-write.html
│   │       │       ├── hosting-create.html
│   │       │       ├── hosting-delete.html
│   │       │       ├── hosting-get.html
│   │       │       ├── hosting-list.html
│   │       │       ├── hosting-update.html
│   │       │       ├── intro-auth.html
│   │       │       ├── intro-chatgpt.html
│   │       │       ├── intro-fs-write.html
│   │       │       ├── intro-gpt-vision.html
│   │       │       ├── intro-hosting.html
│   │       │       ├── intro-kv-set.html
│   │       │       ├── kv-add.html
│   │       │       ├── kv-decr-nested.html
│   │       │       ├── kv-decr.html
│   │       │       ├── kv-del.html
│   │       │       ├── kv-expire.html
│   │       │       ├── kv-expireAt.html
│   │       │       ├── kv-flush.html
│   │       │       ├── kv-get.html
│   │       │       ├── kv-incr-nested.html
│   │       │       ├── kv-incr.html
│   │       │       ├── kv-list.html
│   │       │       ├── kv-name.html
│   │       │       ├── kv-remove.html
│   │       │       ├── kv-set.html
│   │       │       ├── kv-update.html
│   │       │       ├── net-basic.html
│   │       │       ├── net-fetch.html
│   │       │       ├── net-tls.html
│   │       │       ├── peer-basic.html
│   │       │       ├── perms-request-apps.html
│   │       │       ├── perms-request-desktop.html
│   │       │       ├── perms-request-documents.html
│   │       │       ├── perms-request-email.html
│   │       │       ├── perms-request-manage-apps.html
│   │       │       ├── perms-request-manage-subdomains.html
│   │       │       ├── perms-request-permission.html
│   │       │       ├── perms-request-read-apps.html
│   │       │       ├── perms-request-read-desktop.html
│   │       │       ├── perms-request-read-documents.html
│   │       │       ├── perms-request-read-pictures.html
│   │       │       ├── perms-request-read-subdomains.html
│   │       │       ├── perms-request-read-videos.html
│   │       │       ├── perms-request-write-desktop.html
│   │       │       ├── perms-request-write-documents.html
│   │       │       ├── perms-request-write-pictures.html
│   │       │       ├── perms-request-write-videos.html
│   │       │       ├── workers-create.html
│   │       │       ├── workers-delete.html
│   │       │       ├── workers-exec.html
│   │       │       ├── workers-get.html
│   │       │       ├── workers-list.html
│   │       │       └── workers-management.html
│   │       ├── playground.js
│   │       ├── printdir.sh
│   │       ├── redirects.js
│   │       ├── robots.txt
│   │       ├── security.md
│   │       ├── sidebar.js
│   │       ├── supported-platforms.md
│   │       └── user-pays-model.md
│   ├── gui/
│   │   ├── CREDITS.md
│   │   ├── build.js
│   │   ├── dev-server.js
│   │   ├── doc/
│   │   │   ├── el().md
│   │   │   ├── utils.md
│   │   │   └── webpack_attempts.md
│   │   ├── package.json
│   │   ├── puter-gui.json
│   │   ├── src/
│   │   │   ├── .gitignore
│   │   │   ├── IPC.js
│   │   │   ├── UI/
│   │   │   │   ├── Components/
│   │   │   │   │   ├── Button.js
│   │   │   │   │   ├── CodeEntryView.js
│   │   │   │   │   ├── ConfirmationsView.js
│   │   │   │   │   ├── Flexer.js
│   │   │   │   │   ├── JustHTML.js
│   │   │   │   │   ├── PasswordEntry.js
│   │   │   │   │   ├── QRCode.js
│   │   │   │   │   ├── RecoveryCodeEntryView.js
│   │   │   │   │   ├── RecoveryCodesView.js
│   │   │   │   │   ├── StepHeading.js
│   │   │   │   │   └── StepView.js
│   │   │   │   ├── Dashboard/
│   │   │   │   │   ├── ContextMenu/
│   │   │   │   │   │   └── ContextMenu.js
│   │   │   │   │   ├── TabAccount.js
│   │   │   │   │   ├── TabApps.js
│   │   │   │   │   ├── TabFiles.js
│   │   │   │   │   ├── TabHome.js
│   │   │   │   │   ├── TabSecurity.js
│   │   │   │   │   ├── TabUsage.js
│   │   │   │   │   └── UIDashboard.js
│   │   │   │   ├── PuterDialog.js
│   │   │   │   ├── Settings/
│   │   │   │   │   ├── UITabAbout.js
│   │   │   │   │   ├── UITabAccount.js
│   │   │   │   │   ├── UITabKeyboardShortcuts.js
│   │   │   │   │   ├── UITabLanguage.js
│   │   │   │   │   ├── UITabPersonalization.js
│   │   │   │   │   ├── UITabSecurity.js
│   │   │   │   │   ├── UITabUsage.js
│   │   │   │   │   ├── UIWindowChangeEmail.js
│   │   │   │   │   ├── UIWindowConfirmUserDeletion.js
│   │   │   │   │   ├── UIWindowDisable2FA.js
│   │   │   │   │   ├── UIWindowFinalizeUserDeletion.js
│   │   │   │   │   └── UIWindowSettings.js
│   │   │   │   ├── UIAlert.js
│   │   │   │   ├── UIColorPickerWidget.js
│   │   │   │   ├── UIComponentWindow.js
│   │   │   │   ├── UIContextMenu.js
│   │   │   │   ├── UIDesktop.js
│   │   │   │   ├── UIElement.js
│   │   │   │   ├── UIItem.js
│   │   │   │   ├── UINotification.js
│   │   │   │   ├── UIPopover.js
│   │   │   │   ├── UIPrompt.js
│   │   │   │   ├── UITaskbar.js
│   │   │   │   ├── UITaskbarItem.js
│   │   │   │   ├── UIWindow.js
│   │   │   │   ├── UIWindow2FASetup.js
│   │   │   │   ├── UIWindowAuthMe.js
│   │   │   │   ├── UIWindowChangePassword.js
│   │   │   │   ├── UIWindowChangeUsername.js
│   │   │   │   ├── UIWindowClaimReferral.js
│   │   │   │   ├── UIWindowColorPicker.js
│   │   │   │   ├── UIWindowCopyToken.js
│   │   │   │   ├── UIWindowDesktopBGSettings.js
│   │   │   │   ├── UIWindowEmailConfirmationRequired.js
│   │   │   │   ├── UIWindowFeedback.js
│   │   │   │   ├── UIWindowFontPicker.js
│   │   │   │   ├── UIWindowItemProperties.js
│   │   │   │   ├── UIWindowLogin.js
│   │   │   │   ├── UIWindowLoginInProgress.js
│   │   │   │   ├── UIWindowManageSessions.js
│   │   │   │   ├── UIWindowMyWebsites.js
│   │   │   │   ├── UIWindowNewPassword.js
│   │   │   │   ├── UIWindowProgress.js
│   │   │   │   ├── UIWindowPublishWebsite.js
│   │   │   │   ├── UIWindowPublishWorker.js
│   │   │   │   ├── UIWindowQR.js
│   │   │   │   ├── UIWindowRecoverPassword.js
│   │   │   │   ├── UIWindowRefer.js
│   │   │   │   ├── UIWindowRequestPermission.js
│   │   │   │   ├── UIWindowSaveAccount.js
│   │   │   │   ├── UIWindowSearch.js
│   │   │   │   ├── UIWindowSessionList.js
│   │   │   │   ├── UIWindowShare.js
│   │   │   │   ├── UIWindowSignup.js
│   │   │   │   ├── UIWindowSystemInfo.js
│   │   │   │   ├── UIWindowTaskManager.js
│   │   │   │   ├── UIWindowThemeDialog.js
│   │   │   │   └── UIWindowWelcome.js
│   │   │   ├── browserconfig.xml
│   │   │   ├── css/
│   │   │   │   ├── dashboard.css
│   │   │   │   ├── normalize.css
│   │   │   │   ├── style.css
│   │   │   │   └── theme.css
│   │   │   ├── definitions.js
│   │   │   ├── extensions/
│   │   │   │   ├── groups-manager.js
│   │   │   │   └── modify-user-options-menu.js
│   │   │   ├── favicons/
│   │   │   │   ├── browserconfig.xml
│   │   │   │   └── manifest.json
│   │   │   ├── globals.js
│   │   │   ├── helpers/
│   │   │   │   ├── check_password_strength.js
│   │   │   │   ├── content_type_to_icon.js
│   │   │   │   ├── determine_active_container_parent.js
│   │   │   │   ├── download.js
│   │   │   │   ├── fixedEncodeURIComponent.js
│   │   │   │   ├── generate_file_context_menu.js
│   │   │   │   ├── get_html_element_from_options.js
│   │   │   │   ├── globToRegExp.js
│   │   │   │   ├── item_icon.js
│   │   │   │   ├── launch_app.js
│   │   │   │   ├── new_context_menu_item.js
│   │   │   │   ├── open_item.js
│   │   │   │   ├── refresh_item_container.js
│   │   │   │   ├── socialLink.js
│   │   │   │   ├── truncate_filename.js
│   │   │   │   ├── update_last_touch_coordinates.js
│   │   │   │   ├── update_mouse_position.js
│   │   │   │   ├── update_title_based_on_uploads.js
│   │   │   │   └── update_username_in_gui.js
│   │   │   ├── helpers.js
│   │   │   ├── i18n/
│   │   │   │   ├── i18n.js
│   │   │   │   ├── i18nChangeLanguage.js
│   │   │   │   └── translations/
│   │   │   │       ├── ar.js
│   │   │   │       ├── bg.js
│   │   │   │       ├── bn.js
│   │   │   │       ├── br.js
│   │   │   │       ├── da.js
│   │   │   │       ├── de.js
│   │   │   │       ├── emoji.js
│   │   │   │       ├── en.js
│   │   │   │       ├── es.js
│   │   │   │       ├── fa.js
│   │   │   │       ├── fi.js
│   │   │   │       ├── fr.js
│   │   │   │       ├── he.js
│   │   │   │       ├── hi.js
│   │   │   │       ├── hu.js
│   │   │   │       ├── hy.js
│   │   │   │       ├── id.js
│   │   │   │       ├── ig.js
│   │   │   │       ├── it.js
│   │   │   │       ├── ja.js
│   │   │   │       ├── ko.js
│   │   │   │       ├── ku.js
│   │   │   │       ├── ml.js
│   │   │   │       ├── my.js
│   │   │   │       ├── nb.js
│   │   │   │       ├── nl.js
│   │   │   │       ├── nn.js
│   │   │   │       ├── pl.js
│   │   │   │       ├── pt.js
│   │   │   │       ├── ro.js
│   │   │   │       ├── ru.js
│   │   │   │       ├── sl.js
│   │   │   │       ├── sv.js
│   │   │   │       ├── ta.js
│   │   │   │       ├── th.js
│   │   │   │       ├── tr.js
│   │   │   │       ├── translations.js
│   │   │   │       ├── ua.js
│   │   │   │       ├── ur.js
│   │   │   │       ├── vi.js
│   │   │   │       ├── zh.js
│   │   │   │       └── zhtw.js
│   │   │   ├── index.js
│   │   │   ├── init_async.js
│   │   │   ├── init_sync.js
│   │   │   ├── initgui.js
│   │   │   ├── keyboard.js
│   │   │   ├── lib/
│   │   │   │   ├── html-entities.js
│   │   │   │   ├── jquery-ui-1.13.2/
│   │   │   │   │   ├── AUTHORS.txt
│   │   │   │   │   ├── LICENSE.txt
│   │   │   │   │   ├── external/
│   │   │   │   │   │   └── jquery/
│   │   │   │   │   │       └── jquery.js
│   │   │   │   │   ├── index.html
│   │   │   │   │   ├── jquery-ui.css
│   │   │   │   │   ├── jquery-ui.js
│   │   │   │   │   ├── jquery-ui.structure.css
│   │   │   │   │   ├── jquery-ui.theme.css
│   │   │   │   │   └── package.json
│   │   │   │   ├── jquery.dragster.js
│   │   │   │   ├── mime.js
│   │   │   │   ├── path.js
│   │   │   │   └── socket.io/
│   │   │   │       └── socket.io.js
│   │   │   ├── manifest.json
│   │   │   ├── security.txt
│   │   │   ├── services/
│   │   │   │   ├── AntiCSRFService.js
│   │   │   │   ├── BroadcastService.js
│   │   │   │   ├── DebugService.js
│   │   │   │   ├── ExecService.js
│   │   │   │   ├── ExportRegistrantService.js
│   │   │   │   ├── IPCService.js
│   │   │   │   ├── LaunchOnInitService.js
│   │   │   │   ├── LocaleService.js
│   │   │   │   ├── ProcessService.js
│   │   │   │   ├── SettingsService.js
│   │   │   │   └── ThemeService.js
│   │   │   ├── static-assets.js
│   │   │   └── util/
│   │   │       ├── Collector.js
│   │   │       ├── Component.js
│   │   │       ├── Placeholder.js
│   │   │       ├── TeePromise.js
│   │   │       ├── ValueHolder.js
│   │   │       ├── desktop.js
│   │   │       └── openid.js
│   │   ├── utils.js
│   │   ├── webpack/
│   │   │   ├── BaseConfig.cjs
│   │   │   ├── EmitPlugin.cjs
│   │   │   └── libPaths.cjs
│   │   └── webpack.config.cjs
│   ├── puter-js/
│   │   ├── .gitignore
│   │   ├── APACHE_LICENSE.txt
│   │   ├── README.md
│   │   ├── index.d.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.js
│   │   │   ├── init.cjs
│   │   │   ├── init.d.cts
│   │   │   ├── lib/
│   │   │   │   ├── APICallLogger.js
│   │   │   │   ├── EventListener.js
│   │   │   │   ├── RequestError.js
│   │   │   │   ├── path.js
│   │   │   │   ├── polyfills/
│   │   │   │   │   ├── fileReaderPoly.js
│   │   │   │   │   ├── localStorage.js
│   │   │   │   │   └── xhrshim.js
│   │   │   │   ├── socket.io/
│   │   │   │   │   └── socket.io.js
│   │   │   │   ├── utils.js
│   │   │   │   └── xdrpc.js
│   │   │   └── modules/
│   │   │       ├── AI.js
│   │   │       ├── Apps.js
│   │   │       ├── Auth.js
│   │   │       ├── Debug.js
│   │   │       ├── Drivers.js
│   │   │       ├── EmailConfirmationDialog.js
│   │   │       ├── FSItem.js
│   │   │       ├── FileSystem/
│   │   │       │   ├── Batch.js
│   │   │       │   ├── index.js
│   │   │       │   ├── operations/
│   │   │       │   │   ├── copy.js
│   │   │       │   │   ├── deleteFSEntry.js
│   │   │       │   │   ├── getReadUrl.js
│   │   │       │   │   ├── mkdir.js
│   │   │       │   │   ├── move.js
│   │   │       │   │   ├── read.js
│   │   │       │   │   ├── readdir.js
│   │   │       │   │   ├── readdirSubdomains.js
│   │   │       │   │   ├── rename.js
│   │   │       │   │   ├── revokeReadUrl.js
│   │   │       │   │   ├── sign.js
│   │   │       │   │   ├── space.js
│   │   │       │   │   ├── stat.js
│   │   │       │   │   ├── symlink.js
│   │   │       │   │   ├── upload.js
│   │   │       │   │   └── write.js
│   │   │       │   └── utils/
│   │   │       │       └── getAbsolutePathForApp.js
│   │   │       ├── Hosting.js
│   │   │       ├── KV.js
│   │   │       ├── OS.js
│   │   │       ├── Peer.js
│   │   │       ├── Perms.js
│   │   │       ├── PuterDialog.js
│   │   │       ├── UI.js
│   │   │       ├── UsageLimitDialog.js
│   │   │       ├── Util.js
│   │   │       ├── Workers.js
│   │   │       └── networking/
│   │   │           ├── PSocket.js
│   │   │           ├── PTLS.js
│   │   │           ├── PWispHandler.js
│   │   │           ├── parsers.js
│   │   │           └── requests.js
│   │   ├── test/
│   │   │   ├── ai.test.js
│   │   │   ├── fs.test.js
│   │   │   ├── index.html
│   │   │   ├── kv.test.js
│   │   │   └── txt2speech.test.js
│   │   ├── types/
│   │   │   ├── modules/
│   │   │   │   ├── ai.d.ts
│   │   │   │   ├── apps.d.ts
│   │   │   │   ├── auth.d.ts
│   │   │   │   ├── debug.d.ts
│   │   │   │   ├── drivers.d.ts
│   │   │   │   ├── filesystem.d.ts
│   │   │   │   ├── fs-item.d.ts
│   │   │   │   ├── hosting.d.ts
│   │   │   │   ├── kv.d.ts
│   │   │   │   ├── networking.d.ts
│   │   │   │   ├── os.d.ts
│   │   │   │   ├── peer.d.ts
│   │   │   │   ├── perms.d.ts
│   │   │   │   ├── ui.d.ts
│   │   │   │   ├── util.d.ts
│   │   │   │   └── workers.d.ts
│   │   │   ├── puter.d.ts
│   │   │   └── shared.d.ts
│   │   └── webpack.config.js
│   ├── puter-wisp/
│   │   ├── README.md
│   │   ├── basic.html
│   │   ├── devlog/
│   │   │   └── unit_test_usefulness/
│   │   │       ├── a.js
│   │   │       ├── b.js
│   │   │       └── test_a_b.diff
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── exports.js
│   │   └── test/
│   │       └── test.js
│   ├── putility/
│   │   ├── README.md
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── AdvancedBase.js
│   │   │   ├── bases/
│   │   │   │   ├── BasicBase.js
│   │   │   │   └── FeatureBase.js
│   │   │   ├── concepts/
│   │   │   │   └── Service.js
│   │   │   ├── features/
│   │   │   │   ├── EmitterFeature.js
│   │   │   │   ├── NodeModuleDIFeature.js
│   │   │   │   ├── PropertiesFeature.js
│   │   │   │   ├── ServiceFeature.js
│   │   │   │   ├── TopicsFeature.js
│   │   │   │   └── TraitsFeature.js
│   │   │   ├── libs/
│   │   │   │   ├── context.js
│   │   │   │   ├── event.js
│   │   │   │   ├── invoker.js
│   │   │   │   ├── listener.js
│   │   │   │   ├── log.js
│   │   │   │   ├── promise.js
│   │   │   │   └── string.js
│   │   │   ├── system/
│   │   │   │   └── ServiceManager.js
│   │   │   └── traits/
│   │   │       └── traits.js
│   │   └── test/
│   │       ├── ServiceManager.test.js
│   │       ├── context.test.js
│   │       ├── event.test.js
│   │       ├── listener.test.js
│   │       ├── log.test.js
│   │       ├── test.js
│   │       ├── topics.test.js
│   │       └── traits.test.js
│   └── useapi/
│       ├── main.js
│       └── package.json
├── tests/
│   ├── README.md
│   ├── api-tester/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── apitest.js
│   │   ├── benches/
│   │   │   ├── __entry__.js
│   │   │   ├── simple.js
│   │   │   ├── stat_intensive_1.js
│   │   │   └── write_intensive_1.js
│   │   ├── coverage_models/
│   │   │   ├── copy.js
│   │   │   ├── move.js
│   │   │   └── write.js
│   │   ├── doc/
│   │   │   └── cartesian.md
│   │   ├── lib/
│   │   │   ├── Assert.js
│   │   │   ├── CoverageModel.js
│   │   │   ├── ReportGenerator.js
│   │   │   ├── TestFactory.js
│   │   │   ├── TestRegistry.js
│   │   │   ├── TestSDK.js
│   │   │   ├── log_error.js
│   │   │   └── sleep.js
│   │   ├── package.json
│   │   ├── puter_js/
│   │   │   ├── __entry__.js
│   │   │   ├── auth/
│   │   │   │   ├── __entry__.js
│   │   │   │   └── whoami.js
│   │   │   └── load.cjs
│   │   ├── test_sdks/
│   │   │   └── puter-rest.js
│   │   ├── tests/
│   │   │   ├── __entry__.js
│   │   │   ├── auth.js
│   │   │   ├── batch.js
│   │   │   ├── copy_cart.js
│   │   │   ├── delete.js
│   │   │   ├── fsentry.js
│   │   │   ├── mkdir.js
│   │   │   ├── move.js
│   │   │   ├── move_cart.js
│   │   │   ├── readdir.js
│   │   │   ├── stat.js
│   │   │   ├── telem_write.js
│   │   │   ├── write_and_read.js
│   │   │   └── write_cart.js
│   │   ├── tools/
│   │   │   ├── readdir_profile.js
│   │   │   └── test_read.js
│   │   └── toxiproxy/
│   │       ├── toxiproxy.json
│   │       └── toxiproxy_control.json
│   ├── ci/
│   │   ├── api-test.py
│   │   ├── common.py
│   │   ├── playwright-test.py
│   │   ├── requirements.txt
│   │   └── vitest.py
│   ├── example-client-config.yaml
│   ├── playwright/
│   │   ├── .github/
│   │   │   └── workflows/
│   │   │       └── playwright.yml
│   │   ├── .gitignore
│   │   ├── config/
│   │   │   └── test-config.ts
│   │   ├── package.json
│   │   ├── playwright.config.ts
│   │   └── tests/
│   │       ├── file-system/
│   │       │   ├── batch.spec.ts
│   │       │   ├── copy_cart.spec.ts
│   │       │   ├── delete.spec.ts
│   │       │   ├── fixtures.ts
│   │       │   ├── mkdir.spec.ts
│   │       │   ├── move.spec.ts
│   │       │   ├── move_cart.spec.ts
│   │       │   ├── readdir.spec.ts
│   │       │   ├── stat.spec.ts
│   │       │   ├── write_and_read.spec.ts
│   │       │   └── write_cart.spec.ts
│   │       └── whoami.spec.ts
│   ├── puterJsApiTests/
│   │   ├── ai_chat_completions.test.ts
│   │   ├── kv.test.ts
│   │   ├── testUtils.ts
│   │   └── vite.config.ts
│   └── tsconfig.json
├── tools/
│   ├── .commit
│   ├── README.md
│   ├── auth_gui.js
│   ├── build_relay.sh
│   ├── build_v86.sh
│   ├── check-translations.js
│   ├── comment-parser/
│   │   ├── main.js
│   │   ├── package.json
│   │   └── test/
│   │       └── test.js
│   ├── doc_helper.js
│   ├── file-walker/
│   │   ├── package.json
│   │   └── test.js
│   ├── gen-release-notes.js
│   ├── genwiki/
│   │   ├── main.js
│   │   └── package.json
│   ├── keygen/
│   │   ├── gen-peer-keys.js
│   │   └── package.json
│   ├── l_checker_config.json
│   ├── license-headers/
│   │   ├── main.js
│   │   └── package.json
│   ├── migrations-test/
│   │   ├── main.js
│   │   ├── noop.puter.json
│   │   └── package.json
│   ├── module-docgen/
│   │   ├── defs.js
│   │   ├── main.js
│   │   ├── package.json
│   │   └── processors.js
│   ├── run-selfhosted.js
│   ├── token-count-accuracy/
│   │   ├── package.json
│   │   └── test.js
│   └── validate-eslint.js
├── tsconfig.base.json
├── tsconfig.build.json
├── tsconfig.json
├── volatile/
│   ├── README.md
│   ├── config/
│   │   └── .gitignore
│   └── runtime/
│       └── .gitignore
└── ws-debug.mjs

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
.dockerignore
Dockerfile
node_modules
/puter


================================================
FILE: .env.example
================================================
PORT=4000


================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto


================================================
FILE: .github/FUNDING.yml
================================================
github: ['HeyPuter']


================================================
FILE: .github/workflows/docker-image.yaml
================================================
#
name: Docker Image CI

# Configures this workflow to run every time a change is pushed to the
# branch called `main`.
on:
  push:
    tags:
      - '*.*.*'
    branches:
      - 'main'

# 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 }}

# 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

    # Sets the permissions granted to the `GITHUB_TOKEN` for the actions
    # in this job.
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      # 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: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      # 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

      # 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


================================================
FILE: .github/workflows/main.yml
================================================
name: Maintain Release Merge PR

on:
  push:
    branches:
      - main

jobs:
  update-release-pr:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Git
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
      - name: Check for existing PR
        id: find-pr
        uses: juliangruber/find-pull-request-action@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          branch: release
      - uses: actions/checkout@v4
        if: steps.find-pr.outputs.number == ''
        with:
          ref: release
      - name: Reset release branch
        if: steps.find-pr.outputs.number == ''
        run: |
          git fetch origin main:main
          git reset --hard main
      - name: Create/Update PR
        if: steps.find-pr.outputs.number == ''
        uses: peter-evans/create-pull-request@v6
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          commit-message: Update release branch
          title: Merge Release Auto-PR
          body: Merging this PR will invoke release actions          
          branch: auto-update/release


================================================
FILE: .github/workflows/notify-prod.yaml
================================================
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"}}'

================================================
FILE: .github/workflows/release-please.yml
================================================
on:
  push:
    branches:
      - main

permissions:
  contents: write
  pull-requests: write

name: release-please

jobs:
  release-please:
    runs-on: ubuntu-latest
    steps:
      - uses: google-github-actions/release-please-action@v4
        with:
          release-type: node


================================================
FILE: .github/workflows/test.yml
================================================
name: test

on:
  push:
    branches: ["main"]
    paths-ignore:
      - "src/docs/**"
  pull_request:
    branches: ["main"]
    paths-ignore:
      - "src/docs/**"

jobs:
  test-backend:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [24.x]

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: Backend Tests (with coverage)
        env:
          NODE_OPTIONS: "--max-old-space-size=4096"
        run: |
          npm ci
          npm run build
          npm run test:backend -- --coverage --coverage.reporter=json --coverage.reporter=json-summary --coverage.reporter=lcov

      - name: Upload backend coverage report
        if: ${{ always() && hashFiles('coverage/**/coverage-summary.json') != '' }}
        uses: actions/upload-artifact@v4
        with:
          name: backend-coverage-${{ matrix.node-version }}
          path: coverage
          retention-days: 5

  api-test:
    name: API tests (node env, api-test)
    runs-on: ubuntu-latest
    timeout-minutes: 10

    strategy:
      matrix:
        node-version: [24.x]

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: API Test
        run: |
          pip install -r ./tests/ci/requirements.txt
          ./tests/ci/api-test.py

      - uses: actions/upload-artifact@v4
        if: ${{ !cancelled() }}
        with:
          name: (api-test) server-logs
          path: /tmp/backend.log
          retention-days: 3

  vitest:
    name: puterjs (node env, vitest)
    runs-on: ubuntu-latest
    timeout-minutes: 10

    strategy:
      matrix:
        node-version: [24.x]

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: Vitest Test
        run: |
          pip install -r ./tests/ci/requirements.txt
          ./tests/ci/vitest.py


================================================
FILE: .gitignore
================================================
# Misc
.DS_Store

# Dependencies
node_modules/

*.zip
*.tgz
license.config.json
license-header.txt

# Build Outputs
dist/

# VS Code IDE
.vscode/**/*
!.vscode/extensions.json
!.vscode/launch.json
!.vscode/tasks.json

# Local env files
.env
!.env.example

# 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


================================================
FILE: .gitmodules
================================================
[submodule "submodules/v86"]
	path = submodules/v86
	url = git@github.com:HeyPuter/v86.git
[submodule "submodules/twisp"]
	path = submodules/twisp
	url = git@github.com:MercuryWorkshop/twisp.git
[submodule "submodules/epoxy-tls"]
	path = submodules/epoxy-tls
	url = git@github.com:MercuryWorkshop/epoxy-tls.git
[submodule "submodules/wiki"]
	path = submodules/wiki
	url = https://github.com/HeyPuter/puter.wiki.git


================================================
FILE: .husky/pre-commit
================================================
#!/usr/bin/env sh

tmpfile="$(mktemp)"
git diff --cached --name-only -z --diff-filter=ACMR -- \
  '*.js' '*.mjs' '*.cjs' '*.jsx' '*.ts' '*.tsx' '*.vue' \
  > "$tmpfile"

if [ -s "$tmpfile" ]; then
  xargs -0 eslint --fix < "$tmpfile" || true
  xargs -0 git add < "$tmpfile"
fi

rm -f "$tmpfile"


================================================
FILE: .idx/dev.nix
================================================
# To learn more about how to use Nix to configure your environment
# see: https://developers.google.com/idx/guides/customize-idx-env
{ pkgs, ... }: {
  # Which nixpkgs channel to use.
  channel = "stable-25.05"; # or "unstable"

  # Use https://search.nixos.org/packages to find packages
  packages = [
    pkgs.python3
    pkgs.nodejs_24
  ];

  # Sets environment variables in the workspace
  env = {};
  idx = {
    # Search for the extensions you want on https://open-vsx.org/ and use "publisher.id"
    extensions = [
      # "vscodevim.vim"
    ];

    # Enable previews and customize configuration
    previews = {
      # Currently disabled because the preview system wasn't working
      enable = false;
      previews = {
        web = {
        command = [
          "npm"
          "run"
          "start"
          "--"
          "--port"
          "$PORT"
          "--host"
          "0.0.0.0"
          "--disable-host-check"
        ];
          manager = "web";
        };
      };
    };

    # Workspace lifecycle hooks
    workspace = {
      # Runs when a workspace is first created
      onCreate = {
        # npm-install = "npm install";
        # Currently disabled because the preview system wasn't working
      };
      # Runs when the workspace is (re)started
      onStart = {
        # npm-install = "npm install";
        # Currently disabled because the preview system wasn't working
      };
    };
  };
}


================================================
FILE: .is_puter_repository
================================================


================================================
FILE: .npmrc
================================================
engine-strict=true

================================================
FILE: .prettierignore
================================================
node_modules
dist
build

================================================
FILE: BUG-BOUNTY.md
================================================
# 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](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.

## Rules of Engagement

To participate, you must:

1. **Report responsibly**: Provide detailed steps to reproduce the issue, including proof-of-concept code or screenshots where applicable.
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.

Reports that do not meet these guidelines may not be eligible for a reward.

## Reporting Process

To report a vulnerability, email us at: **[security@puter.com](mailto:security@puter.com)**.
Include:

* A description of the vulnerability
* Steps to reproduce
* Potential impact
* Suggested remediation (if available)

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.


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## v2.5.1 (2025-02-13)

### Puter

#### Bug Fixes

- phoenix changelog ([0bcbc8f](https://github.com/HeyPuter/puter/commit/0bcbc8f7845de99305f53c6da2bb1f365b87ac50))
- update package.json ([c2c5d88](https://github.com/HeyPuter/puter/commit/c2c5d883365ae33749709d11e0c2de9050ca144e))
- oops, no export (putility.libs.event) ([fa4b38c](https://github.com/HeyPuter/puter/commit/fa4b38cd028be4b19ec98bcf588227e0fc92af9d))
- broken test in putility ([a803d55](https://github.com/HeyPuter/puter/commit/a803d55cfbdd5b15e7fe48df3f4363c1658f0930))
- parse body before auth for /down ([70fde95](https://github.com/HeyPuter/puter/commit/70fde95255532a7fe0d99c64a4efb1ae625776a4))
- fix previous fix ([e5c3769](https://github.com/HeyPuter/puter/commit/e5c3769bd813b1510dd0429e1e4eca8e277af7c7))
- potential fix for /down auth ([390230c](https://github.com/HeyPuter/puter/commit/390230c5a07b1774f84a1b3505f7531ce81dc2cc))
- allow command provider to not implement complete method ([2000b89](https://github.com/HeyPuter/puter/commit/2000b8909f08d91147b86fce22fe006e0c3152d2))
- unfixed fix from earlier ([e6fc773](https://github.com/HeyPuter/puter/commit/e6fc7737066d09509f0c7b38e4c51f25e86e12d0))
- parser error for empty json buffer ([484bb5c](https://github.com/HeyPuter/puter/commit/484bb5c201e17bf45e1a1d97b1e9b2d61d6087dc))
- fix name and id for openai tool calls ([d2358d2](https://github.com/HeyPuter/puter/commit/d2358d234b45d719a2cc4e92582ed89d2d1832ab))
- let messages with tool_calls have content=null ([29c0241](https://github.com/HeyPuter/puter/commit/29c024111943267b741b1b4a8933e1ea1a35a65e))
- repair stream end ([8f27742](https://github.com/HeyPuter/puter/commit/8f277420380e9c6fa8a9925a3e9651f48b8734e6))
- add type=text ([e2797c3](https://github.com/HeyPuter/puter/commit/e2797c38d0754930033780d5270cc64cbba2c94e))
- various issues with Mail module ([55d052c](https://github.com/HeyPuter/puter/commit/55d052cfc2549bfdf72f3a8b27cdc7dc4294bc54))
- buffer incomplete JSON objects from AI stream ([60eef2f](https://github.com/HeyPuter/puter/commit/60eef2fc6734f88df06e2f85db9b9368cc8c227f))
- mistake in 0c42613 ([8ffd000](https://github.com/HeyPuter/puter/commit/8ffd0004b3b7b34cd6a9c43c6ca960c7a1cbbe15))
- fix microcents to USD conversion in AIChatService ([dcd47bc](https://github.com/HeyPuter/puter/commit/dcd47bc4cfc5f8a67ea86e0485d08c2417f899ed))
- claude duplicate messages in stream ([0fac03a](https://github.com/HeyPuter/puter/commit/0fac03a05a4f597f7ed531651c830e44012b646b))
- skip request-count usage check via AIChatService ([6083e3a](https://github.com/HeyPuter/puter/commit/6083e3ac52fcde7f598c838bc49085e6b3de7162))
- remove log from InternetModule ([c7f3e0b](https://github.com/HeyPuter/puter/commit/c7f3e0b937f5d72d6f30dba25d7c351e2e14f289))
- small workaround for duplicate close ([06452f5](https://github.com/HeyPuter/puter/commit/06452f5283085b18266ee7fb89136b9c23879243))
- race condition and buffer issue in puter.http ([36dc966](https://github.com/HeyPuter/puter/commit/36dc9664ad5520b21c07a1b5c85c8aff7cbe423b))
- missing some buffer contents in no-keepalive ([3f5b34c](https://github.com/HeyPuter/puter/commit/3f5b34cd341b9063d01baba72e708a9ebb16485b))
- new edge cases with function calls / tools ([9cbb741](https://github.com/HeyPuter/puter/commit/9cbb741a8ae8ea6b869b6ccf64cd3152b28c2b8c))
- oops, we're passing negative values; let's just remove this ([cf7aa27](https://github.com/HeyPuter/puter/commit/cf7aa27543700d6268ee709f127e73f7cfe12a5a))
- oops we still need that ([61824ea](https://github.com/HeyPuter/puter/commit/61824ea04b0cb7611d2acdf45e0a1ecc2856901a))
- remove hard-coded token limit for OpenAI ([8143e57](https://github.com/HeyPuter/puter/commit/8143e5700f53279a5a18d21b7c5466f3b9bb6ce6))
- wisp relay authentication ([6f39365](https://github.com/HeyPuter/puter/commit/6f39365b24cda53a6cac7e203b9d8cbc09bb0ba3))
- reduce code paths for querystrings ([e8f5450](https://github.com/HeyPuter/puter/commit/e8f5450cb05213c3c06802442103f5c414eee5cc))
- icons ([d03952b](https://github.com/HeyPuter/puter/commit/d03952b23712ae8a61c7f2c7582d297691e0ecc1))
- subdomains to deleted files tried to deref fs node ([38ccc82](https://github.com/HeyPuter/puter/commit/38ccc82c8e95636ee4b7c5ca2f761098f12affa2))
- app icon empty string should be skipped ([37ca892](https://github.com/HeyPuter/puter/commit/37ca89228cc2f978602098ee4aae1ecb3d333526))
- save_account case for disable_user_signup ([766c235](https://github.com/HeyPuter/puter/commit/766c235cc738051588a67ff5ab4230e76b64173c))
- use .get() for Map lookup. fix: correctly set url and url_paths. fix: null check to throw error. ([78ac033](https://github.com/HeyPuter/puter/commit/78ac033a1ca4f51b71c2bcb185b305903f7be495))
- ensure puter.signup emit resolves ([113ed31](https://github.com/HeyPuter/puter/commit/113ed31336c494a3f7a9e744a34de35b3785c033))
- --onlycase param broke cartesian tests ([d9822a4](https://github.com/HeyPuter/puter/commit/d9822a4f09e3e0c5fbed8c655435f534af949290))
- empty response when mkdir is a no-op ([f359ae1](https://github.com/HeyPuter/puter/commit/f359ae193e87552b3a2e2aafa3fda389478fca38))
- mkdir with create_missing when some parents exist ([807c3ba](https://github.com/HeyPuter/puter/commit/807c3ba5eca02f69b5e6ce547420312b68c7993f))
- possible out-or-order response objects from batch ([fb70251](https://github.com/HeyPuter/puter/commit/fb7025164e3f42cae1365ec65960019b24f4360d))
- app data check error in write ([5ef75e5](https://github.com/HeyPuter/puter/commit/5ef75e5df35ae95242da97235512495b7585bd0d))
- missing parent dirs created in move ([9d9d97f](https://github.com/HeyPuter/puter/commit/9d9d97fd0074058506b0506d5027b0c6b8a26845))
- missing changes to run-selfhosted.js ([6f4b1bf](https://github.com/HeyPuter/puter/commit/6f4b1bf94a031b3324f5ecd51557b1298a1c3175))
- appease mocha's import requirements ([d6bbba7](https://github.com/HeyPuter/puter/commit/d6bbba7bf064991d59fbfe74db5221e0118a781c))
- error msg for invalid puter-ocr urls ([6a6bfa0](https://github.com/HeyPuter/puter/commit/6a6bfa034fe16dba7172ab5adbf23f00df38301d))
- improper 500 in wisp token verify ([75aaaa6](https://github.com/HeyPuter/puter/commit/75aaaa66a8c7df00e1fb80c353d890269296839c))
- actor param in legacy /write ([7aa886d](https://github.com/HeyPuter/puter/commit/7aa886d573362e6739bd99bbed02f4831557ccb4))
- new desktop height calculation when resizing browser window ([a295420](https://github.com/HeyPuter/puter/commit/a295420f58326b04c976cf92bd2d582d2eafa71b))
- circular imports ([8fabf01](https://github.com/HeyPuter/puter/commit/8fabf014a9eb783183e87489ae2b6c6bbc42c99a))
- test and improve boolify ([44ad3c5](https://github.com/HeyPuter/puter/commit/44ad3c578106d2b01007240188db57760c15af96))
- skip test files in mod lib loading ([f60c008](https://github.com/HeyPuter/puter/commit/f60c008158127458e02e3bb92287617d9f1f9514))
- shortcut issue ([6d196d5](https://github.com/HeyPuter/puter/commit/6d196d59f026bec4acb0296d8f0f38c7cee2e8c2))
- test for get-launch-apps ([740fdb5](https://github.com/HeyPuter/puter/commit/740fdb592e494bf5b197493774cef6559bfb50b9))
- add package-lock.json ([3097b86](https://github.com/HeyPuter/puter/commit/3097b86597218de9e59b450b70185634a94be210))
- try redundant npm install after build stage ([8963eb0](https://github.com/HeyPuter/puter/commit/8963eb0c4f1220dd515ac6ed7a2a8f1de26655ae))
- I'ma buy GitHub a coffee and spill it on their servers if this works ([686d3de](https://github.com/HeyPuter/puter/commit/686d3de518e6e090d683294ad3dd856db26856a0))
- oh, right; there's two of them ([a13af7e](https://github.com/HeyPuter/puter/commit/a13af7e31aa4cd36457a90a7d75878b6d39ba73b))

## v2.5.0 (2025-01-07)

### Puter

#### Features

- hash-based distributed cache inval ([d386096](https://github.com/HeyPuter/puter/commit/d38609646793a5a14b8af96964fc7176725a0531))
- add Escape key functionality to UIPrompt for closing the prompt ([e1b6c83](https://github.com/HeyPuter/puter/commit/e1b6c83813d03809aba0abdecbf6de5529728031))
- set max token to 8096 ([b2ea8a3](https://github.com/HeyPuter/puter/commit/b2ea8a3888c5496858d257018071ba54abd6f4a8))
- added tagify in Filetype-Association input in dev center ([0cd1f15](https://github.com/HeyPuter/puter/commit/0cd1f151b5986ede431f1792139fa1a5471ae059))
- add reset edit changes button to dev-center ([55ffd80](https://github.com/HeyPuter/puter/commit/55ffd801e007723758eacc17ec732ee5a336123e))
- enable/disable save button in dev-center iff changes made ([63a0053](https://github.com/HeyPuter/puter/commit/63a0053da8c76bf4ac175c7f17353225443dd342))
- record signup metadata for abuse prevention ([66016b9](https://github.com/HeyPuter/puter/commit/66016b9db602ca85e8f0ddc846865d4641e64190))
- add support for categories in the Dev Center ([7cf215a](https://github.com/HeyPuter/puter/commit/7cf215ab677e3fc912a3bd1ac52795c1e8860c32))
- puter.js's showSpinner() will keep the spinner active for at least 1200ms ([fc5aca1](https://github.com/HeyPuter/puter/commit/fc5aca1f72de22c1530054272b55a59021ba9caa))
- allow developers to set social media images for their apps ([be36d31](https://github.com/HeyPuter/puter/commit/be36d31509280340e2a62a8c478b1e64617792a4))
- automatically open the browser when starting Puter ([2d43129](https://github.com/HeyPuter/puter/commit/2d4312972a1377a64732694811fe889f59573432))
- spinner for the `showWorking()` overlay in puter.js ([1062363](https://github.com/HeyPuter/puter/commit/1062363096418f164a6d00ed8872770ff64237b5))
- show profile pics in sharing notifications ([0e45132](https://github.com/HeyPuter/puter/commit/0e45132c05aa1106503fef02b7e4c97ecc675e10))
- Implement profile pictures ([0885937](https://github.com/HeyPuter/puter/commit/0885937f033caf35503eeb9e65bb390952992faf))
- allow `launchApp` to open explorer at a specific path ([8fefd4a](https://github.com/HeyPuter/puter/commit/8fefd4a61f0005d4f3ec2e43f7249f3edd91c837))
- Require email confirmation before sharing ([cdd1a8c](https://github.com/HeyPuter/puter/commit/cdd1a8c4e379b885ff48a874ae5577d2f0efae06))
- show unread notification count in the browser tab's title ([045259c](https://github.com/HeyPuter/puter/commit/045259cefbe24e3f52fe3840e4975d3243e99957))
- in Share window, display access level next to recipient ([cf4b6aa](https://github.com/HeyPuter/puter/commit/cf4b6aa1c24d936f9a42ca1e2945eea40939c970))
- when sharing, users can choose between 'viewer' and 'editor' for permissions ([0cbe013](https://github.com/HeyPuter/puter/commit/0cbe0139d7f306ce62992f1eda94d99e09b32df8))
- handle `notif.ack` in desktop ([a6650ee](https://github.com/HeyPuter/puter/commit/a6650ee2d8074aeb7c476e5572334853f1b6d7e8))
- add error handling to the share flow ([b5bb95e](https://github.com/HeyPuter/puter/commit/b5bb95e2d7f6021a6341e26cf15d5449ada48830))
- search ([55d2af1](https://github.com/HeyPuter/puter/commit/55d2af189e9479fb5980ce149ce74e890b325014))
- search endpoint ([b589512](https://github.com/HeyPuter/puter/commit/b589512c9dedec22fd41b92cbba2570042149873))
- the `socialLink` UI component ([1adfe5c](https://github.com/HeyPuter/puter/commit/1adfe5c70947d9de008c9d601f91b1ee14128d5d))
- Reaload App option in the window title bar context menu ([27c01c9](https://github.com/HeyPuter/puter/commit/27c01c9bd991ef871153eb5931f78fec265a62e4))
- add puter.auth.whoami() ([da0022a](https://github.com/HeyPuter/puter/commit/da0022abf0f880c7b52d2cd937ef9d1298fc09cc))
- add puter.log ([755736e](https://github.com/HeyPuter/puter/commit/755736edee9baa783be9b7d96083d908a2f2f750))
- collapsible sidebar menu in Dev Center ([1056231](https://github.com/HeyPuter/puter/commit/1056231004a629f3f76f2525ec7d83b67d3d7fa5))
- customize the order of Explorer sidebar items ([ff30de1](https://github.com/HeyPuter/puter/commit/ff30de1d6947e4692b5cf0da2e19ab37aacf1ec8))
- add extension API for modules ([14d45a2](https://github.com/HeyPuter/puter/commit/14d45a27edb99f63b4f6e010221e3a0880ae246d))
- first extension that implements a custom user options menu ([fc5e15f](https://github.com/HeyPuter/puter/commit/fc5e15f2a6d4eb5e5847fa7f2dd87b1fa382fc7c))
- add support for extensions ([b018571](https://github.com/HeyPuter/puter/commit/b018571a86f4114eab9b5edde4ecd87e343d22a7))
- add an 'Upload' button at the bottom of `OpenFilePicker` ([54ae69b](https://github.com/HeyPuter/puter/commit/54ae69b7b76016307c3b92437ca06dc2aa1eddb9))
- Allow apps to toggle `credentialless` via Dev Center ([af511c0](https://github.com/HeyPuter/puter/commit/af511c05e3ddddcce661c5406d5c831a21689608))
- add config for blocked email domains ([955b087](https://github.com/HeyPuter/puter/commit/955b087297f829b11b82dc9bd79a0e03721c5f33))
- add support for `fadeIn` effect for `UIWindow` ([13248a9](https://github.com/HeyPuter/puter/commit/13248a99bfa318e84cb99e2954a5f46805eda34f))
- welcome screen to quickly explain what Puter is ([564ff65](https://github.com/HeyPuter/puter/commit/564ff65363258cab4196b967dd556105e424d48c))
- v86 9p server support ([b145e30](https://github.com/HeyPuter/puter/commit/b145e30a90ff2f0d44d89f83dbda4de1bf2991d4))
- support readdir for directory symlinks ([7f1b870](https://github.com/HeyPuter/puter/commit/7f1b870d302421972c4f6221ae6d93b5979d51dd))
- allow passing cli args via url ([5317adf](https://github.com/HeyPuter/puter/commit/5317adf8a4961be3f0ca2a8c403c922633f934fa))
- add -c flag for phoenix ([b6c0cb6](https://github.com/HeyPuter/puter/commit/b6c0cb6abc1c29846b4b7e696812476bea24bbc7))
- translate README.md to Dutch ([31e2773](https://github.com/HeyPuter/puter/commit/31e2773743c336630c917e893b0148441f5fc515))
- add connectToInstance method to puter.ui ([62634b0](https://github.com/HeyPuter/puter/commit/62634b0afe4d33da08768975322d4deb23041442))
- add method to list models ([fd86934](https://github.com/HeyPuter/puter/commit/fd86934bc9021541810447cf7e2a5f33b3e283b3))
- add streaming to XHR driver client ([7600d9b](https://github.com/HeyPuter/puter/commit/7600d9b07c5b719d529f8a48c38d9178efefa266))
- add writable attribute to fs items ([2386d87](https://github.com/HeyPuter/puter/commit/2386d87229aa6205ef8ced6563371ab40a0def62))
- report feature flags in /whoami ([4561b89](https://github.com/HeyPuter/puter/commit/4561b8937de025471c2dfb1771465d779cefab5d))
- make public folders a config opt-in ([209555c](https://github.com/HeyPuter/puter/commit/209555c1d93845fa129bea450f9c25d595a3c60f))
- add feature flag for /share ([461ea3e](https://github.com/HeyPuter/puter/commit/461ea3eae6ad32bf34c43a822de7a06f08efb556))
- add message encryption between Puter peers ([cea2964](https://github.com/HeyPuter/puter/commit/cea29645fec493020a4f66e378b087fa17ae03d4))
- add test_mode flag ([9a9bd5e](https://github.com/HeyPuter/puter/commit/9a9bd5eaf0aca8fd1cc57455db03dba55801d5a0))
- add tts driver to puterai module ([78fa77d](https://github.com/HeyPuter/puter/commit/78fa77d9200e0b9fafc4014f8d0cb08c74cd16cb))
- add image generation driver to puterai module ([fb26fdb](https://github.com/HeyPuter/puter/commit/fb26fdbc561d5545d28352427553695cd3237ad5))
- add chat completions driver to puterai module ([4e3bd18](https://github.com/HeyPuter/puter/commit/4e3bd1831e92e83ce9b4e30a16afd562b0221dd8))
- add --overwrite-config and configurable uuid masking ([ef6671d](https://github.com/HeyPuter/puter/commit/ef6671da18f6841cb2143808fe21586ac3505942))
- add textract driver to puterai module ([f924d48](https://github.com/HeyPuter/puter/commit/f924d48b02f39884931db45a05dd61b65f2cee4a))
- add password reset from server console ([984ae9e](https://github.com/HeyPuter/puter/commit/984ae9e6a23da17414e43d58fc0e861827031269))
- add server command to scan permissions ([54471fa](https://github.com/HeyPuter/puter/commit/54471fada946a70eaa0df6bfceae995bc4e5848c))
- grant user driver perms from admin ([c9ded89](https://github.com/HeyPuter/puter/commit/c9ded89b22bb822c20aea379a17a8bdf74a658de))
- replace default_user with admin ([f0c36a1](https://github.com/HeyPuter/puter/commit/f0c36a1cdf16f11765c29360a5c38140008b90c7))
- add system user ([ab15629](https://github.com/HeyPuter/puter/commit/ab156297a746c0754145c2abdb2c99bb1b30651a))
- add options to disable winston and devwatch ([5d5f566](https://github.com/HeyPuter/puter/commit/5d5f5660b4020650b68b79ccf3860d3fb0bf98a9))
- 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


- complete Hungarian translation of Puter #972 ([7d2787d](https://github.com/HeyPuter/puter/commit/7d2787d26b3a64cbc128fb2cb3871b43b41912fe))
- add missing Igbo translations for billing-related terms ([f0f19e7](https://github.com/HeyPuter/puter/commit/f0f19e727e574a8558fcbbf27ba501f434db69f8))
- Complete the Vietnamese translation of Puter #954 ([56489c3](https://github.com/HeyPuter/puter/commit/56489c33f611fc053096b455e4cb7b3d8f20852c))
- Complete the  French (Français) translation of Puter #975 ([c840bc8](https://github.com/HeyPuter/puter/commit/c840bc8161055b90e040bdae3196817e0791ecf5))
- Complete the German (Deutsch) translation of Puter ([05fef67](https://github.com/HeyPuter/puter/commit/05fef6749e8d80f13ab94a4e0ea49ce4972a0961))
- (#954) Add Vietnamese translations for billing-related terms ([267a55a](https://github.com/HeyPuter/puter/commit/267a55aae50f87edb483abb375029ff79e736112))
- add vietnamese translations for billing in vi.js ([3e26dbe](https://github.com/HeyPuter/puter/commit/3e26dbe6a0411fe75c36cf2866d34f28a2dcb553))
- added a few Korean translatations ([b23e800](https://github.com/HeyPuter/puter/commit/b23e800f4e70f162b52cc15053d03961a37033bb))
- add brazillian translations for billing-related terms in br.js (revision) ([fdfc90a](https://github.com/HeyPuter/puter/commit/fdfc90a9317a19d45a0b2b3ad283be9a10a92732))
- add brazillian translations for billing-related terms in br.js ([e66df14](https://github.com/HeyPuter/puter/commit/e66df14862e6dd7278623279e43e2189e7ddafe5))
- Add Indonesian Translation for i18n ([033643b](https://github.com/HeyPuter/puter/commit/033643b0e757b51ea0be90e2198bbec65d31cfc5))
- add Polish translations for billing-related terms ([15f9ade](https://github.com/HeyPuter/puter/commit/15f9aded26eaa4c630fe948350d3a53cdb0278a3))
- update Urdu localization with missing translations ([0c4b994](https://github.com/HeyPuter/puter/commit/0c4b9946442ad92549522fcd91ea6aefbb9f19d6))
- 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))
- correct Igbo translation for "Free" in billing terms ([6f4d57a](https://github.com/HeyPuter/puter/commit/6f4d57a3c6da607038f4fbe49c691478f47933be))

#### Bug Fixes

- missing ll_copy import ([8a9164d](https://github.com/HeyPuter/puter/commit/8a9164d7c5380aafb864b56ca1a3ee59f24daf38))
- bad uuid reference to resourceService ([13003c4](https://github.com/HeyPuter/puter/commit/13003c486fbebad0f26dd1b569f5fd5f2cefc9e7))
- allow localhost for development ([ad8a397](https://github.com/HeyPuter/puter/commit/ad8a3978c07e44f7a534981ddd65bc131c9aac6b))
- rewrite confusing log message ([dacbbf0](https://github.com/HeyPuter/puter/commit/dacbbf033dcc0f4506198761eab3bfb6ef915336))
- AppInformationService initialization ([2332602](https://github.com/HeyPuter/puter/commit/233260233c4e52399541aedbf8b13800de80d3fd))
- dev center app icon SVG issue ([47a4313](https://github.com/HeyPuter/puter/commit/47a4313d92152b9e5b4036715ac4f19431be8940))
- app icon double-encode bug ([23eab63](https://github.com/HeyPuter/puter/commit/23eab63776a146a78b10e973518158fc07b13653))
- first read of recommended apps ([a6b9d33](https://github.com/HeyPuter/puter/commit/a6b9d33d27909ead3d14eff4446062d62aad4651))
- prefix peer addresses with protocol ([efd4730](https://github.com/HeyPuter/puter/commit/efd4730f757471c3eac2d5e396dd69b619ad2999))
- clone message object ([728ecbf](https://github.com/HeyPuter/puter/commit/728ecbfb033082186ca9480f2ab2d1607b57ca5a))
- timing for PrefixLogger call to /whoami ([2dc6c47](https://github.com/HeyPuter/puter/commit/2dc6c4737b9ec9db281b4b32ed4bd20ac490e47d))
- try catching icon read errors before stream ([e56a62c](https://github.com/HeyPuter/puter/commit/e56a62c5390958e585f299751bafd13becc1c9b6))
- try catching on stream_to_buffer ([ada051b](https://github.com/HeyPuter/puter/commit/ada051b9b87e945b4a80c1fae99b8c5644b82dc0))
- check if row.timestamp is Date ([5d049e8](https://github.com/HeyPuter/puter/commit/5d049e8f06dafe2e499ccfea66ef013a9b595396))
- AppES PD alert ([f14e1fe](https://github.com/HeyPuter/puter/commit/f14e1fefcf18438bd59eb86d625b8c5a6fb3ffc5))
- fix for previous fix ([648d6e0](https://github.com/HeyPuter/puter/commit/648d6e036d6f8040a1e440c1e76dc9dcc746156f))
- fix fallback icon behavior in get_icon_stream ([4f3a161](https://github.com/HeyPuter/puter/commit/4f3a1618b10dd393f5c94c0967beb228a593b214))
- revert test change ([9c86614](https://github.com/HeyPuter/puter/commit/9c86614df5d58ca0385450e1edb5adb5b6d72300))
- acl check for subdomain on access ([c69006e](https://github.com/HeyPuter/puter/commit/c69006e1852befa93f94a7c45651025214941a4e))
- attempt fix for prod issue with app icons ([925ebd5](https://github.com/HeyPuter/puter/commit/925ebd531013e36ee5c05d53ef229d314fb89435))
- remove redundant notification query ([f87769b](https://github.com/HeyPuter/puter/commit/f87769b445d53e6322a55a788e26d38629299ae9))
- share only emails email_confirmed recipients ([2336a62](https://github.com/HeyPuter/puter/commit/2336a62b4f635c025b02bb7efe91b5ddf58bae25))
- database issue with KBKV update ([7ba1b76](https://github.com/HeyPuter/puter/commit/7ba1b7656b5e24375cad639b9a8e37577b526c09))
- taskbar items of apps should always appear before Trash ([94e7f5d](https://github.com/HeyPuter/puter/commit/94e7f5deb4330a844a680c22f55b8753225a1a7e))
- fullpage mode ([65d9188](https://github.com/HeyPuter/puter/commit/65d918866ea0ee981bc26151332b730abccb7be8))
- bug in writeFile rename ([298609c](https://github.com/HeyPuter/puter/commit/298609c6e9080e00c90b66c673e104d90f9d3ed0))
- remove unnecessary `item_path` definition in `delete` fs api ([c792f4a](https://github.com/HeyPuter/puter/commit/c792f4a345b307d024f73ff2817ae473b2620913))
- add missing permissions ([69e9df1](https://github.com/HeyPuter/puter/commit/69e9df1ae21cf906dfcc3d9d7a23455e5274271c))
- logic from previous commit ([6ca7011](https://github.com/HeyPuter/puter/commit/6ca701139a07a0d20071cf1532cc6e95639a01da))
- add fallback moderation in case openai goes down ([c6e814d](https://github.com/HeyPuter/puter/commit/c6e814daa80eec01c10f319ebebcb84c42cd26e1))
- permission strings for ES services ([4d9cc9b](https://github.com/HeyPuter/puter/commit/4d9cc9bd830d0c73024f2bc5a91ab226aedefded))
- resolve issue #983 - Stuck on Creating new app loading screen ([c75c9d0](https://github.com/HeyPuter/puter/commit/c75c9d03833af52730cac89a8fee5f5c317f0f78))
- provide actor context to ws event ([1b57801](https://github.com/HeyPuter/puter/commit/1b578019f915918e51185f5705d7fa6e0328b9ae))
- context error in user connected event ([9600823](https://github.com/HeyPuter/puter/commit/96008233ba4935e789cd092c07aa8b351cb44d45))
- signup 500 for temp user ([01395f3](https://github.com/HeyPuter/puter/commit/01395f302e763cdad022c0e5a995869fcd805d86))
- bad import for TeePromise ([acf8ae3](https://github.com/HeyPuter/puter/commit/acf8ae302ec4ee79c11c2b0e810edd53f21446c5))
- sorting bug in AIChatService ([7acb096](https://github.com/HeyPuter/puter/commit/7acb096addd58113cc8d4338ba941cd14ac81f4f))
- test issues from contextlink removal ([545e7db](https://github.com/HeyPuter/puter/commit/545e7db5bdac6e39962390469767667bc62857fd))
- add missing import ([e279dc6](https://github.com/HeyPuter/puter/commit/e279dc6e5f4095550f41aadd194ea94e1e2a2271))
- fake_chat default model and usage errors ([13a895b](https://github.com/HeyPuter/puter/commit/13a895b76b1e5a677c2eeeb0a07be6ce9fd02a99))
- update test kernel ([a1c2226](https://github.com/HeyPuter/puter/commit/a1c2226561655e091cbc0d014ada62bfc7881f2a))
- correct AI comment faults ([b40d453](https://github.com/HeyPuter/puter/commit/b40d4534a71565a7f2d0ae278c98d7326c5aa963))
- update package-lock.json ([8577185](https://github.com/HeyPuter/puter/commit/857718538b8a7bf27dc036f4eeb3728cb6ea96e7))
- ignore two calls with undefined origin ([ab4ba76](https://github.com/HeyPuter/puter/commit/ab4ba76433ac623abaa17c0e5dd024e95b9fef3f))
- undefined APIOrigin ([340c7a8](https://github.com/HeyPuter/puter/commit/340c7a821fb91e2d106c2b3febf8182de7b21f7d))
- add id to the setting menu item in user option menu ([67ca4cc](https://github.com/HeyPuter/puter/commit/67ca4ccf20fd714848121192d5ae7c41f3763da4))
- add an id to `My Websites` content menu item ([e662c78](https://github.com/HeyPuter/puter/commit/e662c782b745f4f98024d1353a6a162d5fe58c44))
- remove unnecessary `integrity` and `crossorigin` attributes in dev center when linking to jquery ([8dec78b](https://github.com/HeyPuter/puter/commit/8dec78b090ec4434ad77003d6f3c25de98779864))
- remove inactive links in README ([f3d270c](https://github.com/HeyPuter/puter/commit/f3d270ccbcd8990270cf968a3638b7affa2df6ba))
- improve backend mod error handling ([fe1a4cf](https://github.com/HeyPuter/puter/commit/fe1a4cfd4d5dd1eddbb2d50ef3f5ebf78a81656d))
- app query should return app metadata ([3cedd17](https://github.com/HeyPuter/puter/commit/3cedd17b8ed4acb1099bc2e87aba0137339c8a17))
- safe parsing of app metadata ([a2c7b37](https://github.com/HeyPuter/puter/commit/a2c7b379f8181b373b0513d9166f75adc147aafa))
- configuration for browser launch ([791f774](https://github.com/HeyPuter/puter/commit/791f7748c7c1959f63327a73a7e24e41b574a910))
- previous fix ([ee7bedd](https://github.com/HeyPuter/puter/commit/ee7bedd5586d69ce74f32c1400f377d6a8971eaa))
- always adapt model for ClaudeEnough ([56710e1](https://github.com/HeyPuter/puter/commit/56710e17f3b06eef07e54c243f6b725fcc4a4583))
- automatically open browser when starting only if in dev env ([f500fb4](https://github.com/HeyPuter/puter/commit/f500fb47061f8f3a3dc7d871cb529f5c0b058185))
- image generation supports test mode ([f533dca](https://github.com/HeyPuter/puter/commit/f533dca1a6d88ca7a14bd69f15d0a151e24c58e1))
- share issue with prefix usernames ([d30d62f](https://github.com/HeyPuter/puter/commit/d30d62f558ca5f8c74090900aa39c13ca3ca1d2e))
- permission grants in open_item ([16257a7](https://github.com/HeyPuter/puter/commit/16257a7b5459550ee3782cf32c87a8241325878d))
- sharing notification click opening directories ([bfacfc2](https://github.com/HeyPuter/puter/commit/bfacfc2a4e4b50c9e0842f9f2d56de67a598b959))
- add placeholders ([2c86240](https://github.com/HeyPuter/puter/commit/2c862403994ff6385144841db07dcc94c5c2fc2e))
- capitalize `Hindi` in i18n ([35fd158](https://github.com/HeyPuter/puter/commit/35fd15854ad3cc92924c4ded752e337f467a7125))
- give camera and recorder write permission to Desktop ([65e6d6c](https://github.com/HeyPuter/puter/commit/65e6d6c09fd464b3fea979689fab5f26a2647c4a))
- potential null-or-undefined in DriverService ([01725ff](https://github.com/HeyPuter/puter/commit/01725ffebf86ed332087c877956e59570ea700ed))
- usage bug ([0fd3b1e](https://github.com/HeyPuter/puter/commit/0fd3b1e61157d989d55e6dacba2add0e03d260e7))
- update share email ([7e7234b](https://github.com/HeyPuter/puter/commit/7e7234b2f3fb89560108447cfd7fa87499ec6f38))
- allow scrolling of user list in share window ([905b5d8](https://github.com/HeyPuter/puter/commit/905b5d851ef68d923d8f7fbaddbe214cb812bae6))
- mobile detection ([b11016d](https://github.com/HeyPuter/puter/commit/b11016dab321717f2c367e985167a4689fc02814))
- mobile-friendly taskbar ([7a7c14f](https://github.com/HeyPuter/puter/commit/7a7c14fb040b28ef769abdba41b50d88c856fb20))
- prevent permission cycles ([e0128aa](https://github.com/HeyPuter/puter/commit/e0128aa88c54548304532282e5ed1b4a2d36ff3e))
- `launchApp` on explorer supports `~` now ([e482b00](https://github.com/HeyPuter/puter/commit/e482b00a303ca7ec0230be1924334d59adc00f8e))
- only allow UserActorType for ShareService ([69bfa60](https://github.com/HeyPuter/puter/commit/69bfa601993eb6c47c3555b92559878d76ba749e))
- new sessions miss notifications ([b1ffb8e](https://github.com/HeyPuter/puter/commit/b1ffb8eca13520fa41833f5361ff6a6505a80a2c))
- don't allow sharing with recipient just shared with ([d0f16c8](https://github.com/HeyPuter/puter/commit/d0f16c810509c7e4e8acba3408c71655664cfad2))
- add username to comments ([085d808](https://github.com/HeyPuter/puter/commit/085d808817e985f2bc52b7a91a31991ca3b2e89f))
- occasional db error from notics ([9e303a2](https://github.com/HeyPuter/puter/commit/9e303a2f7c7bf6ac9032e6c9b87bffd3126baa86))
- un-awked notif check in wrong place ([3f3f4e6](https://github.com/HeyPuter/puter/commit/3f3f4e6cb9fd3faad2e87fbf9ea1f09b934151ca))
- disabled sortable on sharing section in the sidebar ([9d7987f](https://github.com/HeyPuter/puter/commit/9d7987fae50b510f1836e306d5f6f497a560de08))
- add mixxing context to BroadcastService ([665471f](https://github.com/HeyPuter/puter/commit/665471f9f02b1f1163edb47932a31f52577ee7df))
- attempt at fixing broadcast ([22dd42e](https://github.com/HeyPuter/puter/commit/22dd42ef7f64d32ada0c776287f53a80a4470315))
- replace ll_readshares with better approach ([cd22425](https://github.com/HeyPuter/puter/commit/cd22425a3d363f6008b3d07f40a082769ee22a14))
- only add enabled_logs when not empty ([34836e3](https://github.com/HeyPuter/puter/commit/34836e374fccac297a6f0fa5f323f3609d0c9179))
- don't check share permission anymore ([249dc06](https://github.com/HeyPuter/puter/commit/249dc062014947c32bee8a8238b2c8acf86188bb))
- files shared array in notification ([27cc07e](https://github.com/HeyPuter/puter/commit/27cc07e985a799fae791d6edf61b7e656e0e182e))
- report path for broken files as /-void/ ([5725bd8](https://github.com/HeyPuter/puter/commit/5725bd8c66539564e7f58f96c6e81044a3751f97))
- issue with popover closing when clicked ([ac3317a](https://github.com/HeyPuter/puter/commit/ac3317aea918953358947638ca11822baa38e23f))
- groups manager location ([a08e975](https://github.com/HeyPuter/puter/commit/a08e9758fe7625d31279b8947a4e5ca6471578ff))
- don't show kvstore in usages ([402ffb0](https://github.com/HeyPuter/puter/commit/402ffb0fd1e812a8db8ea90ac53ed613fdd30a4b))
- add missing id for task_manager menu item ([4f9d9a5](https://github.com/HeyPuter/puter/commit/4f9d9a54efb3c5177125904a1c9ddec66ca089dc))
- Update security.txt canonical URL ([6c44032](https://github.com/HeyPuter/puter/commit/6c44032293836871a27fb3c857a0ff3b80462702))
- update apps cache by reading from primary db ([e8f67da](https://github.com/HeyPuter/puter/commit/e8f67da9a3d81273f59d136c8383f00d9dc8ca5a))
- logging in AppConnection ([5caa2c0](https://github.com/HeyPuter/puter/commit/5caa2c0e3a152d1fc947b86329778db462139db0))
- persist clock visibility change ([1a6d648](https://github.com/HeyPuter/puter/commit/1a6d648a6ecdda07b23da9e6f4ef49b70b54cce1))
- don't access `metadata.credentialless` if it doesn't exist ([9590bbd](https://github.com/HeyPuter/puter/commit/9590bbdad1099cf75d6073663a9fcec5f3136482))
- reinitialize settings tabs for DOM events ([16b9f09](https://github.com/HeyPuter/puter/commit/16b9f09e66ffe1584f925cb1a9f261bc159c8dda))
- use correct cursor when hovering over sidebar items ([c44b9ab](https://github.com/HeyPuter/puter/commit/c44b9ab8d5f575393bf864fd30235287f845a4e8))
- issue with context menu divider item stealing the event from previous item ([121043d](https://github.com/HeyPuter/puter/commit/121043d312577a6e048497108309cd08b73df4d0))
- issue with non-scrollable window body and document Context Menu ([0315cb3](https://github.com/HeyPuter/puter/commit/0315cb333719b08c6581b556c69a14cbe671b7bd))
- temporary fix because .on can't call ensure_service ([f836ac3](https://github.com/HeyPuter/puter/commit/f836ac30a901a7b3258399a54eab5c7c8cc47463))
- issues in kdmod ([0a47daa](https://github.com/HeyPuter/puter/commit/0a47daa2896d97c318aec2e2288f61ade5f4ea48))
- Collector bug on undefined body ([14f477a](https://github.com/HeyPuter/puter/commit/14f477a6330c9169145a7f8b2721d02e7517513b))
- hyphenize_confirm_code bug ([463c96c](https://github.com/HeyPuter/puter/commit/463c96c69a915ea75db66fd449e83a61ca036f6f))
- app close issue in phoenix ([38adb57](https://github.com/HeyPuter/puter/commit/38adb5741b241081dd3f30de2f9afdd708cc9fa5))
- reading JSON string from service_usage_monthly ([b30de5b](https://github.com/HeyPuter/puter/commit/b30de5bf786ae8f28f3248277c5b2df2f0e5ebf4))
- recently broke counting service sql ([7ba16d1](https://github.com/HeyPuter/puter/commit/7ba16d1c21d07e58cefebf967e5ca2b74502e841))
- ignore invalid entries from service_usage_monthly ([f108795](https://github.com/HeyPuter/puter/commit/f1087953b57297a1e066ea68563e8a273a1af4c0))
- service usage screen ([193da63](https://github.com/HeyPuter/puter/commit/193da633044f463ec1ed60eca4608761fc40b1d7))
- continue work on blocked_email_domains (2) ([4dc1e01](https://github.com/HeyPuter/puter/commit/4dc1e01682571f16a25eebb2e9c7918587ca89ae))
- continue work on blocked_email_domains ([515051d](https://github.com/HeyPuter/puter/commit/515051dabf9f2a145ae2d090f829df7188e9fd28))
- errors thrown by launch_app ([c22a69f](https://github.com/HeyPuter/puter/commit/c22a69ffb1809ad7959f8a8fe934052369b5d44f))
- notepad save issue ([bc51d4b](https://github.com/HeyPuter/puter/commit/bc51d4bd52b5d0a7bb4feddea7bb9d73e449f7d8))
- height 100% on flexer and step view ([c6bc42f](https://github.com/HeyPuter/puter/commit/c6bc42f551a46919b4b70a9ae3dfec85086b0233))
- wait no ([12e0cec](https://github.com/HeyPuter/puter/commit/12e0cecf02f4d906035a6f0059557416475db106))
- phoenix incorrect lookup order ([c8f913d](https://github.com/HeyPuter/puter/commit/c8f913d710454d0ab3da2147309b442a78965720))
- turns out we don't support `utm_source` I learn something new about Puter every day! ([99ce3bd](https://github.com/HeyPuter/puter/commit/99ce3bde199de729c4796a681c188c4a0da9165e))
- issue with service scripts that use TestView ([e0b9072](https://github.com/HeyPuter/puter/commit/e0b90721299fa3013f66c866ba637c52efe9df1d))
- 1954f8-related issue #2 ([143cfb5](https://github.com/HeyPuter/puter/commit/143cfb5654eca8b50fb7ff434f47db24d7bdf3aa))
- 1954f8-related issue ([f5865da](https://github.com/HeyPuter/puter/commit/f5865daede2b32682d0472926bc5db65c9ef37ab))
- small issue in Service.js ([3c5d2af](https://github.com/HeyPuter/puter/commit/3c5d2af8c8341ef78236ef38153ed0b4f20c5cac))
- prevent code from breaking just because it was bundled ([fb1216d](https://github.com/HeyPuter/puter/commit/fb1216d488bed8ee8d88c7c71e4a6f1054e3a01c))
- don't display all apps for extensionless files ([010282e](https://github.com/HeyPuter/puter/commit/010282edf299c2a39e53de7441b8850d0b8011b8))
- creating app shortcut in self-hosted ([38dcb60](https://github.com/HeyPuter/puter/commit/38dcb60d3f407dd185999d01d8e14355b47df0b8))
- disable thumbnails for AppData uploads ([37e7b6a](https://github.com/HeyPuter/puter/commit/37e7b6ad70f197db3be8712315446079caa23892))
- thumbnail service updates ([c2a9506](https://github.com/HeyPuter/puter/commit/c2a9506b4855f67d320eb479a67800098d73e8ec))
- remove redundant openai model fallback ([9db55fc](https://github.com/HeyPuter/puter/commit/9db55fc5f7a975ab301c88bbac493b7a5b1933bb))
- app pseudonym in wrong conditional block ([9985996](https://github.com/HeyPuter/puter/commit/99859966866ebce005f88e3a916c68dc04ba97bf))
- properly add owner object to fsentries ([04c05a5](https://github.com/HeyPuter/puter/commit/04c05a5bb8b73dda21093a2bf563f5cd6faaa356))
- add progress bar fix ([a70d0dd](https://github.com/HeyPuter/puter/commit/a70d0dd0881b0a07cea404fe13515a5e10321e3e))
- allow ETX to propagate to bash ([259877b](https://github.com/HeyPuter/puter/commit/259877b677a7bfc8e5b377c8852d687978c9bc24))
- error deleting entry from My Websites window ([fff8993](https://github.com/HeyPuter/puter/commit/fff89932002d67bf0f121532709c871263e33473))
- second half of connectToInstance ([4311b48](https://github.com/HeyPuter/puter/commit/4311b482fd629c6d1f65956eb711c8e890453179))
- error in process.handle_connection ([cb324cc](https://github.com/HeyPuter/puter/commit/cb324cc125285b5cd6a6b0cebf444a6cd873ded9))
- quick patch to avoid columnify error ([4396534](https://github.com/HeyPuter/puter/commit/439653458eab38e622cf215ae96b6af34d1db7d4))
- upsert subdomain check to insert only ([f2acd83](https://github.com/HeyPuter/puter/commit/f2acd83b72c388939233fd7145f2dcf78d8ad39e))
- simplify callback listener and fix async bug ([db3e0b5](https://github.com/HeyPuter/puter/commit/db3e0b5ce84e4b0b35550f380da97b5d6fcb394b))
- email change on account with unverified email ([33de981](https://github.com/HeyPuter/puter/commit/33de98107f6e3284acb180b1a44bb02ae082642f))
- html-webpack-plugin dev dep ([cc4ab1c](https://github.com/HeyPuter/puter/commit/cc4ab1cb36a002929f26a39f252a262fc1f1aab4))
- double-echo in phoenix ([6bdcae7](https://github.com/HeyPuter/puter/commit/6bdcae769d311b5deb82136d5e35d7ad986bca28))
- webpack error reporting + unintentional whitespace changes ([4910838](https://github.com/HeyPuter/puter/commit/4910838ab1a72738b44f948cbf65feea848e5271))
- dist ([ed7d6dc](https://github.com/HeyPuter/puter/commit/ed7d6dcbfbf432ae90d9e379dbf47de5587a57a2))
- use jq el for focus ([d350264](https://github.com/HeyPuter/puter/commit/d35026467eb9a5f67d6ec0c99f2a24d418b8e3a5))
- fix sourcemap ([cd39bb5](https://github.com/HeyPuter/puter/commit/cd39bb5aa073286baa053f8458f0af54a4b7313a))
- remove now-redundant loadScript call ([c9d09a7](https://github.com/HeyPuter/puter/commit/c9d09a78b6f4bc9682d13d2f982f9a2b7f77dd66))
- env for dev build ([46a0f71](https://github.com/HeyPuter/puter/commit/46a0f714d10c2fa99ee9436f453176d54cc161f8))
- mistakes ([3092300](https://github.com/HeyPuter/puter/commit/3092300a0144791b25816b39845a3d85968e9059))
- add env to EmitPlugin config ([4b89101](https://github.com/HeyPuter/puter/commit/4b8910169a26f85489135cd84b27fe8f91b37bc6))
- remove accidentally left-over code ([72946f9](https://github.com/HeyPuter/puter/commit/72946f920c9f27f4c9de3156aa9144d290699222))
- don't var when no var ([5f7d1f5](https://github.com/HeyPuter/puter/commit/5f7d1f589a56b3d3ea2026dcbd5f9c48b8dc9e6d))
- fallback to read access in /sign ([813ee95](https://github.com/HeyPuter/puter/commit/813ee95cee6f1fca79a886b12d8fe4603ca0d213))
- typo in a default file ([aa61c30](https://github.com/HeyPuter/puter/commit/aa61c3009c624099e7bd518870b18b02c008530c))
- fix 500 when check-app has bad url ([9a62200](https://github.com/HeyPuter/puter/commit/9a622004ea488783127abd83f3f4caf779a5aabb))
- ll_write ([a7cdb70](https://github.com/HeyPuter/puter/commit/a7cdb70251ae86f883257de3596838d20196c62d))
- don't try to sanitize null owners ([cb4cab5](https://github.com/HeyPuter/puter/commit/cb4cab529affa5c28ddb32b90328ad47f21de8d4))
- missing key for feature flag perm check ([1482048](https://github.com/HeyPuter/puter/commit/14820481b9700a5c61c6d9a156944f42f9879008))
- implicit app permissions bug ([6b4a19e](https://github.com/HeyPuter/puter/commit/6b4a19e12a115be2c0e323d17340ab2ce2b6b025))
- share services and features with apps ([48fea77](https://github.com/HeyPuter/puter/commit/48fea77a20a0938fc2272483c798b817ca1c9848))
- admin user public folder ([3819584](https://github.com/HeyPuter/puter/commit/3819584d119076658c9d4be2b2b941c58d122ad4))
- add anti-csrf token for /revoke-session ([b6b64d3](https://github.com/HeyPuter/puter/commit/b6b64d3bccb6e17240a245c956ead2ae5a87c8dd))
- only show 2fa when available ([9fa12d4](https://github.com/HeyPuter/puter/commit/9fa12d43fc782d7e4d2584b1cf74dca13b7ced25))
- requirement for email_confirmed in backend ([6e325fa](https://github.com/HeyPuter/puter/commit/6e325fa000f19b8f20d79829ab2bd78edce80425))
- do primary read of user after setting email_confirmed ([ef245b7](https://github.com/HeyPuter/puter/commit/ef245b70df482ff470877459fcb28e1f490fe42d))
- require confirmed email for public folder ([0519b4a](https://github.com/HeyPuter/puter/commit/0519b4a71b236e464c9d1136065e8f5ba15def8e))
- sqlite condition in MonthlyUsageService ([d4319ea](https://github.com/HeyPuter/puter/commit/d4319ea072e0793a32dbddb1d456227cf481e42c))
- add context to event listener aiife ([3f07ead](https://github.com/HeyPuter/puter/commit/3f07ead1b9940ee133c142f4c34d19884bbb3cd2))
- missing method in SLink ([5b74b4a](https://github.com/HeyPuter/puter/commit/5b74b4affae5473029e887542717c76c7b32f562))
- disable unconfigured ai services ([476acae](https://github.com/HeyPuter/puter/commit/476acae0e0d07c7b025cdbcfd86aacfedd7831a5))
- add missing driver parameter to /call endpoint ([b520783](https://github.com/HeyPuter/puter/commit/b520783bf4a543c71eaef73277f42d5918ac4469))
- sqlite migrations error ([d0e461e](https://github.com/HeyPuter/puter/commit/d0e461e206300e7fe3f9bc7f54eaa3a25bb762d8))
- prevent large logs from service events (2) ([e514dfc](https://github.com/HeyPuter/puter/commit/e514dfcf5049771af3901334e37b1a7c53e05452))
- prevent large logs from service events (1) ([fa9cc8e](https://github.com/HeyPuter/puter/commit/fa9cc8efcfda5e573c73841ae49c423879e5fcd8))
- 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))
- 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

- verify dest_node uid matches signature ([e208b99](https://github.com/HeyPuter/puter/commit/e208b99d211e98cd88e0a8b2917bbe6b2f2423a0))
- always use actor ([1954f86](https://github.com/HeyPuter/puter/commit/1954f86680be642e1af03f648d6b587fe67dfaa8))
- signing in public folders ([937528f](https://github.com/HeyPuter/puter/commit/937528f7676e8ace7287141e1f5057842a2b5eb7))
- remove unconfirmed_email from /whoami for apps ([a002ad0](https://github.com/HeyPuter/puter/commit/a002ad08e5622a349b5d24ed2c7c5f61215146b8))
- hoist acl check in ll_read ([6a2fbc1](https://github.com/HeyPuter/puter/commit/6a2fbc1925952ecceed741afe138270d1eeda7b7))
### Backend


#### Features

- add comments for fsentries ([db79a72](https://github.com/HeyPuter/puter/commit/db79a72daab5460bc8e24f6e16c6280291b2f6fe))
### AI


#### Features

- add xAI grok-beta ([28adcf5](https://github.com/HeyPuter/puter/commit/28adcf533fd867dfdf3bda0007753e65c91ff5e5))
- add groq ([53e7a91](https://github.com/HeyPuter/puter/commit/53e7a91f1800b60b48575a6e41d96d2ccbd6d362))
- add mistral ([055c628](https://github.com/HeyPuter/puter/commit/055c628afd2e33589d3dc66c52934505143eafd4))
- add togetherai ([bdfdf23](https://github.com/HeyPuter/puter/commit/bdfdf2331b37680b95ac56b31026d3bdab4c173b))
- add claude ([d009cd0](https://github.com/HeyPuter/puter/commit/d009cd0aaff645a24d37085ed41c55fe296a5722))
- add streaming ([9d5963c](https://github.com/HeyPuter/puter/commit/9d5963cdf5fe63a4f7970d2d03bc307f4d4fa3ab))

#### Bug Fixes

- close streams ([eb18550](https://github.com/HeyPuter/puter/commit/eb18550f411947a0d8ccaf283701596b1386cfe6))
- adapt message role for claude ([c08b897](https://github.com/HeyPuter/puter/commit/c08b897d4a6a77c54a7e8d2e705e2048ab4797ba))
### GUI

### Putility


#### Features

- trait method override support ([43c5402](https://github.com/HeyPuter/puter/commit/43c5402b7cb92e604cbe59badc8f735131d2c349))
### Docker


#### Bug Fixes

- ensure temp admin pass shows ([d2c7477](https://github.com/HeyPuter/puter/commit/d2c7477b3bf170be492a6d5387330645cdf9c33a))
### Puter JS


#### Features

- add drivers module ([439f52b](https://github.com/HeyPuter/puter/commit/439f52b5a3f1a94e6d15ddacc315ae797f4709c2))

#### Bug Fixes

- fix settings object check ([5a616f6](https://github.com/HeyPuter/puter/commit/5a616f67dd22a0dcbb8a380bbbd2347a0029ce31))
### API


#### Features

- add /lsmod ([32f0edb](https://github.com/HeyPuter/puter/commit/32f0edb93a8fb0c33b0614b99c7fc439c8f6afc9))



## 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))


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Puter

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.

<br>

# Report bugs

Before reporting a bug, please check [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.

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:

- 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, ...

Please open a separate issue for each bug you find.

Maintainers will apply the appropriate labels to your issue.

<br>

# Suggest new features

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.

When suggesting a new feature, please include as much information as possible, including:

- 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

<br>

# Contribute code

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).

We'll review your pull request and work with you to get your changes merged into the project.

<br>

## PR Standards

We expect the following from pull requests (it makes things easier):
- If you're closing an issue, please reference that issue in the PR description
- Avoid whitespace changes
- No regressions for "appspace" (Puter apps)

<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:support@puter.com)


================================================
FILE: Dockerfile
================================================
# /!\ NOTICE /!\

# 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-alpine AS build

# Install build dependencies
RUN apk add --no-cache git python3 make g++ \
    && ln -sf /usr/bin/python3 /usr/bin/python

# Set up working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package.json package-lock.json ./

# Fail early if lockfile or manifest is missing
RUN test -f package.json && test -f package-lock.json

# Copy the source files
COPY . .

# Install mocha
RUN npm i -g npm@latest
RUN npm install -g mocha

# 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 \
            LOG_DIR="$(npm config get cache | tr -d '\"')/_logs"; \
            echo "npm install failed; dumping logs from $LOG_DIR"; \
            if [ -d "$LOG_DIR" ]; then \
                ls -al "$LOG_DIR" || true; \
                cat "$LOG_DIR"/* || true; \
            else \
                echo "Log directory not found (npm cache: $(npm config get cache))"; \
            fi; \
            exit 1; \
        fi; \
    done

# Run the build command if necessary
RUN cd src/gui && npm run build && cd -

# Production stage
FROM node:24-alpine

# 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"

# Install git (required by Puter to check version)
RUN apk add --no-cache git

# 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

EXPOSE 4100

HEALTHCHECK --interval=30s --timeout=3s \
    CMD wget --no-verbose --tries=1 --spider http://puter.localhost:4100/test || exit 1

ENV NO_VAR_RUNTUME=1

# Attempt to fix `lru-cache@11.0.2` missing after build stage
# by doing a redundant `npm install` at this stage
RUN npm install

CMD ["npm", "start"]


================================================
FILE: LICENSE.txt
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.

================================================
FILE: README.md
================================================
<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">
    <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://puter.com/app/app-center">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 is an advanced, open-source internet operating system designed to be feature-rich, 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

### to install npm and node 

[install](install.md)

### 💻 Local Development

```bash
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
```
**→** This should launch Puter at 
<font color="red"> http://puter.localhost:4100 (or the next available port). </font>



If this does not work, see [First Run Issues](./doc/self-hosters/first-run-issues.md) for
troubleshooting steps.

<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
```
**→** This should launch Puter at 
<font color="red"> http://puter.localhost:4100 (or the next available port). </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
```
**→** This should be available at 
<font color="red"> http://puter.localhost:4100 (or the next available port). </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
```
**→** This should launch Puter at 
<font color="red"> http://puter.localhost:4100 (or the next available port). </font>

<br/>

### 🚀 Self-Hosting

For detailed guides on self-hosting Puter, including configuration options and best practices, see our [Self-Hosting Documentation](https://github.com/HeyPuter/puter/blob/main/doc/self-hosters/instructions.md).

<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 24+
- **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? [security@puter.com](mailto:security@puter.com)
- Email maintainers at [hi@puter.com](mailto:hi@puter.com)

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/>

## 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)
- [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)
- [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)


================================================
FILE: SECURITY-ACKNOWLEDGEMENTS.md
================================================
We would like to thank the following security researchers for their responsible disclosures:


# 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](tim@blackfortresslabs.com) | [Website](https://www.blackfortresslabs.com)
- xyzeva: [Github](https://github.com/xyzeva) | [Email](mailto:xyzeva@riseup.net) | [Website](https://kibty.town/)
- Yusuf Kelany: [GitHub](https://github.com/YusufYaser) | [X](https://x.com/RealYusufYaser) | [Website](https://yusufyaser.xyz)


================================================
FILE: SECURITY.md
================================================
# Puter Security Policy

Thank you for helping make Puter safe. Keeping user information safe and secure is a top priority, and we welcome the contribution of external security researchers.

<br>

# Scope

If you believe you've found a security issue in software that is maintained in this repository, we encourage you to notify us.

<br>

# How to Submit a Report

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.

> [!WARNING]  
> Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.

<br>

# Safe Harbor

We support safe harbor for security researchers who:

* Make a good faith effort to avoid privacy violations, destruction of data, and interruption or degradation of our services.
* Only interact with accounts you own or with explicit permission of the account holder. If you do encounter Personally Identifiable Information (PII) contact us immediately, do not proceed with access, and immediately purge any local information.
* Provide us with a reasonable amount of time to resolve vulnerabilities prior to any disclosure to the public or a third-party.

We will consider activities conducted consistent with this policy to constitute "authorized" conduct and will not pursue civil action or initiate a complaint to law enforcement. We will help to the extent we can if legal action is initiated by a third party against you.

Please submit a report to us before engaging in conduct that may be inconsistent with or unaddressed by this policy.

<br>

# Preferences

* 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.


================================================
FILE: TRADEMARK.md
================================================
# 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.

================================================
FILE: doc/AI.md
================================================
# Documentation for Robots

Hello, if you're an AI agent then you're reading the correct documentation.
Here are a few important notes:
- Puter is probably already cloned and configured, so avoid any setup
  or configuration steps unless explicitly asked to perform them.
- Anything under `/src` (relative to the root of the repo) is probably
  a workspace module. That means different directories might have different
  code styles or use different import mechanisms (ESM vs CJS). Try to keep
  changes consistent in the scope of where they are.
  
# Backend

Any file under `src/backend` that extends **BaseService** is called a
"backend service". Backend services can implement "traits". That looks
like this:

```javascript
class SomeClass extends BaseService {
  static IMPLEMENTS = {
    ['name-of-interface']: {
      async some_method_name () {
        const instance_of_SomeClass = this;
      }
    }
  }
}
```

Methods on traits are bound to the same "this" (instance variable) as
methods on the class itself. Trait methods cannot be indexed from the
instance variable; instead common functionality is usually moved to
regular instance methods which typically have an underscore at the end
of their name.

# Furher Documentation
  
Proceed to read the README.md document beside this file.


================================================
FILE: doc/File Structure.drawio
================================================
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" version="25.0.1">
  <diagram name="Page-1" id="5LlmtnmR4draSSsTtYyD">
    <mxGraphModel grid="1" page="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" pageScale="1" pageWidth="1100" pageHeight="850" math="0" shadow="0">
      <root>
        <mxCell id="0" />
        <mxCell id="1" parent="0" />
        <mxCell id="skmebJAFKBwesmhEX21R-64" value="Legacy Notice" style="rounded=1;whiteSpace=wrap;html=1;align=left;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=14;" vertex="1" parent="1">
          <mxGeometry x="540" y="555" width="130" height="20" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-8" value="only most important directories shown" style="rounded=1;whiteSpace=wrap;html=1;align=right;" vertex="1" parent="1">
          <mxGeometry x="380" y="50" width="230" height="20" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-1" value="src/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="360" y="110" width="80" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-2" value="Puter Repository" style="rounded=0;whiteSpace=wrap;html=1;fontSize=18;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
          <mxGeometry x="240" y="40" width="160" height="40" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-4" value="Every directory under src/ is a node module." style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;size=14;align=left;" vertex="1" parent="1">
          <mxGeometry x="470" y="110" width="260" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-5" value="" style="endArrow=classic;html=1;rounded=0;edgeStyle=elbowEdgeStyle;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-2" target="skmebJAFKBwesmhEX21R-1">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="490" y="260" as="sourcePoint" />
            <mxPoint x="540" y="210" as="targetPoint" />
            <Array as="points">
              <mxPoint x="320" y="125" />
            </Array>
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-6" value="backend/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="440" y="190" width="80" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-7" value="gui/src/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="440" y="1000" width="80" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-10" value="" style="endArrow=none;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-1" target="skmebJAFKBwesmhEX21R-4">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="490" y="260" as="sourcePoint" />
            <mxPoint x="540" y="210" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-12" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-1" target="skmebJAFKBwesmhEX21R-6">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="490" y="260" as="sourcePoint" />
            <mxPoint x="540" y="210" as="targetPoint" />
            <Array as="points">
              <mxPoint x="400" y="205" />
            </Array>
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-14" value="extensions/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="520" y="1080" width="140" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-15" value="Puter GUI Extensions" style="rounded=1;whiteSpace=wrap;html=1;fontSize=16;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
          <mxGeometry x="730" y="1080" width="180" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-16" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-14" target="skmebJAFKBwesmhEX21R-15">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="530" y="980" as="sourcePoint" />
            <mxPoint x="580" y="930" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-15" target="skmebJAFKBwesmhEX21R-15">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-18" value="UI/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="520" y="1120" width="140" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-19" value="Puter Desktop" style="rounded=1;whiteSpace=wrap;html=1;fontSize=16;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
          <mxGeometry x="730" y="1120" width="180" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-20" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-18" target="skmebJAFKBwesmhEX21R-19">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="670" y="1098" as="sourcePoint" />
            <mxPoint x="740" y="1098" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-21" value="services/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="520" y="1160" width="140" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-22" value="Frontend Services" style="rounded=1;whiteSpace=wrap;html=1;fontSize=16;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
          <mxGeometry x="730" y="1160" width="180" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-23" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-21" target="skmebJAFKBwesmhEX21R-22">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="670" y="1138" as="sourcePoint" />
            <mxPoint x="740" y="1138" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-24" value="initgui.js" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
          <mxGeometry x="520" y="1200" width="140" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-25" value="Launches services and initializes the GUI" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
          <mxGeometry x="730" y="1200" width="180" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-26" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-24" target="skmebJAFKBwesmhEX21R-25">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="670" y="1185" as="sourcePoint" />
            <mxPoint x="740" y="1185" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-27" value="IPC.js" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
          <mxGeometry x="520" y="1240" width="140" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-28" value="Manages communication between Desktop and apps" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
          <mxGeometry x="730" y="1240" width="180" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-29" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-27" target="skmebJAFKBwesmhEX21R-28">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="670" y="1225" as="sourcePoint" />
            <mxPoint x="740" y="1225" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-46" value="modules/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="520" y="280" width="140" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-47" value="New Code goes Here" style="rounded=1;whiteSpace=wrap;html=1;fontSize=16;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
          <mxGeometry x="730" y="280" width="180" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-48" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-46" target="skmebJAFKBwesmhEX21R-47">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="530" y="180" as="sourcePoint" />
            <mxPoint x="580" y="130" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-49" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-47" target="skmebJAFKBwesmhEX21R-47">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-50" value="services/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="520" y="320" width="140" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-51" value="Core Module services" style="rounded=1;whiteSpace=wrap;html=1;fontSize=16;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
          <mxGeometry x="730" y="320" width="180" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-52" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-50" target="skmebJAFKBwesmhEX21R-51">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="670" y="298" as="sourcePoint" />
            <mxPoint x="740" y="298" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-53" value="routers/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="520" y="480" width="140" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-54" value="HTTP endpoints" style="rounded=1;whiteSpace=wrap;html=1;fontSize=16;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
          <mxGeometry x="730" y="480" width="180" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-55" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-53" target="skmebJAFKBwesmhEX21R-54">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="670" y="458" as="sourcePoint" />
            <mxPoint x="740" y="458" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-62" value="&lt;div&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;This is the original directory where routes&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;were placed. New services should use the&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;&quot;Endpoint&quot; class to define routes.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;Examples:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;- PermissionAPIService.js&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;- NotificationService.js&lt;/span&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;- KernelInfoService.js&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-wrap: nowrap;&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22extensions%2F%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D16%3BfillColor%3D%23e1d5e7%3BstrokeColor%3D%239673a6%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22520%22%20y%3D%22400%22%20width%3D%22140%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%223%22%20value%3D%22Puter%20GUI%20Extensions%22%20style%3D%22rounded%3D1%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D16%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22730%22%20y%3D%22400%22%20width%3D%22180%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%224%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20source%3D%222%22%20target%3D%223%22%20parent%3D%221%22%3E%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CmxPoint%20x%3D%22530%22%20y%3D%22300%22%20as%3D%22sourcePoint%22%2F%3E%3CmxPoint%20x%3D%22580%22%20y%3D%22250%22%20as%3D%22targetPoint%22%2F%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%225%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3BorthogonalLoop%3D1%3BjettySize%3Dauto%3Bhtml%3D1%3BexitX%3D0.5%3BexitY%3D1%3BexitDx%3D0%3BexitDy%3D0%3B%22%20edge%3D%221%22%20source%3D%223%22%20target%3D%223%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%226%22%20value%3D%22UI%2F%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D16%3BfillColor%3D%23e1d5e7%3BstrokeColor%3D%239673a6%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22520%22%20y%3D%22440%22%20width%3D%22140%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%227%22%20value%3D%22Puter%20Desktop%22%20style%3D%22rounded%3D1%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D16%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22730%22%20y%3D%22440%22%20width%3D%22180%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%228%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20source%3D%226%22%20target%3D%227%22%20parent%3D%221%22%3E%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CmxPoint%20x%3D%22670%22%20y%3D%22418%22%20as%3D%22sourcePoint%22%2F%3E%3CmxPoint%20x%3D%22740%22%20y%3D%22418%22%20as%3D%22targetPoint%22%2F%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%229%22%20value%3D%22services%2F%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D16%3BfillColor%3D%23e1d5e7%3BstrokeColor%3D%239673a6%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22520%22%20y%3D%22480%22%20width%3D%22140%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2210%22%20value%3D%22Frontend%20Services%22%20style%3D%22rounded%3D1%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D16%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22730%22%20y%3D%22480%22%20width%3D%22180%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2211%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20source%3D%229%22%20target%3D%2210%22%20parent%3D%221%22%3E%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CmxPoint%20x%3D%22670%22%20y%3D%22458%22%20as%3D%22sourcePoint%22%2F%3E%3CmxPoint%20x%3D%22740%22%20y%3D%22458%22%20as%3D%22targetPoint%22%2F%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2212%22%20value%3D%22initgui.js%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D16%3BfillColor%3D%23f8cecc%3BstrokeColor%3D%23b85450%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22520%22%20y%3D%22520%22%20width%3D%22140%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2213%22%20value%3D%22Launches%20services%20and%20initializes%20the%20GUI%22%20style%3D%22rounded%3D1%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D13%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22730%22%20y%3D%22520%22%20width%3D%22180%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2214%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20source%3D%2212%22%20target%3D%2213%22%20parent%3D%221%22%3E%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CmxPoint%20x%3D%22670%22%20y%3D%22505%22%20as%3D%22sourcePoint%22%2F%3E%3CmxPoint%20x%3D%22740%22%20y%3D%22505%22%20as%3D%22targetPoint%22%2F%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2215%22%20value%3D%22IPC.js%22%20style%3D%22rounded%3D0%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D16%3BfillColor%3D%23f8cecc%3BstrokeColor%3D%23b85450%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22520%22%20y%3D%22560%22%20width%3D%22140%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2216%22%20value%3D%22Manages%20communication%20between%20Desktop%20and%20apps%22%20style%3D%22rounded%3D1%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontSize%3D13%3BfillColor%3D%23d5e8d4%3BstrokeColor%3D%2382b366%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22730%22%20y%3D%22560%22%20width%3D%22180%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2217%22%20value%3D%22%22%20style%3D%22endArrow%3Dclassic%3Bhtml%3D1%3Brounded%3D0%3B%22%20edge%3D%221%22%20source%3D%2215%22%20target%3D%2216%22%20parent%3D%221%22%3E%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%3CmxPoint%20x%3D%22670%22%20y%3D%22545%22%20as%3D%22sourcePoint%22%2F%3E%3CmxPoint%20x%3D%22740%22%20y%3D%22545%22%20as%3D%22targetPoint%22%2F%3E%3C%2FmxGeometry%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphMode&lt;/span&gt;&lt;br&gt;&lt;/div&gt;" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;size=18;fillColor=#fff2cc;strokeColor=#d6b656;align=left;verticalAlign=top;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="645" y="545" width="270" height="135" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-63" value="" style="endArrow=classic;html=1;rounded=0;edgeStyle=elbowEdgeStyle;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-62" target="skmebJAFKBwesmhEX21R-54">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="730" y="560" as="sourcePoint" />
            <mxPoint x="780" y="510" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-65" value="structured/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="520" y="700" width="140" height="20" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-66" value="unstructured/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="520" y="720" width="140" height="20" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-68" value="&lt;div&gt;These directories mostly contain code for&lt;/div&gt;&lt;div&gt;the permission system to make it easier to maintain.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;structured/&amp;lt;pattern&amp;gt;/ contains code that is formatted according to &quot;&amp;lt;pattern&amp;gt;&quot;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;unstructured/ contains miscellaneous code used by the permission system.&lt;/div&gt;" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;size=18;fillColor=#f5f5f5;strokeColor=#666666;align=left;verticalAlign=top;fontSize=13;fontColor=#333333;" vertex="1" parent="1">
          <mxGeometry x="730" y="700" width="270" height="150" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-69" value="" style="endArrow=classic;html=1;rounded=0;edgeStyle=elbowEdgeStyle;elbow=vertical;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-68" target="skmebJAFKBwesmhEX21R-65">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="730" y="680" as="sourcePoint" />
            <mxPoint x="780" y="630" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-70" value="" style="endArrow=classic;html=1;rounded=0;edgeStyle=elbowEdgeStyle;elbow=vertical;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-68" target="skmebJAFKBwesmhEX21R-66">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="740" y="720" as="sourcePoint" />
            <mxPoint x="670" y="720" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-71" value="these should go to:&lt;div&gt;modules/auth/&lt;/div&gt;&lt;div&gt;in the future&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
          <mxGeometry x="520" y="760" width="140" height="50" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-72" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-71" target="skmebJAFKBwesmhEX21R-66">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="730" y="680" as="sourcePoint" />
            <mxPoint x="780" y="630" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-73" value="util/" style="rounded=0;whiteSpace=wrap;html=1;fontSize=16;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
          <mxGeometry x="520" y="880" width="140" height="30" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-74" value="&lt;div&gt;Utilities used by various services in Puter&#39;s backend.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;These should be incrementally moved to individual `lib` directories in modules/&lt;/div&gt;" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;size=18;fillColor=#f5f5f5;strokeColor=#666666;align=left;verticalAlign=top;fontSize=13;fontColor=#333333;" vertex="1" parent="1">
          <mxGeometry x="730" y="880" width="270" height="90" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-75" value="" style="endArrow=classic;html=1;rounded=0;edgeStyle=elbowEdgeStyle;elbow=vertical;" edge="1" parent="1" source="skmebJAFKBwesmhEX21R-74" target="skmebJAFKBwesmhEX21R-73">
          <mxGeometry width="50" height="50" relative="1" as="geometry">
            <mxPoint x="740" y="740" as="sourcePoint" />
            <mxPoint x="670" y="740" as="targetPoint" />
          </mxGeometry>
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-76" value="Migration Notice" style="rounded=1;whiteSpace=wrap;html=1;align=left;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=14;" vertex="1" parent="1">
          <mxGeometry x="540" y="400" width="130" height="20" as="geometry" />
        </mxCell>
        <mxCell id="skmebJAFKBwesmhEX21R-77" value="&lt;div&gt;Services here should be incrementally&lt;/div&gt;&lt;div&gt;migrated into the modules/ directory.&lt;/div&gt;" style="shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;size=18;fillColor=#fff2cc;strokeColor=#d6b656;align=left;verticalAlign=top;fontSize=13;" vertex="1" parent="1">
          <mxGeometry x="650" y="390" width="270" height="50" as="geometry" />
        </mxCell>
      </root>
    </mxGraphModel>
  </diagram>
</mxfile>


================================================
FILE: doc/README.md
================================================
# Puter Documentation

Hi, you've found Puter's wiki page on GitHub! If you were looking for
something else, you might find it in the links below.
All of the wiki docs are generated from `doc/` directories in the main
repository, so it's best to edit docs there rather than here.

## Users

If you have general questions about using [Puter](https://puter.com),
our [community Discord](https://discord.gg/PQcx7Teh8u) and
[subreddit](https://www.reddit.com/r/puter/) are good places
to ask questions.

## Deployers

- [Hosting Instructions](./self-hosters/instructions.md)
- [Configuration](./self-hosters/config.md)
- [Domain Setup](./self-hosters/domains.md)
- [Support Levels](./self-hosters/support.md)

## App Developer Links
- [developer.puter.com](https://developer.puter.com)
- [docs.puter.com](https://docs.puter.com)
- share your apps on [Reddit](https://www.reddit.com/r/puter/) or
  [Discord](https://discord.gg/PQcx7Teh8u)

## Contributor Documentation

### Where to Start

Start with [Repo Structure and Tooling](./contributors/structure.md).

### Index

- **Conventions**
  - [Repo Structure and Tooling](./contributors/structure.md)
    - How directories and files are organized in our GitHub repo
    - What tools are used to build parts of Puter
  - [Comment Prefixes](./contributors/comment_prefixes.md)
    - A convention we use for line comments in code

- [Frontend Documentation](/src/gui/doc)
- [Backend Documentation](/src/backend/doc)
- [Extensions](./contributors/extensions/)


================================================
FILE: doc/RFCS/20250826_captcha_cloudflare_turnstile.md
================================================
- Feature Name: Cloudflare Turnstile CAPTCHA
- Status: Completed
- Created: 2025-08-26

## Summary

We propose integrating **Cloudflare Turnstile** to protect our signup flow against automated bot activity, while maintaining a seamless experience for legitimate users.

## Motivation

Puter allocates resources to **free** user account — including storage, compute, and AI credits. To prevent these from being exploited by bots, we need a more robust verification mechanism. Although Puter currently includes a [custom CAPTCHA service](https://github.com/HeyPuter/puter/blob/4c3a68ee51a1b255edbe6b3c7e4c4e3b0394dae3/src/backend/src/modules/captcha/services/CaptchaService.js), it has several shortcomings:

* The text-recognition CAPTCHA creates friction and disrupts the user experience.
* Maintaining a token pool is resource-intensive and doesn’t scale well. The validation logic also requires ongoing maintenance within the codebase.

## Choose of Service Provider

We choose Cloudflare Turnstile since:

* It's free for unlimited use.
* It's easy to integrate.
* It's relative secure.

Here's a comparison of major CAPTCHA providers:


| Provider                                                  | Security (typical)                                                              | User experience (typical)                                                               | Price (publicly listed)                                                                                                                                                                                                                          |
| ----------------------------------------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Cloudflare Turnstile**                                  | **High** for most sites; adaptive challenges; works without image puzzles.      | **Excellent** (can be fully invisible or auto-verify; checkbox only for risky traffic). | **Free for everyone (unlimited use)**. ([The Cloudflare Blog](https://blog.cloudflare.com/turnstile-ga/?utm_source=chatgpt.com), [cloudflare.com](https://www.cloudflare.com/application-services/products/turnstile/?utm_source=chatgpt.com)) |
| **Google reCAPTCHA (Essentials / Standard / Enterprise)** | **Medium–High** (v3 score + server rules; Enterprise adds features & support). | **Good–OK** (v3 is invisible; v2 can show puzzles).                                    | **Free up to 10k assessments/mo; \$8 for up to 100k/mo; then \$1 per 1k** (Enterprise tiers). ([Google Cloud](https://cloud.google.com/recaptcha/docs/compare-tiers?utm_source=chatgpt.com))                                                    |
| **hCaptcha (Basic / Pro / Enterprise)**                   | **High** (ML signals; enterprise options).                                      | **Good** on Basic; **Very good** on Pro with “low-friction 99.9% passive mode.”       | **Basic: Free. Pro: \$99/mo annual (\$139 month-to-month) incl. 100k evals, then \$0.99/1k**; Enterprise custom. ([hcaptcha.com](https://www.hcaptcha.com/pricing?utm_source=chatgpt.com))                                                      |
| **Friendly Captcha**                                      | **Medium–High** (proof-of-work + risk signals).                                | **Excellent** (invisible/automatic challenge; no image tasks).                          | **Starter €9/mo (1k req/mo); Growth €39/mo (5k/mo); Advanced €200/mo (50k/mo); Free non-commercial 1k/mo**; Enterprise custom. ([Friendly Captcha](https://friendlycaptcha.com/))                                                            |
| **Arkose Labs (FunCaptcha / MatchKey)**                   | **Very High** (step-up, anti-farm, enterprise focus).                           | **Good–OK** (challenge can be more involved when risk is high).                        | **Enterprise pricing (contact sales)**; publicly not listed. (Product overview only.) ([Arkose Labs](https://www.arkoselabs.com/arkose-matchkey/?utm_source=chatgpt.com))                                                                       |

## Implementation

### Signup Flow

When a user submits the signup form, the client will include a **Turnstile token** alongside the other form data.
On the backend, Puter will call the **Cloudflare Turnstile verification API** to validate this token before provisioning a new account.

Only if the token is verified as valid will the signup request be processed. Invalid or missing tokens will result in a rejected signup attempt.

## Setup

1. Create a new *Widget* on the Cloudflare Turnstile dashboard.
2. Configure *Widget name* and *Hostnames*.
3. Set *Widget Mode* to **Managed** and *pre-clearance* to **Yes - Interactive**. These settings minimize friction for legitimate users while also giving suspicious users one more chance to clear the CAPTCHA. (See [Turnstile widgets · Cloudflare Turnstile docs](https://developers.cloudflare.com/turnstile/concepts/widget/) for details)
4. Add Site Key and Secret Key to the config file (default location: `volatile/config/config.json`):

    ```
    "cloudflare-turnstile": {
        "enabled": true,
        "site_key": "<your-site-key>",
        "secret_key": "<your-secret-key>"
    }
    ```


================================================
FILE: doc/api/README.md
================================================
# 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.


================================================
FILE: doc/api/concepts/share-link.md
================================================
# 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.


================================================
FILE: doc/api/drivers.md
================================================
## Puter Drivers

### **POST** `/drivers/call`

#### Notes

- **HTTP response status** -
  A successful driver response, even if the response is an error message, will always have HTTP status `200`. Note that sometimes this will include rate limit and usage limit errors as well.

This endpoint allows you to call a Puter driver. Whether or not the
driver call fails, this endpoint will respond with HTTP 200 OK.
When a driver call fails, you will get a JSON response from the driver
with 

#### Parameters

Parameters are provided in the request body. The content type of the
request should be `application/json`.

- **interface:** `string`
  - **description:** The type of driver to call. For example,
    LLMs use the interface called `puter-chat-completion`.
- **service:** `string`
  - **description:** The name of the service to use. For example, the `claude` service might be used for `puter-chat-completion`.
- **method:** `string`
  - **description:** The name of the method to call. For example, LLMs implement `complete` which does a chat completion, and `list` which lists models.
- **args:** `object`
  - **description:** Parametized arguments for the driver call. For example, `puter-chat-completion`'s `complete` method supports the arguments `messages` and `temperature` (and others), so you might set this to `{ "messages": [...], "temperature": 1.2 }`

#### Example
```json
{
    "interface": "<name of interface>",
    "service": "<name of service>",
    "method": "<name of method>",
    "args": { "parametized": "arguments" }
}
```

#### Response

- **Error Response** - Driver error responses will always have **status 200**, content type `application/json`, and a response body in this format:
  ```json
  {
    "success": false,
    "error": {
        "code": "string identifier for the error",
        "message": "some message about the error",
    }
  }
  ```
- **Success Response** - The success response is either a JSON response
  wrapped in `{ "success": true, "result": ___ }`, or a response with a
  `Content-Type` that is **not** `application/json`.
  ```json
  {
    "success": true,
    "result": {}
  }
  ```

================================================
FILE: doc/api/group.md
================================================
# 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
Download .txt
gitextract_iu1nqdoe/

├── .dockerignore
├── .env.example
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       ├── docker-image.yaml
│       ├── main.yml
│       ├── notify-prod.yaml
│       ├── release-please.yml
│       └── test.yml
├── .gitignore
├── .gitmodules
├── .husky/
│   └── pre-commit
├── .idx/
│   └── dev.nix
├── .is_puter_repository
├── .npmrc
├── .prettierignore
├── BUG-BOUNTY.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE.txt
├── README.md
├── SECURITY-ACKNOWLEDGEMENTS.md
├── SECURITY.md
├── TRADEMARK.md
├── doc/
│   ├── AI.md
│   ├── File Structure.drawio
│   ├── README.md
│   ├── RFCS/
│   │   └── 20250826_captcha_cloudflare_turnstile.md
│   ├── api/
│   │   ├── README.md
│   │   ├── concepts/
│   │   │   └── share-link.md
│   │   ├── drivers.md
│   │   ├── group.md
│   │   ├── notifications.md
│   │   ├── share.md
│   │   ├── type-tagged.md
│   │   └── types/
│   │       ├── app-share.md
│   │       └── file-share.md
│   ├── contributors/
│   │   ├── comment_prefixes.md
│   │   ├── email_testing.md
│   │   ├── extensions/
│   │   │   ├── README.md
│   │   │   ├── definitions.md
│   │   │   ├── dev-console.md
│   │   │   ├── events.json.js
│   │   │   ├── events.md
│   │   │   ├── gen.js
│   │   │   └── manual_overrides.json.js
│   │   ├── extensions.md
│   │   ├── structure.md
│   │   └── vscode.md
│   ├── devlog.md
│   ├── devmeta/
│   │   └── track-comments.md
│   ├── docmeta.md
│   ├── i18n/
│   │   ├── README.ar.md
│   │   ├── README.bn.md
│   │   ├── README.da.md
│   │   ├── README.de.md
│   │   ├── README.en.md
│   │   ├── README.es.md
│   │   ├── README.fa.md
│   │   ├── README.fi.md
│   │   ├── README.fr.md
│   │   ├── README.he.md
│   │   ├── README.hi.md
│   │   ├── README.hu.md
│   │   ├── README.hy.md
│   │   ├── README.id.md
│   │   ├── README.it.md
│   │   ├── README.jp.md
│   │   ├── README.ko.md
│   │   ├── README.ml.md
│   │   ├── README.my.md
│   │   ├── README.nl.md
│   │   ├── README.od.md
│   │   ├── README.pa.md
│   │   ├── README.pl.md
│   │   ├── README.pt.md
│   │   ├── README.ro.md
│   │   ├── README.ru.md
│   │   ├── README.sv.md
│   │   ├── README.ta.md
│   │   ├── README.te.md
│   │   ├── README.th.md
│   │   ├── README.tr.md
│   │   ├── README.ua.md
│   │   ├── README.ur.md
│   │   ├── README.vi.md
│   │   └── README.zh.md
│   ├── license_header.txt
│   ├── planning/
│   │   ├── 2025-10-21_puter-fs-extension.md
│   │   ├── alternatives-to-$.md
│   │   └── micro-modules.md
│   ├── prod.md
│   ├── self-hosters/
│   │   ├── config-vals.json.js
│   │   ├── config.md
│   │   ├── config_values.md
│   │   ├── domains.md
│   │   ├── first-run-issues.md
│   │   ├── gen.js
│   │   ├── instructions.md
│   │   └── support.md
│   ├── test/
│   │   └── playwright-test.md
│   ├── testing_with_email.md
│   └── uncategorized/
│       ├── README.md
│       ├── es6-note.md
│       └── puter-mods.md
├── docker-compose.yml
├── eslint/
│   ├── bang-space-if.js
│   ├── control-structure-spacing.js
│   ├── mandatory.eslint.config.js
│   └── space-unary-ops-with-exception.js
├── eslint.config.js
├── exports.js
├── extensions/
│   ├── .gitkeep
│   ├── README.md
│   ├── api.d.ts
│   ├── app-telemetry/
│   │   ├── app-user-count.ts
│   │   ├── index.d.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   ├── data.js
│   ├── example-kv.js
│   ├── example_gui_extension.js
│   ├── exports_something.js
│   ├── extension-util.js
│   ├── extensionController/
│   │   ├── package.json
│   │   ├── puter.json
│   │   ├── src/
│   │   │   ├── ExtensionController.ts
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── hellodriver/
│   │   ├── config.json
│   │   ├── hellodriver.js
│   │   └── package.json
│   ├── imports_something.js
│   ├── metering/
│   │   ├── config.json
│   │   ├── controllers/
│   │   │   └── UsageController.ts
│   │   ├── eventListeners/
│   │   │   └── subscriptionEvents.ts
│   │   ├── main.ts
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   └── types.ts
│   ├── puterfs/
│   │   ├── PuterFSProvider.js
│   │   ├── fsentries/
│   │   │   ├── BaseOperation.js
│   │   │   ├── Delete.js
│   │   │   ├── FSEntryController.js
│   │   │   ├── Insert.js
│   │   │   └── Update.js
│   │   ├── lib/
│   │   │   └── objectfn.js
│   │   ├── main.js
│   │   ├── package.json
│   │   └── storage/
│   │       ├── LocalDiskStorageController.js
│   │       └── ProxyStorageController.js
│   ├── serverInfo/
│   │   ├── config.json
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   └── types.ts
│   ├── tsconfig.json
│   ├── utilities.js
│   ├── whoami/
│   │   ├── main.js
│   │   ├── package.json
│   │   └── routes.js
│   └── worker-sandbox.js
├── install.md
├── mod_packages/
│   └── testex/
│       └── package.json
├── mods/
│   ├── README.md
│   ├── mods_available/
│   │   ├── dev-socket/
│   │   │   ├── main.js
│   │   │   └── package.json
│   │   ├── example/
│   │   │   ├── main.js
│   │   │   └── package.json
│   │   ├── example-singlefile.js
│   │   ├── kdmod/
│   │   │   ├── CustomPuterService.js
│   │   │   ├── README.md
│   │   │   ├── ShareTestService.js
│   │   │   ├── data/
│   │   │   │   └── sharetest_scenarios.js
│   │   │   ├── gui/
│   │   │   │   └── main.js
│   │   │   ├── module.js
│   │   │   └── package.json
│   │   ├── test-actions/
│   │   │   ├── main.js
│   │   │   └── package.json
│   │   └── testex.js
│   └── mods_enabled/
│       └── .gitignore
├── package.json
├── rust-toolchain.toml
├── scripts/
│   └── gen.sh
├── src/
│   ├── backend/
│   │   ├── .gitignore
│   │   ├── CONTRIBUTING.md
│   │   ├── README.md
│   │   ├── doc/
│   │   │   ├── A-and-A/
│   │   │   │   ├── auth.md
│   │   │   │   └── permission.md
│   │   │   ├── Kernel.md
│   │   │   ├── README.md
│   │   │   ├── contributors/
│   │   │   │   ├── boot-sequence.md
│   │   │   │   ├── coding-style.md
│   │   │   │   ├── modules.md
│   │   │   │   └── structure.md
│   │   │   ├── dev_socket.md
│   │   │   ├── extensions/
│   │   │   │   ├── README.md
│   │   │   │   ├── builtins/
│   │   │   │   │   └── data.md
│   │   │   │   └── pages/
│   │   │   │       ├── core-devs.md
│   │   │   │       ├── drivers.md
│   │   │   │       ├── import-and-export.md
│   │   │   │       └── runtime-modules.md
│   │   │   ├── features/
│   │   │   │   ├── batch-and-symlinks.md
│   │   │   │   ├── protected-apps.md
│   │   │   │   └── service-scripts.md
│   │   │   ├── howto_make_driver.md
│   │   │   ├── license_header.txt
│   │   │   ├── lists-of-things/
│   │   │   │   ├── list-of-permissions.md
│   │   │   │   └── list-of-tto-types.md
│   │   │   ├── log_config.md
│   │   │   ├── modules/
│   │   │   │   ├── filesystem/
│   │   │   │   │   └── API_SPEC.md
│   │   │   │   └── puterai/
│   │   │   │       └── README.md
│   │   │   ├── notes/
│   │   │   │   └── 2024-10-03_email_in_use_checks.md
│   │   │   └── services/
│   │   │       ├── config.md
│   │   │       ├── event_buses.md
│   │   │       ├── http.md
│   │   │       └── log.md
│   │   ├── exports.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── CoreModule.js
│   │   │   ├── DatabaseModule.js
│   │   │   ├── Extension.js
│   │   │   ├── ExtensionModule.js
│   │   │   ├── ExtensionService.js
│   │   │   ├── Kernel.js
│   │   │   ├── LocalDiskStorageModule.js
│   │   │   ├── MemoryStorageModule.js
│   │   │   ├── annotatedobjects.js
│   │   │   ├── api/
│   │   │   │   ├── APIError.js
│   │   │   │   ├── PathOrUIDValidator.js
│   │   │   │   ├── api_error_handler.js
│   │   │   │   ├── eggspress.js
│   │   │   │   └── filesystem/
│   │   │   │       ├── FSNodeParam.js
│   │   │   │       ├── FlagParam.js
│   │   │   │       ├── StringParam.js
│   │   │   │       └── UserParam.js
│   │   │   ├── boot/
│   │   │   │   ├── BootLogger.js
│   │   │   │   ├── RuntimeEnvironment.js
│   │   │   │   └── default_config.js
│   │   │   ├── clients/
│   │   │   │   ├── dynamodb/
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── DDBClient.ts
│   │   │   │   │   └── DDBClientWrapper.ts
│   │   │   │   └── redis/
│   │   │   │       ├── .gitignore
│   │   │   │       ├── cacheUpdate.ts
│   │   │   │       ├── deleteRedisKeys.ts
│   │   │   │       ├── redisSingleton.test.ts
│   │   │   │       └── redisSingleton.ts
│   │   │   ├── codex/
│   │   │   │   ├── CodeUtil.js
│   │   │   │   ├── README.md
│   │   │   │   └── Sequence.js
│   │   │   ├── config/
│   │   │   │   ├── ConfigLoader.js
│   │   │   │   ├── deep_proto_merge.js
│   │   │   │   └── reserved_words.js
│   │   │   ├── config.d.ts
│   │   │   ├── config.js
│   │   │   ├── consts/
│   │   │   │   └── app-icons.js
│   │   │   ├── data/
│   │   │   │   └── hardcoded-permissions.js
│   │   │   ├── definitions/
│   │   │   │   └── SimpleEntity.js
│   │   │   ├── entities/
│   │   │   │   └── Group.js
│   │   │   ├── env
│   │   │   ├── errors/
│   │   │   │   ├── TechnicalError.js
│   │   │   │   └── error_help_details.js
│   │   │   ├── extension/
│   │   │   │   ├── RuntimeModule.js
│   │   │   │   └── RuntimeModuleRegistry.js
│   │   │   ├── filesystem/
│   │   │   │   ├── ECMAP.js
│   │   │   │   ├── FSNodeContext.js
│   │   │   │   ├── FilesystemService.js
│   │   │   │   ├── batch/
│   │   │   │   │   ├── BatchExecutor.js
│   │   │   │   │   └── commands.js
│   │   │   │   ├── definitions/
│   │   │   │   │   ├── capabilities.js
│   │   │   │   │   ├── proto/
│   │   │   │   │   │   └── fsentry.proto
│   │   │   │   │   └── ts/
│   │   │   │   │       ├── fsentry.js
│   │   │   │   │       └── fsentry.ts
│   │   │   │   ├── hl_operations/
│   │   │   │   │   ├── definitions.js
│   │   │   │   │   ├── hl_copy.js
│   │   │   │   │   ├── hl_data_read.js
│   │   │   │   │   ├── hl_mkdir.js
│   │   │   │   │   ├── hl_mklink.js
│   │   │   │   │   ├── hl_mkshortcut.js
│   │   │   │   │   ├── hl_move.js
│   │   │   │   │   ├── hl_name_search.js
│   │   │   │   │   ├── hl_read.js
│   │   │   │   │   ├── hl_readdir.js
│   │   │   │   │   ├── hl_remove.js
│   │   │   │   │   ├── hl_stat.js
│   │   │   │   │   └── hl_write.js
│   │   │   │   ├── lib/
│   │   │   │   │   └── PuterPath.js
│   │   │   │   ├── ll_operations/
│   │   │   │   │   ├── definitions.js
│   │   │   │   │   ├── ll_copy.js
│   │   │   │   │   ├── ll_copy_idea.js
│   │   │   │   │   ├── ll_listusers.js
│   │   │   │   │   ├── ll_mkdir.js
│   │   │   │   │   ├── ll_move.js
│   │   │   │   │   ├── ll_read.js
│   │   │   │   │   ├── ll_readdir.js
│   │   │   │   │   ├── ll_readshares.js
│   │   │   │   │   ├── ll_rmdir.js
│   │   │   │   │   ├── ll_rmnode.js
│   │   │   │   │   └── ll_write.js
│   │   │   │   ├── node/
│   │   │   │   │   ├── selectors.js
│   │   │   │   │   └── states.js
│   │   │   │   ├── storage/
│   │   │   │   │   └── UploadProgressTracker.js
│   │   │   │   ├── strategies/
│   │   │   │   │   ├── README.md
│   │   │   │   │   └── storage_a/
│   │   │   │   │       ├── LocalDiskStorageStrategy.js
│   │   │   │   │       └── README.md
│   │   │   │   ├── validation.bench.js
│   │   │   │   └── validation.js
│   │   │   ├── helpers.js
│   │   │   ├── index.js
│   │   │   ├── kernel/
│   │   │   │   └── modutil.js
│   │   │   ├── loadTestConfig.js
│   │   │   ├── middleware/
│   │   │   │   ├── abuse.js
│   │   │   │   ├── anticsrf.js
│   │   │   │   ├── auth.js
│   │   │   │   ├── auth2.js
│   │   │   │   ├── configurable_auth.js
│   │   │   │   ├── featureflag.js
│   │   │   │   ├── measure.js
│   │   │   │   ├── subdomain.js
│   │   │   │   └── verified.js
│   │   │   ├── modules/
│   │   │   │   ├── ai/
│   │   │   │   │   └── PuterAIChatModule.js
│   │   │   │   ├── apps/
│   │   │   │   │   ├── AppIconService.js
│   │   │   │   │   ├── AppIconService.test.js
│   │   │   │   │   ├── AppInformationService.js
│   │   │   │   │   ├── AppPermissionService.js
│   │   │   │   │   ├── AppRedisCacheSpace.js
│   │   │   │   │   ├── AppsModule.js
│   │   │   │   │   ├── OldAppNameService.js
│   │   │   │   │   ├── ProtectedAppService.js
│   │   │   │   │   ├── RecommendedAppsRedisCacheSpace.js
│   │   │   │   │   ├── RecommendedAppsService.js
│   │   │   │   │   ├── default-app-icon.js
│   │   │   │   │   ├── lib/
│   │   │   │   │   │   └── IconResult.js
│   │   │   │   │   └── privateLaunchAccess.js
│   │   │   │   ├── broadcast/
│   │   │   │   │   ├── BroadcastModule.js
│   │   │   │   │   ├── BroadcastService.js
│   │   │   │   │   └── BroadcastService.redisPubSub.test.js
│   │   │   │   ├── captcha/
│   │   │   │   │   ├── CaptchaModule.js
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── middleware/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   └── captcha-middleware.js
│   │   │   │   │   └── services/
│   │   │   │   │       └── CaptchaService.js
│   │   │   │   ├── core/
│   │   │   │   │   ├── AlarmService.d.ts
│   │   │   │   │   ├── AlarmService.js
│   │   │   │   │   ├── ContextService.js
│   │   │   │   │   ├── Core2Module.js
│   │   │   │   │   ├── ErrorService.js
│   │   │   │   │   ├── ExpectationService.js
│   │   │   │   │   ├── LogService.js
│   │   │   │   │   ├── PagerService.js
│   │   │   │   │   ├── ParameterService.js
│   │   │   │   │   ├── ProcessEventService.js
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── ServerHealthService/
│   │   │   │   │   │   ├── ServerHealthRedisCacheKeys.js
│   │   │   │   │   │   └── ServerHealthService.js
│   │   │   │   │   └── lib/
│   │   │   │   │       ├── __lib__.js
│   │   │   │   │       ├── expect.js
│   │   │   │   │       ├── identifier.js
│   │   │   │   │       ├── linux.js
│   │   │   │   │       ├── log.js
│   │   │   │   │       └── stdio.js
│   │   │   │   ├── data-access/
│   │   │   │   │   ├── AppRepository.js
│   │   │   │   │   ├── AppService.comp.test.js
│   │   │   │   │   ├── AppService.js
│   │   │   │   │   ├── AppService.test.js
│   │   │   │   │   ├── DEV.md
│   │   │   │   │   ├── DataAccessModule.js
│   │   │   │   │   └── lib/
│   │   │   │   │       ├── coercion.js
│   │   │   │   │       ├── error.js
│   │   │   │   │       ├── filter.js
│   │   │   │   │       ├── sqlutil.js
│   │   │   │   │       └── validation.js
│   │   │   │   ├── development/
│   │   │   │   │   ├── DevelopmentModule.js
│   │   │   │   │   └── LocalTerminalService.js
│   │   │   │   ├── dns/
│   │   │   │   │   ├── DNSModule.js
│   │   │   │   │   └── DNSService.js
│   │   │   │   ├── domain/
│   │   │   │   │   ├── DomainModule.js
│   │   │   │   │   ├── DomainVerificationService.js
│   │   │   │   │   └── TXTVerifyService.js
│   │   │   │   ├── entitystore/
│   │   │   │   │   ├── EntityStoreInterfaceService.js
│   │   │   │   │   └── EntityStoreModule.js
│   │   │   │   ├── filesystem/
│   │   │   │   │   └── roadmap.md
│   │   │   │   ├── hostos/
│   │   │   │   │   ├── HostOSModule.js
│   │   │   │   │   └── ProcessService.js
│   │   │   │   ├── internet/
│   │   │   │   │   ├── InternetModule.js
│   │   │   │   │   └── WispRelayService.js
│   │   │   │   ├── kvstore/
│   │   │   │   │   ├── KVStoreInterfaceService.js
│   │   │   │   │   └── KVStoreModule.js
│   │   │   │   ├── perfmon/
│   │   │   │   │   └── TelemetryService.js
│   │   │   │   ├── puterfs/
│   │   │   │   │   ├── MountpointService.js
│   │   │   │   │   ├── PuterFSModule.js
│   │   │   │   │   ├── ResourceService.js
│   │   │   │   │   ├── SizeService.js
│   │   │   │   │   └── customfs/
│   │   │   │   │       ├── MemoryFSProvider.js
│   │   │   │   │       ├── MemoryFSService.js
│   │   │   │   │       └── README.md
│   │   │   │   ├── selfhosted/
│   │   │   │   │   ├── DefaultUserService.js
│   │   │   │   │   ├── DevCreditService.js
│   │   │   │   │   ├── DevWatcherService.js
│   │   │   │   │   ├── SelfHostedModule.js
│   │   │   │   │   ├── SelfhostedService.js
│   │   │   │   │   ├── ServeSingeFileService.js
│   │   │   │   │   └── ServeStaticFilesService.js
│   │   │   │   ├── template/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── TemplateModule.js
│   │   │   │   │   ├── TemplateService.js
│   │   │   │   │   └── lib/
│   │   │   │   │       ├── __lib__.js
│   │   │   │   │       └── hello_world.js
│   │   │   │   ├── test-config/
│   │   │   │   │   ├── TestConfigModule.js
│   │   │   │   │   ├── TestConfigReadService.js
│   │   │   │   │   └── TestConfigUpdateService.js
│   │   │   │   ├── test-core/
│   │   │   │   │   └── TestCoreModule.js
│   │   │   │   ├── test-drivers/
│   │   │   │   │   ├── TestAssetHostService.js
│   │   │   │   │   ├── TestDriversModule.js
│   │   │   │   │   ├── TestImageService.js
│   │   │   │   │   └── doc/
│   │   │   │   │       └── requests.md
│   │   │   │   └── web/
│   │   │   │       ├── APIErrorService.js
│   │   │   │       ├── README.md
│   │   │   │       ├── SocketioService.js
│   │   │   │       ├── WebModule.js
│   │   │   │       ├── WebServerService.d.ts
│   │   │   │       ├── WebServerService.js
│   │   │   │       └── lib/
│   │   │   │           ├── __lib__.js
│   │   │   │           ├── api_error_handler.js
│   │   │   │           └── eggspress.js
│   │   │   ├── om/
│   │   │   │   ├── IdentifierUtil.js
│   │   │   │   ├── definitions/
│   │   │   │   │   ├── Mapping.js
│   │   │   │   │   ├── PropType.js
│   │   │   │   │   ├── PropType.test.js
│   │   │   │   │   └── Property.js
│   │   │   │   ├── docs/
│   │   │   │   │   └── DESIGN.md
│   │   │   │   ├── entitystorage/
│   │   │   │   │   ├── AppES.js
│   │   │   │   │   ├── AppLimitedES.js
│   │   │   │   │   ├── BaseES.js
│   │   │   │   │   ├── ESBuilder.js
│   │   │   │   │   ├── Entity.js
│   │   │   │   │   ├── MaxLimitES.js
│   │   │   │   │   ├── NotificationES.js
│   │   │   │   │   ├── OwnerLimitedES.js
│   │   │   │   │   ├── ProtectedAppES.js
│   │   │   │   │   ├── ReadOnlyES.js
│   │   │   │   │   ├── SQLES.js
│   │   │   │   │   ├── SetOwnerES.js
│   │   │   │   │   ├── SubdomainES.js
│   │   │   │   │   ├── ValidationES.js
│   │   │   │   │   ├── WriteByOwnerOnlyES.js
│   │   │   │   │   └── consts.js
│   │   │   │   ├── mappings/
│   │   │   │   │   ├── __all__.js
│   │   │   │   │   ├── access-token.js
│   │   │   │   │   ├── app.js
│   │   │   │   │   ├── notification.js
│   │   │   │   │   └── subdomain.js
│   │   │   │   ├── proptypes/
│   │   │   │   │   ├── __all__.js
│   │   │   │   │   └── __all__.test.js
│   │   │   │   └── query/
│   │   │   │       ├── query.js
│   │   │   │       └── query.test.js
│   │   │   ├── polyfill/
│   │   │   │   └── to-string-higher-radix.js
│   │   │   ├── public/
│   │   │   │   └── assets/
│   │   │   │       ├── css/
│   │   │   │       │   ├── admin.css
│   │   │   │       │   └── style.css
│   │   │   │       ├── img/
│   │   │   │       │   ├── logo-bold.psd
│   │   │   │       │   └── logo.psd
│   │   │   │       └── js/
│   │   │   │           └── app.js
│   │   │   ├── routers/
│   │   │   │   ├── _default.js
│   │   │   │   ├── apps.js
│   │   │   │   ├── auth/
│   │   │   │   │   ├── app-uid-from-origin.js
│   │   │   │   │   ├── check-app-acl.endpoint.js
│   │   │   │   │   ├── check-app.js
│   │   │   │   │   ├── check-permissions.js
│   │   │   │   │   ├── configure-2fa.js
│   │   │   │   │   ├── create-access-token.js
│   │   │   │   │   ├── get-user-app-token.js
│   │   │   │   │   ├── grant-dev-app.js
│   │   │   │   │   ├── grant-user-app.js
│   │   │   │   │   ├── grant-user-group.js
│   │   │   │   │   ├── grant-user-user.js
│   │   │   │   │   ├── list-permissions.js
│   │   │   │   │   ├── list-sessions.js
│   │   │   │   │   ├── oidc.js
│   │   │   │   │   ├── request-app-root-dir.js
│   │   │   │   │   ├── revoke-access-token.js
│   │   │   │   │   ├── revoke-dev-app.js
│   │   │   │   │   ├── revoke-session.js
│   │   │   │   │   ├── revoke-user-app.js
│   │   │   │   │   ├── revoke-user-group.js
│   │   │   │   │   └── revoke-user-user.js
│   │   │   │   ├── change_email.js
│   │   │   │   ├── change_username.js
│   │   │   │   ├── confirmEmail/
│   │   │   │   │   ├── ConfirmEmailRedisCacheSpace.js
│   │   │   │   │   └── confirm-email.js
│   │   │   │   ├── contactUs.js
│   │   │   │   ├── delete-site.js
│   │   │   │   ├── df.js
│   │   │   │   ├── down.js
│   │   │   │   ├── drivers/
│   │   │   │   │   ├── call.js
│   │   │   │   │   ├── list-interfaces.js
│   │   │   │   │   ├── usage.js
│   │   │   │   │   └── xd.js
│   │   │   │   ├── file.js
│   │   │   │   ├── filesystem_api/
│   │   │   │   │   ├── batch/
│   │   │   │   │   │   ├── PathResolver.js
│   │   │   │   │   │   └── all.js
│   │   │   │   │   ├── cache.js
│   │   │   │   │   ├── copy.js
│   │   │   │   │   ├── delete.js
│   │   │   │   │   ├── mkdir.js
│   │   │   │   │   ├── move.js
│   │   │   │   │   ├── read.js
│   │   │   │   │   ├── readdir-subdomains.mjs
│   │   │   │   │   ├── readdir.js
│   │   │   │   │   ├── rename.js
│   │   │   │   │   ├── search.js
│   │   │   │   │   ├── stat.js
│   │   │   │   │   ├── token-read.js
│   │   │   │   │   ├── touch.js
│   │   │   │   │   ├── update.js
│   │   │   │   │   └── write.js
│   │   │   │   ├── get-dev-profile.js
│   │   │   │   ├── get-launch-apps.js
│   │   │   │   ├── get-launch-apps.test.js
│   │   │   │   ├── healthcheck.js
│   │   │   │   ├── hosting/
│   │   │   │   │   ├── puter-site-config.js
│   │   │   │   │   ├── puter-site-config.test.js
│   │   │   │   │   ├── puterSiteMiddleware.js
│   │   │   │   │   └── puterSiteMiddleware.test.js
│   │   │   │   ├── itemMetadata.js
│   │   │   │   ├── kvstore/
│   │   │   │   │   ├── clearItems.js
│   │   │   │   │   ├── getItem.js
│   │   │   │   │   ├── listItems.js
│   │   │   │   │   └── setItem.js
│   │   │   │   ├── login.js
│   │   │   │   ├── logout.js
│   │   │   │   ├── open_item.js
│   │   │   │   ├── passwd.js
│   │   │   │   ├── puterai/
│   │   │   │   │   └── openai/
│   │   │   │   │       ├── chat_completions.js
│   │   │   │   │       └── completions.js
│   │   │   │   ├── query/
│   │   │   │   │   └── app.js
│   │   │   │   ├── recentAppOpens/
│   │   │   │   │   ├── RecentAppOpensRedisCacheSpace.js
│   │   │   │   │   └── rao.js
│   │   │   │   ├── remove-site-dir.js
│   │   │   │   ├── removeItem.js
│   │   │   │   ├── save_account.js
│   │   │   │   ├── send-confirm-email.js
│   │   │   │   ├── send-pass-recovery-email.js
│   │   │   │   ├── set-desktop-bg.js
│   │   │   │   ├── set-pass-using-token.js
│   │   │   │   ├── set_layout.js
│   │   │   │   ├── set_sort_by.js
│   │   │   │   ├── sign.js
│   │   │   │   ├── signup.js
│   │   │   │   ├── signup_create_new_user.js
│   │   │   │   ├── sites.js
│   │   │   │   ├── suggest_apps.js
│   │   │   │   ├── test.js
│   │   │   │   ├── update-taskbar-items.js
│   │   │   │   ├── user-protected/
│   │   │   │   │   ├── change-email.js
│   │   │   │   │   ├── change-password.js
│   │   │   │   │   ├── change-username.js
│   │   │   │   │   ├── delete-own-user.js
│   │   │   │   │   └── disable-2fa.js
│   │   │   │   ├── verify-pass-recovery-token.js
│   │   │   │   ├── version.js
│   │   │   │   ├── writeFile/
│   │   │   │   │   ├── copy.js
│   │   │   │   │   ├── delete.js
│   │   │   │   │   ├── mkdir.js
│   │   │   │   │   ├── move.js
│   │   │   │   │   ├── rename.js
│   │   │   │   │   ├── trash.js
│   │   │   │   │   ├── write.js
│   │   │   │   │   └── writeFile_handlers.js
│   │   │   │   └── writeFile.js
│   │   │   ├── server
│   │   │   ├── services/
│   │   │   │   ├── AWSSecretsPopulator.js
│   │   │   │   ├── AnomalyService.js
│   │   │   │   ├── AnomalyService.test.ts
│   │   │   │   ├── BaseService.d.ts
│   │   │   │   ├── BaseService.js
│   │   │   │   ├── BootScriptService.js
│   │   │   │   ├── ChatAPIService.js
│   │   │   │   ├── ChatAPIService.test.js
│   │   │   │   ├── CleanEmailService.js
│   │   │   │   ├── CleanEmailService.test.ts
│   │   │   │   ├── ClientOperationService.js
│   │   │   │   ├── ClientOperationService.test.ts
│   │   │   │   ├── CommandService.js
│   │   │   │   ├── CommandService.test.ts
│   │   │   │   ├── ConfigurableCountingService.js
│   │   │   │   ├── ConfigurableCountingService.test.ts
│   │   │   │   ├── Container.js
│   │   │   │   ├── ContextInitService.js
│   │   │   │   ├── ContextInitService.test.ts
│   │   │   │   ├── DetailProviderService.js
│   │   │   │   ├── DetailProviderService.test.ts
│   │   │   │   ├── DynamoKVStore/
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── DynamoKVStore.test.ts
│   │   │   │   │   ├── DynamoKVStore.ts
│   │   │   │   │   ├── DynamoKVStoreWrapper.ts
│   │   │   │   │   └── tableDefinition.ts
│   │   │   │   ├── EmailService.js
│   │   │   │   ├── EngPortalService.js
│   │   │   │   ├── EntityStoreService.js
│   │   │   │   ├── EntriService.js
│   │   │   │   ├── EventService.js
│   │   │   │   ├── EventService.test.ts
│   │   │   │   ├── FeatureFlagService.js
│   │   │   │   ├── FeatureFlagService.test.ts
│   │   │   │   ├── FilesystemAPIService.js
│   │   │   │   ├── GetUserService.js
│   │   │   │   ├── HelloWorldService.js
│   │   │   │   ├── HelloWorldService.test.ts
│   │   │   │   ├── HostDiskUsageService.js
│   │   │   │   ├── HostnameService.js
│   │   │   │   ├── HostnameService.test.ts
│   │   │   │   ├── KernelInfoService.js
│   │   │   │   ├── LocalDiskStorageService.js
│   │   │   │   ├── LockService.js
│   │   │   │   ├── LockService.test.ts
│   │   │   │   ├── MakeProdDebuggingLessAwfulService.js
│   │   │   │   ├── MemoryStorageService.js
│   │   │   │   ├── MemoryStorageService.test.ts
│   │   │   │   ├── MeteringService/
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   ├── MeteringService.test.ts
│   │   │   │   │   ├── MeteringService.ts
│   │   │   │   │   ├── MeteringServiceWrapper.mjs
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── consts.ts
│   │   │   │   │   ├── costMaps/
│   │   │   │   │   │   ├── awsPollyCostMap.ts
│   │   │   │   │   │   ├── awsTextractCostMap.ts
│   │   │   │   │   │   ├── claudeCostMap.ts
│   │   │   │   │   │   ├── deepSeekCostMap.ts
│   │   │   │   │   │   ├── elevenlabsCostMap.ts
│   │   │   │   │   │   ├── fileSystemCostMap.ts
│   │   │   │   │   │   ├── geminiCostMap.ts
│   │   │   │   │   │   ├── groqCostMap.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── kvCostMap.ts
│   │   │   │   │   │   ├── mistralCostMap.ts
│   │   │   │   │   │   ├── openAiCostMap.ts
│   │   │   │   │   │   ├── openaiImageCostMap.ts
│   │   │   │   │   │   ├── openaiVideoCostMap.ts
│   │   │   │   │   │   ├── openrouterCostMap.ts
│   │   │   │   │   │   ├── togetherCostMap.ts
│   │   │   │   │   │   └── xaiCostMap.ts
│   │   │   │   │   ├── subPolicies/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── registeredUserFreePolicy.ts
│   │   │   │   │   │   └── tempUserFreePolicy.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── NotificationService.js
│   │   │   │   ├── NotificationService.test.ts
│   │   │   │   ├── OperationTraceService.js
│   │   │   │   ├── PeerService.js
│   │   │   │   ├── PermissionAPIService.js
│   │   │   │   ├── PuterAPIService.js
│   │   │   │   ├── PuterHomepageService.js
│   │   │   │   ├── PuterSiteService.js
│   │   │   │   ├── PuterVersionService.js
│   │   │   │   ├── PuterVersionService.test.ts
│   │   │   │   ├── ReferralCodeService.js
│   │   │   │   ├── ReferralCodeService.test.js
│   │   │   │   ├── RefreshAssociationsService.js
│   │   │   │   ├── RegistrantService.js
│   │   │   │   ├── RegistryService.js
│   │   │   │   ├── RegistryService.test.ts
│   │   │   │   ├── RequestMeasureService.js
│   │   │   │   ├── SNSService.js
│   │   │   │   ├── SNSService.test.ts
│   │   │   │   ├── SUService.js
│   │   │   │   ├── ScriptService.js
│   │   │   │   ├── ScriptService.test.ts
│   │   │   │   ├── ServeGUIService.js
│   │   │   │   ├── ServicePatch.js
│   │   │   │   ├── SessionService.js
│   │   │   │   ├── SessionService.test.js
│   │   │   │   ├── ShareService.js
│   │   │   │   ├── ShutdownService.js
│   │   │   │   ├── ShutdownService.test.ts
│   │   │   │   ├── StorageService.js
│   │   │   │   ├── StrategizedService.js
│   │   │   │   ├── SystemDataService.js
│   │   │   │   ├── SystemValidationService.js
│   │   │   │   ├── SystemValidationService.test.ts
│   │   │   │   ├── TestService.js
│   │   │   │   ├── TestService.test.ts
│   │   │   │   ├── User.d.ts
│   │   │   │   ├── UserRedisCacheSpace.js
│   │   │   │   ├── UserService.d.ts
│   │   │   │   ├── UserService.js
│   │   │   │   ├── VerifiedGroupService.js
│   │   │   │   ├── WSPushService.js
│   │   │   │   ├── WebDAV/
│   │   │   │   │   ├── WebDAVService.js
│   │   │   │   │   ├── lockStore.mjs
│   │   │   │   │   ├── methodHandlers/
│   │   │   │   │   │   ├── COPY.mjs
│   │   │   │   │   │   ├── DELETE.mjs
│   │   │   │   │   │   ├── HEAD_GET.mjs
│   │   │   │   │   │   ├── LOCK.mjs
│   │   │   │   │   │   ├── MKCOL.mjs
│   │   │   │   │   │   ├── MOVE.mjs
│   │   │   │   │   │   ├── OPTIONS.mjs
│   │   │   │   │   │   ├── PROPFIND.mjs
│   │   │   │   │   │   ├── PROPPATCH.mjs
│   │   │   │   │   │   ├── PUT.mjs
│   │   │   │   │   │   ├── UNLOCK.mjs
│   │   │   │   │   │   ├── method.mjs
│   │   │   │   │   │   └── methodMap.mjs
│   │   │   │   │   └── utils.mjs
│   │   │   │   ├── WispService.js
│   │   │   │   ├── abuse-prevention/
│   │   │   │   │   ├── AuthAuditService.js
│   │   │   │   │   ├── EdgeRateLimitService.js
│   │   │   │   │   ├── IdentificationService.js
│   │   │   │   │   └── concurrentRequestLimiter/
│   │   │   │   │       ├── .gitignore
│   │   │   │   │       ├── ConcurrentRequestLimiter.test.ts
│   │   │   │   │       ├── ConcurrentRequestLimiter.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── types.ts
│   │   │   │   ├── ai/
│   │   │   │   │   ├── AIInterfaceService.js
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── chat/
│   │   │   │   │   │   ├── .gitignore
│   │   │   │   │   │   ├── AIChatRedisCacheSpace.ts
│   │   │   │   │   │   ├── AIChatService.ts
│   │   │   │   │   │   └── providers/
│   │   │   │   │   │       ├── ChatProvider.ts
│   │   │   │   │   │       ├── ClaudeProvider/
│   │   │   │   │   │       │   ├── ClaudeProvider.test.ts
│   │   │   │   │   │       │   ├── ClaudeProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── DeepSeekProvider/
│   │   │   │   │   │       │   ├── DeepSeekProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── FakeChatProvider.ts
│   │   │   │   │   │       ├── GeminiProvider/
│   │   │   │   │   │       │   ├── GeminiChatProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── GroqAiProvider/
│   │   │   │   │   │       │   ├── GroqAIProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── MistralAiProvider/
│   │   │   │   │   │       │   ├── MistralAiProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── OllamaProvider.ts
│   │   │   │   │   │       ├── OpenAiProvider/
│   │   │   │   │   │       │   ├── OpenAiChatCompletionsProvider.ts
│   │   │   │   │   │       │   ├── OpenAiChatResponsesProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── OpenRouterProvider/
│   │   │   │   │   │       │   ├── OpenRouterProvider.ts
│   │   │   │   │   │       │   └── modelOverrides.ts
│   │   │   │   │   │       ├── TogetherAiProvider/
│   │   │   │   │   │       │   └── TogetherAIProvider.ts
│   │   │   │   │   │       ├── XAIProvider/
│   │   │   │   │   │       │   ├── XAIProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       └── types.ts
│   │   │   │   │   ├── docs/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   ├── ai-services-config.md
│   │   │   │   │   │   ├── api_examples.md
│   │   │   │   │   │   └── config.md
│   │   │   │   │   ├── image/
│   │   │   │   │   │   ├── .gitignore
│   │   │   │   │   │   ├── AIImageGenerationService.ts
│   │   │   │   │   │   └── providers/
│   │   │   │   │   │       ├── CloudflareImageGenerationProvider/
│   │   │   │   │   │       │   ├── CloudflareImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── GeminiImageGenerationProvider/
│   │   │   │   │   │       │   ├── GeminiImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── OpenAiImageGenerationProvider/
│   │   │   │   │   │       │   ├── OpenAiImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── TogetherImageGenerationProvider/
│   │   │   │   │   │       │   ├── TogetherImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       ├── XAIImageGenerationProvider/
│   │   │   │   │   │       │   ├── XAIImageGenerationProvider.ts
│   │   │   │   │   │       │   └── models.ts
│   │   │   │   │   │       └── types.ts
│   │   │   │   │   ├── moderation/
│   │   │   │   │   │   └── AsModeration.js
│   │   │   │   │   ├── ocr/
│   │   │   │   │   │   ├── AWSTextractService.js
│   │   │   │   │   │   └── MistralOCRService.js
│   │   │   │   │   ├── sts/
│   │   │   │   │   │   └── ElevenLabsVoiceChangerService.js
│   │   │   │   │   ├── stt/
│   │   │   │   │   │   └── OpenAISpeechToTextService.js
│   │   │   │   │   ├── tts/
│   │   │   │   │   │   ├── AWSPollyService.js
│   │   │   │   │   │   ├── ElevenLabsTTSService.js
│   │   │   │   │   │   ├── OpenAITTSService.js
│   │   │   │   │   │   └── PollyRedisCacheKeys.js
│   │   │   │   │   ├── utils/
│   │   │   │   │   │   ├── FunctionCalling.js
│   │   │   │   │   │   ├── Messages.js
│   │   │   │   │   │   ├── OpenAIUtil.d.ts
│   │   │   │   │   │   ├── OpenAIUtil.js
│   │   │   │   │   │   ├── Streaming.js
│   │   │   │   │   │   └── messages.test.js
│   │   │   │   │   └── video/
│   │   │   │   │       ├── OpenAIVideoGenerationService/
│   │   │   │   │       │   └── OpenAIVideoGenerationService.js
│   │   │   │   │       └── TogetherVideoGenerationService/
│   │   │   │   │           ├── TogetherVideoGenerationService.js
│   │   │   │   │           └── models.js
│   │   │   │   ├── auth/
│   │   │   │   │   ├── ACLService.js
│   │   │   │   │   ├── Actor.d.ts
│   │   │   │   │   ├── Actor.js
│   │   │   │   │   ├── AntiCSRFService.js
│   │   │   │   │   ├── AntiCSRFService.test.ts
│   │   │   │   │   ├── AuthService.js
│   │   │   │   │   ├── AuthService.privateAssetToken.test.ts
│   │   │   │   │   ├── GroupRedisCacheSpace.js
│   │   │   │   │   ├── GroupService.js
│   │   │   │   │   ├── OIDCService.js
│   │   │   │   │   ├── OTPService.js
│   │   │   │   │   ├── PermissionScanRedisCacheSpace.js
│   │   │   │   │   ├── PermissionScanRedisCacheSpace.test.js
│   │   │   │   │   ├── PermissionService.js
│   │   │   │   │   ├── PermissionShortcutService.js
│   │   │   │   │   ├── PreAuthService.js
│   │   │   │   │   ├── SignupService.js
│   │   │   │   │   ├── TokenService.js
│   │   │   │   │   ├── TokenService.test.ts
│   │   │   │   │   ├── VirtualGroupService.js
│   │   │   │   │   ├── permissionConts.mjs
│   │   │   │   │   ├── permissionUtils.bench.js
│   │   │   │   │   └── permissionUtils.mjs
│   │   │   │   ├── database/
│   │   │   │   │   ├── BaseDatabaseAccessService.js
│   │   │   │   │   ├── SqliteDatabaseAccessService.js
│   │   │   │   │   ├── constructs.js
│   │   │   │   │   ├── consts.js
│   │   │   │   │   └── sqlite_setup/
│   │   │   │   │       ├── 0001_create-tables.sql
│   │   │   │   │       ├── 0002_add-default-apps.sql
│   │   │   │   │       ├── 0003_user-permissions.sql
│   │   │   │   │       ├── 0004_sessions.sql
│   │   │   │   │       ├── 0005_background-apps.sql
│   │   │   │   │       ├── 0006_update-apps.sql
│   │   │   │   │       ├── 0007_sessions.sql
│   │   │   │   │       ├── 0008_otp.sql
│   │   │   │   │       ├── 0009_app-prefix-fix.sql
│   │   │   │   │       ├── 0010_add-git-app.sql
│   │   │   │   │       ├── 0011_notification.sql
│   │   │   │   │       ├── 0012_appmetadata.sql
│   │   │   │   │       ├── 0013_protected-apps.sql
│   │   │   │   │       ├── 0014_share.sql
│   │   │   │   │       ├── 0015_group.sql
│   │   │   │   │       ├── 0016_group-permissions.sql
│   │   │   │   │       ├── 0017_publicdirs.sql
│   │   │   │   │       ├── 0018_fix-0003.sql
│   │   │   │   │       ├── 0019_fix-0016.sql
│   │   │   │   │       ├── 0020_dev-center.sql
│   │   │   │   │       ├── 0021_app-owner-id.sql
│   │   │   │   │       ├── 0022_dev-center-max.sql
│   │   │   │   │       ├── 0023_fix-kv.sql
│   │   │   │   │       ├── 0024_default-groups.sql
│   │   │   │   │       ├── 0025_system-user.dbmig.js
│   │   │   │   │       ├── 0026_user-groups.dbmig.js
│   │   │   │   │       ├── 0027_emulator-app.dbmig.js
│   │   │   │   │       ├── 0028_clean-email.sql
│   │   │   │   │       ├── 0029_emulator_priv.sql
│   │   │   │   │       ├── 0030_comments.sql
│   │   │   │   │       ├── 0031_audit-meta.sql
│   │   │   │   │       ├── 0032_signup_metadata.sql
│   │   │   │   │       ├── 0033_ai-usage.sql
│   │   │   │   │       ├── 0034_app-redirect.sql
│   │   │   │   │       ├── 0035_threads.sql
│   │   │   │   │       ├── 0036_dev-to-app.sql
│   │   │   │   │       ├── 0037_cost.sql
│   │   │   │   │       ├── 0038_custom-domains.sql
│   │   │   │   │       ├── 0039_add-expireAt-to-kv-store.sql
│   │   │   │   │       ├── 0040_add_user_metadata.sql
│   │   │   │   │       ├── 0041_add_unique_constraint_user_uuid.sql
│   │   │   │   │       ├── 0042_add_cloudflare_d1.sql
│   │   │   │   │       ├── 0043_add_dt.sql
│   │   │   │   │       ├── 0044_dev-center-godmode.sql
│   │   │   │   │       ├── 0045_user_oidc_providers.sql
│   │   │   │   │       └── 0046_is-private-apps.sql
│   │   │   │   ├── drivers/
│   │   │   │   │   ├── CoercionService.js
│   │   │   │   │   ├── DriverError.js
│   │   │   │   │   ├── DriverService.js
│   │   │   │   │   ├── DriverUsagePolicyService.js
│   │   │   │   │   ├── FileFacade.js
│   │   │   │   │   ├── meta/
│   │   │   │   │   │   ├── Construct.js
│   │   │   │   │   │   └── Runtime.js
│   │   │   │   │   └── types.js
│   │   │   │   ├── file-cache/
│   │   │   │   │   ├── FileTracker.bench.js
│   │   │   │   │   └── FileTracker.js
│   │   │   │   ├── fs/
│   │   │   │   │   └── FSLockService.js
│   │   │   │   ├── periodic/
│   │   │   │   │   └── FSEntryMigrateService.js
│   │   │   │   ├── sla/
│   │   │   │   │   ├── RateLimitRedisCacheSpace.js
│   │   │   │   │   ├── RateLimitService.js
│   │   │   │   │   └── SLAService.js
│   │   │   │   ├── web/
│   │   │   │   │   └── UserProtectedEndpointsService.js
│   │   │   │   └── worker/
│   │   │   │       ├── .gitignore
│   │   │   │       ├── README.md
│   │   │   │       ├── WorkerService.js
│   │   │   │       ├── package.json
│   │   │   │       ├── src/
│   │   │   │       │   ├── index.js
│   │   │   │       │   └── s2w-router.js
│   │   │   │       ├── template/
│   │   │   │       │   └── puter-portable.js
│   │   │   │       ├── webpack.config.js
│   │   │   │       └── workerUtils/
│   │   │   │           ├── cloudflareDeploy.js
│   │   │   │           ├── nameUtils.js
│   │   │   │           └── puterUtils.js
│   │   │   ├── structured/
│   │   │   │   ├── README.md
│   │   │   │   └── sequence/
│   │   │   │       ├── scan-permission.mjs
│   │   │   │       ├── share/
│   │   │   │       │   ├── process_recipients.js
│   │   │   │       │   ├── process_shares.js
│   │   │   │       │   └── validate.js
│   │   │   │       └── share.js
│   │   │   ├── traits/
│   │   │   │   ├── AssignableMethodsFeature.js
│   │   │   │   ├── AsyncProviderFeature.js
│   │   │   │   ├── ChannelFeature.js
│   │   │   │   ├── ContextAwareFeature.js
│   │   │   │   ├── OtelFeature.js
│   │   │   │   ├── SyncFeature.js
│   │   │   │   └── WeakConstructorFeature.js
│   │   │   ├── unstructured/
│   │   │   │   ├── permission-scan-lib.js
│   │   │   │   └── permission-scanners.js
│   │   │   ├── user-mig.js
│   │   │   ├── util/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── CircularQueue.bench.js
│   │   │   │   ├── CircularQueue.js
│   │   │   │   ├── asyncutil.js
│   │   │   │   ├── configutil.js
│   │   │   │   ├── consolelog.js
│   │   │   │   ├── context.bench.js
│   │   │   │   ├── context.d.ts
│   │   │   │   ├── context.js
│   │   │   │   ├── datautil.bench.js
│   │   │   │   ├── datautil.js
│   │   │   │   ├── debugutil.js
│   │   │   │   ├── errorutil.js
│   │   │   │   ├── esmcontext.js
│   │   │   │   ├── expressutil.js
│   │   │   │   ├── fnutil.js
│   │   │   │   ├── fuzz.js
│   │   │   │   ├── gcutil.js
│   │   │   │   ├── hl_types.js
│   │   │   │   ├── hl_types.test.js
│   │   │   │   ├── identifier.bench.js
│   │   │   │   ├── identifier.js
│   │   │   │   ├── kvSingleton.js
│   │   │   │   ├── lockutil.bench.js
│   │   │   │   ├── lockutil.js
│   │   │   │   ├── multivalue.js
│   │   │   │   ├── objutil.js
│   │   │   │   ├── opmath.bench.js
│   │   │   │   ├── opmath.js
│   │   │   │   ├── opmath.test.js
│   │   │   │   ├── otelutil.js
│   │   │   │   ├── outcomeutil.ts
│   │   │   │   ├── pathutil.bench.js
│   │   │   │   ├── pathutil.js
│   │   │   │   ├── retryutil.js
│   │   │   │   ├── safety.js
│   │   │   │   ├── securehttp.js
│   │   │   │   ├── stdioutil.js
│   │   │   │   ├── streamutil.js
│   │   │   │   ├── structutil.bench.js
│   │   │   │   ├── structutil.js
│   │   │   │   ├── urlutil.js
│   │   │   │   ├── uuidfpe.bench.js
│   │   │   │   ├── uuidfpe.js
│   │   │   │   ├── validutil.js
│   │   │   │   ├── validutil.test.js
│   │   │   │   ├── versionutil.js
│   │   │   │   ├── versionutil.test.js
│   │   │   │   └── workutil.js
│   │   │   └── validation.js
│   │   ├── test/
│   │   │   └── modules/
│   │   │       └── captcha/
│   │   │           └── integration/
│   │   │               └── extension-integration.test.js
│   │   ├── tools/
│   │   │   ├── .test-webhook-config.json
│   │   │   ├── README.md
│   │   │   ├── test-webhook.js
│   │   │   └── test.mjs
│   │   ├── vitest.bench.config.js
│   │   ├── vitest.bench.config.ts
│   │   └── vitest.config.ts
│   ├── dev-center/
│   │   ├── LICENSE.txt
│   │   ├── README.md
│   │   ├── coming-soon.html
│   │   ├── css/
│   │   │   ├── normalize.css
│   │   │   └── style.css
│   │   ├── index.html
│   │   └── js/
│   │       ├── apps.js
│   │       ├── dev-center.js
│   │       ├── images.js
│   │       ├── libs/
│   │       │   ├── html-entities.js
│   │       │   ├── jquery.dragster.js
│   │       │   └── slugify.js
│   │       ├── websites.js
│   │       └── workers.js
│   ├── docs/
│   │   ├── CREDITS.md
│   │   ├── LICENSE-CODE.txt
│   │   ├── LICENSE.txt
│   │   ├── README.md
│   │   ├── build.js
│   │   ├── package.json
│   │   └── src/
│   │       ├── AI/
│   │       │   ├── chat.md
│   │       │   ├── img2txt.md
│   │       │   ├── listModelProviders.md
│   │       │   ├── listModels.md
│   │       │   ├── speech2speech.md
│   │       │   ├── speech2txt.md
│   │       │   ├── txt2img.md
│   │       │   ├── txt2speech.md
│   │       │   └── txt2vid.md
│   │       ├── AI.md
│   │       ├── Apps/
│   │       │   ├── create.md
│   │       │   ├── delete.md
│   │       │   ├── get.md
│   │       │   ├── list.md
│   │       │   └── update.md
│   │       ├── Apps.md
│   │       ├── Auth/
│   │       │   ├── getDetailedAppUsage.md
│   │       │   ├── getMonthlyUsage.md
│   │       │   ├── getUser.md
│   │       │   ├── isSignedIn.md
│   │       │   ├── signIn.md
│   │       │   └── signOut.md
│   │       ├── Auth.md
│   │       ├── Drivers/
│   │       │   └── call.md
│   │       ├── Drivers.md
│   │       ├── FS/
│   │       │   ├── copy.md
│   │       │   ├── delete.md
│   │       │   ├── getReadURL.md
│   │       │   ├── mkdir.md
│   │       │   ├── move.md
│   │       │   ├── read.md
│   │       │   ├── readdir.md
│   │       │   ├── rename.md
│   │       │   ├── space.md
│   │       │   ├── stat.md
│   │       │   ├── upload.md
│   │       │   └── write.md
│   │       ├── FS.md
│   │       ├── Hosting/
│   │       │   ├── create.md
│   │       │   ├── delete.md
│   │       │   ├── get.md
│   │       │   ├── list.md
│   │       │   └── update.md
│   │       ├── Hosting.md
│   │       ├── KV/
│   │       │   ├── MAX_KEY_SIZE.md
│   │       │   ├── MAX_VALUE_SIZE.md
│   │       │   ├── add.md
│   │       │   ├── decr.md
│   │       │   ├── del.md
│   │       │   ├── expire.md
│   │       │   ├── expireAt.md
│   │       │   ├── flush.md
│   │       │   ├── get.md
│   │       │   ├── incr.md
│   │       │   ├── list.md
│   │       │   ├── remove.md
│   │       │   ├── set.md
│   │       │   └── update.md
│   │       ├── KV.md
│   │       ├── Networking/
│   │       │   ├── Socket.md
│   │       │   ├── TLSSocket.md
│   │       │   └── fetch.md
│   │       ├── Networking.md
│   │       ├── Objects/
│   │       │   ├── AppConnection.md
│   │       │   ├── app.md
│   │       │   ├── chatresponse.md
│   │       │   ├── chatresponsechunk.md
│   │       │   ├── createappresult.md
│   │       │   ├── detailedappusage.md
│   │       │   ├── fsitem.md
│   │       │   ├── kvlistpage.md
│   │       │   ├── kvpair.md
│   │       │   ├── monthlyusage.md
│   │       │   ├── signinresult.md
│   │       │   ├── spaceinfo.md
│   │       │   ├── speech2txtresult.md
│   │       │   ├── subdomain.md
│   │       │   ├── toolcall.md
│   │       │   ├── user.md
│   │       │   ├── workerdeployment.md
│   │       │   └── workerinfo.md
│   │       ├── Objects.md
│   │       ├── Peer/
│   │       │   ├── connect.md
│   │       │   ├── ensureTurnRelays.md
│   │       │   └── serve.md
│   │       ├── Peer.md
│   │       ├── Perms/
│   │       │   ├── request.md
│   │       │   ├── requestEmail.md
│   │       │   ├── requestManageApps.md
│   │       │   ├── requestManageSubdomains.md
│   │       │   ├── requestReadApps.md
│   │       │   ├── requestReadDesktop.md
│   │       │   ├── requestReadDocuments.md
│   │       │   ├── requestReadPictures.md
│   │       │   ├── requestReadSubdomains.md
│   │       │   ├── requestReadVideos.md
│   │       │   ├── requestWriteDesktop.md
│   │       │   ├── requestWriteDocuments.md
│   │       │   ├── requestWritePictures.md
│   │       │   └── requestWriteVideos.md
│   │       ├── Perms.md
│   │       ├── UI/
│   │       │   ├── alert.md
│   │       │   ├── authenticateWithPuter.md
│   │       │   ├── contextMenu.md
│   │       │   ├── createWindow.md
│   │       │   ├── exit.md
│   │       │   ├── getLanguage.md
│   │       │   ├── hideSpinner.md
│   │       │   ├── hideWindow.md
│   │       │   ├── launchApp.md
│   │       │   ├── notify.md
│   │       │   ├── on.md
│   │       │   ├── onItemsOpened.md
│   │       │   ├── onLaunchedWithItems.md
│   │       │   ├── onWindowClose.md
│   │       │   ├── parentApp.md
│   │       │   ├── prompt.md
│   │       │   ├── setMenubar.md
│   │       │   ├── setWindowHeight.md
│   │       │   ├── setWindowPosition.md
│   │       │   ├── setWindowSize.md
│   │       │   ├── setWindowTitle.md
│   │       │   ├── setWindowWidth.md
│   │       │   ├── setWindowX.md
│   │       │   ├── setWindowY.md
│   │       │   ├── showColorPicker.md
│   │       │   ├── showDirectoryPicker.md
│   │       │   ├── showFontPicker.md
│   │       │   ├── showOpenFilePicker.md
│   │       │   ├── showSaveFilePicker.md
│   │       │   ├── showSpinner.md
│   │       │   ├── showWindow.md
│   │       │   ├── socialShare.md
│   │       │   └── wasLaunchedWithItems.md
│   │       ├── UI.md
│   │       ├── Utils/
│   │       │   ├── appID.md
│   │       │   ├── env.md
│   │       │   ├── print.md
│   │       │   └── randName.md
│   │       ├── Utils.md
│   │       ├── Workers/
│   │       │   ├── create.md
│   │       │   ├── delete.md
│   │       │   ├── exec.md
│   │       │   ├── get.md
│   │       │   ├── list.md
│   │       │   └── router.md
│   │       ├── Workers.md
│   │       ├── assets/
│   │       │   ├── css/
│   │       │   │   └── style.css
│   │       │   ├── favicon/
│   │       │   │   ├── browserconfig.xml
│   │       │   │   └── manifest.json
│   │       │   └── js/
│   │       │       ├── context-menu.js
│   │       │       ├── example.js
│   │       │       ├── index.js
│   │       │       ├── router.js
│   │       │       ├── search.js
│   │       │       └── sidebar.js
│   │       ├── examples.js
│   │       ├── examples.md
│   │       ├── frameworks.md
│   │       ├── getting-started.md
│   │       ├── index.md
│   │       ├── menu.js
│   │       ├── playground/
│   │       │   ├── assets/
│   │       │   │   ├── css/
│   │       │   │   │   └── style.css
│   │       │   │   └── js/
│   │       │   │       └── app.js
│   │       │   └── examples/
│   │       │       ├── ai-chat-claude-3-7-sonnet.html
│   │       │       ├── ai-chat-claude.html
│   │       │       ├── ai-chat-deepseek.html
│   │       │       ├── ai-chat-gemini.html
│   │       │       ├── ai-chat-openai-o3-mini.html
│   │       │       ├── ai-chat-stream.html
│   │       │       ├── ai-chatgpt.html
│   │       │       ├── ai-function-calling.html
│   │       │       ├── ai-gpt-vision.html
│   │       │       ├── ai-img2txt.html
│   │       │       ├── ai-list-model-providers.html
│   │       │       ├── ai-list-models.html
│   │       │       ├── ai-resume-analyzer.html
│   │       │       ├── ai-speech2speech-elevenlabs.html
│   │       │       ├── ai-speech2speech-file.html
│   │       │       ├── ai-speech2speech-url.html
│   │       │       ├── ai-speech2txt.html
│   │       │       ├── ai-streaming-function-calling.html
│   │       │       ├── ai-txt2img-image-to-image.html
│   │       │       ├── ai-txt2img-options.html
│   │       │       ├── ai-txt2img.html
│   │       │       ├── ai-txt2speech-elevenlabs.html
│   │       │       ├── ai-txt2speech-engines.html
│   │       │       ├── ai-txt2speech-openai.html
│   │       │       ├── ai-txt2speech-options.html
│   │       │       ├── ai-txt2speech.html
│   │       │       ├── ai-txt2vid-options.html
│   │       │       ├── ai-txt2vid.html
│   │       │       ├── ai-web-search.html
│   │       │       ├── ai-xai.html
│   │       │       ├── app-ai-chat.html
│   │       │       ├── app-camera.html
│   │       │       ├── app-create.html
│   │       │       ├── app-delete.html
│   │       │       ├── app-get.html
│   │       │       ├── app-list.html
│   │       │       ├── app-summarizer.html
│   │       │       ├── app-todo.html
│   │       │       ├── app-update.html
│   │       │       ├── auth-get-monthly-usage.html
│   │       │       ├── auth-get-user.html
│   │       │       ├── auth-is-signed-in.html
│   │       │       ├── auth-sign-in.html
│   │       │       ├── auth-sign-out.html
│   │       │       ├── fs-copy.html
│   │       │       ├── fs-delete-directory.html
│   │       │       ├── fs-delete.html
│   │       │       ├── fs-mkdir-create-missing-parents.html
│   │       │       ├── fs-mkdir-dedupe.html
│   │       │       ├── fs-mkdir.html
│   │       │       ├── fs-move-create-missing-parents.html
│   │       │       ├── fs-move.html
│   │       │       ├── fs-read.html
│   │       │       ├── fs-readdir.html
│   │       │       ├── fs-rename.html
│   │       │       ├── fs-stat.html
│   │       │       ├── fs-upload.html
│   │       │       ├── fs-write-create-missing-parents.html
│   │       │       ├── fs-write-dedupe.html
│   │       │       ├── fs-write-from-input.html
│   │       │       ├── fs-write.html
│   │       │       ├── hosting-create.html
│   │       │       ├── hosting-delete.html
│   │       │       ├── hosting-get.html
│   │       │       ├── hosting-list.html
│   │       │       ├── hosting-update.html
│   │       │       ├── intro-auth.html
│   │       │       ├── intro-chatgpt.html
│   │       │       ├── intro-fs-write.html
│   │       │       ├── intro-gpt-vision.html
│   │       │       ├── intro-hosting.html
│   │       │       ├── intro-kv-set.html
│   │       │       ├── kv-add.html
│   │       │       ├── kv-decr-nested.html
│   │       │       ├── kv-decr.html
│   │       │       ├── kv-del.html
│   │       │       ├── kv-expire.html
│   │       │       ├── kv-expireAt.html
│   │       │       ├── kv-flush.html
│   │       │       ├── kv-get.html
│   │       │       ├── kv-incr-nested.html
│   │       │       ├── kv-incr.html
│   │       │       ├── kv-list.html
│   │       │       ├── kv-name.html
│   │       │       ├── kv-remove.html
│   │       │       ├── kv-set.html
│   │       │       ├── kv-update.html
│   │       │       ├── net-basic.html
│   │       │       ├── net-fetch.html
│   │       │       ├── net-tls.html
│   │       │       ├── peer-basic.html
│   │       │       ├── perms-request-apps.html
│   │       │       ├── perms-request-desktop.html
│   │       │       ├── perms-request-documents.html
│   │       │       ├── perms-request-email.html
│   │       │       ├── perms-request-manage-apps.html
│   │       │       ├── perms-request-manage-subdomains.html
│   │       │       ├── perms-request-permission.html
│   │       │       ├── perms-request-read-apps.html
│   │       │       ├── perms-request-read-desktop.html
│   │       │       ├── perms-request-read-documents.html
│   │       │       ├── perms-request-read-pictures.html
│   │       │       ├── perms-request-read-subdomains.html
│   │       │       ├── perms-request-read-videos.html
│   │       │       ├── perms-request-write-desktop.html
│   │       │       ├── perms-request-write-documents.html
│   │       │       ├── perms-request-write-pictures.html
│   │       │       ├── perms-request-write-videos.html
│   │       │       ├── workers-create.html
│   │       │       ├── workers-delete.html
│   │       │       ├── workers-exec.html
│   │       │       ├── workers-get.html
│   │       │       ├── workers-list.html
│   │       │       └── workers-management.html
│   │       ├── playground.js
│   │       ├── printdir.sh
│   │       ├── redirects.js
│   │       ├── robots.txt
│   │       ├── security.md
│   │       ├── sidebar.js
│   │       ├── supported-platforms.md
│   │       └── user-pays-model.md
│   ├── gui/
│   │   ├── CREDITS.md
│   │   ├── build.js
│   │   ├── dev-server.js
│   │   ├── doc/
│   │   │   ├── el().md
│   │   │   ├── utils.md
│   │   │   └── webpack_attempts.md
│   │   ├── package.json
│   │   ├── puter-gui.json
│   │   ├── src/
│   │   │   ├── .gitignore
│   │   │   ├── IPC.js
│   │   │   ├── UI/
│   │   │   │   ├── Components/
│   │   │   │   │   ├── Button.js
│   │   │   │   │   ├── CodeEntryView.js
│   │   │   │   │   ├── ConfirmationsView.js
│   │   │   │   │   ├── Flexer.js
│   │   │   │   │   ├── JustHTML.js
│   │   │   │   │   ├── PasswordEntry.js
│   │   │   │   │   ├── QRCode.js
│   │   │   │   │   ├── RecoveryCodeEntryView.js
│   │   │   │   │   ├── RecoveryCodesView.js
│   │   │   │   │   ├── StepHeading.js
│   │   │   │   │   └── StepView.js
│   │   │   │   ├── Dashboard/
│   │   │   │   │   ├── ContextMenu/
│   │   │   │   │   │   └── ContextMenu.js
│   │   │   │   │   ├── TabAccount.js
│   │   │   │   │   ├── TabApps.js
│   │   │   │   │   ├── TabFiles.js
│   │   │   │   │   ├── TabHome.js
│   │   │   │   │   ├── TabSecurity.js
│   │   │   │   │   ├── TabUsage.js
│   │   │   │   │   └── UIDashboard.js
│   │   │   │   ├── PuterDialog.js
│   │   │   │   ├── Settings/
│   │   │   │   │   ├── UITabAbout.js
│   │   │   │   │   ├── UITabAccount.js
│   │   │   │   │   ├── UITabKeyboardShortcuts.js
│   │   │   │   │   ├── UITabLanguage.js
│   │   │   │   │   ├── UITabPersonalization.js
│   │   │   │   │   ├── UITabSecurity.js
│   │   │   │   │   ├── UITabUsage.js
│   │   │   │   │   ├── UIWindowChangeEmail.js
│   │   │   │   │   ├── UIWindowConfirmUserDeletion.js
│   │   │   │   │   ├── UIWindowDisable2FA.js
│   │   │   │   │   ├── UIWindowFinalizeUserDeletion.js
│   │   │   │   │   └── UIWindowSettings.js
│   │   │   │   ├── UIAlert.js
│   │   │   │   ├── UIColorPickerWidget.js
│   │   │   │   ├── UIComponentWindow.js
│   │   │   │   ├── UIContextMenu.js
│   │   │   │   ├── UIDesktop.js
│   │   │   │   ├── UIElement.js
│   │   │   │   ├── UIItem.js
│   │   │   │   ├── UINotification.js
│   │   │   │   ├── UIPopover.js
│   │   │   │   ├── UIPrompt.js
│   │   │   │   ├── UITaskbar.js
│   │   │   │   ├── UITaskbarItem.js
│   │   │   │   ├── UIWindow.js
│   │   │   │   ├── UIWindow2FASetup.js
│   │   │   │   ├── UIWindowAuthMe.js
│   │   │   │   ├── UIWindowChangePassword.js
│   │   │   │   ├── UIWindowChangeUsername.js
│   │   │   │   ├── UIWindowClaimReferral.js
│   │   │   │   ├── UIWindowColorPicker.js
│   │   │   │   ├── UIWindowCopyToken.js
│   │   │   │   ├── UIWindowDesktopBGSettings.js
│   │   │   │   ├── UIWindowEmailConfirmationRequired.js
│   │   │   │   ├── UIWindowFeedback.js
│   │   │   │   ├── UIWindowFontPicker.js
│   │   │   │   ├── UIWindowItemProperties.js
│   │   │   │   ├── UIWindowLogin.js
│   │   │   │   ├── UIWindowLoginInProgress.js
│   │   │   │   ├── UIWindowManageSessions.js
│   │   │   │   ├── UIWindowMyWebsites.js
│   │   │   │   ├── UIWindowNewPassword.js
│   │   │   │   ├── UIWindowProgress.js
│   │   │   │   ├── UIWindowPublishWebsite.js
│   │   │   │   ├── UIWindowPublishWorker.js
│   │   │   │   ├── UIWindowQR.js
│   │   │   │   ├── UIWindowRecoverPassword.js
│   │   │   │   ├── UIWindowRefer.js
│   │   │   │   ├── UIWindowRequestPermission.js
│   │   │   │   ├── UIWindowSaveAccount.js
│   │   │   │   ├── UIWindowSearch.js
│   │   │   │   ├── UIWindowSessionList.js
│   │   │   │   ├── UIWindowShare.js
│   │   │   │   ├── UIWindowSignup.js
│   │   │   │   ├── UIWindowSystemInfo.js
│   │   │   │   ├── UIWindowTaskManager.js
│   │   │   │   ├── UIWindowThemeDialog.js
│   │   │   │   └── UIWindowWelcome.js
│   │   │   ├── browserconfig.xml
│   │   │   ├── css/
│   │   │   │   ├── dashboard.css
│   │   │   │   ├── normalize.css
│   │   │   │   ├── style.css
│   │   │   │   └── theme.css
│   │   │   ├── definitions.js
│   │   │   ├── extensions/
│   │   │   │   ├── groups-manager.js
│   │   │   │   └── modify-user-options-menu.js
│   │   │   ├── favicons/
│   │   │   │   ├── browserconfig.xml
│   │   │   │   └── manifest.json
│   │   │   ├── globals.js
│   │   │   ├── helpers/
│   │   │   │   ├── check_password_strength.js
│   │   │   │   ├── content_type_to_icon.js
│   │   │   │   ├── determine_active_container_parent.js
│   │   │   │   ├── download.js
│   │   │   │   ├── fixedEncodeURIComponent.js
│   │   │   │   ├── generate_file_context_menu.js
│   │   │   │   ├── get_html_element_from_options.js
│   │   │   │   ├── globToRegExp.js
│   │   │   │   ├── item_icon.js
│   │   │   │   ├── launch_app.js
│   │   │   │   ├── new_context_menu_item.js
│   │   │   │   ├── open_item.js
│   │   │   │   ├── refresh_item_container.js
│   │   │   │   ├── socialLink.js
│   │   │   │   ├── truncate_filename.js
│   │   │   │   ├── update_last_touch_coordinates.js
│   │   │   │   ├── update_mouse_position.js
│   │   │   │   ├── update_title_based_on_uploads.js
│   │   │   │   └── update_username_in_gui.js
│   │   │   ├── helpers.js
│   │   │   ├── i18n/
│   │   │   │   ├── i18n.js
│   │   │   │   ├── i18nChangeLanguage.js
│   │   │   │   └── translations/
│   │   │   │       ├── ar.js
│   │   │   │       ├── bg.js
│   │   │   │       ├── bn.js
│   │   │   │       ├── br.js
│   │   │   │       ├── da.js
│   │   │   │       ├── de.js
│   │   │   │       ├── emoji.js
│   │   │   │       ├── en.js
│   │   │   │       ├── es.js
│   │   │   │       ├── fa.js
│   │   │   │       ├── fi.js
│   │   │   │       ├── fr.js
│   │   │   │       ├── he.js
│   │   │   │       ├── hi.js
│   │   │   │       ├── hu.js
│   │   │   │       ├── hy.js
│   │   │   │       ├── id.js
│   │   │   │       ├── ig.js
│   │   │   │       ├── it.js
│   │   │   │       ├── ja.js
│   │   │   │       ├── ko.js
│   │   │   │       ├── ku.js
│   │   │   │       ├── ml.js
│   │   │   │       ├── my.js
│   │   │   │       ├── nb.js
│   │   │   │       ├── nl.js
│   │   │   │       ├── nn.js
│   │   │   │       ├── pl.js
│   │   │   │       ├── pt.js
│   │   │   │       ├── ro.js
│   │   │   │       ├── ru.js
│   │   │   │       ├── sl.js
│   │   │   │       ├── sv.js
│   │   │   │       ├── ta.js
│   │   │   │       ├── th.js
│   │   │   │       ├── tr.js
│   │   │   │       ├── translations.js
│   │   │   │       ├── ua.js
│   │   │   │       ├── ur.js
│   │   │   │       ├── vi.js
│   │   │   │       ├── zh.js
│   │   │   │       └── zhtw.js
│   │   │   ├── index.js
│   │   │   ├── init_async.js
│   │   │   ├── init_sync.js
│   │   │   ├── initgui.js
│   │   │   ├── keyboard.js
│   │   │   ├── lib/
│   │   │   │   ├── html-entities.js
│   │   │   │   ├── jquery-ui-1.13.2/
│   │   │   │   │   ├── AUTHORS.txt
│   │   │   │   │   ├── LICENSE.txt
│   │   │   │   │   ├── external/
│   │   │   │   │   │   └── jquery/
│   │   │   │   │   │       └── jquery.js
│   │   │   │   │   ├── index.html
│   │   │   │   │   ├── jquery-ui.css
│   │   │   │   │   ├── jquery-ui.js
│   │   │   │   │   ├── jquery-ui.structure.css
│   │   │   │   │   ├── jquery-ui.theme.css
│   │   │   │   │   └── package.json
│   │   │   │   ├── jquery.dragster.js
│   │   │   │   ├── mime.js
│   │   │   │   ├── path.js
│   │   │   │   └── socket.io/
│   │   │   │       └── socket.io.js
│   │   │   ├── manifest.json
│   │   │   ├── security.txt
│   │   │   ├── services/
│   │   │   │   ├── AntiCSRFService.js
│   │   │   │   ├── BroadcastService.js
│   │   │   │   ├── DebugService.js
│   │   │   │   ├── ExecService.js
│   │   │   │   ├── ExportRegistrantService.js
│   │   │   │   ├── IPCService.js
│   │   │   │   ├── LaunchOnInitService.js
│   │   │   │   ├── LocaleService.js
│   │   │   │   ├── ProcessService.js
│   │   │   │   ├── SettingsService.js
│   │   │   │   └── ThemeService.js
│   │   │   ├── static-assets.js
│   │   │   └── util/
│   │   │       ├── Collector.js
│   │   │       ├── Component.js
│   │   │       ├── Placeholder.js
│   │   │       ├── TeePromise.js
│   │   │       ├── ValueHolder.js
│   │   │       ├── desktop.js
│   │   │       └── openid.js
│   │   ├── utils.js
│   │   ├── webpack/
│   │   │   ├── BaseConfig.cjs
│   │   │   ├── EmitPlugin.cjs
│   │   │   └── libPaths.cjs
│   │   └── webpack.config.cjs
│   ├── puter-js/
│   │   ├── .gitignore
│   │   ├── APACHE_LICENSE.txt
│   │   ├── README.md
│   │   ├── index.d.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.js
│   │   │   ├── init.cjs
│   │   │   ├── init.d.cts
│   │   │   ├── lib/
│   │   │   │   ├── APICallLogger.js
│   │   │   │   ├── EventListener.js
│   │   │   │   ├── RequestError.js
│   │   │   │   ├── path.js
│   │   │   │   ├── polyfills/
│   │   │   │   │   ├── fileReaderPoly.js
│   │   │   │   │   ├── localStorage.js
│   │   │   │   │   └── xhrshim.js
│   │   │   │   ├── socket.io/
│   │   │   │   │   └── socket.io.js
│   │   │   │   ├── utils.js
│   │   │   │   └── xdrpc.js
│   │   │   └── modules/
│   │   │       ├── AI.js
│   │   │       ├── Apps.js
│   │   │       ├── Auth.js
│   │   │       ├── Debug.js
│   │   │       ├── Drivers.js
│   │   │       ├── EmailConfirmationDialog.js
│   │   │       ├── FSItem.js
│   │   │       ├── FileSystem/
│   │   │       │   ├── Batch.js
│   │   │       │   ├── index.js
│   │   │       │   ├── operations/
│   │   │       │   │   ├── copy.js
│   │   │       │   │   ├── deleteFSEntry.js
│   │   │       │   │   ├── getReadUrl.js
│   │   │       │   │   ├── mkdir.js
│   │   │       │   │   ├── move.js
│   │   │       │   │   ├── read.js
│   │   │       │   │   ├── readdir.js
│   │   │       │   │   ├── readdirSubdomains.js
│   │   │       │   │   ├── rename.js
│   │   │       │   │   ├── revokeReadUrl.js
│   │   │       │   │   ├── sign.js
│   │   │       │   │   ├── space.js
│   │   │       │   │   ├── stat.js
│   │   │       │   │   ├── symlink.js
│   │   │       │   │   ├── upload.js
│   │   │       │   │   └── write.js
│   │   │       │   └── utils/
│   │   │       │       └── getAbsolutePathForApp.js
│   │   │       ├── Hosting.js
│   │   │       ├── KV.js
│   │   │       ├── OS.js
│   │   │       ├── Peer.js
│   │   │       ├── Perms.js
│   │   │       ├── PuterDialog.js
│   │   │       ├── UI.js
│   │   │       ├── UsageLimitDialog.js
│   │   │       ├── Util.js
│   │   │       ├── Workers.js
│   │   │       └── networking/
│   │   │           ├── PSocket.js
│   │   │           ├── PTLS.js
│   │   │           ├── PWispHandler.js
│   │   │           ├── parsers.js
│   │   │           └── requests.js
│   │   ├── test/
│   │   │   ├── ai.test.js
│   │   │   ├── fs.test.js
│   │   │   ├── index.html
│   │   │   ├── kv.test.js
│   │   │   └── txt2speech.test.js
│   │   ├── types/
│   │   │   ├── modules/
│   │   │   │   ├── ai.d.ts
│   │   │   │   ├── apps.d.ts
│   │   │   │   ├── auth.d.ts
│   │   │   │   ├── debug.d.ts
│   │   │   │   ├── drivers.d.ts
│   │   │   │   ├── filesystem.d.ts
│   │   │   │   ├── fs-item.d.ts
│   │   │   │   ├── hosting.d.ts
│   │   │   │   ├── kv.d.ts
│   │   │   │   ├── networking.d.ts
│   │   │   │   ├── os.d.ts
│   │   │   │   ├── peer.d.ts
│   │   │   │   ├── perms.d.ts
│   │   │   │   ├── ui.d.ts
│   │   │   │   ├── util.d.ts
│   │   │   │   └── workers.d.ts
│   │   │   ├── puter.d.ts
│   │   │   └── shared.d.ts
│   │   └── webpack.config.js
│   ├── puter-wisp/
│   │   ├── README.md
│   │   ├── basic.html
│   │   ├── devlog/
│   │   │   └── unit_test_usefulness/
│   │   │       ├── a.js
│   │   │       ├── b.js
│   │   │       └── test_a_b.diff
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── exports.js
│   │   └── test/
│   │       └── test.js
│   ├── putility/
│   │   ├── README.md
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── AdvancedBase.js
│   │   │   ├── bases/
│   │   │   │   ├── BasicBase.js
│   │   │   │   └── FeatureBase.js
│   │   │   ├── concepts/
│   │   │   │   └── Service.js
│   │   │   ├── features/
│   │   │   │   ├── EmitterFeature.js
│   │   │   │   ├── NodeModuleDIFeature.js
│   │   │   │   ├── PropertiesFeature.js
│   │   │   │   ├── ServiceFeature.js
│   │   │   │   ├── TopicsFeature.js
│   │   │   │   └── TraitsFeature.js
│   │   │   ├── libs/
│   │   │   │   ├── context.js
│   │   │   │   ├── event.js
│   │   │   │   ├── invoker.js
│   │   │   │   ├── listener.js
│   │   │   │   ├── log.js
│   │   │   │   ├── promise.js
│   │   │   │   └── string.js
│   │   │   ├── system/
│   │   │   │   └── ServiceManager.js
│   │   │   └── traits/
│   │   │       └── traits.js
│   │   └── test/
│   │       ├── ServiceManager.test.js
│   │       ├── context.test.js
│   │       ├── event.test.js
│   │       ├── listener.test.js
│   │       ├── log.test.js
│   │       ├── test.js
│   │       ├── topics.test.js
│   │       └── traits.test.js
│   └── useapi/
│       ├── main.js
│       └── package.json
├── tests/
│   ├── README.md
│   ├── api-tester/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── apitest.js
│   │   ├── benches/
│   │   │   ├── __entry__.js
│   │   │   ├── simple.js
│   │   │   ├── stat_intensive_1.js
│   │   │   └── write_intensive_1.js
│   │   ├── coverage_models/
│   │   │   ├── copy.js
│   │   │   ├── move.js
│   │   │   └── write.js
│   │   ├── doc/
│   │   │   └── cartesian.md
│   │   ├── lib/
│   │   │   ├── Assert.js
│   │   │   ├── CoverageModel.js
│   │   │   ├── ReportGenerator.js
│   │   │   ├── TestFactory.js
│   │   │   ├── TestRegistry.js
│   │   │   ├── TestSDK.js
│   │   │   ├── log_error.js
│   │   │   └── sleep.js
│   │   ├── package.json
│   │   ├── puter_js/
│   │   │   ├── __entry__.js
│   │   │   ├── auth/
│   │   │   │   ├── __entry__.js
│   │   │   │   └── whoami.js
│   │   │   └── load.cjs
│   │   ├── test_sdks/
│   │   │   └── puter-rest.js
│   │   ├── tests/
│   │   │   ├── __entry__.js
│   │   │   ├── auth.js
│   │   │   ├── batch.js
│   │   │   ├── copy_cart.js
│   │   │   ├── delete.js
│   │   │   ├── fsentry.js
│   │   │   ├── mkdir.js
│   │   │   ├── move.js
│   │   │   ├── move_cart.js
│   │   │   ├── readdir.js
│   │   │   ├── stat.js
│   │   │   ├── telem_write.js
│   │   │   ├── write_and_read.js
│   │   │   └── write_cart.js
│   │   ├── tools/
│   │   │   ├── readdir_profile.js
│   │   │   └── test_read.js
│   │   └── toxiproxy/
│   │       ├── toxiproxy.json
│   │       └── toxiproxy_control.json
│   ├── ci/
│   │   ├── api-test.py
│   │   ├── common.py
│   │   ├── playwright-test.py
│   │   ├── requirements.txt
│   │   └── vitest.py
│   ├── example-client-config.yaml
│   ├── playwright/
│   │   ├── .github/
│   │   │   └── workflows/
│   │   │       └── playwright.yml
│   │   ├── .gitignore
│   │   ├── config/
│   │   │   └── test-config.ts
│   │   ├── package.json
│   │   ├── playwright.config.ts
│   │   └── tests/
│   │       ├── file-system/
│   │       │   ├── batch.spec.ts
│   │       │   ├── copy_cart.spec.ts
│   │       │   ├── delete.spec.ts
│   │       │   ├── fixtures.ts
│   │       │   ├── mkdir.spec.ts
│   │       │   ├── move.spec.ts
│   │       │   ├── move_cart.spec.ts
│   │       │   ├── readdir.spec.ts
│   │       │   ├── stat.spec.ts
│   │       │   ├── write_and_read.spec.ts
│   │       │   └── write_cart.spec.ts
│   │       └── whoami.spec.ts
│   ├── puterJsApiTests/
│   │   ├── ai_chat_completions.test.ts
│   │   ├── kv.test.ts
│   │   ├── testUtils.ts
│   │   └── vite.config.ts
│   └── tsconfig.json
├── tools/
│   ├── .commit
│   ├── README.md
│   ├── auth_gui.js
│   ├── build_relay.sh
│   ├── build_v86.sh
│   ├── check-translations.js
│   ├── comment-parser/
│   │   ├── main.js
│   │   ├── package.json
│   │   └── test/
│   │       └── test.js
│   ├── doc_helper.js
│   ├── file-walker/
│   │   ├── package.json
│   │   └── test.js
│   ├── gen-release-notes.js
│   ├── genwiki/
│   │   ├── main.js
│   │   └── package.json
│   ├── keygen/
│   │   ├── gen-peer-keys.js
│   │   └── package.json
│   ├── l_checker_config.json
│   ├── license-headers/
│   │   ├── main.js
│   │   └── package.json
│   ├── migrations-test/
│   │   ├── main.js
│   │   ├── noop.puter.json
│   │   └── package.json
│   ├── module-docgen/
│   │   ├── defs.js
│   │   ├── main.js
│   │   ├── package.json
│   │   └── processors.js
│   ├── run-selfhosted.js
│   ├── token-count-accuracy/
│   │   ├── package.json
│   │   └── test.js
│   └── validate-eslint.js
├── tsconfig.base.json
├── tsconfig.build.json
├── tsconfig.json
├── volatile/
│   ├── README.md
│   ├── config/
│   │   └── .gitignore
│   └── runtime/
│       └── .gitignore
└── ws-debug.mjs
Download .txt
Showing preview only (360K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4551 symbols across 679 files)

FILE: doc/contributors/extensions/gen.js
  constant N_START (line 9) | const N_START = 3;

FILE: doc/self-hosters/gen.js
  constant N_START (line 9) | const N_START = 3;

FILE: eslint/bang-space-if.js
  method create (line 16) | create (context) {

FILE: eslint/control-structure-spacing.js
  method create (line 18) | create (context) {

FILE: eslint/space-unary-ops-with-exception.js
  function unwrapParens (line 9) | function unwrapParens (node) {
  function isTopLevelBangInIfTest (line 15) | function isTopLevelBangInIfTest (node) {

FILE: extensions/api.d.ts
  type Request (line 20) | interface Request {
  type EndpointOptions (line 36) | interface EndpointOptions {
  type ParameterDefinition (line 48) | interface ParameterDefinition {
  type MethodDefinition (line 52) | interface MethodDefinition {
  type DriverInterface (line 56) | interface DriverInterface {
  type HttpMethod (line 61) | type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch';
  type ExtensionRequestHandler (line 63) | type ExtensionRequestHandler = RequestHandler<
  type ExtensionRequest (line 68) | type ExtensionRequest = Parameters<ExtensionRequestHandler>[0];
  type ExtensionResponse (line 69) | type ExtensionResponse = Parameters<ExtensionRequestHandler>[1];
  type ExtensionNextFunction (line 70) | type ExtensionNextFunction = Parameters<ExtensionRequestHandler>[2];
  type AddRouteFunction (line 72) | type AddRouteFunction = (
  type RouterMethods (line 78) | type RouterMethods = {
  type CoreRuntimeModule (line 85) | interface CoreRuntimeModule {
  type FilesystemModule (line 95) | interface FilesystemModule {
  type ExtensionEventTypeMap (line 100) | interface ExtensionEventTypeMap {
  type Extension (line 178) | interface Extension extends RouterMethods {

FILE: extensions/app-telemetry/app-user-count.ts
  constant DEFAULT_LIMIT (line 7) | const DEFAULT_LIMIT = 100;
  constant MAX_LIMIT (line 8) | const MAX_LIMIT = 1000;
  constant MAX_OFFSET (line 9) | const MAX_OFFSET = 100_000;
  method get_users (line 83) | async get_users ({ app_uuid, limit, offset }: { app_uuid: string, limit?...
  method user_count (line 115) | async user_count ({ app_uuid }: { app_uuid: string }) {

FILE: extensions/extensionController/src/ExtensionController.ts
  type RouteMeta (line 30) | interface RouteMeta {
  class HttpError (line 89) | class HttpError extends Error {
    method constructor (line 91) | constructor (statusCode: StatusCodes, message: string, cause?: unknown) {
  class ExtensionController (line 98) | class ExtensionController {
    method registerRoutes (line 101) | registerRoutes () {

FILE: extensions/hellodriver/hellodriver.js
  method greet (line 63) | greet ({ subject }) {
  method greet (line 84) | greet ({ subject }) {

FILE: extensions/metering/controllers/UsageController.ts
  class UsageController (line 12) | class UsageController extends ExtensionController {
    method constructor (line 16) | constructor (
    method getUsage (line 26) | async getUsage (req: ExtensionRequest, res: ExtensionResponse) {
    method getUsageByApp (line 43) | async getUsageByApp (req: ExtensionRequest, res: ExtensionResponse) {
    method getGlobalUsage (line 86) | async getGlobalUsage (req: ExtensionRequest, res: ExtensionResponse) {

FILE: extensions/puterfs/PuterFSProvider.js
  constant STUCK_STATUS_TIMEOUT (line 20) | const STUCK_STATUS_TIMEOUT = 10 * 1000;
  constant STUCK_ALARM_TIMEOUT (line 21) | const STUCK_ALARM_TIMEOUT = 20 * 1000;
  constant MAX_DIRECTORY_DEPTH (line 24) | const MAX_DIRECTORY_DEPTH = 35;
  class PuterFSProvider (line 101) | class PuterFSProvider {
    method constructor (line 102) | constructor ({ fsEntryController, storageController }) {
    method #pathDepth (line 114) | #pathDepth (path) {
    method #getSourceTreeMaxRelativeDepth (line 125) | async #getSourceTreeMaxRelativeDepth (node) {
    method #assertDepthLimitForTreeOp (line 143) | async #assertDepthLimitForTreeOp (destinationPathDepth, sourceNode) {
    method get_capabilities (line 156) | get_capabilities () {
    method update_thumbnail (line 178) | async update_thumbnail ({ context, node, thumbnail }) {
    method puter_shortcut (line 213) | async puter_shortcut ({ parent, name, user, target }) {
    method readdirstat_uuid (line 266) | async readdirstat_uuid ({
    method quick_check (line 291) | async quick_check ({
    method unlink (line 321) | async unlink ({ context, node, options = {} }) {
    method rmdir (line 329) | async rmdir ({ context, node, options = {} }) {
    method mkdir (line 357) | async mkdir ({ context, parent, name, immutable }) {
    method read (line 420) | async read ({ context, node, version_id, range }) {
    method stat (line 436) | async stat ({
    method copy_tree (line 521) | async copy_tree ({ context, source, parent, target_name }) {
    method move (line 660) | async move ({ context, node, new_parent, new_name, metadata }) {
    method readdir (line 703) | async readdir ({ node }) {
    method directory_has_name (line 709) | async directory_has_name ({ parent, name }) {
    method write_new (line 731) | async write_new ({ context, parent, name, file }) {
    method write_overwrite (line 846) | async write_overwrite ({ context, node, file }) {
    method get_recursive_size (line 928) | async get_recursive_size ({ node }) {
    method #storage_upload (line 958) | async #storage_upload ({
    method #rmnode (line 1054) | async #rmnode ({ node, options }) {

FILE: extensions/puterfs/fsentries/BaseOperation.js
  class BaseOperation (line 3) | class BaseOperation {
    method constructor (line 11) | constructor () {
    method status (line 15) | get status () {
    method status (line 18) | set status (status) {
    method awaitDone (line 24) | async awaitDone () {
    method onComplete (line 27) | async onComplete (fn) {

FILE: extensions/puterfs/fsentries/Delete.js
  method constructor (line 4) | constructor (uuid) {
  method getStatement (line 9) | getStatement () {
  method apply (line 15) | apply (answer) {

FILE: extensions/puterfs/fsentries/FSEntryController.js
  class FSEntryController (line 20) | class FSEntryController {
    method constructor (line 26) | constructor () {
    method init (line 79) | init () {
    method mkPromiseForQueueSize_ (line 90) | mkPromiseForQueueSize_ () {
    method insert (line 97) | async insert (entry) {
    method update (line 103) | async update (uuid, entry) {
    method delete (line 109) | async delete (uuid) {
    method fast_get_descendants (line 117) | async fast_get_descendants (uuid) {
    method fast_get_direct_descendants (line 134) | async fast_get_direct_descendants (uuid) {
    method waitForEntry (line 143) | waitForEntry (node, callback) {
    method get (line 182) | async get (uuid, fetch_entry_options) {
    method get_descendants (line 209) | async get_descendants (uuid) {
    method get_descendants_full (line 228) | async get_descendants_full (uuid, fetch_entry_options) {
    method get_recursive_size (line 270) | async get_recursive_size (uuid) {
    method find (line 296) | async find (selector, fetch_entry_options) {
    method findByUID (line 338) | async findByUID (uuid, fetch_entry_options = {}) {
    method findByID (line 358) | async findByID (id, fetch_entry_options = {}) {
    method findByPath (line 378) | async findByPath (path, fetch_entry_options = {}) {
    method findNameInRoot (line 455) | async findNameInRoot (name) {
    method findNameInParent (line 469) | async findNameInParent (parent_uid, name) {
    method nameExistsUnderParent (line 483) | async nameExistsUnderParent (parent_uid, name) {
    method nameExistsUnderParentID (line 497) | async nameExistsUnderParentID (parent_id, name) {
    method enqueue_ (line 507) | async enqueue_ (op) {
    method checkShouldExec_ (line 545) | checkShouldExec_ () {
    method exec_ (line 551) | async exec_ () {
    method flipState_ (line 599) | flipState_ () {

FILE: extensions/puterfs/fsentries/Insert.js
  method constructor (line 32) | constructor (entry) {
  method getStatement (line 56) | getStatement () {
  method apply (line 65) | apply (answer) {
  method uuid (line 69) | get uuid () {

FILE: extensions/puterfs/fsentries/Update.js
  method constructor (line 17) | constructor (uuid, entry) {
  method getStatement (line 35) | getStatement () {
  method apply (line 45) | apply (answer) {

FILE: extensions/puterfs/main.js
  method createStorageStrategy (line 41) | createStorageStrategy (name, implementation) {
  method mount (line 69) | mount ({ path }) {

FILE: extensions/puterfs/storage/LocalDiskStorageController.js
  class LocalDiskStorageController (line 10) | class LocalDiskStorageController {
    method constructor (line 11) | constructor () {
    method init (line 15) | async init () {
    method upload (line 19) | async upload ({ uid, file, storage_api }) {
    method copy (line 55) | copy () {
    method delete (line 57) | delete () {
    method read (line 59) | read () {
    method #getPath (line 62) | #getPath (key) {

FILE: extensions/puterfs/storage/ProxyStorageController.js
  method constructor (line 2) | constructor (delegate) {
  method setDelegate (line 5) | setDelegate (delegate) {
  method init (line 9) | init (...a) {
  method upload (line 12) | upload (...a) {
  method copy (line 15) | copy (...a) {
  method delete (line 18) | delete (...a) {
  method read (line 21) | read (...a) {

FILE: extensions/serverInfo/index.ts
  class ServerInfoController (line 10) | @Controller('/serverInfo', [...config.allowedUsernames])
    method getServerInfo (line 13) | async getServerInfo (_req: ExtensionRequest, res: ExtensionResponse) {

FILE: mods/mods_available/dev-socket/main.js
  constant SOCKET_NAME (line 24) | const SOCKET_NAME = 'dev.sock';
  constant WELCOME (line 25) | const WELCOME = [
  function getSocketDir (line 31) | function getSocketDir () {

FILE: mods/mods_available/kdmod/CustomPuterService.js
  class CustomPuterService (line 21) | class CustomPuterService extends use.Service {
    method _init (line 22) | async _init () {
    method _register_commands (line 59) | _register_commands (commands) {
  method ['__on_install.routes'] (line 29) | ['__on_install.routes'] (_, { app }) {
  method ['__on_boot.consolidation'] (line 37) | async ['__on_boot.consolidation'] () {

FILE: mods/mods_available/kdmod/ShareTestService.js
  class ShareTestService (line 39) | class ShareTestService extends use.Service {
    method _init (line 44) | async _init () {
    method _register_commands (line 54) | _register_commands (commands) {
    method runit (line 77) | async runit () {
    method setup_ (line 97) | async setup_ () {
    method run_scenario_ (line 103) | async run_scenario_ (scenario) {
    method teardown_ (line 122) | async teardown_ () {
    method create_test_user_ (line 129) | async create_test_user_ (username) {
    method delete_test_user_ (line 148) | async delete_test_user_ (username) {
    method ['__scenario:create-example-file'] (line 155) | async ['__scenario:create-example-file'] (
    method ['__scenario:assert-no-access'] (line 181) | async ['__scenario:assert-no-access'] (
    method ['__scenario:grant'] (line 200) | async ['__scenario:grant'] (
    method ['__scenario:assert-access'] (line 207) | async ['__scenario:assert-access'] (

FILE: mods/mods_available/test-actions/main.js
  constant ACTIONS (line 10) | const ACTIONS = [
  constant INVOKE_HANDLERS (line 22) | const INVOKE_HANDLERS = {

FILE: src/backend/src/CoreModule.js
  class CoreModule (line 411) | class CoreModule extends AdvancedBase {
    method dirname (line 412) | dirname () {
    method install (line 415) | async install (context) {
    method install_legacy (line 433) | async install_legacy (context) {

FILE: src/backend/src/DatabaseModule.js
  class DatabaseModule (line 21) | class DatabaseModule extends AdvancedBase {
    method install (line 22) | async install (context) {

FILE: src/backend/src/Extension.js
  class Extension (line 53) | class Extension extends AdvancedBase {
    method constructor (line 64) | constructor (...a) {
    method randomBrightColor (line 107) | randomBrightColor () {
    method example (line 121) | example () {
    method exports (line 126) | set exports (value) {
    method exports (line 129) | get exports () {
    method import (line 132) | import (name) {
    method db (line 140) | get db () {
    method services (line 149) | get services () {
    method log_context (line 158) | get log_context () {
    method errors (line 167) | get errors () {
    method register (line 179) | register (typeKey, keyOrData, data) {
    method reg (line 215) | reg (...a) {
    method get (line 225) | get (path, handler, options) {
    method post (line 247) | post (path, handler, options) {
    method put (line 269) | put (path, handler, options) {
    method delete (line 291) | delete (path, handler, options) {
    method use (line 307) | use (...args) {
    method preinit (line 315) | get preinit () {
    method preinit (line 320) | set preinit (callback) {
    method init (line 333) | get init () {
    method init (line 338) | set init (callback) {
    method console (line 351) | get console () {
    method tracer (line 385) | get tracer () {
    method span (line 390) | get span () {
    method ensure_service_ (line 415) | ensure_service_ () {

FILE: src/backend/src/ExtensionModule.js
  class ExtensionModule (line 24) | class ExtensionModule extends AdvancedBase {
    method install (line 25) | async install (context) {

FILE: src/backend/src/ExtensionService.js
  class ExtensionServiceState (line 33) | class ExtensionServiceState extends AdvancedBase {
    method constructor (line 34) | constructor (...a) {
    method register_route_handler_ (line 44) | register_route_handler_ (path, handler, options = {}) {
  class ExtensionService (line 79) | class ExtensionService extends BaseService {
    method _construct (line 80) | _construct () {
    method _init (line 83) | async _init (args) {
  method '__on_boot.consolidation' (line 157) | async '__on_boot.consolidation' () {
  method '__on_boot.activation' (line 165) | async '__on_boot.activation' () {
  method '__on_boot.ready' (line 173) | async '__on_boot.ready' () {
  method '__on_install.routes' (line 182) | '__on_install.routes' (_, { app }) {

FILE: src/backend/src/Kernel.js
  class Kernel (line 40) | class Kernel extends AdvancedBase {
    method constructor (line 41) | constructor ({ entry_path } = {}) {
    method add_module (line 60) | add_module (module) {
    method _runtime_init (line 64) | _runtime_init (boot_parameters) {
    method boot (line 88) | boot () {
    method _install_modules (line 143) | async _install_modules () {
    method _boot_services (line 203) | async _boot_services () {
    method install_extern_mods_ (line 234) | async install_extern_mods_ () {
    method install_extern_mod_ (line 311) | async install_extern_mod_ ({
    method _run_extern_mod (line 453) | async _run_extern_mod (mod_entry) {
    method _create_mod_context (line 513) | _create_mod_context (parent, options) {
    method create_mod_package_json (line 553) | async create_mod_package_json (mod_path, { name, entry }) {
    method run_npm_install (line 591) | async run_npm_install (path) {

FILE: src/backend/src/LocalDiskStorageModule.js
  class LocalDiskStorageModule (line 21) | class LocalDiskStorageModule extends AdvancedBase {
    method install (line 22) | async install (context) {

FILE: src/backend/src/MemoryStorageModule.js
  class MemoryStorageModule (line 19) | class MemoryStorageModule {
    method install (line 20) | async install (context) {

FILE: src/backend/src/annotatedobjects.js
  class AnnotatedObject (line 9) | class AnnotatedObject {
    method constructor (line 10) | constructor (o) {
  class object_returned_by_get_app (line 15) | class object_returned_by_get_app extends AnnotatedObject {

FILE: src/backend/src/api/APIError.js
  class APIError (line 29) | class APIError {
    method create (line 601) | static create (status, source = {}, fields = {}) {
    method adapt (line 639) | static adapt (err) {
    method constructor (line 644) | constructor (status, message, source, fields = {}) {
    method write (line 656) | write (res) {
    method serialize (line 665) | serialize () {
    method querystringize (line 674) | querystringize (extra) {
    method querystringize_ (line 678) | querystringize_ (extra) {
    method message (line 692) | get message () {
    method toString (line 699) | toString () {

FILE: src/backend/src/api/PathOrUIDValidator.js
  method validate (line 36) | static validate (req) {

FILE: src/backend/src/api/filesystem/FSNodeParam.js
  class FSNodeParam (line 25) | class FSNodeParam {
    method constructor (line 26) | constructor (srckey, options) {
    method consolidate (line 32) | async consolidate ({ req, getParam }) {

FILE: src/backend/src/api/filesystem/FlagParam.js
  method constructor (line 22) | constructor (srckey, options) {
  method consolidate (line 29) | async consolidate ({ req, getParam }) {

FILE: src/backend/src/api/filesystem/StringParam.js
  method constructor (line 22) | constructor (srckey, options) {
  method consolidate (line 28) | async consolidate ({ req, getParam }) {

FILE: src/backend/src/api/filesystem/UserParam.js
  method consolidate (line 20) | consolidate ({ req }) {

FILE: src/backend/src/boot/BootLogger.js
  class BootLogger (line 19) | class BootLogger {
    method info (line 20) | info (...args) {
    method debug (line 24) | debug (...args) {
    method error (line 28) | error (...args) {
    method warn (line 32) | warn (...args) {

FILE: src/backend/src/boot/RuntimeEnvironment.js
  method path (line 105) | get path () {
  method path (line 117) | get path () {
  method path (line 123) | get path () {
  method path (line 140) | get path () {
  method path (line 155) | get path () {
  method path (line 161) | get path () {
  method path (line 172) | get path () {
  method path (line 187) | get path () {
  class RuntimeEnvironment (line 194) | class RuntimeEnvironment extends AdvancedBase {
    method constructor (line 202) | constructor ({ logger, entry_path, boot_parameters }) {
    method init (line 213) | init () {
    method init_ (line 223) | init_ () {
    method get_first_suitable_path_ (line 341) | get_first_suitable_path_ (meta, paths, last_checks) {

FILE: src/backend/src/clients/dynamodb/DDBClient.ts
  type DBClientConfig (line 8) | interface DBClientConfig {
  constant LOCAL_DYNAMO_PATH_KEY (line 18) | const LOCAL_DYNAMO_PATH_KEY = ':memory:';
  class DDBClient (line 55) | class DDBClient {
    method constructor (line 60) | constructor (config?: DBClientConfig) {
    method recreateClient (line 71) | async recreateClient () {
    method #getClient (line 79) | async #getClient () {
    method get (line 121) | async get <T extends Record<string, unknown>>(table: string, key: T, c...
    method put (line 134) | async put <T extends Record<string, unknown>>(table: string, item: T) {
    method batchGet (line 145) | async batchGet (params: { table: string, items: Record<string, unknown...
    method del (line 173) | async del<T extends Record<string, unknown>> (table: string, key: T) {
    method query (line 183) | async query<T extends Record<string, unknown>> (
    method update (line 228) | async update<T extends Record<string, unknown>> (
    method createTableIfNotExists (line 254) | async createTableIfNotExists (params: CreateTableCommandInput, ttlAttr...

FILE: src/backend/src/clients/dynamodb/DDBClientWrapper.ts
  class DDBClientServiceWrapper (line 5) | class DDBClientServiceWrapper extends BaseService {
    method _construct (line 7) | async _construct () {

FILE: src/backend/src/clients/redis/cacheUpdate.ts
  type CacheKeyInput (line 24) | type CacheKeyInput = string | number | null | undefined | CacheKeyInput[];
  type CacheUpdateOptions (line 25) | interface CacheUpdateOptions {
  constant SERVICES_KEY (line 30) | const SERVICES_KEY = Symbol.for('puter.helpers.services');

FILE: src/backend/src/clients/redis/deleteRedisKeys.ts
  type DeleteRedisKeysInput (line 22) | type DeleteRedisKeysInput = string | number | null | undefined | DeleteR...
  type DeleteRedisKeysOptions (line 23) | interface DeleteRedisKeysOptions {

FILE: src/backend/src/clients/redis/redisSingleton.test.ts
  class RedisClusterMock (line 17) | class RedisClusterMock {
    method constructor (line 21) | constructor (...args: unknown[]) {
  class MockRedisClusterMock (line 35) | class MockRedisClusterMock {
    method constructor (line 36) | constructor (...args: unknown[]) {

FILE: src/backend/src/codex/CodeUtil.js
  class CodeUtil (line 19) | class CodeUtil {
    method mrwrap (line 32) | static mrwrap (method, wrapper, options = {}) {

FILE: src/backend/src/codex/Sequence.js
  class Sequence (line 108) | class Sequence {
    method constructor (line 119) | constructor (sequence, thisArg) {
    method steps (line 141) | get steps () {
    method run (line 150) | async run (values) {
    method get (line 233) | get (k) {
    method set (line 243) | set (k, v) {
    method values (line 253) | values (opt_itemsToSet) {
    method iget (line 276) | iget (k) {
    method icall (line 288) | icall (k, ...args) {
    method idcall (line 300) | idcall (k, ...args) {
    method log (line 308) | get log () {
    method stop (line 317) | stop (return_value) {
    method constructor (line 336) | constructor (...args) {

FILE: src/backend/src/config.d.ts
  type ConfigRecord (line 3) | type ConfigRecord = RecursiveRecord<any>;
  type IConfig (line 5) | interface IConfig extends ConfigRecord {

FILE: src/backend/src/config/ConfigLoader.js
  class ConfigLoader (line 22) | class ConfigLoader extends AdvancedBase {
    method constructor (line 28) | constructor (logger, path, config) {
    method enable (line 35) | enable (name, meta = {}) {
    method apply_requires (line 56) | apply_requires (dir, config_list, { by } = {}) {

FILE: src/backend/src/consts/app-icons.js
  constant APP_ICONS_SUBDOMAIN (line 1) | const APP_ICONS_SUBDOMAIN = 'puter-app-icons';

FILE: src/backend/src/entities/Group.js
  method members (line 24) | async members () {
  method get_client_value (line 31) | async get_client_value (options = {}) {

FILE: src/backend/src/errors/TechnicalError.js
  class TechnicalError (line 28) | class TechnicalError extends Error {
    method constructor (line 29) | constructor (message, ...details) {

FILE: src/backend/src/errors/error_help_details.js
  method apply (line 50) | apply (more) {
  method apply (line 60) | apply (more) {
  method apply (line 81) | apply (more) {
  method apply (line 93) | apply (more) {
  method apply (line 104) | apply (more) {
  method apply (line 119) | apply (more) {
  method apply (line 133) | apply (more) {

FILE: src/backend/src/extension/RuntimeModule.js
  class RuntimeModule (line 3) | class RuntimeModule extends AdvancedBase {
    method constructor (line 4) | constructor (options = {}) {
    method exports (line 12) | set exports (value) {
    method exports (line 16) | get exports () {
    method import (line 22) | import (name) {

FILE: src/backend/src/extension/RuntimeModuleRegistry.js
  class RuntimeModuleRegistry (line 4) | class RuntimeModuleRegistry extends AdvancedBase {
    method constructor (line 5) | constructor () {
    method register (line 10) | register (extensionModule, options = {}) {
    method exportsOf (line 23) | exportsOf (name) {

FILE: src/backend/src/filesystem/ECMAP.js
  constant LOG_PREFIX (line 4) | const LOG_PREFIX = '\x1B[31;1m[[\x1B[33;1mEC\x1B[32;1mMAP\x1B[31;1m]]\x1...
  class ECMAP (line 15) | class ECMAP {
    method constructor (line 18) | constructor () {
    method unlink (line 37) | unlink () {
    method logPrefix (line 46) | get logPrefix () {
    method log (line 50) | log (...a) {
    method get_fsNodeContext_from_selector (line 55) | get_fsNodeContext_from_selector (selector) {
    method store_fsNodeContext_to_selector (line 88) | store_fsNodeContext_to_selector (selector, node) {
    method store_fsNodeContext (line 103) | store_fsNodeContext (node) {
    method arun (line 109) | static async arun (cb) {

FILE: src/backend/src/filesystem/FSNodeContext.js
  constant TYPE_FILE (line 52) | const TYPE_FILE = { label: 'File' };
  constant TYPE_DIRECTORY (line 53) | const TYPE_DIRECTORY = { label: 'Directory' };
  method constructor (line 82) | constructor ({
  method selector (line 156) | set selector (new_selector) {
  method selector (line 171) | get selector () {
  method get_selector_of_type (line 175) | get_selector_of_type (cls) {
  method get_optimal_selector (line 191) | get_optimal_selector () {
  method isRoot (line 200) | get isRoot () {
  method isUserDirectory (line 204) | async isUserDirectory () {
  method isAppDataDirectory (line 214) | async isAppDataDirectory () {
  method isPublic (line 226) | async isPublic () {
  method getPathComponents (line 234) | async getPathComponents () {
  method getUserPart (line 254) | async getUserPart () {
  method getPathSize (line 260) | async getPathSize () {
  method exists (line 266) | async exists ({ fetch_options } = {}) {
  method fetchPath (line 280) | async fetchPath () {
  method #resolvePathFromUuid (line 291) | async #resolvePathFromUuid (uuid) {
  method fetchEntry (line 310) | async fetchEntry (fetch_entry_options = {}) {
  method awaitStableEntry (line 388) | async awaitStableEntry () {
  method fetchSubdomains (line 401) | async fetchSubdomains (user, _force) {
  method applySingleSubdomain (line 418) | applySingleSubdomain (sd) {
  method fetchOwner (line 440) | async fetchOwner (_force) {
  method fetchShares (line 455) | async fetchShares (force) {
  method fetchVersions (line 540) | async fetchVersions (force) {
  method fetchSize (line 569) | async fetchSize () {
  method fetchSuggestedApps (line 582) | async fetchSuggestedApps (user, force) {
  method fetchIsEmpty (line 592) | async fetchIsEmpty () {
  method fetchAll (line 600) | async fetchAll (_fsEntryFetcher, user, _force) {
  method get (line 611) | async get (key, force) {
  method getParent (line 741) | async getParent () {
  method getChild (line 770) | async getChild (name) {
  method hasChild (line 783) | async hasChild (name) {
  method getTarget (line 787) | async getTarget () {
  method is_above (line 804) | async is_above (child_fsNode) {
  method is (line 813) | async is (fsNode) {
  method getSafeEntry (line 831) | async getSafeEntry (fetch_options = {}) {
  method sanitize_pending_entry_info (line 955) | static sanitize_pending_entry_info (res) {

FILE: src/backend/src/filesystem/FilesystemService.js
  class FilesystemService (line 34) | class FilesystemService extends BaseService {
    method old_constructor (line 41) | old_constructor (args) {
    method _init (line 52) | async _init () {
    method mkshortcut (line 141) | async mkshortcut ({ parent, name, user, target }) {
    method mklink (line 174) | async mklink ({ parent, name, user, target }) {
    method update_child_paths (line 236) | async update_child_paths (old_path, new_path, user_id) {
    method node (line 258) | async node (selector) {
    method get_entry (line 342) | async get_entry ({ path, uid, id, mysql_id, ...options }) {

FILE: src/backend/src/filesystem/batch/BatchExecutor.js
  class BatchExecutor (line 28) | class BatchExecutor extends AdvancedBase {
    method constructor (line 31) | constructor (x, { actor, log, errors }) {
    method ready_for_more (line 53) | async ready_for_more () {
    method exec_op (line 60) | async exec_op (req, op, file) {

FILE: src/backend/src/filesystem/batch/commands.js
  class BatchCommand (line 33) | class BatchCommand extends AdvancedBase {
    method run (line 37) | static async run (executor, parameters) {
  class MkdirCommand (line 57) | class MkdirCommand extends BatchCommand {
    method run (line 58) | async run (executor, parameters) {
  class WriteCommand (line 118) | class WriteCommand extends BatchCommand {
    method run (line 119) | async run (executor, parameters) {
  class ShortcutCommand (line 190) | class ShortcutCommand extends BatchCommand {
    method run (line 191) | async run (executor, parameters) {
  class SymlinkCommand (line 228) | class SymlinkCommand extends BatchCommand {
    method run (line 229) | async run (executor, parameters) {
  class DeleteCommand (line 261) | class DeleteCommand extends BatchCommand {
    method run (line 262) | async run (executor, parameters) {
  class MoveCommand (line 280) | class MoveCommand extends BatchCommand {
    method run (line 281) | async run (executor, parameters) {

FILE: src/backend/src/filesystem/definitions/ts/fsentry.js
  function createBaseFSEntry (line 3) | function createBaseFSEntry() {
  method encode (line 20) | encode(message, writer = new BinaryWriter()) {
  method decode (line 59) | decode(input, length) {
  method fromJSON (line 158) | fromJSON(object) {
  method toJSON (line 174) | toJSON(message) {
  method create (line 214) | create(base) {
  method fromPartial (line 217) | fromPartial(object) {
  function longToNumber (line 234) | function longToNumber(int64) {
  function isSet (line 244) | function isSet(value) {

FILE: src/backend/src/filesystem/definitions/ts/fsentry.ts
  type FSEntry (line 18) | interface FSEntry {
  function createBaseFSEntry (line 36) | function createBaseFSEntry(): FSEntry {
  method encode (line 54) | encode(message: FSEntry, writer: BinaryWriter = new BinaryWriter()): Bin...
  method decode (line 94) | decode(input: BinaryReader | Uint8Array, length?: number): FSEntry {
  method fromJSON (line 206) | fromJSON(object: any): FSEntry {
  method toJSON (line 223) | toJSON(message: FSEntry): unknown {
  method create (line 264) | create(base?: DeepPartial<FSEntry>): FSEntry {
  method fromPartial (line 267) | fromPartial(object: DeepPartial<FSEntry>): FSEntry {
  type Builtin (line 285) | type Builtin = Date | Function | Uint8Array | string | number | boolean ...
  type DeepPartial (line 287) | type DeepPartial<T> = T extends Builtin ? T
  function longToNumber (line 293) | function longToNumber(int64: { toString(): string }): number {
  function isSet (line 304) | function isSet(value: any): boolean {
  type MessageFns (line 308) | interface MessageFns<T> {

FILE: src/backend/src/filesystem/hl_operations/definitions.js
  class HLFilesystemOperation (line 21) | class HLFilesystemOperation extends BaseOperation {

FILE: src/backend/src/filesystem/hl_operations/hl_copy.js
  class HLCopy (line 29) | class HLCopy extends HLFilesystemOperation {
    method _run (line 57) | async _run () {

FILE: src/backend/src/filesystem/hl_operations/hl_data_read.js
  class HLDataRead (line 29) | class HLDataRead extends HLFilesystemOperation {
    method _run (line 34) | async _run () {
    method _stream_bytes_to_lines (line 67) | _stream_bytes_to_lines (stream) {
    method _stream_jsonl_lines_to_objects (line 88) | _stream_jsonl_lines_to_objects (stream) {

FILE: src/backend/src/filesystem/hl_operations/hl_mkdir.js
  function createDirOrUseExisting (line 46) | async function createDirOrUseExisting ({ parent, selector, actor, fs }) {
  class MkTree (line 78) | class MkTree extends HLFilesystemOperation {
    method _run (line 107) | async _run () {
    method create_branch_ (line 118) | async create_branch_ ({ parent_node, tree, parent_exists }) {
  class QuickMkdir (line 216) | class QuickMkdir extends HLFilesystemOperation {
    method _run (line 217) | async _run () {
  class HLMkdir (line 260) | class HLMkdir extends HLFilesystemOperation {
    method _run (line 297) | async _run () {
    method _create_parents (line 470) | async _create_parents ({ parent_node }) {
    method _create_dir (line 513) | async _create_dir (dir) {
    method _get_existing_top_parent (line 541) | async _get_existing_top_parent ({ top_parent }) {

FILE: src/backend/src/filesystem/hl_operations/hl_mklink.js
  class HLMkLink (line 25) | class HLMkLink extends HLFilesystemOperation {
    method _run (line 36) | async _run () {

FILE: src/backend/src/filesystem/hl_operations/hl_mkshortcut.js
  class HLMkShortcut (line 26) | class HLMkShortcut extends HLFilesystemOperation {
    method _run (line 39) | async _run () {

FILE: src/backend/src/filesystem/hl_operations/hl_move.js
  class HLMove (line 28) | class HLMove extends HLFilesystemOperation {
    method _run (line 37) | async _run () {

FILE: src/backend/src/filesystem/hl_operations/hl_name_search.js
  class HLNameSearch (line 25) | class HLNameSearch extends HLFilesystemOperation {
    method _run (line 26) | async _run () {

FILE: src/backend/src/filesystem/hl_operations/hl_read.js
  class HLRead (line 23) | class HLRead extends HLFilesystemOperation {
    method _run (line 29) | async _run () {
    method _wrap_stream_line_count (line 65) | _wrap_stream_line_count (stream, line_count) {

FILE: src/backend/src/filesystem/hl_operations/hl_readdir.js
  class HLReadDir (line 31) | class HLReadDir extends HLFilesystemOperation {
    method _run (line 33) | async _run () {
    method __run (line 40) | async __run () {
    method #applySubdomains (line 148) | async #applySubdomains (children) {
    method #batchFetchSubdomains (line 159) | async #batchFetchSubdomains (children, user) {
    method #batchFetchSuggestedApps (line 207) | async #batchFetchSuggestedApps (children, user) {

FILE: src/backend/src/filesystem/hl_operations/hl_remove.js
  class HLRemove (line 26) | class HLRemove extends HLFilesystemOperation {
    method _run (line 34) | async _run () {

FILE: src/backend/src/filesystem/hl_operations/hl_stat.js
  class HLStat (line 25) | class HLStat extends HLFilesystemOperation {
    method _run (line 30) | async _run () {
    method __run (line 40) | async __run () {

FILE: src/backend/src/filesystem/hl_operations/hl_write.js
  constant MAX_THUMBNAIL_SIZE (line 38) | const MAX_THUMBNAIL_SIZE = 2 * 1024 * 1024;
  class WriteCommonFeature (line 40) | class WriteCommonFeature {
    method install_in_instance (line 41) | install_in_instance (instance) {
  class HLWrite (line 94) | class HLWrite extends HLFilesystemOperation {
    method _run (line 141) | async _run () {

FILE: src/backend/src/filesystem/lib/PuterPath.js
  class PuterPath (line 30) | class PuterPath {
    method adapt (line 33) | static adapt (value) {
    method constructor (line 38) | constructor (text) {
    method text (line 42) | set text (text) {
    method text (line 49) | get text () {
    method isRoot (line 53) | isRoot () {
    method isAbsolute (line 61) | isAbsolute () {
    method isFromUID (line 65) | isFromUID () {
    method reference (line 69) | get reference () {
    method relativePortion (line 75) | get relativePortion () {

FILE: src/backend/src/filesystem/ll_operations/definitions.js
  class LLFilesystemOperation (line 21) | class LLFilesystemOperation extends BaseOperation {

FILE: src/backend/src/filesystem/ll_operations/ll_copy.js
  class LLCopy (line 22) | class LLCopy extends LLFilesystemOperation {
    method _run (line 28) | async _run () {

FILE: src/backend/src/filesystem/ll_operations/ll_copy_idea.js
  constant STEPS_COPY_CONTENTS (line 35) | const STEPS_COPY_CONTENTS = [
  constant STEPS (line 83) | const STEPS = [
  class LLCopy (line 138) | class LLCopy extends LLFilesystemOperation {

FILE: src/backend/src/filesystem/ll_operations/ll_listusers.js
  class LLListUsers (line 22) | class LLListUsers extends LLFilesystemOperation {
    method _run (line 28) | async _run () {

FILE: src/backend/src/filesystem/ll_operations/ll_mkdir.js
  class LLMkdir (line 25) | class LLMkdir extends LLFilesystemOperation {
    method _run (line 32) | async _run () {

FILE: src/backend/src/filesystem/ll_operations/ll_move.js
  class LLMove (line 21) | class LLMove extends LLFilesystemOperation {
    method _run (line 26) | async _run () {

FILE: src/backend/src/filesystem/ll_operations/ll_read.js
  class LLRead (line 42) | class LLRead extends LLFilesystemOperation {
    method _run (line 44) | async _run ({ fsNode, no_acl, actor, offset, length, range, version_id...

FILE: src/backend/src/filesystem/ll_operations/ll_readdir.js
  class LLReadDir (line 26) | class LLReadDir extends LLFilesystemOperation {
    method _run (line 28) | async _run () {
    method __run (line 33) | async __run () {
    method #try_readdirstatUUID (line 100) | async #try_readdirstatUUID () {

FILE: src/backend/src/filesystem/ll_operations/ll_readshares.js
  class LLReadShares (line 27) | class LLReadShares extends LLFilesystemOperation {
    method _run (line 37) | async _run () {

FILE: src/backend/src/filesystem/ll_operations/ll_rmdir.js
  class LLRmDir (line 27) | class LLRmDir extends LLFilesystemOperation {
    method _run (line 28) | async _run () {

FILE: src/backend/src/filesystem/ll_operations/ll_rmnode.js
  class LLRmNode (line 21) | class LLRmNode extends LLFilesystemOperation {
    method _run (line 22) | async _run () {

FILE: src/backend/src/filesystem/ll_operations/ll_write.js
  class LLOWrite (line 29) | class LLOWrite extends LLFilesystemOperation {
    method _run (line 35) | async _run () {
  class LLCWrite (line 67) | class LLCWrite extends LLFilesystemOperation {
    method _run (line 79) | async _run () {

FILE: src/backend/src/filesystem/node/selectors.js
  class NodeSelector (line 26) | class NodeSelector {
    method constructor (line 27) | constructor () {
  class NodePathSelector (line 35) | class NodePathSelector extends NodeSelector {
    method constructor (line 36) | constructor (path) {
    method setPropertiesKnownBySelector (line 41) | setPropertiesKnownBySelector (node) {
    method describe (line 46) | describe () {
  class NodeUIDSelector (line 51) | class NodeUIDSelector extends NodeSelector {
    method constructor (line 52) | constructor (uid) {
    method setPropertiesKnownBySelector (line 57) | setPropertiesKnownBySelector (node) {
    method implyFromFetchedData (line 64) | static implyFromFetchedData (node) {
    method describe (line 71) | describe () {
  class NodeInternalIDSelector (line 76) | class NodeInternalIDSelector extends NodeSelector {
    method constructor (line 77) | constructor (service, id, debugInfo) {
    method setPropertiesKnownBySelector (line 84) | setPropertiesKnownBySelector (node) {
    method describe (line 90) | describe (showDebug) {
  class NodeChildSelector (line 100) | class NodeChildSelector extends NodeSelector {
    method constructor (line 101) | constructor (parent, name) {
    method setPropertiesKnownBySelector (line 107) | setPropertiesKnownBySelector (node) {
    method describe (line 116) | describe () {
  class RootNodeSelector (line 121) | class RootNodeSelector extends NodeSelector {
    method setPropertiesKnownBySelector (line 128) | setPropertiesKnownBySelector (node) {
    method constructor (line 133) | constructor () {
    method describe (line 138) | describe () {
  class NodeRawEntrySelector (line 143) | class NodeRawEntrySelector extends NodeSelector {
    method constructor (line 144) | constructor (entry, details_about_fetch = {}) {
    method setPropertiesKnownBySelector (line 163) | setPropertiesKnownBySelector (node) {
    method describe (line 178) | describe () {
  function try_infer_attributes (line 190) | function try_infer_attributes (selector) {

FILE: src/backend/src/filesystem/node/states.js
  class NodeFoundState (line 19) | class NodeFoundState {
  class NodeDoesNotExistState (line 22) | class NodeDoesNotExistState {
  class NodeInitialState (line 25) | class NodeInitialState {

FILE: src/backend/src/filesystem/storage/UploadProgressTracker.js
  class UploadProgressTracker (line 19) | class UploadProgressTracker {
    method constructor (line 20) | constructor () {
    method set_total (line 28) | set_total (v) {
    method set (line 32) | set (value) {
    method add (line 41) | add (amount) {
    method sub (line 55) | sub (callback) {
    method check_if_done_ (line 76) | check_if_done_ () {

FILE: src/backend/src/filesystem/strategies/storage_a/LocalDiskStorageStrategy.js
  class LocalDiskUploadStrategy (line 25) | class LocalDiskUploadStrategy extends BaseOperation {
    method constructor (line 30) | constructor (parent) {
    method _run (line 41) | async _run () {
    method post_insert (line 69) | post_insert () {
  class LocalDiskCopyStrategy (line 77) | class LocalDiskCopyStrategy extends BaseOperation {
    method constructor (line 82) | constructor (parent) {
    method _run (line 92) | async _run () {
    method post_insert (line 109) | post_insert () {
  class LocalDiskDeleteStrategy (line 117) | class LocalDiskDeleteStrategy extends BaseOperation {
    method constructor (line 122) | constructor (parent) {
    method _run (line 131) | async _run () {
  class LocalDiskStorageStrategy (line 144) | class LocalDiskStorageStrategy {
    method constructor (line 150) | constructor ({ services }) {
    method create_upload (line 158) | create_upload () {
    method create_copy (line 166) | create_copy () {
    method create_delete (line 174) | create_delete () {
    method create_read_stream (line 184) | async create_read_stream (uid, options = {}) {

FILE: src/backend/src/helpers.js
  constant SERVICES_KEY (line 43) | const SERVICES_KEY = Symbol.for('puter.helpers.services');
  function tmp_provide_services (line 47) | async function tmp_provide_services (ss) {
  constant PENDING_QUERY_TTL (line 53) | const PENDING_QUERY_TTL = 10;
  constant SUGGESTED_APPS_CACHE_MAX (line 54) | const SUGGESTED_APPS_CACHE_MAX = 10000;
  constant DEFAULT_APP_ICON_SIZE (line 56) | const DEFAULT_APP_ICON_SIZE = 256;
  constant RAW_BASE64_REGEX (line 57) | const RAW_BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/;
  function is_empty (line 148) | async function is_empty (dir_uuid) {
  function is_temp_users_disabled (line 180) | async function is_temp_users_disabled () {
  function is_user_signup_disabled (line 189) | async function is_user_signup_disabled () {
  function validate_fsentry_name (line 227) | function validate_fsentry_name (name) {
  function id2uuid (line 264) | async function id2uuid (id) {
  function df (line 286) | async function df (user_id) {
  function get_user (line 310) | async function get_user (options) {
  function refresh_associations_cache (line 331) | async function refresh_associations_cache () {
  function get_app (line 362) | async function get_app (options) {
  function app_exists (line 781) | async function app_exists (options) {
  function change_username (line 808) | async function change_username (user_id, new_username) {
  function uuid2fsentry (line 836) | async function uuid2fsentry (uuid, return_thumbnail) {
  function id2fsentry (line 886) | async function id2fsentry (id, return_thumbnail) {
  function convert_path_to_fsentry (line 934) | async function convert_path_to_fsentry (path) {
  function byte_format (line 1017) | function byte_format (bytes) {
  function getDescendantsHelper (line 1115) | async function getDescendantsHelper (path, user, depth, return_thumbnail...
  function resolve_glob (line 1321) | async function resolve_glob (glob, user) {
  function isString (line 1345) | function isString (variable) {
  function get_entry (line 1364) | async function get_entry (uid) {
  function is_ancestor_of (line 1379) | async function is_ancestor_of (ancestor_uid, descendant_uid) {
  function sign_file (line 1431) | async function sign_file (fsentry, action) {
  function gen_public_token (line 1464) | async function gen_public_token (file_uuid) {
  function deleteUser (line 1508) | async function deleteUser (user_id) {
  function subdomain (line 1544) | function subdomain (req) {
  function jwt_auth (line 1549) | async function jwt_auth (req, authService) {
  function ancestors (line 1617) | async function ancestors (fsentry_id) {
  function hyphenize_confirm_code (line 1639) | function hyphenize_confirm_code (email_confirm_code) {
  function username_exists (line 1652) | async function username_exists (username) {
  function generate_random_username (line 1663) | async function generate_random_username () {
  function app_name_exists (line 1671) | async function app_name_exists (name) {
  function send_email_verification_code (line 1686) | function send_email_verification_code (email_confirm_code, email) {
  function send_email_verification_token (line 1693) | function send_email_verification_token (email_confirm_token, email, user...
  function generate_random_str (line 1699) | function generate_random_str (length) {
  function seconds_to_string (line 1717) | function seconds_to_string (seconds) {
  constant SUGGEST_APP_CODE_EXTS (line 1731) | const SUGGEST_APP_CODE_EXTS = [
  function suggestedAppsForFsEntries (line 1938) | async function suggestedAppsForFsEntries (fsentries, options) {
  function suggestedAppForFsEntry (line 2037) | async function suggestedAppForFsEntry (fsentry, options) {
  function get_taskbar_items (line 2042) | async function get_taskbar_items (user, {
  function validate_signature_auth (line 2131) | function validate_signature_auth (url, action, options = {}) {
  function get_url_from_req (line 2185) | function get_url_from_req (req) {
  function number_format (line 2199) | function number_format (number, decimals, dec_point, thousands_sep) {

FILE: src/backend/src/kernel/modutil.js
  function prependToJSFiles (line 4) | async function prependToJSFiles (directory, snippet) {

FILE: src/backend/src/middleware/measure.js
  method get (line 20) | get () {
  function measure (line 71) | function measure () {

FILE: src/backend/src/modules/ai/PuterAIChatModule.js
  class PuterAIModule (line 44) | class PuterAIModule extends AdvancedBase {
    method install (line 50) | async install (context) {

FILE: src/backend/src/modules/apps/AppIconService.js
  constant ICON_SIZES (line 37) | const ICON_SIZES = [16, 32, 64, 128, 256, 512];
  constant DEFAULT_ICON_SIZE (line 38) | const DEFAULT_ICON_SIZE = 128;
  constant RAW_BASE64_REGEX (line 39) | const RAW_BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/;
  constant REDIRECT_MAX_AGE_SIZE (line 42) | const REDIRECT_MAX_AGE_SIZE = 15 * 60;
  constant REDIRECT_MAX_AGE_ORIGINAL (line 43) | const REDIRECT_MAX_AGE_ORIGINAL = 60;
  class AppIconService (line 58) | class AppIconService extends BaseService {
    method getSizes (line 121) | getSizes () {
    method iconifyApps (line 125) | async iconifyApps ({ apps, size }) {
    method getAppIconPath (line 138) | getAppIconPath ({ appUid, size }) {
    method getAppIconEndpointUrl (line 157) | getAppIconEndpointUrl ({ appUid }) {
    method normalizeAppUid (line 171) | normalizeAppUid (appUid) {
    method isDataUrl (line 176) | isDataUrl (value) {
    method isRawBase64ImageString (line 184) | isRawBase64ImageString (value) {
    method normalizeRawBase64ImageString (line 202) | normalizeRawBase64ImageString (value) {
    method parseAppIconEndpointUrl (line 209) | parseAppIconEndpointUrl (iconUrl) {
    method isAppIconEndpointUrl (line 232) | isAppIconEndpointUrl (iconUrl) {
    method isSameAppIconEndpointUrl (line 236) | isSameAppIconEndpointUrl ({ iconUrl, appUid, size }) {
    method extractPuterSubdomainFromUrl (line 245) | extractPuterSubdomainFromUrl (url) {
    method isPuterSubdomainUrl (line 271) | isPuterSubdomainUrl (url) {
    method getAppIconsBaseUrl (line 275) | getAppIconsBaseUrl () {
    method getSizedIconUrl (line 292) | getSizedIconUrl ({ appUid, size }) {
    method getOriginalIconUrl (line 303) | getOriginalIconUrl ({ appUid }) {
    method ensureAppIconsDirectory (line 313) | async ensureAppIconsDirectory ({ dirSystem = null } = {}) {
    method getOriginalIconLookup (line 344) | async getOriginalIconLookup ({ dirAppIcons, appUid }) {
    method ensureAppIconsSubdomain (line 360) | async ensureAppIconsSubdomain ({ dirAppIcons }) {
    method readIconNodeBuffer (line 390) | async readIconNodeBuffer ({ node }) {
    method writePngToDir (line 400) | async writePngToDir ({ destination_or_parent, filename, output }) {
    method shouldRedirectIconUrl (line 421) | shouldRedirectIconUrl ({ iconUrl, appUid, size }) {
    method generateMissingSizeFromOriginal (line 436) | async generateMissingSizeFromOriginal ({ appUid, size }) {
    method queueMissingSizeFromOriginal (line 466) | queueMissingSizeFromOriginal ({ appUid, size }) {
    method queueDataUrlIconWrite (line 491) | queueDataUrlIconWrite ({ appUid, dataUrl }) {
    method persistConvertedIconUrl (line 531) | async persistConvertedIconUrl ({ appUid, iconUrl }) {
    method #getIconStream (line 562) | async #getIconStream ({ appIcon, appUid, size, tries = 0, allowRedirec...
    method getAppIcons (line 722) | async getAppIcons () {
    method getSharp (line 733) | getSharp ({ metadata, input }) {
    method loadIconSource (line 749) | async loadIconSource ({ iconUrl }) {
    method createAppIcons (line 807) | async createAppIcons ({ data }) {
    method _init (line 858) | async _init () {
  method '__on_install.routes' (line 73) | async '__on_install.routes' (_, { app }) {
  method '__on_user.system-user-ready' (line 788) | async '__on_user.system-user-ready' () {

FILE: src/backend/src/modules/apps/AppInformationService.js
  constant APP_UID_ALIAS_KEY_PREFIX (line 26) | const APP_UID_ALIAS_KEY_PREFIX = 'app:canonicalUidAlias';
  constant APP_UID_ALIAS_REVERSE_KEY_PREFIX (line 27) | const APP_UID_ALIAS_REVERSE_KEY_PREFIX = 'app:canonicalUidAliasReverse';
  class AppInformationService (line 39) | class AppInformationService extends BaseService {
    method _construct (line 42) | _construct () {
    method invalidateAppCache (line 93) | async invalidateAppCache ({ appUid, oldName, app }) {
    method get_stats (line 157) | async get_stats (app_uid, options = {}) {
    method _refresh_app_stats (line 550) | async _refresh_app_stats () {
    method _refresh_app_stat_referrals (line 625) | async _refresh_app_stat_referrals () {
    method delete_app (line 711) | async delete_app (app_uid, app, options = {}) {
    method buildCanonicalAppUidAliasKey_ (line 777) | buildCanonicalAppUidAliasKey_ (appUid) {
    method buildCanonicalAppUidAliasReverseKey_ (line 781) | buildCanonicalAppUidAliasReverseKey_ (canonicalAppUid) {
    method normalizeCanonicalAliasUidList_ (line 785) | normalizeCanonicalAliasUidList_ (value) {
    method cleanupCanonicalAppUidAliases_ (line 798) | async cleanupCanonicalAppUidAliases_ (appUid) {
    method generateAllPeriods (line 831) | generateAllPeriods (startDate, endDate, grouping) {
    method getWeekNumber (line 871) | getWeekNumber (date) {
    method mergeWithGeneratedPeriods (line 884) | mergeWithGeneratedPeriods (actualData, allPeriods, stats_grouping) {
  method '__on_boot.consolidation' (line 64) | '__on_boot.consolidation' () {

FILE: src/backend/src/modules/apps/AppPermissionService.js
  class AppPermissionService (line 5) | class AppPermissionService extends BaseService {
    method _init (line 6) | async _init () {

FILE: src/backend/src/modules/apps/AppsModule.js
  class AppsModule (line 22) | class AppsModule extends AdvancedBase {
    method install (line 23) | async install (context) {

FILE: src/backend/src/modules/apps/OldAppNameService.js
  constant N_MONTHS (line 23) | const N_MONTHS = 4;
  class OldAppNameService (line 25) | class OldAppNameService extends BaseService {
    method _init (line 28) | _init () {
    method check_app_name (line 41) | async check_app_name (name) {
    method remove_name (line 76) | async remove_name (id) {
  method '__on_boot.consolidation' (line 32) | async '__on_boot.consolidation' () {

FILE: src/backend/src/modules/apps/ProtectedAppService.js
  class ProtectedAppService (line 32) | class ProtectedAppService extends BaseService {
    method _init (line 41) | async _init () {

FILE: src/backend/src/modules/apps/RecommendedAppsService.js
  class RecommendedAppsService (line 27) | class RecommendedAppsService extends BaseService {
    method _construct (line 71) | _construct () {
    method get_recommended_apps (line 97) | async get_recommended_apps ({ icon_size: iconSize }) {
  method '__on_boot.consolidation' (line 75) | '__on_boot.consolidation' () {

FILE: src/backend/src/modules/apps/lib/IconResult.js
  method constructor (line 24) | constructor (o) {
  method get_data_url (line 28) | async get_data_url () {

FILE: src/backend/src/modules/apps/privateLaunchAccess.js
  constant DEFAULT_FALLBACK_APP_NAME (line 22) | const DEFAULT_FALLBACK_APP_NAME = 'app-center';
  function isPrivateApp (line 24) | function isPrivateApp (app) {
  function buildFallbackPath (line 28) | function buildFallbackPath (appName) {
  function buildDefaultDeniedDecision (line 35) | function buildDefaultDeniedDecision (appName, reason) {
  function normalizeLaunchDecision (line 47) | function normalizeLaunchDecision (decision, appName) {
  function getActorUserUid (line 87) | function getActorUserUid (actor) {
  function resolvePrivateLaunchAccess (line 108) | async function resolvePrivateLaunchAccess ({

FILE: src/backend/src/modules/broadcast/BroadcastModule.js
  class BroadcastModule (line 22) | class BroadcastModule extends AdvancedBase {
    method install (line 23) | async install (context) {

FILE: src/backend/src/modules/broadcast/BroadcastService.js
  class BroadcastService (line 27) | class BroadcastService extends BaseService {
    method _init (line 45) | async _init () {
    method outBroadcastEventHandler (line 100) | async outBroadcastEventHandler (key, data, meta) {
    method #enqueueOutboundEvent (line 115) | #enqueueOutboundEvent (event) {
    method #createDedupKey (line 121) | #createDedupKey (event) {
    method #scheduleOutboundFlush (line 131) | #scheduleOutboundFlush () {
    method #flushOutboundEvents (line 144) | async #flushOutboundEvents () {
    method #normalizeMeta (line 167) | #normalizeMeta (meta) {
    method #resolveLocalPeerId (line 174) | #resolveLocalPeerId () {
    method #resolvePeerId (line 180) | #resolvePeerId (peerConfig) {
    method #isNonceReplayForPeer (line 187) | #isNonceReplayForPeer ({ timestamp, nonce, peerId }) {
    method #initRedisPubSub (line 197) | async #initRedisPubSub () {
    method #isRedisWebhookEventKey (line 220) | #isRedisWebhookEventKey (key) {
    method #filterRedisWebhookEvents (line 226) | #filterRedisWebhookEvents (events) {
    method #publishWebhookEventsToRedis (line 230) | async #publishWebhookEventsToRedis (events) {
    method #handleRedisPubSubMessage (line 254) | async #handleRedisPubSubMessage (channel, message) {
    method #normalizeIncomingPayload (line 286) | #normalizeIncomingPayload (payload) {
    method #normalizeIncomingEvent (line 306) | #normalizeIncomingEvent (event) {
    method #emitIncomingEventsSequentially (line 326) | async #emitIncomingEventsSequentially (events) {
    method #handleWebhookRequest (line 359) | async #handleWebhookRequest (req, res) {
    method #sendWebhookToPeer (line 454) | async #sendWebhookToPeer (peer_config, events) {
    method #normalizeWebhookUrl (line 503) | #normalizeWebhookUrl (url) {
  method '__on_install.routes' (line 347) | async '__on_install.routes' (_, { app }) {

FILE: src/backend/src/modules/captcha/CaptchaModule.js
  class CaptchaModule (line 31) | class CaptchaModule extends AdvancedBase {
    method install (line 32) | async install (context) {

FILE: src/backend/src/modules/captcha/services/CaptchaService.js
  class CaptchaService (line 31) | class CaptchaService extends BaseService {
    method _construct (line 35) | async _construct () {
    method _init (line 71) | async _init () {
    method _destroy (line 90) | async _destroy () {
    method registerEndpoints (line 101) | registerEndpoints () {
    method generateCaptcha (line 350) | generateCaptcha () {
    method verifyCaptcha (line 406) | verifyCaptcha (token, userAnswer) {
    method _checkServiceHealth (line 465) | _checkServiceHealth () {
    method cleanupExpiredTokens (line 473) | cleanupExpiredTokens () {
    method _getCaptchaOptions (line 535) | _getCaptchaOptions () {
    method verifySelfTest (line 576) | verifySelfTest () {
    method getDiagnosticInfo (line 626) | getDiagnosticInfo () {
  method '__on_install.middlewares.context-aware' (line 63) | async '__on_install.middlewares.context-aware' (_, { app }) {

FILE: src/backend/src/modules/core/AlarmService.d.ts
  class AlarmService (line 1) | class AlarmService {

FILE: src/backend/src/modules/core/AlarmService.js
  class AlarmService (line 29) | class AlarmService extends BaseService {
    method _construct (line 41) | async _construct () {
    method _init (line 51) | async _init () {
    method adapt_id_ (line 68) | adapt_id_ (id) {
    method create (line 88) | create (id, message, fields) {
    method clear (line 198) | clear (id) {
    method apply_known_errors_ (line 207) | apply_known_errors_ (alarm) {
    method handle_alarm_repeat_ (line 234) | handle_alarm_repeat_ (alarm) {
    method handle_alarm_on_ (line 262) | handle_alarm_on_ (alarm) {
    method handle_alarm_off_ (line 328) | handle_alarm_off_ (alarm) {
    method get_alarm (line 339) | get_alarm (id) {
    method _register_commands (line 343) | _register_commands (commands) {
  method '__on_boot.consolidation' (line 64) | '__on_boot.consolidation' () {

FILE: src/backend/src/modules/core/ContextService.js
  class ContextService (line 32) | class ContextService extends BaseService {
    method register_context_hook (line 33) | register_context_hook (event, hook) {

FILE: src/backend/src/modules/core/Core2Module.js
  class Core2Module (line 34) | class Core2Module extends AdvancedBase {
    method install (line 35) | async install (context) {

FILE: src/backend/src/modules/core/ErrorService.js
  class ErrorContext (line 32) | class ErrorContext {
    method constructor (line 33) | constructor (error_service, log_context) {
    method report (line 37) | report (location, fields) {
  class ErrorService (line 53) | class ErrorService extends BaseService {
    method init (line 62) | async init () {
    method create (line 74) | create (log_context) {
    method report (line 88) | report (location, { source, logger, trace, extra, message }, alarm = t...

FILE: src/backend/src/modules/core/ExpectationService.js
  class ExpectationService (line 35) | class ExpectationService extends BaseService {
    method _construct (line 47) | async _construct () {
    method _init (line 84) | async _init () {
    method purgeExpectations_ (line 109) | purgeExpectations_ () {
    method expect_eventually (line 127) | expect_eventually ({ workUnit, checkpoint }) {
  method '__on_boot.consolidation' (line 55) | '__on_boot.consolidation' () {

FILE: src/backend/src/modules/core/LogService.js
  constant LOG_LEVEL_ERRO (line 20) | const LOG_LEVEL_ERRO = logSeverity(0, 'ERRO', '31;1', 'error');
  constant LOG_LEVEL_WARN (line 21) | const LOG_LEVEL_WARN = logSeverity(1, 'WARN', '33;1', 'warn');
  constant LOG_LEVEL_INFO (line 22) | const LOG_LEVEL_INFO = logSeverity(2, 'INFO', '36;1', 'info');
  constant LOG_LEVEL_NOTICEME (line 23) | const LOG_LEVEL_NOTICEME = logSeverity(3, 'NOTICE_ME', '33;1', 'error');
  constant LOG_LEVEL_SYSTEM (line 24) | const LOG_LEVEL_SYSTEM = logSeverity(3, 'SYSTEM', '36;1', 'system');
  constant LOG_LEVEL_DEBU (line 25) | const LOG_LEVEL_DEBU = logSeverity(4, 'DEBU', '37', 'debug');
  constant LOG_LEVEL_TICK (line 26) | const LOG_LEVEL_TICK = logSeverity(10, 'TICK', '34;1', 'info');
  constant WINSTON_LEVELS (line 34) | const WINSTON_LEVELS = {
  class LogContext (line 61) | class LogContext {
    method constructor (line 62) | constructor (logService, { crumbs, fields }) {
    method sub (line 68) | sub (name, fields = {}) {
    method info (line 76) | info (message, fields, objects) {
    method warn (line 79) | warn (message, fields, objects) {
    method debug (line 82) | debug (message, fields, objects) {
    method error (line 85) | error (message, fields, objects) {
    method tick (line 88) | tick (message, fields, objects) {
    method called (line 91) | called (fields = {}) {
    method noticeme (line 94) | noticeme (message, fields, objects) {
    method system (line 97) | system (message, fields, objects) {
    method cache (line 101) | cache (isCacheHit, identifier, fields = {}) {
    method log (line 107) | log (log_level, message, fields = {}, objects = {}) {
    method mkid (line 145) | mkid () {
    method traceOn (line 158) | traceOn () {
    method get_log_buffer (line 168) | get_log_buffer () {
  class DevLogger (line 187) | class DevLogger {
    method constructor (line 189) | constructor (log, opt_delegate) {
    method onLogMessage (line 198) | onLogMessage (log_lvl, crumbs, message, fields, objects) {
    method log_ (line 221) | log_ (text) {
  class NullLogger (line 236) | class NullLogger {
    method constructor (line 238) | constructor (log, opt_delegate) {
    method onLogMessage (line 245) | onLogMessage () {
  class WinstonLogger (line 254) | class WinstonLogger {
    method constructor (line 255) | constructor (winst) {
    method onLogMessage (line 258) | onLogMessage (log_lvl, crumbs, message, fields) {
  class TimestampLogger (line 276) | class TimestampLogger {
    method constructor (line 277) | constructor (delegate) {
    method onLogMessage (line 280) | onLogMessage (log_lvl, crumbs, message, fields, ...a) {
  class BufferLogger (line 294) | class BufferLogger {
    method constructor (line 295) | constructor (size, delegate) {
    method onLogMessage (line 300) | onLogMessage (log_lvl, crumbs, message, fields, ...a) {
  class CustomLogger (line 316) | class CustomLogger {
    method constructor (line 317) | constructor (delegate, callback) {
    method onLogMessage (line 321) | async onLogMessage (log_lvl, crumbs, message, fields, ...a) {
  class LogService (line 375) | class LogService extends BaseService {
    method _construct (line 385) | async _construct () {
    method register_log_middleware (line 394) | register_log_middleware (callback) {
    method _init (line 467) | async _init () {
    method create (line 597) | create (prefix, fields = {}) {
    method log_ (line 607) | log_ (log_lvl, crumbs, message, fields, objects) {
    method ensure_log_directory_ (line 639) | ensure_log_directory_ () {
    method get_log_file (line 694) | get_log_file (name) {
    method get_log_buffer (line 705) | get_log_buffer () {
  method '__on_boot.consolidation' (line 401) | '__on_boot.consolidation' () {

FILE: src/backend/src/modules/core/PagerService.js
  class PagerService (line 32) | class PagerService extends BaseService {
    method _construct (line 37) | async _construct () {
    method _init (line 59) | async _init () {
    method onInit (line 76) | onInit () {
    method alert (line 132) | async alert (alert) {
    method _register_commands (line 142) | _register_commands (commands) {
  method '__on_boot.consolidation' (line 47) | '__on_boot.consolidation' () {

FILE: src/backend/src/modules/core/ParameterService.js
  class Parameter (line 28) | class Parameter {
    method constructor (line 29) | constructor (spec) {
    method set (line 45) | async set (value) {
    method get (line 63) | async get () {
    method bindToInstance (line 67) | bindToInstance (instance, name) {
    method subscribe (line 75) | subscribe (listener) {
  class ParameterService (line 88) | class ParameterService extends BaseService {
    method _construct (line 89) | _construct () {
    method createParameters (line 104) | createParameters (serviceName, parameters, opt_instance) {
    method get (line 125) | async get (id) {
    method bindToInstance (line 130) | bindToInstance (id, instance, name) {
    method subscribe (line 135) | subscribe (id, listener) {
    method _get_param (line 140) | _get_param (id) {
    method _registerCommands (line 152) | _registerCommands (commands) {
  method '__on_boot.consolidation' (line 100) | '__on_boot.consolidation' () {

FILE: src/backend/src/modules/core/ProcessEventService.js
  class ProcessEventService (line 30) | class ProcessEventService extends BaseService {
    method _init (line 35) | _init () {

FILE: src/backend/src/modules/core/ServerHealthService/ServerHealthService.js
  constant SECOND (line 24) | const SECOND = 1000;
  class ServerHealthService (line 37) | class ServerHealthService extends BaseService {
    method _construct (line 58) | _construct () {
    method _init (line 63) | async _init () {
    method init_service_checks_ (line 125) | init_service_checks_ () {
    method get_stats (line 205) | async get_stats () {
    method add_check (line 209) | add_check (name, fn) {
    method get_status (line 229) | async get_status () {

FILE: src/backend/src/modules/core/lib/expect.js
  class WorkUnit (line 29) | class WorkUnit {
    method create (line 42) | static create () {
    method constructor (line 50) | constructor () {
    method checkpoint (line 54) | checkpoint (label) {
  class CheckpointExpectation (line 68) | class CheckpointExpectation {
    method constructor (line 69) | constructor (workUnit, checkpoint) {
    method check (line 79) | check () {
    method report (line 83) | report (log) {

FILE: src/backend/src/modules/core/lib/identifier.js
  function generate_identifier (line 79) | function generate_identifier (separator = '_', rng = Math.random) {
  constant HUMAN_READABLE_CASE_INSENSITIVE (line 90) | const HUMAN_READABLE_CASE_INSENSITIVE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ01234...
  function generate_random_code (line 92) | function generate_random_code (n, {
  function compose_code (line 109) | function compose_code (mask, value) {

FILE: src/backend/src/modules/data-access/AppRepository.js
  class AppRepository (line 1) | class AppRepository {

FILE: src/backend/src/modules/data-access/AppService.comp.test.js
  constant ES_APP_ARGS (line 38) | const ES_APP_ARGS = {

FILE: src/backend/src/modules/data-access/AppService.js
  constant APP_ICON_ENDPOINT_PATH_REGEX (line 27) | const APP_ICON_ENDPOINT_PATH_REGEX = /^\/app-icon\/([^/?#]+)(?:\/(\d+))?...
  constant LEGACY_APP_ICON_FILE_PATH_REGEX (line 28) | const LEGACY_APP_ICON_FILE_PATH_REGEX = /^\/(app-[^/?#]+?)(?:-(\d+))?\.p...
  constant ABSOLUTE_URL_REGEX (line 29) | const ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
  constant RAW_BASE64_REGEX (line 30) | const RAW_BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/;
  constant APP_UID_ALIAS_KEY_PREFIX (line 31) | const APP_UID_ALIAS_KEY_PREFIX = 'app:canonicalUidAlias';
  constant APP_UID_ALIAS_REVERSE_KEY_PREFIX (line 32) | const APP_UID_ALIAS_REVERSE_KEY_PREFIX = 'app:canonicalUidAliasReverse';
  constant APP_UID_ALIAS_TTL_SECONDS (line 33) | const APP_UID_ALIAS_TTL_SECONDS = 60 * 60 * 24 * 90;
  class AppService (line 227) | class AppService extends BaseService {
    method _init (line 228) | async _init () {
    method create (line 299) | async create ({ object, options }) {
    method update (line 302) | async update ({ object, id, options }) {
    method upsert (line 305) | async upsert ({ object, id, options }) {
    method read (line 331) | async read ({ uid, id, params = {} }) {
    method select (line 334) | async select (options) {
    method delete (line 337) | async delete ({ uid, id }) {
    method #select (line 346) | async #select ({ predicate, params, ..._rest }) {
    method #read (line 464) | async #read ({ uid, id, params = {}, backend_only_options = {} }) {
    method #parseFiletypeAssociationsJson (line 598) | #parseFiletypeAssociationsJson (filetypes) {
    method #getFiletypeAssociationsByAppId (line 602) | async #getFiletypeAssociationsByAppId (appId) {
    method #normalizeFiletypeAssociations (line 614) | #normalizeFiletypeAssociations (filetypesAsJSON) {
    method #getFiletypeAssociationsByAppIds (line 630) | async #getFiletypeAssociationsByAppIds (appIds) {
    method #create (line 659) | async #create ({ object, options }) {
    method #execute_insert (line 821) | async #execute_insert (object, uid, owner_user_id, app_owner_id) {
    method #delete (line 867) | async #delete ({ uid, id }) {
    method #check_app_owner_permission (line 901) | async #check_app_owner_permission (old_app, actor) {
    method #update (line 921) | async #update ({ object, id, options }) {
    method #resolveAppId (line 1069) | async #resolveAppId (app) {
    method #check_owner_permission (line 1083) | async #check_owner_permission (old_app) {
    method getAppRootDirId (line 1119) | async getAppRootDirId (app) {
    method #ensure_puter_site_subdomain_is_owned (line 1147) | async #ensure_puter_site_subdomain_is_owned (index_url, user) {
    method #normalizeConfiguredHostedDomain (line 1160) | #normalizeConfiguredHostedDomain (domainValue) {
    method #getPuterHostedDomains (line 1167) | #getPuterHostedDomains () {
    method #extractPuterHostedSubdomain (line 1183) | #extractPuterHostedSubdomain (indexUrl) {
    method #isPuterHostedIndexUrl (line 1207) | #isPuterHostedIndexUrl (indexUrl) {
    method #buildEquivalentIndexUrlCandidates (line 1211) | #buildEquivalentIndexUrlCandidates (indexUrl) {
    method #findIndexUrlConflictRow (line 1240) | async #findIndexUrlConflictRow ({ indexUrl, excludeAppId } = {}) {
    method #ensureIndexUrlNotAlreadyInUse (line 1277) | async #ensureIndexUrlNotAlreadyInUse ({ indexUrl, excludeAppId } = {}) {
    method #claimAppOwnershipByIdForUser (line 1287) | async #claimAppOwnershipByIdForUser ({ appId, userId }) {
    method #buildCanonicalAppUidAliasKey (line 1297) | #buildCanonicalAppUidAliasKey (oldAppUid) {
    method #buildCanonicalAppUidAliasReverseKey (line 1301) | #buildCanonicalAppUidAliasReverseKey (canonicalAppUid) {
    method #normalizeCanonicalAliasUidList (line 1305) | #normalizeCanonicalAliasUidList (value) {
    method #readCanonicalAppUidAlias (line 1318) | async #readCanonicalAppUidAlias (oldAppUid) {
    method #writeCanonicalAppUidAlias (line 1338) | async #writeCanonicalAppUidAlias ({ oldAppUid, canonicalAppUid }) {
    method #maybeJoinOwnedHostedIndexUrlAppOnCreate (line 1375) | async #maybeJoinOwnedHostedIndexUrlAppOnCreate ({
    method #isOriginBootstrapApp (line 1494) | #isOriginBootstrapApp (app) {
    method #handle_name_conflict (line 1503) | async #handle_name_conflict (object, old_app, options) {
    method #execute_update (line 1537) | async #execute_update (object, old_app) {
    method #update_filetype_associations (line 1586) | async #update_filetype_associations (app_id, filetype_associations) {
    method #emit_change_events (line 1627) | async #emit_change_events (object, old_app) {
    method #build_complex_id_where (line 1668) | #build_complex_id_where (id) {
    method #check_protected_app_access (line 1718) | async #check_protected_app_access (app, owner_user_id) {

FILE: src/backend/src/modules/data-access/DataAccessModule.js
  class DataAccessModule (line 4) | class DataAccessModule extends AdvancedBase {
    method install (line 5) | async install (context) {

FILE: src/backend/src/modules/data-access/lib/error.js
  class CoercionTypeError (line 5) | class CoercionTypeError extends Error {
    method constructor (line 6) | constructor ({ expected, got }) {

FILE: src/backend/src/modules/development/DevelopmentModule.js
  class DevelopmentModule (line 28) | class DevelopmentModule extends AdvancedBase {
    method install (line 29) | async install (context) {

FILE: src/backend/src/modules/development/LocalTerminalService.js
  constant PERM_LOCAL_TERMINAL (line 25) | const PERM_LOCAL_TERMINAL = 'local-terminal:access';
  class LocalTerminalService (line 32) | class LocalTerminalService extends BaseService {
    method _construct (line 33) | _construct () {
    method get_profiles (line 36) | get_profiles () {
    method _init (line 145) | async _init () {
  method '__on_install.routes' (line 51) | '__on_install.routes' (_, { app }) {

FILE: src/backend/src/modules/dns/DNSModule.js
  class DNSModule (line 3) | class DNSModule extends AdvancedBase {
    method install (line 4) | async install (context) {

FILE: src/backend/src/modules/dns/DNSService.js
  class DNSService (line 8) | class DNSService extends BaseService {
    method _init (line 13) | async _init () {
    method get_client (line 30) | get_client () {
    method test_server_ (line 38) | test_server_ () {

FILE: src/backend/src/modules/domain/DomainModule.js
  class DomainModule (line 3) | class DomainModule extends AdvancedBase {
    method install (line 4) | async install (context) {

FILE: src/backend/src/modules/domain/DomainVerificationService.js
  class DomainVerificationService (line 4) | class DomainVerificationService extends BaseService {
    method _init (line 5) | _init () {
    method get_controlling_user (line 8) | async get_controlling_user ({ domain }) {
    method _register_commands (line 26) | _register_commands (commands) {

FILE: src/backend/src/modules/domain/TXTVerifyService.js
  class TXTVerifyService (line 5) | class TXTVerifyService extends BaseService {
  method '__on_boot.consolidation' (line 6) | '__on_boot.consolidation' () {

FILE: src/backend/src/modules/entitystore/EntityStoreInterfaceService.js
  class EntityStoreInterfaceService (line 28) | class EntityStoreInterfaceService extends BaseService {
  method '__on_driver.register.interfaces' (line 33) | async '__on_driver.register.interfaces' () {

FILE: src/backend/src/modules/entitystore/EntityStoreModule.js
  class EntityStoreModule (line 26) | class EntityStoreModule extends AdvancedBase {
    method install (line 27) | async install (context) {

FILE: src/backend/src/modules/hostos/HostOSModule.js
  class HostOSModule (line 3) | class HostOSModule extends AdvancedBase {
    method install (line 4) | async install (context) {

FILE: src/backend/src/modules/hostos/ProcessService.js
  class ProxyLogger (line 3) | class ProxyLogger {
    method constructor (line 4) | constructor (log) {
    method attach (line 7) | attach (stream) {
  class ProcessService (line 28) | class ProcessService extends BaseService {
    method _construct (line 36) | _construct () {
    method _init (line 40) | async _init (args) {
    method log_ (line 48) | log_ (name, isErr, line) {
    method exit_all_ (line 57) | async exit_all_ () {
    method start (line 63) | async start ({ name, fullpath, command, args, env }) {

FILE: src/backend/src/modules/internet/InternetModule.js
  class InternetModule (line 4) | class InternetModule extends AdvancedBase {
    method install (line 5) | async install (context) {

FILE: src/backend/src/modules/internet/WispRelayService.js
  class WispRelayService (line 3) | class WispRelayService extends BaseService {
    method _init (line 4) | _init () {

FILE: src/backend/src/modules/kvstore/KVStoreInterfaceService.js
  class KVStoreInterfaceService (line 85) | class KVStoreInterfaceService extends BaseService {
  method '__on_driver.register.interfaces' (line 90) | async '__on_driver.register.interfaces' () {

FILE: src/backend/src/modules/kvstore/KVStoreModule.js
  class KVStoreModule (line 26) | class KVStoreModule extends AdvancedBase {
    method install (line 27) | async install (context) {

FILE: src/backend/src/modules/perfmon/TelemetryService.js
  class TelemetryService (line 31) | class TelemetryService extends BaseService {
    method constructor (line 40) | constructor (service_resources, ...args) {
    method _init (line 49) | _init () {
    method #normalizeRoute (line 75) | static #normalizeRoute (route) {
    method #buildRoute (line 92) | static #buildRoute (req, route) {
    method #applyRouteToSpan (line 102) | static #applyRouteToSpan (span, req, route) {
    method #buildInstrumentationConfig (line 112) | static #buildInstrumentationConfig () {
    method #resolveExporterConfig (line 142) | static #resolveExporterConfig (serviceConfig) {
    method #getConfiguredExporter (line 146) | static #getConfiguredExporter (serviceConfig) {
    method #getMetricExporter (line 156) | static #getMetricExporter (serviceConfig) {
    method #startTelemetry (line 166) | static #startTelemetry ({ serviceConfig } = {}) {

FILE: src/backend/src/modules/puterfs/MountpointService.js
  class MountpointService (line 39) | class MountpointService extends BaseService {
    method register_mounter (line 45) | register_mounter (name, mounter) {
    method get_provider (line 87) | async get_provider (selector) {
    method set_storage (line 147) | set_storage (provider, storage) {
    method get_storage (line 155) | get_storage (provider) {
  method '__on_boot.consolidation' (line 49) | async '__on_boot.consolidation' () {

FILE: src/backend/src/modules/puterfs/PuterFSModule.js
  class PuterFSModule (line 29) | class PuterFSModule extends AdvancedBase {
    method install (line 30) | async install (context) {

FILE: src/backend/src/modules/puterfs/ResourceService.js
  constant RESOURCE_STATUS_PENDING_CREATE (line 27) | const RESOURCE_STATUS_PENDING_CREATE = {};
  constant RESOURCE_STATUS_PENDING_UPDATE (line 28) | const RESOURCE_STATUS_PENDING_UPDATE = {};
  constant RS_DIRECTORY_PENDING_CHILD_INSERT (line 29) | const RS_DIRECTORY_PENDING_CHILD_INSERT = {};
  class ResourceService (line 44) | class ResourceService extends BaseService {
    method _construct (line 45) | _construct () {
    method register (line 51) | register (entry) {
    method free (line 74) | free (uid) {
    method waitForResourceByPath (line 87) | async waitForResourceByPath (path) {
    method waitForResourceByUID (line 95) | async waitForResourceByUID (uid) {
    method waitForResource (line 103) | async waitForResource (selector) {
    method getResourceInfo (line 120) | getResourceInfo (uid) {

FILE: src/backend/src/modules/puterfs/SizeService.js
  class UserParameter (line 24) | class UserParameter {
    method adapt (line 25) | static async adapt (value) {
  class SizeService (line 34) | class SizeService extends BaseService {
    method _construct (line 35) | _construct () {
    method _init (line 39) | _init () {
    method get_usage (line 76) | async get_usage (user_id) {
    method change_usage (line 94) | async change_usage (user_id, delta) {
    method add_node_size (line 100) | async add_node_size (fs, node, user, factor = 1) {
    method get_storage_capacity (line 126) | async get_storage_capacity (user_or_id, { exclude_transient } = {}) {
    method add_storage (line 152) | async add_storage (user_or_id, amount_in_bytes, reason, { field_a, fie...
  method '__on_boot.consolidate' (line 44) | '__on_boot.consolidate' () {

FILE: src/backend/src/modules/puterfs/customfs/MemoryFSProvider.js
  class MemoryFile (line 36) | class MemoryFile {
    method constructor (line 44) | constructor ({ path, is_dir, content, parent_uid = null }) {
  class MemoryFSProvider (line 75) | class MemoryFSProvider {
    method constructor (line 76) | constructor (mountpoint) {
    method get_capabilities (line 104) | get_capabilities () {
    method _inner_path (line 120) | _inner_path (path) {
    method _integrity_check (line 141) | _integrity_check () {
    method quick_check (line 203) | async quick_check ({ selector }) {
    method stat (line 228) | async stat ({ selector }) {
    method readdir (line 284) | async readdir ({ context, node }) {
    method mkdir (line 318) | async mkdir ({ context, parent, name }) {
    method rmdir (line 363) | async rmdir ({ context, node, options = {} }) {
    method unlink (line 413) | async unlink ({ context, node }) {
    method move (line 436) | async move ({ context, node, new_parent, new_name, metadata }) {
    method copy_tree (line 477) | async copy_tree ({ context, source, parent, target_name }) {
    method write_new (line 523) | async write_new ({ context, parent, name, file }) {
    method write_overwrite (line 567) | async write_overwrite ({ context, node, file }) {
    method read (line 598) | async read ({

FILE: src/backend/src/modules/puterfs/customfs/MemoryFSService.js
  class MemoryFSService (line 23) | class MemoryFSService extends BaseService {
    method _init (line 24) | async _init () {
    method mount (line 31) | async mount ({ path, options }) {

FILE: src/backend/src/modules/selfhosted/DefaultUserService.js
  constant USERNAME (line 33) | const USERNAME = 'admin';
  constant DEFAULT_FILES (line 35) | const DEFAULT_FILES = {};
  class DefaultUserService (line 37) | class DefaultUserService extends BaseService {
    method _init (line 38) | async _init () {
    method create_default_user_ (line 70) | async create_default_user_ () {
    method #recursiveCreateDefaultFilesIfMissing (line 111) | async #recursiveCreateDefaultFilesIfMissing ({ components, tree, actor...
    method #createDefaultUserFiles (line 164) | async #createDefaultUserFiles (actor) {
    method get_tmp_password_ (line 174) | async get_tmp_password_ (user) {
    method force_tmp_password_ (line 198) | async force_tmp_password_ (user) {
    method _register_commands (line 224) | _register_commands (commands) {
  method '__on_ready.webserver' (line 41) | async '__on_ready.webserver' () {

FILE: src/backend/src/modules/selfhosted/DevCreditService.js
  class PermissiveCreditService (line 10) | class PermissiveCreditService extends BaseService {
    method _init (line 14) | _init () {
    method get_user_credit_ (line 63) | get_user_credit_ (username) {
    method consume_user_credit_ (line 72) | consume_user_credit_ (username, amount) {

FILE: src/backend/src/modules/selfhosted/DevWatcherService.js
  class ProxyLogger (line 26) | class ProxyLogger {
    method constructor (line 27) | constructor (log) {
    method attach (line 30) | attach (stream) {
  class DevWatcherService (line 55) | class DevWatcherService extends BaseService {
    method _init (line 61) | async _init (args) {
    method get_configjs (line 94) | async get_configjs ({ directory, configIsFor, possibleConfigNames }) {
    method start_a_webpack_watcher_ (line 128) | async start_a_webpack_watcher_ (entry) {
  method '__on_ready.webserver' (line 70) | async '__on_ready.webserver' () {

FILE: src/backend/src/modules/selfhosted/SelfHostedModule.js
  class SelfHostedModule (line 22) | class SelfHostedModule extends AdvancedBase {
    method install (line 23) | async install (context) {

FILE: src/backend/src/modules/selfhosted/SelfhostedService.js
  class SelfhostedService (line 22) | class SelfhostedService extends BaseService {
    method _init (line 27) | async _init () {
    method _register_commands (line 31) | _register_commands (commands) {

FILE: src/backend/src/modules/selfhosted/ServeSingeFileService.js
  class ServeSingleFileService (line 21) | class ServeSingleFileService extends BaseService {
    method _init (line 22) | async _init (args) {
  method '__on_install.routes' (line 26) | async '__on_install.routes' () {

FILE: src/backend/src/modules/selfhosted/ServeStaticFilesService.js
  class ServeStaticFilesService (line 21) | class ServeStaticFilesService extends BaseService {
    method _init (line 22) | async _init (args) {
  method '__on_install.routes' (line 26) | async '__on_install.routes' () {

FILE: src/backend/src/modules/template/TemplateModule.js
  class TemplateModule (line 29) | class TemplateModule extends AdvancedBase {
    method install (line 30) | async install (context) {

FILE: src/backend/src/modules/template/TemplateService.js
  class TemplateService (line 28) | class TemplateService extends BaseService {
    method _construct (line 35) | _construct () {
    method _init (line 39) | async _init () {
  method '__on_install.routes' (line 48) | '__on_install.routes' (_, { app }) {
  method '__on_boot.consolidation' (line 64) | '__on_boot.consolidation' () {
  method '__on_boot.activation' (line 84) | '__on_boot.activation' () {
  method '__on_start.webserver' (line 91) | '__on_start.webserver' () {

FILE: src/backend/src/modules/test-config/TestConfigModule.js
  class TestConfigModule (line 3) | class TestConfigModule extends AdvancedBase {
    method install (line 4) | async install (context) {

FILE: src/backend/src/modules/test-config/TestConfigReadService.js
  class TestConfigReadService (line 3) | class TestConfigReadService extends BaseService {
    method _init (line 4) | async _init () {

FILE: src/backend/src/modules/test-config/TestConfigUpdateService.js
  class TestConfigUpdateService (line 3) | class TestConfigUpdateService extends BaseService {
    method _run_as_early_as_possible (line 4) | async _run_as_early_as_possible () {

FILE: src/backend/src/modules/test-core/TestCoreModule.js
  class TestCoreModule (line 26) | class TestCoreModule {
    method install (line 27) | async install (context) {

FILE: src/backend/src/modules/test-drivers/TestAssetHostService.js
  class TestAssetHostService (line 22) | class TestAssetHostService extends BaseService {
  method '__on_install.routes' (line 23) | async '__on_install.routes' () {

FILE: src/backend/src/modules/test-drivers/TestDriversModule.js
  class TestDriversModule (line 22) | class TestDriversModule extends AdvancedBase {
    method install (line 23) | async install (context) {

FILE: src/backend/src/modules/test-drivers/TestImageService.js
  constant PUBLIC_DOMAIN_IMAGES (line 25) | const PUBLIC_DOMAIN_IMAGES = [
  class TestImageService (line 33) | class TestImageService extends BaseService {
    method get_version (line 72) | get_version () {
    method echo_image (line 77) | async echo_image ({
    method get_image (line 86) | async get_image ({
  method '__on_driver.register.interfaces' (line 34) | async '__on_driver.register.interfaces' () {

FILE: src/backend/src/modules/web/APIErrorService.js
  class APIErrorService (line 37) | class APIErrorService extends BaseService {
    method _construct (line 38) | _construct () {
    method register (line 52) | register (codes) {
    method create (line 58) | create (code, fields) {

FILE: src/backend/src/modules/web/SocketioService.js
  class SocketioService (line 30) | class SocketioService extends BaseService {
    method send (line 60) | async send (socket_specifiers, key, data) {
    method has (line 80) | has (socket_specifier) {
  method '__on_install.socketio' (line 36) | '__on_install.socketio' (_, { server }) {

FILE: src/backend/src/modules/web/WebModule.js
  class WebModule (line 28) | class WebModule extends AdvancedBase {
    method install (line 29) | async install (context) {

FILE: src/backend/src/modules/web/WebServerService.d.ts
  class WebServerService (line 7) | class WebServerService extends BaseService {

FILE: src/backend/src/modules/web/WebServerService.js
  class WebServerService (line 53) | class WebServerService extends BaseService {
    method allow_undefined_origin (line 70) | allow_undefined_origin (route) {
    method install_post_middlewares_ (line 109) | install_post_middlewares_ ({ app }) {
    method get_server (line 330) | get_server () {
    method _init (line 339) | async _init () {
  method '__on_boot.consolidation' (line 82) | async '__on_boot.consolidation' () {
  method '__on_boot.activation' (line 133) | async '__on_boot.activation' () {
  method '__on_start.webserver' (line 148) | async '__on_start.webserver' () {

FILE: src/backend/src/om/IdentifierUtil.js
  class IdentifierUtil (line 24) | class IdentifierUtil extends AdvancedBase {
    method detect_identifier (line 29) | async detect_identifier (object, allow_mutation = false) {

FILE: src/backend/src/om/definitions/Mapping.js
  class Mapping (line 30) | class Mapping extends AdvancedBase {
    method create (line 40) | static create (context, data) {
    method get_client_safe (line 55) | async get_client_safe (data) {

FILE: src/backend/src/om/definitions/PropType.js
  class PropType (line 22) | class PropType extends AdvancedBase {
    method create (line 27) | static create (context, data, k) {
    method populate_subtype_ (line 58) | populate_subtype_ (chains) {
    method adapt (line 67) | async adapt (value, extra) {
    method sql_dereference (line 79) | async sql_dereference (value, extra) {
    method sql_reference (line 89) | async sql_reference (value, extra) {
    method validate (line 99) | async validate (value, extra) {
    method factory (line 112) | async factory (extra) {
    method is_set (line 131) | async is_set (value) {

FILE: src/backend/src/om/definitions/Property.js
  class Property (line 22) | class Property extends AdvancedBase {
    method create (line 27) | static create (context, name, descriptor) {
    method constructor (line 46) | constructor (...a) {
    method adapt (line 50) | async adapt (value) {
    method sql_dereference (line 63) | async sql_dereference (value) {
    method sql_reference (line 68) | async sql_reference (value) {
    method validate (line 73) | async validate (value) {
    method factory (line 82) | async factory () {
    method is_set (line 91) | async is_set (value) {

FILE: src/backend/src/om/entitystorage/AppES.js
  constant APP_UID_ALIAS_KEY_PREFIX (line 33) | const APP_UID_ALIAS_KEY_PREFIX = 'app:canonicalUidAlias';
  constant APP_UID_ALIAS_REVERSE_KEY_PREFIX (line 34) | const APP_UID_ALIAS_REVERSE_KEY_PREFIX = 'app:canonicalUidAliasReverse';
  constant APP_UID_ALIAS_TTL_SECONDS (line 35) | const APP_UID_ALIAS_TTL_SECONDS = 60 * 60 * 24 * 90;
  class AppES (line 103) | class AppES extends BaseES {
    method _on_context_provided (line 105) | async _on_context_provided () {
    method create_predicate (line 116) | async create_predicate (id, ...args) {
    method delete (line 130) | async delete (uid, _extra) {
    method read (line 135) | async read (uid) {
    method select (line 159) | async select (options) {
    method upsert (line 196) | async upsert (entity, extra) {
    method retry_predicate_rewrite (line 381) | async retry_predicate_rewrite ({ predicate }) {
    method queueIconMigration (line 407) | async queueIconMigration (entity) {
    method read_transform (line 453) | async read_transform (entity) {
    method maybe_insert_subdomain_ (line 571) | async maybe_insert_subdomain_ (entity) {
    method ensurePuterSiteSubdomainIsOwned (line 608) | async ensurePuterSiteSubdomainIsOwned (entity, extra, user) {
    method is_puter_hosted_index_url_ (line 632) | is_puter_hosted_index_url_ (index_url) {
    method build_equivalent_index_url_candidates_ (line 636) | build_equivalent_index_url_candidates_ (index_url) {
    method find_index_url_conflict_ (line 663) | async find_index_url_conflict_ ({ indexUrl, excludeMysqlId }) {
    method resolve_entity_mysql_id_ (line 699) | async resolve_entity_mysql_id_ (entity) {
    method claim_app_ownership_by_id_for_user_ (line 726) | async claim_app_ownership_by_id_for_user_ ({ appId, userId }) {
    method build_canonical_app_uid_alias_key_ (line 736) | build_canonical_app_uid_alias_key_ (oldAppUid) {
    method build_canonical_app_uid_alias_reverse_key_ (line 740) | build_canonical_app_uid_alias_reverse_key_ (canonicalAppUid) {
    method normalize_canonical_alias_uid_list_ (line 744) | normalize_canonical_alias_uid_list_ (value) {
    method read_canonical_app_uid_alias_ (line 757) | async read_canonical_app_uid_alias_ (oldAppUid) {
    method write_canonical_app_uid_alias_ (line 778) | async write_canonical_app_uid_alias_ ({ oldAppUid, canonicalAppUid }) {
    method maybe_join_owned_hosted_index_url_app_on_create_ (line 816) | async maybe_join_owned_hosted_index_url_app_on_create_ (entity, extra,...
    method apply_joined_requested_name_ (line 899) | async apply_joined_requested_name_ ({ canonicalUid, requestedName }) {
    method is_origin_bootstrap_app_entity_ (line 933) | async is_origin_bootstrap_app_entity_ (entity) {
    method ensureIndexUrlUnique (line 944) | async ensureIndexUrlUnique (entity, extra) {

FILE: src/backend/src/om/entitystorage/AppLimitedES.js
  class AppLimitedES (line 27) | class AppLimitedES extends BaseES {
    method select (line 32) | async select (options) {
    method read (line 66) | async read (uid) {
    method upsert (line 102) | async upsert (entity, extra) {
    method delete (line 112) | async delete (uid, extra) {
    method _check_edit_allowed (line 120) | async _check_edit_allowed ({ old_entity }) {

FILE: src/backend/src/om/entitystorage/BaseES.js
  class BaseES (line 25) | class BaseES extends AdvancedBase {
    method upsert (line 32) | async upsert (entity, extra) {
    method read (line 38) | async read (uid) {
    method delete (line 44) | async delete (uid, extra) {
    method select (line 50) | async select (options) {
    method create_predicate (line 56) | async create_predicate (id, ...args) {
    method constructor (line 64) | constructor (...a) {
    method provide_context (line 86) | async provide_context ( args ) {
    method read (line 95) | async read (uid) {
    method upsert (line 107) | async upsert (entity, extra) {
    method delete (line 110) | async delete (uid, extra) {
    method select (line 114) | async select (options) {
    method retry_predicate_rewrite (line 125) | async retry_predicate_rewrite ({ predicate }) {
    method read_transform (line 130) | async read_transform (entity) {
    method call_on_impl_ (line 138) | call_on_impl_ (method_name, ...args) {

FILE: src/backend/src/om/entitystorage/ESBuilder.js
  class ESBuilder (line 19) | class ESBuilder {
    method create (line 20) | static create (list) {

FILE: src/backend/src/om/entitystorage/Entity.js
  class Entity (line 22) | class Entity extends AdvancedBase {
    method constructor (line 27) | constructor (args) {
    method create (line 37) | static async create (args, data) {
    method clone (line 49) | async clone () {
    method apply (line 74) | async apply (other) {
    method set (line 83) | async set (key, value) {
    method get (line 91) | async get (key) {
    method del (line 128) | async del (key) {
    method has (line 136) | async has (key) {
    method check (line 144) | async check (condition) {
    method om_has_property (line 148) | om_has_property (key) {
    method is_set (line 153) | async is_set (key) {
    method get_client_safe (line 157) | async get_client_safe () {

FILE: src/backend/src/om/entitystorage/MaxLimitES.js
  class MaxLimitES (line 21) | class MaxLimitES extends BaseES {
    method select (line 23) | async select (options) {

FILE: src/backend/src/om/entitystorage/NotificationES.js
  class NotificationES (line 22) | class NotificationES extends BaseES {
    method create_predicate (line 24) | async create_predicate (id) {
    method read_transform (line 46) | async read_transform (entity) {

FILE: src/backend/src/om/entitystorage/OwnerLimitedES.js
  class OwnerLimitedES (line 24) | class OwnerLimitedES extends BaseES {
    method select (line 26) | async select (options) {
    method read (line 46) | async read (uid) {

FILE: src/backend/src/om/entitystorage/ProtectedAppES.js
  class ProtectedAppES (line 24) | class ProtectedAppES extends BaseES {
    method select (line 25) | async select (options) {
    method read (line 43) | async read (uid) {
    method check_ (line 60) | async check_ ({ actor, services }, entity) {

FILE: src/backend/src/om/entitystorage/ReadOnlyES.js
  class ReadOnlyES (line 22) | class ReadOnlyES extends BaseES {
    method upsert (line 23) | async upsert () {
    method delete (line 26) | async delete () {

FILE: src/backend/src/om/entitystorage/SQLES.js
  class RawCondition (line 30) | class RawCondition extends AdvancedBase {
  class SQLES (line 37) | class SQLES extends BaseES {
    method _on_context_provided (line 38) | async _on_context_provided () {
    method create_predicate (line 43) | async create_predicate (id, args) {
    method read (line 48) | async read (uid) {
    method select (line 92) | async select ({ predicate, limit, offset }) {
    method upsert (line 124) | async upsert (entity, extra) {
    method delete (line 166) | async delete (uid) {
    method sql_row_to_entity_ (line 187) | async sql_row_to_entity_ (data) {
    method create_ (line 221) | async create_ (entity) {
    method update_ (line 243) | async update_ (entity, old_entity) {
    method get_sql_data_ (line 276) | async get_sql_data_ (entity) {
    method om_to_sql_condition_ (line 317) | async om_to_sql_condition_ (om_query) {

FILE: src/backend/src/om/entitystorage/SetOwnerES.js
  class SetOwnerES (line 24) | class SetOwnerES extends BaseES {
    method upsert (line 26) | async upsert (entity, extra) {
    method read (line 50) | async read (uid) {
    method select (line 58) | async select (...args) {
    method _sanitize_owner (line 65) | async _sanitize_owner (entity) {

FILE: src/backend/src/om/entitystorage/SubdomainES.js
  constant PERM_READ_ALL_SUBDOMAINS (line 27) | const PERM_READ_ALL_SUBDOMAINS = 'read-all-subdomains';
  class SubdomainES (line 29) | class SubdomainES extends BaseES {
    method _on_context_provided (line 30) | async _on_context_provided () {
    method create_predicate (line 34) | async create_predicate (id) {
    method upsert (line 42) | async upsert (entity, extra) {
    method select (line 49) | async select (options) {
    method _check_max_subdomains (line 68) | async _check_max_subdomains () {

FILE: src/backend/src/om/entitystorage/ValidationES.js
  class ValidationES (line 25) | class ValidationES extends BaseES {
    method _on_context_provided (line 26) | async _on_context_provided () {
    method upsert (line 41) | async upsert (entity, extra) {
    method validate_ (line 60) | async validate_ (entity, diff) {

FILE: src/backend/src/om/entitystorage/WriteByOwnerOnlyES.js
  constant WRITE_ALL_OWNER_ES (line 23) | const WRITE_ALL_OWNER_ES = 'system:es:write-all-owners';
  class WriteByOwnerOnlyES (line 29) | class WriteByOwnerOnlyES extends BaseES {
    method upsert (line 40) | async upsert (entity, extra) {
    method delete (line 56) | async delete (uid, extra) {
    method _check_allowed (line 71) | async _check_allowed ({ old_entity }) {

FILE: src/backend/src/om/mappings/subdomain.js
  method adapt (line 45) | async adapt (value) {
  method validate (line 48) | async validate (value) {
  method adapt (line 65) | async adapt (value) {

FILE: src/backend/src/om/proptypes/__all__.js
  constant NULL (line 29) | const NULL = Symbol('NULL');
  constant APP_ICON_ENDPOINT_PATH_REGEX (line 30) | const APP_ICON_ENDPOINT_PATH_REGEX = /^\/app-icon\/([^/?#]+)(?:\/(\d+))?...
  constant LEGACY_APP_ICON_FILE_PATH_REGEX (line 31) | const LEGACY_APP_ICON_FILE_PATH_REGEX = /^\/(app-[^/?#]+?)(?:-(\d+))?\.p...
  constant ABSOLUTE_URL_REGEX (line 32) | const ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
  constant RAW_BASE64_REGEX (line 33) | const RAW_BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/;
  class OMTypeError (line 210) | class OMTypeError extends Error {
    method constructor (line 211) | constructor ({ expected, got }) {
  method is_set (line 220) | is_set (value) {
  method is_set (line 228) | is_set (value) {
  method adapt (line 231) | async adapt (value) {
  method validate (line 247) | validate (value, { name, descriptor }) {
  method validate (line 265) | validate (value, { name, descriptor }) {
  method validate (line 296) | validate (value) {
  method validate (line 302) | validate (value, { descriptor }) {
  method factory (line 309) | factory ({ descriptor }) {
  method is_set (line 317) | is_set (value) {
  method adapt (line 320) | adapt (value) {
  method validate (line 332) | validate (value) {
  method validate (line 360) | validate (value) {
  method sql_reference (line 370) | async sql_reference (value, { descriptor }) {
  method sql_dereference (line 378) | async sql_dereference (value, { descriptor }) {
  method adapt (line 385) | async adapt (value, { descriptor }) {
  method sql_reference (line 399) | async sql_reference (value) {
  method is_set (line 407) | async is_set (value) {
  method sql_dereference (line 410) | async sql_dereference (value) {
  method adapt (line 418) | async adapt (value, { name }) {
  method validate (line 457) | async validate (value, { descriptor }) {

FILE: src/backend/src/om/query/query.js
  class Predicate (line 22) | class Predicate extends AdvancedBase {
  class Null (line 28) | class Null extends Predicate {
  class And (line 32) | class And extends Predicate {
  class Or (line 36) | class Or extends Predicate {
    method check (line 37) | async check (entity) {
  class Eq (line 47) | class Eq extends Predicate {
    method check (line 48) | async check (entity) {
  class StartsWith (line 53) | class StartsWith extends Predicate {
    method check (line 54) | async check (entity) {
  class IsNotNull (line 59) | class IsNotNull extends Predicate {
    method check (line 60) | async check (entity) {
  class Like (line 65) | class Like extends Predicate {
    method check (line 66) | async check (entity) {
  class PredicateUtil (line 78) | class PredicateUtil {
    method simplify (line 79) | static simplify (predicate) {
    method write_human_readable (line 121) | static write_human_readable (predicate) {

FILE: src/backend/src/routers/auth/oidc.js
  constant REVALIDATION_COOKIE_NAME (line 25) | const REVALIDATION_COOKIE_NAME = 'puter_revalidation';
  constant REVALIDATION_EXPIRY_SEC (line 26) | const REVALIDATION_EXPIRY_SEC = 300;
  constant MISSING_CODE_OR_STATE (line 28) | const MISSING_CODE_OR_STATE = Symbol('MISSING_CODE_OR_STATE');
  constant INVALID_OR_EXPIRED_STATE (line 29) | const INVALID_OR_EXPIRED_STATE = Symbol('INVALID_OR_EXPIRED_STATE');
  constant TOKEN_EXCHANGE_FAILED (line 30) | const TOKEN_EXCHANGE_FAILED = Symbol('TOKEN_EXCHANGE_FAILED');
  constant COULD_NOT_GET_USER_INFO (line 31) | const COULD_NOT_GET_USER_INFO = Symbol('COULD_NOT_GET_USER_INFO');
  constant OIDC_CALLBACK_ERROR_RESPONSES (line 33) | const OIDC_CALLBACK_ERROR_RESPONSES = {
  constant OIDC_ERROR_REDIRECT_MAP (line 40) | const OIDC_ERROR_REDIRECT_MAP = {
  function buildOIDCErrorRedirectUrl (line 67) | function buildOIDCErrorRedirectUrl (sourceFlow, errorCondition, message,...
  function appendQueryParam (line 88) | function appendQueryParam (url, key, value) {

FILE: src/backend/src/routers/auth/revoke-access-token.js
  function tokenOrUuidFromInput (line 28) | function tokenOrUuidFromInput (value) {

FILE: src/backend/src/routers/change_email.js
  constant CHANGE_EMAIL_CONFIRM (line 29) | const CHANGE_EMAIL_CONFIRM = eggspress('/change_email/confirm', {

FILE: src/backend/src/routers/filesystem_api/batch/PathResolver.js
  constant ERR_INVALID_PATHREF (line 21) | const ERR_INVALID_PATHREF = 'Invalid path reference in path: ';
  constant ERR_UNKNOWN_PATHREF (line 22) | const ERR_UNKNOWN_PATHREF = 'Unknown path reference in path: ';
  method constructor (line 36) | constructor ({ actor }) {
  method putPath (line 55) | putPath (refName, path) {
  method putSelector (line 59) | putSelector (refName, selector, meta) {
  method resolve (line 79) | resolve (inputPath) {
  method awaitSelector (line 90) | async awaitSelector (inputPath) {
  method getMeta (line 123) | getMeta (inputPath) {
  method getReferenceUsed (line 130) | getReferenceUsed (inputPath) {

FILE: src/backend/src/routers/get-launch-apps.test.js
  constant TEST_UUID_NAMESPACE (line 30) | const TEST_UUID_NAMESPACE = '5568ab95-229d-4d87-b98c-0b12680a9524';

FILE: src/backend/src/routers/hosting/puter-site-config.js
  constant ERROR_CLASS_REGEX (line 21) | const ERROR_CLASS_REGEX = /^([45])xx$/i;
  constant STATUS_CODE_REGEX (line 22) | const STATUS_CODE_REGEX = /^[1-5][0-9][0-9]$/;

FILE: src/backend/src/routers/hosting/puterSiteMiddleware.js
  constant AT_DIRECTORY_NAMESPACE (line 57) | const AT_DIRECTORY_NAMESPACE = '4aa6dc52-34c1-4b8a-b63c-a62b27f727cf';
  function isPrivateApp (line 62) | function isPrivateApp (app) {
  function normalizeConfiguredHostname (line 66) | function normalizeConfiguredHostname (hostValue) {
  function getPrivateHostingDomainsForMatch (line 77) | function getPrivateHostingDomainsForMatch () {
  function getPrivateHostingDomainForRedirect (line 91) | function getPrivateHostingDomainForRedirect () {
  function hostMatchesPrivateDomain (line 101) | function hostMatchesPrivateDomain (hostname) {
  function getSubdomainFromHostedRequest (line 110) | function getSubdomainFromHostedRequest (req) {
  function getRequestedPrivateHost (line 130) | function getRequestedPrivateHost (req) {
  function buildPrivateHostRedirectUrl (line 137) | function buildPrivateHostRedirectUrl (req, app) {
  function normalizeHostFromHeader (line 167) | function normalizeHostFromHeader (hostValue) {
  function normalizeConfiguredHost (line 178) | function normalizeConfiguredHost (hostValue) {
  function buildPrivateAppIndexUrlCandidates (line 185) | function buildPrivateAppIndexUrlCandidates (req) {
  function resolvePrivateAppForHostedSite (line 231) | async function resolvePrivateAppForHostedSite ({ req, site, services, as...
  function getPrivateDeniedRedirectUrl (line 258) | function getPrivateDeniedRedirectUrl (app, denyRedirectUrl) {
  function getMarketplaceAppUrl (line 271) | function getMarketplaceAppUrl (app) {
  function appendLinkHeader (line 283) | function appendLinkHeader (res, linkValue) {
  function setReferrerPolicyHeader (line 307) | function setReferrerPolicyHeader (res, policyValue = 'no-referrer') {
  function isPrivateAccessGateEnabled (line 319) | function isPrivateAccessGateEnabled () {
  function logPrivateAccessEvent (line 323) | function logPrivateAccessEvent (eventName, fields = {}) {
  function getPrivateAccessRejectionReason (line 330) | function getPrivateAccessRejectionReason (error) {
  function stripBootstrapAuthTokenFromOriginalUrl (line 334) | function stripBootstrapAuthTokenFromOriginalUrl (originalUrl) {
  function hasAppInstanceIdQueryParam (line 356) | function hasAppInstanceIdQueryParam (req) {
  function getTokenFromAuthorizationHeader (line 381) | function getTokenFromAuthorizationHeader (req) {
  function getBootstrapTokenFromReferrer (line 388) | function getBootstrapTokenFromReferrer (req) {
  function getBootstrapPrivateToken (line 403) | function getBootstrapPrivateToken (req) {
  function getBootstrapPrivateTokenSource (line 426) | function getBootstrapPrivateTokenSource (req) {
  function actorToPrivateIdentity (line 449) | function actorToPrivateIdentity (actor) {
  function resolvePrivateIdentity (line 479) | async function resolvePrivateIdentity ({ req, services, appUid }) {
  function getPublicHostedActorCookieName (line 667) | function getPublicHostedActorCookieName (authService) {
  function getRequestedHostedHost (line 674) | function getRequestedHostedHost (req) {
  function buildLightweightHostedActor (line 679) | function buildLightweightHostedActor ({ userUid, sessionUuid }) {
  function setHostedActorOnRequestContext (line 694) | function setHostedActorOnRequestContext ({ req, actor }) {
  function resolvePublicHostedIdentity (line 700) | async function resolvePublicHostedIdentity ({ req, services, appUid }) {
  function evaluatePublicHostedActorContext (line 840) | async function evaluatePublicHostedActorContext ({
  function escapeHtml (line 938) | function escapeHtml (value) {
  function respondPrivateLoginBootstrap (line 948) | function respondPrivateLoginBootstrap ({ res, app }) {
  function evaluatePrivateAppAccess (line 1152) | async function evaluatePrivateAppAccess ({ req, res, services, app, requ...
  function runInternal (line 1280) | async function runInternal (req, res, next) {
  function respondSiteError (line 1695) | async function respondSiteError ({ path, html, req, res, next, subdomain...
  function getSiteErrorConfig (line 1708) | async function getSiteErrorConfig (req, subdomainRootPath) {
  function getSiteFileNode (line 1758) | async function getSiteFileNode (subdomainRootPath, sitePath) {
  function maybeRespondWithSiteConfig (line 1771) | async function maybeRespondWithSiteConfig ({
  function streamSiteFile (line 1810) | async function streamSiteFile ({ req, res, fsNode, status }) {
  function respond404 (line 1831) | async function respond404 ({ path, html }, req, res, next, subdomainRoot...
  function respondHtmlError (line 1858) | function respondHtmlError ({ path, html, status = 404 }, req, res, _next) {
  function respondError (line 1885) | function respondError ({ req, res, e }) {
  function puterSiteMiddleware (line 1898) | async function puterSiteMiddleware (req, res, next) {

FILE: src/backend/src/routers/hosting/puterSiteMiddleware.test.js
  class UserActorType (line 106) | class UserActorType {
    method constructor (line 107) | constructor ({ user, session, hasHttpOnlyCookie } = {}) {
  class SiteActorType (line 113) | class SiteActorType {
  class Actor (line 115) | class Actor {
    method constructor (line 116) | constructor ({ user_uid, app_uid, type } = {}) {
    method get_related_actor (line 122) | get_related_actor (actorType) {
  method create (line 140) | static create () {

FILE: src/backend/src/routers/puterai/openai/chat_completions.js
  constant DEFAULT_PROVIDER (line 27) | const DEFAULT_PROVIDER = 'openai-completion';

FILE: src/backend/src/routers/puterai/openai/completions.js
  constant DEFAULT_PROVIDER (line 27) | const DEFAULT_PROVIDER = 'openai-completion';

FILE: src/backend/src/routers/query/app.js
  constant PREFIX_APP_UID (line 25) | const PREFIX_APP_UID = 'app-';

FILE: src/backend/src/routers/save_account.js
  constant SECOND (line 29) | const SECOND = 1000;

FILE: src/backend/src/routers/set-pass-using-token.js
  constant SAFE_NEGATIVE_RESPONSE (line 29) | const SAFE_NEGATIVE_RESPONSE = 'This password recovery token is no longe...

FILE: src/backend/src/routers/signup.js
  function generate_random_username (line 30) | async function generate_random_username () {

FILE: src/backend/src/routers/signup_create_new_user.js
  function signup_create_new_user (line 32) | async function signup_create_new_user (services, options) {

FILE: src/backend/src/routers/user-protected/delete-own-user.js
  constant REVALIDATION_COOKIE_NAME (line 22) | const REVALIDATION_COOKIE_NAME = 'puter_revalidation';

FILE: src/backend/src/routers/verify-pass-recovery-token.js
  constant SAFE_NEGATIVE_RESPONSE (line 28) | const SAFE_NEGATIVE_RESPONSE = 'This password recovery token is no longe...

FILE: src/backend/src/routers/writeFile.js
  method get_dest_node (line 84) | async get_dest_node () {

FILE: src/backend/src/services/AWSSecretsPopulator.js
  class AWSSecretsPopulator (line 5) | class AWSSecretsPopulator extends BaseService {
    method _run_as_early_as_possible (line 6) | async _run_as_early_as_possible () {

FILE: src/backend/src/services/AnomalyService.js
  constant DENY_SERVICE_INSTRUCTION (line 22) | const DENY_SERVICE_INSTRUCTION = Symbol('DENY_SERVICE_INSTRUCTION');
  class AnomalyService (line 30) | class AnomalyService extends BaseService {
    method _construct (line 40) | _construct () {
    method register (line 53) | register (type, config) {
    method note (line 76) | async note (id, data) {

FILE: src/backend/src/services/BaseService.d.ts
  type ServicesMap (line 23) | interface ServicesMap {
  type ServiceResources (line 47) | interface ServiceResources {
  type EventHandler (line 61) | type EventHandler = (id: string, ...args: any[]) => any;
  type Logger (line 63) | interface Logger {
  class BaseService (line 69) | class BaseService {

FILE: src/backend/src/services/BaseService.js
  class BaseService (line 38) | class BaseService extends concepts.Service {
    method constructor (line 39) | constructor (service_resources, ...a) {
    method run_as_early_as_possible (line 64) | async run_as_early_as_possible () {
    method construct (line 74) | async construct () {
    method init (line 93) | async init () {
    method __on (line 124) | async __on (id, args) {
    method __get_event_handler (line 130) | __get_event_handler (id) {

FILE: src/backend/src/services/BootScriptService.js
  class BootScriptService (line 30) | class BootScriptService extends BaseService {
    method run_script (line 66) | async run_script (boot_json) {
  method '__on_boot.ready' (line 44) | async '__on_boot.ready' () {

FILE: src/backend/src/services/ChatAPIService.js
  class ChatAPIService (line 30) | class ChatAPIService extends BaseService {
    method install_chat_endpoints_ (line 64) | install_chat_endpoints_ ({ router }) {
  method '__on_install.routes' (line 43) | async '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/CleanEmailService.js
  class CleanEmailService (line 29) | class CleanEmailService extends BaseService {
    method _construct (line 89) | _construct () {
    method clean (line 106) | clean (email) {
    method validate (line 154) | async validate (email) {

FILE: src/backend/src/services/ClientOperationService.js
  constant CONTEXT_KEY (line 22) | const CONTEXT_KEY = Context.make_context_key('operation-trace');
  class ClientOperationTracker (line 29) | class ClientOperationTracker {
    method constructor (line 30) | constructor (parameters) {
  class ClientOperationService (line 46) | class ClientOperationService {
    method constructor (line 47) | constructor ({ services }) {
    method add_operation (line 57) | async add_operation (parameters) {
    method ckey (line 63) | ckey (key) {

FILE: src/backend/src/services/CommandService.js
  class Command (line 29) | class Command {
    method constructor (line 30) | constructor (spec) {
    method id (line 38) | get id () {
    method execute (line 49) | async execute (args, log) {
    method completeArgument (line 60) | completeArgument (args) {
  class CommandService (line 77) | class CommandService extends BaseService {
    method _construct (line 82) | async _construct () {
    method _init (line 89) | async _init () {
    method registerCommands (line 126) | registerCommands (serviceName, commands) {
    method executeCommand (line 155) | async executeCommand (args, log) {
    method executeRawCommand (line 183) | async executeRawCommand (text, log) {
    method commandNames (line 193) | get commandNames () {
    method getCommand (line 197) | getCommand (id) {
  method '__on_boot.consolidation' (line 102) | async '__on_boot.consolidation' () {

FILE: src/backend/src/services/ConfigurableCountingService.js
  class ConfigurableCountingService (line 39) | class ConfigurableCountingService extends BaseService {
    method _init (line 94) | async _init () {
    method increment (line 111) | async increment ({ service_name, service_type, values }) {

FILE: src/backend/src/services/Container.js
  class Container (line 35) | class Container {
    method constructor (line 36) | constructor ({ logger }) {
    method registerEnforcer (line 50) | registerEnforcer (func) {
    method registerModule (line 54) | registerModule (name, module) {
    method setModuleName (line 72) | setModuleName (name) {
    method registerService (line 83) | registerService (name, cls, args) {
    method patchService (line 125) | patchService (name, patch, args) {
    method get_implementors (line 133) | get_implementors (interface_name) {
    method set (line 139) | set (name, instance) {
    method _get (line 142) | _get (name, opts) {
    method get (line 151) | get (name, opts) {
    method has (line 168) | has (name) {
    method values (line 171) | get values () {
    method init (line 201) | async init () {
    method emit (line 240) | async emit (id, ...args) {
  class ProxyContainer (line 262) | class ProxyContainer {
    method constructor (line 263) | constructor (delegate) {
    method set (line 267) | set (name, instance) {
    method get (line 270) | get (name) {
    method has (line 282) | has (name) {
    method values (line 288) | get values () {

FILE: src/backend/src/services/ContextInitService.js
  class ContextInitExpressMiddleware (line 31) | class ContextInitExpressMiddleware {
    method constructor (line 39) | constructor () {
    method register_initializer (line 42) | register_initializer (initializer) {
    method install (line 45) | install (app) {
    method run (line 53) | async run (req, res, next) {
  class ContextInitService (line 74) | class ContextInitService extends BaseService {
    method _construct (line 82) | _construct () {
    method register_value (line 85) | register_value (key, value) {
    method register_async_factory (line 95) | register_async_factory (key, async_factory) {
  method '__on_install.middlewares.context-aware' (line 100) | async '__on_install.middlewares.context-aware' (_, { app }) {

FILE: src/backend/src/services/DetailProviderService.js
  class DetailProviderService (line 26) | class DetailProviderService extends BaseService {
    method _construct (line 27) | _construct () {
    method register_provider (line 31) | register_provider (fn) {
    method get_details (line 48) | async get_details (context, out) {

FILE: src/backend/src/services/DynamoKVStore/DynamoKVStore.ts
  class DynamoKVStore (line 12) | class DynamoKVStore {
    method constructor (line 23) | constructor ({ ddbClient, sqlClient, tableName, meteringService }: { d...
    method createTableIfNotExists (line 31) | async createTableIfNotExists () {
    method #getNameSpace (line 36) | #getNameSpace (actor: Actor) {
    method get (line 50) | async get ({ key }: { key: string | string[]; }): Promise<unknown | nu...
    method #getBatches (line 119) | async #getBatches (namespace: string, allKeys: string[]) {
    method set (line 144) | async set ({ key, value, expireAt }: { key: string; value: unknown; ex...
    method del (line 178) | async del ({ key }: { key: string; }): Promise<boolean> {
    method #encodeCursor (line 203) | #encodeCursor (pageKey?: Record<string, unknown>) {
    method #decodeCursor (line 210) | #decodeCursor (cursor?: string | Record<string, unknown>) {
    method #normalizeLimit (line 240) | #normalizeLimit (limit?: number) {
    method #normalizePattern (line 254) | #normalizePattern (pattern?: string) {
    method list (line 275) | async list ({
    method flush (line 373) | async flush () {
    method expireAt (line 417) | async expireAt ({ key, timestamp }: { key: string; timestamp: number; ...
    method expire (line 430) | async expire ({ key, ttl }: { key: string; ttl: number; }): Promise<vo...
    method #createPaths (line 445) | async #createPaths ( namespace: string, key: string, pathList: string[...
    method incr (line 533) | async incr<T extends Record<string, number>>({ key, pathAndAmountMap }...
    method decr (line 593) | async decr<T extends Record<string, number>>({ key, pathAndAmountMap }...
    method add (line 598) | async add ({ key, pathAndValueMap }: { key: string; pathAndValueMap: R...
    method remove (line 655) | async remove ({ key, paths }: { key: string; paths: string[]; }): Prom...
    method update (line 717) | async update ({ key, pathAndValueMap, ttl }: { key: string; pathAndVal...
    method #expireAt (line 783) | async #expireAt (key: string, timestamp: number) {

FILE: src/backend/src/services/DynamoKVStore/DynamoKVStoreWrapper.ts
  class DynamoKVStoreServiceWrapper (line 7) | class DynamoKVStoreServiceWrapper extends BaseService {
    method _init (line 10) | async _init () {
    method registerHealthcheck (line 24) | async registerHealthcheck () {
  type IDynamoKVStoreWrapper (line 60) | type IDynamoKVStoreWrapper = DynamoKVStoreServiceWrapper;

FILE: src/backend/src/services/DynamoKVStore/tableDefinition.ts
  constant PUTER_KV_STORE_TABLE_DEFINITION (line 3) | const PUTER_KV_STORE_TABLE_DEFINITION: CreateTableCommandInput = {

FILE: src/backend/src/services/EmailService.js
  constant TEMPLATES (line 22) | const TEMPLATES = {
  class Emailservice (line 203) | class Emailservice extends BaseService {
    method _construct (line 219) | _construct () {
    method _init (line 256) | _init () {
    method get_transport_ (line 267) | get_transport_ () {
    method send_email (line 289) | async send_email (user, template, values) {
    method sendMail (line 305) | sendMail (params) {

FILE: src/backend/src/services/EngPortalService.js
  class EngPortalService (line 31) | class EngPortalService extends AdvancedBase {
    method constructor (line 36) | constructor ({ services }) {
    method list_operations (line 51) | async list_operations () {
    method _serialize_frame (line 62) | _serialize_frame (frame) {
    method list_alarms (line 95) | async list_alarms () {
    method get_stats (line 114) | async get_stats () {
    method _serialize_alarm (line 119) | _serialize_alarm (alarm) {
    method _serialize_occurance (line 136) | _serialize_occurance (occurance) {
    method _registerCommands (line 146) | _registerCommands (commands) {

FILE: src/backend/src/services/EntityStoreService.js
  class EntityStoreService (line 32) | class EntityStoreService extends BaseService {
    method _init (line 46) | async _init (args) {
    method create (line 65) | async create ({ object, options }) {
    method update (line 74) | async update ({ object, id, options }) {
    method upsert (line 78) | async upsert ({ object, id, options }) {
    method read (line 82) | async read ({ uid, id, params = {} }) {
    method select (line 101) | async select (options) {
    method delete (line 114) | async delete ({ uid, id }) {
    method create (line 144) | async create (entity, options) {
    method read (line 154) | async read (uid) {
    method select (line 164) | async select ({ predicate, ...rest }) {
    method update (line 187) | async update (entity, id, options) {
    method upsert (line 232) | async upsert (entity, id, options) {
    method delete (line 269) | async delete (uid) {
    method fetch_based_on_complex_id_ (line 279) | async fetch_based_on_complex_id_ (id) {
    method fetch_based_on_either_id_ (line 333) | async fetch_based_on_either_id_ (uid, id) {

FILE: src/backend/src/services/EntriService.js
  class EntriService (line 39) | class EntriService extends BaseService {
    method _init (line 40) | _init () {
    method _construct (line 44) | async _construct () {
    method getConfig (line 98) | async getConfig ({ domain, userHostedSite }) {
    method deleteMapping (line 177) | async deleteMapping ({ domain }) {
    method fullyRegistered (line 227) | async fullyRegistered ({ domain, userHostedSite }) {
  method '__on_install.routes' (line 48) | '__on_install.routes' (_, { app }) {
  method '__on_driver.register.interfaces' (line 234) | async '__on_driver.register.interfaces' () {

FILE: src/backend/src/services/EventService.js
  class ScopedEventBus (line 27) | class ScopedEventBus {
    method constructor (line 28) | constructor (event_bus, scope) {
    method emit (line 33) | async emit (key, data) {
    method on (line 37) | on (key, callback) {
  class EventService (line 48) | class EventService extends BaseService {
    method _construct (line 57) | async _construct () {
    method emit (line 66) | async emit (key, data, meta) {
    method on (line 133) | on (selector, callback) {
    method on_all (line 151) | on_all (callback) {
    method get_scoped (line 155) | get_scoped (scope) {
  method '__on_boot.ready' (line 62) | async '__on_boot.ready' () {

FILE: src/backend/src/services/FeatureFlagService.js
  class FeatureFlagService (line 36) | class FeatureFlagService extends BaseService {
    method _construct (line 42) | _construct () {
    method _init (line 54) | async _init () {
    method register (line 67) | register (name, spec) {
    method check (line 80) | async check (...a) {
    method get_summary (line 129) | async get_summary (actor) {

FILE: src/backend/src/services/FilesystemAPIService.js
  class FilesystemAPIService (line 30) | class FilesystemAPIService extends BaseService {
  method '__on_install.routes' (line 41) | async '__on_install.routes' () {

FILE: src/backend/src/services/GetUserService.js
  class GetUserService (line 37) | class GetUserService extends BaseService {
    method _construct (line 42) | _construct () {
    method _init (line 59) | async _init () {
    method get_user (line 94) | async get_user (options) {
    method refresh_actor (line 127) | async refresh_actor (actor) {
    method get_user_ (line 137) | async get_user_ (options) {
    method register_id_property (line 174) | register_id_property (prop) {

FILE: src/backend/src/services/HelloWorldService.js
  class HelloWorldService (line 29) | class HelloWorldService extends BaseService {
    method get_version (line 37) | get_version () {
    method greet (line 49) | async greet ({ subject }) {

FILE: src/backend/src/services/HostDiskUsageService.js
  class HostDiskUsageService (line 33) | class HostDiskUsageService extends BaseService {
    method _init (line 51) | async _init () {
    method get_host_usage (line 83) | get_host_usage () {
    method get_extra (line 108) | get_extra () {
    method get_darwin_mountpoint (line 115) | get_darwin_mountpoint (directory) {
    method get_linux_mountpint (line 121) | get_linux_mountpint (directory) {
    method get_windows_drive (line 128) | get_windows_drive (directory) {
    method get_disk_capacity_darwin (line 133) | get_disk_capacity_darwin (mountpoint) {
    method get_disk_capacity_linux (line 140) | get_disk_capacity_linux (mountpoint) {
    method get_disk_capacity_windows (line 147) | get_disk_capacity_windows (drive) {
    method get_disk_use_darwin (line 152) | get_disk_use_darwin (mountpoint) {
    method get_disk_use_linux (line 159) | get_disk_use_linux (mountpoint) {
    method get_disk_use_windows (line 166) | get_disk_use_windows (drive) {

FILE: src/backend/src/services/HostnameService.js
  class HostnameService (line 5) | class HostnameService extends BaseService {
    method _construct (line 6) | _construct () {
    method _init (line 10) | _init () {
    method get_broadcast_addresses (line 27) | get_broadcast_addresses () {

FILE: src/backend/src/services/KernelInfoService.js
  constant PERM_SEE_ALL (line 27) | const PERM_SEE_ALL = 'kernel-info:see-all-services';
  constant PERM_SEE_DRIVERS (line 29) | const PERM_SEE_DRIVERS = 'kernel-info:see-all-drivers';
  class KernelInfoService (line 38) | class KernelInfoService extends BaseService {
    method _init (line 39) | async _init () {
  method '__on_install.routes' (line 49) | '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/LocalDiskStorageService.js
  class LocalDiskStorageService (line 32) | class LocalDiskStorageService extends BaseService {
    method _init (line 64) | async _init () {
    method _get_path (line 75) | _get_path (key) {
    method store_stream (line 96) | async store_stream ({ key, size, stream, on_progress }) {
    method store_buffer (line 131) | async store_buffer ({ key, buffer }) {
    method create_read_stream (line 147) | async create_read_stream (uid, options = {}) {
    method copy (line 184) | async copy ({ src_key, dst_key }) {
    method delete (line 203) | async delete ({ key }) {
  method '__on_install.context-initializers' (line 46) | async '__on_install.context-initializers' () {

FILE: src/backend/src/services/LockService.js
  class LockService (line 29) | class LockService extends BaseService {
    method _construct (line 35) | async _construct () {
    method _init (line 47) | async _init () {
    method lock (line 93) | async lock (name, opt_options, callback) {

FILE: src/backend/src/services/MakeProdDebuggingLessAwfulService.js
  class MakeProdDebuggingLessAwfulService (line 29) | class MakeProdDebuggingLessAwfulService extends BaseService {
    method constructor (line 50) | constructor () {
    method install (line 53) | install (app) {
    method run (line 64) | async run (req, res, next) {
    method _init (line 71) | async _init () {
  method '__on_install.middlewares.context-aware' (line 113) | async '__on_install.middlewares.context-aware' (_, { app }) {

FILE: src/backend/src/services/MemoryStorageService.js
  class MemoryStorageService (line 23) | class MemoryStorageService extends BaseService {
    method _init (line 24) | async _init () {
    method create_read_stream (line 29) | async create_read_stream (uuid, options) {

FILE: src/backend/src/services/MeteringService/MeteringService.ts
  class MeteringService (line 15) | class MeteringService {
    method constructor (line 24) | constructor ({ kvStore, superUserService, alarmService, eventService }...
    method utilRecordUsageObject (line 34) | utilRecordUsageObject<T extends Record<string, number>>(trackedUsageOb...
    method #getMonthYearString (line 45) | #getMonthYearString () {
    method #generateGloabalUsageKey (line 56) | #generateGloabalUsageKey (userId: string, appId: string, currentMonth:...
    method #generateAppUsageKey (line 62) | #generateAppUsageKey (appId: string, userId: string, currentMonth: str...
    method incrementUsage (line 69) | async incrementUsage (actor: Actor, usageType: (keyof typeof COST_MAPS...
    method batchIncrementUsages (line 233) | async batchIncrementUsages (actor: Actor, usages: { usageType: (keyof ...
    method getActorCurrentMonthUsageDetails (line 413) | async getActorCurrentMonthUsageDetails (actor: Actor) {
    method setActorCurrentMonthUsageTotal (line 458) | async setActorCurrentMonthUsageTotal (actor: Actor, totalCost: number) {
    method getActorCurrentMonthAppUsageDetails (line 532) | async getActorCurrentMonthAppUsageDetails (actor: Actor, appId?: strin...
    method getRemainingUsage (line 552) | async getRemainingUsage (actor: Actor) {
    method getAllowedUsage (line 558) | async getAllowedUsage (actor: Actor) {
    method hasAnyUsage (line 571) | async hasAnyUsage (actor: Actor) {
    method hasEnoughCreditsFor (line 575) | async hasEnoughCreditsFor (actor: Actor, usageType: keyof typeof COST_...
    method hasEnoughCredits (line 581) | async hasEnoughCredits (actor: Actor, amount: number) {
    method getActorSubscription (line 586) | async getActorSubscription (actor: Actor): Promise<(typeof SUB_POLICIE...
    method getActorAddons (line 610) | async getActorAddons (actor: Actor) {
    method getActorAppUsage (line 621) | async getActorAppUsage (actor: Actor, appId: string) {
    method getGlobalUsage (line 639) | async getGlobalUsage () {
    method updateAddonCredit (line 670) | async updateAddonCredit (userId: string, tokenAmount: number) {
    method #checkRateOfChange (line 685) | async #checkRateOfChange () {

FILE: src/backend/src/services/MeteringService/MeteringServiceWrapper.mjs
  class MeteringServiceWrapper (line 4) | class MeteringServiceWrapper extends BaseService {
    method _init (line 8) | _init () {

FILE: src/backend/src/services/MeteringService/consts.ts
  constant GLOBAL_APP_KEY (line 2) | const GLOBAL_APP_KEY = 'os-global';
  constant METRICS_PREFIX (line 3) | const METRICS_PREFIX = 'metering';
  constant POLICY_PREFIX (line 4) | const POLICY_PREFIX = 'policy';
  constant PERIOD_ESCAPE (line 5) | const PERIOD_ESCAPE = '_dot_';
  constant DEFAULT_FREE_SUBSCRIPTION (line 6) | const DEFAULT_FREE_SUBSCRIPTION = 'user_free';
  constant DEFAULT_TEMP_SUBSCRIPTION (line 7) | const DEFAULT_TEMP_SUBSCRIPTION = 'temp_free';

FILE: src/backend/src/services/MeteringService/costMaps/awsPollyCostMap.ts
  constant AWS_POLLY_COST_MAP (line 12) | const AWS_POLLY_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/awsTextractCostMap.ts
  constant AWS_TEXTRACT_COST_MAP (line 12) | const AWS_TEXTRACT_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/claudeCostMap.ts
  constant CLAUDE_COST_MAP (line 20) | const CLAUDE_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/deepSeekCostMap.ts
  constant DEEPSEEK_COST_MAP (line 20) | const DEEPSEEK_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/elevenlabsCostMap.ts
  constant ELEVENLABS_COST_MAP (line 8) | const ELEVENLABS_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/fileSystemCostMap.ts
  constant FILE_SYSTEM_COST_MAP (line 3) | const FILE_SYSTEM_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/geminiCostMap.ts
  constant GEMINI_COST_MAP (line 10) | const GEMINI_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/groqCostMap.ts
  constant GROQ_COST_MAP (line 20) | const GROQ_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/index.ts
  constant COST_MAPS (line 18) | const COST_MAPS = {

FILE: src/backend/src/services/MeteringService/costMaps/kvCostMap.ts
  constant KV_COST_MAP (line 1) | const KV_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/mistralCostMap.ts
  constant MISTRAL_COST_MAP (line 20) | const MISTRAL_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/openAiCostMap.ts
  constant OPENAI_COST_MAP (line 21) | const OPENAI_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/openaiImageCostMap.ts
  constant OPENAI_IMAGE_COST_MAP (line 8) | const OPENAI_IMAGE_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/openaiVideoCostMap.ts
  constant OPENAI_VIDEO_COST_MAP (line 4) | const OPENAI_VIDEO_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/openrouterCostMap.ts
  constant OPENROUTER_COST_MAP (line 1) | const OPENROUTER_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/togetherCostMap.ts
  constant TOGETHER_COST_MAP (line 3) | const TOGETHER_COST_MAP = {

FILE: src/backend/src/services/MeteringService/costMaps/xaiCostMap.ts
  constant XAI_COST_MAP (line 20) | const XAI_COST_MAP = {

FILE: src/backend/src/services/MeteringService/subPolicies/index.ts
  constant SUB_POLICIES (line 4) | const SUB_POLICIES = [

FILE: src/backend/src/services/MeteringService/subPolicies/registeredUserFreePolicy.ts
  constant REGISTERED_USER_FREE (line 4) | const REGISTERED_USER_FREE = {

FILE: src/backend/src/services/MeteringService/subPolicies/tempUserFreePolicy.ts
  constant TEMP_USER_FREE (line 4) | const TEMP_USER_FREE = {

FILE: src/backend/src/services/MeteringService/types.ts
  type UsageAddons (line 6) | interface UsageAddons {
  type RecursiveRecord (line 15) | interface RecursiveRecord<T> { [k: string]: T | RecursiveRecord<T> }
  type UsageRecord (line 17) | interface UsageRecord {
  type UsageByType (line 23) | type UsageByType = { total: number } & Partial<Record<Exclude<string, 't...
  type AppTotals (line 25) | interface AppTotals {
  type MeteringServiceDeps (line 29) | interface MeteringServiceDeps {

FILE: src/backend/src/services/NotificationService.js
  class NotificationService (line 66) | class NotificationService extends BaseService {
    method _construct (line 79) | _construct () {
    method _init (line 89) | async _init () {
    method on_user_connected (line 171) | async on_user_connected ({ user }) {
    method do_on_user_connected (line 193) | async do_on_user_connected ({ user }) {
    method on_sent_to_user (line 253) | async on_sent_to_user ({ user_id, response }) {
    method notify (line 276) | async notify (selector, notification) {
  method '__on_install.routes' (line 117) | '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/OperationTraceService.js
  constant CONTEXT_KEY (line 28) | const CONTEXT_KEY = Context.make_context_key('operation-trace');
  class OperationFrame (line 34) | class OperationFrame {
    method constructor (line 36) | constructor ({ parent, label, x }) {
    method status (line 59) | set status (status) {
    method _calc_effective_status (line 82) | _calc_effective_status () {
    method status (line 121) | get status () {
    method tag (line 125) | tag (...tags) {
    method attr (line 130) | attr (key, value) {
    method get_attr (line 136) | get_attr (key) {
    method log (line 141) | log (message) {
    method error (line 146) | error (err) {
    method push_child (line 151) | push_child (frame) {
    method get_root_frame (line 161) | get_root_frame () {
    method done (line 175) | done () {
    method describe (line 179) | describe (show_tree, highlight_frame) {
  class OperationTraceService (line 226) | class OperationTraceService {
    method constructor (line 229) | constructor ({ services }) {
    method add_frame (line 250) | async add_frame (label) {
    method add_frame_sync (line 254) | add_frame_sync (label, x) {
    method ckey (line 276) | ckey (key) {
  class BaseOperation (line 290) | class BaseOperation extends AdvancedBase {
    method run (line 309) | async run (firstArg, ...rest) {
    method checkpoint (line 366) | checkpoint (name) {
    method field (line 370) | field (key, value) {
    method _post_run (line 381) | _post_run () {

FILE: src/backend/src/services/PeerService.js
  function addDashesToUUID (line 25) | function addDashesToUUID (i) {
  class PeerService (line 29) | class PeerService extends BaseService {
  method '__on_install.routes' (line 30) | '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/PermissionAPIService.js
  class PermissionAPIService (line 32) | class PermissionAPIService extends BaseService {
    method install_group_endpoints_ (line 78) | install_group_endpoints_ ({ router }) {
  method '__on_install.routes' (line 44) | async '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/PuterAPIService.js
  class PuterAPIService (line 35) | class PuterAPIService extends BaseService {
  method '__on_install.routes' (line 41) | async '__on_install.routes' () {

FILE: src/backend/src/services/PuterHomepageService.js
  class PuterHomepageService (line 30) | class PuterHomepageService extends BaseService {
    method _construct (line 34) | _construct () {
    method _init (line 49) | async _init () {
    method register_script (line 63) | register_script (url) {
    method set_gui_param (line 67) | set_gui_param (key, val) {
    method send (line 100) | async send ({ req, res }, meta, launch_options) {
    method generate_puter_page_html (line 209) | async generate_puter_page_html ({
    method generate_error_html (line 442) | generate_error_html ({ message }) {
  method '__on_install.routes' (line 71) | async '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/PuterSiteService.js
  class PuterSiteService (line 34) | class PuterSiteService extends BaseService {
    method _init (line 41) | async _init () {
    method get_subdomain (line 107) | async get_subdomain (subdomain, options) {
    method get_subdomain_by_uid (line 128) | async get_subdomain_by_uid (uid) {

FILE: src/backend/src/services/PuterVersionService.js
  class PuterVersionService (line 29) | class PuterVersionService extends BaseService {
    method _init (line 35) | async _init () {
    method get_version (line 64) | get_version () {
  method '__on_install.routes' (line 46) | async '__on_install.routes' () {

FILE: src/backend/src/services/ReferralCodeService.js
  class ReferralCodeService (line 36) | class ReferralCodeService extends BaseService {
    method _construct (line 37) | _construct () {
    method _init (line 54) | async _init () {
    method gen_referral_code (line 72) | async gen_referral_code (user) {
    method on_verified (line 127) | async on_verified (user) {
    method getMonthlyReferralKey (line 192) | getMonthlyReferralKey (referredByUserId, nowMs = Date.now()) {
    method getNextMonthTimestamp (line 197) | getNextMonthTimestamp (nowMs = Date.now()) {
    method consumeMonthlyReferralSlot (line 209) | async consumeMonthlyReferralSlot (referredByUserId) {
    method getUser (line 228) | async getUser (query) {

FILE: src/backend/src/services/RefreshAssociationsService.js
  class RefreshAssociationsService (line 29) | class RefreshAssociationsService extends BaseService {
  method '__on_boot.consolidation' (line 39) | async '__on_boot.consolidation' () {

FILE: src/backend/src/services/RegistrantService.js
  class RegistrantService (line 30) | class RegistrantService extends BaseService {
    method _init (line 34) | async _init () {
    method _populate_registry (line 50) | async _populate_registry () {

FILE: src/backend/src/services/RegistryService.js
  class MapCollection (line 31) | class MapCollection extends AdvancedBase {
    method constructor (line 32) | constructor () {
    method get (line 40) | get (key) {
    method exists (line 44) | exists (key) {
    method set (line 48) | set (key, value) {
    method del (line 52) | del (key) {
    method keys (line 64) | keys () {
    method _mk_key (line 69) | _mk_key (key) {
  class RegistryService (line 80) | class RegistryService extends BaseService {
    method _construct (line 94) | _construct () {
    method register_collection (line 110) | register_collection (name) {
    method get (line 118) | get (name) {
  method '__on_boot.consolidation' (line 104) | async '__on_boot.consolidation' () {

FILE: src/backend/src/services/RequestMeasureService.js
  class RequestMeasureService (line 3) | class RequestMeasureService extends BaseService {
    method _init (line 17) | _init () {
  method '__on_install.middlewares.context-aware' (line 4) | async '__on_install.middlewares.context-aware' (_, { app }) {

FILE: src/backend/src/services/SNSService.js
  constant MAX_CERT_RETRIES (line 27) | const MAX_CERT_RETRIES = 3;
  constant CERT_RETRY_DELAY (line 28) | const CERT_RETRY_DELAY = 100;
  constant SNS_TYPES (line 36) | const SNS_TYPES = {
  constant CERT_URL_PATTERN (line 45) | const CERT_URL_PATTERN = /^https:\/\/sns\.[a-zA-Z0-9-]{3,}\.amazonaws\.c...
  constant TEST_CERT (line 48) | const TEST_CERT = '';
  constant TEST_MESSAGE (line 50) | const TEST_MESSAGE = {};
  class SNSService (line 52) | class SNSService extends BaseService {
    method _construct (line 53) | _construct () {
    method _init (line 61) | _init () {
    method verify_message_ (line 149) | async verify_message_ (message, options = {}) {
    method get_sns_cert_ (line 171) | async get_sns_cert_ (url) {
  method '__on_install.routes' (line 66) | async '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/SUService.js
  class SUService (line 35) | class SUService extends BaseService {
    method _construct (line 41) | _construct () {
    method get_system_user (line 73) | async get_system_user () {
    method get_system_actor (line 85) | async get_system_actor () {
    method sudo (line 111) | async sudo (actor, callback) {
  method '__on_boot.consolidation' (line 56) | async '__on_boot.consolidation' () {

FILE: src/backend/src/services/ScriptService.js
  class BackendScript (line 26) | class BackendScript {
    method constructor (line 27) | constructor (name, fn) {
    method run (line 40) | async run (ctx, args) {
  class ScriptService (line 50) | class ScriptService extends BaseService {
    method _construct (line 61) | _construct () {
    method _init (line 72) | async _init () {
    method register (line 103) | register (name, fn) {

FILE: src/backend/src/services/ServeGUIService.js
  class ServeGUIService (line 31) | class ServeGUIService extends BaseService {
  method '__on_install.routes-gui' (line 40) | async '__on_install.routes-gui' () {

FILE: src/backend/src/services/ServicePatch.js
  class ServicePatch (line 31) | class ServicePatch extends AdvancedBase {
    method patch (line 32) | patch ({ original_service }) {

FILE: src/backend/src/services/SessionService.js
  constant SECOND (line 24) | const SECOND = 1000;
  constant MINUTE (line 25) | const MINUTE = 60 * SECOND;
  constant SESSION_CACHE_TTL_SECONDS (line 28) | const SESSION_CACHE_TTL_SECONDS = 5 * 60;
  constant SESSION_CACHE_KEY_PREFIX (line 29) | const SESSION_CACHE_KEY_PREFIX = 'session-cache';
  class SessionService (line 46) | class SessionService extends BaseService {
    method _construct (line 47) | _construct () {
    method getSessionCacheKey (line 51) | getSessionCacheKey (uuid) {
    method cacheSession (line 55) | async cacheSession (session) {
    method getCachedSession (line 72) | async getCachedSession (uuid) {
    method invalidateCachedSession (line 97) | async invalidateCachedSession (uuid) {
    method _init (line 116) | async _init () {
    method create_session (line 145) | async create_session (user, meta) {
    method get_session_ (line 182) | async get_session_ (uuid) {
    method get_session (line 216) | async get_session (uuid) {
    method remove_internal_values_ (line 226) | remove_internal_values_ (session) {
    method get_user_sessions (line 238) | get_user_sessions (user) {
    method remove_session (line 254) | async remove_session (uuid) {
    method _update_sessions (line 263) | async _update_sessions () {

FILE: src/backend/src/services/ShareService.js
  class ShareService (line 28) | class ShareService extends BaseService {
    method _init (line 35) | async _init () {
    method install_sharelink_endpoints (line 103) | install_sharelink_endpoints ({ app }) {
    method install_share_endpoint (line 291) | install_share_endpoint ({ app }) {
    method get_share (line 333) | async get_share ({ uid }) {
    method create_share (line 352) | async create_share ({
  method '__on_install.routes' (line 89) | '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/ShutdownService.js
  class ShutdownService (line 29) | class ShutdownService extends BaseService {
    method shutdown (line 30) | shutdown ({ reason, code } = {}) {

FILE: src/backend/src/services/StorageService.js
  class StorageService (line 26) | class StorageService extends AdvancedBase {
    method constructor (line 27) | constructor ({ services }) {

FILE: src/backend/src/services/StrategizedService.js
  class StrategizedService (line 27) | class StrategizedService {
    method constructor (line 28) | constructor (service_resources, ...a) {
    method init (line 60) | async init () {
    method construct (line 64) | async construct () {

FILE: src/backend/src/services/SystemDataService.js
  class SystemDataService (line 33) | class SystemDataService extends BaseService {
    method _init (line 34) | async _init () {
    method interpret (line 46) | async interpret (data) {
    method #dereference (line 76) | async #dereference (data) {

FILE: src/backend/src/services/SystemValidationService.js
  class SystemValidationService (line 32) | class SystemValidationService extends BaseService {
    method mark_invalid (line 42) | async mark_invalid (message, source) {

FILE: src/backend/src/services/TestService.js
  class TestService (line 9) | class TestService extends BaseService {

FILE: src/backend/src/services/User.d.ts
  type IUser (line 3) | interface IUser {

FILE: src/backend/src/services/UserRedisCacheSpace.js
  constant DEFAULT_USER_CACHE_TTL_SECONDS (line 24) | const DEFAULT_USER_CACHE_TTL_SECONDS = 15 * 60;

FILE: src/backend/src/services/UserService.d.ts
  type IInsertResult (line 4) | interface IInsertResult {
  class UserService (line 8) | class UserService extends BaseService {

FILE: src/backend/src/services/UserService.js
  class UserService (line 28) | class UserService extends BaseService {
    method _init (line 33) | async _init () {
    method get_system_dir (line 58) | get_system_dir () {
    method generate_default_fsentries (line 65) | async generate_default_fsentries ({ user }) {
    method updateUserMetadata (line 153) | async updateUserMetadata (userId, updatedMetadata) {
  method '__on_filesystem.ready' (line 38) | async '__on_filesystem.ready' () {

FILE: src/backend/src/services/VerifiedGroupService.js
  class VerifiedGroupService (line 4) | class VerifiedGroupService extends BaseService {
    method _init (line 5) | async _init () {

FILE: src/backend/src/services/WSPushService.js
  class WSPushService (line 21) | class WSPushService extends BaseService {
    method _init (line 30) | async _init () {
    method _on_fs_create (line 55) | async _on_fs_create (key, data) {
    method _on_fs_update (line 103) | async _on_fs_update (key, data) {
    method _on_fs_move (line 149) | async _on_fs_move (key, data) {
    method _on_fs_pending (line 193) | async _on_fs_pending (key, data) {
    method _on_upload_progress (line 235) | async _on_upload_progress (key, data) {
    method _on_submission_done (line 272) | async _on_submission_done (key, data) {
    method _on_outer_gui (line 302) | async _on_outer_gui (key, { user_id_list, response }, meta) {
    method _update_user_ts (line 324) | async _update_user_ts (user_id_list, timestamp, metadata = {}) {

FILE: src/backend/src/services/WebDAV/WebDAVService.js
  constant COOKIE_NAME (line 27) | let COOKIE_NAME = null;
  constant ROOT_WEB_DAV_RESPONSE_XML (line 29) | const ROOT_WEB_DAV_RESPONSE_XML = `<?xml version="1.0" encoding="utf-8"?>
  class WebDAVService (line 83) | class WebDAVService extends BaseService {
    method _construct (line 84) | async _construct () {
    method _init (line 88) | async _init () {
    method authenticateWebDavUser (line 106) | async authenticateWebDavUser ( username, password, _req, res ) {
    method handleHttpBasicAuth (line 148) | async handleHttpBasicAuth ( actor, req, res ) {
    method handleWebDavServer (line 200) | async handleWebDavServer ( filePath, req, res ) {
  method '__on_install.routes' (line 212) | '__on_install.routes' ( _, { app } ) {

FILE: src/backend/src/services/WebDAV/lockStore.mjs
  constant DAV_LOCK_DURATION (line 1) | const DAV_LOCK_DURATION = 30;
  constant LOCK_PREFIX (line 22) | const LOCK_PREFIX = 'locktoken:';

FILE: src/backend/src/services/WispService.js
  class WispService (line 24) | class WispService extends BaseService {
  method '__on_install.routes' (line 25) | '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/abuse-prevention/AuthAuditService.js
  class AuthAuditService (line 31) | class AuthAuditService extends BaseService {
    method _init (line 36) | async _init () {
    method record (line 54) | async record (parameters) {
    method _record (line 83) | async _record ({ requester, action, body, extra }) {

FILE: src/backend/src/services/abuse-prevention/EdgeRateLimitService.js
  constant MINUTE (line 24) | const MINUTE = 60 * 1000;
  constant HOUR (line 25) | const HOUR = 60 * MINUTE;
  constant DEFAULT_SCOPE (line 27) | const DEFAULT_SCOPE = {
  class EdgeRateLimitService (line 44) | class EdgeRateLimitService extends BaseService {
    method _init (line 139) | async _init () {
    method check (line 143) | check (scope, noIncrease = false) {
    method incr (line 182) | incr (scope) {
    method cleanup (line 203) | cleanup () {

FILE: src/backend/src/services/abuse-prevention/IdentificationService.js
  class Requester (line 33) | class Requester {
    method constructor (line 34) | constructor (o) {
    method create (line 37) | static create (o) {
    method from_request (line 40) | static from_request (req) {
    method is_puter_referer (line 71) | is_puter_referer () {
    method is_puter_origin (line 84) | is_puter_origin () {
    method rl_identifier (line 97) | get rl_identifier () {
    method serialize (line 109) | serialize () {
  class RequesterIdentificationExpressMiddleware (line 129) | class RequesterIdentificationExpressMiddleware extends AdvancedBase {
    method register_initializer (line 130) | register_initializer (initializer) {
    method install (line 133) | install (app) {
    method run (line 136) | async run (req, res, next) {
  class IdentificationService (line 157) | class IdentificationService extends BaseService {
    method _construct (line 166) | _construct () {
    method _init (line 178) | _init () {
  method '__on_install.middlewares.context-aware' (line 184) | async '__on_install.middlewares.context-aware' (_, { app }) {

FILE: src/backend/src/services/abuse-prevention/concurrentRequestLimiter/ConcurrentRequestLimiter.ts
  class ConcurrentRequestLimiter (line 59) | class ConcurrentRequestLimiter {
    method #eventService (line 63) | get #eventService () {
    method constructor (line 67) | constructor ({ redis = redisClient }: { redis?: Cluster } = {}) {
    method #isTemporaryUser (line 72) | #isTemporaryUser (actor: Actor) {
    method #getActorUserGroup (line 78) | async #getActorUserGroup (actor: Actor, noSub = false) {
    method registerLimitKey (line 95) | registerLimitKey (key: string, config: ConcurrentLimitConfig): void {
    method hasLimitKey (line 109) | hasLimitKey (key: string): boolean {
    method checkAndIncrementConcurrent (line 113) | async checkAndIncrementConcurrent (
    method decrementConcurrent (line 192) | async decrementConcurrent (
    method #resolveLimit (line 200) | #resolveLimit ({
    method #toRedisKey (line 229) | #toRedisKey ({
    method #createToken (line 239) | #createToken (): string {

FILE: src/backend/src/services/abuse-prevention/concurrentRequestLimiter/types.ts
  type SimpleLimitConfig (line 3) | interface SimpleLimitConfig {
  type GroupLimitConfig (line 7) | type GroupLimitConfig = { default: SimpleLimitConfig } & Record<string, ...
  type ConcurrentLimitConfig (line 9) | type ConcurrentLimitConfig = SimpleLimitConfig | GroupLimitConfig;
  type CheckAndIncrementConcurrentOptions (line 11) | interface CheckAndIncrementConcurrentOptions {
  type ConcurrentPermit (line 17) | interface ConcurrentPermit {
  type CheckAndIncrementConcurrentResult (line 27) | interface CheckAndIncrementConcurrentResult {

FILE: src/backend/src/services/ai/AIInterfaceService.js
  class AIInterfaceService (line 29) | class AIInterfaceService extends BaseService {
  method '__on_driver.register.interfaces' (line 35) | async '__on_driver.register.interfaces' () {

FILE: src/backend/src/services/ai/chat/AIChatService.ts
  constant MAX_FALLBACKS (line 55) | const MAX_FALLBACKS = 3 + 1;
  class AIChatService (line 59) | class AIChatService extends BaseService {
    method meteringService (line 65) | get meteringService (): MeteringService {
    method db (line 69) | get db (): BaseDatabaseAccessService {
    method errorService (line 73) | get errorService (): ErrorService {
    method eventService (line 77) | get eventService (): EventService {
    method driverService (line 81) | get driverService (): DriverService {
    method getProvider (line 85) | getProvider (name: string): IChatProvider | undefined {
    method #toLimitValue (line 92) | #toLimitValue (rawLimit: unknown): number | null {
    method #getAiChatConcurrentLimitConfig (line 107) | #getAiChatConcurrentLimitConfig (): GroupLimitConfig {
    method #getAiChatConcurrentLeaseMs (line 130) | #getAiChatConcurrentLeaseMs (): number {
    method supports_test_mode (line 142) | supports_test_mode (iface: string, method_name: string) {
    method models (line 149) | async models () {
    method list (line 153) | async list () {
    method complete (line 157) | async complete (...parameters: Parameters<AIChatService['complete']>) {
    method getModel (line 163) | getModel ({ modelId, provider}: { modelId: string, provider?: string }) {
    method registerProviders (line 176) | private async registerProviders () {
    method models (line 339) | models () {
    method list (line 359) | list () {
    method complete (line 363) | async complete (parameters: ICompleteArguments) {
    method moderate (line 732) | async moderate ({ messages }: { messages: Array<unknown>; }) {
    method getFallbackModel (line 780) | async getFallbackModel (modelId: string, triedIds: string[], triedProv...
  method '__on_boot.consolidation' (line 250) | protected async '__on_boot.consolidation' () {

FILE: src/backend/src/services/ai/chat/providers/ChatProvider.ts
  class ChatProvider (line 7) | class ChatProvider implements IChatProvider {
    method getDefaultModel (line 8) | getDefaultModel (): string {
    method models (line 11) | models (): IChatModel[] | Promise<IChatModel[]> {
    method list (line 14) | list (): string[] | Promise<string[]> {
    method checkModeration (line 17) | async checkModeration (_text: string): ReturnType<IChatProvider['check...
    method complete (line 23) | async complete (_arg: ICompleteArguments): ReturnType<IChatProvider['c...

FILE: src/backend/src/services/ai/chat/providers/ClaudeProvider/ClaudeProvider.ts
  class ClaudeProvider (line 36) | class ClaudeProvider implements IChatProvider {
    method constructor (line 43) | constructor (meteringService: MeteringService, config: { apiKey: strin...
    method getDefaultModel (line 56) | getDefaultModel () {
    method list (line 60) | async list () {
    method complete (line 72) | async complete ({ messages, stream, model, tools, max_tokens, temperat...
    method #usageFormatterUtil (line 423) | #usageFormatterUtil (usage: Usage | BetaUsage) {
    method #buildThinkingConfig (line 434) | #buildThinkingConfig ({
    method #buildCostsOverrideFromModel (line 471) | #buildCostsOverrideFromModel (usage: Record<string, number>, modelUsed...
    method models (line 478) | models () {
    method checkModeration (line 482) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...

FILE: src/backend/src/services/ai/chat/providers/ClaudeProvider/models.ts
  constant CLAUDE_MODELS (line 4) | const CLAUDE_MODELS: IChatModel[] = [

FILE: src/backend/src/services/ai/chat/providers/DeepSeekProvider/DeepSeekProvider.ts
  class DeepSeekProvider (line 29) | class DeepSeekProvider implements IChatProvider {
    method constructor (line 34) | constructor (config: { apiKey: string }, meteringService: MeteringServ...
    method getDefaultModel (line 42) | getDefaultModel () {
    method models (line 46) | models () {
    method list (line 50) | async list () {
    method complete (line 62) | async complete ({ messages, stream, model, tools, max_tokens, temperat...
    method checkModeration (line 128) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...

FILE: src/backend/src/services/ai/chat/providers/DeepSeekProvider/models.ts
  constant DEEPSEEK_MODELS (line 4) | const DEEPSEEK_MODELS: IChatModel[] = [

FILE: src/backend/src/services/ai/chat/providers/FakeChatProvider.ts
  class FakeChatProvider (line 25) | class FakeChatProvider implements IChatProvider {
    method checkModeration (line 26) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...
    method getDefaultModel (line 30) | getDefaultModel () {
    method models (line 34) | async models () {
    method list (line 69) | async list () {
    method complete (line 72) | async complete ({ messages, stream, model, max_tokens, custom }: IComp...
    method getFakeResponse (line 99) | async getFakeResponse (modelId: string, custom: unknown, messages: Put...

FILE: src/backend/src/services/ai/chat/providers/GeminiProvider/GeminiChatProvider.ts
  class GeminiChatProvider (line 11) | class GeminiChatProvider implements IChatProvider {
    method constructor (line 18) | constructor ( meteringService: MeteringService, config: { apiKey: stri...
    method getDefaultModel (line 27) | getDefaultModel () {
    method models (line 31) | async models () {
    method list (line 34) | async list () {
    method complete (line 38) | async complete ({ messages, stream, model, tools, max_tokens, temperat...
    method checkModeration (line 90) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...

FILE: src/backend/src/services/ai/chat/providers/GeminiProvider/models.ts
  constant GEMINI_MODELS (line 4) | const GEMINI_MODELS: IChatModel[] = [

FILE: src/backend/src/services/ai/chat/providers/GroqAiProvider/GroqAIProvider.ts
  class GroqAIProvider (line 29) | class GroqAIProvider implements IChatProvider {
    method constructor (line 34) | constructor (config: { apiKey: string }, meteringService: MeteringServ...
    method getDefaultModel (line 41) | getDefaultModel () {
    method models (line 45) | models () {
    method list (line 49) | async list () {
    method complete (line 61) | async complete ({ messages, model, stream, tools, max_tokens, temperat...
    method checkModeration (line 101) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...

FILE: src/backend/src/services/ai/chat/providers/GroqAiProvider/models.ts
  constant GROQ_MODELS (line 4) | const GROQ_MODELS: IChatModel[] = [

FILE: src/backend/src/services/ai/chat/providers/MistralAiProvider/MistralAiProvider.ts
  class MistralAIProvider (line 28) | class MistralAIProvider implements IChatProvider {
    method constructor (line 33) | constructor (config: { apiKey: string }, meteringService: MeteringServ...
    method getDefaultModel (line 40) | getDefaultModel () {
    method models (line 44) | async models () {
    method list (line 48) | async list () {
    method complete (line 60) | async complete ({ messages, stream, model, tools, max_tokens, temperat...
    method checkModeration (line 119) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...

FILE: src/backend/src/services/ai/chat/providers/MistralAiProvider/models.ts
  constant MISTRAL_MODELS (line 4) | const MISTRAL_MODELS: IChatModel[] = [

FILE: src/backend/src/services/ai/chat/providers/OllamaProvider.ts
  class OllamaChatProvider (line 35) | class OllamaChatProvider implements IChatProvider {
    method constructor (line 43) | constructor (config: { api_base_url?: string } | undefined, meteringSe...
    method models (line 56) | async models () {
    method list (line 97) | async list () {
    method complete (line 105) | async complete ({ messages, stream, model, tools, max_tokens, temperat...
    method checkModeration (line 149) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...
    method getDefaultModel (line 157) | getDefaultModel () {

FILE: src/backend/src/services/ai/chat/providers/OpenAiProvider/OpenAiChatCompletionsProvider.ts
  constant MAX_FILE_SIZE (line 36) | const MAX_FILE_SIZE = 5 * 1_000_000;
  class OpenAiChatProvider (line 45) | class OpenAiChatProvider implements IChatProvider {
    method constructor (line 55) | constructor (
    method models (line 82) | models () {
    method list (line 86) | list () {
    method getDefaultModel (line 98) | getDefaultModel () {
    method complete (line 102) | async complete (params: ICompleteArguments): ReturnType<IChatProvider[...
    method checkModeration (line 246) | async checkModeration (text: string) {

FILE: src/backend/src/services/ai/chat/providers/OpenAiProvider/OpenAiChatResponsesProvider.ts
  constant MAX_FILE_SIZE (line 36) | const MAX_FILE_SIZE = 5 * 1_000_000;
  class OpenAiResponsesChatProvider (line 45) | class OpenAiResponsesChatProvider implements IChatProvider {
    method constructor (line 55) | constructor (
    method models (line 82) | models (extra_params) {
    method list (line 90) | list () {
    method getDefaultModel (line 102) | getDefaultModel () {
    method complete (line 106) | async complete ({ messages, model, max_tokens, moderation, tools, verb...
    method checkModeration (line 253) | async checkModeration (text: string) {

FILE: src/backend/src/services/ai/chat/providers/OpenAiProvider/models.ts
  constant OPEN_AI_MODELS (line 6) | const OPEN_AI_MODELS: IChatModel[] = [

FILE: src/backend/src/services/ai/chat/providers/OpenRouterProvider/OpenRouterProvider.ts
  type OpenrouterUsage (line 31) | type OpenrouterUsage = OpenAI.Completions.CompletionUsage & {
  class OpenRouterProvider (line 35) | class OpenRouterProvider implements IChatProvider {
    method constructor (line 43) | constructor (config: { apiBaseUrl?: string, apiKey: string }, metering...
    method getDefaultModel (line 52) | getDefaultModel () {
    method list (line 61) | async list () {
    method complete (line 74) | async complete ({ messages, stream, model, tools, max_tokens, temperat...
    method models (line 160) | async models () {
    method checkModeration (line 202) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...

FILE: src/backend/src/services/ai/chat/providers/OpenRouterProvider/modelOverrides.ts
  constant OPEN_ROUTER_MODEL_OVERRIDES (line 4) | const OPEN_ROUTER_MODEL_OVERRIDES: IChatModel[] = [

FILE: src/backend/src/services/ai/chat/providers/TogetherAiProvider/TogetherAIProvider.ts
  constant TOGETHER_AI_CHAT_COST_MAP (line 27) | const TOGETHER_AI_CHAT_COST_MAP = {
  class TogetherAIProvider (line 32) | class TogetherAIProvider implements IChatProvider {
    method constructor (line 39) | constructor (config: { apiKey: string }, meteringService: MeteringServ...
    method getDefaultModel (line 46) | getDefaultModel () {
    method models (line 50) | async models () {
    method list (line 94) | async list () {
    method complete (line 106) | async complete ({ messages, stream, model, tools, max_tokens, temperat...
    method checkModeration (line 147) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...

FILE: src/backend/src/services/ai/chat/providers/XAIProvider/XAIProvider.ts
  class XAIProvider (line 28) | class XAIProvider implements IChatProvider {
    method constructor (line 33) | constructor (config: { apiKey: string }, meteringService: MeteringServ...
    method getDefaultModel (line 41) | getDefaultModel () {
    method models (line 45) | models () {
    method list (line 49) | async list () {
    method complete (line 61) | async complete ({ messages, stream, model, tools }: ICompleteArguments...
    method checkModeration (line 97) | checkModeration (_text: string): ReturnType<IChatProvider['checkModera...

FILE: src/backend/src/services/ai/chat/providers/XAIProvider/models.ts
  constant XAI_MODELS (line 4) | const XAI_MODELS: IChatModel[] = [

FILE: src/backend/src/services/ai/chat/providers/types.ts
  type ModelCost (line 5) | type ModelCost = Record<string, number>;
  type ModelModalities (line 7) | interface ModelModalities {
  type IChatModel (line 12) | interface IChatModel<T extends ModelCost = ModelCost> extends Record<str...
  type PuterMessage (line 33) | type PuterMessage = Message | any;
  type ICompleteArguments (line 34) | interface ICompleteArguments {
  type IChatProvider (line 54) | interface IChatProvider {

FILE: src/backend/src/services/ai/image/AIImageGenerationService.ts
  class AIImageGenerationService (line 36) | class AIImageGenerationService extends BaseService {
    method meteringService (line 42) | get meteringService (): MeteringService {
    method db (line 46) | get db (): BaseDatabaseAccessService {
    method errorService (line 50) | get errorService (): ErrorService {
    method eventService (line 54) | get eventService (): EventService {
    method driverService (line 58) | get driverService (): DriverService {
    method getProvider (line 62) | getProvider (name: string): IImageProvider | undefined {
    method supports_test_mode (line 72) | supports_test_mode (iface: string, method_name: string) {
    method generate (line 79) | async generate (...parameters: Parameters<AIImageGenerationService['ge...
    method getModel (line 85) | getModel ({ modelId, provider }: { modelId: string, provider?: string ...
    method registerProviders (line 105) | private async registerProviders () {
    method models (line 210) | models () {
    method list (line 231) | list () {
    method generate (line 235) | async generate (parameters: IGenerateParams) {
  method '__on_boot.consolidation' (line 153) | protected async '__on_boot.consolidation' () {

FILE: src/backend/src/services/ai/image/providers/CloudflareImageGenerationProvider/CloudflareImageGenerationProvider.ts
  type CloudflareGenerateParams (line 28) | type CloudflareGenerateParams = IGenerateParams & {
  type CostComponent (line 38) | interface CostComponent {
  constant DEFAULT_MODEL (line 44) | const DEFAULT_MODEL = '@cf/black-forest-labs/flux-1-schnell';
  constant DEFAULT_RATIO (line 45) | const DEFAULT_RATIO = { w: 1024, h: 1024 };
  class CloudflareImageGenerationProvider (line 47) | class CloudflareImageGenerationProvider implements IImageProvider {
    method constructor (line 55) | constructor (
    method models (line 86) | models (): IImageModel[] {
    method getDefaultModel (line 90) | getDefaultModel (): string {
    method generate (line 94) | async generate (params: IGenerateParams): Promise<string> {
    method #getModel (line 151) | #getModel (model?: string): CloudflareImageModel {
    method #normalizeRatio (line 157) | #normalizeRatio (ratio?: { w: number; h: number }) {
    method #resolveSteps (line 166) | #resolveSteps (model: CloudflareImageModel, options: CloudflareGenerat...
    method #estimateCost (line 179) | #estimateCost (
    method #runModel (line 268) | async #runModel (model: CloudflareImageModel, params: CloudflareGenera...
    method #extractImageString (line 353) | #extractImageString (payload: unknown): string | undefined {
    method #extractErrorMessage (line 378) | #extractErrorMessage (payload: unknown): string | undefined {
    method #tileCount (line 392) | #tileCount ({ w, h }: { w: number; h: number }) {
    method #megapixels (line 396) | #megapixels ({ w, h }: { w: number; h: number }) {
    method #mimeForFormat (line 400) | #mimeForFormat (format?: string) {
    method #costForUnits (line 406) | #costForUnits (units: number, microCentsPerUnit?: number) {
    method #costForMillionUnits (line 413) | #costForMillionUnits (numerator: number, microCentsPerMillion?: number) {
    method #getMeteringModelKey (line 419) | #getMeteringModelKey (model: CloudflareImageModel) {

FILE: src/backend/src/services/ai/image/providers/CloudflareImageGenerationProvider/models.ts
  type CloudflareBillingScheme (line 22) | type CloudflareBillingScheme =
  type CloudflareImageModel (line 29) | type CloudflareImageModel = IImageModel & {
  constant CLOUDFLARE_IMAGE_GENERATION_MODELS (line 37) | const CLOUDFLARE_IMAGE_GENERATION_MODELS: CloudflareImageModel[] = [

FILE: src/backend/src/services/ai/image/providers/GeminiImageGenerationProvider/GeminiImageGenerationProvider.ts
  constant MIME_SIGNATURES (line 28) | const MIME_SIGNATURES: Record<string, string> = {
  type GeminiUsageMetadata (line 34) | interface GeminiUsageMetadata {
  class GeminiImageGenerationProvider (line 42) | class GeminiImageGenerationProvider implements IImageProvider {
    method constructor (line 47) | constructor (config: { apiKey: string }, meteringService: MeteringServ...
    method models (line 56) | models (): IImageModel[] {
    method getDefaultModel (line 60) | getDefaultModel (): string {
    method generate (line 64) | async generate (params: IGenerateParams): Promise<string> {
    method #buildContents (line 200) | #buildContents (prompt: string, input_images?: string[], input_image_m...
    method #setResponseCostMetadata (line 220) | #setResponseCostMetadata ({
    method #extractUsageMetadata (line 267) | #extractUsageMetadata (response: GenerateContentResponse): GeminiUsage...
    method #estimatePromptTokenCount (line 294) | #estimatePromptTokenCount (prompt: string): number {
    method #calculateTokenCostInCents (line 302) | #calculateTokenCostInCents (tokenCount: number, centsPerMillion?: numb...
    method #toMicroCents (line 309) | #toMicroCents (cents: number): number {
    method #toSafeCount (line 314) | #toSafeCount (value: unknown): number {
    method #extractImageUrl (line 319) | #extractImageUrl (response: GenerateContentResponse): string | undefin...
    method #detectMimeType (line 334) | #detectMimeType (data: string): string | undefined {
    method #parseDataUri (line 349) | #parseDataUri (data: string): { mimeType: string; base64: string } | u...
    method #isValidRatio (line 364) | #isValidRatio (ratio: { w: number; h: number }, allowedRatios: { w: nu...

FILE: src/backend/src/services/ai/image/providers/GeminiImageGenerationProvider/models.ts
  constant GEMINI_DEFAULT_RATIO (line 22) | const GEMINI_DEFAULT_RATIO = { w: 1024, h: 1024 };
  constant GEMINI_ESTIMATED_IMAGE_TOKENS (line 27) | const GEMINI_ESTIMATED_IMAGE_TOKENS: Record<string, number> = {
  constant GEMINI_IMAGE_GENERATION_MODELS (line 40) | const GEMINI_IMAGE_GENERATION_MODELS: IImageModel[] = [

FILE: src/backend/src/services/ai/image/providers/OpenAiImageGenerationProvider/OpenAiImageGenerationProvider.ts
  type OpenAIImageUsage (line 29) | interface OpenAIImageUsage {
  class OpenAiImageGenerationProvider (line 46) | class OpenAiImageGenerationProvider implements IImageProvider {
    method constructor (line 60) | constructor (config: { apiKey: string }, meteringService: MeteringServ...
    method models (line 68) | models () {
    method getDefaultModel (line 72) | getDefaultModel (): string {
    method generate (line 76) | async generate ({ prompt, quality, test_mode, model, ratio }: IGenerat...
    method #extractUsage (line 211) | #extractUsage (result: ImagesResponse): OpenAIImageUsage {
    method #calculateInputCostInCents (line 240) | #calculateInputCostInCents (selectedModel: IImageModel, usage: OpenAII...
    method #calculateOutputCostInCents (line 307) | #calculateOutputCostInCents (selectedModel: IImageModel, usage: OpenAI...
    method #setResponseCostMetadata (line 329) | #setResponseCostMetadata ({
    method #estimatePromptTokenCount (line 382) | #estimatePromptTokenCount (prompt: string): number {
    method #getCostRate (line 390) | #getCostRate (selectedModel: IImageModel, key: string): number | undef...
    method #costForTokens (line 398) | #costForTokens (tokenCount: number, centsPerMillion?: number): number {
    method #toMicroCents (line 404) | #toMicroCents (cents: number): number {
    method #toSafeCount (line 409) | #toSafeCount (value: unknown): number {
    method #isGptImageModel (line 414) | #isGptImageModel (model: string) {
    method #buildPriceKey (line 419) | #buildPriceKey (model: string, quality: string, size: string) {
    method #buildApiParams (line 430) | #buildApiParams (model: string, baseParams: Partial<ImageGenerateParam...

FILE: src/backend/src/services/ai/image/providers/OpenAiImageGenerationProvider/models.ts
  constant OPEN_AI_IMAGE_GENERATION_MODELS (line 3) | const OPEN_AI_IMAGE_GENERATION_MODELS: IImageModel[] = [

FILE: src/backend/src/services/ai/image/providers/TogetherImageGenerationProvider/TogetherImageGenerationProvider.ts
  constant TOGETHER_DEFAULT_RATIO (line 29) | const TOGETHER_DEFAULT_RATIO = { w: 1024, h: 1024 };
  type TogetherGenerateParams (line 30) | type TogetherGenerateParams = IGenerateParams & {
  constant DEFAULT_MODEL (line 45) | const DEFAULT_MODEL = 'togetherai:black-forest-labs/FLUX.1-schnell';
  constant CONDITION_IMAGE_MODELS (line 46) | const CONDITION_IMAGE_MODELS = [
  class TogetherImageGenerationProvider (line 52) | class TogetherImageGenerationProvider implements IImageProvider {
    method constructor (line 58) | constructor (config: { apiKey: string }, meteringService: MeteringServ...
    method models (line 68) | models (): IImageModel[] {
    method getDefaultModel (line 72) | getDefaultModel (): string {
    method generate (line 76) | async generate (params: IGenerateParams): Promise<string> {
    method #getModel (line 166) | #getModel (model?: string) {
    method #buildRequest (line 170) | #buildRequest (prompt: string, options: TogetherGenerateParams) {
    method #normalizeDimension (line 243) | #normalizeDimension (value?: number) {
    method #modelRequiresConditionImage (line 250) | #modelRequiresConditionImage (modelId?: string) {

FILE: src/backend/src/services/ai/image/providers/TogetherImageGenerationProvider/models.ts
  constant TOGETHER_IMAGE_GENERATION_MODELS (line 22) | const TOGETHER_IMAGE_GENERATION_MODELS: IImageModel[] = [
  constant GEMINI_3_IMAGE_RESOLUTION_MAP (line 321) | const GEMINI_3_IMAGE_RESOLUTION_MAP: Record<string, Record<string, { w: ...

FILE: src/backend/src/services/ai/image/providers/XAIImageGenerationProvider/XAIImageGenerationProvider.ts
  constant DEFAULT_MODEL (line 28) | const DEFAULT_MODEL = 'grok-2-image';
  constant PRICE_KEY (line 29) | const PRICE_KEY = 'output';
  class XAIImageGenerationProvider (line 31) | class XAIImageGenerationProvider implements IImageProvider {
    method constructor (line 36) | constructor (config: { apiKey: string }, meteringService: MeteringServ...
    method models (line 49) | models (): IImageModel[] {
    method getDefaultModel (line 53) | getDefaultModel (): string {
    method generate (line 57) | async generate (params: IGenerateParams): Promise<string> {
    method #getModel (line 107) | #getModel (model?: string) {

FILE: src/backend/src/services/ai/image/providers/XAIImageGenerationProvider/models.ts
  constant XAI_IMAGE_GENERATION_MODELS (line 3) | const XAI_IMAGE_GENERATION_MODELS: IImageModel[] = [

FILE: src/backend/src/services/ai/image/providers/types.ts
  type IImageModel (line 1) | interface IImageModel {
  type IGenerateParams (line 17) | interface IGenerateParams {
  type IImageProvider (line 28) | interface IImageProvider {

FILE: src/backend/src/services/ai/moderation/AsModeration.js
  class AsModeration (line 22) | class AsModeration {
    method constructor (line 35) | constructor ({ chatProvider, model }) {
    method moderate (line 40) | async moderate (text) {

FILE: src/backend/src/services/ai/ocr/AWSTextractService.js
  class AWSTextractService (line 32) | class AWSTextractService extends BaseService {
    method meteringService (line 34) | get meteringService () {
    method _construct (line 43) | _construct () {
    method supports_test_mode (line 49) | supports_test_mode (iface, method_name) {
    method recognize (line 61) | async recognize ({ source, test_mode }) {
    method _create_aws_credentials (line 112) | _create_aws_credentials () {
    method _get_client (line 119) | _get_client (region) {
    method analyze_document (line 142) | async analyze_document (file_facade) {
    method _get_client_and_document (line 209) | async _get_client_and_document (file_facade, force_buffer) {

FILE: src/backend/src/services/ai/ocr/MistralOCRService.js
  class MistralOCRService (line 34) | class MistralOCRService extends BaseService {
    method supports_test_mode (line 58) | supports_test_mode (iface, method_name) {
    method recognize (line 63) | async recognize (...params) {
    method _init (line 75) | async _init () {
    method recognize (line 84) | async recognize ({
    method _buildDocumentChunkFromSource (line 141) | async _buildDocumentChunkFromSource (fileFacade) {
    method _safeFileValue (line 169) | async _safeFileValue (fileFacade, key) {
    method _chunkFromUrl (line 182) | _chunkFromUrl (url, fileName, mimeType) {
    method _inferMimeFromName (line 207) | _inferMimeFromName (name) {
    method _extractMimeFromDataUrl (line 212) | _extractMimeFromDataUrl (url) {
    method _createDataUrl (line 218) | _createDataUrl (buffer, mimeType) {
    method #normalizeOcrResponse (line 222) | #normalizeOcrResponse (response) {
    method #recordOcrUsage (line 252) | #recordOcrUsage (response, model, { annotationsRequested } = {}) {
    method #sampleOcrResponse (line 269) | #sampleOcrResponse () {

FILE: src/backend/src/services/ai/sts/ElevenLabsVoiceChangerService.js
  constant DEFAULT_MODEL (line 27) | const DEFAULT_MODEL = 'eleven_multilingual_sts_v2';
  constant DEFAULT_VOICE_ID (line 28) | const DEFAULT_VOICE_ID = '21m00Tcm4TlvDq8ikWAM';
  constant SAMPLE_AUDIO_URL (line 29) | const SAMPLE_AUDIO_URL = 'https://puter-sample-data.puter.site/tts_examp...
  constant MAX_AUDIO_FILE_SIZE (line 30) | const MAX_AUDIO_FILE_SIZE = 25 * 1024 * 1024;
  constant DEFAULT_OUTPUT_FORMAT (line 31) | const DEFAULT_OUTPUT_FORMAT = 'mp3_44100_128';
  class ElevenLabsVoiceChangerService (line 36) | class ElevenLabsVoiceChangerService extends BaseService {
    method meteringService (line 38) | get meteringService () {
    method supports_test_mode (line 50) | supports_test_mode (iface, method_name) {
    method convert (line 55) | async convert (params) {
    method _init (line 61) | async _init () {
    method convert (line 76) | async convert (params) {
    method _prepareAudioBuffer (line 214) | async _prepareAudioBuffer (file) {

FILE: src/backend/src/services/ai/stt/OpenAISpeechToTextService.js
  constant MAX_AUDIO_FILE_SIZE (line 25) | const MAX_AUDIO_FILE_SIZE = 25 * 1024 * 1024;
  constant DEFAULT_TRANSCRIBE_MODEL (line 26) | const DEFAULT_TRANSCRIBE_MODEL = 'gpt-4o-mini-transcribe';
  constant DEFAULT_TRANSLATE_MODEL (line 27) | const DEFAULT_TRANSLATE_MODEL = 'whisper-1';
  constant SAMPLE_TRANSCRIPT (line 28) | const SAMPLE_TRANSCRIPT = {
  constant TRANSCRIPTION_MODEL_CAPABILITIES (line 39) | const TRANSCRIPTION_MODEL_CAPABILITIES = {
  class OpenAISpeechToTextService (line 65) | class OpenAISpeechToTextService extends BaseService {
    method meteringService (line 67) | get meteringService () {
    method _init (line 78) | async _init () {
    method supports_test_mode (line 103) | supports_test_mode (iface, method_name) {
    method list_models (line 109) | async list_models () {
    method transcribe (line 112) | async transcribe (params) {
    method translate (line 115) | async translate (params) {
    method listModels (line 121) | listModels () {
    method _handleTranscription (line 160) | async _handleTranscription ({
    method _prepareAudioBuffer (line 306) | async _prepareAudioBuffer (file) {
    method _formatResponse (line 390) | _formatResponse (result, response_format) {

FILE: src/backend/src/services/ai/tts/AWSPollyService.js
  constant ENGINE_PRICING (line 30) | const ENGINE_PRICING = {
  constant VALID_ENGINES (line 38) | const VALID_ENGINES = ['standard', 'neural', 'long-form', 'generative'];
  class AWSPollyService (line 48) | class AWSPollyService extends BaseService {
    method meteringService (line 51) | get meteringService () {
    method _construct (line 60) | async _construct () {
    method supports_test_mode (line 66) | supports_test_mode (iface, method_name) {
    method list_voices (line 79) | async list_voices ({ engine } = {}) {
    method list_engines (line 104) | async list_engines () {
    method synthesize (line 111) | async synthesize ({
    method _create_aws_credentials (line 166) | _create_aws_credentials () {
    method _get_client (line 173) | _get_client (region) {
    method describe_voices (line 194) | async describe_voices () {
    method synthesize_speech (line 235) | async synthesize_speech (text, { format, voice_id, language, text_type...
    method maybe_get_language_appropriate_voice_ (line 275) | async maybe_get_language_appropriate_voice_ (language, engine = 'stand...
    method get_default_voice_for_engine_ (line 295) | async get_default_voice_for_engine_ (engine = 'standard') {

FILE: src/backend/src/services/ai/tts/ElevenLabsTTSService.js
  constant DEFAULT_MODEL (line 26) | const DEFAULT_MODEL = 'eleven_multilingual_v2';
  constant DEFAULT_VOICE_ID (line 27) | const DEFAULT_VOICE_ID = '21m00Tcm4TlvDq8ikWAM';
  constant DEFAULT_OUTPUT_FORMAT (line 28) | const DEFAULT_OUTPUT_FORMAT = 'mp3_44100_128';
  constant SAMPLE_AUDIO_URL (line 29) | const SAMPLE_AUDIO_URL = 'https://puter-sample-data.puter.site/tts_examp...
  constant ELEVENLABS_TTS_MODELS (line 31) | const ELEVENLABS_TTS_MODELS = [
  class ElevenLabsTTSService (line 43) | class ElevenLabsTTSService extends BaseService {
    method meteringService (line 45) | get meteringService () {
    method supports_test_mode (line 51) | supports_test_mode (iface, method_name) {
    method list_voices (line 56) | async list_voices () {
    method list_engines (line 59) | async list_engines () {
    method synthesize (line 62) | async synthesize (params) {
    method _init (line 68) | async _init () {
    method request (line 80) | async request (path, { method = 'GET', body, headers = {} } = {}) {
    method listVoices (line 105) | async listVoices () {
    method listEngines (line 123) | async listEngines () {
    method synthesize (line 132) | async synthesize (params) {

FILE: src/backend/src/services/ai/tts/OpenAITTSService.js
  constant DEFAULT_MODEL (line 26) | const DEFAULT_MODEL = 'gpt-4o-mini-tts';
  constant DEFAULT_VOICE (line 27) | const DEFAULT_VOICE = 'alloy';
  constant SAMPLE_AUDIO_URL (line 28) | const SAMPLE_AUDIO_URL = 'https://puter-sample-data.puter.site/tts_examp...
  constant RESPONSE_CONTENT_TYPES (line 30) | const RESPONSE_CONTENT_TYPES = {
  constant OPENAI_TTS_VOICES (line 39) | const OPENAI_TTS_VOICES = [
  constant OPENAI_TTS_MODELS (line 52) | const OPENAI_TTS_MODELS = [
  class OpenAITTSService (line 75) | class OpenAITTSService extends BaseService {
    method meteringService (line 77) | get meteringService () {
    method _init (line 85) | async _init () {
    method supports_test_mode (line 110) | supports_test_mode (iface, method_name) {
    method list_voices (line 115) | async list_voices ({ provider } = {}) {
    method list_engines (line 131) | async list_engines ({ provider } = {}) {
    method synthesize (line 143) | async synthesize (params) {
    method synthesize (line 149) | async synthesize ({

FILE: src/backend/src/services/ai/utils/OpenAIUtil.d.ts
  type ToolUseContent (line 11) | interface ToolUseContent {
  type ToolResultContent (line 19) | interface ToolResultContent {
  type NormalizedContent (line 25) | type NormalizedContent =
  type NormalizedMessage (line 31) | interface NormalizedMessage extends Partial<ChatCompletionMessageParam> {
  type UsageCalculator (line 39) | type UsageCalculator = (args: { usage: CompletionUsage }) => Record<stri...
  type ChatStream (line 41) | interface ChatStream {
  type StreamingToolCall (line 55) | type StreamingToolCall = ChatCompletionChunk.Choice.Delta.ToolCall & { e...
  type CompletionChunk (line 57) | type CompletionChunk = Omit<ChatCompletionChunk, 'choices' | 'usage'> & {
  type StreamDeviations (line 71) | interface StreamDeviations {
  type CompletionDeviations (line 77) | interface CompletionDeviations<TCompletion = ChatCompletion> {
  type CompletionChoice (line 106) | type CompletionChoice<TCompletion> = TCompletion extends { choices: Arra...

FILE: src/backend/src/services/ai/utils/Streaming.js
  class AIChatConstructStream (line 1) | class AIChatConstructStream {
    method constructor (line 2) | constructor (chatStream, params) {
    method end (line 6) | end () {
  class AIChatTextStream (line 10) | class AIChatTextStream extends AIChatConstructStream {
    method addText (line 11) | addText (text, extra_content) {
    method addReasoning (line 20) | addReasoning (reasoning) {
    method addExtraContent (line 27) | addExtraContent (extra_content) {
  class AIChatToolUseStream (line 36) | class AIChatToolUseStream extends AIChatConstructStream {
    method _start (line 37) | _start (params) {
    method addPartialJSON (line 41) | addPartialJSON (partial_json) {
    method end (line 44) | end () {
  class AIChatMessageStream (line 59) | class AIChatMessageStream extends AIChatConstructStream {
    method contentBlock (line 60) | contentBlock ({ type, ...params }) {
  class AIChatStream (line 71) | class AIChatStream {
    method constructor (line 73) | constructor ({ stream }) {
    method end (line 77) | end (/** @type {Record<string,number>} */ usage) {
    method message (line 85) | message () {
    method write (line 88) | write (...args) {
  class Streaming (line 93) | class Streaming {

FILE: src/backend/src/services/ai/video/OpenAIVideoGenerationService/OpenAIVideoGenerationService.js
  constant DEFAULT_TEST_VIDEO_URL (line 26) | const DEFAULT_TEST_VIDEO_URL = 'https://assets.puter.site/txt2vid.mp4';
  constant DEFAULT_TIMEOUT_MS (line 27) | const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
  constant POLL_INTERVAL_MS (line 28) | const POLL_INTERVAL_MS = 5_000;
  constant DEFAULT_DURATION_SECONDS (line 29) | const DEFAULT_DURATION_SECONDS = 4;
  constant DEFAULT_SIZE (line 30) | const DEFAULT_SIZE = '720x1280';
  constant ALLOWED_SIZES (line 31) | const ALLOWED_SIZES = new Set(['720x1280', '1280x720', '1024x1792', '179...
  constant ALLOWED_SECONDS (line 32) | const ALLOWED_SECONDS = new Set(['4', '8', '12']);
  constant OPENAI_VIDEO_MODELS (line 33) | const OPENAI_VIDEO_MODELS = [
  class OpenAIVideoGenerationService (line 48) | class OpenAIVideoGenerationService extends BaseService {
    method meteringService (line 50) | get meteringService () {
    method _construct (line 58) | _construct () {
    method _init (line 65) | async _init () {
    method supports_test_mode (line 86) | supports_test_mode (iface, method_name) {
    method generate (line 92) | async generate (params) {
    method models (line 98) | async models () {
    method generateVideo (line 139) | async generateVideo (params) {
    method #pollUntilComplete (line 243) | async #pollUntilComplete (initialJob) {
    method #delay (line 259) | async #delay (ms) {
    method #normalizeSize (line 263) | #normalizeSize (candidate) {
    method #normalizeSeconds (line 272) | #normalizeSeconds (value) {
    method #determineUsageKey (line 297) | #determineUsageKey (model, normalizedSize) {
    method #normalizeResolution (line 308) | #normalizeResolution (value) {
    method #parseSeconds (line 325) | #parseSeconds (value) {

FILE: src/backend/src/services/ai/video/TogetherVideoGenerationService/TogetherVideoGenerationService.js
  constant DEFAULT_TEST_VIDEO_URL (line 26) | const DEFAULT_TEST_VIDEO_URL = 'https://assets.puter.site/txt2vid.mp4';
  constant POLL_INTERVAL_MS (line 27) | const POLL_INTERVAL_MS = 5_000;
  constant DEFAULT_TIMEOUT_MS (line 28) | const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
  constant DEFAULT_MODEL (line 29) | const DEFAULT_MODEL = 'minimax/video-01-director';
  constant DEFAULT_DURATION_SECONDS (line 30) | const DEFAULT_DURATION_SECONDS = 6;
  constant DEFAULT_USAGE_KEY (line 31) | const DEFAULT_USAGE_KEY = 'together-video:default';
  class TogetherVideoGenerationService (line 35) | class TogetherVideoGenerationService extends BaseService {
    method meteringService (line 37) | get meteringService () {
    method _init (line 43) | async _init () {
    method supports_test_mode (line 57) | supports_test_mode (iface, method_name) {
    method generate (line 63) | async generate (params) {
    method generateVideo (line 69) | async generateVideo (params) {
    method models (line 201) | async models () {
    method #pollUntilComplete (line 234) | async #pollUntilComplete (jobId) {
    method #delay (line 250) | async #delay (ms) {
    method #determineUsageKey (line 254) | #determineUsageKey (model) {
    method #stripTogetherPrefix (line 261) | #stripTogetherPrefix (model) {
    method #coercePositiveInteger (line 268) | #coercePositiveInteger (value) {
    method #isFiniteNumber (line 280) | #isFiniteNumber (value) {

FILE: src/backend/src/services/ai/video/TogetherVideoGenerationService/models.js
  constant TOGETHER_VIDEO_GENERATION_MODELS (line 1) | const TOGETHER_VIDEO_GENERATION_MODELS = [

FILE: src/backend/src/services/auth/ACLService.js
  class ACLService (line 40) | class ACLService extends BaseService {
    method _init (line 54) | async _init () {
    method check (line 69) | async check (actor, resource, mode) {
    method set_user_user (line 216) | async set_user_user (issuer, holder, resource, mode, options = {}) {
    method stat_user_user (line 295) | async stat_user_user (issuer, holder, resource) {
    method _check_fsNode (line 340) | async _check_fsNode (actor, fsNode, mode) {
    method get_safe_acl_error (line 543) | async get_safe_acl_error (actor, resource, _mode) {
    method get_highest_mode (line 564) | get_highest_mode () {
    method _higher_modes (line 569) | _higher_modes (mode) {
  method '__on_install.routes' (line 104) | async '__on_install.routes' (_, { app }) {

FILE: src/backend/src/services/auth/Actor.d.ts
  type ActorLogFields (line 3) | interface ActorLogFields {
  class SystemActorType (line 8) | class SystemActorType {
  class UserActorType (line 14) | class UserActorType {
  class AppUnderUserActorType (line 23) | class AppUnderUserActorType {
  class AccessTokenActorType (line 31) | class AccessTokenActorType {
  class SiteActorType (line 40) | class SiteActorType {
  type ActorType (line 46) | type ActorType =
  type ActorInit (line 53) | interface ActorInit {
  class Actor (line 57) | class Actor {

FILE: src/backend/src/services/auth/Actor.js
  constant PRIVATE_UID_NAMESPACE (line 27) | const PRIVATE_UID_NAMESPACE = config.private_uid_namespace
  constant PRIVATE_UID_SECRET (line 29) | const PRIVATE_UID_SECRET = config.private_uid_secret
  class ActorType (line 36) | class ActorType {
    method constructor (line 42) | constructor (o) {
  class SystemActorType (line 55) | class SystemActorType extends ActorType {
    method uid (line 61) | get uid () {
    method get_related_type (line 72) | get_related_type (type_class) {
  class Actor (line 86) | class Actor extends AdvancedBase {
    method get_system_actor (line 100) | static get_system_actor () {
    method create (line 119) | static async create (type, params) {
    method constructor (line 139) | constructor (o, ...a) {
    method uid (line 151) | get uid () {
    method toLogFields (line 160) | toLogFields () {
    method private_uid (line 177) | get private_uid () {
    method clone (line 200) | clone () {
    method get_related_actor (line 212) | get_related_actor (type_class) {
  class UserActorType (line 224) | class UserActorType extends ActorType {
    method constructor (line 225) | constructor (o) {
    method uid (line 237) | get uid () {
    method get_related_type (line 248) | get_related_type (type_class) {
  class AppUnderUserActorType (line 262) | class AppUnderUserActorType extends ActorType {
    method uid (line 268) | get uid () {
    method get_related_type (line 279) | get_related_type (type_class) {
  class AccessTokenActorType (line 295) | class AccessTokenActorType extends ActorType {
    method uid (line 307) | get uid () {
    method get_related_actor (line 319) | get_related_actor () {
  class SiteActorType (line 331) | class SiteActorType {
    method constructor (line 339) | constructor (o, ..._a) {
    method uid (line 350) | get uid () {

FILE: src/backend/src/services/auth/AntiCSRFService.js
  class AntiCSRFService (line 29) | class AntiCSRFService extends BaseService {
    method _construct (line 36) | _construct () {
    method create_token (line 78) | create_token (session) {
    method consume_token (line 96) | consume_token (session, token) {
    method generate_token_ (line 109) | generate_token_ () {
  method '__on_install.routes' (line 46) | '__on_install.routes' () {

FILE: src/backend/src/services/auth/AuthService.js
  constant APP_ORIGIN_UUID_NAMESPACE (line 33) | const APP_ORIGIN_UUID_NAMESPACE = '33de3768-8ee0-43e9-9e73-db192b97a5d8';
  constant APP_ORIGIN_CACHE_KEY_PREFIX (line 34) | const APP_ORIGIN_CACHE_KEY_PREFIX = 'auth:appOriginCanonicalization:orig...
  constant APP_ORIGIN_LOCAL_CACHE_KEY_PREFIX (line 35) | const APP_ORIGIN_LOCAL_CACHE_KEY_PREFIX = 'auth:appOriginCanonicalizatio...
  constant DEFAULT_APP_ORIGIN_CANONICAL_CACHE_TTL_SECONDS (line 36) | const DEFAULT_APP_ORIGIN_CANONICAL_CACHE_TTL_SECONDS = 300;
  constant DEFAULT_PRIVATE_APP_ASSET_TOKEN_TTL_SECONDS (line 37) | const DEFAULT_PRIVATE_APP_ASSET_TOKEN_TTL_SECONDS = 60 * 60;
  constant DEFAULT_PRIVATE_APP_ASSET_COOKIE_NAME (line 38) | const DEFAULT_PRIVATE_APP_ASSET_COOKIE_NAME = 'puter.private.asset.token';
  constant DEFAULT_PUBLIC_HOSTED_ACTOR_TOKEN_TTL_SECONDS (line 39) | const DEFAULT_PUBLIC_HOSTED_ACTOR_TOKEN_TTL_SECONDS = 15 * 60;
  constant DEFAULT_PUBLIC_HOSTED_ACTOR_COOKIE_NAME (line 40) | const DEFAULT_PUBLIC_HOSTED_ACTOR_COOKIE_NAME = 'puter.public.hosted.act...
  class AuthService (line 49) | class AuthService extends BaseService {
    method _init (line 51) | async _init () {
    method authenticate_from_token (line 95) | async authenticate_from_token (token) {
    method get_user_app_token (line 233) | get_user_app_token (app_uid) {
    method get_site_app_token (line 260) | get_site_app_token ({ site_uid }) {
    method resolvePositiveInteger (line 274) | resolvePositiveInteger (value, fallback) {
    method getPrivateAssetTokenTtlSeconds (line 282) | getPrivateAssetTokenTtlSeconds () {
    method getPrivateAssetCookieName (line 289) | getPrivateAssetCookieName () {
    method getPublicHostedActorTokenTtlSeconds (line 297) | getPublicHostedActorTokenTtlSeconds () {
    method getPublicHostedActorCookieName (line 304) | getPublicHostedActorCookieName () {
    method normalizeHostnameForCookieDomain (line 312) | normalizeHostnameForCookieDomain (hostnameValue) {
    method isCookieDomainHostEligible (line 323) | isCookieDomainHostEligible (hostnameValue) {
    method getConfiguredPrivateCookieDomains (line 332) | getConfiguredPrivateCookieDomains () {
    method getConfiguredHostedCookieDomains (line 346) | getConfiguredHostedCookieDomains () {
    method resolvePrivateAssetCookieDomain (line 362) | resolvePrivateAssetCookieDomain ({ requestHostname } = {}) {
    method getPrivateAssetCookieOptions (line 387) | getPrivateAssetCookieOptions ({ ttlSeconds, requestHostname } = {}) {
    method resolvePublicHostedActorCookieDomain (line 409) | resolvePublicHostedActorCookieDomain ({ requestHostname } = {}) {
    method getPublicHostedActorCookieOptions (line 432) | getPublicHostedActorCookieOptions ({ ttlSeconds, requestHostname } = {...
    method normalizePrivateAssetSubdomain (line 456) | normalizePrivateAssetSubdomain (subdomain) {
    method normalizePrivateAssetHost (line 462) | normalizePrivateAssetHost (privateHost) {
    method createPrivateAssetToken (line 469) | createPrivateAssetToken ({ appUid, userUid, sessionUuid, subdomain, pr...
    method createPublicHostedActorToken (line 508) | createPublicHostedActorToken ({ appUid, userUid, sessionUuid, subdomai...
    method verifyPrivateAssetToken (line 547) | verifyPrivateAssetToken (
    method verifyPublicHostedActorToken (line 637) | verifyPublicHostedActorToken (
    method resolvePrivateBootstrapSessionUuid (line 730) | resolvePrivateBootstrapSessionUuid (decoded) {
    method resolvePrivateBootstrapIdentityFromToken (line 756) | async resolvePrivateBootstrapIdentityFromToken (token, { expectedAppUi...
    method create_session_ (line 827) | async create_session_ (user, meta = {}) {
    method get_session_ (line 874) | async get_session_ (uuid) {
    method create_session_token (line 886) | async create_session_token (user, meta) {
    method create_gui_token (line 910) | create_gui_token (user, session) {
    method create_session_token_for_session (line 929) | create_session_token_for_session (user, session_uuid) {
    method check_session (line 946) | async check_session (cur_token, meta) {
    method remove_session_by_token (line 1006) | async remove_session_by_token (token) {
    method create_access_token (line 1026) | async create_access_token (authorizer, permissions, options) {
    method revoke_access_token (line 1092) | async revoke_access_token (tokenOrUuid) {
    method list_sessions (line 1121) | async list_sessions (actor) {
    method revoke_session (line 1171) | async revoke_session (actor, uuid) {
    method get_user_app_token_from_origin (line 1183) | async get_user_app_token_from_origin (origin) {
    method app_uid_from_origin (line 1229) | async app_uid_from_origin (origin) {
    method getAppOriginCanonicalCacheTtlSeconds (line 1241) | getAppOriginCanonicalCacheTtlSeconds () {
    method buildAppOriginCanonicalCacheKey (line 1248) | buildAppOriginCanonicalCacheKey ({ origin }) {
    method createAppOriginLocalCacheNamespace (line 1253) | createAppOriginLocalCacheNamespace () {
    method getAppOriginLocalCacheNamespace (line 1257) | getAppOriginLocalCacheNamespace () {
    method buildLocalCanonicalAppUidCacheKey (line 1267) | buildLocalCanonicalAppUidCacheKey (origin) {
    method readLocalCanonicalAppUidFromCache (line 1272) | readLocalCanonicalAppUidFromCache (origin) {
    method writeLocalCanonicalAppUidToCache (line 1284) | writeLocalCanonicalAppUidToCache (origin, appUid) {
    method readCanonicalAppUidFromRedisCache (line 1292) | async readCanonicalAppUidFromRedisCache (origin) {
    method writeCanonicalAppUidToRedisCache (line 1316) | async writeCanonicalAppUidToRedisCache (origin, appUid) {
    method resolveCanonicalAppUidFromOrigin (line 1328) | async re
Copy disabled (too large) Download .json
Condensed preview — 1698 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (12,022K chars).
[
  {
    "path": ".dockerignore",
    "chars": 45,
    "preview": ".dockerignore\nDockerfile\nnode_modules\n/puter\n"
  },
  {
    "path": ".env.example",
    "chars": 10,
    "preview": "PORT=4000\n"
  },
  {
    "path": ".gitattributes",
    "chars": 66,
    "preview": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 21,
    "preview": "github: ['HeyPuter']\n"
  },
  {
    "path": ".github/workflows/docker-image.yaml",
    "chars": 3093,
    "preview": "#\nname: Docker Image CI\n\n# Configures this workflow to run every time a change is pushed to the\n# branch called `main`.\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "chars": 1183,
    "preview": "name: Maintain Release Merge PR\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n  update-release-pr:\n    runs-on: ubuntu-"
  },
  {
    "path": ".github/workflows/notify-prod.yaml",
    "chars": 493,
    "preview": "name: Notify HeyPuter\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n  notify:\n    runs-on: ubuntu-latest\n    steps:\n   "
  },
  {
    "path": ".github/workflows/release-please.yml",
    "chars": 283,
    "preview": "on:\n  push:\n    branches:\n      - main\n\npermissions:\n  contents: write\n  pull-requests: write\n\nname: release-please\n\njob"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 2228,
    "preview": "name: test\n\non:\n  push:\n    branches: [\"main\"]\n    paths-ignore:\n      - \"src/docs/**\"\n  pull_request:\n    branches: [\"m"
  },
  {
    "path": ".gitignore",
    "chars": 1263,
    "preview": "# Misc\n.DS_Store\n\n# Dependencies\nnode_modules/\n\n*.zip\n*.tgz\nlicense.config.json\nlicense-header.txt\n\n# Build Outputs\ndist"
  },
  {
    "path": ".gitmodules",
    "chars": 415,
    "preview": "[submodule \"submodules/v86\"]\n\tpath = submodules/v86\n\turl = git@github.com:HeyPuter/v86.git\n[submodule \"submodules/twisp\""
  },
  {
    "path": ".husky/pre-commit",
    "chars": 295,
    "preview": "#!/usr/bin/env sh\n\ntmpfile=\"$(mktemp)\"\ngit diff --cached --name-only -z --diff-filter=ACMR -- \\\n  '*.js' '*.mjs' '*.cjs'"
  },
  {
    "path": ".idx/dev.nix",
    "chars": 1441,
    "preview": "# To learn more about how to use Nix to configure your environment\n# see: https://developers.google.com/idx/guides/custo"
  },
  {
    "path": ".is_puter_repository",
    "chars": 0,
    "preview": ""
  },
  {
    "path": ".npmrc",
    "chars": 18,
    "preview": "engine-strict=true"
  },
  {
    "path": ".prettierignore",
    "chars": 23,
    "preview": "node_modules\ndist\nbuild"
  },
  {
    "path": "BUG-BOUNTY.md",
    "chars": 3201,
    "preview": "# Puter Bug Bounty Program\n\nWe at **Puter** are committed to maintaining a secure experience for our users and community"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 81047,
    "preview": "# Changelog\n\n## v2.5.1 (2025-02-13)\n\n### Puter\n\n#### Bug Fixes\n\n- phoenix changelog ([0bcbc8f](https://github.com/HeyPut"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 3415,
    "preview": "# Contributing to Puter\n\nWelcome to Puter, the open-source distributed internet operating system. We're excited to have "
  },
  {
    "path": "Dockerfile",
    "chars": 2494,
    "preview": "# /!\\ NOTICE /!\\\n\n# Many of the developers DO NOT USE the Dockerfile or image.\n# While we do test new changes to Docker "
  },
  {
    "path": "LICENSE.txt",
    "chars": 34522,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "README.md",
    "chars": 7762,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "SECURITY-ACKNOWLEDGEMENTS.md",
    "chars": 621,
    "preview": "We would like to thank the following security researchers for their responsible disclosures:\n\n\n# 2024\n\n- Ritesh Sahu [Gi"
  },
  {
    "path": "SECURITY.md",
    "chars": 1858,
    "preview": "# Puter Security Policy\n\nThank you for helping make Puter safe. Keeping user information safe and secure is a top priori"
  },
  {
    "path": "TRADEMARK.md",
    "chars": 8334,
    "preview": "# Trademark Guidelines\n\nVersion 1.0 dated January 1, 2025\n\n<img src=\"https://puter.com/images/logo.png\" alt=\"Puter Techn"
  },
  {
    "path": "doc/AI.md",
    "chars": 1300,
    "preview": "# Documentation for Robots\n\nHello, if you're an AI agent then you're reading the correct documentation.\nHere are a few i"
  },
  {
    "path": "doc/File Structure.drawio",
    "chars": 25711,
    "preview": "<mxfile host=\"app.diagrams.net\" agent=\"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128"
  },
  {
    "path": "doc/README.md",
    "chars": 1502,
    "preview": "# Puter Documentation\n\nHi, you've found Puter's wiki page on GitHub! If you were looking for\nsomething else, you might f"
  },
  {
    "path": "doc/RFCS/20250826_captcha_cloudflare_turnstile.md",
    "chars": 5622,
    "preview": "- Feature Name: Cloudflare Turnstile CAPTCHA\n- Status: Completed\n- Created: 2025-08-26\n\n## Summary\n\nWe propose integrati"
  },
  {
    "path": "doc/api/README.md",
    "chars": 292,
    "preview": "# API Documentation\n\nNote that this documentation is different from the [puter.js docs](https://docs.puter.com).\nThe sco"
  },
  {
    "path": "doc/api/concepts/share-link.md",
    "chars": 359,
    "preview": "# Share Links\n\nA **share link** is a link to Puter's origin which contains a token\nin the query string (the key is `shar"
  },
  {
    "path": "doc/api/drivers.md",
    "chars": 2144,
    "preview": "## Puter Drivers\n\n### **POST** `/drivers/call`\n\n#### Notes\n\n- **HTTP response status** -\n  A successful driver response,"
  },
  {
    "path": "doc/api/group.md",
    "chars": 5003,
    "preview": "# Group Endpoints\n\n## POST `/group/create` (auth required)\n\n### Description\n\nCreates a group and returns a UID (UUID for"
  },
  {
    "path": "doc/api/notifications.md",
    "chars": 2522,
    "preview": "# Notification Endpoints\n\nEndpoints for managing notifications.\n\n## POST `/notif/mark-ack` (auth required)\n\n### Descript"
  },
  {
    "path": "doc/api/share.md",
    "chars": 8147,
    "preview": "# Share Endpoints\n\nShare endpoints allow sharing files with other users.\n\n## POST `/share` (auth required)\n\n### Descript"
  },
  {
    "path": "doc/api/type-tagged.md",
    "chars": 2006,
    "preview": "# Type-Tagged Objects\n\n```js\n{\n    \"$\": \"some-type\",\n    \"$version\": \"0.0.0\",\n    \n    \"some_property\": \"some value\",\n}\n"
  },
  {
    "path": "doc/api/types/app-share.md",
    "chars": 370,
    "preview": "# `{\"$\": \"app-share\"}` - File Share\n\n## Structure\n- **name:** name of the app\n- **uid:** name of the app\n\n## Notes\n- One"
  },
  {
    "path": "doc/api/types/file-share.md",
    "chars": 475,
    "preview": "# `{\"$\": \"file-share\"}` - File Share\n\n## Structure\n- **path:** file or directory's path or uuid\n- **access:** one of: `\""
  },
  {
    "path": "doc/contributors/comment_prefixes.md",
    "chars": 1208,
    "preview": "# Comment Prefixes\n\nComments have prefixes using\n[Conventional: Comments](https://conventionalcomments.org/)\nas a **loos"
  },
  {
    "path": "doc/contributors/email_testing.md",
    "chars": 3140,
    "preview": "# Local Email Testing\n\nThis guide describes how to set up and use [MailHog](https://github.com/mailhog/MailHog) for loca"
  },
  {
    "path": "doc/contributors/extensions/README.md",
    "chars": 2926,
    "preview": "# Puter Extensions\n\n## Quickstart\n\nCreate and edit this file: `mods/mods_enabled/hello-puter.js`\n\n```javascript\n// You c"
  },
  {
    "path": "doc/contributors/extensions/definitions.md",
    "chars": 341,
    "preview": "## Definitions\n\n### `core.config` - Configuration\n\nPuter's configuration object. This includes values from `config.json`"
  },
  {
    "path": "doc/contributors/extensions/dev-console.md",
    "chars": 950,
    "preview": "# dev-console extension\n\nThe **dev-console** extension provides a **dev socket** so you can run backend commands on a lo"
  },
  {
    "path": "doc/contributors/extensions/events.json.js",
    "chars": 22559,
    "preview": "export default [\n    {\n        properties: {\n            completionId: {\n                type: 'any',\n                mu"
  },
  {
    "path": "doc/contributors/extensions/events.md",
    "chars": 11931,
    "preview": "#### Property `completionId`\n\ncompletionId\n- **Type**: any\n- **Mutability**: mutable\n- **Notes**:\n\n#### Property `allow`"
  },
  {
    "path": "doc/contributors/extensions/gen.js",
    "chars": 1009,
    "preview": "import dedent from 'dedent';\nimport events from './events.json.js';\n\nconst mdlib = {};\nmdlib.h = (out, n, str) => {\n    "
  },
  {
    "path": "doc/contributors/extensions/manual_overrides.json.js",
    "chars": 2170,
    "preview": "export default [\n    {\n        id: 'core.email.validate',\n        description: `\n            This event is emitted when "
  },
  {
    "path": "doc/contributors/extensions.md",
    "chars": 831,
    "preview": "# Puter Extensions\n\n## Quickstart\n\nCreate and edit this file: `mods/mods_enabled/hello-puter.js`\n\n```javascript\nconst { "
  },
  {
    "path": "doc/contributors/structure.md",
    "chars": 3094,
    "preview": "# Repository Structure and Tooling\n\nPuter has many of its parts in a single [monorepo](https://en.wikipedia.org/wiki/Mon"
  },
  {
    "path": "doc/contributors/vscode.md",
    "chars": 33,
    "preview": "### `vscode`\n- `es6-string-html`\n"
  },
  {
    "path": "doc/devlog.md",
    "chars": 4598,
    "preview": "## 2024-10-16\n\n### Considerations for Mountpoints Feature\n\n- `_storage_upload` takes paramter `uuid` instead of `path`\n "
  },
  {
    "path": "doc/devmeta/track-comments.md",
    "chars": 2635,
    "preview": "# Track Comments\n\nComments beginning with `// track:`. See\n[comment_prefixes.md](../contributors/comment_prefixes.md)\n\n#"
  },
  {
    "path": "doc/docmeta.md",
    "chars": 1826,
    "preview": "# Meta Documentation\n\nGuidelines for documentation.\n\n## How documentation is organized\n\nThis documentation exists in the"
  },
  {
    "path": "doc/i18n/README.ar.md",
    "chars": 4128,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com، الحاسوب السحابي الشخصي: جميع ملفاتك وتطبيقاتك وألعابك في مكان واحد يم"
  },
  {
    "path": "doc/i18n/README.bn.md",
    "chars": 4117,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, ব্যক্তিগত ক্লাউড কম্পিউটার: আপনার সমস্ত ফাইল, অ্যাপস, এবং গেম এক জায়"
  },
  {
    "path": "doc/i18n/README.da.md",
    "chars": 4310,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, Den Personlige Cloudcomputer: Alle dine filer, apps og spil på ét ste"
  },
  {
    "path": "doc/i18n/README.de.md",
    "chars": 4487,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, Der persönliche Cloud-Computer: Alle Ihre Dateien, Apps und Spiele an"
  },
  {
    "path": "doc/i18n/README.en.md",
    "chars": 4221,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "doc/i18n/README.es.md",
    "chars": 7743,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, El Computador Personal en Nube: Todos tus archivos, apps y juegos en "
  },
  {
    "path": "doc/i18n/README.fa.md",
    "chars": 4269,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com، رایانش ابری شخصی: همه فایل‌ها، برنامه‌ها و بازی‌های شما در یک مکان قا"
  },
  {
    "path": "doc/i18n/README.fi.md",
    "chars": 4522,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "doc/i18n/README.fr.md",
    "chars": 4509,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, L'ordinateur cloud personnel : Tous vos fichiers, applications et jeu"
  },
  {
    "path": "doc/i18n/README.he.md",
    "chars": 4013,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, \nהענן הפרטי: כל הקבצים, האפליקציות והמשחקים שלך במקום אחד נגיש מכל מק"
  },
  {
    "path": "doc/i18n/README.hi.md",
    "chars": 7526,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: आपकी सारी फाइलें, ऐप्स, और गेम एक ही जगह"
  },
  {
    "path": "doc/i18n/README.hu.md",
    "chars": 4452,
    "preview": "<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 he"
  },
  {
    "path": "doc/i18n/README.hy.md",
    "chars": 4411,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "doc/i18n/README.id.md",
    "chars": 4423,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, Komputer Cloud Pribadi: Semua file, aplikasi, dan permainan Anda bera"
  },
  {
    "path": "doc/i18n/README.it.md",
    "chars": 4557,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "doc/i18n/README.jp.md",
    "chars": 3517,
    "preview": "\n<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, あなたのファイル、アプリ、ゲームをどこからでもアクセス可能にするパーソナルクラウドコンピュータ\" src=\"https://assets"
  },
  {
    "path": "doc/i18n/README.ko.md",
    "chars": 3670,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "doc/i18n/README.ml.md",
    "chars": 4674,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "doc/i18n/README.my.md",
    "chars": 4669,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: Semua fail, apl, dan permainan anda di s"
  },
  {
    "path": "doc/i18n/README.nl.md",
    "chars": 4278,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, De Persoonlijke Cloud Computer: Al je bestanden, apps en games op één"
  },
  {
    "path": "doc/i18n/README.od.md",
    "chars": 4834,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "doc/i18n/README.pa.md",
    "chars": 7885,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "doc/i18n/README.pl.md",
    "chars": 4209,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, Osobisty Komputer Chmurowy: Wszystkie twoje pliki, aplikacje i gry w "
  },
  {
    "path": "doc/i18n/README.pt.md",
    "chars": 7755,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, O Computador Pessoal em Nuvem: Todos os seus arquivos, aplicativos e "
  },
  {
    "path": "doc/i18n/README.ro.md",
    "chars": 4902,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, calculatorul personal în cloud: toate fișierele, aplicațiile și jocur"
  },
  {
    "path": "doc/i18n/README.ru.md",
    "chars": 4450,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, персональный облачный компьютер: все ваши файлы, приложения и игры в "
  },
  {
    "path": "doc/i18n/README.sv.md",
    "chars": 4255,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, Den personliga molndatorn: Alla dina filer, appar och spel på ett stä"
  },
  {
    "path": "doc/i18n/README.ta.md",
    "chars": 4659,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: உங்கள் கோப்புகள், ஆப்ஸ் மற்றும் கேம்கள் "
  },
  {
    "path": "doc/i18n/README.te.md",
    "chars": 7161,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: మీ అన్ని ఫైల్‌లు, యాప్‌లు మరియు గేమ్‌లను"
  },
  {
    "path": "doc/i18n/README.th.md",
    "chars": 4256,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: All your files, apps, and games in one p"
  },
  {
    "path": "doc/i18n/README.tr.md",
    "chars": 4429,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, Kişisel Bulut Bilgisayar: Tüm dosyalarınız, uygulamalarınız ve oyunla"
  },
  {
    "path": "doc/i18n/README.ua.md",
    "chars": 4331,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, The Personal Cloud Computer: Всі ваші файли, додатки та ігри в одному"
  },
  {
    "path": "doc/i18n/README.ur.md",
    "chars": 4130,
    "preview": "<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com, ذاتی کلاؤڈ کمپیوٹر: آپ کی تمام فائلیں، ایپس، اور کھیل ایک جگہ پر، کہی"
  },
  {
    "path": "doc/i18n/README.vi.md",
    "chars": 4213,
    "preview": "<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"
  },
  {
    "path": "doc/i18n/README.zh.md",
    "chars": 3416,
    "preview": "\n<h3 align=\"center\"><img width=\"80\" alt=\"Puter.com,个人云计算机:所有文件、应用程序和游戏在一个地方,随时随地可访问。\" src=\"https://assets.puter.site/put"
  },
  {
    "path": "doc/license_header.txt",
    "chars": 699,
    "preview": "Copyright (C) 2024 Puter Technologies Inc.\n\nThis file is part of Puter.\n\nPuter is free software: you can redistribute it"
  },
  {
    "path": "doc/planning/2025-10-21_puter-fs-extension.md",
    "chars": 2281,
    "preview": "## 2025-10-21\n\n### Moving PuterFSProvider to an Extension\n\nPuterFSProvider is not trivial to move to an extension becaus"
  },
  {
    "path": "doc/planning/alternatives-to-$.md",
    "chars": 3381,
    "preview": "### Problem\n\nWhen sending metadata along with arbitrary JSON objects,\na collision of property names may occur. For examp"
  },
  {
    "path": "doc/planning/micro-modules.md",
    "chars": 585,
    "preview": "# Micro Modules\n\n**CoreModule** has a large number of services. Each service handles\na general concern, like \"notificati"
  },
  {
    "path": "doc/prod.md",
    "chars": 7162,
    "preview": "# Puter in Production\n\n## Building\n    \n```bash\nnpm run build\n```\n\n## Usage\n\nWill build Puter in the `dist` directory. I"
  },
  {
    "path": "doc/self-hosters/config-vals.json.js",
    "chars": 2718,
    "preview": "export default [\n    {\n        key: 'domain',\n        description: `\n            Domain name of the Puter instance. This"
  },
  {
    "path": "doc/self-hosters/config.md",
    "chars": 2234,
    "preview": "# Configuring Puter\n\n## Terminology\n\n- **root** - the \"top level\" of configuration; if a key-value pair is in/at \"the ro"
  },
  {
    "path": "doc/self-hosters/config_values.md",
    "chars": 1831,
    "preview": "### `domain`\n\nDomain name of the Puter instance. This may be used to generate URLs\nin the UI. If \"allow_all_host_values\""
  },
  {
    "path": "doc/self-hosters/domains.md",
    "chars": 3729,
    "preview": "# Configuring Domains for Self-Hosted Puter\n\n## Local Network Configuration\n\n### Prerequisite Conditions\n\nEnsure the hos"
  },
  {
    "path": "doc/self-hosters/first-run-issues.md",
    "chars": 1708,
    "preview": "# First Run Issues\n\n## \"Cannot find package '@heyputer/backend'\"\n\nScenario: You see the following output:\n\n```\n┏━━━━━━━━"
  },
  {
    "path": "doc/self-hosters/gen.js",
    "chars": 632,
    "preview": "import dedent from 'dedent';\nimport configVals from './config-vals.json.js';\n\nconst mdlib = {};\nmdlib.h = (out, n, str) "
  },
  {
    "path": "doc/self-hosters/instructions.md",
    "chars": 2465,
    "preview": "# Self-Hosting Puter\n\n> [!WARNING]\n> The self-hosted version of Puter is currently in alpha stage and should not be used"
  },
  {
    "path": "doc/self-hosters/support.md",
    "chars": 1401,
    "preview": "## Puter Support Levels for Repository Updates\n\nThis document describes issues requiring repository changes;\nwhich issue"
  },
  {
    "path": "doc/test/playwright-test.md",
    "chars": 1117,
    "preview": "## Summary\n\nPlaywright test the puter-js API in browser environment.\n\n## Motivation\n\nSome features of the puter-js/puter"
  },
  {
    "path": "doc/testing_with_email.md",
    "chars": 861,
    "preview": "# Testing with Email\n\nTesting anything involving email is really simple using [mailhog](https://github.com/mailhog/MailH"
  },
  {
    "path": "doc/uncategorized/README.md",
    "chars": 435,
    "preview": "# Uncategorized Documentation\n\nAny document in this directory may be moved in the future to\na more suitable location. Th"
  },
  {
    "path": "doc/uncategorized/es6-note.md",
    "chars": 1444,
    "preview": "# Notes about ES6 Class Syntax\n\n## Document Meta\n\n> **backend focus:** This documentation is more relevant to\n> Puter's "
  },
  {
    "path": "doc/uncategorized/puter-mods.md",
    "chars": 2057,
    "preview": "# Puter Mods\n\n## What is a Puter Mod?\n\nCurrently, the definition of a Puter mod is:\n\n> A [Module](../../packages/backend"
  },
  {
    "path": "docker-compose.yml",
    "chars": 579,
    "preview": "---\nversion: \"3.8\"\nservices:\n  puter:\n    container_name: puter\n    image: ghcr.io/heyputer/puter:latest\n    pull_policy"
  },
  {
    "path": "eslint/bang-space-if.js",
    "chars": 2485,
    "preview": "// eslint-plugin-bang-space-if/index.js\n'use strict';\n\n/** @type {import('eslint').ESLint.Plugin} */\nexport default {\n  "
  },
  {
    "path": "eslint/control-structure-spacing.js",
    "chars": 8648,
    "preview": "export default {\n    meta: {\n        type: 'layout',\n        docs: {\n            description: 'enforce spacing inside pa"
  },
  {
    "path": "eslint/mandatory.eslint.config.js",
    "chars": 2509,
    "preview": "import tseslintPlugin from '@typescript-eslint/eslint-plugin';\nimport { defineConfig } from 'eslint/config';\nimport glob"
  },
  {
    "path": "eslint/space-unary-ops-with-exception.js",
    "chars": 1358,
    "preview": "import ruleComposer from 'eslint-rule-composer';\n\n// Adjust this require to match the package you use for the rule.\n// F"
  },
  {
    "path": "eslint.config.js",
    "chars": 6531,
    "preview": "import js from '@eslint/js';\nimport stylistic from '@stylistic/eslint-plugin';\nimport tseslintPlugin from '@typescript-e"
  },
  {
    "path": "exports.js",
    "chars": 824,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "extensions/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "extensions/README.md",
    "chars": 714,
    "preview": "# Extension System Development Guide\n\n## Where to find documentation\n\n### Here\nDocumentation for extensions is [here](sr"
  },
  {
    "path": "extensions/api.d.ts",
    "chars": 6955,
    "preview": "\nimport type APIError from '@heyputer/backend/src/api/APIError.js';\nimport type query from '@heyputer/backend/src/om/que"
  },
  {
    "path": "extensions/app-telemetry/app-user-count.ts",
    "chars": 4863,
    "preview": "const { Eq } = extension.import('query');\nconst { db } = extension.import('data');\nconst { APIError, Context } = extensi"
  },
  {
    "path": "extensions/app-telemetry/index.d.ts",
    "chars": 19,
    "preview": "import '../api.js';"
  },
  {
    "path": "extensions/app-telemetry/package.json",
    "chars": 259,
    "preview": "{\n  \"name\": \"@heyputer/app-telemetry\",\n  \"main\": \"app-user-count.js\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"postinstal"
  },
  {
    "path": "extensions/app-telemetry/tsconfig.json",
    "chars": 518,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2024\",\n    \"module\": \"nodenext\",\n    \"moduleResolution\": \"nodenext\",\n    \"root"
  },
  {
    "path": "extensions/data.js",
    "chars": 918,
    "preview": "//@extension priority -10000\n\nconst { redisClient, kvjs } = extension.import('core');\nconst svc_database = extension.imp"
  },
  {
    "path": "extensions/example-kv.js",
    "chars": 933,
    "preview": "const { kv } = extension.import('data');\nconst { sleep } = extension.import('utilities');\n\n// \"kv\" is load ready to use "
  },
  {
    "path": "extensions/example_gui_extension.js",
    "chars": 625,
    "preview": "extension.on('puter.gui.addons', async (event) => {\n    if ( event.guiParams.app ) {\n        // disabled for now\n       "
  },
  {
    "path": "extensions/exports_something.js",
    "chars": 208,
    "preview": "//@puter priority -1\nconsole.log('exporting something...');\nextension.exports = {\n    testval: 5,\n};\n\nextension.on('init"
  },
  {
    "path": "extensions/extension-util.js",
    "chars": 1058,
    "preview": "//@extension name extension\nconst { Context } = extension.import('core');\n\n// The 'create.commands' event is fired by Co"
  },
  {
    "path": "extensions/extensionController/package.json",
    "chars": 470,
    "preview": "{\n  \"name\": \"@puter/extension-controller\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"src/index.js\",\n  \"type\""
  },
  {
    "path": "extensions/extensionController/puter.json",
    "chars": 23,
    "preview": "{\n    \"priority\": -10\n}"
  },
  {
    "path": "extensions/extensionController/src/ExtensionController.ts",
    "chars": 7306,
    "preview": "import type { RequestHandler } from 'express';\nimport { StatusCodes } from 'http-status-codes';\nimport type {\n    Endpoi"
  },
  {
    "path": "extensions/extensionController/src/index.ts",
    "chars": 318,
    "preview": "import { Controller, Delete, ExtensionController, Get, HttpError, Post, Put } from './ExtensionController.js';\n\nextensio"
  },
  {
    "path": "extensions/extensionController/tsconfig.json",
    "chars": 525,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2024\",\n    \"module\": \"nodenext\",\n    \"moduleResolution\": \"nodenext\",\n    \"stri"
  },
  {
    "path": "extensions/hellodriver/config.json",
    "chars": 33,
    "preview": "{\n    \"test\": \"yes I am a test\"\n}"
  },
  {
    "path": "extensions/hellodriver/hellodriver.js",
    "chars": 4672,
    "preview": "const { kv } = extension.import('data');\n\nconst span = extension.span;\n\n/**\n * Here we create an interface called 'hello"
  },
  {
    "path": "extensions/hellodriver/package.json",
    "chars": 81,
    "preview": "{\n    \"name\": \"hellodriver\",\n    \"main\": \"hellodriver.js\",\n    \"type\": \"module\"\n}"
  },
  {
    "path": "extensions/imports_something.js",
    "chars": 215,
    "preview": "console.log('importing something...');\nconst { testval } = extension.import('exports_something');\nconsole.log(testval);\n"
  },
  {
    "path": "extensions/metering/config.json",
    "chars": 177,
    "preview": "{\n    \"unlimitedUsage\": false,\n    \"unlimitedAllowList\": [\n        \"admin\"\n    ],\n    \"allowedGlobalUsageUsers\": [\n     "
  },
  {
    "path": "extensions/metering/controllers/UsageController.ts",
    "chars": 3425,
    "preview": "/* global extension */\nimport type { BaseDatabaseAccessService } from '@heyputer/backend/src/services/database/BaseDatab"
  },
  {
    "path": "extensions/metering/eventListeners/subscriptionEvents.ts",
    "chars": 1453,
    "preview": "extension.on('metering:overrideDefaultSubscription', async (event) => {\n    // bit of a stub implementation for OSS, tec"
  },
  {
    "path": "extensions/metering/main.ts",
    "chars": 341,
    "preview": "import { UsageController } from './controllers/UsageController.js';\nimport './eventListeners/subscriptionEvents.js';\n\nco"
  },
  {
    "path": "extensions/metering/package.json",
    "chars": 204,
    "preview": "{\n  \"name\": \"@heyputer/extension-metering-service\",\n  \"main\": \"main.js\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"postins"
  },
  {
    "path": "extensions/metering/tsconfig.json",
    "chars": 526,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2024\",\n    \"module\": \"nodenext\",\n    \"moduleResolution\": \"nodenext\",\n    \"stri"
  },
  {
    "path": "extensions/metering/types.ts",
    "chars": 20,
    "preview": "import '../api.js';\n"
  },
  {
    "path": "extensions/puterfs/PuterFSProvider.js",
    "chars": 35481,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "extensions/puterfs/fsentries/BaseOperation.js",
    "chars": 757,
    "preview": "import { TeePromise } from 'teepromise';\n\nexport default class BaseOperation {\n    static STATUS_PENDING = {};\n    stati"
  },
  {
    "path": "extensions/puterfs/fsentries/Delete.js",
    "chars": 404,
    "preview": "import BaseOperation from './BaseOperation.js';\n\nexport default class extends BaseOperation {\n    constructor (uuid) {\n "
  },
  {
    "path": "extensions/puterfs/fsentries/FSEntryController.js",
    "chars": 19513,
    "preview": "import { TeePromise } from 'teepromise';\nimport BaseOperation from './BaseOperation.js';\nimport Delete from './Delete.js"
  },
  {
    "path": "extensions/puterfs/fsentries/Insert.js",
    "chars": 1821,
    "preview": "import { safeHasOwnProperty } from '../lib/objectfn.js';\nimport BaseOperation from './BaseOperation.js';\n\nexport default"
  },
  {
    "path": "extensions/puterfs/fsentries/Update.js",
    "chars": 1366,
    "preview": "import { safeHasOwnProperty } from '../lib/objectfn.js';\nimport BaseOperation from './BaseOperation.js';\n\nexport default"
  },
  {
    "path": "extensions/puterfs/lib/objectfn.js",
    "chars": 569,
    "preview": "/**\n * Instead of `myObject.hasOwnProperty(k)`, always write:\n * `safeHasOwnProperty(myObject, k)`.\n *\n * This is a less"
  },
  {
    "path": "extensions/puterfs/main.js",
    "chars": 2734,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "extensions/puterfs/package.json",
    "chars": 135,
    "preview": "{\n    \"main\": \"main.js\",\n    \"type\": \"module\",\n    \"dependencies\": {\n        \"teepromise\": \"^0.1.1\",\n        \"uuid\": \"^1"
  },
  {
    "path": "extensions/puterfs/storage/LocalDiskStorageController.js",
    "chars": 1700,
    "preview": "import fs from 'node:fs';\nimport path_ from 'node:path';\nimport { TeePromise } from 'teepromise';\n\nconst {\n    progress_"
  },
  {
    "path": "extensions/puterfs/storage/ProxyStorageController.js",
    "chars": 505,
    "preview": "export default class {\n    constructor (delegate) {\n        this.delegate = delegate ?? null;\n    }\n    setDelegate (del"
  },
  {
    "path": "extensions/serverInfo/config.json",
    "chars": 47,
    "preview": "{\n    \"allowedUsernames\": [\n        \"puter\"\n]\n}"
  },
  {
    "path": "extensions/serverInfo/index.ts",
    "chars": 2335,
    "preview": "/* global config, extension */\nimport fs from 'fs/promises';\nimport os from 'os';\nimport type {\n    ExtensionRequest,\n  "
  },
  {
    "path": "extensions/serverInfo/package.json",
    "chars": 200,
    "preview": "{\n  \"name\": \"@heyputer/server-info-extension\",\n  \"main\": \"index.js\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"postinstall"
  },
  {
    "path": "extensions/serverInfo/tsconfig.json",
    "chars": 526,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2024\",\n    \"module\": \"nodenext\",\n    \"moduleResolution\": \"nodenext\",\n    \"stri"
  },
  {
    "path": "extensions/serverInfo/types.ts",
    "chars": 20,
    "preview": "import '../api.js';\n"
  },
  {
    "path": "extensions/tsconfig.json",
    "chars": 563,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2024\",\n    \"module\": \"node16\",\n    \"moduleResolution\": \"node16\",\n    \"allowJs\""
  },
  {
    "path": "extensions/utilities.js",
    "chars": 186,
    "preview": "//@extension priority -10000\n\nextension.exports = {};\n\nextension.exports.sleep = async (seconds) => {\n    await new Prom"
  },
  {
    "path": "extensions/whoami/main.js",
    "chars": 22,
    "preview": "import './routes.js';\n"
  },
  {
    "path": "extensions/whoami/package.json",
    "chars": 160,
    "preview": "{\n    \"name\": \"@heyputer/extension-whoami\",\n    \"main\": \"main.js\",\n    \"type\": \"module\",\n    \"dependencies\": {\n        \""
  },
  {
    "path": "extensions/whoami/routes.js",
    "chars": 9567,
    "preview": "// static imports\nimport _path from 'fs';\nimport TimeAgo from 'javascript-time-ago';\nimport localeEn from 'javascript-ti"
  },
  {
    "path": "extensions/worker-sandbox.js",
    "chars": 6548,
    "preview": "const page = `\n<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"wid"
  },
  {
    "path": "install.md",
    "chars": 2209,
    "preview": "\n# INSTALL.md\n\n## Node.js & npm Installation Guide\n\n\n## 1. Arch Linux / Manjaro\n\n```bash\n# Update package database\nsudo "
  },
  {
    "path": "mod_packages/testex/package.json",
    "chars": 4,
    "preview": "{}\n"
  },
  {
    "path": "mods/README.md",
    "chars": 326,
    "preview": "# Puter Mods\n\nA list of Puter mods which may be expanded in the future.\n\n**Contributions of new mods are welcome.**\n\n## "
  },
  {
    "path": "mods/mods_available/dev-socket/main.js",
    "chars": 3392,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "mods/mods_available/dev-socket/package.json",
    "chars": 223,
    "preview": "{\n  \"name\": \"@heyputer/extension-dev-console\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Dev socket for running backend co"
  },
  {
    "path": "mods/mods_available/example/main.js",
    "chars": 935,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "mods/mods_available/example/package.json",
    "chars": 246,
    "preview": "{\n  \"name\": \"example-puter-extension\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"main.js\",\n  \"scripts\": {\n  "
  },
  {
    "path": "mods/mods_available/example-singlefile.js",
    "chars": 939,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "mods/mods_available/kdmod/CustomPuterService.js",
    "chars": 2787,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "mods/mods_available/kdmod/README.md",
    "chars": 227,
    "preview": "# Kernel Dev Mod\n\nThis mod makes testing and debugging easier.\n\n## Current Features:\n- A service-script adds `reqex` to "
  },
  {
    "path": "mods/mods_available/kdmod/ShareTestService.js",
    "chars": 8425,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "mods/mods_available/kdmod/data/sharetest_scenarios.js",
    "chars": 2946,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "mods/mods_available/kdmod/gui/main.js",
    "chars": 4254,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "mods/mods_available/kdmod/module.js",
    "chars": 1078,
    "preview": "/*\n * Copyright (C) 2024-present Puter Technologies Inc.\n *\n * This file is part of Puter.\n *\n * Puter is free software:"
  },
  {
    "path": "mods/mods_available/kdmod/package.json",
    "chars": 241,
    "preview": "{\n  \"name\": \"custom-puter-mod\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"module.js\",\n  \"scripts\": {\n    \"te"
  },
  {
    "path": "mods/mods_available/test-actions/main.js",
    "chars": 5392,
    "preview": "/*\n * Test-actions extension: declarative actions page for testing user suspension\n * and other admin actions. All chang"
  },
  {
    "path": "mods/mods_available/test-actions/package.json",
    "chars": 178,
    "preview": "{\n    \"name\": \"@heyputer/test-actions\",\n    \"version\": \"1.0.0\",\n    \"description\": \"Actions for test purposes\",\n    \"mai"
  },
  {
    "path": "mods/mods_available/testex.js",
    "chars": 4001,
    "preview": "// Test extension for event listeners\n\nextension.on('ai.prompt.complete', event => {\n    console.log('GOT AI.PROMPT.COMP"
  },
  {
    "path": "mods/mods_enabled/.gitignore",
    "chars": 14,
    "preview": "*\n!.gitignore\n"
  },
  {
    "path": "package.json",
    "chars": 3321,
    "preview": "{\n  \"name\": \"puter.com\",\n  \"version\": \"2.5.1\",\n  \"author\": \"Puter Technologies Inc.\",\n  \"license\": \"AGPL-3.0-only\",\n  \"d"
  },
  {
    "path": "rust-toolchain.toml",
    "chars": 154,
    "preview": "[toolchain]\nchannel = \"nightly\"\ncomponents = [ \"rustc\", \"rust-std\" ]\ntargets = [ \"wasm32-unknown-unknown\", \"i686-unknown"
  },
  {
    "path": "scripts/gen.sh",
    "chars": 415,
    "preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\n\nprotoc \\\n  -I=src/backend/src/filesystem/definitions/proto \\\n  --plugin=protoc-"
  },
  {
    "path": "src/backend/.gitignore",
    "chars": 2430,
    "preview": "# MAC OS hidden directory settings file\n.DS_Store\n\n# Created by https://www.toptal.com/developers/gitignore/api/node\n# E"
  },
  {
    "path": "src/backend/CONTRIBUTING.md",
    "chars": 3450,
    "preview": "# Contributing to Puter's Backend\n\n## File Structure\n\n\n\n## Architecture\n\n- [boot sequence](./doc/contributors/boot-seque"
  },
  {
    "path": "src/backend/README.md",
    "chars": 2023,
    "preview": "# Puter Backend\n\n_Part of a High-Level Distributed Operating System_\n\nWhether or not you call Puter an operating system\n"
  },
  {
    "path": "src/backend/doc/A-and-A/auth.md",
    "chars": 2977,
    "preview": "# Authentication Documentation\n\n## Concepts\n\n### Actor\n\nAn \"Actor\" is an entity that can be authenticated. The following"
  },
  {
    "path": "src/backend/doc/A-and-A/permission.md",
    "chars": 6786,
    "preview": "# Permission Documentation\n\n## Concepts\n\n### Permission\n\nA permission is a string composed of colon-delimited components"
  },
  {
    "path": "src/backend/doc/Kernel.md",
    "chars": 3082,
    "preview": "# Puter Kernel Documentation\n\n## Overview\n\nThe **Puter Kernel** is the core runtime component of the Puter system. It pr"
  },
  {
    "path": "src/backend/doc/README.md",
    "chars": 689,
    "preview": "## Backend - Contributor Documentation\n\n### Where to Start\n\nStart with [Backend File Structure](./contributors/structure"
  },
  {
    "path": "src/backend/doc/contributors/boot-sequence.md",
    "chars": 3042,
    "preview": "# Puter Backend Boot Sequence\n\nThis document describes the boot sequence of Puter's backend.\n\n**Runtime Environment**\n  "
  },
  {
    "path": "src/backend/doc/contributors/coding-style.md",
    "chars": 5488,
    "preview": "# Backend Style\n\n## File Structure\n\n### Copyright Notice\n\nAll files should begin with the standard copyright notice:\n\n``"
  },
  {
    "path": "src/backend/doc/contributors/modules.md",
    "chars": 3094,
    "preview": "# Puter Kernel Moduels and Services\n\n## Modules\n\nA Puter kernel module is simply a collection of services that run when\n"
  },
  {
    "path": "src/backend/doc/contributors/structure.md",
    "chars": 4232,
    "preview": "# Puter Backend - Directory Structure\n\n## MFU - Most Frequently Used\n\nThese locations under `/src/backend/src` are the m"
  },
  {
    "path": "src/backend/doc/dev_socket.md",
    "chars": 1158,
    "preview": "## Backend - dev socket\n\nThe \"dev socket\" allows you to interact with Puter's backend by running commands.\nIt's a UNIX s"
  },
  {
    "path": "src/backend/doc/extensions/README.md",
    "chars": 2925,
    "preview": "# Puter Backend Extensions\n\n## What Are Extensions\n\nExtensions can extend the functionality of Puter's backend by handli"
  },
  {
    "path": "src/backend/doc/extensions/builtins/data.md",
    "chars": 2837,
    "preview": "## Extensions - the `data` extension\n\nThe `data` extension can be imported in custom extensions for access\nto the databa"
  },
  {
    "path": "src/backend/doc/extensions/pages/core-devs.md",
    "chars": 6731,
    "preview": "## Extensions - Technical Context for Core Devs\n\nThis document provides technical context for extensions from the perspe"
  }
]

// ... and 1498 more files (download for full content)

About this extraction

This page contains the full source code of the HeyPuter/puter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1698 files (10.9 MB), approximately 3.0M tokens, and a symbol index with 4551 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!