@node-agent/local 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LKJacky
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,36 @@
1
- # Temporary Holding Version
1
+ # @node-agent/local
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Run NodeAgentOS locally: one persistent agent, one bus, and the core nodes in a single command.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npx @node-agent/local
9
+ # open http://127.0.0.1:8790/
10
+ ```
11
+
12
+ Node 23.6 or newer is required. Bring an OpenAI-compatible model key; the first run opens the
13
+ onboarding page and stores the setup locally.
14
+
15
+ ## Environment
16
+
17
+ | variable | meaning |
18
+ |---|---|
19
+ | `NODE_AGENT_BUS_PORT` | bus port; `0` picks a free one |
20
+ | `NODE_AGENT_BUS_BIND` | bus bind address, default `127.0.0.1` |
21
+ | `NODE_AGENT_NODES` | extra core nodes, comma separated package names |
22
+ | `NODE_AGENT_ACCESS_TOKEN` | optional login proxy token; unset keeps the stack local |
23
+ | `NODE_AGENT_USER` | deployment user id, default `default` |
24
+
25
+ ## What starts
26
+
27
+ - the runtime and shared WebSocket bus
28
+ - the persistent agent and history
29
+ - the optional core nodes: provider, webui, notes, todo, timer, search, introduce
30
+
31
+ The runtime is bundled into the launcher, so `@node-agent/runtime` does not need a separate registry
32
+ install. Nodes stay independent packages and can be replaced or extended. See the repository README for the architecture and Node contract.
33
+
34
+ ## License
35
+
36
+ MIT
@@ -0,0 +1,5 @@
1
+ export * from 'node-agent-bus';
2
+ export * from 'node-agent-agent';
3
+ export * from 'node-agent-history';
4
+ export * from './runtime/index.js';
5
+ export * from './local.js';
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ // node-agent: the meta package — the bus (node-agent-bus) and the agent node (node-agent-agent)
2
+ // still go out under this one name, and the backend entry serve.ts lives here too, so bin:
3
+ // node-agent and consumers' existing imports are unchanged.
4
+ export * from 'node-agent-bus';
5
+ export * from 'node-agent-agent';
6
+ export * from 'node-agent-history';
7
+ export * from './runtime/index.js';
8
+ export * from './local.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,2FAA2F;AAC3F,4DAA4D;AAC5D,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type Locale } from '@node-agent/sdk';
2
+ /**
3
+ * The language the environment names, if it names one of ours.
4
+ *
5
+ * `LC_ALL`, `LC_MESSAGES`, `LANG`, `LANGUAGE` -- and each value in the shapes a POSIX locale comes
6
+ * in: `zh_CN.UTF-8`, `en_US.utf8`, `zh_CN.UTF-8@euro`. `normalizeLocale` reads all of them, because
7
+ * the language is the first subtag of the tag. `C`, `POSIX` and a variable that is not set name
8
+ * nothing of ours, so the walk moves on instead of giving up on the environment.
9
+ */
10
+ export declare function languageFromEnvironment(env?: NodeJS.ProcessEnv): Locale | undefined;
11
+ /** The locale the runtime's own ICU data resolved, asked of `Intl`: the last thing to try before
12
+ * the default. A runtime built without full ICU answers `undefined` here and the walk goes on. */
13
+ export declare function localeFromIcu(): Locale | undefined;
@@ -0,0 +1,48 @@
1
+ // The language a process runs in: the POSIX variables a locale comes from, and the locale the
2
+ // runtime's own ICU data resolved.
3
+ //
4
+ // They belong to the runtime, not to every node: the runtime asks them once, at startup, to settle
5
+ // the language a stack speaks, and stores the answer in the profile. The setup itself only reads
6
+ // `system.language`, so no node needs a reading of `zh_CN.UTF-8` of its own -- and the SDK, which is
7
+ // also the browser's, stays free of `process`.
8
+ import { normalizeLocale } from '@node-agent/sdk';
9
+ /** The POSIX variables that name a language, in the order POSIX gives them. */
10
+ const LOCALE_VARIABLES = ['LC_ALL', 'LC_MESSAGES', 'LANG', 'LANGUAGE'];
11
+ /** The tags one variable holds: `LANGUAGE` is a colon-separated list, the others hold one tag. */
12
+ function tagsOf(value) {
13
+ if (typeof value !== 'string')
14
+ return [];
15
+ return value
16
+ .split(':')
17
+ .map((one) => one.trim())
18
+ .filter((one) => one !== '');
19
+ }
20
+ /**
21
+ * The language the environment names, if it names one of ours.
22
+ *
23
+ * `LC_ALL`, `LC_MESSAGES`, `LANG`, `LANGUAGE` -- and each value in the shapes a POSIX locale comes
24
+ * in: `zh_CN.UTF-8`, `en_US.utf8`, `zh_CN.UTF-8@euro`. `normalizeLocale` reads all of them, because
25
+ * the language is the first subtag of the tag. `C`, `POSIX` and a variable that is not set name
26
+ * nothing of ours, so the walk moves on instead of giving up on the environment.
27
+ */
28
+ export function languageFromEnvironment(env = process.env) {
29
+ for (const name of LOCALE_VARIABLES) {
30
+ for (const tag of tagsOf(env[name])) {
31
+ const locale = normalizeLocale(tag);
32
+ if (locale !== null)
33
+ return locale;
34
+ }
35
+ }
36
+ return undefined;
37
+ }
38
+ /** The locale the runtime's own ICU data resolved, asked of `Intl`: the last thing to try before
39
+ * the default. A runtime built without full ICU answers `undefined` here and the walk goes on. */
40
+ export function localeFromIcu() {
41
+ try {
42
+ return normalizeLocale(Intl.DateTimeFormat().resolvedOptions().locale) ?? undefined;
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ }
48
+ //# sourceMappingURL=language-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language-env.js","sourceRoot":"","sources":["../src/language-env.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,mCAAmC;AACnC,EAAE;AACF,mGAAmG;AACnG,iGAAiG;AACjG,qGAAqG;AACrG,+CAA+C;AAC/C,OAAO,EAAE,eAAe,EAAe,MAAM,iBAAiB,CAAC;AAE/D,+EAA+E;AAC/E,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAEhF,kGAAkG;AAClG,SAAS,MAAM,CAAC,KAAyB;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzC,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;SACxB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IAC1E,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACpC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,MAAM,KAAK,IAAI;gBAAE,OAAO,MAAM,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;mGACmG;AACnG,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC;QACH,OAAO,eAAe,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { Bus } from 'node-agent-bus';
2
+ import { type BusHandle, type BusOptions, type NodeHandle, type NodeOptions, type Runtime, type RuntimeServerOptions, type UserHandle } from './runtime/index.js';
3
+ export declare class LocalRuntime implements Runtime {
4
+ /** One node launch at a time: two users asking at startup must not spawn the same shared node twice. */
5
+ private launchQueue;
6
+ private readonly options;
7
+ private readonly logger?;
8
+ private busRecord;
9
+ private readonly nodes;
10
+ private readonly knownUsers;
11
+ constructor(options?: RuntimeServerOptions);
12
+ /** The shared bus, once it is listening. Used by the process entry to print its user table. */
13
+ get bus(): Bus | undefined;
14
+ private home;
15
+ private nodeHome;
16
+ /** The bus never sees a display name: it sees a stable digest of the name. */
17
+ private busId;
18
+ busUser(user: string): string;
19
+ private tokenFor;
20
+ launchBus(options?: BusOptions): Promise<BusHandle>;
21
+ stopBus(): Promise<void>;
22
+ launchNode(node: string, options?: NodeOptions): Promise<NodeHandle>;
23
+ private launchNodeNow;
24
+ stopNode(node: string): Promise<void>;
25
+ createUser(user: string): Promise<UserHandle>;
26
+ destroyUser(user: string): Promise<void>;
27
+ connect(user: string, node: string, options?: NodeOptions): Promise<NodeHandle>;
28
+ disconnect(user: string, node: string): Promise<void>;
29
+ /** Every user this runtime has connected, and the shared nodes each one may reach. */
30
+ sessions(user?: string): Promise<Record<string, unknown>>;
31
+ /** The newest package the installer materialized for this user, if there is one. */
32
+ private installedPackage;
33
+ private nodeRunning;
34
+ /** Where the shared page node printed its address, if it has started yet. */
35
+ private webuiTarget;
36
+ /** The shared bus, for a trusted caller that has to proxy an outside node. */
37
+ busTarget(): {
38
+ url: string;
39
+ token: string;
40
+ } | undefined;
41
+ /** Recent stdout/stderr of one running node, for the entry process to surface its address. */
42
+ nodeOutput(node: string): string | undefined;
43
+ stopAll(): Promise<void>;
44
+ }