clankie 0.9.0 → 0.10.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/README.md +3 -0
- package/dist/cli.js +154 -35
- package/package.json +2 -2
- package/web-ui-dist/_shell.html +2 -2
- package/web-ui-dist/assets/{auth-B9O56j8p.js → auth-B20mIC_p.js} +1 -1
- package/web-ui-dist/assets/badge-3e57zy_2.js +1 -0
- package/web-ui-dist/assets/check-CePvKusa.js +1 -0
- package/web-ui-dist/assets/{circle-x-DXPT4pz6.js → circle-x-B1Pwi07a.js} +1 -1
- package/web-ui-dist/assets/{connection-yciJazNP.js → connection-D4rgB5k2.js} +1 -1
- package/web-ui-dist/assets/extensions-BxWXmCbJ.js +1 -0
- package/web-ui-dist/assets/{extensions-OUCiAY5C.js → extensions-Cf8QLmLt.js} +1 -1
- package/web-ui-dist/assets/{field-BbqZG4RJ.js → field-DfBj0pPw.js} +1 -1
- package/web-ui-dist/assets/{index-r9_5oSFI.js → index-Ff5WtXhh.js} +1 -1
- package/web-ui-dist/assets/{index-DDPzWyca.js → index-TBNB5eLy.js} +1 -1
- package/web-ui-dist/assets/{json-render-renderer-BcrsT8Ur.js → json-render-renderer-BrlU1n47.js} +1 -1
- package/web-ui-dist/assets/main-CP6prmzV.js +35 -0
- package/web-ui-dist/assets/{scoped-models-C9IkaHnT.js → scoped-models-DDH_ssLY.js} +1 -1
- package/web-ui-dist/assets/{sessions._sessionId-D9fk3HTP.js → sessions._sessionId-CWtQlITL.js} +24 -24
- package/web-ui-dist/assets/{skills-DYeJYRTs.js → skills-Clk3tV2m.js} +1 -1
- package/web-ui-dist/assets/styles-KEhqa3CU.css +1 -0
- package/web-ui-dist/assets/{theme-D4lx1WJW.js → theme-e79Jvep_.js} +1 -1
- package/web-ui-dist/assets/badge-CFXQDPlY.js +0 -1
- package/web-ui-dist/assets/check-D-vykl4i.js +0 -1
- package/web-ui-dist/assets/extensions-COhAmsTM.js +0 -1
- package/web-ui-dist/assets/main-D1-MPeAM.js +0 -35
- package/web-ui-dist/assets/styles-C4OT29Wk.css +0 -1
package/README.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
+
import { execSync, spawn, spawnSync } from "node:child_process";
|
|
3
4
|
import * as crypto$2 from "node:crypto";
|
|
4
5
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
5
6
|
import * as fs$6 from "node:fs";
|
|
@@ -14,7 +15,7 @@ import path, { basename as basename$1, dirname as dirname$1, isAbsolute as isAbs
|
|
|
14
15
|
import { fileURLToPath } from "url";
|
|
15
16
|
import * as os$2 from "node:os";
|
|
16
17
|
import os, { homedir as homedir$1, platform as platform$1, tmpdir } from "node:os";
|
|
17
|
-
import { exec, execSync, spawn, spawnSync } from "child_process";
|
|
18
|
+
import { exec, execSync as execSync$1, spawn as spawn$1, spawnSync as spawnSync$1 } from "child_process";
|
|
18
19
|
import { Readable } from "stream";
|
|
19
20
|
import crypto$1, { randomUUID as randomUUID$1 } from "crypto";
|
|
20
21
|
import { createServer } from "http";
|
|
@@ -36,7 +37,6 @@ import { access as access$1, lstat, open, readFile as readFile$1, readdir as rea
|
|
|
36
37
|
import { EventEmitter as EventEmitter$1 } from "node:events";
|
|
37
38
|
import tty from "node:tty";
|
|
38
39
|
import { createRequire as createRequire$1 } from "module";
|
|
39
|
-
import { execSync as execSync$1, spawn as spawn$1, spawnSync as spawnSync$1 } from "node:child_process";
|
|
40
40
|
import { StringDecoder } from "node:string_decoder";
|
|
41
41
|
import { finished as finished$1 } from "stream/promises";
|
|
42
42
|
import { createInterface } from "node:readline";
|
|
@@ -213478,7 +213478,7 @@ let cachedShellConfig = null;
|
|
|
213478
213478
|
function findBashOnPath() {
|
|
213479
213479
|
if (process.platform === "win32") {
|
|
213480
213480
|
try {
|
|
213481
|
-
const result = spawnSync("where", ["bash.exe"], {
|
|
213481
|
+
const result = spawnSync$1("where", ["bash.exe"], {
|
|
213482
213482
|
encoding: "utf-8",
|
|
213483
213483
|
timeout: 5e3
|
|
213484
213484
|
});
|
|
@@ -213490,7 +213490,7 @@ function findBashOnPath() {
|
|
|
213490
213490
|
return null;
|
|
213491
213491
|
}
|
|
213492
213492
|
try {
|
|
213493
|
-
const result = spawnSync("which", ["bash"], {
|
|
213493
|
+
const result = spawnSync$1("which", ["bash"], {
|
|
213494
213494
|
encoding: "utf-8",
|
|
213495
213495
|
timeout: 5e3
|
|
213496
213496
|
});
|
|
@@ -213601,7 +213601,7 @@ function sanitizeBinaryOutput(str) {
|
|
|
213601
213601
|
*/
|
|
213602
213602
|
function killProcessTree(pid) {
|
|
213603
213603
|
if (process.platform === "win32") try {
|
|
213604
|
-
spawn("taskkill", [
|
|
213604
|
+
spawn$1("taskkill", [
|
|
213605
213605
|
"/F",
|
|
213606
213606
|
"/T",
|
|
213607
213607
|
"/PID",
|
|
@@ -213822,7 +213822,7 @@ function truncateLine(line, maxChars = 500) {
|
|
|
213822
213822
|
function executeBash(command, options) {
|
|
213823
213823
|
return new Promise((resolve, reject) => {
|
|
213824
213824
|
const { shell, args } = getShellConfig();
|
|
213825
|
-
const child = spawn(shell, [...args, command], {
|
|
213825
|
+
const child = spawn$1(shell, [...args, command], {
|
|
213826
213826
|
detached: true,
|
|
213827
213827
|
env: getShellEnv(),
|
|
213828
213828
|
stdio: [
|
|
@@ -263025,7 +263025,7 @@ function walkDirectoryWithFd(baseDir, fdPath, query, maxResults) {
|
|
|
263025
263025
|
".git/**"
|
|
263026
263026
|
];
|
|
263027
263027
|
if (query) args.push(query);
|
|
263028
|
-
const result = spawnSync(fdPath, args, {
|
|
263028
|
+
const result = spawnSync$1(fdPath, args, {
|
|
263029
263029
|
encoding: "utf-8",
|
|
263030
263030
|
stdio: [
|
|
263031
263031
|
"pipe",
|
|
@@ -271480,7 +271480,7 @@ function createEventBus() {
|
|
|
271480
271480
|
*/
|
|
271481
271481
|
async function execCommand(command, args, cwd, options) {
|
|
271482
271482
|
return new Promise((resolve) => {
|
|
271483
|
-
const proc = spawn
|
|
271483
|
+
const proc = spawn(command, args, {
|
|
271484
271484
|
cwd,
|
|
271485
271485
|
shell: false,
|
|
271486
271486
|
stdio: [
|
|
@@ -273542,7 +273542,7 @@ const defaultBashOperations = { exec: (command, cwd, { onData, signal, timeout,
|
|
|
273542
273542
|
reject(/* @__PURE__ */ new Error(`Working directory does not exist: ${cwd}\nCannot execute bash commands.`));
|
|
273543
273543
|
return;
|
|
273544
273544
|
}
|
|
273545
|
-
const child = spawn(shell, [...args, command], {
|
|
273545
|
+
const child = spawn$1(shell, [...args, command], {
|
|
273546
273546
|
cwd,
|
|
273547
273547
|
detached: true,
|
|
273548
273548
|
env: env ?? getShellEnv(),
|
|
@@ -279228,7 +279228,7 @@ const TOOLS = {
|
|
|
279228
279228
|
};
|
|
279229
279229
|
function commandExists(cmd) {
|
|
279230
279230
|
try {
|
|
279231
|
-
const result = spawnSync(cmd, ["--version"], { stdio: "pipe" });
|
|
279231
|
+
const result = spawnSync$1(cmd, ["--version"], { stdio: "pipe" });
|
|
279232
279232
|
return result.error === void 0 || result.error === null;
|
|
279233
279233
|
} catch {
|
|
279234
279234
|
return false;
|
|
@@ -279289,7 +279289,7 @@ async function downloadTool(tool) {
|
|
|
279289
279289
|
mkdirSync$1(extractDir, { recursive: true });
|
|
279290
279290
|
try {
|
|
279291
279291
|
if (assetName.endsWith(".tar.gz")) {
|
|
279292
|
-
const extractResult = spawnSync("tar", [
|
|
279292
|
+
const extractResult = spawnSync$1("tar", [
|
|
279293
279293
|
"xzf",
|
|
279294
279294
|
archivePath,
|
|
279295
279295
|
"-C",
|
|
@@ -279451,7 +279451,7 @@ function createFindTool(cwd, options) {
|
|
|
279451
279451
|
} catch {}
|
|
279452
279452
|
for (const gitignorePath of gitignoreFiles) args.push("--ignore-file", gitignorePath);
|
|
279453
279453
|
args.push(pattern, searchPath);
|
|
279454
|
-
const result = spawnSync(fdPath, args, {
|
|
279454
|
+
const result = spawnSync$1(fdPath, args, {
|
|
279455
279455
|
encoding: "utf-8",
|
|
279456
279456
|
maxBuffer: 10 * 1024 * 1024
|
|
279457
279457
|
});
|
|
@@ -279606,7 +279606,7 @@ function createGrepTool(cwd, options) {
|
|
|
279606
279606
|
if (literal) args.push("--fixed-strings");
|
|
279607
279607
|
if (glob) args.push("--glob", glob);
|
|
279608
279608
|
args.push(pattern, searchPath);
|
|
279609
|
-
const child = spawn(rgPath, args, { stdio: [
|
|
279609
|
+
const child = spawn$1(rgPath, args, { stdio: [
|
|
279610
279610
|
"ignore",
|
|
279611
279611
|
"pipe",
|
|
279612
279612
|
"pipe"
|
|
@@ -285304,7 +285304,7 @@ function executeCommand(commandConfig) {
|
|
|
285304
285304
|
const command = commandConfig.slice(1);
|
|
285305
285305
|
let result;
|
|
285306
285306
|
try {
|
|
285307
|
-
result = execSync(command, {
|
|
285307
|
+
result = execSync$1(command, {
|
|
285308
285308
|
encoding: "utf-8",
|
|
285309
285309
|
timeout: 1e4,
|
|
285310
285310
|
stdio: [
|
|
@@ -289898,7 +289898,7 @@ var DefaultPackageManager = class {
|
|
|
289898
289898
|
}
|
|
289899
289899
|
runCommand(command, args, options) {
|
|
289900
289900
|
return new Promise((resolvePromise, reject) => {
|
|
289901
|
-
const child = spawn
|
|
289901
|
+
const child = spawn(command, args, {
|
|
289902
289902
|
cwd: options?.cwd,
|
|
289903
289903
|
stdio: "inherit",
|
|
289904
289904
|
shell: process.platform === "win32"
|
|
@@ -289911,7 +289911,7 @@ var DefaultPackageManager = class {
|
|
|
289911
289911
|
});
|
|
289912
289912
|
}
|
|
289913
289913
|
runCommandSync(command, args) {
|
|
289914
|
-
const result = spawnSync
|
|
289914
|
+
const result = spawnSync(command, args, {
|
|
289915
289915
|
stdio: [
|
|
289916
289916
|
"ignore",
|
|
289917
289917
|
"pipe",
|
|
@@ -292560,7 +292560,7 @@ var SessionList = class {
|
|
|
292560
292560
|
* Delete a session file, trying the `trash` CLI first, then falling back to unlink
|
|
292561
292561
|
*/
|
|
292562
292562
|
async function deleteSessionFile(sessionPath) {
|
|
292563
|
-
const trashResult = spawnSync
|
|
292563
|
+
const trashResult = spawnSync("trash", sessionPath.startsWith("-") ? ["--", sessionPath] : [sessionPath], { encoding: "utf-8" });
|
|
292564
292564
|
const getTrashErrorHint = () => {
|
|
292565
292565
|
const parts = [];
|
|
292566
292566
|
if (trashResult.error) parts.push(trashResult.error.message);
|
|
@@ -293321,7 +293321,7 @@ async function convertToPng$1(bytes) {
|
|
|
293321
293321
|
}
|
|
293322
293322
|
}
|
|
293323
293323
|
function runCommand(command, args, options) {
|
|
293324
|
-
const result = spawnSync(command, args, {
|
|
293324
|
+
const result = spawnSync$1(command, args, {
|
|
293325
293325
|
timeout: options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS,
|
|
293326
293326
|
maxBuffer: options?.maxBufferBytes ?? DEFAULT_MAX_BUFFER_BYTES
|
|
293327
293327
|
});
|
|
@@ -293418,16 +293418,16 @@ function copyToClipboard(text) {
|
|
|
293418
293418
|
timeout: 5e3
|
|
293419
293419
|
};
|
|
293420
293420
|
try {
|
|
293421
|
-
if (p === "darwin") execSync("pbcopy", options);
|
|
293422
|
-
else if (p === "win32") execSync("clip", options);
|
|
293421
|
+
if (p === "darwin") execSync$1("pbcopy", options);
|
|
293422
|
+
else if (p === "win32") execSync$1("clip", options);
|
|
293423
293423
|
else {
|
|
293424
293424
|
if (process.env.TERMUX_VERSION) try {
|
|
293425
|
-
execSync("termux-clipboard-set", options);
|
|
293425
|
+
execSync$1("termux-clipboard-set", options);
|
|
293426
293426
|
return;
|
|
293427
293427
|
} catch {}
|
|
293428
293428
|
if (isWaylandSession()) try {
|
|
293429
|
-
execSync("which wl-copy", { stdio: "ignore" });
|
|
293430
|
-
const proc = spawn("wl-copy", [], { stdio: [
|
|
293429
|
+
execSync$1("which wl-copy", { stdio: "ignore" });
|
|
293430
|
+
const proc = spawn$1("wl-copy", [], { stdio: [
|
|
293431
293431
|
"pipe",
|
|
293432
293432
|
"ignore",
|
|
293433
293433
|
"ignore"
|
|
@@ -293438,15 +293438,15 @@ function copyToClipboard(text) {
|
|
|
293438
293438
|
proc.unref();
|
|
293439
293439
|
} catch {
|
|
293440
293440
|
try {
|
|
293441
|
-
execSync("xclip -selection clipboard", options);
|
|
293441
|
+
execSync$1("xclip -selection clipboard", options);
|
|
293442
293442
|
} catch {
|
|
293443
|
-
execSync("xsel --clipboard --input", options);
|
|
293443
|
+
execSync$1("xsel --clipboard --input", options);
|
|
293444
293444
|
}
|
|
293445
293445
|
}
|
|
293446
293446
|
else try {
|
|
293447
|
-
execSync("xclip -selection clipboard", options);
|
|
293447
|
+
execSync$1("xclip -selection clipboard", options);
|
|
293448
293448
|
} catch {
|
|
293449
|
-
execSync("xsel --clipboard --input", options);
|
|
293449
|
+
execSync$1("xsel --clipboard --input", options);
|
|
293450
293450
|
}
|
|
293451
293451
|
}
|
|
293452
293452
|
} catch {}
|
|
@@ -294465,7 +294465,7 @@ var ExtensionEditorComponent = class extends Container {
|
|
|
294465
294465
|
fs$6.writeFileSync(tmpFile, currentText, "utf-8");
|
|
294466
294466
|
this.tui.stop();
|
|
294467
294467
|
const [editor, ...editorArgs] = editorCmd.split(" ");
|
|
294468
|
-
if (spawnSync
|
|
294468
|
+
if (spawnSync(editor, [...editorArgs, tmpFile], { stdio: "inherit" }).status === 0) {
|
|
294469
294469
|
const newContent = fs$6.readFileSync(tmpFile, "utf-8").replace(/\n$/, "");
|
|
294470
294470
|
this.editor.setText(newContent);
|
|
294471
294471
|
}
|
|
@@ -298986,7 +298986,7 @@ var InteractiveMode = class InteractiveMode {
|
|
|
298986
298986
|
fs$6.writeFileSync(tmpFile, currentText, "utf-8");
|
|
298987
298987
|
this.ui.stop();
|
|
298988
298988
|
const [editor, ...editorArgs] = editorCmd.split(" ");
|
|
298989
|
-
if (spawnSync(editor, [...editorArgs, tmpFile], { stdio: "inherit" }).status === 0) {
|
|
298989
|
+
if (spawnSync$1(editor, [...editorArgs, tmpFile], { stdio: "inherit" }).status === 0) {
|
|
298990
298990
|
const newContent = fs$6.readFileSync(tmpFile, "utf-8").replace(/\n$/, "");
|
|
298991
298991
|
this.editor.setText(newContent);
|
|
298992
298992
|
}
|
|
@@ -299749,7 +299749,7 @@ var InteractiveMode = class InteractiveMode {
|
|
|
299749
299749
|
}
|
|
299750
299750
|
async handleShareCommand() {
|
|
299751
299751
|
try {
|
|
299752
|
-
if (spawnSync("gh", ["auth", "status"], { encoding: "utf-8" }).status !== 0) {
|
|
299752
|
+
if (spawnSync$1("gh", ["auth", "status"], { encoding: "utf-8" }).status !== 0) {
|
|
299753
299753
|
this.showError("GitHub CLI is not logged in. Run 'gh auth login' first.");
|
|
299754
299754
|
return;
|
|
299755
299755
|
}
|
|
@@ -299786,7 +299786,7 @@ var InteractiveMode = class InteractiveMode {
|
|
|
299786
299786
|
};
|
|
299787
299787
|
try {
|
|
299788
299788
|
const result = await new Promise((resolve) => {
|
|
299789
|
-
proc = spawn("gh", [
|
|
299789
|
+
proc = spawn$1("gh", [
|
|
299790
299790
|
"gist",
|
|
299791
299791
|
"create",
|
|
299792
299792
|
"--public=false",
|
|
@@ -308838,7 +308838,7 @@ function execSafe(cmd) {
|
|
|
308838
308838
|
try {
|
|
308839
308839
|
return {
|
|
308840
308840
|
ok: true,
|
|
308841
|
-
stdout: execSync
|
|
308841
|
+
stdout: execSync(cmd, {
|
|
308842
308842
|
encoding: "utf-8",
|
|
308843
308843
|
stdio: [
|
|
308844
308844
|
"pipe",
|
|
@@ -309027,6 +309027,51 @@ async function uninstallService() {
|
|
|
309027
309027
|
process.exit(1);
|
|
309028
309028
|
}
|
|
309029
309029
|
}
|
|
309030
|
+
function hasInstalledService() {
|
|
309031
|
+
if (isMac) return existsSync(launchdPlistPath());
|
|
309032
|
+
if (isLinux) return existsSync(systemdUnitPath());
|
|
309033
|
+
return false;
|
|
309034
|
+
}
|
|
309035
|
+
function restartInstalledService() {
|
|
309036
|
+
if (isMac) {
|
|
309037
|
+
const plistPath = launchdPlistPath();
|
|
309038
|
+
if (!existsSync(plistPath)) {
|
|
309039
|
+
console.error("Clankie is not installed as a launchd agent.");
|
|
309040
|
+
process.exit(1);
|
|
309041
|
+
}
|
|
309042
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
309043
|
+
if (uid === void 0) {
|
|
309044
|
+
console.error("Could not determine current user ID for launchd restart.");
|
|
309045
|
+
process.exit(1);
|
|
309046
|
+
}
|
|
309047
|
+
if (!execSafe(`launchctl bootout gui/${uid} "${plistPath}"`).ok) execSafe(`launchctl unload "${plistPath}"`);
|
|
309048
|
+
const bootstrap = execSafe(`launchctl bootstrap gui/${uid} "${plistPath}"`);
|
|
309049
|
+
if (!bootstrap.ok) {
|
|
309050
|
+
const load = execSafe(`launchctl load "${plistPath}"`);
|
|
309051
|
+
if (!load.ok) {
|
|
309052
|
+
console.error(`launchctl restart failed: ${bootstrap.stderr || load.stderr}`);
|
|
309053
|
+
process.exit(1);
|
|
309054
|
+
}
|
|
309055
|
+
}
|
|
309056
|
+
console.log(`Restarted launchd agent: ${LAUNCHD_LABEL}`);
|
|
309057
|
+
return;
|
|
309058
|
+
}
|
|
309059
|
+
if (isLinux) {
|
|
309060
|
+
if (!existsSync(systemdUnitPath())) {
|
|
309061
|
+
console.error("Clankie is not installed as a systemd user service.");
|
|
309062
|
+
process.exit(1);
|
|
309063
|
+
}
|
|
309064
|
+
const restart = execSafe(`systemctl --user restart ${SERVICE_NAME}.service`);
|
|
309065
|
+
if (!restart.ok) {
|
|
309066
|
+
console.error(`systemd restart failed: ${restart.stderr || restart.stdout}`);
|
|
309067
|
+
process.exit(1);
|
|
309068
|
+
}
|
|
309069
|
+
console.log(`Restarted systemd service: ${SERVICE_NAME}.service`);
|
|
309070
|
+
return;
|
|
309071
|
+
}
|
|
309072
|
+
console.error(`Service management not supported on ${platform$1()}.`);
|
|
309073
|
+
process.exit(1);
|
|
309074
|
+
}
|
|
309030
309075
|
function showServiceLogs() {
|
|
309031
309076
|
if (isMac) logsLaunchd();
|
|
309032
309077
|
else if (isLinux) logsSystemd();
|
|
@@ -309055,6 +309100,8 @@ function showServiceStatus() {
|
|
|
309055
309100
|
* clankie start Start the daemon (channels + agent)
|
|
309056
309101
|
* clankie stop Stop the daemon
|
|
309057
309102
|
* clankie restart Restart the daemon
|
|
309103
|
+
* clankie update Update clankie via npm and restart daemon/service if needed
|
|
309104
|
+
* clankie self-update Alias for update
|
|
309058
309105
|
* clankie status Check daemon status
|
|
309059
309106
|
* clankie daemon install Install as a system service (systemd/launchd)
|
|
309060
309107
|
* clankie daemon uninstall Remove the system service
|
|
@@ -309076,6 +309123,8 @@ Usage:
|
|
|
309076
309123
|
clankie start [--foreground] Start the daemon (foreground by default)
|
|
309077
309124
|
clankie stop Stop the daemon
|
|
309078
309125
|
clankie restart Restart the daemon
|
|
309126
|
+
clankie update Update clankie via npm and restart daemon/service if needed
|
|
309127
|
+
clankie self-update Alias for update
|
|
309079
309128
|
clankie status Check if daemon is running
|
|
309080
309129
|
clankie daemon install Install as a system service (systemd/launchd)
|
|
309081
309130
|
clankie daemon uninstall Remove the system service
|
|
@@ -309125,15 +309174,40 @@ Examples:
|
|
|
309125
309174
|
Credentials are stored at ~/.clankie/auth.json (separate from pi's auth).
|
|
309126
309175
|
`);
|
|
309127
309176
|
}
|
|
309128
|
-
function
|
|
309177
|
+
function getCurrentVersion() {
|
|
309129
309178
|
const packagePath = join(import.meta.dirname, "..", "package.json");
|
|
309130
309179
|
try {
|
|
309131
309180
|
const pkg = JSON.parse(readFileSync(packagePath, "utf-8"));
|
|
309132
|
-
|
|
309181
|
+
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
309133
309182
|
} catch {
|
|
309134
|
-
|
|
309183
|
+
return;
|
|
309135
309184
|
}
|
|
309136
309185
|
}
|
|
309186
|
+
function printVersion() {
|
|
309187
|
+
const version = getCurrentVersion();
|
|
309188
|
+
if (version) console.log(`clankie ${version}`);
|
|
309189
|
+
else console.log("clankie (version unknown)");
|
|
309190
|
+
}
|
|
309191
|
+
function getGlobalNpmRoot() {
|
|
309192
|
+
const result = spawnSync("npm", ["root", "-g"], { encoding: "utf-8" });
|
|
309193
|
+
if (result.status !== 0) return void 0;
|
|
309194
|
+
return result.stdout.trim() || void 0;
|
|
309195
|
+
}
|
|
309196
|
+
function isInstalledFromGlobalNpm() {
|
|
309197
|
+
const globalRoot = getGlobalNpmRoot();
|
|
309198
|
+
if (!globalRoot) return false;
|
|
309199
|
+
const packageRoot = join(import.meta.dirname, "..");
|
|
309200
|
+
return packageRoot === join(globalRoot, "clankie") || packageRoot.startsWith(`${join(globalRoot, "clankie")}/`);
|
|
309201
|
+
}
|
|
309202
|
+
function getLatestPublishedVersion() {
|
|
309203
|
+
const result = spawnSync("npm", [
|
|
309204
|
+
"view",
|
|
309205
|
+
"clankie",
|
|
309206
|
+
"version"
|
|
309207
|
+
], { encoding: "utf-8" });
|
|
309208
|
+
if (result.status !== 0) return void 0;
|
|
309209
|
+
return result.stdout.trim() || void 0;
|
|
309210
|
+
}
|
|
309137
309211
|
async function cmdSend(args) {
|
|
309138
309212
|
const message = args.join(" ").trim();
|
|
309139
309213
|
if (!message) {
|
|
@@ -309295,6 +309369,47 @@ function cmdStop() {
|
|
|
309295
309369
|
async function cmdRestart() {
|
|
309296
309370
|
await restartDaemon();
|
|
309297
309371
|
}
|
|
309372
|
+
async function cmdUpdate() {
|
|
309373
|
+
const packageName = "clankie";
|
|
309374
|
+
const currentVersion = getCurrentVersion();
|
|
309375
|
+
const latestVersion = getLatestPublishedVersion();
|
|
309376
|
+
const serviceInstalled = hasInstalledService();
|
|
309377
|
+
const daemonRunning = isRunning().running;
|
|
309378
|
+
if (!isInstalledFromGlobalNpm()) {
|
|
309379
|
+
console.error("Self-update only supports npm global installs.");
|
|
309380
|
+
console.error("Please update clankie with the same package manager or workflow you used to install it.");
|
|
309381
|
+
process.exit(1);
|
|
309382
|
+
}
|
|
309383
|
+
if (currentVersion && latestVersion) {
|
|
309384
|
+
console.log(`Current version: ${currentVersion}`);
|
|
309385
|
+
console.log(`Latest version: ${latestVersion}`);
|
|
309386
|
+
if (currentVersion === latestVersion) {
|
|
309387
|
+
console.log("clankie is already up to date.");
|
|
309388
|
+
return;
|
|
309389
|
+
}
|
|
309390
|
+
console.log();
|
|
309391
|
+
} else console.log("Checking latest version via npm failed or returned no version; proceeding with update.");
|
|
309392
|
+
console.log(`Updating ${packageName} via npm...`);
|
|
309393
|
+
const update = spawnSync("npm", [
|
|
309394
|
+
"install",
|
|
309395
|
+
"-g",
|
|
309396
|
+
`${packageName}@latest`
|
|
309397
|
+
], { stdio: "inherit" });
|
|
309398
|
+
if (update.status !== 0) process.exit(update.status ?? 1);
|
|
309399
|
+
console.log("\n✓ clankie updated.");
|
|
309400
|
+
if (serviceInstalled) {
|
|
309401
|
+
console.log("Restarting installed service...");
|
|
309402
|
+
restartInstalledService();
|
|
309403
|
+
return;
|
|
309404
|
+
}
|
|
309405
|
+
if (daemonRunning) {
|
|
309406
|
+
console.log("Restarting daemon with the updated CLI...");
|
|
309407
|
+
const restart = spawnSync("clankie", ["restart"], { stdio: "inherit" });
|
|
309408
|
+
if (restart.status !== 0) process.exit(restart.status ?? 1);
|
|
309409
|
+
return;
|
|
309410
|
+
}
|
|
309411
|
+
console.log("Daemon is not running. Start it with 'clankie start' when ready.");
|
|
309412
|
+
}
|
|
309298
309413
|
function cmdStatus() {
|
|
309299
309414
|
const status = isRunning();
|
|
309300
309415
|
if (status.running) console.log(`Daemon is running (pid ${status.pid}).`);
|
|
@@ -309418,6 +309533,10 @@ async function main() {
|
|
|
309418
309533
|
case "restart":
|
|
309419
309534
|
await cmdRestart();
|
|
309420
309535
|
break;
|
|
309536
|
+
case "update":
|
|
309537
|
+
case "self-update":
|
|
309538
|
+
await cmdUpdate();
|
|
309539
|
+
break;
|
|
309421
309540
|
case "status":
|
|
309422
309541
|
cmdStatus();
|
|
309423
309542
|
break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clankie",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "A minimal personal AI assistant built on pi's SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"check:fix": "biome check --fix .",
|
|
23
23
|
"format": "biome format --write .",
|
|
24
24
|
"typecheck": "tsgo --noEmit",
|
|
25
|
-
"typecheck:all": "tsgo --noEmit && cd web-ui && npx tsgo --noEmit && cd ../extensions/clankie-memory && npx tsgo --noEmit"
|
|
25
|
+
"typecheck:all": "tsgo --noEmit && cd web-ui && npx tsgo --noEmit && cd ../extensions/clankie-memory && npx tsgo --noEmit && cd ../clankie-json-ui-render && npx tsgo --noEmit"
|
|
26
26
|
},
|
|
27
27
|
"engines": {
|
|
28
28
|
"node": ">=18.0.0"
|
package/web-ui-dist/_shell.html
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en"><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-D1-MPeAM.js"/><link rel="modulepreload" href="/assets/index-DDPzWyca.js"/><link rel="icon" type="image/svg+xml" href="/favicon.svg"/><link rel="stylesheet" href="/assets/styles-C4OT29Wk.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)] border-r border-border/20"><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="p-2 flex flex-col gap-3 px-4 py-4"><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 text-sm group-data-[collapsible=icon]:p-0! h-10 active" href="/" data-status="active" aria-current="page"><div class="flex items-center gap-3"><div class="flex items-center justify-center w-8 h-8 rounded-xl bg-primary/15 border border-primary/20"><span class="text-sm font-mono font-bold text-primary">c/</span></div><span class="text-lg font-mono font-semibold tracking-tight text-sidebar-foreground">clankie</span></div></a></li></ul><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_spb6_" 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 p-2 text-left 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-10 text-sm font-medium bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground active:bg-primary/90 active:text-primary-foreground transition-all rounded-xl"><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 h-4 w-4 mr-1" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="M8 12h8"></path><path d="M12 8v8"></path></svg><span>New Chat</span></button></li></ul></div><div data-slot="sidebar-content" data-sidebar="content" class="no-scrollbar flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden gap-2 px-2 py-2"><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 py-2"><div data-slot="sidebar-group-label" data-sidebar="group-label" class="ring-sidebar-ring h-8 rounded-md 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 text-[11px] font-medium uppercase tracking-wider text-muted-foreground/40 px-3 py-2">Recent</div><ul data-slot="sidebar-menu" data-sidebar="menu" class="flex w-full min-w-0 flex-col gap-1 px-1"><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 text-sm h-12 opacity-40" disabled=""><span class="text-sm text-sidebar-foreground/40">No sessions yet</span></button></li></ul></div></div><div data-slot="sidebar-footer" data-sidebar="footer" class="gap-2 p-2 flex flex-col px-2 py-2"><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="dropdown-menu-trigger" 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 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 h-10 text-sm text-sidebar-foreground/70 hover:text-sidebar-foreground rounded-xl" tabindex="0" aria-haspopup="menu" id="base-ui-_R_7pb6_"><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 h-4 w-4" 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></button></li></ul></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 flex w-full flex-1 flex-col relative"><div class="absolute left-4 top-3.5 z-50 md:hidden"><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></div><!--$--><!--$--><!--/$--><script></script><!--/$--></main></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><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-
|
|
1
|
+
<!DOCTYPE html><html lang="en"><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-CP6prmzV.js"/><link rel="modulepreload" href="/assets/index-TBNB5eLy.js"/><link rel="icon" type="image/svg+xml" href="/favicon.svg"/><link rel="stylesheet" href="/assets/styles-KEhqa3CU.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)] border-r border-border/20"><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="p-2 flex flex-col gap-3 px-4 py-4"><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="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 text-sm group-data-[collapsible=icon]:p-0! h-10"><div class="flex items-center gap-3"><div class="flex items-center justify-center w-8 h-8 rounded-xl bg-primary/15 border border-primary/20"><span class="text-sm font-mono font-bold text-primary">c/</span></div><span class="text-lg font-mono font-semibold tracking-tight text-sidebar-foreground">clankie</span></div></button></li></ul><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_1phb6_" 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 p-2 text-left 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-10 text-sm font-medium bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground active:bg-primary/90 active:text-primary-foreground transition-all rounded-xl"><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 h-4 w-4 mr-1" aria-hidden="true"><circle cx="12" cy="12" r="10"></circle><path d="M8 12h8"></path><path d="M12 8v8"></path></svg><span>New Chat</span></button></li></ul></div><div data-slot="sidebar-content" data-sidebar="content" class="no-scrollbar flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden gap-2 px-2 py-2"><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 py-2"><div data-slot="sidebar-group-label" data-sidebar="group-label" class="ring-sidebar-ring h-8 rounded-md 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 text-[11px] font-medium uppercase tracking-wider text-muted-foreground/40 px-3 py-2">Recent</div><ul data-slot="sidebar-menu" data-sidebar="menu" class="flex w-full min-w-0 flex-col gap-1 px-1"><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 text-sm h-12 opacity-40" disabled=""><span class="text-sm text-sidebar-foreground/40">No sessions yet</span></button></li></ul></div></div><div data-slot="sidebar-footer" data-sidebar="footer" class="gap-2 p-2 flex flex-col px-2 py-2"><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="dropdown-menu-trigger" 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 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 h-10 text-sm text-sidebar-foreground/70 hover:text-sidebar-foreground rounded-xl" tabindex="0" aria-haspopup="menu" id="base-ui-_R_fhb6_"><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 h-4 w-4" 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></button></li></ul></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 flex w-full flex-1 flex-col relative min-h-0"><header class="topbar-glass sticky top-0 z-40 flex h-14 shrink-0 items-center border-b px-4 md:hidden"><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><div class="min-h-0 flex-1"><!--$--><!--$--><!--/$--><script></script><!--/$--></div></main></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><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-CP6prmzV.js"],assets:$R[5]=[$R[6]={tag:"script",attrs:$R[7]={type:"module",async:!0},children:"import(\"/assets/main-CP6prmzV.js\")"}]}}},matches:$R[8]=[$R[9]={i:"__root__",u:1772806123370,s:"success",ssr:!0}],lastMatchId:"__root__"})($R["tsr"]);$_TSR.e();document.currentScript.remove()</script><script type="module" async="">import("/assets/main-CP6prmzV.js")</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as b,z as R,A as K,D as O,E,r as u,j as e,H as T,J as B,w as p,M as V,N as U,B as x,O as $,Q as q,R as H,a as A,U as S,V as Y,m as j,o as y,I,c as W,W as X,X as w,s as J,Y as Q,C as D,g as P,h as F,n as Z,e as L,K as G,Z as ee,_ as te}from"./main-D1-MPeAM.js";import{F as k,a as z}from"./field-BbqZG4RJ.js";import{C as M}from"./circle-x-DXPT4pz6.js";import{B as se}from"./badge-CFXQDPlY.js";const ae=[["path",{d:"M21.801 10A10 10 0 1 1 17 3.335",key:"yps3ct"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]],ne=b("circle-check-big",ae);const re=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],ie=b("external-link",re);const oe=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]],_=b("shield",oe);function le(t){const{children:a,open:s,defaultOpen:l=!1,onOpenChange:r,onOpenChangeComplete:i,actionsRef:m,handle:f,triggerId:g,defaultTriggerId:h=null}=t,v=R(),N=!!v,c=K(()=>f?.store??new O({open:l,openProp:s,activeTriggerId:h,triggerIdProp:g,modal:!0,disablePointerDismissal:!0,nested:N,role:"alertdialog"})).current;c.useControlledProp("openProp",s),c.useControlledProp("triggerIdProp",g),c.useSyncedValue("nested",N),c.useContextCallback("onOpenChange",r),c.useContextCallback("onOpenChangeComplete",i);const C=c.useState("payload");E({store:c,actionsRef:m,parentContext:v?.store.context});const n=u.useMemo(()=>({store:c}),[c]);return e.jsx(T.Provider,{value:n,children:typeof a=="function"?a({payload:C}):a})}function ce({...t}){return e.jsx(le,{"data-slot":"alert-dialog",...t})}function de({...t}){return e.jsx(q,{"data-slot":"alert-dialog-portal",...t})}function ue({className:t,...a}){return e.jsx(H,{"data-slot":"alert-dialog-overlay",className:p("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 isolate z-50",t),...a})}function me({className:t,size:a="default",...s}){return e.jsxs(de,{children:[e.jsx(ue,{}),e.jsx(B,{"data-slot":"alert-dialog-content","data-size":a,className:p("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 bg-background ring-foreground/10 gap-4 rounded-xl p-4 ring-1 duration-100 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 outline-none",t),...s})]})}function xe({className:t,...a}){return e.jsx("div",{"data-slot":"alert-dialog-header",className:p("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",t),...a})}function ge({className:t,...a}){return e.jsx("div",{"data-slot":"alert-dialog-footer",className:p("bg-muted/50 -mx-4 -mb-4 rounded-b-xl border-t p-4 flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",t),...a})}function he({className:t,...a}){return e.jsx(V,{"data-slot":"alert-dialog-title",className:p("text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",t),...a})}function pe({className:t,...a}){return e.jsx(U,{"data-slot":"alert-dialog-description",className:p("text-muted-foreground *:[a]:hover:text-foreground text-sm text-balance md:text-pretty *:[a]:underline *:[a]:underline-offset-3",t),...a})}function fe({className:t,...a}){return e.jsx(x,{"data-slot":"alert-dialog-action",className:p(t),...a})}function je({className:t,variant:a="outline",size:s="default",...l}){return e.jsx($,{"data-slot":"alert-dialog-cancel",className:p(t),render:e.jsx(x,{variant:a,size:s}),...l})}function ye({open:t,onOpenChange:a}){const{loginFlow:s}=A(S,i=>({loginFlow:i.loginFlow}));if(u.useEffect(()=>{!t&&s&&Y()},[t,s]),u.useEffect(()=>{if(t&&s?.status==="complete"&&s.success===!0){const i=setTimeout(()=>{a(!1)},1500);return()=>clearTimeout(i)}},[t,s,a]),!s)return null;const l=()=>{s.loginFlowId&&s.status!=="complete"&&s.status!=="error"&&j.getClient()?.authLoginCancel(s.loginFlowId),a(!1)},r=()=>{a(!1)};return e.jsx(ce,{open:t,onOpenChange:a,children:e.jsxs(me,{children:[e.jsxs(xe,{children:[e.jsx(he,{children:s.status==="complete"&&s.success?"Login Successful":s.status==="error"?"Login Failed":`Sign in to ${s.providerId}`}),e.jsx(pe,{children:e.jsx(ve,{flow:s})})]}),e.jsx(ge,{children:s.status==="complete"||s.status==="error"?e.jsx(fe,{onClick:r,children:"Close"}):e.jsx(je,{onClick:l,children:"Cancel"})})]})})}function ve({flow:t}){const a=j.getClient(),s=u.useRef(null),l=i=>{t.loginFlowId&&a&&a.authLoginInput(t.loginFlowId,i)},r=i=>{t.loginFlowId&&a&&a.authLoginInput(t.loginFlowId,i)};return u.useEffect(()=>{t.status==="waiting_url"&&t.url&&s.current!==t.url&&(s.current=t.url,window.open(t.url,"_blank"))},[t.status,t.url]),t.status==="idle"?e.jsxs("div",{className:"flex items-center gap-3 py-4",children:[e.jsx(y,{className:"h-5 w-5 animate-spin text-muted-foreground"}),e.jsx("span",{className:"text-sm",children:"Starting login..."})]}):t.status==="waiting_url"&&t.url?e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(y,{className:"h-5 w-5 animate-spin text-muted-foreground"}),e.jsx("span",{className:"text-sm",children:"Complete the authentication in your browser..."})]}),t.instructions&&e.jsx("p",{className:"text-xs text-muted-foreground rounded-md bg-muted p-2",children:t.instructions}),e.jsxs(x,{onClick:()=>window.open(t.url,"_blank"),className:"w-full",variant:"outline",size:"sm",children:[e.jsx(ie,{className:"mr-2 h-4 w-4"}),"Open in Browser"]}),t.showManualInput&&e.jsx(Ne,{onSubmit:l}),t.progressMessage&&e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx(y,{className:"h-3 w-3 animate-spin"}),e.jsx("span",{children:t.progressMessage})]})]}):t.status==="waiting_input"&&t.promptMessage?e.jsx("div",{className:"py-4",children:e.jsx(Ce,{message:t.promptMessage,placeholder:t.promptPlaceholder,onSubmit:r})}):t.status==="in_progress"?e.jsxs("div",{className:"flex items-center gap-3 py-4",children:[e.jsx(y,{className:"h-5 w-5 animate-spin text-muted-foreground"}),e.jsx("span",{className:"text-sm",children:t.progressMessage||"Completing authentication..."})]}):t.status==="complete"&&t.success?e.jsxs("div",{className:"flex items-center gap-3 py-4 text-green-600",children:[e.jsx(ne,{className:"h-5 w-5"}),e.jsxs("span",{className:"text-sm",children:["Successfully authenticated with ",t.providerId]})]}):t.status==="error"||t.status==="complete"&&!t.success?e.jsxs("div",{className:"space-y-2 py-4",children:[e.jsxs("div",{className:"flex items-center gap-3 text-destructive",children:[e.jsx(M,{className:"h-5 w-5"}),e.jsx("span",{className:"text-sm font-medium",children:"Authentication failed"})]}),t.error&&e.jsx("p",{className:"text-xs text-muted-foreground rounded-md bg-muted p-2",children:t.error})]}):null}function Ne({onSubmit:t}){const a=s=>{s.preventDefault();const r=new FormData(s.currentTarget).get("code");r?.trim()&&t(r.trim())};return e.jsx("form",{onSubmit:a,className:"space-y-2",children:e.jsxs(k,{children:[e.jsx(z,{htmlFor:"manual-code",children:"Or paste the authorization code/URL here:"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(I,{id:"manual-code",name:"code",type:"text",placeholder:"Paste code or redirect URL",className:"flex-1"}),e.jsx(x,{type:"submit",size:"sm",children:"Submit"})]})]})})}function Ce({message:t,placeholder:a,onSubmit:s}){const l=r=>{r.preventDefault();const m=new FormData(r.currentTarget).get("prompt-value");m?.trim()&&s(m.trim())};return e.jsxs("form",{onSubmit:l,className:"space-y-3",children:[e.jsx("p",{className:"text-sm",children:t}),e.jsx(k,{children:e.jsxs("div",{className:"flex gap-2",children:[e.jsx(I,{id:"prompt-value",name:"prompt-value",type:"text",placeholder:a||"Enter value",className:"flex-1",autoFocus:!0}),e.jsx(x,{type:"submit",size:"sm",children:"Submit"})]})})]})}function Pe(){const{status:t}=A(W,s=>({status:s.status}));return t==="connected"?e.jsx(be,{}):e.jsx("div",{className:"h-full flex items-center justify-center chat-background",children:e.jsxs("div",{className:"text-center space-y-4 max-w-md p-8",children:[e.jsx("div",{className:"inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-destructive/10 border border-destructive/20 mb-2",children:e.jsx(_,{className:"h-8 w-8 text-destructive"})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("h2",{className:"text-2xl font-semibold",children:"Not Connected"}),e.jsx("p",{className:"text-muted-foreground",children:"Connect to clankie to manage AI provider authentication"})]})]})})}function be(){const{providers:t,isLoadingProviders:a,loginFlow:s}=A(S,n=>({providers:n.providers,isLoadingProviders:n.isLoadingProviders,loginFlow:n.loginFlow})),[l,r]=u.useState(!1),[i,m]=u.useState(null),[f,g]=u.useState(""),h=u.useCallback(async()=>{const n=j.getClient();if(n){X(!0);try{const{providers:o}=await n.getAuthProviders();w(o)}catch(o){console.error("Failed to load auth providers:",o),w([])}}},[]);u.useEffect(()=>{h()},[h]),u.useEffect(()=>{if(s?.status==="complete"&&s.success===!0){h();const{activeSessionId:n}=J.state;if(n){const o=j.getClient();o&&o.getAvailableModels(n).then(({models:d})=>{Q(d),console.log("[settings/auth] Refreshed available models after OAuth login")}).catch(d=>{console.error("[settings/auth] Failed to refresh available models:",d)})}}},[s?.status,s?.success,h]);const v=async n=>{const o=j.getClient();if(o)try{const{loginFlowId:d}=await o.authLogin(n);te(d,n),r(!0)}catch(d){console.error("Failed to start login:",d)}},N=n=>{m(n),g("")},c=async n=>{const o=j.getClient();if(!(!o||!f.trim()))try{await o.authSetApiKey(n,f.trim()),m(null),g(""),await h()}catch(d){console.error("Failed to save API key:",d)}},C=async n=>{const o=j.getClient();if(o)try{await o.authLogout(n),await h()}catch(d){console.error("Failed to logout:",d)}};return e.jsxs("div",{className:"h-full overflow-y-auto chat-background",children:[e.jsxs("div",{className:"container max-w-2xl py-8 px-4",children:[e.jsxs(D,{className:"card-depth",children:[e.jsxs(P,{children:[e.jsx(F,{children:"AI Provider Authentication"}),e.jsx(Z,{children:"Configure authentication for AI providers (OpenAI, Anthropic, etc.)"})]}),e.jsx(L,{children:a?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(y,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):t.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"No providers available. Make sure clankie is configured with at least one AI provider."}):e.jsx("div",{className:"space-y-3",children:t.map(n=>e.jsx(Ae,{provider:n,isEditing:i===n.id,apiKeyValue:f,onApiKeyChange:g,onLogin:()=>n.type==="oauth"?v(n.id):N(n.id),onSaveApiKey:()=>c(n.id),onCancelApiKey:()=>m(null),onLogout:()=>C(n.id)},n.id))})})]}),e.jsxs(D,{className:"mt-4 card-depth",children:[e.jsx(P,{children:e.jsx(F,{children:"About Provider Authentication"})}),e.jsxs(L,{className:"space-y-3 text-sm text-muted-foreground",children:[e.jsx("p",{children:"AI providers require authentication to access their APIs. You can authenticate using:"}),e.jsxs("ul",{className:"list-disc list-inside space-y-1",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"OAuth"})," - Browser-based authentication flow for supported providers"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"API Key"})," - Direct API key entry for providers that support it"]})]}),e.jsx("p",{className:"text-xs",children:"Your credentials are stored securely by clankie and are never shared with the web UI."})]})]})]}),e.jsx(ye,{open:l,onOpenChange:r})]})}function Ae({provider:t,isEditing:a,apiKeyValue:s,onApiKeyChange:l,onLogin:r,onSaveApiKey:i,onCancelApiKey:m,onLogout:f}){return e.jsx("div",{className:"rounded-lg border p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("h4",{className:"font-medium",children:t.name}),e.jsx(se,{variant:t.type==="oauth"?"default":"secondary",className:"text-xs",children:t.type==="oauth"?e.jsxs(e.Fragment,{children:[e.jsx(_,{className:"h-3 w-3 mr-1"}),"OAuth"]}):e.jsxs(e.Fragment,{children:[e.jsx(G,{className:"h-3 w-3 mr-1"}),"API Key"]})}),t.hasAuth?e.jsx(ee,{className:"h-4 w-4 text-green-600"}):e.jsx(M,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:t.hasAuth?"Authenticated":"Not configured"}),a&&t.type==="apikey"&&e.jsxs("div",{className:"mt-3 space-y-2",children:[e.jsxs(k,{children:[e.jsx(z,{htmlFor:`api-key-${t.id}`,children:"API Key"}),e.jsx(I,{id:`api-key-${t.id}`,type:"password",placeholder:"Enter API key",value:s,onChange:g=>l(g.target.value),autoFocus:!0})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(x,{size:"sm",onClick:i,disabled:!s.trim(),children:"Save"}),e.jsx(x,{size:"sm",variant:"outline",onClick:m,children:"Cancel"})]})]})]}),!a&&e.jsx("div",{className:"flex gap-2",children:t.hasAuth?e.jsx(x,{size:"sm",variant:"outline",onClick:f,children:"Logout"}):e.jsx(x,{size:"sm",onClick:r,children:"Login"})})]})})}export{Pe as component};
|
|
1
|
+
import{i as b,A as R,D as K,E as O,H as E,r as u,j as e,J as T,M as B,x as p,N as V,O as $,B as x,Q as U,R as q,U as H,a as A,V as S,W as Y,m as j,o as y,I,c as W,X,Y as D,s as J,Z as Q,C as w,g as P,h as F,n as Z,e as L,K as G,_ as ee,$ as te}from"./main-CP6prmzV.js";import{F as k,a as z}from"./field-DfBj0pPw.js";import{C as M}from"./circle-x-B1Pwi07a.js";import{B as se}from"./badge-3e57zy_2.js";const ae=[["path",{d:"M21.801 10A10 10 0 1 1 17 3.335",key:"yps3ct"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]],ne=b("circle-check-big",ae);const re=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],ie=b("external-link",re);const oe=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]],_=b("shield",oe);function le(t){const{children:a,open:s,defaultOpen:l=!1,onOpenChange:r,onOpenChangeComplete:i,actionsRef:m,handle:f,triggerId:g,defaultTriggerId:h=null}=t,v=R(),N=!!v,c=K(()=>f?.store??new O({open:l,openProp:s,activeTriggerId:h,triggerIdProp:g,modal:!0,disablePointerDismissal:!0,nested:N,role:"alertdialog"})).current;c.useControlledProp("openProp",s),c.useControlledProp("triggerIdProp",g),c.useSyncedValue("nested",N),c.useContextCallback("onOpenChange",r),c.useContextCallback("onOpenChangeComplete",i);const C=c.useState("payload");E({store:c,actionsRef:m,parentContext:v?.store.context});const n=u.useMemo(()=>({store:c}),[c]);return e.jsx(T.Provider,{value:n,children:typeof a=="function"?a({payload:C}):a})}function ce({...t}){return e.jsx(le,{"data-slot":"alert-dialog",...t})}function de({...t}){return e.jsx(q,{"data-slot":"alert-dialog-portal",...t})}function ue({className:t,...a}){return e.jsx(H,{"data-slot":"alert-dialog-overlay",className:p("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 isolate z-50",t),...a})}function me({className:t,size:a="default",...s}){return e.jsxs(de,{children:[e.jsx(ue,{}),e.jsx(B,{"data-slot":"alert-dialog-content","data-size":a,className:p("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 bg-background ring-foreground/10 gap-4 rounded-xl p-4 ring-1 duration-100 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 outline-none",t),...s})]})}function xe({className:t,...a}){return e.jsx("div",{"data-slot":"alert-dialog-header",className:p("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",t),...a})}function ge({className:t,...a}){return e.jsx("div",{"data-slot":"alert-dialog-footer",className:p("bg-muted/50 -mx-4 -mb-4 rounded-b-xl border-t p-4 flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",t),...a})}function he({className:t,...a}){return e.jsx(V,{"data-slot":"alert-dialog-title",className:p("text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",t),...a})}function pe({className:t,...a}){return e.jsx($,{"data-slot":"alert-dialog-description",className:p("text-muted-foreground *:[a]:hover:text-foreground text-sm text-balance md:text-pretty *:[a]:underline *:[a]:underline-offset-3",t),...a})}function fe({className:t,...a}){return e.jsx(x,{"data-slot":"alert-dialog-action",className:p(t),...a})}function je({className:t,variant:a="outline",size:s="default",...l}){return e.jsx(U,{"data-slot":"alert-dialog-cancel",className:p(t),render:e.jsx(x,{variant:a,size:s}),...l})}function ye({open:t,onOpenChange:a}){const{loginFlow:s}=A(S,i=>({loginFlow:i.loginFlow}));if(u.useEffect(()=>{!t&&s&&Y()},[t,s]),u.useEffect(()=>{if(t&&s?.status==="complete"&&s.success===!0){const i=setTimeout(()=>{a(!1)},1500);return()=>clearTimeout(i)}},[t,s,a]),!s)return null;const l=()=>{s.loginFlowId&&s.status!=="complete"&&s.status!=="error"&&j.getClient()?.authLoginCancel(s.loginFlowId),a(!1)},r=()=>{a(!1)};return e.jsx(ce,{open:t,onOpenChange:a,children:e.jsxs(me,{children:[e.jsxs(xe,{children:[e.jsx(he,{children:s.status==="complete"&&s.success?"Login Successful":s.status==="error"?"Login Failed":`Sign in to ${s.providerId}`}),e.jsx(pe,{children:e.jsx(ve,{flow:s})})]}),e.jsx(ge,{children:s.status==="complete"||s.status==="error"?e.jsx(fe,{onClick:r,children:"Close"}):e.jsx(je,{onClick:l,children:"Cancel"})})]})})}function ve({flow:t}){const a=j.getClient(),s=u.useRef(null),l=i=>{t.loginFlowId&&a&&a.authLoginInput(t.loginFlowId,i)},r=i=>{t.loginFlowId&&a&&a.authLoginInput(t.loginFlowId,i)};return u.useEffect(()=>{t.status==="waiting_url"&&t.url&&s.current!==t.url&&(s.current=t.url,window.open(t.url,"_blank"))},[t.status,t.url]),t.status==="idle"?e.jsxs("div",{className:"flex items-center gap-3 py-4",children:[e.jsx(y,{className:"h-5 w-5 animate-spin text-muted-foreground"}),e.jsx("span",{className:"text-sm",children:"Starting login..."})]}):t.status==="waiting_url"&&t.url?e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(y,{className:"h-5 w-5 animate-spin text-muted-foreground"}),e.jsx("span",{className:"text-sm",children:"Complete the authentication in your browser..."})]}),t.instructions&&e.jsx("p",{className:"text-xs text-muted-foreground rounded-md bg-muted p-2",children:t.instructions}),e.jsxs(x,{onClick:()=>window.open(t.url,"_blank"),className:"w-full",variant:"outline",size:"sm",children:[e.jsx(ie,{className:"mr-2 h-4 w-4"}),"Open in Browser"]}),t.showManualInput&&e.jsx(Ne,{onSubmit:l}),t.progressMessage&&e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsx(y,{className:"h-3 w-3 animate-spin"}),e.jsx("span",{children:t.progressMessage})]})]}):t.status==="waiting_input"&&t.promptMessage?e.jsx("div",{className:"py-4",children:e.jsx(Ce,{message:t.promptMessage,placeholder:t.promptPlaceholder,onSubmit:r})}):t.status==="in_progress"?e.jsxs("div",{className:"flex items-center gap-3 py-4",children:[e.jsx(y,{className:"h-5 w-5 animate-spin text-muted-foreground"}),e.jsx("span",{className:"text-sm",children:t.progressMessage||"Completing authentication..."})]}):t.status==="complete"&&t.success?e.jsxs("div",{className:"flex items-center gap-3 py-4 text-green-600",children:[e.jsx(ne,{className:"h-5 w-5"}),e.jsxs("span",{className:"text-sm",children:["Successfully authenticated with ",t.providerId]})]}):t.status==="error"||t.status==="complete"&&!t.success?e.jsxs("div",{className:"space-y-2 py-4",children:[e.jsxs("div",{className:"flex items-center gap-3 text-destructive",children:[e.jsx(M,{className:"h-5 w-5"}),e.jsx("span",{className:"text-sm font-medium",children:"Authentication failed"})]}),t.error&&e.jsx("p",{className:"text-xs text-muted-foreground rounded-md bg-muted p-2",children:t.error})]}):null}function Ne({onSubmit:t}){const a=s=>{s.preventDefault();const r=new FormData(s.currentTarget).get("code");r?.trim()&&t(r.trim())};return e.jsx("form",{onSubmit:a,className:"space-y-2",children:e.jsxs(k,{children:[e.jsx(z,{htmlFor:"manual-code",children:"Or paste the authorization code/URL here:"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(I,{id:"manual-code",name:"code",type:"text",placeholder:"Paste code or redirect URL",className:"flex-1"}),e.jsx(x,{type:"submit",size:"sm",children:"Submit"})]})]})})}function Ce({message:t,placeholder:a,onSubmit:s}){const l=r=>{r.preventDefault();const m=new FormData(r.currentTarget).get("prompt-value");m?.trim()&&s(m.trim())};return e.jsxs("form",{onSubmit:l,className:"space-y-3",children:[e.jsx("p",{className:"text-sm",children:t}),e.jsx(k,{children:e.jsxs("div",{className:"flex gap-2",children:[e.jsx(I,{id:"prompt-value",name:"prompt-value",type:"text",placeholder:a||"Enter value",className:"flex-1",autoFocus:!0}),e.jsx(x,{type:"submit",size:"sm",children:"Submit"})]})})]})}function Pe(){const{status:t}=A(W,s=>({status:s.status}));return t==="connected"?e.jsx(be,{}):e.jsx("div",{className:"h-full flex items-center justify-center chat-background",children:e.jsxs("div",{className:"text-center space-y-4 max-w-md p-8",children:[e.jsx("div",{className:"inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-destructive/10 border border-destructive/20 mb-2",children:e.jsx(_,{className:"h-8 w-8 text-destructive"})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("h2",{className:"text-2xl font-semibold",children:"Not Connected"}),e.jsx("p",{className:"text-muted-foreground",children:"Connect to clankie to manage AI provider authentication"})]})]})})}function be(){const{providers:t,isLoadingProviders:a,loginFlow:s}=A(S,n=>({providers:n.providers,isLoadingProviders:n.isLoadingProviders,loginFlow:n.loginFlow})),[l,r]=u.useState(!1),[i,m]=u.useState(null),[f,g]=u.useState(""),h=u.useCallback(async()=>{const n=j.getClient();if(n){X(!0);try{const{providers:o}=await n.getAuthProviders();D(o)}catch(o){console.error("Failed to load auth providers:",o),D([])}}},[]);u.useEffect(()=>{h()},[h]),u.useEffect(()=>{if(s?.status==="complete"&&s.success===!0){h();const{activeSessionId:n}=J.state;if(n){const o=j.getClient();o&&o.getAvailableModels(n).then(({models:d})=>{Q(d),console.log("[settings/auth] Refreshed available models after OAuth login")}).catch(d=>{console.error("[settings/auth] Failed to refresh available models:",d)})}}},[s?.status,s?.success,h]);const v=async n=>{const o=j.getClient();if(o)try{const{loginFlowId:d}=await o.authLogin(n);te(d,n),r(!0)}catch(d){console.error("Failed to start login:",d)}},N=n=>{m(n),g("")},c=async n=>{const o=j.getClient();if(!(!o||!f.trim()))try{await o.authSetApiKey(n,f.trim()),m(null),g(""),await h()}catch(d){console.error("Failed to save API key:",d)}},C=async n=>{const o=j.getClient();if(o)try{await o.authLogout(n),await h()}catch(d){console.error("Failed to logout:",d)}};return e.jsxs("div",{className:"h-full overflow-y-auto chat-background",children:[e.jsxs("div",{className:"container max-w-2xl py-8 px-4",children:[e.jsxs(w,{className:"card-depth",children:[e.jsxs(P,{children:[e.jsx(F,{children:"AI Provider Authentication"}),e.jsx(Z,{children:"Configure authentication for AI providers (OpenAI, Anthropic, etc.)"})]}),e.jsx(L,{children:a?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(y,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):t.length===0?e.jsx("p",{className:"text-sm text-muted-foreground py-4",children:"No providers available. Make sure clankie is configured with at least one AI provider."}):e.jsx("div",{className:"space-y-3",children:t.map(n=>e.jsx(Ae,{provider:n,isEditing:i===n.id,apiKeyValue:f,onApiKeyChange:g,onLogin:()=>n.type==="oauth"?v(n.id):N(n.id),onSaveApiKey:()=>c(n.id),onCancelApiKey:()=>m(null),onLogout:()=>C(n.id)},n.id))})})]}),e.jsxs(w,{className:"mt-4 card-depth",children:[e.jsx(P,{children:e.jsx(F,{children:"About Provider Authentication"})}),e.jsxs(L,{className:"space-y-3 text-sm text-muted-foreground",children:[e.jsx("p",{children:"AI providers require authentication to access their APIs. You can authenticate using:"}),e.jsxs("ul",{className:"list-disc list-inside space-y-1",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"OAuth"})," - Browser-based authentication flow for supported providers"]}),e.jsxs("li",{children:[e.jsx("strong",{children:"API Key"})," - Direct API key entry for providers that support it"]})]}),e.jsx("p",{className:"text-xs",children:"Your credentials are stored securely by clankie and are never shared with the web UI."})]})]})]}),e.jsx(ye,{open:l,onOpenChange:r})]})}function Ae({provider:t,isEditing:a,apiKeyValue:s,onApiKeyChange:l,onLogin:r,onSaveApiKey:i,onCancelApiKey:m,onLogout:f}){return e.jsx("div",{className:"rounded-lg border p-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("h4",{className:"font-medium",children:t.name}),e.jsx(se,{variant:t.type==="oauth"?"default":"secondary",className:"text-xs",children:t.type==="oauth"?e.jsxs(e.Fragment,{children:[e.jsx(_,{className:"h-3 w-3 mr-1"}),"OAuth"]}):e.jsxs(e.Fragment,{children:[e.jsx(G,{className:"h-3 w-3 mr-1"}),"API Key"]})}),t.hasAuth?e.jsx(ee,{className:"h-4 w-4 text-green-600"}):e.jsx(M,{className:"h-4 w-4 text-muted-foreground"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:t.hasAuth?"Authenticated":"Not configured"}),a&&t.type==="apikey"&&e.jsxs("div",{className:"mt-3 space-y-2",children:[e.jsxs(k,{children:[e.jsx(z,{htmlFor:`api-key-${t.id}`,children:"API Key"}),e.jsx(I,{id:`api-key-${t.id}`,type:"password",placeholder:"Enter API key",value:s,onChange:g=>l(g.target.value),autoFocus:!0})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(x,{size:"sm",onClick:i,disabled:!s.trim(),children:"Save"}),e.jsx(x,{size:"sm",variant:"outline",onClick:m,children:"Cancel"})]})]})]}),!a&&e.jsx("div",{className:"flex gap-2",children:t.hasAuth?e.jsx(x,{size:"sm",variant:"outline",onClick:f,children:"Logout"}):e.jsx(x,{size:"sm",onClick:r,children:"Login"})})]})})}export{Pe as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a0 as i,a1 as n,x as d,a2 as s}from"./main-CP6prmzV.js";const o=s("h-5 gap-1 rounded-4xl border border-transparent 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 justify-center w-fit 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",{variants:{variant:{default:"bg-primary text-primary-foreground [a]:hover:bg-primary/80",secondary:"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",destructive:"bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20",outline:"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",ghost:"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",link:"text-primary underline-offset-4 hover:underline"}},defaultVariants:{variant:"default"}});function g({className:r,variant:e="default",render:t,...a}){return i({defaultTagName:"span",props:n({className:d(o({variant:e}),r)},a),render:t,state:{slot:"badge",variant:e}})}export{g as B};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as c}from"./main-CP6prmzV.js";const e=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],t=c("check",e);export{t as C};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as c}from"./main-
|
|
1
|
+
import{i as c}from"./main-CP6prmzV.js";const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]],i=c("circle-x",e);export{i as C};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as S,c as w,r,j as e,C as d,g as h,h as x,n as y,e as u,I as m,B as c,L as T,S as F,
|
|
1
|
+
import{a as S,c as w,r,j as e,C as d,g as h,h as x,n as y,e as u,I as m,B as c,L as T,S as F,z as j,m as p}from"./main-CP6prmzV.js";import{F as g,a as k}from"./field-DfBj0pPw.js";function A(){const{settings:o,status:l}=S(w,t=>({settings:t.settings,status:t.status})),[a,b]=r.useState(o.url),[n,v]=r.useState(o.authToken),s=l==="connected",i=l==="connecting",C=()=>{j({url:a,authToken:n})},N=()=>{j({url:a,authToken:n}),p.connect()},f=()=>{p.disconnect()};return e.jsx("div",{className:"h-full overflow-y-auto chat-background",children:e.jsxs("div",{className:"container max-w-2xl py-8 px-4",children:[e.jsxs(d,{className:"card-depth",children:[e.jsxs(h,{children:[e.jsx(x,{children:"Connection Settings"}),e.jsx(y,{children:"Configure the WebSocket connection to your clankie instance"})]}),e.jsxs(u,{className:"space-y-4",children:[e.jsxs(g,{children:[e.jsx(k,{htmlFor:"ws-url",children:"WebSocket URL"}),e.jsx(m,{id:"ws-url",type:"text",placeholder:"ws://localhost:3100",value:a,onChange:t=>b(t.target.value),disabled:s})]}),e.jsxs(g,{children:[e.jsx(k,{htmlFor:"auth-token",children:"Auth Token"}),e.jsx(m,{id:"auth-token",type:"password",placeholder:"Enter your authentication token",value:n,onChange:t=>v(t.target.value),disabled:s}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["Set with:"," ",e.jsx("code",{className:"rounded bg-muted px-1 py-0.5",children:'clankie config set channels.web.authToken "your-token"'})]})]}),e.jsx("div",{className:"flex gap-2 pt-2",children:s?e.jsx(c,{variant:"destructive",onClick:f,children:"Disconnect"}):e.jsxs(e.Fragment,{children:[e.jsx(c,{onClick:N,disabled:i||!n,children:i?"Connecting...":"Connect"}),e.jsx(c,{variant:"outline",onClick:C,disabled:i,children:"Save"})]})}),!n&&e.jsxs("div",{className:"rounded-md border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive",children:[e.jsx("p",{className:"font-medium",children:"Auth token required"}),e.jsx("p",{className:"text-xs mt-1",children:"Configure the token in clankie and enter it above to connect."})]})]})]}),e.jsxs(d,{className:"mt-4 card-depth",children:[e.jsx(h,{children:e.jsx(x,{children:"Setup Instructions"})}),e.jsxs(u,{className:"space-y-3 text-sm",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"1. Enable the web channel in clankie"}),e.jsxs("code",{className:"block mt-1 rounded bg-muted p-2 text-xs",children:['clankie config set channels.web.authToken "your-secret-token"',e.jsx("br",{}),"clankie config set channels.web.port 3100"]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"2. Start the clankie daemon"}),e.jsx("code",{className:"block mt-1 rounded bg-muted p-2 text-xs",children:"clankie start"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"font-medium",children:"3. Enter the token above and connect"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"The web-ui will connect to ws://localhost:3100 by default"})]})]})]}),!s&&e.jsx("div",{className:"mt-4 text-center",children:e.jsx(T,{to:"/settings",children:e.jsxs(c,{variant:"outline",children:[e.jsx(F,{className:"mr-2 h-4 w-4"}),"Back to Settings"]})})})]})})}export{A as component};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as a,y as i}from"./main-CP6prmzV.js";const o=[["path",{d:"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5",key:"1gvzjb"}],["path",{d:"M9 18h6",key:"x1upvd"}],["path",{d:"M10 22h4",key:"ceow96"}]],c=a("lightbulb",o),l={extensions:[],extensionErrors:[],skills:[],skillDiagnostics:[],isLoading:!1,installStatus:{isInstalling:!1,output:"",exitCode:null}},e=new i(l);function r(t){e.setState(s=>({...s,isLoading:t}))}function S(t,s){e.setState(n=>({...n,extensions:t,extensionErrors:s,isLoading:!1}))}function d(t,s){e.setState(n=>({...n,skills:t,skillDiagnostics:s,isLoading:!1}))}function g(t){e.setState(s=>({...s,installStatus:{...s.installStatus,...t}}))}function f(){e.setState(t=>({...t,installStatus:{isInstalling:!1,output:"",exitCode:null,error:void 0}}))}export{c as L,d as a,S as b,g as c,e,f as r,r as s};
|