clankie 0.2.11 → 0.2.12
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/dist/cli.js +77 -48
- package/package.json +1 -1
- package/web-ui-dist/_shell.html +1 -1
package/dist/cli.js
CHANGED
|
@@ -203502,7 +203502,7 @@ var require_src6 = __commonJS((exports2) => {
|
|
|
203502
203502
|
// src/cli.ts
|
|
203503
203503
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
203504
203504
|
import { readFileSync as readFileSync26 } from "node:fs";
|
|
203505
|
-
import { join as
|
|
203505
|
+
import { join as join34 } from "node:path";
|
|
203506
203506
|
import * as readline3 from "node:readline/promises";
|
|
203507
203507
|
|
|
203508
203508
|
// node_modules/@mariozechner/pi-coding-agent/dist/index.js
|
|
@@ -297043,6 +297043,9 @@ class ThinkingSelectorComponent extends Container {
|
|
|
297043
297043
|
// src/cli.ts
|
|
297044
297044
|
var import_json52 = __toESM(require_lib5(), 1);
|
|
297045
297045
|
|
|
297046
|
+
// src/agent.ts
|
|
297047
|
+
import { join as join28 } from "node:path";
|
|
297048
|
+
|
|
297046
297049
|
// src/config.ts
|
|
297047
297050
|
var import_json5 = __toESM(require_lib5(), 1);
|
|
297048
297051
|
import { chmodSync as chmodSync3, existsSync as existsSync23, mkdirSync as mkdirSync9, readFileSync as readFileSync21, writeFileSync as writeFileSync10 } from "node:fs";
|
|
@@ -297275,7 +297278,9 @@ async function createSession(options2 = {}) {
|
|
|
297275
297278
|
const extensionFactories = [];
|
|
297276
297279
|
const restrictToWorkspace = config.agent?.restrictToWorkspace ?? true;
|
|
297277
297280
|
if (restrictToWorkspace) {
|
|
297278
|
-
const
|
|
297281
|
+
const configuredAllowedPaths = config.agent?.allowedPaths ?? [];
|
|
297282
|
+
const attachmentRoot = join28(getAppDir(), "attachments");
|
|
297283
|
+
const allowedPaths = Array.from(new Set([...configuredAllowedPaths, attachmentRoot]));
|
|
297279
297284
|
extensionFactories.push(createWorkspaceJailExtension(cwd, allowedPaths));
|
|
297280
297285
|
}
|
|
297281
297286
|
const loader = new DefaultResourceLoader({
|
|
@@ -297367,16 +297372,16 @@ function buildApiKeyProviders(oauthIds, dynamicProviderIds) {
|
|
|
297367
297372
|
|
|
297368
297373
|
// src/daemon.ts
|
|
297369
297374
|
import { existsSync as existsSync28, readFileSync as readFileSync24, unlinkSync as unlinkSync3, watch as watch3, writeFileSync as writeFileSync12 } from "node:fs";
|
|
297370
|
-
import { join as
|
|
297375
|
+
import { join as join32 } from "node:path";
|
|
297371
297376
|
|
|
297372
297377
|
// src/channels/slack.ts
|
|
297373
297378
|
var import_socket_mode = __toESM(require_src6(), 1);
|
|
297374
297379
|
var import_web_api = __toESM(require_dist18(), 1);
|
|
297375
297380
|
import { existsSync as existsSync25, mkdirSync as mkdirSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync11 } from "node:fs";
|
|
297376
297381
|
import { homedir as homedir14 } from "node:os";
|
|
297377
|
-
import { join as
|
|
297382
|
+
import { join as join29 } from "node:path";
|
|
297378
297383
|
var SLACK_MAX_LENGTH = 4000;
|
|
297379
|
-
var ACTIVE_THREADS_FILE =
|
|
297384
|
+
var ACTIVE_THREADS_FILE = join29(homedir14(), ".clankie", "slack-active-threads.json");
|
|
297380
297385
|
var THREAD_TTL_DAYS = 7;
|
|
297381
297386
|
|
|
297382
297387
|
class SlackChannel {
|
|
@@ -297464,7 +297469,7 @@ class SlackChannel {
|
|
|
297464
297469
|
}
|
|
297465
297470
|
saveActiveThreads() {
|
|
297466
297471
|
try {
|
|
297467
|
-
const dir =
|
|
297472
|
+
const dir = join29(homedir14(), ".clankie");
|
|
297468
297473
|
if (!existsSync25(dir)) {
|
|
297469
297474
|
mkdirSync10(dir, { recursive: true, mode: 448 });
|
|
297470
297475
|
}
|
|
@@ -297607,7 +297612,7 @@ class SlackChannel {
|
|
|
297607
297612
|
// src/channels/web.ts
|
|
297608
297613
|
import * as crypto5 from "node:crypto";
|
|
297609
297614
|
import { existsSync as existsSync27, readdirSync as readdirSync11, readFileSync as readFileSync23, statSync as statSync12 } from "node:fs";
|
|
297610
|
-
import { join as
|
|
297615
|
+
import { join as join31, resolve as resolve11 } from "node:path";
|
|
297611
297616
|
|
|
297612
297617
|
// node_modules/@hono/node-server/dist/index.mjs
|
|
297613
297618
|
import { createServer as createServerHTTP } from "http";
|
|
@@ -299868,7 +299873,7 @@ var Hono2 = class extends Hono {
|
|
|
299868
299873
|
|
|
299869
299874
|
// src/sessions.ts
|
|
299870
299875
|
import { existsSync as existsSync26, mkdirSync as mkdirSync11 } from "node:fs";
|
|
299871
|
-
import { join as
|
|
299876
|
+
import { join as join30 } from "node:path";
|
|
299872
299877
|
var sessionCache = new Map;
|
|
299873
299878
|
var activeSessionNames = new Map;
|
|
299874
299879
|
var chatLocks = new Map;
|
|
@@ -299887,7 +299892,9 @@ async function getOrCreateSession(chatKey, config) {
|
|
|
299887
299892
|
const extensionFactories = [];
|
|
299888
299893
|
const restrictToWorkspace = config.agent?.restrictToWorkspace ?? true;
|
|
299889
299894
|
if (restrictToWorkspace) {
|
|
299890
|
-
const
|
|
299895
|
+
const configuredAllowedPaths = config.agent?.allowedPaths ?? [];
|
|
299896
|
+
const attachmentRoot = join30(getAppDir(), "attachments");
|
|
299897
|
+
const allowedPaths = Array.from(new Set([...configuredAllowedPaths, attachmentRoot]));
|
|
299891
299898
|
extensionFactories.push(createWorkspaceJailExtension(cwd, allowedPaths));
|
|
299892
299899
|
}
|
|
299893
299900
|
const loader = new DefaultResourceLoader({
|
|
@@ -299896,7 +299903,7 @@ async function getOrCreateSession(chatKey, config) {
|
|
|
299896
299903
|
extensionFactories
|
|
299897
299904
|
});
|
|
299898
299905
|
await loader.reload();
|
|
299899
|
-
const sessionDir =
|
|
299906
|
+
const sessionDir = join30(getAppDir(), "sessions", chatKey);
|
|
299900
299907
|
if (!existsSync26(sessionDir)) {
|
|
299901
299908
|
mkdirSync11(sessionDir, { recursive: true });
|
|
299902
299909
|
}
|
|
@@ -299968,7 +299975,7 @@ async function getOrCreateSession(chatKey, config) {
|
|
|
299968
299975
|
return session;
|
|
299969
299976
|
}
|
|
299970
299977
|
function listSessionNames(chatIdentifier) {
|
|
299971
|
-
const sessionsDir =
|
|
299978
|
+
const sessionsDir = join30(getAppDir(), "sessions");
|
|
299972
299979
|
if (!existsSync26(sessionsDir)) {
|
|
299973
299980
|
return [];
|
|
299974
299981
|
}
|
|
@@ -299978,7 +299985,7 @@ function listSessionNames(chatIdentifier) {
|
|
|
299978
299985
|
const sessionNames = new Set;
|
|
299979
299986
|
for (const entry of entries) {
|
|
299980
299987
|
if (entry.startsWith(`${chatIdentifier}_`)) {
|
|
299981
|
-
const entryPath =
|
|
299988
|
+
const entryPath = join30(sessionsDir, entry);
|
|
299982
299989
|
if (statSync12(entryPath).isDirectory()) {
|
|
299983
299990
|
const sessionName = entry.substring(chatIdentifier.length + 1);
|
|
299984
299991
|
if (sessionName) {
|
|
@@ -300012,13 +300019,13 @@ async function saveNonImageAttachments(attachments, chatKey) {
|
|
|
300012
300019
|
if (nonImages.length === 0)
|
|
300013
300020
|
return [];
|
|
300014
300021
|
const { mkdirSync: mkdirSync12, writeFileSync: writeFileSync12 } = await import("node:fs");
|
|
300015
|
-
const { join:
|
|
300016
|
-
const dir =
|
|
300022
|
+
const { join: join31 } = await import("node:path");
|
|
300023
|
+
const dir = join31(getAppDir(), "attachments", chatKey);
|
|
300017
300024
|
mkdirSync12(dir, { recursive: true });
|
|
300018
300025
|
const results = [];
|
|
300019
300026
|
for (const att of nonImages) {
|
|
300020
300027
|
const name = att.fileName || `file_${Date.now()}`;
|
|
300021
|
-
const filePath =
|
|
300028
|
+
const filePath = join31(dir, name);
|
|
300022
300029
|
writeFileSync12(filePath, Buffer.from(att.data, "base64"));
|
|
300023
300030
|
results.push({ fileName: name, path: filePath });
|
|
300024
300031
|
console.log(`[session] Saved attachment: ${filePath} (${att.mimeType})`);
|
|
@@ -300119,7 +300126,7 @@ class WebChannel {
|
|
|
300119
300126
|
if (pathname === "" || pathname === "/") {
|
|
300120
300127
|
pathname = "_shell.html";
|
|
300121
300128
|
}
|
|
300122
|
-
const _filePath =
|
|
300129
|
+
const _filePath = join31(this.options.staticDir, pathname);
|
|
300123
300130
|
const resolvedPath = resolve11(this.options.staticDir, pathname);
|
|
300124
300131
|
if (!resolvedPath.startsWith(resolve11(this.options.staticDir))) {
|
|
300125
300132
|
return c.text("Forbidden", 403);
|
|
@@ -300152,7 +300159,7 @@ class WebChannel {
|
|
|
300152
300159
|
}
|
|
300153
300160
|
});
|
|
300154
300161
|
}
|
|
300155
|
-
const shellPath =
|
|
300162
|
+
const shellPath = join31(this.options.staticDir, "_shell.html");
|
|
300156
300163
|
if (existsSync27(shellPath)) {
|
|
300157
300164
|
const content = readFileSync23(shellPath);
|
|
300158
300165
|
return new Response(content, {
|
|
@@ -300290,12 +300297,34 @@ class WebChannel {
|
|
|
300290
300297
|
this.sendError(ws2, inbound.sessionId, command.type, err instanceof Error ? err.message : String(err), commandId);
|
|
300291
300298
|
}
|
|
300292
300299
|
}
|
|
300300
|
+
injectAttachmentPaths(sessionId, message) {
|
|
300301
|
+
const attachmentNames = Array.from(message.matchAll(/\[Attached:\s*([^\]]+)\]/g)).map((match3) => match3[1]?.trim()).filter((name) => Boolean(name));
|
|
300302
|
+
if (attachmentNames.length === 0)
|
|
300303
|
+
return message;
|
|
300304
|
+
const attachmentDir = join31(getAppDir(), "attachments", sessionId);
|
|
300305
|
+
const resolved = [];
|
|
300306
|
+
for (const name of attachmentNames) {
|
|
300307
|
+
const path14 = join31(attachmentDir, name);
|
|
300308
|
+
if (existsSync27(path14)) {
|
|
300309
|
+
resolved.push(` - ${name}: ${path14}`);
|
|
300310
|
+
}
|
|
300311
|
+
}
|
|
300312
|
+
if (resolved.length === 0)
|
|
300313
|
+
return message;
|
|
300314
|
+
const suffix = `
|
|
300315
|
+
|
|
300316
|
+
[Attached files saved to disk]
|
|
300317
|
+
${resolved.join(`
|
|
300318
|
+
`)}`;
|
|
300319
|
+
return `${message}${suffix}`;
|
|
300320
|
+
}
|
|
300293
300321
|
async executeCommand(sessionId, session, command) {
|
|
300294
300322
|
const id = command.id;
|
|
300295
300323
|
switch (command.type) {
|
|
300296
300324
|
case "prompt": {
|
|
300297
300325
|
console.log(`[web] Executing prompt - session.sessionId: ${session.sessionId}, sessionFile: ${session.sessionFile}`);
|
|
300298
|
-
|
|
300326
|
+
const promptWithAttachmentPaths = this.injectAttachmentPaths(sessionId, command.message);
|
|
300327
|
+
session.prompt(promptWithAttachmentPaths, {
|
|
300299
300328
|
images: command.images,
|
|
300300
300329
|
streamingBehavior: command.streamingBehavior,
|
|
300301
300330
|
source: "rpc"
|
|
@@ -300320,13 +300349,13 @@ class WebChannel {
|
|
|
300320
300349
|
case "upload_attachment": {
|
|
300321
300350
|
const { fileName, data, mimeType } = command;
|
|
300322
300351
|
const { mkdirSync: mkdirSync12, writeFileSync: writeFileSync12 } = await import("node:fs");
|
|
300323
|
-
const { join:
|
|
300324
|
-
const dir =
|
|
300352
|
+
const { join: join32 } = await import("node:path");
|
|
300353
|
+
const dir = join32(getAppDir(), "attachments", sessionId);
|
|
300325
300354
|
mkdirSync12(dir, { recursive: true });
|
|
300326
300355
|
const timestamp = Date.now();
|
|
300327
300356
|
const sanitizedName = fileName.replace(/[^a-zA-Z0-9.-]/g, "_");
|
|
300328
300357
|
const uniqueFileName = `${timestamp}_${sanitizedName}`;
|
|
300329
|
-
const filePath =
|
|
300358
|
+
const filePath = join32(dir, uniqueFileName);
|
|
300330
300359
|
writeFileSync12(filePath, Buffer.from(data, "base64"));
|
|
300331
300360
|
console.log(`[web] Saved attachment: ${filePath} (${mimeType})`);
|
|
300332
300361
|
return {
|
|
@@ -300860,8 +300889,8 @@ class WebChannel {
|
|
|
300860
300889
|
try {
|
|
300861
300890
|
const files = readdirSync11(sessionPath).filter((f3) => f3.endsWith(".jsonl")).map((f3) => ({
|
|
300862
300891
|
name: f3,
|
|
300863
|
-
path:
|
|
300864
|
-
mtime: statSync12(
|
|
300892
|
+
path: join31(sessionPath, f3),
|
|
300893
|
+
mtime: statSync12(join31(sessionPath, f3)).mtime.getTime()
|
|
300865
300894
|
})).sort((a, b) => b.mtime - a.mtime);
|
|
300866
300895
|
if (files.length === 0)
|
|
300867
300896
|
return;
|
|
@@ -300888,13 +300917,13 @@ class WebChannel {
|
|
|
300888
300917
|
}
|
|
300889
300918
|
async listAllSessions() {
|
|
300890
300919
|
const sessions = [];
|
|
300891
|
-
const sessionsDir =
|
|
300920
|
+
const sessionsDir = join31(getAppDir(), "sessions");
|
|
300892
300921
|
if (!existsSync27(sessionsDir)) {
|
|
300893
300922
|
return sessions;
|
|
300894
300923
|
}
|
|
300895
300924
|
try {
|
|
300896
300925
|
const dirs = readdirSync11(sessionsDir);
|
|
300897
|
-
const webSessions = dirs.filter((dir) => dir.startsWith("web_")).map((dir) => ({ sessionId: dir, path:
|
|
300926
|
+
const webSessions = dirs.filter((dir) => dir.startsWith("web_")).map((dir) => ({ sessionId: dir, path: join31(sessionsDir, dir) })).filter(({ path: path14 }) => {
|
|
300898
300927
|
try {
|
|
300899
300928
|
return statSync12(path14).isDirectory();
|
|
300900
300929
|
} catch {
|
|
@@ -300965,7 +300994,7 @@ class WebChannel {
|
|
|
300965
300994
|
}
|
|
300966
300995
|
|
|
300967
300996
|
// src/daemon.ts
|
|
300968
|
-
var PID_FILE =
|
|
300997
|
+
var PID_FILE = join32(getAppDir(), "daemon.pid");
|
|
300969
300998
|
function isRunning() {
|
|
300970
300999
|
if (!existsSync28(PID_FILE))
|
|
300971
301000
|
return { running: false };
|
|
@@ -301223,23 +301252,23 @@ async function restartDaemon() {
|
|
|
301223
301252
|
import { execSync as execSync3 } from "node:child_process";
|
|
301224
301253
|
import { existsSync as existsSync29, mkdirSync as mkdirSync12, readFileSync as readFileSync25, unlinkSync as unlinkSync4, writeFileSync as writeFileSync13 } from "node:fs";
|
|
301225
301254
|
import { homedir as homedir15, platform as platform3 } from "node:os";
|
|
301226
|
-
import { dirname as dirname16, join as
|
|
301255
|
+
import { dirname as dirname16, join as join33 } from "node:path";
|
|
301227
301256
|
var SERVICE_NAME = "clankie";
|
|
301228
301257
|
var LAUNCHD_LABEL = "ai.clankie.daemon";
|
|
301229
301258
|
function resolveProgramArguments() {
|
|
301230
301259
|
const runtime = process.execPath || process.argv[0];
|
|
301231
301260
|
const thisFile = import.meta.filename;
|
|
301232
|
-
const cliEntry = thisFile.endsWith("service.ts") ?
|
|
301261
|
+
const cliEntry = thisFile.endsWith("service.ts") ? join33(dirname16(thisFile), "cli.ts") : join33(dirname16(thisFile), "cli.js");
|
|
301233
301262
|
return [runtime, cliEntry, "start", "--foreground"];
|
|
301234
301263
|
}
|
|
301235
301264
|
function systemdUnitPath() {
|
|
301236
|
-
return
|
|
301265
|
+
return join33(homedir15(), ".config", "systemd", "user", `${SERVICE_NAME}.service`);
|
|
301237
301266
|
}
|
|
301238
301267
|
function buildSystemdUnit() {
|
|
301239
301268
|
const args = resolveProgramArguments();
|
|
301240
301269
|
const execStart = args.map(systemdEscapeArg).join(" ");
|
|
301241
|
-
const workspace =
|
|
301242
|
-
const logDir =
|
|
301270
|
+
const workspace = join33(getAppDir(), "workspace");
|
|
301271
|
+
const logDir = join33(getAppDir(), "logs");
|
|
301243
301272
|
return [
|
|
301244
301273
|
"[Unit]",
|
|
301245
301274
|
`Description=clankie — personal AI assistant daemon`,
|
|
@@ -301254,8 +301283,8 @@ function buildSystemdUnit() {
|
|
|
301254
301283
|
"KillMode=process",
|
|
301255
301284
|
`Environment=HOME=${homedir15()}`,
|
|
301256
301285
|
`Environment=PATH=${process.env.PATH}`,
|
|
301257
|
-
`StandardOutput=append:${
|
|
301258
|
-
`StandardError=append:${
|
|
301286
|
+
`StandardOutput=append:${join33(logDir, "daemon.log")}`,
|
|
301287
|
+
`StandardError=append:${join33(logDir, "daemon.log")}`,
|
|
301259
301288
|
"",
|
|
301260
301289
|
"[Install]",
|
|
301261
301290
|
"WantedBy=default.target",
|
|
@@ -301287,8 +301316,8 @@ async function installSystemd() {
|
|
|
301287
301316
|
}
|
|
301288
301317
|
}
|
|
301289
301318
|
const unitPath = systemdUnitPath();
|
|
301290
|
-
const logDir =
|
|
301291
|
-
const workspace =
|
|
301319
|
+
const logDir = join33(getAppDir(), "logs");
|
|
301320
|
+
const workspace = join33(getAppDir(), "workspace");
|
|
301292
301321
|
mkdirSync12(dirname16(unitPath), { recursive: true });
|
|
301293
301322
|
mkdirSync12(logDir, { recursive: true });
|
|
301294
301323
|
mkdirSync12(workspace, { recursive: true });
|
|
@@ -301317,7 +301346,7 @@ async function installSystemd() {
|
|
|
301317
301346
|
console.log(`
|
|
301318
301347
|
✓ Installed and started systemd service: ${SERVICE_NAME}.service`);
|
|
301319
301348
|
console.log(` Logs: journalctl --user -u ${SERVICE_NAME} -f`);
|
|
301320
|
-
console.log(` Or: ${
|
|
301349
|
+
console.log(` Or: ${join33(logDir, "daemon.log")}`);
|
|
301321
301350
|
}
|
|
301322
301351
|
async function uninstallSystemd() {
|
|
301323
301352
|
const unitPath = systemdUnitPath();
|
|
@@ -301332,7 +301361,7 @@ async function uninstallSystemd() {
|
|
|
301332
301361
|
console.log(`✓ Uninstalled systemd service.`);
|
|
301333
301362
|
}
|
|
301334
301363
|
function logsSystemd() {
|
|
301335
|
-
const logFile =
|
|
301364
|
+
const logFile = join33(getAppDir(), "logs", "daemon.log");
|
|
301336
301365
|
console.log(`Log file: ${logFile}
|
|
301337
301366
|
`);
|
|
301338
301367
|
const result = execSafe(`journalctl --user -u ${SERVICE_NAME} --no-pager -n 50`);
|
|
@@ -301354,15 +301383,15 @@ function statusSystemd() {
|
|
|
301354
301383
|
console.log(result.stdout || result.stderr || "Service not found.");
|
|
301355
301384
|
}
|
|
301356
301385
|
function launchdPlistPath() {
|
|
301357
|
-
return
|
|
301386
|
+
return join33(homedir15(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
|
|
301358
301387
|
}
|
|
301359
301388
|
function plistEscape(value2) {
|
|
301360
301389
|
return value2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
301361
301390
|
}
|
|
301362
301391
|
function buildLaunchdPlist() {
|
|
301363
301392
|
const args = resolveProgramArguments();
|
|
301364
|
-
const logDir =
|
|
301365
|
-
const workspace =
|
|
301393
|
+
const logDir = join33(getAppDir(), "logs");
|
|
301394
|
+
const workspace = join33(getAppDir(), "workspace");
|
|
301366
301395
|
const argsXml = args.map((a) => ` <string>${plistEscape(a)}</string>`).join(`
|
|
301367
301396
|
`);
|
|
301368
301397
|
const envVars = {};
|
|
@@ -301390,9 +301419,9 @@ ${argsXml}
|
|
|
301390
301419
|
<key>WorkingDirectory</key>
|
|
301391
301420
|
<string>${plistEscape(workspace)}</string>
|
|
301392
301421
|
<key>StandardOutPath</key>
|
|
301393
|
-
<string>${plistEscape(
|
|
301422
|
+
<string>${plistEscape(join33(logDir, "daemon.log"))}</string>
|
|
301394
301423
|
<key>StandardErrorPath</key>
|
|
301395
|
-
<string>${plistEscape(
|
|
301424
|
+
<string>${plistEscape(join33(logDir, "daemon.log"))}</string>
|
|
301396
301425
|
<key>EnvironmentVariables</key>
|
|
301397
301426
|
<dict>
|
|
301398
301427
|
${envXml}
|
|
@@ -301403,8 +301432,8 @@ ${envXml}
|
|
|
301403
301432
|
}
|
|
301404
301433
|
async function installLaunchd() {
|
|
301405
301434
|
const plistPath = launchdPlistPath();
|
|
301406
|
-
const logDir =
|
|
301407
|
-
const workspace =
|
|
301435
|
+
const logDir = join33(getAppDir(), "logs");
|
|
301436
|
+
const workspace = join33(getAppDir(), "workspace");
|
|
301408
301437
|
mkdirSync12(dirname16(plistPath), { recursive: true });
|
|
301409
301438
|
mkdirSync12(logDir, { recursive: true });
|
|
301410
301439
|
mkdirSync12(workspace, { recursive: true });
|
|
@@ -301421,7 +301450,7 @@ async function installLaunchd() {
|
|
|
301421
301450
|
}
|
|
301422
301451
|
console.log(`
|
|
301423
301452
|
✓ Installed and started launchd agent: ${LAUNCHD_LABEL}`);
|
|
301424
|
-
console.log(` Logs: tail -f ${
|
|
301453
|
+
console.log(` Logs: tail -f ${join33(logDir, "daemon.log")}`);
|
|
301425
301454
|
}
|
|
301426
301455
|
async function uninstallLaunchd() {
|
|
301427
301456
|
const plistPath = launchdPlistPath();
|
|
@@ -301435,7 +301464,7 @@ async function uninstallLaunchd() {
|
|
|
301435
301464
|
console.log(`✓ Uninstalled launchd agent.`);
|
|
301436
301465
|
}
|
|
301437
301466
|
function logsLaunchd() {
|
|
301438
|
-
const logFile =
|
|
301467
|
+
const logFile = join33(getAppDir(), "logs", "daemon.log");
|
|
301439
301468
|
console.log(`Log file: ${logFile}
|
|
301440
301469
|
`);
|
|
301441
301470
|
if (existsSync29(logFile)) {
|
|
@@ -301493,7 +301522,7 @@ function showServiceLogs() {
|
|
|
301493
301522
|
} else if (isLinux) {
|
|
301494
301523
|
logsSystemd();
|
|
301495
301524
|
} else {
|
|
301496
|
-
const logFile =
|
|
301525
|
+
const logFile = join33(getAppDir(), "logs", "daemon.log");
|
|
301497
301526
|
if (existsSync29(logFile)) {
|
|
301498
301527
|
console.log(readFileSync25(logFile, "utf-8"));
|
|
301499
301528
|
} else {
|
|
@@ -301583,7 +301612,7 @@ Credentials are stored at ~/.clankie/auth.json (separate from pi's auth).
|
|
|
301583
301612
|
`);
|
|
301584
301613
|
}
|
|
301585
301614
|
function printVersion() {
|
|
301586
|
-
const packagePath =
|
|
301615
|
+
const packagePath = join34(import.meta.dirname, "..", "package.json");
|
|
301587
301616
|
try {
|
|
301588
301617
|
const pkg3 = JSON.parse(readFileSync26(packagePath, "utf-8"));
|
|
301589
301618
|
console.log(`clankie ${pkg3.version}`);
|
package/package.json
CHANGED
package/web-ui-dist/_shell.html
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
<!DOCTYPE html><html lang="en" class="dark"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>clankie — Personal AI Assistant</title><link rel="modulepreload" href="/assets/main-UkFzTTck.js"/><link rel="modulepreload" href="/assets/index-CdxpJyJ4.js"/><link rel="icon" type="image/svg+xml" href="/favicon.svg"/><link rel="stylesheet" href="/assets/styles-DAZ1IN1z.css"/></head><body><div data-slot="sidebar-wrapper" style="--sidebar-width:16rem;--sidebar-width-icon:3rem" class="group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full"><div class="group peer text-sidebar-foreground hidden md:block" data-state="expanded" data-collapsible="" data-variant="inset" data-side="left" data-slot="sidebar"><div data-slot="sidebar-gap" class="transition-[width] duration-200 ease-linear relative w-(--sidebar-width) bg-transparent group-data-[collapsible=offcanvas]:w-0 group-data-[side=right]:rotate-180 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"></div><div data-slot="sidebar-container" data-side="left" class="fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"><div data-sidebar="sidebar" data-slot="sidebar-inner" class="bg-sidebar group-data-[variant=floating]:ring-sidebar-border group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 flex size-full flex-col"><div data-slot="sidebar-header" data-sidebar="header" class="gap-2 p-2 flex flex-col"><ul data-slot="sidebar-menu" data-sidebar="menu" class="gap-0 flex w-full min-w-0 flex-col"><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><a data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="lg" class="ring-sidebar-ring active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-md p-2 text-left transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! focus-visible:ring-2 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-12 text-sm group-data-[collapsible=icon]:p-0! active" href="/" data-status="active" aria-current="page"><div class="flex items-center gap-2"><div class="flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 border border-primary/20"><span class="text-sm font-mono font-bold text-primary">c/</span></div><span class="text-base font-mono font-semibold tracking-tight">clankie</span></div></a></li></ul></div><div data-slot="sidebar-content" data-sidebar="content" class="no-scrollbar gap-0 flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden"><div data-slot="sidebar-group" data-sidebar="group" class="p-2 relative flex w-full min-w-0 flex-col"><div data-slot="sidebar-group-content" data-sidebar="group-content" class="text-sm w-full"><ul data-slot="sidebar-menu" data-sidebar="menu" class="gap-0 flex w-full min-w-0 flex-col"><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><button type="button" id="base-ui-_R_6qb6_" data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" class="ring-sidebar-ring data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-md p-2 text-left transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:size-4 [&_svg]:shrink-0 h-8 text-sm bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground active:bg-primary/90 active:text-primary-foreground duration-200 ease-linear"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-plus" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="M8 12h8"></path><path d="M12 8v8"></path></svg><span>Create Chat</span></button></li></ul></div></div><div data-slot="sidebar-group" data-sidebar="group" class="p-2 relative flex w-full min-w-0 flex-col group-data-[collapsible=icon]:hidden"><div data-slot="sidebar-group-label" data-sidebar="group-label" class="text-sidebar-foreground/70 ring-sidebar-ring h-8 rounded-md px-2 text-xs font-medium transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 flex shrink-0 items-center outline-hidden [&>svg]:shrink-0">Recent Sessions</div><ul data-slot="sidebar-menu" data-sidebar="menu" class="gap-0 flex w-full min-w-0 flex-col"><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><button type="button" data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" class="ring-sidebar-ring active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-md p-2 text-left transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-8 text-sm" disabled=""><span class="text-sidebar-foreground/70">No sessions yet</span></button></li></ul></div><div data-slot="sidebar-group" data-sidebar="group" class="p-2 relative flex w-full min-w-0 flex-col mt-auto"><div data-slot="sidebar-group-content" data-sidebar="group-content" class="text-sm w-full"><ul data-slot="sidebar-menu" data-sidebar="menu" class="gap-0 flex w-full min-w-0 flex-col"><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><a data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" href="/settings" class="ring-sidebar-ring active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-md p-2 text-left transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-8 text-sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings" aria-hidden="true"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"></path><circle cx="12" cy="12" r="3"></circle></svg><span>Settings</span></a></li><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><a data-slot="sidebar-menu-button" data-sidebar="menu-button" data-size="default" href="/extensions" class="ring-sidebar-ring active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-md p-2 text-left transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground h-8 text-sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-puzzle" aria-hidden="true"><path d="M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z"></path></svg><span>Extensions</span></a></li><li data-slot="sidebar-menu-item" data-sidebar="menu-item" class="group/menu-item relative"><div class="px-2 py-1.5"><span data-slot="badge" data-variant="secondary" class="h-5 gap-1 rounded-4xl border px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! inline-flex items-center whitespace-nowrap shrink-0 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive overflow-hidden group/badge [a]:hover:bg-secondary/80 bg-red-500/10 text-red-500 border-red-500/20 w-full justify-start"><div class="size-2 rounded-full mr-2 bg-red-500 "></div>Disconnected</span></div></li></ul></div></div></div></div></div></div><main data-slot="sidebar-inset" class="bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2 relative flex w-full flex-1 flex-col"><div class="flex flex-1 flex-col overflow-hidden"><header class="flex h-14 shrink-0 items-center gap-2 border-b px-4"><button type="button" tabindex="0" data-slot="sidebar-trigger" data-sidebar="trigger" class="focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-panel-left" aria-hidden="true"><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M9 3v18"></path></svg><span class="sr-only">Toggle Sidebar</span></button></header><!--$--><!--$--><!--/$--><script></script><!--/$--></div></main></div><script class="$tsr" id="$tsr-stream-barrier">(self.$R=self.$R||{})["tsr"]=[];self.$_TSR={h(){this.hydrated=!0,this.c()},e(){this.streamEnded=!0,this.c()},c(){this.hydrated&&this.streamEnded&&(delete self.$_TSR,delete self.$R.tsr)},p(e){this.initialized?e():this.buffer.push(e)},buffer:[]};
|
|
2
|
-
;$_TSR.router=($R=>$R[0]={manifest:$R[1]={routes:$R[2]={__root__:$R[3]={preloads:$R[4]=["/assets/main-UkFzTTck.js"],assets:$R[5]=[$R[6]={tag:"script",attrs:$R[7]={type:"module",async:!0},children:"import(\"/assets/main-UkFzTTck.js\")"}]}}},matches:$R[8]=[$R[9]={i:"__root__",u:
|
|
2
|
+
;$_TSR.router=($R=>$R[0]={manifest:$R[1]={routes:$R[2]={__root__:$R[3]={preloads:$R[4]=["/assets/main-UkFzTTck.js"],assets:$R[5]=[$R[6]={tag:"script",attrs:$R[7]={type:"module",async:!0},children:"import(\"/assets/main-UkFzTTck.js\")"}]}}},matches:$R[8]=[$R[9]={i:"__root__",u:1772486954401,s:"success",ssr:!0}],lastMatchId:"__root__"})($R["tsr"]);$_TSR.e();document.currentScript.remove()</script><script type="module" async="">import("/assets/main-UkFzTTck.js")</script></body></html>
|