@ryukin-dev/pi-featherless-kali 1.1.1 → 1.1.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.3
4
+
5
+ - Extension wird jetzt über `pi install npm:@ryukin-dev/pi-featherless-kali` als Pi-Paket geladen.
6
+ - Behebt das Problem, dass der Featherless-Provider nicht unter `/login` → API keys erschien.
7
+ - Alte manuelle Extension-/Skill-Kopien werden beim Start bereinigt.
8
+
9
+ ## 1.1.2
10
+
11
+ - `kaliai` installiert den Pi Coding Agent automatisch, wenn er fehlt.
12
+ - Kein manueller `npm install -g @earendil-works/pi-coding-agent` mehr nötig.
13
+
3
14
  ## 1.1.1
4
15
 
5
16
  - Unerwünschte Abhängigkeiten (`puppeteer`, `openai`, `JSONStream`) entfernt.
package/bin/kaliai.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawnSync, execFileSync } from "node:child_process";
3
- import { existsSync, mkdirSync, rmSync, symlinkSync, cpSync, readFileSync, readdirSync } from "node:fs";
3
+ import { existsSync, mkdirSync, rmSync, readdirSync, readlinkSync, readFileSync } from "node:fs";
4
4
  import { homedir, platform } from "node:os";
5
5
  import { dirname, join, basename } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
@@ -9,8 +9,6 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
9
9
  const SOURCE_DIR = join(__dirname, "..");
10
10
  const HOME = homedir();
11
11
  const AGENT_DIR = join(HOME, ".pi", "agent");
12
- const EXT_DIR = join(AGENT_DIR, "extensions", "pi-featherless");
13
- const SKILLS_DIR = join(AGENT_DIR, "skills");
14
12
  const PI_PACKAGE = "@earendil-works/pi-coding-agent";
15
13
  const NPM_PACKAGE = "@ryukin-dev/pi-featherless-kali";
16
14
 
@@ -32,6 +30,78 @@ function getPiCliPath() {
32
30
  return join(root, PI_PACKAGE, "dist", "cli.js");
33
31
  }
34
32
 
