@pellux/goodvibes-agent 0.1.112 → 0.1.114
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 +12 -0
- package/dist/package/main.js +831 -85
- package/package.json +1 -1
- package/src/agent/persona-discovery.ts +117 -0
- package/src/agent/routine-discovery.ts +115 -0
- package/src/cli/help.ts +13 -1
- package/src/cli/local-library-command.ts +171 -2
- package/src/cli/routines-command.ts +156 -1
- package/src/cli/service-posture.ts +1 -8
- package/src/cli/status.ts +1 -30
- package/src/input/agent-workspace-basic-command-editors.ts +90 -0
- package/src/input/agent-workspace-categories.ts +4 -0
- package/src/input/agent-workspace-command-editor.ts +2 -0
- package/src/input/agent-workspace-types.ts +2 -0
- package/src/input/commands/personas-runtime.ts +87 -2
- package/src/input/commands/routines-runtime.ts +87 -2
- package/src/renderer/ui-factory.ts +1 -1
- package/src/version.ts +1 -1
package/dist/package/main.js
CHANGED
|
@@ -816523,7 +816523,7 @@ var createStyledCell = (char, overrides = {}) => ({
|
|
|
816523
816523
|
// src/version.ts
|
|
816524
816524
|
import { readFileSync } from "fs";
|
|
816525
816525
|
import { join } from "path";
|
|
816526
|
-
var _version = "0.1.
|
|
816526
|
+
var _version = "0.1.114";
|
|
816527
816527
|
var _sdkVersion = "0.33.35";
|
|
816528
816528
|
try {
|
|
816529
816529
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
|
|
@@ -816960,7 +816960,7 @@ class UIFactory {
|
|
|
816960
816960
|
const CYAN = "#00ffff";
|
|
816961
816961
|
const GREY = "244";
|
|
816962
816962
|
const TITLE_COLOR = "250";
|
|
816963
|
-
const brand = ` GoodVibes `;
|
|
816963
|
+
const brand = ` GoodVibes Agent `;
|
|
816964
816964
|
const ver = `v${VERSION} `;
|
|
816965
816965
|
const stats = ` ${model} `;
|
|
816966
816966
|
const prov = `(${provider}) `;
|
|
@@ -841974,7 +841974,7 @@ async function initializeBootstrapCore(stdout, options, getControlPlaneRecentEve
|
|
|
841974
841974
|
}
|
|
841975
841975
|
|
|
841976
841976
|
// src/runtime/bootstrap-shell.ts
|
|
841977
|
-
import { join as
|
|
841977
|
+
import { join as join91 } from "path";
|
|
841978
841978
|
|
|
841979
841979
|
// src/input/command-registry.ts
|
|
841980
841980
|
class CommandRegistry {
|
|
@@ -852664,6 +852664,100 @@ function registerDelegationRuntimeCommands(registry5) {
|
|
|
852664
852664
|
});
|
|
852665
852665
|
}
|
|
852666
852666
|
|
|
852667
|
+
// src/agent/persona-discovery.ts
|
|
852668
|
+
import { promises as fsPromises5 } from "fs";
|
|
852669
|
+
import { join as join87 } from "path";
|
|
852670
|
+
var DIRECTORY_MARKERS = ["PERSONA.md", "persona.md", "AGENT.md", "agent.md"];
|
|
852671
|
+
function parseFrontmatter2(content) {
|
|
852672
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
852673
|
+
if (!match)
|
|
852674
|
+
return {};
|
|
852675
|
+
const result2 = {};
|
|
852676
|
+
for (const line of match[1].split(`
|
|
852677
|
+
`)) {
|
|
852678
|
+
const [key, ...rest] = line.split(":");
|
|
852679
|
+
if (key && rest.length > 0) {
|
|
852680
|
+
result2[key.trim()] = rest.join(":").trim();
|
|
852681
|
+
}
|
|
852682
|
+
}
|
|
852683
|
+
return result2;
|
|
852684
|
+
}
|
|
852685
|
+
function getPersonaDirectories(cwd, homeDir) {
|
|
852686
|
+
return [
|
|
852687
|
+
{ root: join87(cwd, ".goodvibes", "personas"), origin: "project-local" },
|
|
852688
|
+
{ root: join87(cwd, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "personas"), origin: "project-local" },
|
|
852689
|
+
{ root: join87(cwd, ".goodvibes", "agents"), origin: "project-local" },
|
|
852690
|
+
{ root: join87(homeDir, ".goodvibes", "personas"), origin: "global" },
|
|
852691
|
+
{ root: join87(homeDir, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "personas"), origin: "global" },
|
|
852692
|
+
{ root: join87(homeDir, ".goodvibes", "agents"), origin: "global" }
|
|
852693
|
+
];
|
|
852694
|
+
}
|
|
852695
|
+
async function readPersonaFile(path7, origin) {
|
|
852696
|
+
let content = "";
|
|
852697
|
+
try {
|
|
852698
|
+
content = await fsPromises5.readFile(path7, "utf-8");
|
|
852699
|
+
} catch {
|
|
852700
|
+
return null;
|
|
852701
|
+
}
|
|
852702
|
+
const frontmatter = parseFrontmatter2(content);
|
|
852703
|
+
const markdownBody = content.replace(/^---\n[\s\S]*?\n---\n?/, "").trim();
|
|
852704
|
+
const body2 = (frontmatter.system_prompt ?? markdownBody).trim();
|
|
852705
|
+
if (!body2)
|
|
852706
|
+
return null;
|
|
852707
|
+
const name51 = frontmatter.name ?? path7.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "persona";
|
|
852708
|
+
const description = frontmatter.description ?? frontmatter.summary ?? frontmatter.title ?? "";
|
|
852709
|
+
return {
|
|
852710
|
+
name: name51,
|
|
852711
|
+
description,
|
|
852712
|
+
path: path7,
|
|
852713
|
+
origin,
|
|
852714
|
+
body: body2,
|
|
852715
|
+
frontmatter
|
|
852716
|
+
};
|
|
852717
|
+
}
|
|
852718
|
+
async function scanPersonaDirectory(root, origin) {
|
|
852719
|
+
let entries = [];
|
|
852720
|
+
try {
|
|
852721
|
+
entries = await fsPromises5.readdir(root);
|
|
852722
|
+
} catch {
|
|
852723
|
+
return [];
|
|
852724
|
+
}
|
|
852725
|
+
const records = [];
|
|
852726
|
+
for (const entry of entries.sort((a4, b3) => a4.localeCompare(b3))) {
|
|
852727
|
+
if (entry.endsWith(".md")) {
|
|
852728
|
+
const record2 = await readPersonaFile(join87(root, entry), origin);
|
|
852729
|
+
if (record2)
|
|
852730
|
+
records.push(record2);
|
|
852731
|
+
continue;
|
|
852732
|
+
}
|
|
852733
|
+
for (const marker of DIRECTORY_MARKERS) {
|
|
852734
|
+
const record2 = await readPersonaFile(join87(root, entry, marker), origin);
|
|
852735
|
+
if (record2) {
|
|
852736
|
+
records.push(record2);
|
|
852737
|
+
break;
|
|
852738
|
+
}
|
|
852739
|
+
}
|
|
852740
|
+
}
|
|
852741
|
+
return records;
|
|
852742
|
+
}
|
|
852743
|
+
async function discoverPersonas(shellPaths) {
|
|
852744
|
+
const seen = new Set;
|
|
852745
|
+
const records = [];
|
|
852746
|
+
for (const { root, origin } of getPersonaDirectories(shellPaths.workingDirectory, shellPaths.homeDirectory)) {
|
|
852747
|
+
for (const record2 of await scanPersonaDirectory(root, origin)) {
|
|
852748
|
+
const key = record2.name.toLowerCase();
|
|
852749
|
+
if (seen.has(key))
|
|
852750
|
+
continue;
|
|
852751
|
+
seen.add(key);
|
|
852752
|
+
records.push(record2);
|
|
852753
|
+
}
|
|
852754
|
+
}
|
|
852755
|
+
return records.sort((a4, b3) => {
|
|
852756
|
+
const originRank = a4.origin === b3.origin ? 0 : a4.origin === "project-local" ? -1 : 1;
|
|
852757
|
+
return originRank || a4.name.localeCompare(b3.name);
|
|
852758
|
+
});
|
|
852759
|
+
}
|
|
852760
|
+
|
|
852667
852761
|
// src/input/commands/personas-runtime.ts
|
|
852668
852762
|
function parsePersonaArgs(args2) {
|
|
852669
852763
|
const flags2 = new Map;
|
|
@@ -852737,6 +852831,84 @@ function renderPersona(persona, activePersonaId) {
|
|
|
852737
852831
|
].filter(Boolean).join(`
|
|
852738
852832
|
`);
|
|
852739
852833
|
}
|
|
852834
|
+
function summarizeDiscoveredPersona(persona) {
|
|
852835
|
+
const description = persona.description ? ` - ${persona.description}` : "";
|
|
852836
|
+
return ` ${persona.name} ${persona.origin}${description}
|
|
852837
|
+
path: ${persona.path}`;
|
|
852838
|
+
}
|
|
852839
|
+
function renderDiscoveredPersonas(personas) {
|
|
852840
|
+
if (personas.length === 0) {
|
|
852841
|
+
return [
|
|
852842
|
+
"Discovered Agent persona files",
|
|
852843
|
+
" No persona markdown files found in project/global Agent persona folders.",
|
|
852844
|
+
" Search roots: .goodvibes/personas, .goodvibes/agent/personas, .goodvibes/agents, ~/.goodvibes/personas, ~/.goodvibes/agent/personas, ~/.goodvibes/agents"
|
|
852845
|
+
].join(`
|
|
852846
|
+
`);
|
|
852847
|
+
}
|
|
852848
|
+
return [
|
|
852849
|
+
`Discovered Agent persona files (${personas.length})`,
|
|
852850
|
+
...personas.map(summarizeDiscoveredPersona),
|
|
852851
|
+
"",
|
|
852852
|
+
"Import one with: /personas import-discovered <name> --yes"
|
|
852853
|
+
].join(`
|
|
852854
|
+
`);
|
|
852855
|
+
}
|
|
852856
|
+
function discoveredPersonaLookupValues(persona) {
|
|
852857
|
+
const slug = persona.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
852858
|
+
const basename5 = persona.path.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
|
|
852859
|
+
return [persona.name, slug, persona.path, basename5].map((value) => value.trim().toLowerCase()).filter(Boolean);
|
|
852860
|
+
}
|
|
852861
|
+
function findDiscoveredPersona(personas, idOrName) {
|
|
852862
|
+
const lookup = idOrName.trim().toLowerCase();
|
|
852863
|
+
if (!lookup)
|
|
852864
|
+
return null;
|
|
852865
|
+
return personas.find((persona) => discoveredPersonaLookupValues(persona).includes(lookup)) ?? null;
|
|
852866
|
+
}
|
|
852867
|
+
function frontmatterList(persona, key) {
|
|
852868
|
+
const value = persona.frontmatter[key];
|
|
852869
|
+
if (!value)
|
|
852870
|
+
return [];
|
|
852871
|
+
return splitList(value);
|
|
852872
|
+
}
|
|
852873
|
+
async function importDiscoveredPersona(args2, ctx, personaRegistry) {
|
|
852874
|
+
const parsed = parsePersonaArgs(args2);
|
|
852875
|
+
const name51 = parsed.rest.join(" ").trim();
|
|
852876
|
+
if (!name51) {
|
|
852877
|
+
ctx.print("Usage: /personas import-discovered <name> [--use] --yes");
|
|
852878
|
+
return;
|
|
852879
|
+
}
|
|
852880
|
+
const discovered = findDiscoveredPersona(await discoverPersonas(requireShellPaths(ctx)), name51);
|
|
852881
|
+
if (!discovered) {
|
|
852882
|
+
ctx.print(`Unknown discovered Agent persona: ${name51}
|
|
852883
|
+
Run /personas discover to inspect available persona files.`);
|
|
852884
|
+
return;
|
|
852885
|
+
}
|
|
852886
|
+
if (!parsed.yes) {
|
|
852887
|
+
ctx.print([
|
|
852888
|
+
"Agent persona import preview",
|
|
852889
|
+
` name: ${discovered.name}`,
|
|
852890
|
+
` origin: ${discovered.origin}`,
|
|
852891
|
+
` path: ${discovered.path}`,
|
|
852892
|
+
` description: ${discovered.description || "(none)"}`,
|
|
852893
|
+
` body characters: ${discovered.body.length}`,
|
|
852894
|
+
" next: rerun with --yes to import into the Agent-local persona registry"
|
|
852895
|
+
].join(`
|
|
852896
|
+
`));
|
|
852897
|
+
return;
|
|
852898
|
+
}
|
|
852899
|
+
const persona = personaRegistry.create({
|
|
852900
|
+
name: discovered.name,
|
|
852901
|
+
description: discovered.description || `Imported persona from ${discovered.origin} markdown file.`,
|
|
852902
|
+
body: discovered.body,
|
|
852903
|
+
tags: frontmatterList(discovered, "tags"),
|
|
852904
|
+
triggers: frontmatterList(discovered, "triggers"),
|
|
852905
|
+
source: "imported",
|
|
852906
|
+
provenance: `discovered:${discovered.origin}:${discovered.path}`
|
|
852907
|
+
});
|
|
852908
|
+
if (parsed.flags.get("use") === "true")
|
|
852909
|
+
personaRegistry.setActive(persona.id);
|
|
852910
|
+
ctx.print(`Imported Agent persona ${persona.id}: ${persona.name}${parsed.flags.get("use") === "true" ? " (active)" : ""}`);
|
|
852911
|
+
}
|
|
852740
852912
|
function requiredFlag(flags2, key) {
|
|
852741
852913
|
const value = flags2.get(key)?.trim();
|
|
852742
852914
|
if (!value)
|
|
@@ -852751,7 +852923,7 @@ function registerPersonasRuntimeCommands(registry5) {
|
|
|
852751
852923
|
name: "personas",
|
|
852752
852924
|
aliases: ["persona"],
|
|
852753
852925
|
description: "Manage local GoodVibes Agent personas",
|
|
852754
|
-
usage: "[list|search <query>|show <id>|create --name <name> --description <summary> --body <instructions>|update <id> [--name ...] [--description ...] [--body ...]|use <id>|active|clear|review <id>|stale <id> <reason...>|delete <id> --yes]",
|
|
852926
|
+
usage: "[list|discover|import-discovered <name> --yes|search <query>|show <id>|create --name <name> --description <summary> --body <instructions>|update <id> [--name ...] [--description ...] [--body ...]|use <id>|active|clear|review <id>|stale <id> <reason...>|delete <id> --yes]",
|
|
852755
852927
|
async handler(args2, ctx) {
|
|
852756
852928
|
const sub = (args2[0] ?? "list").toLowerCase();
|
|
852757
852929
|
const registryStore = registryFromContext(ctx);
|
|
@@ -852760,6 +852932,14 @@ function registerPersonasRuntimeCommands(registry5) {
|
|
|
852760
852932
|
ctx.print(renderList("Agent Personas", registryStore, registryStore.list()));
|
|
852761
852933
|
return;
|
|
852762
852934
|
}
|
|
852935
|
+
if (sub === "discover" || sub === "discovered") {
|
|
852936
|
+
ctx.print(renderDiscoveredPersonas(await discoverPersonas(requireShellPaths(ctx))));
|
|
852937
|
+
return;
|
|
852938
|
+
}
|
|
852939
|
+
if (sub === "import-discovered" || sub === "import-persona") {
|
|
852940
|
+
await importDiscoveredPersona(args2.slice(1), ctx, registryStore);
|
|
852941
|
+
return;
|
|
852942
|
+
}
|
|
852763
852943
|
if (sub === "search") {
|
|
852764
852944
|
const query2 = args2.slice(1).join(" ").trim();
|
|
852765
852945
|
ctx.print(renderList(query2 ? `Agent Personas matching "${query2}"` : "Agent Personas", registryStore, registryStore.search(query2)));
|
|
@@ -852864,7 +853044,7 @@ function registerPersonasRuntimeCommands(registry5) {
|
|
|
852864
853044
|
ctx.print(`Deleted Agent persona ${removed.id}: ${removed.name}`);
|
|
852865
853045
|
return;
|
|
852866
853046
|
}
|
|
852867
|
-
ctx.print("Usage: /personas [list|search <query>|show <id>|create|update|use|active|clear|review|stale|delete]");
|
|
853047
|
+
ctx.print("Usage: /personas [list|discover|import-discovered|search <query>|show <id>|create|update|use|active|clear|review|stale|delete]");
|
|
852868
853048
|
} catch (error51) {
|
|
852869
853049
|
printError2(ctx, error51);
|
|
852870
853050
|
}
|
|
@@ -852975,7 +853155,7 @@ function findDiscoveredSkill(skills, idOrName) {
|
|
|
852975
853155
|
return null;
|
|
852976
853156
|
return skills.find((skill) => discoveredSkillLookupValues(skill).includes(lookup)) ?? null;
|
|
852977
853157
|
}
|
|
852978
|
-
function
|
|
853158
|
+
function frontmatterList2(skill, key) {
|
|
852979
853159
|
const value = skill.frontmatter[key];
|
|
852980
853160
|
if (!value)
|
|
852981
853161
|
return [];
|
|
@@ -853011,8 +853191,8 @@ Run /agent-skills discover to inspect available skill files.`);
|
|
|
853011
853191
|
name: discovered.name,
|
|
853012
853192
|
description: discovered.description || `Imported skill from ${discovered.origin} skill file.`,
|
|
853013
853193
|
procedure: discovered.body,
|
|
853014
|
-
triggers:
|
|
853015
|
-
tags:
|
|
853194
|
+
triggers: frontmatterList2(discovered, "triggers"),
|
|
853195
|
+
tags: frontmatterList2(discovered, "tags"),
|
|
853016
853196
|
enabled: parsed.flags.get("enabled") === "true",
|
|
853017
853197
|
source: "imported",
|
|
853018
853198
|
provenance: `discovered:${discovered.origin}:${discovered.path}`
|
|
@@ -853317,6 +853497,98 @@ function registerAgentSkillsRuntimeCommands(registry5) {
|
|
|
853317
853497
|
});
|
|
853318
853498
|
}
|
|
853319
853499
|
|
|
853500
|
+
// src/agent/routine-discovery.ts
|
|
853501
|
+
import { promises as fsPromises6 } from "fs";
|
|
853502
|
+
import { join as join88 } from "path";
|
|
853503
|
+
var DIRECTORY_MARKERS2 = ["ROUTINE.md", "routine.md"];
|
|
853504
|
+
function parseFrontmatter3(content) {
|
|
853505
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
853506
|
+
if (!match)
|
|
853507
|
+
return {};
|
|
853508
|
+
const result2 = {};
|
|
853509
|
+
for (const line of match[1].split(`
|
|
853510
|
+
`)) {
|
|
853511
|
+
const [key, ...rest] = line.split(":");
|
|
853512
|
+
if (key && rest.length > 0) {
|
|
853513
|
+
result2[key.trim()] = rest.join(":").trim();
|
|
853514
|
+
}
|
|
853515
|
+
}
|
|
853516
|
+
return result2;
|
|
853517
|
+
}
|
|
853518
|
+
function getRoutineDirectories(cwd, homeDir) {
|
|
853519
|
+
return [
|
|
853520
|
+
{ root: join88(cwd, ".goodvibes", "routines"), origin: "project-local" },
|
|
853521
|
+
{ root: join88(cwd, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "routines"), origin: "project-local" },
|
|
853522
|
+
{ root: join88(homeDir, ".goodvibes", "routines"), origin: "global" },
|
|
853523
|
+
{ root: join88(homeDir, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "routines"), origin: "global" }
|
|
853524
|
+
];
|
|
853525
|
+
}
|
|
853526
|
+
async function readRoutineFile(path7, origin) {
|
|
853527
|
+
let content = "";
|
|
853528
|
+
try {
|
|
853529
|
+
content = await fsPromises6.readFile(path7, "utf-8");
|
|
853530
|
+
} catch {
|
|
853531
|
+
return null;
|
|
853532
|
+
}
|
|
853533
|
+
const frontmatter = parseFrontmatter3(content);
|
|
853534
|
+
const markdownBody = content.replace(/^---\n[\s\S]*?\n---\n?/, "").trim();
|
|
853535
|
+
const steps = (frontmatter.steps ?? markdownBody).trim();
|
|
853536
|
+
if (!steps)
|
|
853537
|
+
return null;
|
|
853538
|
+
const name51 = frontmatter.name ?? path7.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "routine";
|
|
853539
|
+
const description = frontmatter.description ?? frontmatter.summary ?? frontmatter.title ?? "";
|
|
853540
|
+
return {
|
|
853541
|
+
name: name51,
|
|
853542
|
+
description,
|
|
853543
|
+
path: path7,
|
|
853544
|
+
origin,
|
|
853545
|
+
steps,
|
|
853546
|
+
frontmatter
|
|
853547
|
+
};
|
|
853548
|
+
}
|
|
853549
|
+
async function scanRoutineDirectory(root, origin) {
|
|
853550
|
+
let entries = [];
|
|
853551
|
+
try {
|
|
853552
|
+
entries = await fsPromises6.readdir(root);
|
|
853553
|
+
} catch {
|
|
853554
|
+
return [];
|
|
853555
|
+
}
|
|
853556
|
+
const records = [];
|
|
853557
|
+
for (const entry of entries.sort((a4, b3) => a4.localeCompare(b3))) {
|
|
853558
|
+
if (entry.endsWith(".md")) {
|
|
853559
|
+
const record2 = await readRoutineFile(join88(root, entry), origin);
|
|
853560
|
+
if (record2)
|
|
853561
|
+
records.push(record2);
|
|
853562
|
+
continue;
|
|
853563
|
+
}
|
|
853564
|
+
for (const marker of DIRECTORY_MARKERS2) {
|
|
853565
|
+
const record2 = await readRoutineFile(join88(root, entry, marker), origin);
|
|
853566
|
+
if (record2) {
|
|
853567
|
+
records.push(record2);
|
|
853568
|
+
break;
|
|
853569
|
+
}
|
|
853570
|
+
}
|
|
853571
|
+
}
|
|
853572
|
+
return records;
|
|
853573
|
+
}
|
|
853574
|
+
async function discoverRoutines(shellPaths) {
|
|
853575
|
+
const seen = new Set;
|
|
853576
|
+
const records = [];
|
|
853577
|
+
for (const { root, origin } of getRoutineDirectories(shellPaths.workingDirectory, shellPaths.homeDirectory)) {
|
|
853578
|
+
for (const record2 of await scanRoutineDirectory(root, origin)) {
|
|
853579
|
+
const key = record2.name.toLowerCase();
|
|
853580
|
+
if (seen.has(key))
|
|
853581
|
+
continue;
|
|
853582
|
+
seen.add(key);
|
|
853583
|
+
records.push(record2);
|
|
853584
|
+
}
|
|
853585
|
+
}
|
|
853586
|
+
return records.sort((a4, b3) => {
|
|
853587
|
+
const originRank = a4.origin === b3.origin ? 0 : a4.origin === "project-local" ? -1 : 1;
|
|
853588
|
+
return originRank || a4.name.localeCompare(b3.name);
|
|
853589
|
+
});
|
|
853590
|
+
}
|
|
853591
|
+
|
|
853320
853592
|
// src/input/commands/routines-runtime.ts
|
|
853321
853593
|
function parseRoutineArgs(args2) {
|
|
853322
853594
|
const flags2 = new Map;
|
|
@@ -853400,9 +853672,86 @@ function renderRoutine(routine) {
|
|
|
853400
853672
|
].filter(Boolean).join(`
|
|
853401
853673
|
`);
|
|
853402
853674
|
}
|
|
853675
|
+
function summarizeDiscoveredRoutine(routine) {
|
|
853676
|
+
const description = routine.description ? ` - ${routine.description}` : "";
|
|
853677
|
+
return ` ${routine.name} ${routine.origin}${description}
|
|
853678
|
+
path: ${routine.path}`;
|
|
853679
|
+
}
|
|
853680
|
+
function renderDiscoveredRoutines(routines) {
|
|
853681
|
+
if (routines.length === 0) {
|
|
853682
|
+
return [
|
|
853683
|
+
"Discovered Agent routine files",
|
|
853684
|
+
" No routine markdown files found in project/global Agent routine folders.",
|
|
853685
|
+
" Search roots: .goodvibes/routines, .goodvibes/agent/routines, ~/.goodvibes/routines, ~/.goodvibes/agent/routines"
|
|
853686
|
+
].join(`
|
|
853687
|
+
`);
|
|
853688
|
+
}
|
|
853689
|
+
return [
|
|
853690
|
+
`Discovered Agent routine files (${routines.length})`,
|
|
853691
|
+
...routines.map(summarizeDiscoveredRoutine),
|
|
853692
|
+
"",
|
|
853693
|
+
"Import one with: /routines import-discovered <name> --yes"
|
|
853694
|
+
].join(`
|
|
853695
|
+
`);
|
|
853696
|
+
}
|
|
853697
|
+
function discoveredRoutineLookupValues(routine) {
|
|
853698
|
+
const slug = routine.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
853699
|
+
const basename5 = routine.path.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
|
|
853700
|
+
return [routine.name, slug, routine.path, basename5].map((value) => value.trim().toLowerCase()).filter(Boolean);
|
|
853701
|
+
}
|
|
853702
|
+
function findDiscoveredRoutine(routines, idOrName) {
|
|
853703
|
+
const lookup = idOrName.trim().toLowerCase();
|
|
853704
|
+
if (!lookup)
|
|
853705
|
+
return null;
|
|
853706
|
+
return routines.find((routine) => discoveredRoutineLookupValues(routine).includes(lookup)) ?? null;
|
|
853707
|
+
}
|
|
853708
|
+
function frontmatterList3(routine, key) {
|
|
853709
|
+
const value = routine.frontmatter[key];
|
|
853710
|
+
if (!value)
|
|
853711
|
+
return [];
|
|
853712
|
+
return splitList3(value);
|
|
853713
|
+
}
|
|
853403
853714
|
function printError4(ctx, error51) {
|
|
853404
853715
|
ctx.print(`Error: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
853405
853716
|
}
|
|
853717
|
+
async function importDiscoveredRoutine(args2, ctx, routineRegistry) {
|
|
853718
|
+
const parsed = parseRoutineArgs(args2);
|
|
853719
|
+
const name51 = parsed.rest.join(" ").trim();
|
|
853720
|
+
if (!name51) {
|
|
853721
|
+
ctx.print("Usage: /routines import-discovered <name> [--enabled] --yes");
|
|
853722
|
+
return;
|
|
853723
|
+
}
|
|
853724
|
+
const discovered = findDiscoveredRoutine(await discoverRoutines(requireShellPaths(ctx)), name51);
|
|
853725
|
+
if (!discovered) {
|
|
853726
|
+
ctx.print(`Unknown discovered Agent routine: ${name51}
|
|
853727
|
+
Run /routines discover to inspect available routine files.`);
|
|
853728
|
+
return;
|
|
853729
|
+
}
|
|
853730
|
+
if (!parsed.yes) {
|
|
853731
|
+
ctx.print([
|
|
853732
|
+
"Agent routine import preview",
|
|
853733
|
+
` name: ${discovered.name}`,
|
|
853734
|
+
` origin: ${discovered.origin}`,
|
|
853735
|
+
` path: ${discovered.path}`,
|
|
853736
|
+
` description: ${discovered.description || "(none)"}`,
|
|
853737
|
+
` steps characters: ${discovered.steps.length}`,
|
|
853738
|
+
" next: rerun with --yes to import into the Agent-local routine registry"
|
|
853739
|
+
].join(`
|
|
853740
|
+
`));
|
|
853741
|
+
return;
|
|
853742
|
+
}
|
|
853743
|
+
const routine = routineRegistry.create({
|
|
853744
|
+
name: discovered.name,
|
|
853745
|
+
description: discovered.description || `Imported routine from ${discovered.origin} markdown file.`,
|
|
853746
|
+
steps: discovered.steps,
|
|
853747
|
+
tags: frontmatterList3(discovered, "tags"),
|
|
853748
|
+
triggers: frontmatterList3(discovered, "triggers"),
|
|
853749
|
+
enabled: parsed.flags.get("enabled") === "true",
|
|
853750
|
+
source: "imported",
|
|
853751
|
+
provenance: `discovered:${discovered.origin}:${discovered.path}`
|
|
853752
|
+
});
|
|
853753
|
+
ctx.print(`Imported Agent routine ${routine.id}: ${routine.name}${routine.enabled ? " (enabled)" : ""}`);
|
|
853754
|
+
}
|
|
853406
853755
|
async function promoteRoutine(args2, routineRegistry, ctx) {
|
|
853407
853756
|
const parsed = parseRoutineSchedulePromotionArgs(args2);
|
|
853408
853757
|
if (parsed.errors.length > 0) {
|
|
@@ -853444,6 +853793,14 @@ async function runRoutinesRuntimeCommand(args2, ctx) {
|
|
|
853444
853793
|
ctx.print(renderList3("Enabled Agent Routines", routineRegistry, snapshot.enabledRoutines));
|
|
853445
853794
|
return;
|
|
853446
853795
|
}
|
|
853796
|
+
if (sub === "discover" || sub === "discovered") {
|
|
853797
|
+
ctx.print(renderDiscoveredRoutines(await discoverRoutines(requireShellPaths(ctx))));
|
|
853798
|
+
return;
|
|
853799
|
+
}
|
|
853800
|
+
if (sub === "import-discovered" || sub === "import-routine") {
|
|
853801
|
+
await importDiscoveredRoutine(args2.slice(1), ctx, routineRegistry);
|
|
853802
|
+
return;
|
|
853803
|
+
}
|
|
853447
853804
|
if (sub === "search") {
|
|
853448
853805
|
const query2 = args2.slice(1).join(" ").trim();
|
|
853449
853806
|
ctx.print(renderList3(query2 ? `Agent Routines matching "${query2}"` : "Agent Routines", routineRegistry, routineRegistry.search(query2)));
|
|
@@ -853579,7 +853936,7 @@ async function runRoutinesRuntimeCommand(args2, ctx) {
|
|
|
853579
853936
|
ctx.print(`Deleted Agent routine ${removed.id}: ${removed.name}`);
|
|
853580
853937
|
return;
|
|
853581
853938
|
}
|
|
853582
|
-
ctx.print("Usage: /routines [list|enabled|search|show|receipts|reconcile|receipt|create|update|enable|disable|start|review|stale|promote|delete]");
|
|
853939
|
+
ctx.print("Usage: /routines [list|enabled|discover|import-discovered|search|show|receipts|reconcile|receipt|create|update|enable|disable|start|review|stale|promote|delete]");
|
|
853583
853940
|
} catch (error51) {
|
|
853584
853941
|
printError4(ctx, error51);
|
|
853585
853942
|
}
|
|
@@ -853589,14 +853946,14 @@ function registerRoutinesRuntimeCommands(registry5) {
|
|
|
853589
853946
|
name: "routines",
|
|
853590
853947
|
aliases: ["routine"],
|
|
853591
853948
|
description: "Manage local GoodVibes Agent routines",
|
|
853592
|
-
usage: "[list|enabled|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps>|update <id> [--name ...] [--description ...] [--steps ...]|enable <id>|disable <id>|start <id>|review <id>|stale <id> <reason...>|promote <id> --cron <expr> [--delivery-channel slack] --yes|delete <id> --yes]",
|
|
853949
|
+
usage: "[list|enabled|discover|import-discovered <name> --yes|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps>|update <id> [--name ...] [--description ...] [--steps ...]|enable <id>|disable <id>|start <id>|review <id>|stale <id> <reason...>|promote <id> --cron <expr> [--delivery-channel slack] --yes|delete <id> --yes]",
|
|
853593
853950
|
handler: runRoutinesRuntimeCommand
|
|
853594
853951
|
});
|
|
853595
853952
|
}
|
|
853596
853953
|
|
|
853597
853954
|
// src/input/commands/channels-runtime.ts
|
|
853598
853955
|
import { existsSync as existsSync72, readFileSync as readFileSync79 } from "fs";
|
|
853599
|
-
import { join as
|
|
853956
|
+
import { join as join89 } from "path";
|
|
853600
853957
|
|
|
853601
853958
|
// src/input/agent-workspace-channels.ts
|
|
853602
853959
|
var AGENT_WORKSPACE_CHANNEL_SPECS = [
|
|
@@ -853807,7 +854164,7 @@ function resolveChannelDaemonConnection(context) {
|
|
|
853807
854164
|
const host = typeof hostValue === "string" && hostValue.trim().length > 0 ? hostValue.trim() : "127.0.0.1";
|
|
853808
854165
|
const port = typeof portValue === "number" && Number.isFinite(portValue) ? portValue : 3421;
|
|
853809
854166
|
const homeDirectory = context.workspace?.shellPaths?.homeDirectory ?? process.env.HOME ?? "";
|
|
853810
|
-
const tokenPath =
|
|
854167
|
+
const tokenPath = join89(homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
853811
854168
|
if (!existsSync72(tokenPath))
|
|
853812
854169
|
return { baseUrl: `http://${host}:${port}`, token: null, tokenPath };
|
|
853813
854170
|
try {
|
|
@@ -854903,7 +855260,7 @@ function registerBuiltinCommands(registry5) {
|
|
|
854903
855260
|
|
|
854904
855261
|
// src/input/input-history.ts
|
|
854905
855262
|
import { existsSync as existsSync73, mkdirSync as mkdirSync61, readFileSync as readFileSync80, writeFileSync as writeFileSync52 } from "fs";
|
|
854906
|
-
import { dirname as dirname59, join as
|
|
855263
|
+
import { dirname as dirname59, join as join90 } from "path";
|
|
854907
855264
|
class HistorySearch {
|
|
854908
855265
|
getEntries;
|
|
854909
855266
|
active = false;
|
|
@@ -854982,7 +855339,7 @@ function resolveHistoryPath2(options) {
|
|
|
854982
855339
|
if (!userRoot) {
|
|
854983
855340
|
throw new Error("InputHistory requires historyPath or an explicit userRoot/homeDirectory.");
|
|
854984
855341
|
}
|
|
854985
|
-
return
|
|
855342
|
+
return join90(userRoot, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "input-history.json");
|
|
854986
855343
|
}
|
|
854987
855344
|
|
|
854988
855345
|
class InputHistory {
|
|
@@ -863784,7 +864141,7 @@ function createBootstrapShell(options) {
|
|
|
863784
864141
|
hookActivityTracker: services.hookActivityTracker,
|
|
863785
864142
|
hookWorkbench: services.hookWorkbench,
|
|
863786
864143
|
mcpRegistry: services.mcpRegistry,
|
|
863787
|
-
daemonHomeDir:
|
|
864144
|
+
daemonHomeDir: join91(services.homeDirectory, ".goodvibes", "daemon")
|
|
863788
864145
|
});
|
|
863789
864146
|
services.panelManager.prewarmRegistered();
|
|
863790
864147
|
const systemMessageRouter = createSystemMessageRouter(conversation, systemMessagesPanel, (kind2) => {
|
|
@@ -866199,7 +866556,7 @@ import { dirname as dirname61 } from "path";
|
|
|
866199
866556
|
// src/runtime/onboarding/verify.ts
|
|
866200
866557
|
init_config8();
|
|
866201
866558
|
import { existsSync as existsSync75 } from "fs";
|
|
866202
|
-
import { join as
|
|
866559
|
+
import { join as join92 } from "path";
|
|
866203
866560
|
function getNow(deps) {
|
|
866204
866561
|
return deps.clock?.() ?? Date.now();
|
|
866205
866562
|
}
|
|
@@ -866280,7 +866637,7 @@ function verifyAuthOperation(_deps, operation) {
|
|
|
866280
866637
|
}
|
|
866281
866638
|
function verifyCreateAgentProfileOperation(deps, operation) {
|
|
866282
866639
|
const resolution2 = resolveAgentRuntimeProfileHome(deps.shellPaths.homeDirectory, operation.name);
|
|
866283
|
-
const ok3 = existsSync75(
|
|
866640
|
+
const ok3 = existsSync75(join92(resolution2.homeDirectory, "profile.json"));
|
|
866284
866641
|
return {
|
|
866285
866642
|
id: `agent-profile:${resolution2.id}`,
|
|
866286
866643
|
status: ok3 ? "pass" : "fail",
|
|
@@ -868337,7 +868694,7 @@ class AutocompleteEngine {
|
|
|
868337
868694
|
|
|
868338
868695
|
// src/input/file-picker.ts
|
|
868339
868696
|
import { readdir as readdir6 } from "fs/promises";
|
|
868340
|
-
import { join as
|
|
868697
|
+
import { join as join93, relative as relative15 } from "path";
|
|
868341
868698
|
|
|
868342
868699
|
class FilePickerModal {
|
|
868343
868700
|
shellPaths;
|
|
@@ -868470,7 +868827,7 @@ class FilePickerModal {
|
|
|
868470
868827
|
continue;
|
|
868471
868828
|
if (entry.name === "node_modules" || entry.name === "dist")
|
|
868472
868829
|
continue;
|
|
868473
|
-
const fullPath =
|
|
868830
|
+
const fullPath = join93(dir, entry.name);
|
|
868474
868831
|
const relPath = relative15(this.shellPaths.workingDirectory, fullPath);
|
|
868475
868832
|
if (entry.isDirectory()) {
|
|
868476
868833
|
files.push(relPath + "/");
|
|
@@ -871900,7 +872257,7 @@ function splitCommaList(value) {
|
|
|
871900
872257
|
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
871901
872258
|
}
|
|
871902
872259
|
function isAgentWorkspaceBasicCommandEditorKind(kind2) {
|
|
871903
|
-
return kind2 === "knowledge-bookmarks" || kind2 === "knowledge-file" || kind2 === "knowledge-browser-history" || kind2 === "knowledge-connector-ingest" || kind2 === "tts-prompt" || kind2 === "image-input" || kind2 === "skill-bundle" || kind2 === "skill-discovery-import" || kind2 === "profile-template-export" || kind2 === "profile-template-import" || kind2 === "mcp-server" || kind2 === "notify-webhook" || kind2 === "notify-webhook-remove" || kind2 === "notify-webhook-test";
|
|
872260
|
+
return kind2 === "knowledge-bookmarks" || kind2 === "knowledge-file" || kind2 === "knowledge-browser-history" || kind2 === "knowledge-connector-ingest" || kind2 === "tts-prompt" || kind2 === "image-input" || kind2 === "skill-bundle" || kind2 === "persona-discovery-import" || kind2 === "routine-discovery-import" || kind2 === "skill-discovery-import" || kind2 === "profile-template-export" || kind2 === "profile-template-import" || kind2 === "mcp-server" || kind2 === "notify-webhook" || kind2 === "notify-webhook-remove" || kind2 === "notify-webhook-test";
|
|
871904
872261
|
}
|
|
871905
872262
|
function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
871906
872263
|
if (kind2 === "knowledge-bookmarks") {
|
|
@@ -872090,6 +872447,34 @@ function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
|
872090
872447
|
]
|
|
872091
872448
|
};
|
|
872092
872449
|
}
|
|
872450
|
+
if (kind2 === "persona-discovery-import") {
|
|
872451
|
+
return {
|
|
872452
|
+
kind: kind2,
|
|
872453
|
+
mode: "create",
|
|
872454
|
+
title: "Import Discovered Persona",
|
|
872455
|
+
selectedFieldIndex: 0,
|
|
872456
|
+
message: "Import one discovered persona markdown file into the Agent-local persona registry. Type yes on the final field to confirm.",
|
|
872457
|
+
fields: [
|
|
872458
|
+
{ id: "name", label: "Discovered persona", value: "", required: true, multiline: false, hint: "Name shown by /personas discover." },
|
|
872459
|
+
{ id: "use", label: "Use now", value: "yes", required: false, multiline: false, hint: "yes/no." },
|
|
872460
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /personas import-discovered with --yes." }
|
|
872461
|
+
]
|
|
872462
|
+
};
|
|
872463
|
+
}
|
|
872464
|
+
if (kind2 === "routine-discovery-import") {
|
|
872465
|
+
return {
|
|
872466
|
+
kind: kind2,
|
|
872467
|
+
mode: "create",
|
|
872468
|
+
title: "Import Discovered Routine",
|
|
872469
|
+
selectedFieldIndex: 0,
|
|
872470
|
+
message: "Import one discovered routine markdown file into the Agent-local routine registry. Type yes on the final field to confirm.",
|
|
872471
|
+
fields: [
|
|
872472
|
+
{ id: "name", label: "Discovered routine", value: "", required: true, multiline: false, hint: "Name shown by /routines discover." },
|
|
872473
|
+
{ id: "enabled", label: "Enable now", value: "yes", required: false, multiline: false, hint: "yes/no." },
|
|
872474
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /routines import-discovered with --yes." }
|
|
872475
|
+
]
|
|
872476
|
+
};
|
|
872477
|
+
}
|
|
872093
872478
|
return {
|
|
872094
872479
|
kind: kind2,
|
|
872095
872480
|
mode: "create",
|
|
@@ -872460,6 +872845,66 @@ function buildAgentWorkspaceBasicCommandEditorSubmission(editor, readField, comm
|
|
|
872460
872845
|
}
|
|
872461
872846
|
};
|
|
872462
872847
|
}
|
|
872848
|
+
if (editor.kind === "persona-discovery-import") {
|
|
872849
|
+
if (!isAffirmative2(readField("confirm"))) {
|
|
872850
|
+
return {
|
|
872851
|
+
kind: "editor",
|
|
872852
|
+
editor: { ...editor, message: "Discovered persona import not confirmed. Type yes, then press Enter." },
|
|
872853
|
+
status: "Agent persona import not confirmed."
|
|
872854
|
+
};
|
|
872855
|
+
}
|
|
872856
|
+
const parts2 = [
|
|
872857
|
+
"/personas",
|
|
872858
|
+
"import-discovered",
|
|
872859
|
+
quoteSlashCommandArg(readField("name"))
|
|
872860
|
+
];
|
|
872861
|
+
if (isAffirmative2(readField("use")))
|
|
872862
|
+
parts2.push("--use");
|
|
872863
|
+
parts2.push("--yes");
|
|
872864
|
+
const command9 = parts2.join(" ");
|
|
872865
|
+
return {
|
|
872866
|
+
kind: "dispatch",
|
|
872867
|
+
command: command9,
|
|
872868
|
+
status: "Opening discovered persona import.",
|
|
872869
|
+
actionResult: {
|
|
872870
|
+
kind: "dispatched",
|
|
872871
|
+
title: "Opening discovered persona import",
|
|
872872
|
+
detail: "The workspace handed a confirmed local persona import command to the shell-owned command router.",
|
|
872873
|
+
command: command9,
|
|
872874
|
+
safety: "safe"
|
|
872875
|
+
}
|
|
872876
|
+
};
|
|
872877
|
+
}
|
|
872878
|
+
if (editor.kind === "routine-discovery-import") {
|
|
872879
|
+
if (!isAffirmative2(readField("confirm"))) {
|
|
872880
|
+
return {
|
|
872881
|
+
kind: "editor",
|
|
872882
|
+
editor: { ...editor, message: "Discovered routine import not confirmed. Type yes, then press Enter." },
|
|
872883
|
+
status: "Agent routine import not confirmed."
|
|
872884
|
+
};
|
|
872885
|
+
}
|
|
872886
|
+
const parts2 = [
|
|
872887
|
+
"/routines",
|
|
872888
|
+
"import-discovered",
|
|
872889
|
+
quoteSlashCommandArg(readField("name"))
|
|
872890
|
+
];
|
|
872891
|
+
if (isAffirmative2(readField("enabled")))
|
|
872892
|
+
parts2.push("--enabled");
|
|
872893
|
+
parts2.push("--yes");
|
|
872894
|
+
const command9 = parts2.join(" ");
|
|
872895
|
+
return {
|
|
872896
|
+
kind: "dispatch",
|
|
872897
|
+
command: command9,
|
|
872898
|
+
status: "Opening discovered routine import.",
|
|
872899
|
+
actionResult: {
|
|
872900
|
+
kind: "dispatched",
|
|
872901
|
+
title: "Opening discovered routine import",
|
|
872902
|
+
detail: "The workspace handed a confirmed local routine import command to the shell-owned command router.",
|
|
872903
|
+
command: command9,
|
|
872904
|
+
safety: "safe"
|
|
872905
|
+
}
|
|
872906
|
+
};
|
|
872907
|
+
}
|
|
872463
872908
|
const commandParts = [
|
|
872464
872909
|
"/agent-skills bundle create",
|
|
872465
872910
|
"--name",
|
|
@@ -873034,6 +873479,8 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
873034
873479
|
actions: [
|
|
873035
873480
|
{ id: "personas-list", label: "List personas", detail: "Print the full local persona library.", command: "/personas list", kind: "command", safety: "read-only" },
|
|
873036
873481
|
{ id: "personas-active", label: "Show active persona", detail: "Inspect the active local persona applied to new turns.", command: "/personas active", kind: "command", safety: "read-only" },
|
|
873482
|
+
{ id: "personas-discover", label: "Discover persona files", detail: "Scan project and global Agent persona folders for persona markdown without importing it.", command: "/personas discover", kind: "command", safety: "read-only" },
|
|
873483
|
+
{ id: "personas-import-discovered", label: "Import discovered persona", detail: "Open an in-workspace form that imports one reviewed persona markdown file into the Agent-local persona registry after typed confirmation.", editorKind: "persona-discovery-import", kind: "editor", safety: "safe" },
|
|
873037
873484
|
{ id: "personas-prev", label: "Previous persona", detail: "Move the local persona selection up without changing active state.", localKind: "persona", selectionDelta: -1, kind: "local-selection", safety: "safe" },
|
|
873038
873485
|
{ id: "personas-next", label: "Next persona", detail: "Move the local persona selection down without changing active state.", localKind: "persona", selectionDelta: 1, kind: "local-selection", safety: "safe" },
|
|
873039
873486
|
{ id: "personas-create", label: "Create persona", detail: "Open an in-workspace form for a local persona that writes Agent-local state only.", editorKind: "persona", kind: "editor", safety: "safe" },
|
|
@@ -873076,6 +873523,8 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
873076
873523
|
actions: [
|
|
873077
873524
|
{ id: "routines-list", label: "List routines", detail: "Print the full local Agent routine library.", command: "/routines list", kind: "command", safety: "read-only" },
|
|
873078
873525
|
{ id: "routines-enabled", label: "Enabled routines", detail: "Show routines available for direct use.", command: "/routines enabled", kind: "command", safety: "read-only" },
|
|
873526
|
+
{ id: "routines-discover", label: "Discover routine files", detail: "Scan project and global Agent routine folders for routine markdown without importing it.", command: "/routines discover", kind: "command", safety: "read-only" },
|
|
873527
|
+
{ id: "routines-import-discovered", label: "Import discovered routine", detail: "Open an in-workspace form that imports one reviewed routine markdown file into the Agent-local routine registry after typed confirmation.", editorKind: "routine-discovery-import", kind: "editor", safety: "safe" },
|
|
873079
873528
|
{ id: "routines-prev", label: "Previous routine", detail: "Move the local routine selection up without changing enabled state.", localKind: "routine", selectionDelta: -1, kind: "local-selection", safety: "safe" },
|
|
873080
873529
|
{ id: "routines-next", label: "Next routine", detail: "Move the local routine selection down without changing enabled state.", localKind: "routine", selectionDelta: 1, kind: "local-selection", safety: "safe" },
|
|
873081
873530
|
{ id: "routines-create", label: "Create routine", detail: "Open an in-workspace form for a repeatable local workflow that writes Agent-local state only.", editorKind: "routine", kind: "editor", safety: "safe" },
|
|
@@ -883063,7 +883512,7 @@ function wireShellUiOpeners(options) {
|
|
|
883063
883512
|
|
|
883064
883513
|
// src/cli/entrypoint.ts
|
|
883065
883514
|
import { existsSync as existsSync85 } from "fs";
|
|
883066
|
-
import { join as
|
|
883515
|
+
import { join as join101 } from "path";
|
|
883067
883516
|
// src/cli/parser.ts
|
|
883068
883517
|
var COMMAND_ALIASES = {
|
|
883069
883518
|
run: "run",
|
|
@@ -883428,7 +883877,7 @@ function parseGoodVibesCli(argv, binary2 = "goodvibes-agent") {
|
|
|
883428
883877
|
}
|
|
883429
883878
|
// src/cli/help.ts
|
|
883430
883879
|
import { existsSync as existsSync79, readFileSync as readFileSync87 } from "fs";
|
|
883431
|
-
import { dirname as dirname63, join as
|
|
883880
|
+
import { dirname as dirname63, join as join94 } from "path";
|
|
883432
883881
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
883433
883882
|
function readJsonVersion(path7) {
|
|
883434
883883
|
try {
|
|
@@ -883442,7 +883891,7 @@ function readJsonVersion(path7) {
|
|
|
883442
883891
|
}
|
|
883443
883892
|
function getPackageVersion() {
|
|
883444
883893
|
const here = dirname63(fileURLToPath4(import.meta.url));
|
|
883445
|
-
return readJsonVersion(
|
|
883894
|
+
return readJsonVersion(join94(here, "..", "..", "package.json")) ?? VERSION;
|
|
883446
883895
|
}
|
|
883447
883896
|
function renderGoodVibesVersion(binary2 = "goodvibes-agent") {
|
|
883448
883897
|
return `${binary2} ${getPackageVersion()}`;
|
|
@@ -883582,6 +884031,8 @@ var COMMAND_HELP = {
|
|
|
883582
884031
|
usage: [
|
|
883583
884032
|
"personas list",
|
|
883584
884033
|
"personas active",
|
|
884034
|
+
"personas discover",
|
|
884035
|
+
"personas import-discovered <name> [--use] --yes",
|
|
883585
884036
|
"personas search <query>",
|
|
883586
884037
|
"personas show <id>",
|
|
883587
884038
|
"personas create --name <name> --description <summary> --body <instructions> [--tags a,b] [--triggers a,b] [--use]",
|
|
@@ -883595,6 +884046,8 @@ var COMMAND_HELP = {
|
|
|
883595
884046
|
summary: "Manage Agent-local personas for the serial main conversation. Personas do not spawn worker agents.",
|
|
883596
884047
|
examples: [
|
|
883597
884048
|
"personas list",
|
|
884049
|
+
"personas discover",
|
|
884050
|
+
'personas import-discovered "Travel Planner" --use --yes',
|
|
883598
884051
|
'personas create --name "Travel Planner" --description "Plan trips" --body "Compare options before booking" --use',
|
|
883599
884052
|
"personas review travel-planner",
|
|
883600
884053
|
"personas delete travel-planner --yes"
|
|
@@ -883605,6 +884058,8 @@ var COMMAND_HELP = {
|
|
|
883605
884058
|
"skills list",
|
|
883606
884059
|
"skills enabled",
|
|
883607
884060
|
"skills active",
|
|
884061
|
+
"skills discover",
|
|
884062
|
+
"skills import-discovered <name> [--enabled] --yes",
|
|
883608
884063
|
"skills search <query>",
|
|
883609
884064
|
"skills show <id>",
|
|
883610
884065
|
"skills create --name <name> --description <summary> --procedure <steps> [--tags a,b] [--triggers a,b] [--enabled]",
|
|
@@ -883619,6 +884074,8 @@ var COMMAND_HELP = {
|
|
|
883619
884074
|
summary: "Manage reusable Agent-local procedures and skill bundles for the main conversation.",
|
|
883620
884075
|
examples: [
|
|
883621
884076
|
"skills list",
|
|
884077
|
+
"skills discover",
|
|
884078
|
+
'skills import-discovered "Daily Brief" --enabled --yes',
|
|
883622
884079
|
'skills create --name "Daily Brief" --description "Summarize operator state" --procedure "Review Agent Knowledge, work plans, approvals, and routines" --enabled',
|
|
883623
884080
|
'skills bundle create --name "Ops Pack" --description "Daily operations bundle" --skills daily-brief --enabled',
|
|
883624
884081
|
"skills delete daily-brief --yes"
|
|
@@ -883656,15 +884113,19 @@ var COMMAND_HELP = {
|
|
|
883656
884113
|
usage: [
|
|
883657
884114
|
"routines list",
|
|
883658
884115
|
"routines enabled",
|
|
884116
|
+
"routines discover",
|
|
884117
|
+
"routines import-discovered <name> [--enabled] --yes",
|
|
883659
884118
|
"routines show <id>",
|
|
883660
884119
|
"routines receipts",
|
|
883661
884120
|
"routines reconcile",
|
|
883662
884121
|
"routines receipt <receipt-id>",
|
|
883663
884122
|
"routines promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--timezone <tz>] [--name <schedule-name>] [--provider <id>] [--model <model>] [--delivery-channel <channel[:route[:label]]>|--delivery-route <route[:label]>|--delivery-webhook <url>|--delivery-link <url>] [--disabled] --yes"
|
|
883664
884123
|
],
|
|
883665
|
-
summary: "Inspect Agent-local routines, review local promotion receipts, reconcile receipts against live connected schedules, and explicitly promote a reviewed routine into a GoodVibes schedule. Without --yes, promote only prints the schedules.create preview.",
|
|
884124
|
+
summary: "Inspect and import Agent-local routines, review local promotion receipts, reconcile receipts against live connected schedules, and explicitly promote a reviewed routine into a GoodVibes schedule. Without --yes, promote only prints the schedules.create preview.",
|
|
883666
884125
|
examples: [
|
|
883667
884126
|
"routines list",
|
|
884127
|
+
"routines discover",
|
|
884128
|
+
'routines import-discovered "Daily Brief" --enabled --yes',
|
|
883668
884129
|
"routines show daily-operations-sweep",
|
|
883669
884130
|
"routines receipts",
|
|
883670
884131
|
"routines reconcile",
|
|
@@ -883882,8 +884343,6 @@ function bindLine(label, enabled, binding) {
|
|
|
883882
884343
|
function buildCliDoctorFindings(options) {
|
|
883883
884344
|
const config6 = options.configManager;
|
|
883884
884345
|
const serviceEnabled = config6.get("service.enabled") === true;
|
|
883885
|
-
const serviceAutostart = config6.get("service.autostart") === true;
|
|
883886
|
-
const restartOnFailure = config6.get("service.restartOnFailure") === true;
|
|
883887
884346
|
const daemonEnabled = config6.get("danger.daemon") === true;
|
|
883888
884347
|
const listenerEnabled = config6.get("danger.httpListener") === true;
|
|
883889
884348
|
const webEnabled = config6.get("web.enabled") === true;
|
|
@@ -883957,28 +884416,6 @@ function buildCliDoctorFindings(options) {
|
|
|
883957
884416
|
action: "Manage connected-service availability from GoodVibes TUI or the owning host, then use Agent for read-only diagnostics."
|
|
883958
884417
|
});
|
|
883959
884418
|
}
|
|
883960
|
-
if (serviceEnabled && !serviceAutostart) {
|
|
883961
|
-
findings.push({
|
|
883962
|
-
id: "runtime-autostart-disabled",
|
|
883963
|
-
area: "runtime",
|
|
883964
|
-
severity: "warning",
|
|
883965
|
-
summary: "Connected-service autostart is off.",
|
|
883966
|
-
cause: "service.enabled is true and service.autostart is false.",
|
|
883967
|
-
impact: "Connected GoodVibes services may not be available after login or reboot even though host-managed startup is selected.",
|
|
883968
|
-
action: "Configure autostart from GoodVibes TUI or the owning host; Agent will not mutate this setting."
|
|
883969
|
-
});
|
|
883970
|
-
}
|
|
883971
|
-
if (serviceEnabled && !restartOnFailure) {
|
|
883972
|
-
findings.push({
|
|
883973
|
-
id: "runtime-restart-disabled",
|
|
883974
|
-
area: "runtime",
|
|
883975
|
-
severity: "warning",
|
|
883976
|
-
summary: "Connected-service restart-on-failure is off.",
|
|
883977
|
-
cause: "service.enabled is true and service.restartOnFailure is false.",
|
|
883978
|
-
impact: "A crashed connected service or listener may stay down until manually restarted.",
|
|
883979
|
-
action: "Configure restart-on-failure from GoodVibes TUI or the owning host; Agent will not mutate this setting."
|
|
883980
|
-
});
|
|
883981
|
-
}
|
|
883982
884419
|
if (options.service) {
|
|
883983
884420
|
for (const issue2 of options.service.issues) {
|
|
883984
884421
|
if (findings.some((finding) => finding.summary === issue2))
|
|
@@ -884109,8 +884546,6 @@ function renderCliStatus(options) {
|
|
|
884109
884546
|
const config6 = options.configManager;
|
|
884110
884547
|
const snapshot2 = buildCliStatusSnapshot(options);
|
|
884111
884548
|
const serviceEnabled = snapshot2.runtimeConnection.enabled;
|
|
884112
|
-
const serviceAutostart = snapshot2.runtimeConnection.autostart;
|
|
884113
|
-
const restartOnFailure = snapshot2.runtimeConnection.restartOnFailure;
|
|
884114
884549
|
const controlPlaneEnabled = snapshot2.runtimeEndpoints.controlPlane.enabled;
|
|
884115
884550
|
const listenerEnabled = snapshot2.runtimeEndpoints.httpListener.enabled;
|
|
884116
884551
|
const webEnabled = snapshot2.runtimeEndpoints.web.enabled;
|
|
@@ -884169,7 +884604,7 @@ function renderCliStatus(options) {
|
|
|
884169
884604
|
` updatedAt: ${marker?.payload ? new Date(marker.payload.updatedAt).toISOString() : "n/a"}`
|
|
884170
884605
|
];
|
|
884171
884606
|
if (options.doctor) {
|
|
884172
|
-
lines.push("", "Connected-Service Config Signals:", ` host config present: ${yesNo(serviceEnabled)}`,
|
|
884607
|
+
lines.push("", "Connected-Service Config Signals:", ` host config present: ${yesNo(serviceEnabled)}`, " lifecycle config: external to Agent", "", "Endpoint Diagnostics:", bindLine("runtimeApi", controlPlaneEnabled, controlPlaneBinding), bindLine("incomingWebhook", listenerEnabled, httpListenerBinding), bindLine("browserCompanion", webEnabled, webBinding));
|
|
884173
884608
|
lines.push("", "Warnings:");
|
|
884174
884609
|
if (findings.length === 0) {
|
|
884175
884610
|
lines.push(" none");
|
|
@@ -884197,7 +884632,7 @@ function renderOnboardingCliStatus(options) {
|
|
|
884197
884632
|
}
|
|
884198
884633
|
// src/cli/external-runtime.ts
|
|
884199
884634
|
import { existsSync as existsSync80, readFileSync as readFileSync88 } from "fs";
|
|
884200
|
-
import { join as
|
|
884635
|
+
import { join as join95 } from "path";
|
|
884201
884636
|
function isRecord29(value) {
|
|
884202
884637
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
884203
884638
|
}
|
|
@@ -884211,7 +884646,7 @@ function resolveBaseUrl2(configManager) {
|
|
|
884211
884646
|
return `http://${host}:${Number.isFinite(port) ? port : 3421}`;
|
|
884212
884647
|
}
|
|
884213
884648
|
function readOperatorToken(homeDirectory) {
|
|
884214
|
-
const path7 =
|
|
884649
|
+
const path7 = join95(homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
884215
884650
|
if (!existsSync80(path7))
|
|
884216
884651
|
return { token: null, path: path7 };
|
|
884217
884652
|
try {
|
|
@@ -884589,7 +885024,7 @@ function applyRuntimeCommandEndpointFlagOverrides(configManager, command8, flags
|
|
|
884589
885024
|
}
|
|
884590
885025
|
// src/cli/bundle-command.ts
|
|
884591
885026
|
import { existsSync as existsSync82, mkdirSync as mkdirSync65, readFileSync as readFileSync89, writeFileSync as writeFileSync56 } from "fs";
|
|
884592
|
-
import { dirname as dirname64, join as
|
|
885027
|
+
import { dirname as dirname64, join as join97 } from "path";
|
|
884593
885028
|
|
|
884594
885029
|
// src/cli/provider-classification.ts
|
|
884595
885030
|
var SUBSCRIPTION_PROVIDERS = new Set([
|
|
@@ -884680,7 +885115,7 @@ function classifyProviderSetup(input) {
|
|
|
884680
885115
|
// src/cli/service-posture.ts
|
|
884681
885116
|
import { closeSync as closeSync4, existsSync as existsSync81, openSync as openSync4, readSync as readSync2, statSync as statSync21 } from "fs";
|
|
884682
885117
|
import net3 from "net";
|
|
884683
|
-
import { isAbsolute as isAbsolute13, join as
|
|
885118
|
+
import { isAbsolute as isAbsolute13, join as join96 } from "path";
|
|
884684
885119
|
|
|
884685
885120
|
// src/cli/redaction.ts
|
|
884686
885121
|
var REDACTED_VALUE = "<redacted>";
|
|
@@ -884850,7 +885285,7 @@ function resolveConfiguredLogPath(runtime3) {
|
|
|
884850
885285
|
const trimmed2 = value.trim();
|
|
884851
885286
|
if (!trimmed2)
|
|
884852
885287
|
return;
|
|
884853
|
-
return isAbsolute13(trimmed2) ? trimmed2 :
|
|
885288
|
+
return isAbsolute13(trimmed2) ? trimmed2 : join96(runtime3.homeDirectory, trimmed2);
|
|
884854
885289
|
}
|
|
884855
885290
|
function createExternalDaemonLifecycle(logPath) {
|
|
884856
885291
|
return {
|
|
@@ -884892,12 +885327,6 @@ async function buildCliServicePosture(runtime3, options = {}) {
|
|
|
884892
885327
|
if (serverBackedEnabled && !config6.enabled) {
|
|
884893
885328
|
issues.push("Connected-service settings are present, but Agent service ownership is disabled by design.");
|
|
884894
885329
|
}
|
|
884895
|
-
if (config6.enabled && !config6.autostart) {
|
|
884896
|
-
issues.push("Connected-service autostart is off.");
|
|
884897
|
-
}
|
|
884898
|
-
if (config6.enabled && !config6.restartOnFailure) {
|
|
884899
|
-
issues.push("Connected-service restart-on-failure is off.");
|
|
884900
|
-
}
|
|
884901
885330
|
for (const endpoint5 of endpoints5) {
|
|
884902
885331
|
if (endpoint5.enabled && options.probe && endpoint5.reachable === false) {
|
|
884903
885332
|
issues.push(`${endpoint5.label} is enabled but not reachable on ${endpoint5.binding.host}:${endpoint5.binding.port}.`);
|
|
@@ -884965,7 +885394,7 @@ function readAuthPosture(runtime3) {
|
|
|
884965
885394
|
});
|
|
884966
885395
|
const userStorePath = shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
|
|
884967
885396
|
const bootstrapCredentialPath = shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
|
|
884968
|
-
const operatorTokenPath =
|
|
885397
|
+
const operatorTokenPath = join97(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
884969
885398
|
return {
|
|
884970
885399
|
userStorePath,
|
|
884971
885400
|
userStorePresent: existsSync82(userStorePath),
|
|
@@ -885125,7 +885554,7 @@ async function handleBundleCommand(runtime3) {
|
|
|
885125
885554
|
}
|
|
885126
885555
|
// src/cli/management.ts
|
|
885127
885556
|
import { existsSync as existsSync84 } from "fs";
|
|
885128
|
-
import { join as
|
|
885557
|
+
import { join as join100 } from "path";
|
|
885129
885558
|
import { spawn as spawn5 } from "child_process";
|
|
885130
885559
|
import { networkInterfaces as networkInterfaces4 } from "os";
|
|
885131
885560
|
|
|
@@ -885152,7 +885581,7 @@ function formatProviderAuthRoute(route) {
|
|
|
885152
885581
|
|
|
885153
885582
|
// src/cli/management-commands.ts
|
|
885154
885583
|
import { mkdirSync as mkdirSync66, writeFileSync as writeFileSync57 } from "fs";
|
|
885155
|
-
import { dirname as dirname65, join as
|
|
885584
|
+
import { dirname as dirname65, join as join98 } from "path";
|
|
885156
885585
|
init_config8();
|
|
885157
885586
|
init_config8();
|
|
885158
885587
|
init_config8();
|
|
@@ -885469,7 +885898,7 @@ async function handleTasks(runtime3) {
|
|
|
885469
885898
|
});
|
|
885470
885899
|
}
|
|
885471
885900
|
async function renderPairing(runtime3) {
|
|
885472
|
-
const daemonHomeDir =
|
|
885901
|
+
const daemonHomeDir = join98(runtime3.homeDirectory, ".goodvibes", "daemon");
|
|
885473
885902
|
const tokenRecord = getOrCreateCompanionToken(GOODVIBES_AGENT_PAIRING_SURFACE, { daemonHomeDir });
|
|
885474
885903
|
const binding = resolveRuntimeEndpointBinding(runtime3.configManager, "controlPlane");
|
|
885475
885904
|
const daemonUrl = `http://${urlHostForBindHost2(binding.host)}:${binding.port}`;
|
|
@@ -886008,7 +886437,7 @@ var DELEGATION_METHOD = {
|
|
|
886008
886437
|
|
|
886009
886438
|
// src/cli/agent-knowledge-runtime.ts
|
|
886010
886439
|
import { existsSync as existsSync83, readFileSync as readFileSync90 } from "fs";
|
|
886011
|
-
import { join as
|
|
886440
|
+
import { join as join99 } from "path";
|
|
886012
886441
|
|
|
886013
886442
|
// node_modules/@pellux/goodvibes-sdk/dist/browser-scoped.js
|
|
886014
886443
|
init_dist();
|
|
@@ -886374,7 +886803,7 @@ function resolveDaemonConnection(runtime3) {
|
|
|
886374
886803
|
const host = String(runtime3.configManager.get("controlPlane.host") ?? "127.0.0.1");
|
|
886375
886804
|
const port = Number(runtime3.configManager.get("controlPlane.port") ?? 3421);
|
|
886376
886805
|
const baseUrl = `http://${host}:${Number.isFinite(port) ? port : 3421}`;
|
|
886377
|
-
const tokenPath =
|
|
886806
|
+
const tokenPath = join99(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
886378
886807
|
if (!existsSync83(tokenPath))
|
|
886379
886808
|
return { baseUrl, token: null, tokenPath };
|
|
886380
886809
|
try {
|
|
@@ -887113,6 +887542,12 @@ function skillRegistry(runtime3) {
|
|
|
887113
887542
|
homeDirectory: runtime3.homeDirectory
|
|
887114
887543
|
}));
|
|
887115
887544
|
}
|
|
887545
|
+
function shellPaths(runtime3) {
|
|
887546
|
+
return createShellPathService2({
|
|
887547
|
+
workingDirectory: runtime3.workingDirectory,
|
|
887548
|
+
homeDirectory: runtime3.homeDirectory
|
|
887549
|
+
});
|
|
887550
|
+
}
|
|
887116
887551
|
function summarizePersona2(persona, activePersonaId) {
|
|
887117
887552
|
const active = persona.id === activePersonaId ? "active" : "available";
|
|
887118
887553
|
const tags = persona.tags.length > 0 ? ` tags=${persona.tags.join(",")}` : "";
|
|
@@ -887154,6 +887589,48 @@ function renderPersona2(persona, activePersonaId) {
|
|
|
887154
887589
|
].filter((line2) => Boolean(line2)).join(`
|
|
887155
887590
|
`);
|
|
887156
887591
|
}
|
|
887592
|
+
function summarizeDiscoveredPersona2(persona) {
|
|
887593
|
+
const description = persona.description ? ` - ${persona.description}` : "";
|
|
887594
|
+
return [
|
|
887595
|
+
` ${persona.name} ${persona.origin}${description}`,
|
|
887596
|
+
` path: ${persona.path}`
|
|
887597
|
+
].join(`
|
|
887598
|
+
`);
|
|
887599
|
+
}
|
|
887600
|
+
function renderDiscoveredPersonaList(personas) {
|
|
887601
|
+
if (personas.length === 0) {
|
|
887602
|
+
return [
|
|
887603
|
+
"Discovered Agent persona files",
|
|
887604
|
+
" No persona markdown files found in Agent persona folders.",
|
|
887605
|
+
" Search roots: .goodvibes/personas, .goodvibes/agent/personas, .goodvibes/agents, ~/.goodvibes/personas, ~/.goodvibes/agent/personas, ~/.goodvibes/agents"
|
|
887606
|
+
].join(`
|
|
887607
|
+
`);
|
|
887608
|
+
}
|
|
887609
|
+
return [
|
|
887610
|
+
`Discovered Agent persona files (${personas.length})`,
|
|
887611
|
+
...personas.map(summarizeDiscoveredPersona2),
|
|
887612
|
+
"",
|
|
887613
|
+
"Import one with: goodvibes-agent personas import-discovered <name> --yes"
|
|
887614
|
+
].join(`
|
|
887615
|
+
`);
|
|
887616
|
+
}
|
|
887617
|
+
function discoveredPersonaLookupValues2(persona) {
|
|
887618
|
+
const slug = persona.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
887619
|
+
const basename6 = persona.path.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
|
|
887620
|
+
return [persona.name, slug, persona.path, basename6].map((value) => value.trim().toLowerCase()).filter(Boolean);
|
|
887621
|
+
}
|
|
887622
|
+
function findDiscoveredPersona2(personas, idOrName) {
|
|
887623
|
+
const lookup = idOrName.trim().toLowerCase();
|
|
887624
|
+
if (!lookup)
|
|
887625
|
+
return null;
|
|
887626
|
+
return personas.find((persona) => discoveredPersonaLookupValues2(persona).includes(lookup)) ?? null;
|
|
887627
|
+
}
|
|
887628
|
+
function discoveredPersonaFrontmatterList(persona, key) {
|
|
887629
|
+
const value = persona.frontmatter[key];
|
|
887630
|
+
if (!value)
|
|
887631
|
+
return [];
|
|
887632
|
+
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
887633
|
+
}
|
|
887157
887634
|
function summarizeSkill2(skill) {
|
|
887158
887635
|
const enabled = skill.enabled ? "enabled" : "disabled";
|
|
887159
887636
|
const tags = skill.tags.length > 0 ? ` tags=${skill.tags.join(",")}` : "";
|
|
@@ -887179,6 +887656,50 @@ function renderSkillList(title, path7, skills) {
|
|
|
887179
887656
|
].join(`
|
|
887180
887657
|
`);
|
|
887181
887658
|
}
|
|
887659
|
+
function summarizeDiscoveredSkill2(skill) {
|
|
887660
|
+
const description = skill.description ? ` - ${skill.description}` : "";
|
|
887661
|
+
const dependencies = skill.dependencies.length > 0 ? ` deps=${skill.dependencies.join(",")}` : "";
|
|
887662
|
+
const includes = skill.includes.length > 0 ? ` includes=${skill.includes.join(",")}` : "";
|
|
887663
|
+
return [
|
|
887664
|
+
` ${skill.name} ${skill.origin}${description}${dependencies}${includes}`,
|
|
887665
|
+
` path: ${skill.path}`
|
|
887666
|
+
].join(`
|
|
887667
|
+
`);
|
|
887668
|
+
}
|
|
887669
|
+
function renderDiscoveredSkillList(skills) {
|
|
887670
|
+
if (skills.length === 0) {
|
|
887671
|
+
return [
|
|
887672
|
+
"Discovered Agent skill files",
|
|
887673
|
+
" No SKILL.md or .md skill files found in Agent skill folders.",
|
|
887674
|
+
" Search roots: .goodvibes/skills, .goodvibes/agent/skills, ~/.goodvibes/skills, ~/.goodvibes/agent/skills"
|
|
887675
|
+
].join(`
|
|
887676
|
+
`);
|
|
887677
|
+
}
|
|
887678
|
+
return [
|
|
887679
|
+
`Discovered Agent skill files (${skills.length})`,
|
|
887680
|
+
...skills.map(summarizeDiscoveredSkill2),
|
|
887681
|
+
"",
|
|
887682
|
+
"Import one with: goodvibes-agent skills import-discovered <name> --yes"
|
|
887683
|
+
].join(`
|
|
887684
|
+
`);
|
|
887685
|
+
}
|
|
887686
|
+
function discoveredSkillLookupValues2(skill) {
|
|
887687
|
+
const slug = skill.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
887688
|
+
const basename6 = skill.path.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
|
|
887689
|
+
return [skill.name, slug, skill.path, basename6].map((value) => value.trim().toLowerCase()).filter(Boolean);
|
|
887690
|
+
}
|
|
887691
|
+
function findDiscoveredSkill2(skills, idOrName) {
|
|
887692
|
+
const lookup = idOrName.trim().toLowerCase();
|
|
887693
|
+
if (!lookup)
|
|
887694
|
+
return null;
|
|
887695
|
+
return skills.find((skill) => discoveredSkillLookupValues2(skill).includes(lookup)) ?? null;
|
|
887696
|
+
}
|
|
887697
|
+
function discoveredFrontmatterList(skill, key) {
|
|
887698
|
+
const value = skill.frontmatter[key];
|
|
887699
|
+
if (!value)
|
|
887700
|
+
return [];
|
|
887701
|
+
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
887702
|
+
}
|
|
887182
887703
|
function renderBundleList2(title, path7, bundles) {
|
|
887183
887704
|
if (bundles.length === 0) {
|
|
887184
887705
|
return [
|
|
@@ -887233,10 +887754,10 @@ function renderBundle2(bundle) {
|
|
|
887233
887754
|
`);
|
|
887234
887755
|
}
|
|
887235
887756
|
function usagePersonas() {
|
|
887236
|
-
return "Usage: goodvibes-agent personas [list|active|search <query>|show <id>|create|update <id>|use <id>|clear|review <id>|stale <id> <reason>|delete <id> --yes]";
|
|
887757
|
+
return "Usage: goodvibes-agent personas [list|active|discover|import-discovered <name> --yes|search <query>|show <id>|create|update <id>|use <id>|clear|review <id>|stale <id> <reason>|delete <id> --yes]";
|
|
887237
887758
|
}
|
|
887238
887759
|
function usageSkills() {
|
|
887239
|
-
return "Usage: goodvibes-agent skills [list|enabled|active|search <query>|show <id>|create|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes|bundle ...]";
|
|
887760
|
+
return "Usage: goodvibes-agent skills [list|enabled|active|discover|import-discovered <name> --yes|search <query>|show <id>|create|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes|bundle ...]";
|
|
887240
887761
|
}
|
|
887241
887762
|
function usageBundles() {
|
|
887242
887763
|
return "Usage: goodvibes-agent skills bundle [list|enabled|search <query>|show <id>|create|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes]";
|
|
@@ -887262,6 +887783,45 @@ async function handlePersonasCommand(runtime3) {
|
|
|
887262
887783
|
return failure(runtime3, "agent.personas.active_missing", "No active Agent persona.", 1);
|
|
887263
887784
|
return success3(runtime3, "agent.personas.active", active, renderPersona2(active, active.id));
|
|
887264
887785
|
}
|
|
887786
|
+
if (normalized === "discover") {
|
|
887787
|
+
const discovered = await discoverPersonas(shellPaths(runtime3));
|
|
887788
|
+
return success3(runtime3, "agent.personas.discover", { personas: discovered }, renderDiscoveredPersonaList(discovered));
|
|
887789
|
+
}
|
|
887790
|
+
if (normalized === "import-discovered" || normalized === "import-persona") {
|
|
887791
|
+
const options = parseOptions(rest);
|
|
887792
|
+
const name51 = options.positionals.join(" ").trim();
|
|
887793
|
+
if (!name51)
|
|
887794
|
+
return failure(runtime3, "invalid_persona_command", "Usage: goodvibes-agent personas import-discovered <name> [--use] --yes", 2);
|
|
887795
|
+
const discovered = findDiscoveredPersona2(await discoverPersonas(shellPaths(runtime3)), name51);
|
|
887796
|
+
if (!discovered) {
|
|
887797
|
+
return failure(runtime3, "persona_discovery_not_found", `Unknown discovered Agent persona: ${name51}
|
|
887798
|
+
Run goodvibes-agent personas discover to inspect available persona files.`, 1);
|
|
887799
|
+
}
|
|
887800
|
+
if (!hasFlag3(options, "yes")) {
|
|
887801
|
+
return success3(runtime3, "agent.personas.import_discovered.preview", { persona: discovered }, [
|
|
887802
|
+
"Agent persona import preview",
|
|
887803
|
+
` name: ${discovered.name}`,
|
|
887804
|
+
` origin: ${discovered.origin}`,
|
|
887805
|
+
` path: ${discovered.path}`,
|
|
887806
|
+
` description: ${discovered.description || "(none)"}`,
|
|
887807
|
+
` body characters: ${discovered.body.length}`,
|
|
887808
|
+
" next: rerun with --yes to import into the Agent-local persona registry"
|
|
887809
|
+
].join(`
|
|
887810
|
+
`));
|
|
887811
|
+
}
|
|
887812
|
+
const persona = registry5.create({
|
|
887813
|
+
name: discovered.name,
|
|
887814
|
+
description: discovered.description || `Imported persona from ${discovered.origin} markdown file.`,
|
|
887815
|
+
body: discovered.body,
|
|
887816
|
+
tags: discoveredPersonaFrontmatterList(discovered, "tags"),
|
|
887817
|
+
triggers: discoveredPersonaFrontmatterList(discovered, "triggers"),
|
|
887818
|
+
source: "imported",
|
|
887819
|
+
provenance: `discovered:${discovered.origin}:${discovered.path}`
|
|
887820
|
+
});
|
|
887821
|
+
if (hasFlag3(options, "use"))
|
|
887822
|
+
registry5.setActive(persona.id);
|
|
887823
|
+
return success3(runtime3, "agent.personas.import_discovered", persona, `Imported Agent persona ${persona.id}: ${persona.name}${hasFlag3(options, "use") ? " (active)" : ""}`);
|
|
887824
|
+
}
|
|
887265
887825
|
if (normalized === "search" || normalized === "find") {
|
|
887266
887826
|
const query2 = rest.join(" ").trim();
|
|
887267
887827
|
const results = registry5.search(query2);
|
|
@@ -887466,6 +888026,44 @@ async function handleSkillsCommand(runtime3) {
|
|
|
887466
888026
|
|
|
887467
888027
|
`));
|
|
887468
888028
|
}
|
|
888029
|
+
if (normalized === "discover") {
|
|
888030
|
+
const discovered = await discoverSkills(shellPaths(runtime3));
|
|
888031
|
+
return success3(runtime3, "agent.skills.discover", { skills: discovered }, renderDiscoveredSkillList(discovered));
|
|
888032
|
+
}
|
|
888033
|
+
if (normalized === "import-discovered" || normalized === "import-skill") {
|
|
888034
|
+
const options = parseOptions(rest);
|
|
888035
|
+
const name51 = options.positionals.join(" ").trim();
|
|
888036
|
+
if (!name51)
|
|
888037
|
+
return failure(runtime3, "invalid_skill_command", "Usage: goodvibes-agent skills import-discovered <name> [--enabled] --yes", 2);
|
|
888038
|
+
const discovered = findDiscoveredSkill2(await discoverSkills(shellPaths(runtime3)), name51);
|
|
888039
|
+
if (!discovered) {
|
|
888040
|
+
return failure(runtime3, "skill_discovery_not_found", `Unknown discovered Agent skill: ${name51}
|
|
888041
|
+
Run goodvibes-agent skills discover to inspect available skill files.`, 1);
|
|
888042
|
+
}
|
|
888043
|
+
if (!hasFlag3(options, "yes")) {
|
|
888044
|
+
return success3(runtime3, "agent.skills.import_discovered.preview", { skill: discovered }, [
|
|
888045
|
+
"Agent skill import preview",
|
|
888046
|
+
` name: ${discovered.name}`,
|
|
888047
|
+
` origin: ${discovered.origin}`,
|
|
888048
|
+
` path: ${discovered.path}`,
|
|
888049
|
+
` description: ${discovered.description || "(none)"}`,
|
|
888050
|
+
` procedure characters: ${discovered.body.length}`,
|
|
888051
|
+
" next: rerun with --yes to import into the Agent-local skill registry"
|
|
888052
|
+
].join(`
|
|
888053
|
+
`));
|
|
888054
|
+
}
|
|
888055
|
+
const skill = registry5.create({
|
|
888056
|
+
name: discovered.name,
|
|
888057
|
+
description: discovered.description || `Imported skill from ${discovered.origin} skill file.`,
|
|
888058
|
+
procedure: discovered.body,
|
|
888059
|
+
tags: discoveredFrontmatterList(discovered, "tags"),
|
|
888060
|
+
triggers: discoveredFrontmatterList(discovered, "triggers"),
|
|
888061
|
+
enabled: hasFlag3(options, "enabled"),
|
|
888062
|
+
source: "imported",
|
|
888063
|
+
provenance: `discovered:${discovered.origin}:${discovered.path}`
|
|
888064
|
+
});
|
|
888065
|
+
return success3(runtime3, "agent.skills.import_discovered", skill, `Imported Agent skill ${skill.id}: ${skill.name}${skill.enabled ? " (enabled)" : ""}`);
|
|
888066
|
+
}
|
|
887469
888067
|
if (normalized === "search" || normalized === "find") {
|
|
887470
888068
|
const query2 = rest.join(" ").trim();
|
|
887471
888069
|
const results = registry5.search(query2);
|
|
@@ -888451,17 +889049,87 @@ function routineRegistry(runtime3) {
|
|
|
888451
889049
|
homeDirectory: runtime3.homeDirectory
|
|
888452
889050
|
}));
|
|
888453
889051
|
}
|
|
889052
|
+
function shellPaths2(runtime3) {
|
|
889053
|
+
return createShellPathService2({
|
|
889054
|
+
workingDirectory: runtime3.workingDirectory,
|
|
889055
|
+
homeDirectory: runtime3.homeDirectory
|
|
889056
|
+
});
|
|
889057
|
+
}
|
|
888454
889058
|
function routineReceiptStore(runtime3) {
|
|
888455
889059
|
return RoutineScheduleReceiptStore.fromShellPaths(createShellPathService2({
|
|
888456
889060
|
workingDirectory: runtime3.workingDirectory,
|
|
888457
889061
|
homeDirectory: runtime3.homeDirectory
|
|
888458
889062
|
}));
|
|
888459
889063
|
}
|
|
889064
|
+
function splitList6(value) {
|
|
889065
|
+
if (!value)
|
|
889066
|
+
return [];
|
|
889067
|
+
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
889068
|
+
}
|
|
889069
|
+
function parseImportFlags(args2) {
|
|
889070
|
+
const positionals = [];
|
|
889071
|
+
let enabled = false;
|
|
889072
|
+
let yes = false;
|
|
889073
|
+
for (const arg of args2) {
|
|
889074
|
+
if (arg === "--enabled") {
|
|
889075
|
+
enabled = true;
|
|
889076
|
+
continue;
|
|
889077
|
+
}
|
|
889078
|
+
if (arg === "--yes") {
|
|
889079
|
+
yes = true;
|
|
889080
|
+
continue;
|
|
889081
|
+
}
|
|
889082
|
+
positionals.push(arg);
|
|
889083
|
+
}
|
|
889084
|
+
return { name: positionals.join(" ").trim(), enabled, yes };
|
|
889085
|
+
}
|
|
888460
889086
|
function summarizeRoutine2(routine) {
|
|
888461
889087
|
const enabled = routine.enabled ? "enabled" : "disabled";
|
|
888462
889088
|
const tags = routine.tags.length > 0 ? ` tags=${routine.tags.join(",")}` : "";
|
|
888463
889089
|
return ` ${routine.id} ${enabled} ${routine.reviewState} starts=${routine.startCount} ${routine.name} - ${routine.description}${tags}`;
|
|
888464
889090
|
}
|
|
889091
|
+
function summarizeDiscoveredRoutine2(routine) {
|
|
889092
|
+
const description = routine.description ? ` - ${routine.description}` : "";
|
|
889093
|
+
return [
|
|
889094
|
+
` ${routine.name} ${routine.origin}${description}`,
|
|
889095
|
+
` path: ${routine.path}`
|
|
889096
|
+
].join(`
|
|
889097
|
+
`);
|
|
889098
|
+
}
|
|
889099
|
+
function renderDiscoveredRoutineList(routines) {
|
|
889100
|
+
if (routines.length === 0) {
|
|
889101
|
+
return [
|
|
889102
|
+
"Discovered Agent routine files",
|
|
889103
|
+
" No routine markdown files found in Agent routine folders.",
|
|
889104
|
+
" Search roots: .goodvibes/routines, .goodvibes/agent/routines, ~/.goodvibes/routines, ~/.goodvibes/agent/routines"
|
|
889105
|
+
].join(`
|
|
889106
|
+
`);
|
|
889107
|
+
}
|
|
889108
|
+
return [
|
|
889109
|
+
`Discovered Agent routine files (${routines.length})`,
|
|
889110
|
+
...routines.map(summarizeDiscoveredRoutine2),
|
|
889111
|
+
"",
|
|
889112
|
+
"Import one with: goodvibes-agent routines import-discovered <name> --yes"
|
|
889113
|
+
].join(`
|
|
889114
|
+
`);
|
|
889115
|
+
}
|
|
889116
|
+
function discoveredRoutineLookupValues2(routine) {
|
|
889117
|
+
const slug = routine.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
889118
|
+
const basename6 = routine.path.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
|
|
889119
|
+
return [routine.name, slug, routine.path, basename6].map((value) => value.trim().toLowerCase()).filter(Boolean);
|
|
889120
|
+
}
|
|
889121
|
+
function findDiscoveredRoutine2(routines, idOrName) {
|
|
889122
|
+
const lookup = idOrName.trim().toLowerCase();
|
|
889123
|
+
if (!lookup)
|
|
889124
|
+
return null;
|
|
889125
|
+
return routines.find((routine) => discoveredRoutineLookupValues2(routine).includes(lookup)) ?? null;
|
|
889126
|
+
}
|
|
889127
|
+
function discoveredRoutineFrontmatterList(routine, key) {
|
|
889128
|
+
const value = routine.frontmatter[key];
|
|
889129
|
+
if (!value)
|
|
889130
|
+
return [];
|
|
889131
|
+
return splitList6(value);
|
|
889132
|
+
}
|
|
888465
889133
|
function renderRoutineList(title, path7, routines) {
|
|
888466
889134
|
if (routines.length === 0) {
|
|
888467
889135
|
return [
|
|
@@ -888580,6 +889248,84 @@ async function handleRoutinesCommand(runtime3) {
|
|
|
888580
889248
|
exitCode: 0
|
|
888581
889249
|
};
|
|
888582
889250
|
}
|
|
889251
|
+
if (normalized === "discover") {
|
|
889252
|
+
const discovered = await discoverRoutines(shellPaths2(runtime3));
|
|
889253
|
+
const value = {
|
|
889254
|
+
ok: true,
|
|
889255
|
+
kind: "agent.routines.discover",
|
|
889256
|
+
data: { routines: discovered }
|
|
889257
|
+
};
|
|
889258
|
+
return {
|
|
889259
|
+
output: jsonOrText3(runtime3, value, renderDiscoveredRoutineList(discovered)),
|
|
889260
|
+
exitCode: 0
|
|
889261
|
+
};
|
|
889262
|
+
}
|
|
889263
|
+
if (normalized === "import-discovered" || normalized === "import-routine") {
|
|
889264
|
+
const parsed = parseImportFlags(rest);
|
|
889265
|
+
if (!parsed.name) {
|
|
889266
|
+
const failure3 = {
|
|
889267
|
+
ok: false,
|
|
889268
|
+
kind: "invalid_routine_command",
|
|
889269
|
+
error: "Usage: goodvibes-agent routines import-discovered <name> [--enabled] --yes"
|
|
889270
|
+
};
|
|
889271
|
+
return {
|
|
889272
|
+
output: runtime3.cli.flags.outputFormat === "json" ? JSON.stringify(failure3, null, 2) : failure3.error,
|
|
889273
|
+
exitCode: 2
|
|
889274
|
+
};
|
|
889275
|
+
}
|
|
889276
|
+
const discovered = findDiscoveredRoutine2(await discoverRoutines(shellPaths2(runtime3)), parsed.name);
|
|
889277
|
+
if (!discovered) {
|
|
889278
|
+
const failure3 = {
|
|
889279
|
+
ok: false,
|
|
889280
|
+
kind: "routine_discovery_not_found",
|
|
889281
|
+
error: `Unknown discovered Agent routine: ${parsed.name}
|
|
889282
|
+
Run goodvibes-agent routines discover to inspect available routine files.`
|
|
889283
|
+
};
|
|
889284
|
+
return {
|
|
889285
|
+
output: runtime3.cli.flags.outputFormat === "json" ? JSON.stringify(failure3, null, 2) : failure3.error,
|
|
889286
|
+
exitCode: 1
|
|
889287
|
+
};
|
|
889288
|
+
}
|
|
889289
|
+
if (!parsed.yes) {
|
|
889290
|
+
const value2 = {
|
|
889291
|
+
ok: true,
|
|
889292
|
+
kind: "agent.routines.import_discovered.preview",
|
|
889293
|
+
data: { routine: discovered }
|
|
889294
|
+
};
|
|
889295
|
+
return {
|
|
889296
|
+
output: jsonOrText3(runtime3, value2, [
|
|
889297
|
+
"Agent routine import preview",
|
|
889298
|
+
` name: ${discovered.name}`,
|
|
889299
|
+
` origin: ${discovered.origin}`,
|
|
889300
|
+
` path: ${discovered.path}`,
|
|
889301
|
+
` description: ${discovered.description || "(none)"}`,
|
|
889302
|
+
` steps characters: ${discovered.steps.length}`,
|
|
889303
|
+
" next: rerun with --yes to import into the Agent-local routine registry"
|
|
889304
|
+
].join(`
|
|
889305
|
+
`)),
|
|
889306
|
+
exitCode: 0
|
|
889307
|
+
};
|
|
889308
|
+
}
|
|
889309
|
+
const routine = registry5.create({
|
|
889310
|
+
name: discovered.name,
|
|
889311
|
+
description: discovered.description || `Imported routine from ${discovered.origin} markdown file.`,
|
|
889312
|
+
steps: discovered.steps,
|
|
889313
|
+
tags: discoveredRoutineFrontmatterList(discovered, "tags"),
|
|
889314
|
+
triggers: discoveredRoutineFrontmatterList(discovered, "triggers"),
|
|
889315
|
+
enabled: parsed.enabled,
|
|
889316
|
+
source: "imported",
|
|
889317
|
+
provenance: `discovered:${discovered.origin}:${discovered.path}`
|
|
889318
|
+
});
|
|
889319
|
+
const value = {
|
|
889320
|
+
ok: true,
|
|
889321
|
+
kind: "agent.routines.import_discovered",
|
|
889322
|
+
data: routine
|
|
889323
|
+
};
|
|
889324
|
+
return {
|
|
889325
|
+
output: jsonOrText3(runtime3, value, `Imported Agent routine ${routine.id}: ${routine.name}${routine.enabled ? " (enabled)" : ""}`),
|
|
889326
|
+
exitCode: 0
|
|
889327
|
+
};
|
|
889328
|
+
}
|
|
888583
889329
|
if (normalized === "show") {
|
|
888584
889330
|
const id = rest[0];
|
|
888585
889331
|
if (!id)
|
|
@@ -888644,7 +889390,7 @@ async function handleRoutinesCommand(runtime3) {
|
|
|
888644
889390
|
return handleRoutinePromotion(runtime3, rest);
|
|
888645
889391
|
}
|
|
888646
889392
|
return {
|
|
888647
|
-
output: "Usage: goodvibes-agent routines [list|enabled|show <id>|receipts|reconcile|receipt <id>|promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes]",
|
|
889393
|
+
output: "Usage: goodvibes-agent routines [list|enabled|discover|import-discovered <name> --yes|show <id>|receipts|reconcile|receipt <id>|promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes]",
|
|
888648
889394
|
exitCode: 2
|
|
888649
889395
|
};
|
|
888650
889396
|
}
|
|
@@ -888746,13 +889492,13 @@ async function withRuntimeServices(runtime3, fn) {
|
|
|
888746
889492
|
}
|
|
888747
889493
|
}
|
|
888748
889494
|
function readAuthPaths(runtime3) {
|
|
888749
|
-
const
|
|
889495
|
+
const shellPaths3 = createShellPathService2({
|
|
888750
889496
|
workingDirectory: runtime3.workingDirectory,
|
|
888751
889497
|
homeDirectory: runtime3.homeDirectory
|
|
888752
889498
|
});
|
|
888753
|
-
const userStorePath =
|
|
888754
|
-
const bootstrapCredentialPath =
|
|
888755
|
-
const operatorTokenPath =
|
|
889499
|
+
const userStorePath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
|
|
889500
|
+
const bootstrapCredentialPath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
|
|
889501
|
+
const operatorTokenPath = join100(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
888756
889502
|
return {
|
|
888757
889503
|
userStorePath,
|
|
888758
889504
|
userStorePresent: existsSync84(userStorePath),
|
|
@@ -889267,7 +890013,7 @@ async function prepareShellCliRuntime(argv, roots, binary2 = "goodvibes-agent")
|
|
|
889267
890013
|
workingDirectory: bootstrapWorkingDir,
|
|
889268
890014
|
homeDirectory: bootstrapHomeDirectory
|
|
889269
890015
|
} = ownership;
|
|
889270
|
-
configureActivityLogger(
|
|
890016
|
+
configureActivityLogger(join101(bootstrapWorkingDir, ".goodvibes", "logs"));
|
|
889271
890017
|
const configManager = new ConfigManager({
|
|
889272
890018
|
workingDir: bootstrapWorkingDir,
|
|
889273
890019
|
homeDir: bootstrapHomeDirectory,
|
|
@@ -889312,14 +890058,14 @@ async function prepareShellCliRuntime(argv, roots, binary2 = "goodvibes-agent")
|
|
|
889312
890058
|
process.exit(2);
|
|
889313
890059
|
}
|
|
889314
890060
|
if (cli.command === "status" || cli.command === "doctor" || cli.command === "onboarding" && cli.commandArgs[0] === "status") {
|
|
889315
|
-
const
|
|
890061
|
+
const shellPaths3 = createShellPathService2({
|
|
889316
890062
|
workingDirectory: bootstrapWorkingDir,
|
|
889317
890063
|
homeDirectory: bootstrapHomeDirectory
|
|
889318
890064
|
});
|
|
889319
|
-
const userStorePath =
|
|
889320
|
-
const bootstrapCredentialPath =
|
|
889321
|
-
const operatorTokenPath =
|
|
889322
|
-
const onboardingMarkers = readOnboardingCheckMarkers(
|
|
890065
|
+
const userStorePath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
|
|
890066
|
+
const bootstrapCredentialPath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
|
|
890067
|
+
const operatorTokenPath = join101(bootstrapHomeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
890068
|
+
const onboardingMarkers = readOnboardingCheckMarkers(shellPaths3);
|
|
889323
890069
|
const service = await buildCliServicePosture({
|
|
889324
890070
|
configManager,
|
|
889325
890071
|
workingDirectory: bootstrapWorkingDir,
|
|
@@ -889433,8 +890179,8 @@ function getInteractiveTerminalLaunchError(input) {
|
|
|
889433
890179
|
`);
|
|
889434
890180
|
}
|
|
889435
890181
|
function applyInitialTuiCliState(options) {
|
|
889436
|
-
const { cli, input, commandRegistry, commandContext, shellPaths, render } = options;
|
|
889437
|
-
const globalOnboardingMarker = readOnboardingCheckMarker(
|
|
890182
|
+
const { cli, input, commandRegistry, commandContext, shellPaths: shellPaths3, render } = options;
|
|
890183
|
+
const globalOnboardingMarker = readOnboardingCheckMarker(shellPaths3, "user");
|
|
889438
890184
|
const seededPrompt = cli.flags.prompt ?? (cli.rawCommand === undefined && cli.positionals.length > 0 ? cli.positionals.join(" ") : undefined);
|
|
889439
890185
|
if (cli.command === "onboarding") {
|
|
889440
890186
|
input.openOnboardingWizard({ mode: "edit", reset: true });
|
|
@@ -889456,7 +890202,7 @@ function applyInitialTuiCliState(options) {
|
|
|
889456
890202
|
|
|
889457
890203
|
// src/audio/player.ts
|
|
889458
890204
|
import { accessSync, constants as constants4 } from "fs";
|
|
889459
|
-
import { delimiter, join as
|
|
890205
|
+
import { delimiter, join as join102 } from "path";
|
|
889460
890206
|
import { spawn as spawn6 } from "child_process";
|
|
889461
890207
|
|
|
889462
890208
|
class LocalStreamingAudioPlayer {
|
|
@@ -889553,7 +890299,7 @@ function findExecutable(name51, env2) {
|
|
|
889553
890299
|
if (!dir)
|
|
889554
890300
|
continue;
|
|
889555
890301
|
for (const ext of extensions14) {
|
|
889556
|
-
const candidate =
|
|
890302
|
+
const candidate = join102(dir, `${name51}${ext}`);
|
|
889557
890303
|
try {
|
|
889558
890304
|
accessSync(candidate, constants4.X_OK);
|
|
889559
890305
|
return candidate;
|