@pikaa-ai/pikaa 0.3.23 → 0.3.24
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/assets/brand/orbit-logo-option4-whale.jpg +0 -0
- package/assets/brand/orbit-logo.jpg +0 -0
- package/assets/brand/orbit-logo.png +0 -0
- package/assets/brand/orbit-logo.svg +3 -0
- package/dist/cli.js +337 -162
- package/dist/index.js +1 -2
- package/package.json +1 -2
- package/skills/adaptyv/SKILL.md +0 -240
- package/skills/aeon/SKILL.md +0 -402
- package/skills/analytical-method-validation/SKILL.md +0 -299
- package/skills/anndata/SKILL.md +0 -431
- package/skills/arbor/SKILL.md +0 -152
- package/skills/arboreto/SKILL.md +0 -267
- package/skills/astropy/SKILL.md +0 -353
- package/skills/autoskill/SKILL.md +0 -233
- package/skills/benchling-integration/SKILL.md +0 -229
- package/skills/bgpt-paper-search/SKILL.md +0 -75
- package/skills/bids/SKILL.md +0 -237
- package/skills/biopython/SKILL.md +0 -472
- package/skills/bioservices/SKILL.md +0 -399
- package/skills/bulk-rnaseq/SKILL.md +0 -198
- package/skills/cellxgene-census/SKILL.md +0 -283
- package/skills/cirq/SKILL.md +0 -370
- package/skills/citation-management/SKILL.md +0 -329
- package/skills/clinical-decision-support/SKILL.md +0 -238
- package/skills/clinical-decision-support/references/README.md +0 -62
- package/skills/clinical-reports/SKILL.md +0 -248
- package/skills/clinical-reports/references/README.md +0 -34
- package/skills/cobrapy/SKILL.md +0 -496
- package/skills/consciousness-council/SKILL.md +0 -151
- package/skills/dask/SKILL.md +0 -482
- package/skills/database-lookup/SKILL.md +0 -386
- package/skills/datamol/SKILL.md +0 -200
- package/skills/deepchem/SKILL.md +0 -244
- package/skills/deepspot-m/SKILL.md +0 -175
- package/skills/deeptools/SKILL.md +0 -412
- package/skills/depmap/SKILL.md +0 -301
- package/skills/dhdna-profiler/SKILL.md +0 -184
- package/skills/diffdock/SKILL.md +0 -488
- package/skills/dnanexus-integration/SKILL.md +0 -325
- package/skills/docx/SKILL.md +0 -99
- package/skills/esm/SKILL.md +0 -334
- package/skills/etetoolkit/SKILL.md +0 -327
- package/skills/exa-search/SKILL.md +0 -102
- package/skills/executing-plans/SKILL.md +0 -14
- package/skills/experimental-design/SKILL.md +0 -234
- package/skills/exploratory-data-analysis/SKILL.md +0 -280
- package/skills/flowio/SKILL.md +0 -310
- package/skills/fluidsim/SKILL.md +0 -279
- package/skills/frontend-design/SKILL.md +0 -100
- package/skills/generate-image/SKILL.md +0 -304
- package/skills/geniml/SKILL.md +0 -310
- package/skills/genomic-coordinates/SKILL.md +0 -189
- package/skills/genomic-intelligence/SKILL.md +0 -243
- package/skills/geomaster/README.md +0 -105
- package/skills/geomaster/SKILL.md +0 -366
- package/skills/geopandas/SKILL.md +0 -250
- package/skills/get-available-resources/SKILL.md +0 -260
- package/skills/gget/SKILL.md +0 -153
- package/skills/ginkgo-cloud-lab/SKILL.md +0 -106
- package/skills/glycoengineering/SKILL.md +0 -339
- package/skills/gtars/SKILL.md +0 -282
- package/skills/guardian-rails/SKILL.md +0 -54
- package/skills/histolab/SKILL.md +0 -243
- package/skills/hugging-science/SKILL.md +0 -132
- package/skills/hypogenic/SKILL.md +0 -290
- package/skills/hypothesis-generation/SKILL.md +0 -264
- package/skills/imaging-data-commons/SKILL.md +0 -496
- package/skills/infographics/SKILL.md +0 -315
- package/skills/iso-standards-readiness/SKILL.md +0 -352
- package/skills/lab-hardware-cad/SKILL.md +0 -372
- package/skills/labarchive-integration/SKILL.md +0 -216
- package/skills/lamindb/SKILL.md +0 -408
- package/skills/latchbio-integration/SKILL.md +0 -227
- package/skills/latex-posters/SKILL.md +0 -369
- package/skills/latex-posters/references/README.md +0 -439
- package/skills/liteparse/SKILL.md +0 -295
- package/skills/literature-review/SKILL.md +0 -263
- package/skills/markdown-mermaid-writing/SKILL.md +0 -322
- package/skills/market-research-reports/SKILL.md +0 -337
- package/skills/markitdown/SKILL.md +0 -264
- package/skills/matchms/SKILL.md +0 -276
- package/skills/matlab/SKILL.md +0 -274
- package/skills/matplotlib/SKILL.md +0 -378
- package/skills/medchem/SKILL.md +0 -321
- package/skills/modal/SKILL.md +0 -468
- package/skills/molecular-dynamics/SKILL.md +0 -458
- package/skills/molfeat/SKILL.md +0 -348
- package/skills/ncats-arax/SKILL.md +0 -178
- package/skills/networkx/SKILL.md +0 -440
- package/skills/neurokit2/SKILL.md +0 -323
- package/skills/neuropixels-analysis/SKILL.md +0 -412
- package/skills/nextflow/SKILL.md +0 -195
- package/skills/omero-integration/SKILL.md +0 -222
- package/skills/onekgpd/SKILL.md +0 -371
- package/skills/ontology-term-resolution/SKILL.md +0 -147
- package/skills/open-notebook/SKILL.md +0 -297
- package/skills/openpiv/SKILL.md +0 -469
- package/skills/opentrons-integration/SKILL.md +0 -322
- package/skills/optimize-for-gpu/SKILL.md +0 -176
- package/skills/owasp-top10/SKILL.md +0 -48
- package/skills/pacsomatic/LICENSE +0 -21
- package/skills/pacsomatic/SKILL.md +0 -150
- package/skills/paper-lookup/SKILL.md +0 -263
- package/skills/paperclip/SKILL.md +0 -413
- package/skills/paperzilla/SKILL.md +0 -159
- package/skills/parallel-web/SKILL.md +0 -128
- package/skills/pathml/SKILL.md +0 -222
- package/skills/pathogen-variant-surveillance/SKILL.md +0 -208
- package/skills/pathway-enrichment/SKILL.md +0 -194
- package/skills/pdf/SKILL.md +0 -322
- package/skills/peer-review/SKILL.md +0 -288
- package/skills/penetration-testing/SKILL.md +0 -31
- package/skills/pennylane/SKILL.md +0 -240
- package/skills/phylogenetics/SKILL.md +0 -409
- package/skills/pi-agent/SKILL.md +0 -83
- package/skills/pkpd-modeling/SKILL.md +0 -381
- package/skills/polars/SKILL.md +0 -393
- package/skills/polars-bio/SKILL.md +0 -379
- package/skills/ponytail/SKILL.md +0 -31
- package/skills/ponytail-audit/SKILL.md +0 -18
- package/skills/pptx/SKILL.md +0 -246
- package/skills/pptx-posters/SKILL.md +0 -258
- package/skills/primekg/SKILL.md +0 -99
- package/skills/protocolsio-integration/SKILL.md +0 -236
- package/skills/pufferlib/SKILL.md +0 -328
- package/skills/pydeseq2/SKILL.md +0 -369
- package/skills/pydicom/SKILL.md +0 -381
- package/skills/pyhealth/SKILL.md +0 -124
- package/skills/pylabrobot/SKILL.md +0 -216
- package/skills/pymatgen/SKILL.md +0 -404
- package/skills/pymc/SKILL.md +0 -310
- package/skills/pymoo/SKILL.md +0 -276
- package/skills/pyopenms/SKILL.md +0 -179
- package/skills/pysam/SKILL.md +0 -330
- package/skills/pytdc/SKILL.md +0 -297
- package/skills/pytorch-lightning/SKILL.md +0 -191
- package/skills/pyzotero/SKILL.md +0 -137
- package/skills/qiskit/SKILL.md +0 -259
- package/skills/qutip/SKILL.md +0 -317
- package/skills/rdkit/SKILL.md +0 -94
- package/skills/relsa-severity-assessment/SKILL.md +0 -354
- package/skills/research-grants/SKILL.md +0 -296
- package/skills/research-grants/references/README.md +0 -287
- package/skills/research-lookup/README.md +0 -106
- package/skills/research-lookup/SKILL.md +0 -338
- package/skills/rowan/SKILL.md +0 -398
- package/skills/scanpy/SKILL.md +0 -303
- package/skills/scholar-evaluation/SKILL.md +0 -296
- package/skills/scientific-brainstorming/SKILL.md +0 -282
- package/skills/scientific-critical-thinking/SKILL.md +0 -180
- package/skills/scientific-schematics/SKILL.md +0 -370
- package/skills/scientific-slides/SKILL.md +0 -379
- package/skills/scientific-visualization/SKILL.md +0 -285
- package/skills/scientific-writing/SKILL.md +0 -356
- package/skills/scikit-bio/SKILL.md +0 -470
- package/skills/scikit-learn/SKILL.md +0 -324
- package/skills/scikit-survival/SKILL.md +0 -313
- package/skills/scvelo/SKILL.md +0 -328
- package/skills/scvi-tools/SKILL.md +0 -201
- package/skills/seaborn/SKILL.md +0 -254
- package/skills/security-auditor/SKILL.md +0 -37
- package/skills/shap/SKILL.md +0 -282
- package/skills/simpy/SKILL.md +0 -283
- package/skills/stable-baselines3/SKILL.md +0 -325
- package/skills/statistical-analysis/SKILL.md +0 -446
- package/skills/statistical-power/SKILL.md +0 -200
- package/skills/statsmodels/SKILL.md +0 -238
- package/skills/sympy/SKILL.md +0 -354
- package/skills/systematic-debugging/SKILL.md +0 -35
- package/skills/tamarind/SKILL.md +0 -285
- package/skills/tdd/SKILL.md +0 -26
- package/skills/tiledbvcf/SKILL.md +0 -456
- package/skills/timesfm-forecasting/SKILL.md +0 -408
- package/skills/timesfm-forecasting/examples/global-temperature/README.md +0 -178
- package/skills/torch-geometric/SKILL.md +0 -458
- package/skills/torchdrug/SKILL.md +0 -241
- package/skills/transformers/SKILL.md +0 -195
- package/skills/treatment-plans/SKILL.md +0 -174
- package/skills/treatment-plans/references/README.md +0 -19
- package/skills/umap-learn/SKILL.md +0 -488
- package/skills/uncertainty-and-units/SKILL.md +0 -384
- package/skills/usfiscaldata/SKILL.md +0 -171
- package/skills/vaex/SKILL.md +0 -204
- package/skills/venue-templates/SKILL.md +0 -269
- package/skills/verification-before-completion/SKILL.md +0 -22
- package/skills/waypoint-bio/SKILL.md +0 -273
- package/skills/what-if-oracle/SKILL.md +0 -184
- package/skills/writing-plans/SKILL.md +0 -15
- package/skills/xlsx/SKILL.md +0 -110
- package/skills/zarr-python/SKILL.md +0 -241
package/dist/cli.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
4
|
// src/cli/index.ts
|
|
5
|
-
import { resolve as
|
|
6
|
-
import { existsSync as
|
|
5
|
+
import { resolve as resolve22 } from "path";
|
|
6
|
+
import { existsSync as existsSync24 } from "fs";
|
|
7
7
|
import { createInterface } from "readline";
|
|
8
8
|
|
|
9
9
|
// src/auth/store.ts
|
|
@@ -5269,7 +5269,6 @@ class SessionPersistenceManager {
|
|
|
5269
5269
|
// src/skills/loader.ts
|
|
5270
5270
|
import { existsSync as existsSync16, readdirSync as readdirSync6, readFileSync as readFileSync9 } from "fs";
|
|
5271
5271
|
import { resolve as resolve13, join as join8 } from "path";
|
|
5272
|
-
import { homedir as homedir3 } from "os";
|
|
5273
5272
|
var __dirname = "/home/runner/work/agent-cli/agent-cli/src/skills";
|
|
5274
5273
|
|
|
5275
5274
|
class SkillsLoader {
|
|
@@ -5345,7 +5344,7 @@ class SkillsLoader {
|
|
|
5345
5344
|
}
|
|
5346
5345
|
}
|
|
5347
5346
|
if (this.includeGlobal) {
|
|
5348
|
-
roots.push(getGlobalSkillsDir()
|
|
5347
|
+
roots.push(getGlobalSkillsDir());
|
|
5349
5348
|
}
|
|
5350
5349
|
roots.push(...this.customRoots.map((r) => resolve13(r)));
|
|
5351
5350
|
return roots.filter((r) => existsSync16(r));
|
|
@@ -5491,9 +5490,77 @@ When tackling complex specialized tasks that match any of these skills, autonomo
|
|
|
5491
5490
|
}
|
|
5492
5491
|
}
|
|
5493
5492
|
|
|
5493
|
+
// src/skills/installer.ts
|
|
5494
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync10, writeFileSync as writeFileSync5, rmSync as rmSync2 } from "fs";
|
|
5495
|
+
import { resolve as resolve14, join as join9 } from "path";
|
|
5496
|
+
async function installSkill(skillName, options) {
|
|
5497
|
+
const cleanName = skillName.trim().toLowerCase().replace(/^@/, "");
|
|
5498
|
+
if (!cleanName) {
|
|
5499
|
+
throw new Error("Skill name cannot be empty.");
|
|
5500
|
+
}
|
|
5501
|
+
const credStore = new CredentialsStore;
|
|
5502
|
+
const creds = credStore.load();
|
|
5503
|
+
let backend = (options.backendUrl || process.env.PIKAA_BACKEND_URL || process.env.GROUPY_BACKEND_URL || creds?.baseUrl || "https://api.groupy-hub.store").replace(/\/+$/, "");
|
|
5504
|
+
if (backend.endsWith("/v1")) {
|
|
5505
|
+
backend = backend.slice(0, -3).replace(/\/+$/, "");
|
|
5506
|
+
}
|
|
5507
|
+
const endpoint = `${backend}/api/skills/${encodeURIComponent(cleanName)}`;
|
|
5508
|
+
let resp;
|
|
5509
|
+
try {
|
|
5510
|
+
resp = await fetch(endpoint, {
|
|
5511
|
+
headers: creds?.accessToken ? { Authorization: `Bearer ${creds.accessToken}` } : {}
|
|
5512
|
+
});
|
|
5513
|
+
} catch (netErr) {
|
|
5514
|
+
throw new Error(`Failed to connect to backend at ${backend}: ${netErr.message}`);
|
|
5515
|
+
}
|
|
5516
|
+
if (!resp.ok) {
|
|
5517
|
+
if (resp.status === 404) {
|
|
5518
|
+
throw new Error(`Skill '${cleanName}' not found in catalog (${endpoint}).`);
|
|
5519
|
+
}
|
|
5520
|
+
const errText = await resp.text();
|
|
5521
|
+
throw new Error(`Backend error (${resp.status}): ${errText}`);
|
|
5522
|
+
}
|
|
5523
|
+
const skillData = await resp.json();
|
|
5524
|
+
if (!skillData.content) {
|
|
5525
|
+
throw new Error(`Skill '${cleanName}' does not contain markdown content.`);
|
|
5526
|
+
}
|
|
5527
|
+
const scope = options.global ? "global" : "workspace";
|
|
5528
|
+
const targetDir = options.global ? resolve14(getGlobalSkillsDir(), cleanName) : resolve14(options.cwd, ".agents", "skills", cleanName);
|
|
5529
|
+
mkdirSync10(targetDir, { recursive: true });
|
|
5530
|
+
const targetFile = join9(targetDir, "SKILL.md");
|
|
5531
|
+
let fileContent = skillData.content;
|
|
5532
|
+
if (!fileContent.startsWith("---")) {
|
|
5533
|
+
const desc = skillData.description ? `description: "${skillData.description.replace(/"/g, "\\\"")}"
|
|
5534
|
+
` : "";
|
|
5535
|
+
fileContent = `---
|
|
5536
|
+
name: ${cleanName}
|
|
5537
|
+
${desc}---
|
|
5538
|
+
|
|
5539
|
+
${fileContent}`;
|
|
5540
|
+
}
|
|
5541
|
+
writeFileSync5(targetFile, fileContent, "utf-8");
|
|
5542
|
+
return {
|
|
5543
|
+
success: true,
|
|
5544
|
+
skillName: cleanName,
|
|
5545
|
+
title: skillData.title || cleanName,
|
|
5546
|
+
targetPath: targetFile,
|
|
5547
|
+
scope,
|
|
5548
|
+
message: `Installed skill '${skillData.title || cleanName}' (@${cleanName}) into ${scope} at ${targetFile}`
|
|
5549
|
+
};
|
|
5550
|
+
}
|
|
5551
|
+
function removeSkill(skillName, options) {
|
|
5552
|
+
const cleanName = skillName.trim().toLowerCase().replace(/^@/, "");
|
|
5553
|
+
const targetDir = options.global ? resolve14(getGlobalSkillsDir(), cleanName) : resolve14(options.cwd, ".agents", "skills", cleanName);
|
|
5554
|
+
if (!existsSync17(targetDir)) {
|
|
5555
|
+
return { success: false, targetDir, removed: false };
|
|
5556
|
+
}
|
|
5557
|
+
rmSync2(targetDir, { recursive: true, force: true });
|
|
5558
|
+
return { success: true, targetDir, removed: true };
|
|
5559
|
+
}
|
|
5560
|
+
|
|
5494
5561
|
// src/memories/store.ts
|
|
5495
|
-
import { existsSync as
|
|
5496
|
-
import { resolve as
|
|
5562
|
+
import { existsSync as existsSync18, readFileSync as readFileSync10, writeFileSync as writeFileSync6, mkdirSync as mkdirSync11, readdirSync as readdirSync7 } from "fs";
|
|
5563
|
+
import { resolve as resolve15, join as join10, basename, dirname as dirname8 } from "path";
|
|
5497
5564
|
import { createHash } from "crypto";
|
|
5498
5565
|
class MemoryStore {
|
|
5499
5566
|
globalPath;
|
|
@@ -5503,14 +5570,14 @@ class MemoryStore {
|
|
|
5503
5570
|
this.customWorkspacePath = options.workspacePath;
|
|
5504
5571
|
}
|
|
5505
5572
|
findProjectRoot(cwd) {
|
|
5506
|
-
let current =
|
|
5573
|
+
let current = resolve15(cwd);
|
|
5507
5574
|
while (true) {
|
|
5508
|
-
if (
|
|
5575
|
+
if (existsSync18(join10(current, ".git"))) {
|
|
5509
5576
|
return current;
|
|
5510
5577
|
}
|
|
5511
5578
|
const parent = dirname8(current);
|
|
5512
5579
|
if (parent === current) {
|
|
5513
|
-
return
|
|
5580
|
+
return resolve15(cwd);
|
|
5514
5581
|
}
|
|
5515
5582
|
current = parent;
|
|
5516
5583
|
}
|
|
@@ -5518,30 +5585,30 @@ class MemoryStore {
|
|
|
5518
5585
|
getProjectSlug(cwd) {
|
|
5519
5586
|
const root = this.findProjectRoot(cwd);
|
|
5520
5587
|
const folderName = basename(root).toLowerCase().replace(/[^a-z0-9_-]/g, "-") || "project";
|
|
5521
|
-
const hash = createHash("sha256").update(
|
|
5588
|
+
const hash = createHash("sha256").update(resolve15(root)).digest("hex").slice(0, 6);
|
|
5522
5589
|
return `${folderName}-${hash}`;
|
|
5523
5590
|
}
|
|
5524
5591
|
getProjectMemoryDir(cwd) {
|
|
5525
5592
|
if (this.customWorkspacePath) {
|
|
5526
|
-
const dir2 =
|
|
5527
|
-
if (!
|
|
5593
|
+
const dir2 = resolve15(this.customWorkspacePath);
|
|
5594
|
+
if (!existsSync18(dir2)) {
|
|
5528
5595
|
try {
|
|
5529
|
-
|
|
5596
|
+
mkdirSync11(dir2, { recursive: true });
|
|
5530
5597
|
} catch {}
|
|
5531
5598
|
}
|
|
5532
5599
|
return dir2;
|
|
5533
5600
|
}
|
|
5534
5601
|
const slug = this.getProjectSlug(cwd);
|
|
5535
|
-
const dir =
|
|
5536
|
-
if (!
|
|
5602
|
+
const dir = join10(getProjectsDir(), slug, "memory");
|
|
5603
|
+
if (!existsSync18(dir)) {
|
|
5537
5604
|
try {
|
|
5538
|
-
|
|
5605
|
+
mkdirSync11(dir, { recursive: true });
|
|
5539
5606
|
} catch {}
|
|
5540
5607
|
}
|
|
5541
5608
|
return dir;
|
|
5542
5609
|
}
|
|
5543
5610
|
getMemoryIndexPath(cwd) {
|
|
5544
|
-
return
|
|
5611
|
+
return join10(this.getProjectMemoryDir(cwd), "MEMORY.md");
|
|
5545
5612
|
}
|
|
5546
5613
|
normalizeCategory(raw) {
|
|
5547
5614
|
const cat = raw.toLowerCase().trim();
|
|
@@ -5560,7 +5627,7 @@ class MemoryStore {
|
|
|
5560
5627
|
const sanitizedName = params.name.toLowerCase().trim().replace(/[^a-z0-9_-]/g, "_").replace(/^_+|_+$/g, "") || `note_${Date.now()}`;
|
|
5561
5628
|
const memoryDir = this.getProjectMemoryDir(params.cwd);
|
|
5562
5629
|
const fileName = `${type}_${sanitizedName}.md`;
|
|
5563
|
-
const filePath =
|
|
5630
|
+
const filePath = join10(memoryDir, fileName);
|
|
5564
5631
|
const nowIso = new Date().toISOString();
|
|
5565
5632
|
const cleanContent = params.content.trim();
|
|
5566
5633
|
const desc = (params.description || cleanContent.split(`
|
|
@@ -5579,7 +5646,7 @@ class MemoryStore {
|
|
|
5579
5646
|
""
|
|
5580
5647
|
].join(`
|
|
5581
5648
|
`);
|
|
5582
|
-
|
|
5649
|
+
writeFileSync6(filePath, frontmatter, "utf8");
|
|
5583
5650
|
this.syncMemoryIndex(params.cwd);
|
|
5584
5651
|
return {
|
|
5585
5652
|
id: `mem_${sanitizedName}`,
|
|
@@ -5595,17 +5662,17 @@ class MemoryStore {
|
|
|
5595
5662
|
}
|
|
5596
5663
|
readTopicMemory(topicNameOrFile, cwd) {
|
|
5597
5664
|
const memoryDir = this.getProjectMemoryDir(cwd);
|
|
5598
|
-
let targetPath =
|
|
5599
|
-
if (!
|
|
5665
|
+
let targetPath = join10(memoryDir, topicNameOrFile);
|
|
5666
|
+
if (!existsSync18(targetPath)) {
|
|
5600
5667
|
if (!topicNameOrFile.endsWith(".md")) {
|
|
5601
|
-
targetPath =
|
|
5668
|
+
targetPath = join10(memoryDir, `${topicNameOrFile}.md`);
|
|
5602
5669
|
}
|
|
5603
5670
|
}
|
|
5604
|
-
if (!
|
|
5671
|
+
if (!existsSync18(targetPath)) {
|
|
5605
5672
|
const files = readdirSync7(memoryDir);
|
|
5606
5673
|
const match = files.find((f) => f.includes(topicNameOrFile));
|
|
5607
5674
|
if (match) {
|
|
5608
|
-
targetPath =
|
|
5675
|
+
targetPath = join10(memoryDir, match);
|
|
5609
5676
|
} else {
|
|
5610
5677
|
return null;
|
|
5611
5678
|
}
|
|
@@ -5666,12 +5733,12 @@ class MemoryStore {
|
|
|
5666
5733
|
}
|
|
5667
5734
|
syncMemoryIndex(cwd) {
|
|
5668
5735
|
const memoryDir = this.getProjectMemoryDir(cwd);
|
|
5669
|
-
const indexPath =
|
|
5670
|
-
const files =
|
|
5736
|
+
const indexPath = join10(memoryDir, "MEMORY.md");
|
|
5737
|
+
const files = existsSync18(memoryDir) ? readdirSync7(memoryDir).filter((f) => f.endsWith(".md") && f !== "MEMORY.md") : [];
|
|
5671
5738
|
const items = [];
|
|
5672
5739
|
for (const f of files) {
|
|
5673
5740
|
try {
|
|
5674
|
-
const full =
|
|
5741
|
+
const full = join10(memoryDir, f);
|
|
5675
5742
|
const parsed = this.parseTopicFile(readFileSync10(full, "utf8"), full);
|
|
5676
5743
|
items.push({
|
|
5677
5744
|
type: parsed.type,
|
|
@@ -5692,13 +5759,13 @@ class MemoryStore {
|
|
|
5692
5759
|
indexLines.push(`- [${item.type}] **${item.name}**: ${item.desc} (topic: ${item.file})`);
|
|
5693
5760
|
}
|
|
5694
5761
|
const boundedLines = indexLines.slice(0, 200);
|
|
5695
|
-
|
|
5762
|
+
writeFileSync6(indexPath, boundedLines.join(`
|
|
5696
5763
|
`) + `
|
|
5697
5764
|
`, "utf8");
|
|
5698
5765
|
}
|
|
5699
5766
|
loadMemoryIndex(cwd) {
|
|
5700
5767
|
const indexPath = this.getMemoryIndexPath(cwd);
|
|
5701
|
-
if (!
|
|
5768
|
+
if (!existsSync18(indexPath))
|
|
5702
5769
|
return "";
|
|
5703
5770
|
try {
|
|
5704
5771
|
const raw = readFileSync10(indexPath, "utf8");
|
|
@@ -5714,13 +5781,13 @@ class MemoryStore {
|
|
|
5714
5781
|
}
|
|
5715
5782
|
listProjectMemories(cwd) {
|
|
5716
5783
|
const memoryDir = this.getProjectMemoryDir(cwd);
|
|
5717
|
-
if (!
|
|
5784
|
+
if (!existsSync18(memoryDir))
|
|
5718
5785
|
return [];
|
|
5719
5786
|
const files = readdirSync7(memoryDir).filter((f) => f.endsWith(".md") && f !== "MEMORY.md");
|
|
5720
5787
|
const list = [];
|
|
5721
5788
|
for (const f of files) {
|
|
5722
5789
|
try {
|
|
5723
|
-
const full =
|
|
5790
|
+
const full = join10(memoryDir, f);
|
|
5724
5791
|
list.push(this.parseTopicFile(readFileSync10(full, "utf8"), full));
|
|
5725
5792
|
} catch {}
|
|
5726
5793
|
}
|
|
@@ -5772,11 +5839,11 @@ class MemoryStore {
|
|
|
5772
5839
|
}
|
|
5773
5840
|
|
|
5774
5841
|
// src/worktree/manager.ts
|
|
5775
|
-
import { resolve as
|
|
5776
|
-
import { existsSync as
|
|
5842
|
+
import { resolve as resolve17, join as join11 } from "path";
|
|
5843
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync12, writeFileSync as writeFileSync7, readFileSync as readFileSync11 } from "fs";
|
|
5777
5844
|
|
|
5778
5845
|
// src/worktree/git.ts
|
|
5779
|
-
import { resolve as
|
|
5846
|
+
import { resolve as resolve16 } from "path";
|
|
5780
5847
|
var NON_INHERITABLE_GIT_ENV = [
|
|
5781
5848
|
"GIT_DIR",
|
|
5782
5849
|
"GIT_WORK_TREE",
|
|
@@ -5820,13 +5887,13 @@ async function getRepoRoot(cwd) {
|
|
|
5820
5887
|
const res = await runGit(cwd, ["rev-parse", "--show-toplevel"]);
|
|
5821
5888
|
if (res.exitCode !== 0 || !res.stdout)
|
|
5822
5889
|
return null;
|
|
5823
|
-
return
|
|
5890
|
+
return resolve16(res.stdout);
|
|
5824
5891
|
}
|
|
5825
5892
|
async function getMainRepoRoot(cwd) {
|
|
5826
5893
|
const res = await runGit(cwd, ["rev-parse", "--path-format=absolute", "--git-common-dir"]);
|
|
5827
5894
|
if (res.exitCode === 0 && res.stdout) {
|
|
5828
|
-
const commonDir =
|
|
5829
|
-
return
|
|
5895
|
+
const commonDir = resolve16(cwd, res.stdout);
|
|
5896
|
+
return resolve16(commonDir, "..");
|
|
5830
5897
|
}
|
|
5831
5898
|
return getRepoRoot(cwd);
|
|
5832
5899
|
}
|
|
@@ -5856,7 +5923,7 @@ async function listWorktreesGit(repoRoot) {
|
|
|
5856
5923
|
let isLocked = false;
|
|
5857
5924
|
for (const line of lines) {
|
|
5858
5925
|
if (line.startsWith("worktree ")) {
|
|
5859
|
-
path =
|
|
5926
|
+
path = resolve16(line.slice(9).trim());
|
|
5860
5927
|
} else if (line.startsWith("HEAD ")) {
|
|
5861
5928
|
commitHash = line.slice(5).trim();
|
|
5862
5929
|
} else if (line.startsWith("branch ")) {
|
|
@@ -5921,19 +5988,19 @@ class WorktreeManager {
|
|
|
5921
5988
|
}
|
|
5922
5989
|
const taskId = `task_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
|
5923
5990
|
const branchName = options.branch || `groupy/${taskId}`;
|
|
5924
|
-
const targetDir = options.worktreePath || (this.baseStorageDir ?
|
|
5925
|
-
const worktreeParent =
|
|
5926
|
-
if (!
|
|
5927
|
-
|
|
5991
|
+
const targetDir = options.worktreePath || (this.baseStorageDir ? resolve17(this.baseStorageDir, branchName.replace(/\//g, "_")) : resolve17(repoRoot, ".groupy", "worktrees", branchName.replace(/\//g, "_")));
|
|
5992
|
+
const worktreeParent = resolve17(targetDir, "..");
|
|
5993
|
+
if (!existsSync19(worktreeParent)) {
|
|
5994
|
+
mkdirSync12(worktreeParent, { recursive: true });
|
|
5928
5995
|
}
|
|
5929
5996
|
const baseBranch = options.baseBranch || await getCurrentBranch(repoRoot);
|
|
5930
5997
|
const result = await createWorktreeGit(repoRoot, targetDir, branchName, baseBranch);
|
|
5931
5998
|
if (!result.success) {
|
|
5932
5999
|
throw new Error(`Failed to create git worktree: ${result.error}`);
|
|
5933
6000
|
}
|
|
5934
|
-
const metaPath =
|
|
6001
|
+
const metaPath = join11(targetDir, "groupy-thread.json");
|
|
5935
6002
|
try {
|
|
5936
|
-
|
|
6003
|
+
writeFileSync7(metaPath, JSON.stringify({
|
|
5937
6004
|
version: 1,
|
|
5938
6005
|
ownerThreadId: options.threadId || null,
|
|
5939
6006
|
branch: branchName,
|
|
@@ -5942,7 +6009,7 @@ class WorktreeManager {
|
|
|
5942
6009
|
}, null, 2), "utf8");
|
|
5943
6010
|
} catch {}
|
|
5944
6011
|
const worktrees = await listWorktreesGit(repoRoot);
|
|
5945
|
-
const created = worktrees.find((w) =>
|
|
6012
|
+
const created = worktrees.find((w) => resolve17(w.path) === resolve17(targetDir));
|
|
5946
6013
|
return created || {
|
|
5947
6014
|
path: targetDir,
|
|
5948
6015
|
branch: branchName,
|
|
@@ -5957,8 +6024,8 @@ class WorktreeManager {
|
|
|
5957
6024
|
return [];
|
|
5958
6025
|
const worktrees = await listWorktreesGit(repoRoot);
|
|
5959
6026
|
return worktrees.map((wt) => {
|
|
5960
|
-
const metaPath =
|
|
5961
|
-
if (
|
|
6027
|
+
const metaPath = join11(wt.path, "groupy-thread.json");
|
|
6028
|
+
if (existsSync19(metaPath)) {
|
|
5962
6029
|
try {
|
|
5963
6030
|
const raw = JSON.parse(readFileSync11(metaPath, "utf8"));
|
|
5964
6031
|
return { ...wt, threadId: raw.ownerThreadId || raw.threadId };
|
|
@@ -5968,7 +6035,7 @@ class WorktreeManager {
|
|
|
5968
6035
|
});
|
|
5969
6036
|
}
|
|
5970
6037
|
async mergeWorktree(worktreePath, options = {}) {
|
|
5971
|
-
const resolvedPath =
|
|
6038
|
+
const resolvedPath = resolve17(worktreePath);
|
|
5972
6039
|
const repoRoot = await getMainRepoRoot(resolvedPath);
|
|
5973
6040
|
if (!repoRoot) {
|
|
5974
6041
|
return { success: false, message: "Worktree path is not a valid git repository." };
|
|
@@ -6005,7 +6072,7 @@ class WorktreeManager {
|
|
|
6005
6072
|
};
|
|
6006
6073
|
}
|
|
6007
6074
|
async removeWorktree(worktreePath, deleteBranch = false) {
|
|
6008
|
-
const resolvedPath =
|
|
6075
|
+
const resolvedPath = resolve17(worktreePath);
|
|
6009
6076
|
const repoRoot = await getMainRepoRoot(resolvedPath);
|
|
6010
6077
|
if (!repoRoot)
|
|
6011
6078
|
return false;
|
|
@@ -6086,8 +6153,8 @@ class AuthClient {
|
|
|
6086
6153
|
const authUrl = `${backendUrl}/api/auth/authorize?response_type=code&client_id=groupy-cli&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${encodeURIComponent(codeChallenge)}&code_challenge_method=S256&state=${state}&direct=1`;
|
|
6087
6154
|
let serverResolve;
|
|
6088
6155
|
let serverReject;
|
|
6089
|
-
const codePromise = new Promise((
|
|
6090
|
-
serverResolve =
|
|
6156
|
+
const codePromise = new Promise((resolve18, reject) => {
|
|
6157
|
+
serverResolve = resolve18;
|
|
6091
6158
|
serverReject = reject;
|
|
6092
6159
|
});
|
|
6093
6160
|
if (options.openBrowser !== false) {
|
|
@@ -6656,7 +6723,7 @@ function parsePatch(oldSrc, newSrc, contextLines = 3) {
|
|
|
6656
6723
|
// package.json
|
|
6657
6724
|
var package_default = {
|
|
6658
6725
|
name: "@pikaa-ai/pikaa",
|
|
6659
|
-
version: "0.3.
|
|
6726
|
+
version: "0.3.24",
|
|
6660
6727
|
description: "PIKAA CLI - AI coding agent that runs locally in your terminal.",
|
|
6661
6728
|
main: "./dist/index.js",
|
|
6662
6729
|
module: "./dist/index.js",
|
|
@@ -6672,7 +6739,6 @@ var package_default = {
|
|
|
6672
6739
|
"bin",
|
|
6673
6740
|
"templates",
|
|
6674
6741
|
"assets",
|
|
6675
|
-
"skills/**/SKILL.md",
|
|
6676
6742
|
"README.md",
|
|
6677
6743
|
"LICENSE"
|
|
6678
6744
|
],
|
|
@@ -6734,7 +6800,7 @@ function getCliVersion(options = {}) {
|
|
|
6734
6800
|
}
|
|
6735
6801
|
|
|
6736
6802
|
// src/cli/ui/animation/banner-animation.ts
|
|
6737
|
-
import { homedir as
|
|
6803
|
+
import { homedir as homedir3 } from "os";
|
|
6738
6804
|
import { execSync } from "child_process";
|
|
6739
6805
|
var ROSE = "\x1B[38;2;205;105;74m";
|
|
6740
6806
|
var ROSE_DIM = "\x1B[38;2;120;60;45m";
|
|
@@ -6744,7 +6810,7 @@ var BOLD = "\x1B[1m";
|
|
|
6744
6810
|
var ITALIC = "\x1B[3m";
|
|
6745
6811
|
var RESET = "\x1B[0m";
|
|
6746
6812
|
function shortenPath(cwd) {
|
|
6747
|
-
const home =
|
|
6813
|
+
const home = homedir3();
|
|
6748
6814
|
if (cwd.startsWith(home)) {
|
|
6749
6815
|
return `~${cwd.slice(home.length).replace(/\\/g, "/")}`;
|
|
6750
6816
|
}
|
|
@@ -7302,15 +7368,15 @@ class InteractiveLineEditor {
|
|
|
7302
7368
|
}
|
|
7303
7369
|
async readLine() {
|
|
7304
7370
|
if (!process.stdin.isTTY) {
|
|
7305
|
-
return new Promise((
|
|
7371
|
+
return new Promise((resolve18) => {
|
|
7306
7372
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
7307
7373
|
rl.question(this.promptSymbol, (answer) => {
|
|
7308
7374
|
rl.close();
|
|
7309
|
-
|
|
7375
|
+
resolve18(answer);
|
|
7310
7376
|
});
|
|
7311
7377
|
});
|
|
7312
7378
|
}
|
|
7313
|
-
return new Promise((
|
|
7379
|
+
return new Promise((resolve18) => {
|
|
7314
7380
|
let buffer = "";
|
|
7315
7381
|
let cursor = 0;
|
|
7316
7382
|
let selectedIndex = 0;
|
|
@@ -7516,7 +7582,7 @@ class InteractiveLineEditor {
|
|
|
7516
7582
|
process.stdout.write(`
|
|
7517
7583
|
`);
|
|
7518
7584
|
}
|
|
7519
|
-
|
|
7585
|
+
resolve18(result);
|
|
7520
7586
|
};
|
|
7521
7587
|
const onKeypress = (_str, key) => {
|
|
7522
7588
|
if (!key)
|
|
@@ -7704,7 +7770,7 @@ async function promptChoice(config) {
|
|
|
7704
7770
|
const def = choices[defaultIndex] || choices[0];
|
|
7705
7771
|
return def ? def.value : "";
|
|
7706
7772
|
}
|
|
7707
|
-
return new Promise((
|
|
7773
|
+
return new Promise((resolve18) => {
|
|
7708
7774
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
7709
7775
|
const promptText = ` ${message} (${choices.map((c3) => `[${c3.key}] ${c3.label}`).join(", ")}): `;
|
|
7710
7776
|
rl.question(promptText, (answer) => {
|
|
@@ -7712,15 +7778,15 @@ async function promptChoice(config) {
|
|
|
7712
7778
|
const trimmed = answer.trim().toLowerCase();
|
|
7713
7779
|
const match = choices.find((c3) => c3.key.toLowerCase() === trimmed);
|
|
7714
7780
|
if (match) {
|
|
7715
|
-
|
|
7781
|
+
resolve18(match.value);
|
|
7716
7782
|
} else {
|
|
7717
7783
|
const def = choices[defaultIndex] || choices[0];
|
|
7718
|
-
|
|
7784
|
+
resolve18(def ? def.value : "");
|
|
7719
7785
|
}
|
|
7720
7786
|
});
|
|
7721
7787
|
});
|
|
7722
7788
|
}
|
|
7723
|
-
return new Promise((
|
|
7789
|
+
return new Promise((resolve18) => {
|
|
7724
7790
|
let selectedIndex = defaultIndex;
|
|
7725
7791
|
if (selectedIndex < 0 || selectedIndex >= choices.length)
|
|
7726
7792
|
selectedIndex = 0;
|
|
@@ -7752,7 +7818,7 @@ async function promptChoice(config) {
|
|
|
7752
7818
|
} catch {}
|
|
7753
7819
|
process.stdout.write(`\r\x1B[1A\r\x1B[2K ${style.bold(message)} ${style.cyan(`[${confirmedChoice.key}] ${confirmedChoice.label}`)}
|
|
7754
7820
|
\r\x1B[2K`);
|
|
7755
|
-
|
|
7821
|
+
resolve18(confirmedChoice.value);
|
|
7756
7822
|
};
|
|
7757
7823
|
const onKeypress = (_str, key) => {
|
|
7758
7824
|
if (!key)
|
|
@@ -7818,7 +7884,7 @@ async function promptToolApproval(params) {
|
|
|
7818
7884
|
renderCard(1);
|
|
7819
7885
|
return "yes";
|
|
7820
7886
|
}
|
|
7821
|
-
return new Promise((
|
|
7887
|
+
return new Promise((resolve18) => {
|
|
7822
7888
|
let selectedIndex = 1;
|
|
7823
7889
|
const wasRaw = process.stdin.isRaw;
|
|
7824
7890
|
try {
|
|
@@ -7838,7 +7904,7 @@ async function promptToolApproval(params) {
|
|
|
7838
7904
|
process.stdin.setRawMode(wasRaw ?? false);
|
|
7839
7905
|
} catch {}
|
|
7840
7906
|
console.log();
|
|
7841
|
-
|
|
7907
|
+
resolve18(val);
|
|
7842
7908
|
};
|
|
7843
7909
|
const onKeypress = (_str, key) => {
|
|
7844
7910
|
if (!key)
|
|
@@ -7921,7 +7987,7 @@ async function promptUserQuestion(params) {
|
|
|
7921
7987
|
if (!process.stdin.isTTY || false || !process.stdin.readable) {
|
|
7922
7988
|
return options[0] || "yes";
|
|
7923
7989
|
}
|
|
7924
|
-
return new Promise((
|
|
7990
|
+
return new Promise((resolve18) => {
|
|
7925
7991
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
7926
7992
|
const promptLabel = options.length > 0 ? `Select [1-${options.length}] or type custom response: ` : `Your response: `;
|
|
7927
7993
|
rl.question(` ${style.bold(promptLabel)}`, (answer) => {
|
|
@@ -7931,7 +7997,7 @@ async function promptUserQuestion(params) {
|
|
|
7931
7997
|
const fallback = options[0] || "";
|
|
7932
7998
|
console.log(style.dim(` \u21B3 Default: ${fallback || "(empty)"}
|
|
7933
7999
|
`));
|
|
7934
|
-
|
|
8000
|
+
resolve18(fallback);
|
|
7935
8001
|
return;
|
|
7936
8002
|
}
|
|
7937
8003
|
const num = parseInt(trimmed, 10);
|
|
@@ -7939,26 +8005,26 @@ async function promptUserQuestion(params) {
|
|
|
7939
8005
|
const picked = options[num - 1];
|
|
7940
8006
|
console.log(style.green(` \u2714 Selected: ${picked}
|
|
7941
8007
|
`));
|
|
7942
|
-
|
|
8008
|
+
resolve18(picked);
|
|
7943
8009
|
return;
|
|
7944
8010
|
}
|
|
7945
8011
|
if (options.length === 2) {
|
|
7946
8012
|
if (/^(y|yes)$/i.test(trimmed)) {
|
|
7947
8013
|
console.log(style.green(` \u2714 Selected: ${options[0]}
|
|
7948
8014
|
`));
|
|
7949
|
-
|
|
8015
|
+
resolve18(options[0]);
|
|
7950
8016
|
return;
|
|
7951
8017
|
}
|
|
7952
8018
|
if (/^(n|no)$/i.test(trimmed)) {
|
|
7953
8019
|
console.log(style.green(` \u2714 Selected: ${options[1]}
|
|
7954
8020
|
`));
|
|
7955
|
-
|
|
8021
|
+
resolve18(options[1]);
|
|
7956
8022
|
return;
|
|
7957
8023
|
}
|
|
7958
8024
|
}
|
|
7959
8025
|
console.log(style.green(` \u2714 Answer: ${trimmed}
|
|
7960
8026
|
`));
|
|
7961
|
-
|
|
8027
|
+
resolve18(trimmed);
|
|
7962
8028
|
});
|
|
7963
8029
|
});
|
|
7964
8030
|
}
|
|
@@ -7987,7 +8053,7 @@ async function promptInteractiveList(config) {
|
|
|
7987
8053
|
`);
|
|
7988
8054
|
return { selectedIndex: -1, action: "close" };
|
|
7989
8055
|
}
|
|
7990
|
-
return new Promise((
|
|
8056
|
+
return new Promise((resolve18) => {
|
|
7991
8057
|
let selectedIndex = Math.max(0, Math.min(defaultIndex, items.length - 1));
|
|
7992
8058
|
let scrollTop = 0;
|
|
7993
8059
|
let renderedLines = 0;
|
|
@@ -8082,7 +8148,7 @@ async function promptInteractiveList(config) {
|
|
|
8082
8148
|
try {
|
|
8083
8149
|
process.stdin.setRawMode(wasRaw ?? false);
|
|
8084
8150
|
} catch {}
|
|
8085
|
-
|
|
8151
|
+
resolve18(res);
|
|
8086
8152
|
};
|
|
8087
8153
|
const onKeypress = async (_str, key) => {
|
|
8088
8154
|
if (!key)
|
|
@@ -8153,8 +8219,8 @@ async function promptInteractiveList(config) {
|
|
|
8153
8219
|
}
|
|
8154
8220
|
|
|
8155
8221
|
// src/security/scanner.ts
|
|
8156
|
-
import { existsSync as
|
|
8157
|
-
import { join as
|
|
8222
|
+
import { existsSync as existsSync20, readdirSync as readdirSync8, readFileSync as readFileSync12, statSync as statSync5 } from "fs";
|
|
8223
|
+
import { join as join12, relative as relative2, resolve as resolve18 } from "path";
|
|
8158
8224
|
var SECURITY_RULES = [
|
|
8159
8225
|
{
|
|
8160
8226
|
id: "SEC-001",
|
|
@@ -8286,13 +8352,13 @@ var IGNORED_FILES = new Set([
|
|
|
8286
8352
|
]);
|
|
8287
8353
|
async function runSecurityScan(targetDir, options = {}) {
|
|
8288
8354
|
const startTime = performance.now();
|
|
8289
|
-
const root =
|
|
8355
|
+
const root = resolve18(targetDir);
|
|
8290
8356
|
const isDirectTestDir = targetDir.includes("test") || Boolean(options.includeTests);
|
|
8291
8357
|
const maxFiles = options.maxFiles || 2000;
|
|
8292
8358
|
const findings = [];
|
|
8293
8359
|
let scannedCount = 0;
|
|
8294
8360
|
function walk(current) {
|
|
8295
|
-
if (scannedCount >= maxFiles || !
|
|
8361
|
+
if (scannedCount >= maxFiles || !existsSync20(current))
|
|
8296
8362
|
return;
|
|
8297
8363
|
let entries;
|
|
8298
8364
|
try {
|
|
@@ -8303,7 +8369,7 @@ async function runSecurityScan(targetDir, options = {}) {
|
|
|
8303
8369
|
for (const entry of entries) {
|
|
8304
8370
|
if (scannedCount >= maxFiles)
|
|
8305
8371
|
break;
|
|
8306
|
-
const fullPath =
|
|
8372
|
+
const fullPath = join12(current, entry);
|
|
8307
8373
|
let stat;
|
|
8308
8374
|
try {
|
|
8309
8375
|
stat = statSync5(fullPath);
|
|
@@ -8381,38 +8447,38 @@ async function runSecurityScan(targetDir, options = {}) {
|
|
|
8381
8447
|
}
|
|
8382
8448
|
|
|
8383
8449
|
// src/mcp/servers/chrome-devtools/index.ts
|
|
8384
|
-
import { resolve as
|
|
8450
|
+
import { resolve as resolve19 } from "path";
|
|
8385
8451
|
|
|
8386
8452
|
// src/mcp/servers/chrome-devtools/server.ts
|
|
8387
8453
|
if (false) {}
|
|
8388
8454
|
|
|
8389
8455
|
// src/mcp/servers/chrome-devtools/index.ts
|
|
8390
8456
|
var __dirname = "/home/runner/work/agent-cli/agent-cli/src/mcp/servers/chrome-devtools";
|
|
8391
|
-
var CHROME_DEVTOOLS_MCP_SERVER_PATH =
|
|
8457
|
+
var CHROME_DEVTOOLS_MCP_SERVER_PATH = resolve19(__dirname, "server.ts");
|
|
8392
8458
|
|
|
8393
8459
|
// src/mcp/servers/web-search/index.ts
|
|
8394
|
-
import { resolve as
|
|
8460
|
+
import { resolve as resolve20 } from "path";
|
|
8395
8461
|
|
|
8396
8462
|
// src/mcp/servers/web-search/server.ts
|
|
8397
8463
|
if (false) {}
|
|
8398
8464
|
|
|
8399
8465
|
// src/mcp/servers/web-search/index.ts
|
|
8400
8466
|
var __dirname = "/home/runner/work/agent-cli/agent-cli/src/mcp/servers/web-search";
|
|
8401
|
-
var WEB_SEARCH_MCP_SERVER_PATH =
|
|
8467
|
+
var WEB_SEARCH_MCP_SERVER_PATH = resolve20(__dirname, "server.ts");
|
|
8402
8468
|
|
|
8403
8469
|
// src/mcp/servers/sqlite/index.ts
|
|
8404
|
-
import { resolve as
|
|
8470
|
+
import { resolve as resolve21 } from "path";
|
|
8405
8471
|
|
|
8406
8472
|
// src/mcp/servers/sqlite/server.ts
|
|
8407
8473
|
if (false) {}
|
|
8408
8474
|
|
|
8409
8475
|
// src/mcp/servers/sqlite/index.ts
|
|
8410
8476
|
var __dirname = "/home/runner/work/agent-cli/agent-cli/src/mcp/servers/sqlite";
|
|
8411
|
-
var SQLITE_MCP_SERVER_PATH =
|
|
8477
|
+
var SQLITE_MCP_SERVER_PATH = resolve21(__dirname, "server.ts");
|
|
8412
8478
|
|
|
8413
8479
|
// src/init/project-analyzer.ts
|
|
8414
|
-
import { existsSync as
|
|
8415
|
-
import { join as
|
|
8480
|
+
import { existsSync as existsSync21, readFileSync as readFileSync13, readdirSync as readdirSync9 } from "fs";
|
|
8481
|
+
import { join as join13, basename as basename3 } from "path";
|
|
8416
8482
|
|
|
8417
8483
|
class ProjectAnalyzer {
|
|
8418
8484
|
cwd;
|
|
@@ -8430,8 +8496,8 @@ class ProjectAnalyzer {
|
|
|
8430
8496
|
const architectureNotes = [];
|
|
8431
8497
|
const codeConventions = [];
|
|
8432
8498
|
let description = readmeInfo.description;
|
|
8433
|
-
const pkgPath =
|
|
8434
|
-
if (
|
|
8499
|
+
const pkgPath = join13(this.cwd, "package.json");
|
|
8500
|
+
if (existsSync21(pkgPath)) {
|
|
8435
8501
|
try {
|
|
8436
8502
|
const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
|
|
8437
8503
|
if (!description && pkg.description)
|
|
@@ -8504,8 +8570,8 @@ class ProjectAnalyzer {
|
|
|
8504
8570
|
}
|
|
8505
8571
|
} catch {}
|
|
8506
8572
|
}
|
|
8507
|
-
const tsconfigPath =
|
|
8508
|
-
if (
|
|
8573
|
+
const tsconfigPath = join13(this.cwd, "tsconfig.json");
|
|
8574
|
+
if (existsSync21(tsconfigPath)) {
|
|
8509
8575
|
try {
|
|
8510
8576
|
const tsconfig = JSON.parse(readFileSync13(tsconfigPath, "utf8"));
|
|
8511
8577
|
if (tsconfig.compilerOptions?.strict) {
|
|
@@ -8516,8 +8582,8 @@ class ProjectAnalyzer {
|
|
|
8516
8582
|
}
|
|
8517
8583
|
} catch {}
|
|
8518
8584
|
}
|
|
8519
|
-
const cargoPath =
|
|
8520
|
-
if (
|
|
8585
|
+
const cargoPath = join13(this.cwd, "Cargo.toml");
|
|
8586
|
+
if (existsSync21(cargoPath)) {
|
|
8521
8587
|
try {
|
|
8522
8588
|
commands.dev = commands.dev || "cargo run";
|
|
8523
8589
|
commands.build = commands.build || "cargo build";
|
|
@@ -8526,8 +8592,8 @@ class ProjectAnalyzer {
|
|
|
8526
8592
|
frameworks.push("Rust Cargo");
|
|
8527
8593
|
} catch {}
|
|
8528
8594
|
}
|
|
8529
|
-
const goModPath =
|
|
8530
|
-
if (
|
|
8595
|
+
const goModPath = join13(this.cwd, "go.mod");
|
|
8596
|
+
if (existsSync21(goModPath)) {
|
|
8531
8597
|
try {
|
|
8532
8598
|
commands.dev = commands.dev || "go run .";
|
|
8533
8599
|
commands.build = commands.build || "go build ./...";
|
|
@@ -8536,37 +8602,37 @@ class ProjectAnalyzer {
|
|
|
8536
8602
|
frameworks.push("Go Modules");
|
|
8537
8603
|
} catch {}
|
|
8538
8604
|
}
|
|
8539
|
-
const pyprojectPath =
|
|
8540
|
-
const requirementsPath =
|
|
8541
|
-
if (
|
|
8605
|
+
const pyprojectPath = join13(this.cwd, "pyproject.toml");
|
|
8606
|
+
const requirementsPath = join13(this.cwd, "requirements.txt");
|
|
8607
|
+
if (existsSync21(pyprojectPath) || existsSync21(requirementsPath)) {
|
|
8542
8608
|
commands.test = commands.test || "pytest";
|
|
8543
8609
|
commands.lint = commands.lint || "ruff check .";
|
|
8544
|
-
if (
|
|
8610
|
+
if (existsSync21(join13(this.cwd, "uv.lock"))) {
|
|
8545
8611
|
frameworks.push("uv");
|
|
8546
8612
|
commands.test = "uv run pytest";
|
|
8547
|
-
} else if (
|
|
8613
|
+
} else if (existsSync21(join13(this.cwd, "poetry.lock"))) {
|
|
8548
8614
|
frameworks.push("Poetry");
|
|
8549
8615
|
commands.test = "poetry run pytest";
|
|
8550
8616
|
}
|
|
8551
8617
|
}
|
|
8552
|
-
if (
|
|
8618
|
+
if (existsSync21(join13(this.cwd, "Dockerfile"))) {
|
|
8553
8619
|
infrastructure.push("Docker");
|
|
8554
8620
|
const sanitizedName = projectName.toLowerCase().replace(/[^a-z0-9_-]/g, "-").replace(/^-+|-+$/g, "");
|
|
8555
8621
|
commands.dockerBuild = `docker build -t ${sanitizedName || "app"} .`;
|
|
8556
8622
|
}
|
|
8557
|
-
if (
|
|
8623
|
+
if (existsSync21(join13(this.cwd, "nginx.conf"))) {
|
|
8558
8624
|
infrastructure.push("Nginx");
|
|
8559
8625
|
}
|
|
8560
|
-
if (
|
|
8626
|
+
if (existsSync21(join13(this.cwd, "src/api.ts")) || existsSync21(join13(this.cwd, "src/api"))) {
|
|
8561
8627
|
architectureNotes.push("Backend API endpoints and network client logic are centralized in `src/api`.");
|
|
8562
8628
|
}
|
|
8563
|
-
if (
|
|
8629
|
+
if (existsSync21(join13(this.cwd, "src/components"))) {
|
|
8564
8630
|
architectureNotes.push("Reusable UI presentation components live in `src/components/`.");
|
|
8565
8631
|
}
|
|
8566
|
-
if (
|
|
8632
|
+
if (existsSync21(join13(this.cwd, "src/types.ts")) || existsSync21(join13(this.cwd, "src/types"))) {
|
|
8567
8633
|
architectureNotes.push("Shared TypeScript data models and interfaces are defined in `src/types`.");
|
|
8568
8634
|
}
|
|
8569
|
-
if (
|
|
8635
|
+
if (existsSync21(join13(this.cwd, ".env.example"))) {
|
|
8570
8636
|
architectureNotes.push("Environment configuration template is in `.env.example`.");
|
|
8571
8637
|
}
|
|
8572
8638
|
if (commands.typecheck || commands.lint || commands.test) {
|
|
@@ -8583,7 +8649,7 @@ class ProjectAnalyzer {
|
|
|
8583
8649
|
let hasExistingInstructions = false;
|
|
8584
8650
|
let existingInstructionFile;
|
|
8585
8651
|
for (const f of instructionFiles) {
|
|
8586
|
-
if (
|
|
8652
|
+
if (existsSync21(join13(this.cwd, f))) {
|
|
8587
8653
|
hasExistingInstructions = true;
|
|
8588
8654
|
existingInstructionFile = f;
|
|
8589
8655
|
break;
|
|
@@ -8664,8 +8730,8 @@ class ProjectAnalyzer {
|
|
|
8664
8730
|
extractReadmeMetadata() {
|
|
8665
8731
|
const readmeFiles = ["README.md", "readme.md", "README.MD"];
|
|
8666
8732
|
for (const file of readmeFiles) {
|
|
8667
|
-
const fullPath =
|
|
8668
|
-
if (
|
|
8733
|
+
const fullPath = join13(this.cwd, file);
|
|
8734
|
+
if (existsSync21(fullPath)) {
|
|
8669
8735
|
try {
|
|
8670
8736
|
const content = readFileSync13(fullPath, "utf8");
|
|
8671
8737
|
const lines = content.split(`
|
|
@@ -8690,8 +8756,8 @@ class ProjectAnalyzer {
|
|
|
8690
8756
|
return {};
|
|
8691
8757
|
}
|
|
8692
8758
|
detectProjectName() {
|
|
8693
|
-
const pkgPath =
|
|
8694
|
-
if (
|
|
8759
|
+
const pkgPath = join13(this.cwd, "package.json");
|
|
8760
|
+
if (existsSync21(pkgPath)) {
|
|
8695
8761
|
try {
|
|
8696
8762
|
const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
|
|
8697
8763
|
if (pkg.name && pkg.name !== "frontend" && pkg.name !== "backend" && pkg.name !== "app") {
|
|
@@ -8699,16 +8765,16 @@ class ProjectAnalyzer {
|
|
|
8699
8765
|
}
|
|
8700
8766
|
} catch {}
|
|
8701
8767
|
}
|
|
8702
|
-
const cargoPath =
|
|
8703
|
-
if (
|
|
8768
|
+
const cargoPath = join13(this.cwd, "Cargo.toml");
|
|
8769
|
+
if (existsSync21(cargoPath)) {
|
|
8704
8770
|
try {
|
|
8705
8771
|
const match = readFileSync13(cargoPath, "utf8").match(/name\s*=\s*"([^"]+)"/);
|
|
8706
8772
|
if (match?.[1])
|
|
8707
8773
|
return match[1];
|
|
8708
8774
|
} catch {}
|
|
8709
8775
|
}
|
|
8710
|
-
const goModPath =
|
|
8711
|
-
if (
|
|
8776
|
+
const goModPath = join13(this.cwd, "go.mod");
|
|
8777
|
+
if (existsSync21(goModPath)) {
|
|
8712
8778
|
try {
|
|
8713
8779
|
const match = readFileSync13(goModPath, "utf8").match(/module\s+([^\s]+)/);
|
|
8714
8780
|
if (match?.[1])
|
|
@@ -8719,47 +8785,47 @@ class ProjectAnalyzer {
|
|
|
8719
8785
|
}
|
|
8720
8786
|
detectLanguages() {
|
|
8721
8787
|
const langs = new Set;
|
|
8722
|
-
if (
|
|
8788
|
+
if (existsSync21(join13(this.cwd, "tsconfig.json")) || this.hasFileWithExtension(".ts", ".tsx")) {
|
|
8723
8789
|
langs.add("TypeScript");
|
|
8724
8790
|
}
|
|
8725
|
-
if (
|
|
8791
|
+
if (existsSync21(join13(this.cwd, "package.json")) || this.hasFileWithExtension(".js", ".jsx", ".mjs")) {
|
|
8726
8792
|
langs.add("JavaScript");
|
|
8727
8793
|
}
|
|
8728
|
-
if (
|
|
8794
|
+
if (existsSync21(join13(this.cwd, "Cargo.toml")) || this.hasFileWithExtension(".rs")) {
|
|
8729
8795
|
langs.add("Rust");
|
|
8730
8796
|
}
|
|
8731
|
-
if (
|
|
8797
|
+
if (existsSync21(join13(this.cwd, "go.mod")) || this.hasFileWithExtension(".go")) {
|
|
8732
8798
|
langs.add("Go");
|
|
8733
8799
|
}
|
|
8734
|
-
if (
|
|
8800
|
+
if (existsSync21(join13(this.cwd, "pyproject.toml")) || existsSync21(join13(this.cwd, "requirements.txt")) || this.hasFileWithExtension(".py")) {
|
|
8735
8801
|
langs.add("Python");
|
|
8736
8802
|
}
|
|
8737
|
-
if (
|
|
8803
|
+
if (existsSync21(join13(this.cwd, "pom.xml")) || existsSync21(join13(this.cwd, "build.gradle")) || this.hasFileWithExtension(".java")) {
|
|
8738
8804
|
langs.add("Java");
|
|
8739
8805
|
}
|
|
8740
|
-
if (
|
|
8806
|
+
if (existsSync21(join13(this.cwd, "CMakeLists.txt")) || this.hasFileWithExtension(".cpp", ".c", ".h", ".hpp")) {
|
|
8741
8807
|
langs.add("C/C++");
|
|
8742
8808
|
}
|
|
8743
8809
|
return Array.from(langs);
|
|
8744
8810
|
}
|
|
8745
8811
|
detectPackageManager() {
|
|
8746
|
-
if (
|
|
8812
|
+
if (existsSync21(join13(this.cwd, "bun.lockb")) || existsSync21(join13(this.cwd, "bun.lock")))
|
|
8747
8813
|
return "bun";
|
|
8748
|
-
if (
|
|
8814
|
+
if (existsSync21(join13(this.cwd, "pnpm-lock.yaml")))
|
|
8749
8815
|
return "pnpm";
|
|
8750
|
-
if (
|
|
8816
|
+
if (existsSync21(join13(this.cwd, "yarn.lock")))
|
|
8751
8817
|
return "yarn";
|
|
8752
|
-
if (
|
|
8818
|
+
if (existsSync21(join13(this.cwd, "package-lock.json")))
|
|
8753
8819
|
return "npm";
|
|
8754
|
-
if (
|
|
8820
|
+
if (existsSync21(join13(this.cwd, "Cargo.lock")) || existsSync21(join13(this.cwd, "Cargo.toml")))
|
|
8755
8821
|
return "cargo";
|
|
8756
|
-
if (
|
|
8822
|
+
if (existsSync21(join13(this.cwd, "uv.lock")))
|
|
8757
8823
|
return "uv";
|
|
8758
|
-
if (
|
|
8824
|
+
if (existsSync21(join13(this.cwd, "poetry.lock")))
|
|
8759
8825
|
return "poetry";
|
|
8760
|
-
if (
|
|
8826
|
+
if (existsSync21(join13(this.cwd, "go.sum")) || existsSync21(join13(this.cwd, "go.mod")))
|
|
8761
8827
|
return "go";
|
|
8762
|
-
if (
|
|
8828
|
+
if (existsSync21(join13(this.cwd, "package.json")))
|
|
8763
8829
|
return "npm";
|
|
8764
8830
|
return;
|
|
8765
8831
|
}
|
|
@@ -8773,17 +8839,17 @@ class ProjectAnalyzer {
|
|
|
8773
8839
|
}
|
|
8774
8840
|
}
|
|
8775
8841
|
// src/init/init-command.ts
|
|
8776
|
-
import { existsSync as
|
|
8777
|
-
import { join as
|
|
8842
|
+
import { existsSync as existsSync22, writeFileSync as writeFileSync8 } from "fs";
|
|
8843
|
+
import { join as join14 } from "path";
|
|
8778
8844
|
function runProjectInit(options = {}) {
|
|
8779
8845
|
const cwd = options.cwd || process.cwd();
|
|
8780
8846
|
const filename = options.filename || "AGENTS.md";
|
|
8781
|
-
const targetPath =
|
|
8847
|
+
const targetPath = join14(cwd, filename);
|
|
8782
8848
|
const analyzer = new ProjectAnalyzer(cwd);
|
|
8783
8849
|
const analysis = analyzer.analyze();
|
|
8784
8850
|
const content = analyzer.generateAgentsMarkdown(analysis);
|
|
8785
|
-
const alreadyExists =
|
|
8786
|
-
|
|
8851
|
+
const alreadyExists = existsSync22(targetPath);
|
|
8852
|
+
writeFileSync8(targetPath, content, "utf8");
|
|
8787
8853
|
return {
|
|
8788
8854
|
success: true,
|
|
8789
8855
|
filePath: targetPath,
|
|
@@ -8855,7 +8921,7 @@ var AVAILABLE_SLASH_COMMANDS = [
|
|
|
8855
8921
|
{ name: "/manual", description: "Switch to Manual Mode (all tools require user confirmation)" },
|
|
8856
8922
|
{ name: "/accept-edits", description: "Switch to Accept Edits Mode (file edits auto-approved, shell prompts)" },
|
|
8857
8923
|
{ name: "/plan", description: "Switch to Plan Mode (read-only planning, mutations blocked)" },
|
|
8858
|
-
{ name: "/skills", description: "
|
|
8924
|
+
{ name: "/skills", description: "Manage domain skills (/skills, /skill add <name>, /skill remove <name>)" },
|
|
8859
8925
|
{ name: "/memories", description: "View learned preferences & memories" },
|
|
8860
8926
|
{ name: "/worktrees", description: "List active isolated Git Worktrees" },
|
|
8861
8927
|
{ name: "/resume", description: "Resume a previous conversation session (/resume [id])" },
|
|
@@ -9358,6 +9424,46 @@ async function handleSkillsCommand(ctx, args) {
|
|
|
9358
9424
|
}
|
|
9359
9425
|
const sub = (args[0] || "").toLowerCase();
|
|
9360
9426
|
const target = (args[1] || "").toLowerCase();
|
|
9427
|
+
if (sub === "install" || sub === "add") {
|
|
9428
|
+
if (!target) {
|
|
9429
|
+
console.log(style.yellow("Usage: /skill add <skill-name> [--global]"));
|
|
9430
|
+
return;
|
|
9431
|
+
}
|
|
9432
|
+
const isGlobal = args.includes("--global") || args.includes("-g");
|
|
9433
|
+
try {
|
|
9434
|
+
console.log(style.dim(`
|
|
9435
|
+
Fetching skill '${target}' from catalog...`));
|
|
9436
|
+
const res = await installSkill(target, { cwd: ctx.session.cwd, global: isGlobal });
|
|
9437
|
+
loader.clearCache();
|
|
9438
|
+
console.log(style.green(`
|
|
9439
|
+
\u2713 ${res.message}
|
|
9440
|
+
`));
|
|
9441
|
+
} catch (err) {
|
|
9442
|
+
console.log(style.red(`
|
|
9443
|
+
\u2715 Failed to install skill: ${err.message}
|
|
9444
|
+
`));
|
|
9445
|
+
}
|
|
9446
|
+
return;
|
|
9447
|
+
}
|
|
9448
|
+
if (sub === "remove" || sub === "uninstall" || sub === "rm") {
|
|
9449
|
+
if (!target) {
|
|
9450
|
+
console.log(style.yellow("Usage: /skill remove <skill-name> [--global]"));
|
|
9451
|
+
return;
|
|
9452
|
+
}
|
|
9453
|
+
const isGlobal = args.includes("--global") || args.includes("-g");
|
|
9454
|
+
const res = removeSkill(target, { cwd: ctx.session.cwd, global: isGlobal });
|
|
9455
|
+
loader.clearCache();
|
|
9456
|
+
if (res.removed) {
|
|
9457
|
+
console.log(style.green(`
|
|
9458
|
+
\u2713 Skill '${target}' removed from ${res.targetDir}
|
|
9459
|
+
`));
|
|
9460
|
+
} else {
|
|
9461
|
+
console.log(style.yellow(`
|
|
9462
|
+
\u2715 Skill '${target}' was not found in ${res.targetDir}
|
|
9463
|
+
`));
|
|
9464
|
+
}
|
|
9465
|
+
return;
|
|
9466
|
+
}
|
|
9361
9467
|
if (sub === "disable" || sub === "off") {
|
|
9362
9468
|
if (!target) {
|
|
9363
9469
|
console.log(style.yellow("Usage: /skills disable <skill-name>"));
|
|
@@ -10328,9 +10434,9 @@ class MarkdownHighlighter {
|
|
|
10328
10434
|
}
|
|
10329
10435
|
|
|
10330
10436
|
// src/cli/update-checker.ts
|
|
10331
|
-
import { existsSync as
|
|
10332
|
-
import { homedir as
|
|
10333
|
-
import { join as
|
|
10437
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync13, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "fs";
|
|
10438
|
+
import { homedir as homedir4 } from "os";
|
|
10439
|
+
import { join as join15 } from "path";
|
|
10334
10440
|
var CHECK_INTERVAL_MS = 12 * 60 * 60 * 1000;
|
|
10335
10441
|
function parseSemver(v) {
|
|
10336
10442
|
const clean = v.replace(/^v/, "").trim();
|
|
@@ -10351,8 +10457,8 @@ function isNewerVersion(current, remote) {
|
|
|
10351
10457
|
return remPatch > curPatch;
|
|
10352
10458
|
}
|
|
10353
10459
|
function getUpdateCachePath() {
|
|
10354
|
-
const baseDir = process.env.PIKAA_HOME || process.env.GROUPY_HOME ||
|
|
10355
|
-
return
|
|
10460
|
+
const baseDir = process.env.PIKAA_HOME || process.env.GROUPY_HOME || join15(homedir4(), ".pikaa");
|
|
10461
|
+
return join15(baseDir, "update-cache.json");
|
|
10356
10462
|
}
|
|
10357
10463
|
async function fetchLatestNpmVersion(packageName, timeoutMs = 1500) {
|
|
10358
10464
|
const url = `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`;
|
|
@@ -10385,7 +10491,7 @@ async function checkForUpdates(options = {}) {
|
|
|
10385
10491
|
const cachePath = options.cachePath || getUpdateCachePath();
|
|
10386
10492
|
const now = Date.now();
|
|
10387
10493
|
let cached = null;
|
|
10388
|
-
if (!options.force &&
|
|
10494
|
+
if (!options.force && existsSync23(cachePath)) {
|
|
10389
10495
|
try {
|
|
10390
10496
|
const raw = JSON.parse(readFileSync14(cachePath, "utf8"));
|
|
10391
10497
|
if (raw && typeof raw.lastChecked === "number" && typeof raw.latestVersion === "string") {
|
|
@@ -10415,16 +10521,16 @@ async function checkForUpdates(options = {}) {
|
|
|
10415
10521
|
return null;
|
|
10416
10522
|
}
|
|
10417
10523
|
try {
|
|
10418
|
-
const parentDir =
|
|
10419
|
-
if (!
|
|
10420
|
-
|
|
10524
|
+
const parentDir = join15(cachePath, "..");
|
|
10525
|
+
if (!existsSync23(parentDir)) {
|
|
10526
|
+
mkdirSync13(parentDir, { recursive: true });
|
|
10421
10527
|
}
|
|
10422
10528
|
const cacheData = {
|
|
10423
10529
|
lastChecked: now,
|
|
10424
10530
|
latestVersion,
|
|
10425
10531
|
packageName
|
|
10426
10532
|
};
|
|
10427
|
-
|
|
10533
|
+
writeFileSync9(cachePath, JSON.stringify(cacheData, null, 2), "utf8");
|
|
10428
10534
|
} catch {}
|
|
10429
10535
|
const updateAvailable = isNewerVersion(currentVersion, latestVersion);
|
|
10430
10536
|
return updateAvailable ? {
|
|
@@ -10590,9 +10696,9 @@ class CliRepl {
|
|
|
10590
10696
|
filesModified: Array.from(this.turnFilesModified)
|
|
10591
10697
|
});
|
|
10592
10698
|
if (this.turnDoneResolver) {
|
|
10593
|
-
const
|
|
10699
|
+
const resolve22 = this.turnDoneResolver;
|
|
10594
10700
|
this.turnDoneResolver = undefined;
|
|
10595
|
-
|
|
10701
|
+
resolve22();
|
|
10596
10702
|
}
|
|
10597
10703
|
break;
|
|
10598
10704
|
case "Error":
|
|
@@ -10608,9 +10714,9 @@ class CliRepl {
|
|
|
10608
10714
|
console.error(style.red(`Error: ${msg.message}
|
|
10609
10715
|
`));
|
|
10610
10716
|
if (this.turnDoneResolver) {
|
|
10611
|
-
const
|
|
10717
|
+
const resolve22 = this.turnDoneResolver;
|
|
10612
10718
|
this.turnDoneResolver = undefined;
|
|
10613
|
-
|
|
10719
|
+
resolve22();
|
|
10614
10720
|
}
|
|
10615
10721
|
break;
|
|
10616
10722
|
}
|
|
@@ -10680,9 +10786,9 @@ class CliRepl {
|
|
|
10680
10786
|
`));
|
|
10681
10787
|
this.isProcessing = false;
|
|
10682
10788
|
if (this.turnDoneResolver) {
|
|
10683
|
-
const
|
|
10789
|
+
const resolve22 = this.turnDoneResolver;
|
|
10684
10790
|
this.turnDoneResolver = undefined;
|
|
10685
|
-
|
|
10791
|
+
resolve22();
|
|
10686
10792
|
}
|
|
10687
10793
|
}
|
|
10688
10794
|
}
|
|
@@ -10719,8 +10825,8 @@ class CliRepl {
|
|
|
10719
10825
|
}
|
|
10720
10826
|
async submitTurn(text) {
|
|
10721
10827
|
try {
|
|
10722
|
-
const turnPromise = new Promise((
|
|
10723
|
-
this.turnDoneResolver =
|
|
10828
|
+
const turnPromise = new Promise((resolve22) => {
|
|
10829
|
+
this.turnDoneResolver = resolve22;
|
|
10724
10830
|
});
|
|
10725
10831
|
await this.session.submit({
|
|
10726
10832
|
type: "TurnInput",
|
|
@@ -10786,9 +10892,22 @@ async function main() {
|
|
|
10786
10892
|
} else if (arg === "list" || arg === "sessions" || arg === "--list") {
|
|
10787
10893
|
printSessionsList(storageManager);
|
|
10788
10894
|
process.exit(0);
|
|
10789
|
-
} else if (arg === "skills") {
|
|
10790
|
-
|
|
10791
|
-
|
|
10895
|
+
} else if (arg === "skills" || arg === "skill") {
|
|
10896
|
+
const subAction = args[i + 1];
|
|
10897
|
+
const target = args[i + 2];
|
|
10898
|
+
const isGlobal = args.includes("--global") || args.includes("-g");
|
|
10899
|
+
if (subAction && !subAction.startsWith("-")) {
|
|
10900
|
+
await handleSkillCliCommand(subAction, target, {
|
|
10901
|
+
cwd,
|
|
10902
|
+
isGlobal,
|
|
10903
|
+
baseUrl,
|
|
10904
|
+
loader: skillsLoader
|
|
10905
|
+
});
|
|
10906
|
+
process.exit(0);
|
|
10907
|
+
} else {
|
|
10908
|
+
printSkillsList(skillsLoader, cwd);
|
|
10909
|
+
process.exit(0);
|
|
10910
|
+
}
|
|
10792
10911
|
} else if (arg === "memories" || arg === "memory") {
|
|
10793
10912
|
printMemoriesList(memoryStore, cwd);
|
|
10794
10913
|
process.exit(0);
|
|
@@ -10810,7 +10929,7 @@ async function main() {
|
|
|
10810
10929
|
explicitApiKey = args[++i];
|
|
10811
10930
|
apiKey = explicitApiKey || apiKey;
|
|
10812
10931
|
} else if (arg === "--cwd" || arg === "-C") {
|
|
10813
|
-
cwd =
|
|
10932
|
+
cwd = resolve22(args[++i] || cwd);
|
|
10814
10933
|
} else if (arg === "--role" || arg === "-r") {
|
|
10815
10934
|
role = args[++i] || role;
|
|
10816
10935
|
} else if (arg === "--mcp") {
|
|
@@ -10836,11 +10955,11 @@ async function main() {
|
|
|
10836
10955
|
const mcpManager = new McpManager;
|
|
10837
10956
|
const candidateConfigs = [
|
|
10838
10957
|
mcpConfigFile,
|
|
10839
|
-
|
|
10840
|
-
|
|
10958
|
+
resolve22(cwd, ".mcp.json"),
|
|
10959
|
+
resolve22(cwd, "mcp_config.json")
|
|
10841
10960
|
].filter(Boolean);
|
|
10842
10961
|
for (const cfg of candidateConfigs) {
|
|
10843
|
-
if (
|
|
10962
|
+
if (existsSync24(cfg)) {
|
|
10844
10963
|
try {
|
|
10845
10964
|
await mcpManager.loadConfigFile(cfg);
|
|
10846
10965
|
mcpManager.registerToolsIntoRouter(tools4);
|
|
@@ -11043,6 +11162,62 @@ Resume a session with: ${style.bold("groupy --resume <thread_id>")}`);
|
|
|
11043
11162
|
}
|
|
11044
11163
|
console.log();
|
|
11045
11164
|
}
|
|
11165
|
+
async function handleSkillCliCommand(action, targetName, options) {
|
|
11166
|
+
const act = action.toLowerCase();
|
|
11167
|
+
if (act === "add" || act === "install") {
|
|
11168
|
+
if (!targetName) {
|
|
11169
|
+
console.error(style.yellow(`
|
|
11170
|
+
Usage: pikaa skill add <skill-name> [--global]
|
|
11171
|
+
`));
|
|
11172
|
+
process.exit(1);
|
|
11173
|
+
}
|
|
11174
|
+
try {
|
|
11175
|
+
console.log(style.dim(`
|
|
11176
|
+
Fetching skill '${targetName}' from catalog...`));
|
|
11177
|
+
const res = await installSkill(targetName, {
|
|
11178
|
+
cwd: options.cwd,
|
|
11179
|
+
global: options.isGlobal,
|
|
11180
|
+
backendUrl: options.baseUrl
|
|
11181
|
+
});
|
|
11182
|
+
console.log(style.green(`
|
|
11183
|
+
\u2713 ${res.message}`));
|
|
11184
|
+
console.log(style.dim(` To start using this skill in an AI coding session, simply run: pikaa
|
|
11185
|
+
`));
|
|
11186
|
+
} catch (err) {
|
|
11187
|
+
console.error(style.red(`
|
|
11188
|
+
\u2715 Failed to install skill: ${err.message}
|
|
11189
|
+
`));
|
|
11190
|
+
process.exit(1);
|
|
11191
|
+
}
|
|
11192
|
+
} else if (act === "remove" || act === "uninstall" || act === "rm") {
|
|
11193
|
+
if (!targetName) {
|
|
11194
|
+
console.error(style.yellow(`
|
|
11195
|
+
Usage: pikaa skill remove <skill-name> [--global]
|
|
11196
|
+
`));
|
|
11197
|
+
process.exit(1);
|
|
11198
|
+
}
|
|
11199
|
+
const res = removeSkill(targetName, { cwd: options.cwd, global: options.isGlobal });
|
|
11200
|
+
if (res.removed) {
|
|
11201
|
+
console.log(style.green(`
|
|
11202
|
+
\u2713 Skill '${targetName}' removed from ${res.targetDir}
|
|
11203
|
+
`));
|
|
11204
|
+
} else {
|
|
11205
|
+
console.log(style.yellow(`
|
|
11206
|
+
\u2715 Skill '${targetName}' was not found in ${res.targetDir}
|
|
11207
|
+
`));
|
|
11208
|
+
}
|
|
11209
|
+
} else if (act === "list" || act === "ls") {
|
|
11210
|
+
printSkillsList(options.loader, options.cwd);
|
|
11211
|
+
} else {
|
|
11212
|
+
if (act && !targetName) {
|
|
11213
|
+
return handleSkillCliCommand("add", act, options);
|
|
11214
|
+
}
|
|
11215
|
+
console.error(style.yellow(`
|
|
11216
|
+
Unknown skill action '${action}'. Available: add, remove, list
|
|
11217
|
+
`));
|
|
11218
|
+
process.exit(1);
|
|
11219
|
+
}
|
|
11220
|
+
}
|
|
11046
11221
|
function printSkillsList(loader, cwd) {
|
|
11047
11222
|
const skills = loader.discoverSkills(cwd);
|
|
11048
11223
|
console.log();
|