natroc 0.0.1
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/AGENTS.md +494 -0
- package/LICENSE +7 -0
- package/README.md +0 -0
- package/install.ps1 +109 -0
- package/install.sh +132 -0
- package/package.json +77 -0
- package/server/dist/agent/agent-loop.d.ts +71 -0
- package/server/dist/agent/agent-loop.js +171 -0
- package/server/dist/agent/agent-loop.js.map +1 -0
- package/server/dist/agent/home-context.d.ts +29 -0
- package/server/dist/agent/home-context.js +134 -0
- package/server/dist/agent/home-context.js.map +1 -0
- package/server/dist/agent/improvement-engine.d.ts +23 -0
- package/server/dist/agent/improvement-engine.js +107 -0
- package/server/dist/agent/improvement-engine.js.map +1 -0
- package/server/dist/agent/tools/index.d.ts +14 -0
- package/server/dist/agent/tools/index.js +85 -0
- package/server/dist/agent/tools/index.js.map +1 -0
- package/server/dist/agent/tools/list-directory.d.ts +2 -0
- package/server/dist/agent/tools/list-directory.js +27 -0
- package/server/dist/agent/tools/list-directory.js.map +1 -0
- package/server/dist/agent/tools/read-file.d.ts +2 -0
- package/server/dist/agent/tools/read-file.js +30 -0
- package/server/dist/agent/tools/read-file.js.map +1 -0
- package/server/dist/agent/tools/run-command.d.ts +2 -0
- package/server/dist/agent/tools/run-command.js +72 -0
- package/server/dist/agent/tools/run-command.js.map +1 -0
- package/server/dist/agent/tools/system-info.d.ts +2 -0
- package/server/dist/agent/tools/system-info.js +28 -0
- package/server/dist/agent/tools/system-info.js.map +1 -0
- package/server/dist/agent/tools/types.d.ts +18 -0
- package/server/dist/agent/tools/types.js +2 -0
- package/server/dist/agent/tools/types.js.map +1 -0
- package/server/dist/agent/tools/util.d.ts +7 -0
- package/server/dist/agent/tools/util.js +24 -0
- package/server/dist/agent/tools/util.js.map +1 -0
- package/server/dist/agent/tools/write-file.d.ts +2 -0
- package/server/dist/agent/tools/write-file.js +25 -0
- package/server/dist/agent/tools/write-file.js.map +1 -0
- package/server/dist/app.d.ts +8 -0
- package/server/dist/app.js +39 -0
- package/server/dist/app.js.map +1 -0
- package/server/dist/auth/password.d.ts +7 -0
- package/server/dist/auth/password.js +20 -0
- package/server/dist/auth/password.js.map +1 -0
- package/server/dist/channels/channel-runtime.d.ts +32 -0
- package/server/dist/channels/channel-runtime.js +484 -0
- package/server/dist/channels/channel-runtime.js.map +1 -0
- package/server/dist/cli/agent-deliver.d.ts +14 -0
- package/server/dist/cli/agent-deliver.js +183 -0
- package/server/dist/cli/agent-deliver.js.map +1 -0
- package/server/dist/cli/args.d.ts +11 -0
- package/server/dist/cli/args.js +57 -0
- package/server/dist/cli/args.js.map +1 -0
- package/server/dist/cli/cli-token.d.ts +1 -0
- package/server/dist/cli/cli-token.js +22 -0
- package/server/dist/cli/cli-token.js.map +1 -0
- package/server/dist/cli/daemon.d.ts +2 -0
- package/server/dist/cli/daemon.js +252 -0
- package/server/dist/cli/daemon.js.map +1 -0
- package/server/dist/cli.d.ts +2 -0
- package/server/dist/cli.js +416 -0
- package/server/dist/cli.js.map +1 -0
- package/server/dist/config/natroc-home.d.ts +13 -0
- package/server/dist/config/natroc-home.js +730 -0
- package/server/dist/config/natroc-home.js.map +1 -0
- package/server/dist/gateway/agent-service.d.ts +16 -0
- package/server/dist/gateway/agent-service.js +261 -0
- package/server/dist/gateway/agent-service.js.map +1 -0
- package/server/dist/gateway/connection.d.ts +38 -0
- package/server/dist/gateway/connection.js +254 -0
- package/server/dist/gateway/connection.js.map +1 -0
- package/server/dist/gateway/gateway.d.ts +79 -0
- package/server/dist/gateway/gateway.js +150 -0
- package/server/dist/gateway/gateway.js.map +1 -0
- package/server/dist/gateway/index.d.ts +8 -0
- package/server/dist/gateway/index.js +26 -0
- package/server/dist/gateway/index.js.map +1 -0
- package/server/dist/gateway/protocol.d.ts +102 -0
- package/server/dist/gateway/protocol.js +63 -0
- package/server/dist/gateway/protocol.js.map +1 -0
- package/server/dist/gateway/rpc/agent.d.ts +3 -0
- package/server/dist/gateway/rpc/agent.js +174 -0
- package/server/dist/gateway/rpc/agent.js.map +1 -0
- package/server/dist/gateway/rpc/agents.d.ts +2 -0
- package/server/dist/gateway/rpc/agents.js +68 -0
- package/server/dist/gateway/rpc/agents.js.map +1 -0
- package/server/dist/gateway/rpc/auth.d.ts +3 -0
- package/server/dist/gateway/rpc/auth.js +180 -0
- package/server/dist/gateway/rpc/auth.js.map +1 -0
- package/server/dist/gateway/rpc/channels.d.ts +2 -0
- package/server/dist/gateway/rpc/channels.js +230 -0
- package/server/dist/gateway/rpc/channels.js.map +1 -0
- package/server/dist/gateway/rpc/conversations.d.ts +3 -0
- package/server/dist/gateway/rpc/conversations.js +36 -0
- package/server/dist/gateway/rpc/conversations.js.map +1 -0
- package/server/dist/gateway/rpc/projects.d.ts +3 -0
- package/server/dist/gateway/rpc/projects.js +49 -0
- package/server/dist/gateway/rpc/projects.js.map +1 -0
- package/server/dist/gateway/rpc/providers.d.ts +3 -0
- package/server/dist/gateway/rpc/providers.js +106 -0
- package/server/dist/gateway/rpc/providers.js.map +1 -0
- package/server/dist/gateway/rpc/usage.d.ts +2 -0
- package/server/dist/gateway/rpc/usage.js +41 -0
- package/server/dist/gateway/rpc/usage.js.map +1 -0
- package/server/dist/gateway/types.d.ts +43 -0
- package/server/dist/gateway/types.js +20 -0
- package/server/dist/gateway/types.js.map +1 -0
- package/server/dist/gateway/ws-server.d.ts +10 -0
- package/server/dist/gateway/ws-server.js +37 -0
- package/server/dist/gateway/ws-server.js.map +1 -0
- package/server/dist/index.d.ts +1 -0
- package/server/dist/index.js +9 -0
- package/server/dist/index.js.map +1 -0
- package/server/dist/local-runtime.d.ts +9 -0
- package/server/dist/local-runtime.js +16 -0
- package/server/dist/local-runtime.js.map +1 -0
- package/server/dist/providers/configured-adapters.d.ts +9 -0
- package/server/dist/providers/configured-adapters.js +34 -0
- package/server/dist/providers/configured-adapters.js.map +1 -0
- package/server/dist/providers/ollama.d.ts +23 -0
- package/server/dist/providers/ollama.js +164 -0
- package/server/dist/providers/ollama.js.map +1 -0
- package/server/dist/providers/openrouter.d.ts +24 -0
- package/server/dist/providers/openrouter.js +201 -0
- package/server/dist/providers/openrouter.js.map +1 -0
- package/server/dist/providers/thinking.d.ts +18 -0
- package/server/dist/providers/thinking.js +58 -0
- package/server/dist/providers/thinking.js.map +1 -0
- package/server/dist/providers/types.d.ts +55 -0
- package/server/dist/providers/types.js +2 -0
- package/server/dist/providers/types.js.map +1 -0
- package/server/dist/routes/schemas.d.ts +51 -0
- package/server/dist/routes/schemas.js +53 -0
- package/server/dist/routes/schemas.js.map +1 -0
- package/server/dist/runtime.d.ts +47 -0
- package/server/dist/runtime.js +29 -0
- package/server/dist/runtime.js.map +1 -0
- package/server/dist/server.d.ts +11 -0
- package/server/dist/server.js +19 -0
- package/server/dist/server.js.map +1 -0
- package/server/dist/storage/agent-repository.d.ts +59 -0
- package/server/dist/storage/agent-repository.js +192 -0
- package/server/dist/storage/agent-repository.js.map +1 -0
- package/server/dist/storage/auth-repository.d.ts +49 -0
- package/server/dist/storage/auth-repository.js +139 -0
- package/server/dist/storage/auth-repository.js.map +1 -0
- package/server/dist/storage/channel-repository.d.ts +152 -0
- package/server/dist/storage/channel-repository.js +413 -0
- package/server/dist/storage/channel-repository.js.map +1 -0
- package/server/dist/storage/conversation-repository.d.ts +63 -0
- package/server/dist/storage/conversation-repository.js +196 -0
- package/server/dist/storage/conversation-repository.js.map +1 -0
- package/server/dist/storage/database.d.ts +11 -0
- package/server/dist/storage/database.js +360 -0
- package/server/dist/storage/database.js.map +1 -0
- package/server/dist/storage/memory-repository.d.ts +70 -0
- package/server/dist/storage/memory-repository.js +279 -0
- package/server/dist/storage/memory-repository.js.map +1 -0
- package/server/dist/storage/project-repository.d.ts +25 -0
- package/server/dist/storage/project-repository.js +67 -0
- package/server/dist/storage/project-repository.js.map +1 -0
- package/server/dist/storage/provider-repository.d.ts +44 -0
- package/server/dist/storage/provider-repository.js +159 -0
- package/server/dist/storage/provider-repository.js.map +1 -0
- package/server/dist/storage/tool-call-repository.d.ts +35 -0
- package/server/dist/storage/tool-call-repository.js +83 -0
- package/server/dist/storage/tool-call-repository.js.map +1 -0
- package/server/dist/storage/usage-repository.d.ts +76 -0
- package/server/dist/storage/usage-repository.js +249 -0
- package/server/dist/storage/usage-repository.js.map +1 -0
- package/server/dist/storage/vault.d.ts +3 -0
- package/server/dist/storage/vault.js +57 -0
- package/server/dist/storage/vault.js.map +1 -0
- package/ui/README.md +0 -0
- package/ui/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/ui/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/ui/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/ui/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/ui/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/ui/dist/assets/index-DKaFmZNO.js +114 -0
- package/ui/dist/assets/index-DOfPcjx3.css +2 -0
- package/ui/dist/index.html +14 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token didapat dari (urutan): `--token <t>`, env `NATROC_TOKEN`, atau file
|
|
3
|
+
* `~/.natroc/cli-token`. Buat dengan `natroc cli-token`.
|
|
4
|
+
*/
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { getNatrocPaths } from "../config/natroc-home.js";
|
|
9
|
+
/** Entrypoint sub-command. */
|
|
10
|
+
export async function runAgentDeliver(options) {
|
|
11
|
+
if (!options.message) {
|
|
12
|
+
throw new Error("`--message` is required.");
|
|
13
|
+
}
|
|
14
|
+
const token = await resolveCliToken(options.token);
|
|
15
|
+
if (!token) {
|
|
16
|
+
throw new Error("No CLI token. Pass `--token <t>`, set `NATROC_TOKEN`, or run `natroc cli-token`.");
|
|
17
|
+
}
|
|
18
|
+
const host = options.host ?? "127.0.0.1";
|
|
19
|
+
const port = options.port ?? 18789;
|
|
20
|
+
const url = `ws://${host}:${port}/gateway`;
|
|
21
|
+
const client = await GatewayWsClient.connect(url, token);
|
|
22
|
+
try {
|
|
23
|
+
const result = await client.stream("agent.chat", {
|
|
24
|
+
message: options.message,
|
|
25
|
+
agentId: options.agentId,
|
|
26
|
+
}, (event) => {
|
|
27
|
+
if (options.verbose) {
|
|
28
|
+
process.stdout.write(`[event] ${JSON.stringify(event)}\n`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const responseText = extractAgentText(result);
|
|
32
|
+
process.stdout.write(responseText + "\n");
|
|
33
|
+
if (options.to && options.accountId) {
|
|
34
|
+
await client.unary("channels.send", {
|
|
35
|
+
accountId: options.accountId,
|
|
36
|
+
peer: options.to,
|
|
37
|
+
text: responseText,
|
|
38
|
+
idempotencyKey: randomUUID(),
|
|
39
|
+
});
|
|
40
|
+
process.stderr.write(`Delivered to ${options.to}\n`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
client.close();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Helper: hasilkan teks balasan dari payload `agent.chat`. */
|
|
48
|
+
function extractAgentText(payload) {
|
|
49
|
+
if (!payload || typeof payload !== "object")
|
|
50
|
+
return "";
|
|
51
|
+
const record = payload;
|
|
52
|
+
if (typeof record.content === "string")
|
|
53
|
+
return record.content.trim();
|
|
54
|
+
if (typeof record.text === "string")
|
|
55
|
+
return record.text.trim();
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
/** Membaca CLI token dari (--token | NATROC_TOKEN | file `~/.natroc/cli-token`). */
|
|
59
|
+
async function resolveCliToken(explicit) {
|
|
60
|
+
if (explicit)
|
|
61
|
+
return explicit;
|
|
62
|
+
if (process.env.NATROC_TOKEN)
|
|
63
|
+
return process.env.NATROC_TOKEN;
|
|
64
|
+
const paths = getNatrocPaths();
|
|
65
|
+
const tokenPath = join(paths.root, "cli-token");
|
|
66
|
+
try {
|
|
67
|
+
const buf = await readFile(tokenPath, "utf8");
|
|
68
|
+
const value = buf.trim();
|
|
69
|
+
return value.length > 0 ? value : null;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Klien WebSocket gateway minimal untuk Node CLI. Memakai global WebSocket
|
|
77
|
+
* (Node 22+); tidak butuh library tambahan.
|
|
78
|
+
*/
|
|
79
|
+
class GatewayWsClient {
|
|
80
|
+
ws;
|
|
81
|
+
pending = new Map();
|
|
82
|
+
constructor(ws) {
|
|
83
|
+
this.ws = ws;
|
|
84
|
+
ws.addEventListener("message", (event) => this.handleMessage(event));
|
|
85
|
+
}
|
|
86
|
+
static async connect(url, token) {
|
|
87
|
+
const ws = new WebSocket(url);
|
|
88
|
+
await waitFor(ws, "open");
|
|
89
|
+
const client = new GatewayWsClient(ws);
|
|
90
|
+
await client.handshake(token);
|
|
91
|
+
return client;
|
|
92
|
+
}
|
|
93
|
+
close() {
|
|
94
|
+
this.ws.close();
|
|
95
|
+
}
|
|
96
|
+
/** RPC unary — resolve dengan `payload` dari frame `res`. */
|
|
97
|
+
async unary(method, params) {
|
|
98
|
+
const id = randomUUID();
|
|
99
|
+
return new Promise((resolve, reject) => {
|
|
100
|
+
this.pending.set(id, { resolve, reject });
|
|
101
|
+
this.send({ type: "req", id, method, params });
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/** RPC streaming — onEvent dipanggil per event antara; resolve di `res` final. */
|
|
105
|
+
async stream(method, params, onEvent) {
|
|
106
|
+
const id = randomUUID();
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
this.pending.set(id, { resolve, reject, onEvent });
|
|
109
|
+
this.send({ type: "req", id, method, params });
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
async handshake(token) {
|
|
113
|
+
const id = randomUUID();
|
|
114
|
+
const helloOk = (await new Promise((resolve, reject) => {
|
|
115
|
+
this.pending.set(id, { resolve, reject });
|
|
116
|
+
this.send({
|
|
117
|
+
type: "connect",
|
|
118
|
+
id,
|
|
119
|
+
params: {
|
|
120
|
+
protocol: 1,
|
|
121
|
+
auth: { token },
|
|
122
|
+
client: {
|
|
123
|
+
id: "natroc-cli",
|
|
124
|
+
mode: "cli",
|
|
125
|
+
version: "0.0.1",
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}));
|
|
130
|
+
if (helloOk?.auth?.ok !== true) {
|
|
131
|
+
throw new Error("Handshake rejected: token invalid or expired.");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
send(frame) {
|
|
135
|
+
this.ws.send(JSON.stringify(frame));
|
|
136
|
+
}
|
|
137
|
+
handleMessage(event) {
|
|
138
|
+
if (typeof event.data !== "string")
|
|
139
|
+
return;
|
|
140
|
+
let frame;
|
|
141
|
+
try {
|
|
142
|
+
frame = JSON.parse(event.data);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (frame.type === "res") {
|
|
148
|
+
const pending = this.pending.get(frame.id);
|
|
149
|
+
if (!pending)
|
|
150
|
+
return;
|
|
151
|
+
this.pending.delete(frame.id);
|
|
152
|
+
if (frame.ok) {
|
|
153
|
+
pending.resolve(frame.payload);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
pending.reject(new Error(`${frame.error?.code ?? "error"}: ${frame.error?.message ?? "Unknown gateway error"}`));
|
|
157
|
+
}
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (frame.type === "event" && frame.id) {
|
|
161
|
+
this.pending.get(frame.id)?.onEvent?.(frame.payload);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** Promise wrapper untuk event `open`/`error` pada WebSocket. */
|
|
166
|
+
function waitFor(ws, eventName) {
|
|
167
|
+
return new Promise((resolve, reject) => {
|
|
168
|
+
ws.addEventListener(eventName, () => resolve(), { once: true });
|
|
169
|
+
ws.addEventListener("error", (event) => reject(toError(event)), {
|
|
170
|
+
once: true,
|
|
171
|
+
});
|
|
172
|
+
ws.addEventListener("close", () => reject(new Error("Gateway WebSocket closed before handshake.")), { once: true });
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function toError(event) {
|
|
176
|
+
if (event instanceof Error)
|
|
177
|
+
return event;
|
|
178
|
+
const message = typeof event === "object" && event !== null && "message" in event
|
|
179
|
+
? String(event.message ?? "WebSocket error")
|
|
180
|
+
: "WebSocket error";
|
|
181
|
+
return new Error(message);
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=agent-deliver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-deliver.js","sourceRoot":"","sources":["../../src/cli/agent-deliver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ParsedCliArgs = {
|
|
2
|
+
command: "chat";
|
|
3
|
+
prompt: string;
|
|
4
|
+
flags: Record<string, string | boolean>;
|
|
5
|
+
} | {
|
|
6
|
+
command: string;
|
|
7
|
+
subcommand?: string;
|
|
8
|
+
args: string[];
|
|
9
|
+
flags: Record<string, string | boolean>;
|
|
10
|
+
};
|
|
11
|
+
export declare function parseCliArgs(argv: string[]): ParsedCliArgs;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export function parseCliArgs(argv) {
|
|
2
|
+
const [command = "help", maybeSubcommand, ...rest] = argv;
|
|
3
|
+
if (command === "chat") {
|
|
4
|
+
const { args, flags } = parsePositionalsAndFlags(argv.slice(1));
|
|
5
|
+
return {
|
|
6
|
+
command,
|
|
7
|
+
prompt: args.join(" "),
|
|
8
|
+
flags
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
if (isNestedCommand(command) &&
|
|
12
|
+
maybeSubcommand &&
|
|
13
|
+
!maybeSubcommand.startsWith("--")) {
|
|
14
|
+
const { args, flags } = parsePositionalsAndFlags(rest);
|
|
15
|
+
return {
|
|
16
|
+
command,
|
|
17
|
+
subcommand: maybeSubcommand,
|
|
18
|
+
args,
|
|
19
|
+
flags
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const { args, flags } = parsePositionalsAndFlags(argv.slice(1));
|
|
23
|
+
return {
|
|
24
|
+
command,
|
|
25
|
+
args,
|
|
26
|
+
flags
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function parsePositionalsAndFlags(argv) {
|
|
30
|
+
const args = [];
|
|
31
|
+
const flags = {};
|
|
32
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
33
|
+
const item = argv[index];
|
|
34
|
+
if (!item.startsWith("--")) {
|
|
35
|
+
args.push(item);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const flagName = toCamelCase(item.slice(2));
|
|
39
|
+
const next = argv[index + 1];
|
|
40
|
+
if (!next || next.startsWith("--")) {
|
|
41
|
+
flags[flagName] = true;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
flags[flagName] = next;
|
|
45
|
+
index += 1;
|
|
46
|
+
}
|
|
47
|
+
return { args, flags };
|
|
48
|
+
}
|
|
49
|
+
function isNestedCommand(command) {
|
|
50
|
+
return (command === "providers" ||
|
|
51
|
+
command === "proposals" ||
|
|
52
|
+
command === "daemon");
|
|
53
|
+
}
|
|
54
|
+
function toCamelCase(value) {
|
|
55
|
+
return value.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,MAAM,CAAC,OAAO,GAAG,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IAEzD,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QAE/D,OAAO;YACL,OAAO;YACP,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;YACtB,KAAK;SACN,CAAA;IACH,CAAC;IAED,IACE,eAAe,CAAC,OAAO,CAAC;QACxB,eAAe;QACf,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,EACjC,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAA;QAEtD,OAAO;YACL,OAAO;YACP,UAAU,EAAE,eAAe;YAC3B,IAAI;YACJ,KAAK;SACN,CAAA;IACH,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAE/D,OAAO;QACL,OAAO;QACP,IAAI;QACJ,KAAK;KACN,CAAA;AACH,CAAC;AAED,SAAS,wBAAwB,CAAC,IAAc;IAC9C,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,MAAM,KAAK,GAAqC,EAAE,CAAA;IAElD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QAExB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACf,SAAQ;QACV,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;QAE5B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAA;YACtB,SAAQ;QACV,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAA;QACtB,KAAK,IAAI,CAAC,CAAA;IACZ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AACxB,CAAC;AAED,SAAS,eAAe,CAAC,OAAe;IACtC,OAAO,CACL,OAAO,KAAK,WAAW;QACvB,OAAO,KAAK,WAAW;QACvB,OAAO,KAAK,QAAQ,CACrB,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;AAChF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runCliToken(): Promise<void>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sub-command `natroc cli-token` (Milestone 9 helper): membuat session token
|
|
3
|
+
* untuk dipakai CLI yang nyambung ke gateway daemon, lalu menulisnya ke
|
|
4
|
+
* `~/.natroc/cli-token` dengan mode 0600.
|
|
5
|
+
*/
|
|
6
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { createLocalRuntime } from "../local-runtime.js";
|
|
9
|
+
export async function runCliToken() {
|
|
10
|
+
const { paths, runtime } = await createLocalRuntime();
|
|
11
|
+
const userId = runtime.auth.getFirstUserId();
|
|
12
|
+
if (!userId) {
|
|
13
|
+
throw new Error("No registered user. Create an account via the web UI first.");
|
|
14
|
+
}
|
|
15
|
+
const session = runtime.auth.createSession(userId);
|
|
16
|
+
const filePath = join(paths.root, "cli-token");
|
|
17
|
+
await mkdir(paths.root, { recursive: true });
|
|
18
|
+
await writeFile(filePath, `${session.token}\n`, { mode: 0o600 });
|
|
19
|
+
console.log(`CLI token written: ${filePath}`);
|
|
20
|
+
console.log("Use `natroc agent --message ...` to call the running daemon.");
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=cli-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-token.js","sourceRoot":"","sources":["../../src/cli/cli-token.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAExD,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,kBAAkB,EAAE,CAAA;IACrD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,CAAA;IAE5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAA;IACH,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IAE9C,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5C,MAAM,SAAS,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAEhE,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAA;IAC7C,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAA;AAC7E,CAAC"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daemon lifecycle (Milestone 7): generate + install service file per OS,
|
|
3
|
+
* lalu serahkan ke supervisor sistem (systemd / launchd / schtasks) untuk
|
|
4
|
+
* jaga gateway tetap hidup di latar belakang.
|
|
5
|
+
*
|
|
6
|
+
* Sub-perintah:
|
|
7
|
+
* - `natroc daemon install` pasang service & start.
|
|
8
|
+
* - `natroc daemon uninstall` hentikan service & hapus file unit.
|
|
9
|
+
* - `natroc daemon status` cek status service.
|
|
10
|
+
* - `natroc daemon run` alias `natroc server` — dipanggil supervisor.
|
|
11
|
+
*/
|
|
12
|
+
import { execFile } from "node:child_process";
|
|
13
|
+
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
14
|
+
import { homedir, platform } from "node:os";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { promisify } from "node:util";
|
|
17
|
+
import { getNatrocPaths } from "../config/natroc-home.js";
|
|
18
|
+
/**
|
|
19
|
+
* Wrapper aman atas `execFile` (TANPA shell — argumen di-pass apa adanya).
|
|
20
|
+
* Tidak rentan injection karena tidak ada interpolasi shell.
|
|
21
|
+
*/
|
|
22
|
+
const runProcess = promisify(execFile);
|
|
23
|
+
const SERVICE_LABEL = "ai.natroc.gateway";
|
|
24
|
+
const SERVICE_DESCRIPTION = "Natroc gateway daemon";
|
|
25
|
+
function resolveDaemonPaths() {
|
|
26
|
+
const paths = getNatrocPaths();
|
|
27
|
+
return {
|
|
28
|
+
node: process.execPath,
|
|
29
|
+
cli: process.argv[1] ?? join(paths.root, "bin", "natroc"),
|
|
30
|
+
logDir: join(paths.root, "logs"),
|
|
31
|
+
servicesDir: join(paths.root, "services"),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Entrypoint sub-command `daemon`. */
|
|
35
|
+
export async function runDaemon(subcommand) {
|
|
36
|
+
const paths = resolveDaemonPaths();
|
|
37
|
+
await mkdir(paths.logDir, { recursive: true });
|
|
38
|
+
await mkdir(paths.servicesDir, { recursive: true });
|
|
39
|
+
switch (subcommand) {
|
|
40
|
+
case "install":
|
|
41
|
+
await installService(paths);
|
|
42
|
+
return;
|
|
43
|
+
case "uninstall":
|
|
44
|
+
await uninstallService();
|
|
45
|
+
return;
|
|
46
|
+
case "status":
|
|
47
|
+
await statusService();
|
|
48
|
+
return;
|
|
49
|
+
case "run":
|
|
50
|
+
// Alias `server` — biarkan caller (cli.ts) yang panggil startServer.
|
|
51
|
+
throw new Error("`daemon run` must be dispatched via cli.ts");
|
|
52
|
+
default:
|
|
53
|
+
printDaemonHelp();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function printDaemonHelp() {
|
|
57
|
+
console.log("Usage: natroc daemon <install|uninstall|status>");
|
|
58
|
+
console.log("");
|
|
59
|
+
console.log(" install Install + start the platform service");
|
|
60
|
+
console.log(" uninstall Stop + remove the platform service");
|
|
61
|
+
console.log(" status Show the current service status");
|
|
62
|
+
}
|
|
63
|
+
async function installService(paths) {
|
|
64
|
+
switch (platform()) {
|
|
65
|
+
case "linux":
|
|
66
|
+
await installSystemd(paths);
|
|
67
|
+
return;
|
|
68
|
+
case "darwin":
|
|
69
|
+
await installLaunchAgent(paths);
|
|
70
|
+
return;
|
|
71
|
+
case "win32":
|
|
72
|
+
await installScheduledTask(paths);
|
|
73
|
+
return;
|
|
74
|
+
default:
|
|
75
|
+
throw new Error(`Daemon mode is not supported on ${platform()}.`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function uninstallService() {
|
|
79
|
+
switch (platform()) {
|
|
80
|
+
case "linux":
|
|
81
|
+
await uninstallSystemd();
|
|
82
|
+
return;
|
|
83
|
+
case "darwin":
|
|
84
|
+
await uninstallLaunchAgent();
|
|
85
|
+
return;
|
|
86
|
+
case "win32":
|
|
87
|
+
await uninstallScheduledTask();
|
|
88
|
+
return;
|
|
89
|
+
default:
|
|
90
|
+
throw new Error(`Daemon mode is not supported on ${platform()}.`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function statusService() {
|
|
94
|
+
switch (platform()) {
|
|
95
|
+
case "linux":
|
|
96
|
+
await runAndPrint("systemctl", [
|
|
97
|
+
"--user",
|
|
98
|
+
"status",
|
|
99
|
+
"natroc.service",
|
|
100
|
+
"--no-pager",
|
|
101
|
+
]);
|
|
102
|
+
return;
|
|
103
|
+
case "darwin":
|
|
104
|
+
await runAndPrint("launchctl", ["list", SERVICE_LABEL]);
|
|
105
|
+
return;
|
|
106
|
+
case "win32":
|
|
107
|
+
await runAndPrint("schtasks", ["/Query", "/TN", "Natroc"]);
|
|
108
|
+
return;
|
|
109
|
+
default:
|
|
110
|
+
console.log(`Daemon mode is not supported on ${platform()}.`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// ---------- systemd (Linux/WSL) ----------
|
|
114
|
+
const SYSTEMD_UNIT_DIR = join(homedir(), ".config", "systemd", "user");
|
|
115
|
+
const SYSTEMD_UNIT_PATH = join(SYSTEMD_UNIT_DIR, "natroc.service");
|
|
116
|
+
async function installSystemd(paths) {
|
|
117
|
+
const unit = [
|
|
118
|
+
"[Unit]",
|
|
119
|
+
`Description=${SERVICE_DESCRIPTION}`,
|
|
120
|
+
"After=network.target",
|
|
121
|
+
"",
|
|
122
|
+
"[Service]",
|
|
123
|
+
"Type=simple",
|
|
124
|
+
`ExecStart=${paths.node} ${paths.cli} server`,
|
|
125
|
+
`StandardOutput=append:${join(paths.logDir, "natroc.log")}`,
|
|
126
|
+
`StandardError=append:${join(paths.logDir, "natroc.err.log")}`,
|
|
127
|
+
"Restart=on-failure",
|
|
128
|
+
"RestartSec=5",
|
|
129
|
+
"",
|
|
130
|
+
"[Install]",
|
|
131
|
+
"WantedBy=default.target",
|
|
132
|
+
"",
|
|
133
|
+
].join("\n");
|
|
134
|
+
await mkdir(SYSTEMD_UNIT_DIR, { recursive: true });
|
|
135
|
+
await writeFile(SYSTEMD_UNIT_PATH, unit, { mode: 0o644 });
|
|
136
|
+
await runProcess("systemctl", ["--user", "daemon-reload"]);
|
|
137
|
+
await runProcess("systemctl", [
|
|
138
|
+
"--user",
|
|
139
|
+
"enable",
|
|
140
|
+
"--now",
|
|
141
|
+
"natroc.service",
|
|
142
|
+
]);
|
|
143
|
+
console.log(`Installed: ${SYSTEMD_UNIT_PATH}`);
|
|
144
|
+
console.log("Run `systemctl --user status natroc.service` to inspect.");
|
|
145
|
+
}
|
|
146
|
+
async function uninstallSystemd() {
|
|
147
|
+
await runProcess("systemctl", [
|
|
148
|
+
"--user",
|
|
149
|
+
"disable",
|
|
150
|
+
"--now",
|
|
151
|
+
"natroc.service",
|
|
152
|
+
]).catch(() => undefined);
|
|
153
|
+
await rm(SYSTEMD_UNIT_PATH, { force: true });
|
|
154
|
+
await runProcess("systemctl", ["--user", "daemon-reload"]).catch(() => undefined);
|
|
155
|
+
console.log(`Removed: ${SYSTEMD_UNIT_PATH}`);
|
|
156
|
+
}
|
|
157
|
+
// ---------- launchd (macOS) ----------
|
|
158
|
+
const LAUNCH_AGENTS_DIR = join(homedir(), "Library", "LaunchAgents");
|
|
159
|
+
const LAUNCH_AGENT_PATH = join(LAUNCH_AGENTS_DIR, `${SERVICE_LABEL}.plist`);
|
|
160
|
+
async function installLaunchAgent(paths) {
|
|
161
|
+
const plist = [
|
|
162
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
163
|
+
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" ' +
|
|
164
|
+
'"http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
165
|
+
'<plist version="1.0">',
|
|
166
|
+
"<dict>",
|
|
167
|
+
" <key>Label</key>",
|
|
168
|
+
` <string>${SERVICE_LABEL}</string>`,
|
|
169
|
+
" <key>ProgramArguments</key>",
|
|
170
|
+
" <array>",
|
|
171
|
+
` <string>${paths.node}</string>`,
|
|
172
|
+
` <string>${paths.cli}</string>`,
|
|
173
|
+
" <string>server</string>",
|
|
174
|
+
" </array>",
|
|
175
|
+
" <key>RunAtLoad</key>",
|
|
176
|
+
" <true/>",
|
|
177
|
+
" <key>KeepAlive</key>",
|
|
178
|
+
" <true/>",
|
|
179
|
+
" <key>StandardOutPath</key>",
|
|
180
|
+
` <string>${join(paths.logDir, "natroc.log")}</string>`,
|
|
181
|
+
" <key>StandardErrorPath</key>",
|
|
182
|
+
` <string>${join(paths.logDir, "natroc.err.log")}</string>`,
|
|
183
|
+
"</dict>",
|
|
184
|
+
"</plist>",
|
|
185
|
+
"",
|
|
186
|
+
].join("\n");
|
|
187
|
+
await mkdir(LAUNCH_AGENTS_DIR, { recursive: true });
|
|
188
|
+
await writeFile(LAUNCH_AGENT_PATH, plist, { mode: 0o644 });
|
|
189
|
+
const uid = process.getuid?.() ?? 0;
|
|
190
|
+
try {
|
|
191
|
+
await runProcess("launchctl", [
|
|
192
|
+
"bootstrap",
|
|
193
|
+
`gui/${uid}`,
|
|
194
|
+
LAUNCH_AGENT_PATH,
|
|
195
|
+
]);
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
// Fallback ke perintah lama untuk macOS pre-Catalina.
|
|
199
|
+
console.warn(`launchctl bootstrap failed (${error instanceof Error ? error.message : "unknown"}); falling back to legacy load.`);
|
|
200
|
+
await runProcess("launchctl", ["load", "-w", LAUNCH_AGENT_PATH]);
|
|
201
|
+
}
|
|
202
|
+
console.log(`Installed: ${LAUNCH_AGENT_PATH}`);
|
|
203
|
+
}
|
|
204
|
+
async function uninstallLaunchAgent() {
|
|
205
|
+
const uid = process.getuid?.() ?? 0;
|
|
206
|
+
await runProcess("launchctl", [
|
|
207
|
+
"bootout",
|
|
208
|
+
`gui/${uid}/${SERVICE_LABEL}`,
|
|
209
|
+
]).catch(() => undefined);
|
|
210
|
+
await runProcess("launchctl", ["unload", LAUNCH_AGENT_PATH]).catch(() => undefined);
|
|
211
|
+
await rm(LAUNCH_AGENT_PATH, { force: true });
|
|
212
|
+
console.log(`Removed: ${LAUNCH_AGENT_PATH}`);
|
|
213
|
+
}
|
|
214
|
+
// ---------- Task Scheduler (Windows) ----------
|
|
215
|
+
async function installScheduledTask(paths) {
|
|
216
|
+
const tr = `"${paths.node}" "${paths.cli}" server`;
|
|
217
|
+
await runProcess("schtasks", [
|
|
218
|
+
"/Create",
|
|
219
|
+
"/F",
|
|
220
|
+
"/TN",
|
|
221
|
+
"Natroc",
|
|
222
|
+
"/TR",
|
|
223
|
+
tr,
|
|
224
|
+
"/SC",
|
|
225
|
+
"ONLOGON",
|
|
226
|
+
"/RL",
|
|
227
|
+
"HIGHEST",
|
|
228
|
+
]);
|
|
229
|
+
await runProcess("schtasks", ["/Run", "/TN", "Natroc"]).catch(() => undefined);
|
|
230
|
+
console.log("Installed Windows scheduled task: Natroc");
|
|
231
|
+
}
|
|
232
|
+
async function uninstallScheduledTask() {
|
|
233
|
+
await runProcess("schtasks", ["/End", "/TN", "Natroc"]).catch(() => undefined);
|
|
234
|
+
await runProcess("schtasks", ["/Delete", "/F", "/TN", "Natroc"]).catch(() => undefined);
|
|
235
|
+
console.log("Removed Windows scheduled task: Natroc");
|
|
236
|
+
}
|
|
237
|
+
async function runAndPrint(command, args) {
|
|
238
|
+
try {
|
|
239
|
+
const { stdout, stderr } = await runProcess(command, args);
|
|
240
|
+
if (stdout)
|
|
241
|
+
process.stdout.write(stdout);
|
|
242
|
+
if (stderr)
|
|
243
|
+
process.stderr.write(stderr);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
247
|
+
console.error(`Failed: ${command} ${args.join(" ")}`);
|
|
248
|
+
console.error(message);
|
|
249
|
+
process.exitCode = 1;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"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"}
|