33
+ function ensurePiAgentInstalled() {
34
+ const piCli = getPiCliPath();
35
+ if (piCli && existsSync(piCli)) return piCli;
36
+ print("==> Pi Coding Agent wird installiert...");
37
+ const result = spawnSync("npm", ["install", "-g", PI_PACKAGE], {
38
+ stdio: "inherit",
39
+ });
40
+ if (result.status !== 0) {
41
+ print("Fehler: Pi Coding Agent konnte nicht installiert werden.");
42
+ process.exit(1);
43
+ }
44
+ const fresh = getPiCliPath();
45
+ if (!fresh || !existsSync(fresh)) {
46
+ print("Fehler: Pi Coding Agent nicht auffindbar nach der Installation.");
47
+ process.exit(1);
48
+ }
49
+ return fresh;
50
+ }
51
+
52
+ function removeLegacyCopy() {
53
+ const legacyExt = join(AGENT_DIR, "extensions", "pi-featherless");
54
+ if (existsSync(legacyExt)) {
55
+ print("==> Entferne alte manuelle Extension...");
56
+ rmSync(legacyExt, { recursive: true, force: true });
57
+ }
58
+
59
+ const skillsDir = join(AGENT_DIR, "skills");
60
+ if (!existsSync(skillsDir)) return;
61
+ for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
62
+ if (!entry.isSymbolicLink()) continue;
63
+ const target = readlinkSync(join(skillsDir, entry.name));
64
+ if (target.includes("pi-featherless-kali")) {
65
+ rmSync(join(skillsDir, entry.name), { recursive: true, force: true });
66
+ }
67
+ }
68
+ }
69
+
70
+ function installPiPackage() {
71
+ print("==> Installiere KaliAI als Pi-Paket...");
72
+ const piCli = getPiCliPath();
73
+ const result = spawnSync(process.execPath, [piCli, "install", `npm:${NPM_PACKAGE}`], {
74
+ stdio: "inherit",
75
+ });
76
+ if (result.status !== 0) {
77
+ print("Fehler: KaliAI Pi-Paket konnte nicht installiert werden.");
78
+ process.exit(1);
79
+ }
80
+ }
81
+
82
+ function getInstalledPiPackageDir() {
83
+ const scoped = join(AGENT_DIR, "npm", NPM_PACKAGE);
84
+ if (existsSync(scoped)) return scoped;
85
+ return undefined;
86
+ }
87
+
88
+ function installSkillDeps(skillPath) {
89
+ if (existsSync(join(skillPath, "package.json")) && !existsSync(join(skillPath, "node_modules"))) {
90
+ print(` Installiere Skill-Abhängigkeiten: ${basename(skillPath)}`);
91
+ spawnSync("npm", ["install"], { cwd: skillPath, stdio: "inherit" });
92
+ }
93
+ }
94
+
95
+ function installPiPackageSkillDeps() {
96
+ const pkgDir = getInstalledPiPackageDir();
97
+ if (!pkgDir) return;
98
+ const skillsDir = join(pkgDir, "skills");
99
+ if (!existsSync(skillsDir)) return;
100
+ for (const name of readdirSync(skillsDir)) {
101
+ installSkillDeps(join(skillsDir, name));
102
+ }
103
+ }
104
+
35
105
  function readPackageVersion(dir) {
36
106
  try {
37
107
  const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
@@ -57,54 +127,11 @@ function readChangelog(dir) {
57
127
  }
58
128
  }
59
129
 
60
- function installSkillDeps(skillPath) {
61
- if (existsSync(join(skillPath, "package.json")) && !existsSync(join(skillPath, "node_modules"))) {
62
- print(` Installiere Skill-Abhängigkeiten: ${basename(skillPath)}`);
63
- spawnSync("npm", ["install"], { cwd: skillPath, stdio: "inherit" });
64
- }
65
- }
66
-
67
- function linkOrCopy(source, target) {
68
- if (existsSync(target)) rmSync(target, { recursive: true, force: true });
69
- try {
70
- symlinkSync(source, target, platform() === "win32" ? "junction" : "dir");
71
- } catch {
72
- cpSync(source, target, { recursive: true });
73
- }
74
- }
75
-
76
- function installExtension() {
77
- print("==> KaliAI Extension wird eingerichtet...");
78
- if (existsSync(EXT_DIR)) rmSync(EXT_DIR, { recursive: true, force: true });
79
- cpSync(SOURCE_DIR, EXT_DIR, {
80
- recursive: true,
81
- filter: (src) =>
82
- !src.includes("node_modules") &&
83
- !src.includes(".git"),
84
- });
85
-
86
- const skillsSource = join(SOURCE_DIR, "skills");
87
- if (existsSync(skillsSource)) {
88
- mkdirSync(SKILLS_DIR, { recursive: true });
89
- for (const name of readdirSync(skillsSource)) {
90
- const src = join(skillsSource, name);
91
- const dst = join(SKILLS_DIR, name);
92
- linkOrCopy(src, dst);
93
- installSkillDeps(dst);
94
- }
95
- }
96
- print("==> KaliAI Extension bereit.");
97
- }
98
-
99
130
  async function startChat() {
100
- installExtension();
101
- const piCli = getPiCliPath();
102
- if (!piCli || !existsSync(piCli)) {
103
- print("Fehler: Pi Coding Agent nicht gefunden.");
104
- print(`Installiere ihn mit:`);
105
- print(` npm install -g ${PI_PACKAGE}`);
106
- process.exit(1);
107
- }
131
+ const piCli = ensurePiAgentInstalled();
132
+ removeLegacyCopy();
133
+ installPiPackage();
134
+ installPiPackageSkillDeps();
108
135
  print("==> Starte KaliAI Chat UI...");
109
136
  spawnSync(process.execPath, [piCli], { stdio: "inherit" });
110
137
  }
@@ -119,7 +146,10 @@ async function runUpdate() {
119
146
  print("Update fehlgeschlagen.");
120
147
  process.exit(result.status ?? 1);
121
148
  }
122
- installExtension();
149
+ const piCli = ensurePiAgentInstalled();
150
+ removeLegacyCopy();
151
+ installPiPackage();
152
+ installPiPackageSkillDeps();
123
153
  const after = readPackageVersion(SOURCE_DIR);
124
154
  print("==> KaliAI aktualisiert" + (before && after ? `: v${before} -> v${after}` : ""));
125
155
  print("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryukin-dev/pi-featherless-kali",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "Featherless Provider for Pi with accurate tokenization and concurrency tracking.",
5
5
  "type": "module",
6
6
  "main": "index.js",