diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..45fd5d159 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,13 @@ +## Describe Your Changes + +- + +## Fixes Issues + +- + +## Self Checklist + +- [ ] Added relevant comments, esp in complex areas +- [ ] Updated docs (for bug fixes / features) +- [ ] Created issues for follow-up changes or refactoring needed diff --git a/README.md b/README.md index 7d8cd7802..31e2c4714 100644 --- a/README.md +++ b/README.md @@ -70,25 +70,25 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute
jan.exe
Intel
M1/M2
jan.deb
diff --git a/core/src/node/index.ts b/core/src/node/index.ts
index 49c2c3c26..50651d1fd 100644
--- a/core/src/node/index.ts
+++ b/core/src/node/index.ts
@@ -5,3 +5,4 @@ export * from './extension/store'
export * from './download'
export * from './module'
export * from './api'
+export * from './log'
diff --git a/core/src/node/log.ts b/core/src/node/log.ts
new file mode 100644
index 000000000..7291516cd
--- /dev/null
+++ b/core/src/node/log.ts
@@ -0,0 +1,18 @@
+import fs from 'fs'
+import util from 'util'
+import path from 'path'
+import os from 'os'
+
+const appDir = path.join(os.homedir(), 'jan')
+
+export const logPath = path.join(appDir, 'app.log')
+
+export const log = function (d: any) {
+ if (fs.existsSync(appDir)) {
+ var log_file = fs.createWriteStream(logPath, {
+ flags: 'a',
+ })
+ log_file.write(util.format(d) + '\n')
+ log_file.close()
+ }
+}
diff --git a/docs/docs/docs/README.md b/docs/docs/docs/README.md
index d6ff08d55..a82a8a801 100644
--- a/docs/docs/docs/README.md
+++ b/docs/docs/docs/README.md
@@ -3,4 +3,69 @@ title: Overview
slug: /docs
---
-Hello world
+The following low-level docs are aimed at core contributors and cover how to contribute to the Core SDK.
+
+:::tip
+If you are interested to **build on top of the SDK**, like creating assistants or adding app level extensions, please refer to [developer docs](/developer) instead.
+:::
+
+## Core SDK
+
+At its Core, Jan is a cross-platform, local-first and AI native framework that can be used to build anything. In fact, current features are all implemented as 3rd party extensions on top of this Core SDK.
+
+Ultimately, we aim for a VSCode or Obsidian like framework that allows devs to build and customize complex AI applications for their specific needs, in less than 15 minutes.
+
+### Cross Platform
+
+Jan follows [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) to the best of our ability. Though leaky abstractions remain (we're a fast moving, open source codebase), we do our best to build an SDK that allows devs to **build once, deploy everywhere.**
+
+Currently, Jan supports:
+
+- `Node Native Runtime`, good for server side apps
+- `Electron Chromium`, good for Desktop Native apps
+- `Capacitor`, good for Mobile apps (planned, not built yet)
+- `Python Runtime`, good for MLOps workflows (planned, not built yet)
+
+Currently, Jan works across:
+
+- Mac Intel & Silicon
+- Windows
+- Ubuntu
+- Nvidia GPUs
+
+Read more:
+
+- [Code Entrypoint](https://github.com/janhq/jan/tree/main/core)
+- [Dependency Inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle)
+
+### Local First
+
+Jan's data persistence happens on the user's local filesystem.
+
+We implemented abstractions on top of `fs` and other core modules in an opinionated way, s.t. user data is saved in a folder-based framework that lets users easily package, export, and manage their data.
+
+Read more:
+
+- [Folder-based fs wrapper](https://github.com/janhq/jan/blob/main/core/src/fs.ts)
+- [Piping Node modules across infrastructures](https://github.com/janhq/jan/tree/main/core/src/node)
+
+### AI Native
+
+All software applications can be natively supercharged with an embedded AI server and AI abstractions.
+
+Including:
+
+- OpenAI Compatible AI [types](https://github.com/janhq/jan/tree/main/core/src/types) and [core extensions](https://github.com/janhq/jan/tree/main/core/src/extensions) to support common functionality like making an inference call.
+- A lightweight, embedded C++ [inference engine](https://github.com/janhq/jan/tree/main/extensions/inference-nitro-extension) that's immediately callable from code.
+
+- [Code Entrypoint](https://github.com/janhq/jan/tree/main/core/src/api)
+
+## Fun Project Ideas
+
+Beyond the current Jan client and UX, the Core SDK can be used to build many other AI-powered and privacy preserving applications.
+
+- `Game engine`: For AI enabled character games, procedural generation games
+- `Health app`: For a personal healthcare app that improves habits
+- Got ideas? Make a PR into this docs page!
+
+If you are interested to tackle these issues, or have suggestions for integrations and other OSS tools we can use, please hit us up in [Discord](https://discord.gg/5rQ2zTv3be).
diff --git a/docs/docs/handbook/onboarding.md b/docs/docs/handbook/onboarding.md
index e9124bdad..3aec99258 100644
--- a/docs/docs/handbook/onboarding.md
+++ b/docs/docs/handbook/onboarding.md
@@ -32,7 +32,7 @@ Welcome to Jan! We’re really excited to bring you onboard.
- We operate on the basis of trust.
- We expect you to be available and communicative during scheduled meetings or work hours.
- Turning on video during meetings is encouraged.
-- Casual dress during meetings is acceptable; however, use discretion (No naked top, pajamas, etc.)
+- Casual dress during meetings is acceptable; however, use discretion (No nudity, pajamas, etc.)
- While it’s natural for people to disagree at times, disagreement is no excuse for poor behavior and poor manners. We cannot allow that frustration to turn into a personal attack.
- Respect other people's cultures. Especially since we are working in a diverse working culture.
- Sexual harassment is a specific type of prohibited conduct. Sexual harassment is any unwelcome conduct of a sexual nature that might reasonably be expected or be perceived to cause offense or humiliation. Sexual harassment may involve any conduct of a verbal, nonverbal, or physical nature, including written and electronic communications, and may occur between persons of the same or different genders.
diff --git a/electron/main.ts b/electron/main.ts
index 4ddf4df56..257842cf5 100644
--- a/electron/main.ts
+++ b/electron/main.ts
@@ -68,6 +68,12 @@ function createMainWindow() {
if (process.platform !== 'darwin') app.quit()
})
+ /* Open external links in the default browser */
+ mainWindow.webContents.setWindowOpenHandler(({ url }) => {
+ require('electron').shell.openExternal(url)
+ return { action: 'deny' }
+ })
+
/* Enable dev tools for development */
if (!app.isPackaged) mainWindow.webContents.openDevTools()
}
diff --git a/extensions/monitoring-extension/package.json b/extensions/monitoring-extension/package.json
index 4fc51d578..9935e536e 100644
--- a/extensions/monitoring-extension/package.json
+++ b/extensions/monitoring-extension/package.json
@@ -17,7 +17,7 @@
},
"dependencies": {
"@janhq/core": "file:../../core",
- "os-utils": "^0.0.14",
+ "node-os-utils": "^1.3.7",
"ts-loader": "^9.5.0"
},
"files": [
@@ -26,6 +26,6 @@
"README.md"
],
"bundleDependencies": [
- "os-utils"
+ "node-os-utils"
]
}
diff --git a/extensions/monitoring-extension/src/module.ts b/extensions/monitoring-extension/src/module.ts
index 18b3b6c49..310e7359c 100644
--- a/extensions/monitoring-extension/src/module.ts
+++ b/extensions/monitoring-extension/src/module.ts
@@ -1,25 +1,25 @@
const os = require("os");
-const osUtils = require("os-utils");
+const nodeOsUtils = require("node-os-utils");
const getResourcesInfo = () =>
new Promise((resolve) => {
- const totalMemory = os.totalmem();
- const freeMemory = os.freemem();
- const usedMemory = totalMemory - freeMemory;
-
- const response = {
- mem: {
- totalMemory,
- usedMemory,
- },
- };
- resolve(response);
+ nodeOsUtils.mem.used()
+ .then(ramUsedInfo => {
+ const totalMemory = ramUsedInfo.totalMemMb * 1024 * 1024;
+ const usedMemory = ramUsedInfo.usedMemMb * 1024 * 1024;
+ const response = {
+ mem: {
+ totalMemory,
+ usedMemory,
+ },
+ };
+ resolve(response);
+ })
});
const getCurrentLoad = () =>
new Promise((resolve) => {
- osUtils.cpuUsage(function(v){
- const cpuPercentage = v * 100;
+ nodeOsUtils.cpu.usage().then(cpuPercentage =>{
const response = {
cpu: {
usage: cpuPercentage,
diff --git a/server/index.ts b/server/index.ts
index 6a03c06fd..55b4a8d3c 100644
--- a/server/index.ts
+++ b/server/index.ts
@@ -1,9 +1,8 @@
import fastify from "fastify";
import dotenv from "dotenv";
-import { v1Router } from "@janhq/core/node";
+import { log, v1Router } from "@janhq/core/node";
import path from "path";
-import fs from "fs";
-import util from "util";
+
import os from "os";
dotenv.config();
@@ -14,18 +13,6 @@ const serverLogPath = path.join(os.homedir(), "jan", "server.log");
let server: any | undefined = undefined;
-var log_file = fs.createWriteStream(serverLogPath, {
- flags: "a",
-});
-var log_stdout = process.stdout;
-var log_stderr = process.stderr;
-
-const logServer = function (d: any) {
- log_file.write(util.format(d) + "\n");
- log_stdout.write(util.format(d) + "\n");
- log_stderr.write(util.format(d) + "\n");
-};
-
export const startServer = async (schemaPath?: string, baseDir?: string) => {
try {
server = fastify({
@@ -75,12 +62,10 @@ export const startServer = async (schemaPath?: string, baseDir?: string) => {
host: JAN_API_HOST,
})
.then(() => {
- logServer(
- `JAN API listening at: http://${JAN_API_HOST}:${JAN_API_PORT}`
- );
+ log(`JAN API listening at: http://${JAN_API_HOST}:${JAN_API_PORT}`);
});
} catch (e) {
- logServer(e);
+ log(e);
}
};
@@ -88,6 +73,6 @@ export const stopServer = async () => {
try {
await server.close();
} catch (e) {
- logServer(e);
+ log(e);
}
};
diff --git a/web/containers/Layout/Ribbon/index.tsx b/web/containers/Layout/Ribbon/index.tsx
index fa6d53193..6a0146e64 100644
--- a/web/containers/Layout/Ribbon/index.tsx
+++ b/web/containers/Layout/Ribbon/index.tsx
@@ -11,6 +11,8 @@ import {
SettingsIcon,
MonitorIcon,
LayoutGridIcon,
+ Twitter,
+ Github,
} from 'lucide-react'
import { twMerge } from 'tailwind-merge'
@@ -52,6 +54,23 @@ export default function RibbonNav() {
},
]
+ const linksMenu = [
+ {
+ name: 'Twitter',
+ icon: (
+