@pellux/goodvibes-agent 0.1.114 → 0.1.116
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 +13 -0
- package/README.md +4 -0
- package/dist/package/main.js +1166 -517
- package/docs/getting-started.md +4 -0
- package/package.json +1 -1
- package/src/agent/behavior-discovery-summary.ts +167 -0
- package/src/agent/runtime-profile-starters.ts +331 -0
- package/src/agent/runtime-profile.ts +150 -330
- package/src/cli/help.ts +2 -2
- package/src/cli/profiles-command.ts +128 -0
- package/src/input/agent-workspace-basic-command-editor-submission.ts +534 -0
- package/src/input/agent-workspace-basic-command-editors.ts +45 -453
- package/src/input/agent-workspace-categories.ts +3 -0
- package/src/input/agent-workspace-command-editor.ts +2 -0
- package/src/input/agent-workspace-setup.ts +33 -13
- package/src/input/agent-workspace-snapshot.ts +6 -0
- package/src/input/agent-workspace-types.ts +4 -0
- package/src/input/commands/agent-runtime-profile-runtime.ts +73 -4
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +46 -9
- package/src/input/onboarding/onboarding-wizard-steps.ts +1 -1
- package/src/renderer/agent-workspace.ts +26 -0
- package/src/runtime/onboarding/derivation.ts +20 -1
- package/src/runtime/onboarding/snapshot.ts +2 -0
- package/src/runtime/onboarding/types.ts +2 -0
- 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.116";
|
|
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"));
|
|
@@ -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 join92 } from "path";
|
|
841978
841978
|
|
|
841979
841979
|
// src/input/command-registry.ts
|
|
841980
841980
|
class CommandRegistry {
|
|
@@ -851684,9 +851684,195 @@ import { dirname as dirname58 } from "path";
|
|
|
851684
851684
|
|
|
851685
851685
|
// src/agent/runtime-profile.ts
|
|
851686
851686
|
import { existsSync as existsSync71, mkdirSync as mkdirSync59, readFileSync as readFileSync78, readdirSync as readdirSync20, rmSync as rmSync9, statSync as statSync19, writeFileSync as writeFileSync51 } from "fs";
|
|
851687
|
-
import { dirname as dirname57, join as
|
|
851688
|
-
|
|
851689
|
-
|
|
851687
|
+
import { dirname as dirname57, join as join88 } from "path";
|
|
851688
|
+
|
|
851689
|
+
// src/agent/persona-discovery.ts
|
|
851690
|
+
import { promises as fsPromises5 } from "fs";
|
|
851691
|
+
import { join as join86 } from "path";
|
|
851692
|
+
var DIRECTORY_MARKERS = ["PERSONA.md", "persona.md", "AGENT.md", "agent.md"];
|
|
851693
|
+
function parseFrontmatter2(content) {
|
|
851694
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
851695
|
+
if (!match)
|
|
851696
|
+
return {};
|
|
851697
|
+
const result2 = {};
|
|
851698
|
+
for (const line of match[1].split(`
|
|
851699
|
+
`)) {
|
|
851700
|
+
const [key, ...rest] = line.split(":");
|
|
851701
|
+
if (key && rest.length > 0) {
|
|
851702
|
+
result2[key.trim()] = rest.join(":").trim();
|
|
851703
|
+
}
|
|
851704
|
+
}
|
|
851705
|
+
return result2;
|
|
851706
|
+
}
|
|
851707
|
+
function getPersonaDirectories(cwd, homeDir) {
|
|
851708
|
+
return [
|
|
851709
|
+
{ root: join86(cwd, ".goodvibes", "personas"), origin: "project-local" },
|
|
851710
|
+
{ root: join86(cwd, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "personas"), origin: "project-local" },
|
|
851711
|
+
{ root: join86(cwd, ".goodvibes", "agents"), origin: "project-local" },
|
|
851712
|
+
{ root: join86(homeDir, ".goodvibes", "personas"), origin: "global" },
|
|
851713
|
+
{ root: join86(homeDir, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "personas"), origin: "global" },
|
|
851714
|
+
{ root: join86(homeDir, ".goodvibes", "agents"), origin: "global" }
|
|
851715
|
+
];
|
|
851716
|
+
}
|
|
851717
|
+
async function readPersonaFile(path7, origin) {
|
|
851718
|
+
let content = "";
|
|
851719
|
+
try {
|
|
851720
|
+
content = await fsPromises5.readFile(path7, "utf-8");
|
|
851721
|
+
} catch {
|
|
851722
|
+
return null;
|
|
851723
|
+
}
|
|
851724
|
+
const frontmatter = parseFrontmatter2(content);
|
|
851725
|
+
const markdownBody = content.replace(/^---\n[\s\S]*?\n---\n?/, "").trim();
|
|
851726
|
+
const body2 = (frontmatter.system_prompt ?? markdownBody).trim();
|
|
851727
|
+
if (!body2)
|
|
851728
|
+
return null;
|
|
851729
|
+
const name51 = frontmatter.name ?? path7.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "persona";
|
|
851730
|
+
const description = frontmatter.description ?? frontmatter.summary ?? frontmatter.title ?? "";
|
|
851731
|
+
return {
|
|
851732
|
+
name: name51,
|
|
851733
|
+
description,
|
|
851734
|
+
path: path7,
|
|
851735
|
+
origin,
|
|
851736
|
+
body: body2,
|
|
851737
|
+
frontmatter
|
|
851738
|
+
};
|
|
851739
|
+
}
|
|
851740
|
+
async function scanPersonaDirectory(root, origin) {
|
|
851741
|
+
let entries = [];
|
|
851742
|
+
try {
|
|
851743
|
+
entries = await fsPromises5.readdir(root);
|
|
851744
|
+
} catch {
|
|
851745
|
+
return [];
|
|
851746
|
+
}
|
|
851747
|
+
const records = [];
|
|
851748
|
+
for (const entry of entries.sort((a4, b3) => a4.localeCompare(b3))) {
|
|
851749
|
+
if (entry.endsWith(".md")) {
|
|
851750
|
+
const record2 = await readPersonaFile(join86(root, entry), origin);
|
|
851751
|
+
if (record2)
|
|
851752
|
+
records.push(record2);
|
|
851753
|
+
continue;
|
|
851754
|
+
}
|
|
851755
|
+
for (const marker of DIRECTORY_MARKERS) {
|
|
851756
|
+
const record2 = await readPersonaFile(join86(root, entry, marker), origin);
|
|
851757
|
+
if (record2) {
|
|
851758
|
+
records.push(record2);
|
|
851759
|
+
break;
|
|
851760
|
+
}
|
|
851761
|
+
}
|
|
851762
|
+
}
|
|
851763
|
+
return records;
|
|
851764
|
+
}
|
|
851765
|
+
async function discoverPersonas(shellPaths) {
|
|
851766
|
+
const seen = new Set;
|
|
851767
|
+
const records = [];
|
|
851768
|
+
for (const { root, origin } of getPersonaDirectories(shellPaths.workingDirectory, shellPaths.homeDirectory)) {
|
|
851769
|
+
for (const record2 of await scanPersonaDirectory(root, origin)) {
|
|
851770
|
+
const key = record2.name.toLowerCase();
|
|
851771
|
+
if (seen.has(key))
|
|
851772
|
+
continue;
|
|
851773
|
+
seen.add(key);
|
|
851774
|
+
records.push(record2);
|
|
851775
|
+
}
|
|
851776
|
+
}
|
|
851777
|
+
return records.sort((a4, b3) => {
|
|
851778
|
+
const originRank = a4.origin === b3.origin ? 0 : a4.origin === "project-local" ? -1 : 1;
|
|
851779
|
+
return originRank || a4.name.localeCompare(b3.name);
|
|
851780
|
+
});
|
|
851781
|
+
}
|
|
851782
|
+
|
|
851783
|
+
// src/agent/routine-discovery.ts
|
|
851784
|
+
import { promises as fsPromises6 } from "fs";
|
|
851785
|
+
import { join as join87 } from "path";
|
|
851786
|
+
var DIRECTORY_MARKERS2 = ["ROUTINE.md", "routine.md"];
|
|
851787
|
+
function parseFrontmatter3(content) {
|
|
851788
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
851789
|
+
if (!match)
|
|
851790
|
+
return {};
|
|
851791
|
+
const result2 = {};
|
|
851792
|
+
for (const line of match[1].split(`
|
|
851793
|
+
`)) {
|
|
851794
|
+
const [key, ...rest] = line.split(":");
|
|
851795
|
+
if (key && rest.length > 0) {
|
|
851796
|
+
result2[key.trim()] = rest.join(":").trim();
|
|
851797
|
+
}
|
|
851798
|
+
}
|
|
851799
|
+
return result2;
|
|
851800
|
+
}
|
|
851801
|
+
function getRoutineDirectories(cwd, homeDir) {
|
|
851802
|
+
return [
|
|
851803
|
+
{ root: join87(cwd, ".goodvibes", "routines"), origin: "project-local" },
|
|
851804
|
+
{ root: join87(cwd, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "routines"), origin: "project-local" },
|
|
851805
|
+
{ root: join87(homeDir, ".goodvibes", "routines"), origin: "global" },
|
|
851806
|
+
{ root: join87(homeDir, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "routines"), origin: "global" }
|
|
851807
|
+
];
|
|
851808
|
+
}
|
|
851809
|
+
async function readRoutineFile(path7, origin) {
|
|
851810
|
+
let content = "";
|
|
851811
|
+
try {
|
|
851812
|
+
content = await fsPromises6.readFile(path7, "utf-8");
|
|
851813
|
+
} catch {
|
|
851814
|
+
return null;
|
|
851815
|
+
}
|
|
851816
|
+
const frontmatter = parseFrontmatter3(content);
|
|
851817
|
+
const markdownBody = content.replace(/^---\n[\s\S]*?\n---\n?/, "").trim();
|
|
851818
|
+
const steps = (frontmatter.steps ?? markdownBody).trim();
|
|
851819
|
+
if (!steps)
|
|
851820
|
+
return null;
|
|
851821
|
+
const name51 = frontmatter.name ?? path7.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "routine";
|
|
851822
|
+
const description = frontmatter.description ?? frontmatter.summary ?? frontmatter.title ?? "";
|
|
851823
|
+
return {
|
|
851824
|
+
name: name51,
|
|
851825
|
+
description,
|
|
851826
|
+
path: path7,
|
|
851827
|
+
origin,
|
|
851828
|
+
steps,
|
|
851829
|
+
frontmatter
|
|
851830
|
+
};
|
|
851831
|
+
}
|
|
851832
|
+
async function scanRoutineDirectory(root, origin) {
|
|
851833
|
+
let entries = [];
|
|
851834
|
+
try {
|
|
851835
|
+
entries = await fsPromises6.readdir(root);
|
|
851836
|
+
} catch {
|
|
851837
|
+
return [];
|
|
851838
|
+
}
|
|
851839
|
+
const records = [];
|
|
851840
|
+
for (const entry of entries.sort((a4, b3) => a4.localeCompare(b3))) {
|
|
851841
|
+
if (entry.endsWith(".md")) {
|
|
851842
|
+
const record2 = await readRoutineFile(join87(root, entry), origin);
|
|
851843
|
+
if (record2)
|
|
851844
|
+
records.push(record2);
|
|
851845
|
+
continue;
|
|
851846
|
+
}
|
|
851847
|
+
for (const marker of DIRECTORY_MARKERS2) {
|
|
851848
|
+
const record2 = await readRoutineFile(join87(root, entry, marker), origin);
|
|
851849
|
+
if (record2) {
|
|
851850
|
+
records.push(record2);
|
|
851851
|
+
break;
|
|
851852
|
+
}
|
|
851853
|
+
}
|
|
851854
|
+
}
|
|
851855
|
+
return records;
|
|
851856
|
+
}
|
|
851857
|
+
async function discoverRoutines(shellPaths) {
|
|
851858
|
+
const seen = new Set;
|
|
851859
|
+
const records = [];
|
|
851860
|
+
for (const { root, origin } of getRoutineDirectories(shellPaths.workingDirectory, shellPaths.homeDirectory)) {
|
|
851861
|
+
for (const record2 of await scanRoutineDirectory(root, origin)) {
|
|
851862
|
+
const key = record2.name.toLowerCase();
|
|
851863
|
+
if (seen.has(key))
|
|
851864
|
+
continue;
|
|
851865
|
+
seen.add(key);
|
|
851866
|
+
records.push(record2);
|
|
851867
|
+
}
|
|
851868
|
+
}
|
|
851869
|
+
return records.sort((a4, b3) => {
|
|
851870
|
+
const originRank = a4.origin === b3.origin ? 0 : a4.origin === "project-local" ? -1 : 1;
|
|
851871
|
+
return originRank || a4.name.localeCompare(b3.name);
|
|
851872
|
+
});
|
|
851873
|
+
}
|
|
851874
|
+
|
|
851875
|
+
// src/agent/runtime-profile-starters.ts
|
|
851690
851876
|
var STARTER_TEMPLATES = [
|
|
851691
851877
|
{
|
|
851692
851878
|
id: "household",
|
|
@@ -852007,6 +852193,10 @@ var STARTER_TEMPLATES = [
|
|
|
852007
852193
|
]
|
|
852008
852194
|
}
|
|
852009
852195
|
];
|
|
852196
|
+
|
|
852197
|
+
// src/agent/runtime-profile.ts
|
|
852198
|
+
var PROFILE_CREATED_FILE = "profile.json";
|
|
852199
|
+
var PROFILE_ID_PATTERN = /^[a-z0-9](?:[a-z0-9._-]{0,62}[a-z0-9])?$/;
|
|
852010
852200
|
function normalizeAgentRuntimeProfileId(value) {
|
|
852011
852201
|
return value.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "").replace(/[-_]{2,}/g, "-");
|
|
852012
852202
|
}
|
|
@@ -852022,20 +852212,20 @@ function assertValidAgentRuntimeProfileId(value) {
|
|
|
852022
852212
|
return normalized;
|
|
852023
852213
|
}
|
|
852024
852214
|
function getAgentRuntimeProfilesRoot(baseHomeDirectory) {
|
|
852025
|
-
return
|
|
852215
|
+
return join88(baseHomeDirectory, ".goodvibes", "agent", "profile-homes");
|
|
852026
852216
|
}
|
|
852027
852217
|
function getAgentRuntimeProfileTemplatesRoot(baseHomeDirectory) {
|
|
852028
|
-
return
|
|
852218
|
+
return join88(baseHomeDirectory, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "profile-starters");
|
|
852029
852219
|
}
|
|
852030
852220
|
function resolveAgentRuntimeProfileHome(baseHomeDirectory, profileName) {
|
|
852031
852221
|
const id = assertValidAgentRuntimeProfileId(profileName);
|
|
852032
852222
|
return {
|
|
852033
852223
|
id,
|
|
852034
|
-
homeDirectory:
|
|
852224
|
+
homeDirectory: join88(getAgentRuntimeProfilesRoot(baseHomeDirectory), id)
|
|
852035
852225
|
};
|
|
852036
852226
|
}
|
|
852037
852227
|
function readProfileCreatedAt(homeDirectory) {
|
|
852038
|
-
const path7 =
|
|
852228
|
+
const path7 = join88(homeDirectory, PROFILE_CREATED_FILE);
|
|
852039
852229
|
if (!existsSync71(path7))
|
|
852040
852230
|
return null;
|
|
852041
852231
|
try {
|
|
@@ -852048,7 +852238,7 @@ function readProfileCreatedAt(homeDirectory) {
|
|
|
852048
852238
|
return null;
|
|
852049
852239
|
}
|
|
852050
852240
|
function readProfileStarterTemplate(homeDirectory) {
|
|
852051
|
-
const path7 =
|
|
852241
|
+
const path7 = join88(homeDirectory, PROFILE_CREATED_FILE);
|
|
852052
852242
|
if (!existsSync71(path7))
|
|
852053
852243
|
return {};
|
|
852054
852244
|
try {
|
|
@@ -852082,7 +852272,7 @@ function buildProfileInfo(baseHomeDirectory, id) {
|
|
|
852082
852272
|
};
|
|
852083
852273
|
}
|
|
852084
852274
|
function profileStorePath(homeDirectory, folder, file2) {
|
|
852085
|
-
return
|
|
852275
|
+
return join88(homeDirectory, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, folder, file2);
|
|
852086
852276
|
}
|
|
852087
852277
|
function isAgentRuntimeProfileTemplateId(value) {
|
|
852088
852278
|
if (typeof value !== "string")
|
|
@@ -852111,6 +852301,65 @@ function parseStringArray(value) {
|
|
|
852111
852301
|
return [];
|
|
852112
852302
|
return value.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter(Boolean);
|
|
852113
852303
|
}
|
|
852304
|
+
function splitFrontmatterList(value) {
|
|
852305
|
+
if (!value)
|
|
852306
|
+
return [];
|
|
852307
|
+
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
852308
|
+
}
|
|
852309
|
+
function normalizedLookupValues(value, path7) {
|
|
852310
|
+
const slug = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
852311
|
+
const basename5 = path7?.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
|
|
852312
|
+
return [value, slug, path7 ?? "", basename5].map((entry) => entry.trim().toLowerCase()).filter(Boolean);
|
|
852313
|
+
}
|
|
852314
|
+
function selectDiscoveredRecord(records, selector2, label) {
|
|
852315
|
+
if (records.length === 0)
|
|
852316
|
+
throw new Error(`No discovered Agent ${label} files found.`);
|
|
852317
|
+
if (!selector2?.trim())
|
|
852318
|
+
return records[0];
|
|
852319
|
+
const lookup = selector2.trim().toLowerCase();
|
|
852320
|
+
const match = records.find((record2) => normalizedLookupValues(record2.name, record2.path).includes(lookup));
|
|
852321
|
+
if (!match)
|
|
852322
|
+
throw new Error(`Unknown discovered Agent ${label}: ${selector2}.`);
|
|
852323
|
+
return match;
|
|
852324
|
+
}
|
|
852325
|
+
function selectDiscoveredRecords(records, selectors4, label) {
|
|
852326
|
+
if (records.length === 0)
|
|
852327
|
+
throw new Error(`No discovered Agent ${label} files found.`);
|
|
852328
|
+
if (!selectors4 || selectors4.length === 0 || selectors4.includes("all"))
|
|
852329
|
+
return records;
|
|
852330
|
+
return selectors4.map((selector2) => selectDiscoveredRecord(records, selector2, label));
|
|
852331
|
+
}
|
|
852332
|
+
function discoveredSkillToTemplate(skill) {
|
|
852333
|
+
if (!skill.body.trim())
|
|
852334
|
+
throw new Error(`Discovered Agent skill ${skill.name} has no procedure body.`);
|
|
852335
|
+
return {
|
|
852336
|
+
name: skill.name,
|
|
852337
|
+
description: skill.description || `Imported skill from ${skill.origin} skill file.`,
|
|
852338
|
+
procedure: skill.body,
|
|
852339
|
+
triggers: splitFrontmatterList(skill.frontmatter.triggers),
|
|
852340
|
+
tags: splitFrontmatterList(skill.frontmatter.tags)
|
|
852341
|
+
};
|
|
852342
|
+
}
|
|
852343
|
+
function discoveredRoutineToTemplate(routine) {
|
|
852344
|
+
if (!routine.steps.trim())
|
|
852345
|
+
throw new Error(`Discovered Agent routine ${routine.name} has no steps.`);
|
|
852346
|
+
return {
|
|
852347
|
+
name: routine.name,
|
|
852348
|
+
description: routine.description || `Imported routine from ${routine.origin} markdown file.`,
|
|
852349
|
+
steps: routine.steps,
|
|
852350
|
+
triggers: splitFrontmatterList(routine.frontmatter.triggers),
|
|
852351
|
+
tags: splitFrontmatterList(routine.frontmatter.tags)
|
|
852352
|
+
};
|
|
852353
|
+
}
|
|
852354
|
+
function discoveredPersonaToTemplate(persona) {
|
|
852355
|
+
return {
|
|
852356
|
+
name: persona.name,
|
|
852357
|
+
description: persona.description || `Imported persona from ${persona.origin} markdown file.`,
|
|
852358
|
+
body: persona.body,
|
|
852359
|
+
tags: splitFrontmatterList(persona.frontmatter.tags),
|
|
852360
|
+
triggers: splitFrontmatterList(persona.frontmatter.triggers)
|
|
852361
|
+
};
|
|
852362
|
+
}
|
|
852114
852363
|
function readTemplateTextBlock(value, field) {
|
|
852115
852364
|
if (typeof value !== "string" || !value.trim())
|
|
852116
852365
|
throw new Error(`Starter template ${field} is required.`);
|
|
@@ -852184,7 +852433,7 @@ function listLocalTemplates(baseHomeDirectory) {
|
|
|
852184
852433
|
const root = getAgentRuntimeProfileTemplatesRoot(baseHomeDirectory);
|
|
852185
852434
|
if (!existsSync71(root))
|
|
852186
852435
|
return [];
|
|
852187
|
-
return readdirSync20(root).filter((entry) => entry.endsWith(".json")).map((entry) => readLocalTemplate(
|
|
852436
|
+
return readdirSync20(root).filter((entry) => entry.endsWith(".json")).map((entry) => readLocalTemplate(join88(root, entry))).filter((entry) => entry !== null).sort((left, right) => left.id.localeCompare(right.id));
|
|
852188
852437
|
}
|
|
852189
852438
|
function resolveAgentRuntimeProfileTemplate(templateId, baseHomeDirectory) {
|
|
852190
852439
|
const id = assertValidAgentRuntimeProfileId(templateId);
|
|
@@ -852235,11 +852484,63 @@ function importAgentRuntimeProfileTemplate(baseHomeDirectory, sourcePath) {
|
|
|
852235
852484
|
const parsed = parseStarterTemplate(JSON.parse(readFileSync78(source, "utf-8")), "local");
|
|
852236
852485
|
const root = getAgentRuntimeProfileTemplatesRoot(baseHomeDirectory);
|
|
852237
852486
|
mkdirSync59(root, { recursive: true });
|
|
852238
|
-
const target =
|
|
852487
|
+
const target = join88(root, `${parsed.id}.json`);
|
|
852239
852488
|
writeFileSync51(target, `${JSON.stringify(templateFilePayload({ ...parsed, source: "local", path: target }), null, 2)}
|
|
852240
852489
|
`, "utf-8");
|
|
852241
852490
|
return summarizeTemplate({ ...parsed, source: "local", path: target });
|
|
852242
852491
|
}
|
|
852492
|
+
async function createAgentRuntimeProfileTemplateFromDiscovered(shellPaths, options) {
|
|
852493
|
+
const id = assertValidAgentRuntimeProfileId(options.id);
|
|
852494
|
+
const [personas, skills, routines] = await Promise.all([
|
|
852495
|
+
discoverPersonas(shellPaths),
|
|
852496
|
+
discoverSkills(shellPaths),
|
|
852497
|
+
discoverRoutines(shellPaths)
|
|
852498
|
+
]);
|
|
852499
|
+
const selectedPersona = selectDiscoveredRecord(personas, options.persona, "persona");
|
|
852500
|
+
const selectedSkills = selectDiscoveredRecords(skills, options.skills, "skill");
|
|
852501
|
+
const selectedRoutines = selectDiscoveredRecords(routines, options.routines, "routine");
|
|
852502
|
+
const target = join88(getAgentRuntimeProfileTemplatesRoot(shellPaths.homeDirectory), `${id}.json`);
|
|
852503
|
+
if (existsSync71(target) && options.replace !== true) {
|
|
852504
|
+
throw new Error(`Agent starter template already exists: ${id}. Rerun with --replace to overwrite it.`);
|
|
852505
|
+
}
|
|
852506
|
+
const persona = discoveredPersonaToTemplate(selectedPersona);
|
|
852507
|
+
const template = {
|
|
852508
|
+
id,
|
|
852509
|
+
source: "local",
|
|
852510
|
+
path: target,
|
|
852511
|
+
name: options.name?.trim() || `${persona.name} Starter`,
|
|
852512
|
+
description: options.description?.trim() || "Agent starter template assembled from discovered local persona, skill, and routine files.",
|
|
852513
|
+
personaName: persona.name,
|
|
852514
|
+
skillNames: selectedSkills.map((skill) => skill.name),
|
|
852515
|
+
routineNames: selectedRoutines.map((routine) => routine.name),
|
|
852516
|
+
persona,
|
|
852517
|
+
skills: selectedSkills.map(discoveredSkillToTemplate),
|
|
852518
|
+
routines: selectedRoutines.map(discoveredRoutineToTemplate)
|
|
852519
|
+
};
|
|
852520
|
+
mkdirSync59(dirname57(target), { recursive: true });
|
|
852521
|
+
writeFileSync51(target, `${JSON.stringify(templateFilePayload(template), null, 2)}
|
|
852522
|
+
`, "utf-8");
|
|
852523
|
+
return summarizeTemplate(template);
|
|
852524
|
+
}
|
|
852525
|
+
async function createAgentRuntimeProfileFromDiscovered(shellPaths, options) {
|
|
852526
|
+
const profileId = assertValidAgentRuntimeProfileId(options.profileName);
|
|
852527
|
+
const resolution2 = resolveAgentRuntimeProfileHome(shellPaths.homeDirectory, profileId);
|
|
852528
|
+
if (existsSync71(resolution2.homeDirectory)) {
|
|
852529
|
+
throw new Error(`Agent profile already exists: ${resolution2.id}`);
|
|
852530
|
+
}
|
|
852531
|
+
const templateId = assertValidAgentRuntimeProfileId(options.templateId ?? profileId);
|
|
852532
|
+
const template = await createAgentRuntimeProfileTemplateFromDiscovered(shellPaths, {
|
|
852533
|
+
id: templateId,
|
|
852534
|
+
name: options.name,
|
|
852535
|
+
description: options.description,
|
|
852536
|
+
persona: options.persona,
|
|
852537
|
+
skills: options.skills,
|
|
852538
|
+
routines: options.routines,
|
|
852539
|
+
replace: options.replace
|
|
852540
|
+
});
|
|
852541
|
+
const profile5 = createAgentRuntimeProfile(shellPaths.homeDirectory, profileId, { templateId: template.id });
|
|
852542
|
+
return { profile: profile5, template };
|
|
852543
|
+
}
|
|
852243
852544
|
function createMissingSkill(registry5, template) {
|
|
852244
852545
|
const existing = registry5.get(template.name);
|
|
852245
852546
|
if (existing)
|
|
@@ -852304,7 +852605,7 @@ function listAgentRuntimeProfiles(baseHomeDirectory) {
|
|
|
852304
852605
|
return [];
|
|
852305
852606
|
return readdirSync20(root).filter((entry) => PROFILE_ID_PATTERN.test(entry) && !entry.includes("..")).filter((entry) => {
|
|
852306
852607
|
try {
|
|
852307
|
-
return statSync19(
|
|
852608
|
+
return statSync19(join88(root, entry)).isDirectory();
|
|
852308
852609
|
} catch {
|
|
852309
852610
|
return false;
|
|
852310
852611
|
}
|
|
@@ -852318,7 +852619,7 @@ function createAgentRuntimeProfile(baseHomeDirectory, profileName, options = {})
|
|
|
852318
852619
|
mkdirSync59(resolution2.homeDirectory, { recursive: true });
|
|
852319
852620
|
const createdAt = new Date().toISOString();
|
|
852320
852621
|
const appliedTemplate = options.templateId ? applyAgentRuntimeProfileTemplate(resolution2.homeDirectory, options.templateId, baseHomeDirectory) : undefined;
|
|
852321
|
-
writeFileSync51(
|
|
852622
|
+
writeFileSync51(join88(resolution2.homeDirectory, PROFILE_CREATED_FILE), `${JSON.stringify({
|
|
852322
852623
|
id: resolution2.id,
|
|
852323
852624
|
createdAt,
|
|
852324
852625
|
starterTemplate: appliedTemplate
|
|
@@ -852348,6 +852649,12 @@ function parseFlag(args2, name51) {
|
|
|
852348
852649
|
const value = args2[index + 1];
|
|
852349
852650
|
return value && !value.startsWith("--") ? value : undefined;
|
|
852350
852651
|
}
|
|
852652
|
+
function parseCsvFlag(args2, name51) {
|
|
852653
|
+
const raw = parseFlag(args2, name51);
|
|
852654
|
+
if (!raw)
|
|
852655
|
+
return;
|
|
852656
|
+
return raw.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
852657
|
+
}
|
|
852351
852658
|
function profileLine(profile5) {
|
|
852352
852659
|
const created = profile5.createdAt ? ` created=${profile5.createdAt}` : "";
|
|
852353
852660
|
const starter = profile5.starterTemplateId ? ` starter=${profile5.starterTemplateId}` : "";
|
|
@@ -852387,7 +852694,8 @@ function renderTemplates(homeDirectory) {
|
|
|
852387
852694
|
" /agent-profile template export research ./agent-starter.json --yes",
|
|
852388
852695
|
" edit the JSON file",
|
|
852389
852696
|
" /agent-profile template import ./agent-starter.json --yes",
|
|
852390
|
-
" /agent-profile create <name> --template <imported-id> --yes"
|
|
852697
|
+
" /agent-profile create <name> --template <imported-id> --yes",
|
|
852698
|
+
" /agent-profile create-from-discovered <name> --yes"
|
|
852391
852699
|
].join(`
|
|
852392
852700
|
`);
|
|
852393
852701
|
}
|
|
@@ -852434,8 +852742,8 @@ function registerAgentRuntimeProfileRuntimeCommands(registry5) {
|
|
|
852434
852742
|
name: "agent-profile",
|
|
852435
852743
|
aliases: ["runtime-profile", "agent-profiles"],
|
|
852436
852744
|
description: "Manage isolated Agent profiles and starter templates",
|
|
852437
|
-
usage: "[list|templates|guide|template show|template export|template import|create|delete]",
|
|
852438
|
-
handler(args2, ctx) {
|
|
852745
|
+
usage: "[list|templates|guide|template show|template export|template import|template from-discovered|create|create-from-discovered|delete]",
|
|
852746
|
+
async handler(args2, ctx) {
|
|
852439
852747
|
const shellPaths = requireShellPaths(ctx);
|
|
852440
852748
|
const homeDirectory = shellPaths.homeDirectory;
|
|
852441
852749
|
const parsed = stripYesFlag(args2);
|
|
@@ -852501,7 +852809,36 @@ function registerAgentRuntimeProfileRuntimeCommands(registry5) {
|
|
|
852501
852809
|
use: /agent-profile create <name> --template ${template.id} --yes`);
|
|
852502
852810
|
return;
|
|
852503
852811
|
}
|
|
852504
|
-
|
|
852812
|
+
if (mode === "from-discovered" || mode === "import-discovered") {
|
|
852813
|
+
const templateId = commandArgs[2];
|
|
852814
|
+
if (!templateId) {
|
|
852815
|
+
ctx.print("Usage: /agent-profile template from-discovered <id> [--name <name>] [--description <summary>] [--persona <name>] [--skills all|name,name] [--routines all|name,name] [--replace] --yes");
|
|
852816
|
+
return;
|
|
852817
|
+
}
|
|
852818
|
+
if (!parsed.yes) {
|
|
852819
|
+
requireYesFlag(ctx, `create Agent starter template ${templateId} from discovered behavior`, "/agent-profile template from-discovered <id> --yes");
|
|
852820
|
+
return;
|
|
852821
|
+
}
|
|
852822
|
+
const template = await createAgentRuntimeProfileTemplateFromDiscovered(shellPaths, {
|
|
852823
|
+
id: templateId,
|
|
852824
|
+
name: parseFlag(commandArgs, "--name"),
|
|
852825
|
+
description: parseFlag(commandArgs, "--description"),
|
|
852826
|
+
persona: parseFlag(commandArgs, "--persona"),
|
|
852827
|
+
skills: parseCsvFlag(commandArgs, "--skills"),
|
|
852828
|
+
routines: parseCsvFlag(commandArgs, "--routines"),
|
|
852829
|
+
replace: commandArgs.includes("--replace")
|
|
852830
|
+
});
|
|
852831
|
+
ctx.print([
|
|
852832
|
+
`Agent starter template created from discovered behavior: ${template.id}`,
|
|
852833
|
+
` persona: ${template.personaName}`,
|
|
852834
|
+
` skills: ${template.skillNames.join(", ")}`,
|
|
852835
|
+
` routines: ${template.routineNames.join(", ")}`,
|
|
852836
|
+
` use: /agent-profile create <name> --template ${template.id} --yes`
|
|
852837
|
+
].join(`
|
|
852838
|
+
`));
|
|
852839
|
+
return;
|
|
852840
|
+
}
|
|
852841
|
+
ctx.print("Usage: /agent-profile template [show <id>|export <id> <path> --yes|import <path> --yes|from-discovered <id> --yes]");
|
|
852505
852842
|
return;
|
|
852506
852843
|
}
|
|
852507
852844
|
if (sub === "create") {
|
|
@@ -852522,6 +852859,38 @@ function registerAgentRuntimeProfileRuntimeCommands(registry5) {
|
|
|
852522
852859
|
profile5.starterTemplateId ? ` starter: ${profile5.starterTemplateId}` : "",
|
|
852523
852860
|
` launch: goodvibes-agent --agent-profile ${profile5.id}`
|
|
852524
852861
|
].filter(Boolean).join(`
|
|
852862
|
+
`));
|
|
852863
|
+
return;
|
|
852864
|
+
}
|
|
852865
|
+
if (sub === "create-from-discovered" || sub === "create-discovered") {
|
|
852866
|
+
const profileName = commandArgs[1];
|
|
852867
|
+
if (!profileName) {
|
|
852868
|
+
ctx.print("Usage: /agent-profile create-from-discovered <name> [--template-id <id>] [--profile-name <display>] [--description <summary>] [--persona <name>] [--skills all|name,name] [--routines all|name,name] [--replace] --yes");
|
|
852869
|
+
return;
|
|
852870
|
+
}
|
|
852871
|
+
if (!parsed.yes) {
|
|
852872
|
+
requireYesFlag(ctx, `create Agent profile ${profileName} from discovered behavior`, "/agent-profile create-from-discovered <name> --yes");
|
|
852873
|
+
return;
|
|
852874
|
+
}
|
|
852875
|
+
const created = await createAgentRuntimeProfileFromDiscovered(shellPaths, {
|
|
852876
|
+
profileName,
|
|
852877
|
+
templateId: parseFlag(commandArgs, "--template-id") ?? parseFlag(commandArgs, "--starter-id"),
|
|
852878
|
+
name: parseFlag(commandArgs, "--profile-name") ?? parseFlag(commandArgs, "--name"),
|
|
852879
|
+
description: parseFlag(commandArgs, "--description"),
|
|
852880
|
+
persona: parseFlag(commandArgs, "--persona"),
|
|
852881
|
+
skills: parseCsvFlag(commandArgs, "--skills"),
|
|
852882
|
+
routines: parseCsvFlag(commandArgs, "--routines"),
|
|
852883
|
+
replace: commandArgs.includes("--replace")
|
|
852884
|
+
});
|
|
852885
|
+
ctx.print([
|
|
852886
|
+
`Agent profile created from discovered behavior: ${created.profile.id}`,
|
|
852887
|
+
` home: ${created.profile.homeDirectory}`,
|
|
852888
|
+
` starter: ${created.template.id}`,
|
|
852889
|
+
` persona: ${created.template.personaName}`,
|
|
852890
|
+
` skills: ${created.template.skillNames.join(", ")}`,
|
|
852891
|
+
` routines: ${created.template.routineNames.join(", ")}`,
|
|
852892
|
+
` launch: goodvibes-agent --agent-profile ${created.profile.id}`
|
|
852893
|
+
].join(`
|
|
852525
852894
|
`));
|
|
852526
852895
|
return;
|
|
852527
852896
|
}
|
|
@@ -852538,7 +852907,7 @@ function registerAgentRuntimeProfileRuntimeCommands(registry5) {
|
|
|
852538
852907
|
ctx.print(deleteAgentRuntimeProfile(homeDirectory, name51) ? `Agent profile deleted: ${name51}` : `Agent profile not found: ${name51}`);
|
|
852539
852908
|
return;
|
|
852540
852909
|
}
|
|
852541
|
-
ctx.print("Usage: /agent-profile [list|templates|guide|template show <id>|template export <id> <path> --yes|template import <path> --yes|create <name> [--template <id>] --yes|delete <name> --yes]");
|
|
852910
|
+
ctx.print("Usage: /agent-profile [list|templates|guide|template show <id>|template export <id> <path> --yes|template import <path> --yes|create <name> [--template <id>] --yes|create-from-discovered <name> --yes|delete <name> --yes]");
|
|
852542
852911
|
} catch (error51) {
|
|
852543
852912
|
ctx.print(`Error: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
852544
852913
|
}
|
|
@@ -852664,100 +853033,6 @@ function registerDelegationRuntimeCommands(registry5) {
|
|
|
852664
853033
|
});
|
|
852665
853034
|
}
|
|
852666
853035
|
|
|
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
|
-
|
|
852761
853036
|
// src/input/commands/personas-runtime.ts
|
|
852762
853037
|
function parsePersonaArgs(args2) {
|
|
852763
853038
|
const flags2 = new Map;
|
|
@@ -853497,98 +853772,6 @@ function registerAgentSkillsRuntimeCommands(registry5) {
|
|
|
853497
853772
|
});
|
|
853498
853773
|
}
|
|
853499
853774
|
|
|
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
|
-
|
|
853592
853775
|
// src/input/commands/routines-runtime.ts
|
|
853593
853776
|
function parseRoutineArgs(args2) {
|
|
853594
853777
|
const flags2 = new Map;
|
|
@@ -854489,6 +854672,143 @@ Use /channels list to see available channel ids.`);
|
|
|
854489
854672
|
// src/input/agent-workspace-snapshot.ts
|
|
854490
854673
|
import { basename as basename5, sep as sep3 } from "path";
|
|
854491
854674
|
|
|
854675
|
+
// src/agent/behavior-discovery-summary.ts
|
|
854676
|
+
import { readdirSync as readdirSync21, readFileSync as readFileSync80 } from "fs";
|
|
854677
|
+
import { join as join90 } from "path";
|
|
854678
|
+
var EMPTY_SUMMARY = {
|
|
854679
|
+
count: 0,
|
|
854680
|
+
projectLocalCount: 0,
|
|
854681
|
+
globalCount: 0,
|
|
854682
|
+
names: []
|
|
854683
|
+
};
|
|
854684
|
+
var EMPTY_AGENT_BEHAVIOR_DISCOVERY_SNAPSHOT = {
|
|
854685
|
+
personas: EMPTY_SUMMARY,
|
|
854686
|
+
skills: EMPTY_SUMMARY,
|
|
854687
|
+
routines: EMPTY_SUMMARY
|
|
854688
|
+
};
|
|
854689
|
+
function parseFrontmatter4(content) {
|
|
854690
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
854691
|
+
if (!match)
|
|
854692
|
+
return {};
|
|
854693
|
+
const result2 = {};
|
|
854694
|
+
for (const line of match[1].split(`
|
|
854695
|
+
`)) {
|
|
854696
|
+
const [key, ...rest] = line.split(":");
|
|
854697
|
+
if (key && rest.length > 0) {
|
|
854698
|
+
result2[key.trim()] = rest.join(":").trim();
|
|
854699
|
+
}
|
|
854700
|
+
}
|
|
854701
|
+
return result2;
|
|
854702
|
+
}
|
|
854703
|
+
function markdownBody(content) {
|
|
854704
|
+
return content.replace(/^---\n[\s\S]*?\n---\n?/, "").trim();
|
|
854705
|
+
}
|
|
854706
|
+
function readDiscoveryCandidate(path7, origin, definition) {
|
|
854707
|
+
let content = "";
|
|
854708
|
+
try {
|
|
854709
|
+
content = readFileSync80(path7, "utf-8");
|
|
854710
|
+
} catch {
|
|
854711
|
+
return null;
|
|
854712
|
+
}
|
|
854713
|
+
const frontmatter = parseFrontmatter4(content);
|
|
854714
|
+
const body2 = definition.frontmatterBodyKey ? (frontmatter[definition.frontmatterBodyKey] ?? markdownBody(content)).trim() : markdownBody(content);
|
|
854715
|
+
if (body2.length === 0)
|
|
854716
|
+
return null;
|
|
854717
|
+
const name51 = frontmatter.name ?? path7.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
|
|
854718
|
+
const normalized = name51.trim();
|
|
854719
|
+
return normalized ? { name: normalized, origin } : null;
|
|
854720
|
+
}
|
|
854721
|
+
function candidatePaths(root, entry, markers) {
|
|
854722
|
+
if (entry.endsWith(".md"))
|
|
854723
|
+
return [join90(root, entry)];
|
|
854724
|
+
return markers.map((marker) => join90(root, entry, marker));
|
|
854725
|
+
}
|
|
854726
|
+
function summarizeDefinition(definition, limit3) {
|
|
854727
|
+
const seen = new Set;
|
|
854728
|
+
const names2 = [];
|
|
854729
|
+
let projectLocalCount = 0;
|
|
854730
|
+
let globalCount = 0;
|
|
854731
|
+
for (const { root, origin } of definition.roots) {
|
|
854732
|
+
let entries = [];
|
|
854733
|
+
try {
|
|
854734
|
+
entries = readdirSync21(root);
|
|
854735
|
+
} catch {
|
|
854736
|
+
continue;
|
|
854737
|
+
}
|
|
854738
|
+
for (const entry of entries.sort((left, right) => left.localeCompare(right))) {
|
|
854739
|
+
for (const path7 of candidatePaths(root, entry, definition.markers)) {
|
|
854740
|
+
const candidate = readDiscoveryCandidate(path7, origin, definition);
|
|
854741
|
+
if (!candidate)
|
|
854742
|
+
continue;
|
|
854743
|
+
const key = candidate.name.toLowerCase();
|
|
854744
|
+
if (seen.has(key))
|
|
854745
|
+
break;
|
|
854746
|
+
seen.add(key);
|
|
854747
|
+
if (candidate.origin === "project-local")
|
|
854748
|
+
projectLocalCount += 1;
|
|
854749
|
+
else
|
|
854750
|
+
globalCount += 1;
|
|
854751
|
+
if (names2.length < limit3)
|
|
854752
|
+
names2.push(candidate.name);
|
|
854753
|
+
break;
|
|
854754
|
+
}
|
|
854755
|
+
}
|
|
854756
|
+
}
|
|
854757
|
+
if (seen.size === 0)
|
|
854758
|
+
return EMPTY_SUMMARY;
|
|
854759
|
+
return {
|
|
854760
|
+
count: seen.size,
|
|
854761
|
+
projectLocalCount,
|
|
854762
|
+
globalCount,
|
|
854763
|
+
names: names2
|
|
854764
|
+
};
|
|
854765
|
+
}
|
|
854766
|
+
function definitions(shellPaths) {
|
|
854767
|
+
const cwd = shellPaths.workingDirectory;
|
|
854768
|
+
const homeDir = shellPaths.homeDirectory;
|
|
854769
|
+
const personas = {
|
|
854770
|
+
roots: [
|
|
854771
|
+
{ root: join90(cwd, ".goodvibes", "personas"), origin: "project-local" },
|
|
854772
|
+
{ root: join90(cwd, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "personas"), origin: "project-local" },
|
|
854773
|
+
{ root: join90(cwd, ".goodvibes", "agents"), origin: "project-local" },
|
|
854774
|
+
{ root: join90(homeDir, ".goodvibes", "personas"), origin: "global" },
|
|
854775
|
+
{ root: join90(homeDir, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "personas"), origin: "global" },
|
|
854776
|
+
{ root: join90(homeDir, ".goodvibes", "agents"), origin: "global" }
|
|
854777
|
+
],
|
|
854778
|
+
markers: ["PERSONA.md", "persona.md", "AGENT.md", "agent.md"],
|
|
854779
|
+
frontmatterBodyKey: "system_prompt"
|
|
854780
|
+
};
|
|
854781
|
+
const skills = {
|
|
854782
|
+
roots: [
|
|
854783
|
+
{ root: join90(cwd, ".goodvibes", "skills"), origin: "project-local" },
|
|
854784
|
+
{ root: join90(cwd, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "skills"), origin: "project-local" },
|
|
854785
|
+
{ root: join90(homeDir, ".goodvibes", "skills"), origin: "global" },
|
|
854786
|
+
{ root: join90(homeDir, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "skills"), origin: "global" }
|
|
854787
|
+
],
|
|
854788
|
+
markers: ["SKILL.md"]
|
|
854789
|
+
};
|
|
854790
|
+
const routines = {
|
|
854791
|
+
roots: [
|
|
854792
|
+
{ root: join90(cwd, ".goodvibes", "routines"), origin: "project-local" },
|
|
854793
|
+
{ root: join90(cwd, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "routines"), origin: "project-local" },
|
|
854794
|
+
{ root: join90(homeDir, ".goodvibes", "routines"), origin: "global" },
|
|
854795
|
+
{ root: join90(homeDir, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "routines"), origin: "global" }
|
|
854796
|
+
],
|
|
854797
|
+
markers: ["ROUTINE.md", "routine.md"],
|
|
854798
|
+
frontmatterBodyKey: "steps"
|
|
854799
|
+
};
|
|
854800
|
+
return {
|
|
854801
|
+
personas: summarizeDefinition(personas, 4),
|
|
854802
|
+
skills: summarizeDefinition(skills, 4),
|
|
854803
|
+
routines: summarizeDefinition(routines, 4)
|
|
854804
|
+
};
|
|
854805
|
+
}
|
|
854806
|
+
function summarizeAgentBehaviorDiscovery(shellPaths) {
|
|
854807
|
+
if (!shellPaths)
|
|
854808
|
+
return EMPTY_AGENT_BEHAVIOR_DISCOVERY_SNAPSHOT;
|
|
854809
|
+
return definitions(shellPaths);
|
|
854810
|
+
}
|
|
854811
|
+
|
|
854492
854812
|
// src/agent/memory-prompt.ts
|
|
854493
854813
|
var DEFAULT_LIMIT = 10;
|
|
854494
854814
|
var MIN_PROMPT_MEMORY_CONFIDENCE = 50;
|
|
@@ -854521,9 +854841,16 @@ function buildReviewedMemoryPrompt(memoryRegistry, limit3 = DEFAULT_LIMIT) {
|
|
|
854521
854841
|
function setupStatusForCount(count, ready, empty) {
|
|
854522
854842
|
return count > 0 ? ready : empty;
|
|
854523
854843
|
}
|
|
854844
|
+
function sampleNames(summary) {
|
|
854845
|
+
if (summary.names.length === 0)
|
|
854846
|
+
return "";
|
|
854847
|
+
const suffix = summary.count > summary.names.length ? `, +${summary.count - summary.names.length} more` : "";
|
|
854848
|
+
return ` Found: ${summary.names.join(", ")}${suffix}.`;
|
|
854849
|
+
}
|
|
854524
854850
|
function buildAgentWorkspaceSetupChecklist(input) {
|
|
854525
854851
|
const providerReady = input.provider !== "unknown" && input.model !== "unknown";
|
|
854526
854852
|
const hasActivePersona = input.activePersonaName !== "(none)" && input.activePersonaName !== "(unavailable)";
|
|
854853
|
+
const discoveredBehaviorCount = input.discoveredPersonas.count + input.discoveredSkills.count + input.discoveredRoutines.count;
|
|
854527
854854
|
return [
|
|
854528
854855
|
{
|
|
854529
854856
|
id: "runtime",
|
|
@@ -854549,30 +854876,30 @@ function buildAgentWorkspaceSetupChecklist(input) {
|
|
|
854549
854876
|
{
|
|
854550
854877
|
id: "profile",
|
|
854551
854878
|
label: "Agent profile",
|
|
854552
|
-
status:
|
|
854553
|
-
detail: input.runtimeProfileCount > 0 ? `${input.runtimeProfileCount} isolated Agent profile(s) are available.` : `${input.runtimeStarterTemplateCount} starter template(s) are available if this machine needs separate operator identities.`,
|
|
854554
|
-
command: "/agent-profile templates"
|
|
854879
|
+
status: input.runtimeProfileCount > 0 ? "ready" : discoveredBehaviorCount > 0 ? "recommended" : "optional",
|
|
854880
|
+
detail: input.runtimeProfileCount > 0 ? `${input.runtimeProfileCount} isolated Agent profile(s) are available.` : discoveredBehaviorCount > 0 ? `${discoveredBehaviorCount} discovered behavior file(s) can seed an isolated Agent profile from the Profiles workspace.` : `${input.runtimeStarterTemplateCount} starter template(s) are available if this machine needs separate operator identities.`,
|
|
854881
|
+
command: discoveredBehaviorCount > 0 && input.runtimeProfileCount === 0 ? "/agent-profile guide" : "/agent-profile templates"
|
|
854555
854882
|
},
|
|
854556
854883
|
{
|
|
854557
854884
|
id: "persona",
|
|
854558
854885
|
label: "Persona",
|
|
854559
854886
|
status: hasActivePersona ? "ready" : "recommended",
|
|
854560
|
-
detail: hasActivePersona ? `Active persona: ${input.activePersonaName}.` : "Create or choose a persona to make the assistant voice and policy explicit.",
|
|
854561
|
-
command: "/personas"
|
|
854887
|
+
detail: hasActivePersona ? `Active persona: ${input.activePersonaName}.${input.discoveredPersonas.count > 0 ? ` ${input.discoveredPersonas.count} discovered persona file(s) are still available to import.` : ""}` : input.discoveredPersonas.count > 0 ? `${input.discoveredPersonas.count} discovered persona file(s) can be imported into the Agent-local registry.${sampleNames(input.discoveredPersonas)}` : "Create or choose a persona to make the assistant voice and policy explicit.",
|
|
854888
|
+
command: input.discoveredPersonas.count > 0 ? "/personas discover" : "/personas"
|
|
854562
854889
|
},
|
|
854563
854890
|
{
|
|
854564
854891
|
id: "skills",
|
|
854565
854892
|
label: "Skills",
|
|
854566
|
-
status: input.enabledSkillCount > 0 || input.enabledSkillBundleCount > 0 ? "ready" : input.skillCount > 0 || input.skillBundleCount > 0 ? "recommended" : "optional",
|
|
854567
|
-
detail: input.skillCount > 0 || input.skillBundleCount > 0 ? `${input.enabledSkillCount}/${input.skillCount} local skill(s) enabled; ${input.enabledSkillBundleCount}/${input.skillBundleCount} bundle(s) enabled.` : "Create reusable local skills and bundles for repeated workflows.",
|
|
854568
|
-
command: "/agent-skills"
|
|
854893
|
+
status: input.enabledSkillCount > 0 || input.enabledSkillBundleCount > 0 ? "ready" : input.skillCount > 0 || input.skillBundleCount > 0 || input.discoveredSkills.count > 0 ? "recommended" : "optional",
|
|
854894
|
+
detail: input.skillCount > 0 || input.skillBundleCount > 0 ? `${input.enabledSkillCount}/${input.skillCount} local skill(s) enabled; ${input.enabledSkillBundleCount}/${input.skillBundleCount} bundle(s) enabled.${input.discoveredSkills.count > 0 ? ` ${input.discoveredSkills.count} discovered skill file(s) are still available to import.` : ""}` : input.discoveredSkills.count > 0 ? `${input.discoveredSkills.count} discovered skill file(s) can be imported as local reusable procedures.${sampleNames(input.discoveredSkills)}` : "Create reusable local skills and bundles for repeated workflows.",
|
|
854895
|
+
command: input.discoveredSkills.count > 0 ? "/agent-skills discover" : "/agent-skills"
|
|
854569
854896
|
},
|
|
854570
854897
|
{
|
|
854571
854898
|
id: "routines",
|
|
854572
854899
|
label: "Routines",
|
|
854573
|
-
status: setupStatusForCount(input.enabledRoutineCount, "ready", input.routineCount > 0 ? "recommended" : "optional"),
|
|
854574
|
-
detail: input.routineCount > 0 ? `${input.enabledRoutineCount}/${input.routineCount} local routine(s) enabled.` : "Create local routines first; promote schedules only with explicit confirmation.",
|
|
854575
|
-
command: "/routines"
|
|
854900
|
+
status: setupStatusForCount(input.enabledRoutineCount, "ready", input.routineCount > 0 || input.discoveredRoutines.count > 0 ? "recommended" : "optional"),
|
|
854901
|
+
detail: input.routineCount > 0 ? `${input.enabledRoutineCount}/${input.routineCount} local routine(s) enabled.${input.discoveredRoutines.count > 0 ? ` ${input.discoveredRoutines.count} discovered routine file(s) are still available to import.` : ""}` : input.discoveredRoutines.count > 0 ? `${input.discoveredRoutines.count} discovered routine file(s) can be imported as main-conversation workflows.${sampleNames(input.discoveredRoutines)}` : "Create local routines first; promote schedules only with explicit confirmation.",
|
|
854902
|
+
command: input.discoveredRoutines.count > 0 ? "/routines discover" : "/routines"
|
|
854576
854903
|
},
|
|
854577
854904
|
{
|
|
854578
854905
|
id: "memory",
|
|
@@ -854949,6 +855276,7 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
854949
855276
|
return { count: 0, enabled: 0, items: [] };
|
|
854950
855277
|
}
|
|
854951
855278
|
})();
|
|
855279
|
+
const discoveredBehavior = summarizeAgentBehaviorDiscovery(context.workspace?.shellPaths);
|
|
854952
855280
|
const runtimeProfiles = (() => {
|
|
854953
855281
|
try {
|
|
854954
855282
|
return listAgentRuntimeProfiles(context.workspace?.shellPaths?.homeDirectory ?? "");
|
|
@@ -855035,6 +855363,9 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
855035
855363
|
skillBundleCount: skillSnapshot.bundleCount,
|
|
855036
855364
|
enabledSkillBundleCount: skillSnapshot.enabledBundleCount,
|
|
855037
855365
|
activePersonaName: personaSnapshot.activeName,
|
|
855366
|
+
discoveredPersonas: discoveredBehavior.personas,
|
|
855367
|
+
discoveredSkills: discoveredBehavior.skills,
|
|
855368
|
+
discoveredRoutines: discoveredBehavior.routines,
|
|
855038
855369
|
readyChannelCount: channels.filter((channel) => channel.ready).length,
|
|
855039
855370
|
voiceProviderCount: voiceProviders.length,
|
|
855040
855371
|
mediaProviderCount: mediaProviders.length,
|
|
@@ -855068,6 +855399,7 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
|
|
|
855068
855399
|
localPersonaCount: personaSnapshot.count,
|
|
855069
855400
|
activePersonaName: personaSnapshot.activeName,
|
|
855070
855401
|
localPersonas: personaSnapshot.items,
|
|
855402
|
+
discoveredBehavior,
|
|
855071
855403
|
knowledgeRoute: "/api/goodvibes-agent/knowledge",
|
|
855072
855404
|
knowledgeIsolation: "agent-only",
|
|
855073
855405
|
executionPolicy: "serial-proactive",
|
|
@@ -855259,8 +855591,8 @@ function registerBuiltinCommands(registry5) {
|
|
|
855259
855591
|
}
|
|
855260
855592
|
|
|
855261
855593
|
// src/input/input-history.ts
|
|
855262
|
-
import { existsSync as existsSync73, mkdirSync as mkdirSync61, readFileSync as
|
|
855263
|
-
import { dirname as dirname59, join as
|
|
855594
|
+
import { existsSync as existsSync73, mkdirSync as mkdirSync61, readFileSync as readFileSync81, writeFileSync as writeFileSync52 } from "fs";
|
|
855595
|
+
import { dirname as dirname59, join as join91 } from "path";
|
|
855264
855596
|
class HistorySearch {
|
|
855265
855597
|
getEntries;
|
|
855266
855598
|
active = false;
|
|
@@ -855339,7 +855671,7 @@ function resolveHistoryPath2(options) {
|
|
|
855339
855671
|
if (!userRoot) {
|
|
855340
855672
|
throw new Error("InputHistory requires historyPath or an explicit userRoot/homeDirectory.");
|
|
855341
855673
|
}
|
|
855342
|
-
return
|
|
855674
|
+
return join91(userRoot, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "input-history.json");
|
|
855343
855675
|
}
|
|
855344
855676
|
|
|
855345
855677
|
class InputHistory {
|
|
@@ -855420,7 +855752,7 @@ class InputHistory {
|
|
|
855420
855752
|
load() {
|
|
855421
855753
|
try {
|
|
855422
855754
|
if (existsSync73(this.historyPath)) {
|
|
855423
|
-
const raw =
|
|
855755
|
+
const raw = readFileSync81(this.historyPath, "utf-8");
|
|
855424
855756
|
const parsed = JSON.parse(raw);
|
|
855425
855757
|
if (Array.isArray(parsed)) {
|
|
855426
855758
|
this.entries = parsed.map((entry) => this.normalizeStoredEntry(entry)).filter((entry) => entry !== null).slice(0, this.maxEntries);
|
|
@@ -861193,7 +861525,7 @@ function registerAgentPanels(manager5, deps) {
|
|
|
861193
861525
|
|
|
861194
861526
|
// src/panels/builtin/session.ts
|
|
861195
861527
|
import { networkInterfaces as networkInterfaces3 } from "os";
|
|
861196
|
-
import { readFileSync as
|
|
861528
|
+
import { readFileSync as readFileSync82 } from "fs";
|
|
861197
861529
|
|
|
861198
861530
|
// src/panels/confirm-state.ts
|
|
861199
861531
|
function handleConfirmInput(confirm, key) {
|
|
@@ -862769,7 +863101,7 @@ function getLocalNetworkIp2() {
|
|
|
862769
863101
|
}
|
|
862770
863102
|
function readBootstrapPassword(credentialPath) {
|
|
862771
863103
|
try {
|
|
862772
|
-
const content =
|
|
863104
|
+
const content = readFileSync82(credentialPath, "utf-8");
|
|
862773
863105
|
for (const line2 of content.split(`
|
|
862774
863106
|
`)) {
|
|
862775
863107
|
if (line2.startsWith("password=")) {
|
|
@@ -864141,7 +864473,7 @@ function createBootstrapShell(options) {
|
|
|
864141
864473
|
hookActivityTracker: services.hookActivityTracker,
|
|
864142
864474
|
hookWorkbench: services.hookWorkbench,
|
|
864143
864475
|
mcpRegistry: services.mcpRegistry,
|
|
864144
|
-
daemonHomeDir:
|
|
864476
|
+
daemonHomeDir: join92(services.homeDirectory, ".goodvibes", "daemon")
|
|
864145
864477
|
});
|
|
864146
864478
|
services.panelManager.prewarmRegistered();
|
|
864147
864479
|
const systemMessageRouter = createSystemMessageRouter(conversation, systemMessagesPanel, (kind2) => {
|
|
@@ -866087,7 +866419,7 @@ var verifyBundle2 = exports_security2.verifyBundle;
|
|
|
866087
866419
|
var MAX_INPUT_LENGTH2 = exports_security2.MAX_INPUT_LENGTH;
|
|
866088
866420
|
var MAX_TOKEN_COUNT2 = exports_security2.MAX_TOKEN_COUNT;
|
|
866089
866421
|
// src/runtime/onboarding/state.ts
|
|
866090
|
-
import { existsSync as existsSync74, mkdirSync as mkdirSync62, readFileSync as
|
|
866422
|
+
import { existsSync as existsSync74, mkdirSync as mkdirSync62, readFileSync as readFileSync83, writeFileSync as writeFileSync53 } from "fs";
|
|
866091
866423
|
import { dirname as dirname60 } from "path";
|
|
866092
866424
|
var ONBOARDING_RUNTIME_STATE_FILE = "onboarding-state.json";
|
|
866093
866425
|
function resolveStatePath(shellPaths, scope) {
|
|
@@ -866133,7 +866465,7 @@ function readOnboardingRuntimeState(shellPaths, scope = "project") {
|
|
|
866133
866465
|
};
|
|
866134
866466
|
}
|
|
866135
866467
|
try {
|
|
866136
|
-
const parsed = JSON.parse(
|
|
866468
|
+
const parsed = JSON.parse(readFileSync83(path7, "utf-8"));
|
|
866137
866469
|
if (!isRuntimeStatePayload(parsed)) {
|
|
866138
866470
|
return {
|
|
866139
866471
|
scope,
|
|
@@ -866493,6 +866825,7 @@ async function collectOnboardingSnapshot(deps) {
|
|
|
866493
866825
|
records: sortSurfaceRecords(surfaceResult.value)
|
|
866494
866826
|
},
|
|
866495
866827
|
providerAccounts: providerAccountsResult.value,
|
|
866828
|
+
localBehaviorDiscovery: summarizeAgentBehaviorDiscovery(deps.shellPaths),
|
|
866496
866829
|
collectionIssues
|
|
866497
866830
|
};
|
|
866498
866831
|
}
|
|
@@ -866550,13 +866883,13 @@ var INBOUND_EVENT_SURFACE_KINDS = new Set([
|
|
|
866550
866883
|
]);
|
|
866551
866884
|
// src/runtime/onboarding/apply.ts
|
|
866552
866885
|
init_config8();
|
|
866553
|
-
import { existsSync as existsSync76, mkdirSync as mkdirSync63, readFileSync as
|
|
866886
|
+
import { existsSync as existsSync76, mkdirSync as mkdirSync63, readFileSync as readFileSync84, rmSync as rmSync10, unlinkSync as unlinkSync12, writeFileSync as writeFileSync54 } from "fs";
|
|
866554
866887
|
import { dirname as dirname61 } from "path";
|
|
866555
866888
|
|
|
866556
866889
|
// src/runtime/onboarding/verify.ts
|
|
866557
866890
|
init_config8();
|
|
866558
866891
|
import { existsSync as existsSync75 } from "fs";
|
|
866559
|
-
import { join as
|
|
866892
|
+
import { join as join93 } from "path";
|
|
866560
866893
|
function getNow(deps) {
|
|
866561
866894
|
return deps.clock?.() ?? Date.now();
|
|
866562
866895
|
}
|
|
@@ -866637,7 +866970,7 @@ function verifyAuthOperation(_deps, operation) {
|
|
|
866637
866970
|
}
|
|
866638
866971
|
function verifyCreateAgentProfileOperation(deps, operation) {
|
|
866639
866972
|
const resolution2 = resolveAgentRuntimeProfileHome(deps.shellPaths.homeDirectory, operation.name);
|
|
866640
|
-
const ok3 = existsSync75(
|
|
866973
|
+
const ok3 = existsSync75(join93(resolution2.homeDirectory, "profile.json"));
|
|
866641
866974
|
return {
|
|
866642
866975
|
id: `agent-profile:${resolution2.id}`,
|
|
866643
866976
|
status: ok3 ? "pass" : "fail",
|
|
@@ -866675,7 +867008,7 @@ function isPlainObject3(value) {
|
|
|
866675
867008
|
function readJsonObject(path7) {
|
|
866676
867009
|
if (!existsSync76(path7))
|
|
866677
867010
|
return {};
|
|
866678
|
-
const parsed = JSON.parse(
|
|
867011
|
+
const parsed = JSON.parse(readFileSync84(path7, "utf-8"));
|
|
866679
867012
|
if (!isPlainObject3(parsed))
|
|
866680
867013
|
throw new Error(`Expected an object JSON payload at ${path7}.`);
|
|
866681
867014
|
return parsed;
|
|
@@ -866710,7 +867043,7 @@ function restoreFile(path7, previous, reload) {
|
|
|
866710
867043
|
reload?.();
|
|
866711
867044
|
}
|
|
866712
867045
|
function snapshotFileRollback(path7, reload) {
|
|
866713
|
-
const previous = existsSync76(path7) ?
|
|
867046
|
+
const previous = existsSync76(path7) ? readFileSync84(path7, "utf-8") : null;
|
|
866714
867047
|
return () => restoreFile(path7, previous, reload);
|
|
866715
867048
|
}
|
|
866716
867049
|
async function runRollbacks(rollbacks) {
|
|
@@ -866873,7 +867206,7 @@ async function buildSecretRollbackAction(deps, operation) {
|
|
|
866873
867206
|
throw new Error(`Secret storage locations for ${scope} scope are unavailable.`);
|
|
866874
867207
|
const snapshots = locations.map((location) => ({
|
|
866875
867208
|
path: location.path,
|
|
866876
|
-
previous: existsSync76(location.path) ?
|
|
867209
|
+
previous: existsSync76(location.path) ? readFileSync84(location.path, "utf-8") : null
|
|
866877
867210
|
}));
|
|
866878
867211
|
return () => {
|
|
866879
867212
|
for (const snapshot of snapshots)
|
|
@@ -867093,7 +867426,7 @@ async function applyOnboardingRequest(deps, request2) {
|
|
|
867093
867426
|
};
|
|
867094
867427
|
}
|
|
867095
867428
|
// src/runtime/onboarding/markers.ts
|
|
867096
|
-
import { existsSync as existsSync77, mkdirSync as mkdirSync64, readFileSync as
|
|
867429
|
+
import { existsSync as existsSync77, mkdirSync as mkdirSync64, readFileSync as readFileSync85, writeFileSync as writeFileSync55 } from "fs";
|
|
867097
867430
|
import { dirname as dirname62 } from "path";
|
|
867098
867431
|
var ONBOARDING_CHECK_MARKER_FILE = "onboarding-checked.json";
|
|
867099
867432
|
function resolveMarkerPath(shellPaths, scope) {
|
|
@@ -867140,7 +867473,7 @@ function readOnboardingCheckMarker(shellPaths, scope = "user") {
|
|
|
867140
867473
|
if (!existsSync77(path7))
|
|
867141
867474
|
return buildMissingMarkerState(scope, path7);
|
|
867142
867475
|
try {
|
|
867143
|
-
const parsed = JSON.parse(
|
|
867476
|
+
const parsed = JSON.parse(readFileSync85(path7, "utf-8"));
|
|
867144
867477
|
if (!isCheckMarkerPayload(parsed)) {
|
|
867145
867478
|
return buildParseErrorState(scope, path7, "Invalid onboarding check marker payload.");
|
|
867146
867479
|
}
|
|
@@ -867182,7 +867515,7 @@ function writeOnboardingCheckMarker(shellPaths, options = {}) {
|
|
|
867182
867515
|
return readOnboardingCheckMarker(shellPaths, scope);
|
|
867183
867516
|
}
|
|
867184
867517
|
// src/input/handler-content-actions.ts
|
|
867185
|
-
import { readFileSync as
|
|
867518
|
+
import { readFileSync as readFileSync86, existsSync as existsSync78 } from "fs";
|
|
867186
867519
|
var MARKER_REGEX = /\[(TEXT|IMAGE): [^\]]+\]/g;
|
|
867187
867520
|
var IMAGE_PREFIXES = [
|
|
867188
867521
|
{ prefix: "iVBORw0KGgo", mediaType: "image/png" },
|
|
@@ -867244,7 +867577,7 @@ function registerPaste(state4, content, projectRoot) {
|
|
|
867244
867577
|
try {
|
|
867245
867578
|
const resolvedPath3 = resolveAndValidatePath(trimmed2, projectRoot);
|
|
867246
867579
|
if (existsSync78(resolvedPath3)) {
|
|
867247
|
-
const data =
|
|
867580
|
+
const data = readFileSync86(resolvedPath3);
|
|
867248
867581
|
const base644 = data.toString("base64");
|
|
867249
867582
|
const ext = trimmed2.slice(trimmed2.lastIndexOf("."));
|
|
867250
867583
|
const mediaType = mediaTypeFromExt(ext);
|
|
@@ -867294,7 +867627,7 @@ function expandPrompt(pasteRegistry, imageRegistry, text, projectRoot) {
|
|
|
867294
867627
|
const filePath = injectMatch[1];
|
|
867295
867628
|
try {
|
|
867296
867629
|
const resolvedPath3 = resolveAndValidatePath(filePath, projectRoot);
|
|
867297
|
-
const content =
|
|
867630
|
+
const content = readFileSync86(resolvedPath3, "utf-8");
|
|
867298
867631
|
expanded = expanded.slice(0, injectMatch.index) + content + expanded.slice(injectMatch.index + injectMatch[0].length);
|
|
867299
867632
|
injectRegex.lastIndex = injectMatch.index + content.length;
|
|
867300
867633
|
} catch (err2) {
|
|
@@ -868694,7 +869027,7 @@ class AutocompleteEngine {
|
|
|
868694
869027
|
|
|
868695
869028
|
// src/input/file-picker.ts
|
|
868696
869029
|
import { readdir as readdir6 } from "fs/promises";
|
|
868697
|
-
import { join as
|
|
869030
|
+
import { join as join94, relative as relative15 } from "path";
|
|
868698
869031
|
|
|
868699
869032
|
class FilePickerModal {
|
|
868700
869033
|
shellPaths;
|
|
@@ -868827,7 +869160,7 @@ class FilePickerModal {
|
|
|
868827
869160
|
continue;
|
|
868828
869161
|
if (entry.name === "node_modules" || entry.name === "dist")
|
|
868829
869162
|
continue;
|
|
868830
|
-
const fullPath =
|
|
869163
|
+
const fullPath = join94(dir, entry.name);
|
|
868831
869164
|
const relPath = relative15(this.shellPaths.workingDirectory, fullPath);
|
|
868832
869165
|
if (entry.isDirectory()) {
|
|
868833
869166
|
files.push(relPath + "/");
|
|
@@ -872249,246 +872582,13 @@ function quoteSlashCommandArg(value) {
|
|
|
872249
872582
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
872250
872583
|
}
|
|
872251
872584
|
|
|
872252
|
-
// src/input/agent-workspace-basic-command-
|
|
872585
|
+
// src/input/agent-workspace-basic-command-editor-submission.ts
|
|
872253
872586
|
function isAffirmative2(value) {
|
|
872254
872587
|
return /^(y|yes|true)$/i.test(value.trim());
|
|
872255
872588
|
}
|
|
872256
872589
|
function splitCommaList(value) {
|
|
872257
872590
|
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
872258
872591
|
}
|
|
872259
|
-
function isAgentWorkspaceBasicCommandEditorKind(kind2) {
|
|
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";
|
|
872261
|
-
}
|
|
872262
|
-
function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
872263
|
-
if (kind2 === "knowledge-bookmarks") {
|
|
872264
|
-
return {
|
|
872265
|
-
kind: kind2,
|
|
872266
|
-
mode: "create",
|
|
872267
|
-
title: "Import Bookmarks into Agent Knowledge",
|
|
872268
|
-
selectedFieldIndex: 0,
|
|
872269
|
-
message: "Import a browser bookmark export into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
|
|
872270
|
-
fields: [
|
|
872271
|
-
{ id: "path", label: "Bookmark export path", value: "", required: true, multiline: false, hint: "Path to an HTML or JSON browser bookmark export." },
|
|
872272
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge import-bookmarks with --yes." }
|
|
872273
|
-
]
|
|
872274
|
-
};
|
|
872275
|
-
}
|
|
872276
|
-
if (kind2 === "knowledge-file") {
|
|
872277
|
-
return {
|
|
872278
|
-
kind: kind2,
|
|
872279
|
-
mode: "create",
|
|
872280
|
-
title: "Ingest File into Agent Knowledge",
|
|
872281
|
-
selectedFieldIndex: 0,
|
|
872282
|
-
message: "Import a local source-backed file into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
|
|
872283
|
-
fields: [
|
|
872284
|
-
{ id: "path", label: "File path", value: "", required: true, multiline: false, hint: "Path to a local document or text file to ingest." },
|
|
872285
|
-
{ id: "title", label: "Title", value: "", required: false, multiline: false, hint: "Optional source title." },
|
|
872286
|
-
{ id: "tags", label: "Tags", value: "", required: false, multiline: false, hint: "Comma-separated optional tags." },
|
|
872287
|
-
{ id: "folder", label: "Folder", value: "", required: false, multiline: false, hint: "Optional Agent Knowledge folder path." },
|
|
872288
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge ingest-file with --yes." }
|
|
872289
|
-
]
|
|
872290
|
-
};
|
|
872291
|
-
}
|
|
872292
|
-
if (kind2 === "knowledge-browser-history") {
|
|
872293
|
-
return {
|
|
872294
|
-
kind: kind2,
|
|
872295
|
-
mode: "create",
|
|
872296
|
-
title: "Import Browser History into Agent Knowledge",
|
|
872297
|
-
selectedFieldIndex: 0,
|
|
872298
|
-
message: "Import local browser history/bookmarks into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
|
|
872299
|
-
fields: [
|
|
872300
|
-
{ id: "browsers", label: "Browsers", value: "", required: false, multiline: false, hint: "Optional comma list: chrome, brave, edge, firefox, safari, etc." },
|
|
872301
|
-
{ id: "sources", label: "Sources", value: "history,bookmark", required: false, multiline: false, hint: "history, bookmark, or both." },
|
|
872302
|
-
{ id: "limit", label: "Limit", value: "250", required: false, multiline: false, hint: "Maximum browser entries to import." },
|
|
872303
|
-
{ id: "sinceDays", label: "Since days", value: "", required: false, multiline: false, hint: "Optional age window, such as 30." },
|
|
872304
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge import-browser-history with --yes." }
|
|
872305
|
-
]
|
|
872306
|
-
};
|
|
872307
|
-
}
|
|
872308
|
-
if (kind2 === "knowledge-connector-ingest") {
|
|
872309
|
-
return {
|
|
872310
|
-
kind: kind2,
|
|
872311
|
-
mode: "create",
|
|
872312
|
-
title: "Ingest Connector Input",
|
|
872313
|
-
selectedFieldIndex: 0,
|
|
872314
|
-
message: "Send explicit connector input into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
|
|
872315
|
-
fields: [
|
|
872316
|
-
{ id: "connectorId", label: "Connector id", value: "", required: true, multiline: false, hint: "Connector id from /knowledge connectors." },
|
|
872317
|
-
{ id: "input", label: "Input", value: "", required: false, multiline: true, hint: "Optional JSON or text input. Ctrl-J inserts a new line." },
|
|
872318
|
-
{ id: "path", label: "Path", value: "", required: false, multiline: false, hint: "Optional local path for connectors that read files." },
|
|
872319
|
-
{ id: "content", label: "Content", value: "", required: false, multiline: true, hint: "Optional raw content for connectors that accept text." },
|
|
872320
|
-
{ id: "allowPrivateHosts", label: "Allow private hosts", value: "no", required: false, multiline: false, hint: "yes/no. Defaults to no." },
|
|
872321
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge ingest-connector with --yes." }
|
|
872322
|
-
]
|
|
872323
|
-
};
|
|
872324
|
-
}
|
|
872325
|
-
if (kind2 === "mcp-server") {
|
|
872326
|
-
return {
|
|
872327
|
-
kind: kind2,
|
|
872328
|
-
mode: "create",
|
|
872329
|
-
title: "Add MCP Server",
|
|
872330
|
-
selectedFieldIndex: 0,
|
|
872331
|
-
message: "Add or update one MCP server from the Agent workspace. Type yes on the final field to confirm.",
|
|
872332
|
-
fields: [
|
|
872333
|
-
{ id: "name", label: "Server name", value: "", required: true, multiline: false, hint: "Letters, numbers, dot, underscore, and dash only." },
|
|
872334
|
-
{ id: "command", label: "Command", value: "", required: true, multiline: false, hint: "Executable command, such as bunx, npx, uvx, or a full local binary path." },
|
|
872335
|
-
{ id: "args", label: "Arguments", value: "", required: false, multiline: false, hint: "Optional command arguments. Quotes are supported." },
|
|
872336
|
-
{ id: "scope", label: "Scope", value: "", required: false, multiline: false, hint: "Optional. Defaults to project. Use project or global." },
|
|
872337
|
-
{ id: "role", label: "Role", value: "", required: false, multiline: false, hint: "Optional. general, docs, filesystem, git, database, browser, automation, ops, or remote." },
|
|
872338
|
-
{ id: "trust", label: "Trust mode", value: "", required: false, multiline: false, hint: "Optional. Defaults to constrained. Use constrained, ask-on-risk, or blocked. Use settings for allow-all." },
|
|
872339
|
-
{ id: "env", label: "Env refs", value: "", required: false, multiline: false, hint: "Comma-separated KEY=VALUE entries. Prefer secret refs, not raw secrets." },
|
|
872340
|
-
{ id: "paths", label: "Allowed paths", value: "", required: false, multiline: false, hint: "Comma-separated path allowlist entries." },
|
|
872341
|
-
{ id: "hosts", label: "Allowed hosts", value: "", required: false, multiline: false, hint: "Comma-separated host allowlist entries." },
|
|
872342
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /mcp add with --yes." }
|
|
872343
|
-
]
|
|
872344
|
-
};
|
|
872345
|
-
}
|
|
872346
|
-
if (kind2 === "notify-webhook") {
|
|
872347
|
-
return {
|
|
872348
|
-
kind: kind2,
|
|
872349
|
-
mode: "create",
|
|
872350
|
-
title: "Add Notification Webhook",
|
|
872351
|
-
selectedFieldIndex: 0,
|
|
872352
|
-
message: "Add one webhook notification target for explicit reminder/routine delivery. Type yes on the final field to confirm.",
|
|
872353
|
-
fields: [
|
|
872354
|
-
{ id: "url", label: "Webhook URL", value: "", required: true, multiline: false, hint: "HTTP(S) target, for example https://ntfy.sh/my-topic." },
|
|
872355
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /notify add with --yes." }
|
|
872356
|
-
]
|
|
872357
|
-
};
|
|
872358
|
-
}
|
|
872359
|
-
if (kind2 === "notify-webhook-remove") {
|
|
872360
|
-
return {
|
|
872361
|
-
kind: kind2,
|
|
872362
|
-
mode: "delete",
|
|
872363
|
-
title: "Remove Notification Webhook",
|
|
872364
|
-
selectedFieldIndex: 0,
|
|
872365
|
-
message: "Remove one configured webhook notification target. Type yes on the final field to confirm.",
|
|
872366
|
-
fields: [
|
|
872367
|
-
{ id: "url", label: "Webhook URL", value: "", required: true, multiline: false, hint: "Exact HTTP(S) webhook URL to remove from configured notification targets." },
|
|
872368
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /notify remove with --yes." }
|
|
872369
|
-
]
|
|
872370
|
-
};
|
|
872371
|
-
}
|
|
872372
|
-
if (kind2 === "notify-webhook-test") {
|
|
872373
|
-
return {
|
|
872374
|
-
kind: kind2,
|
|
872375
|
-
mode: "create",
|
|
872376
|
-
title: "Test Notification Webhooks",
|
|
872377
|
-
selectedFieldIndex: 0,
|
|
872378
|
-
message: "Send one test notification to configured webhook targets. Type yes on the final field to confirm.",
|
|
872379
|
-
fields: [
|
|
872380
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /notify test with --yes." }
|
|
872381
|
-
]
|
|
872382
|
-
};
|
|
872383
|
-
}
|
|
872384
|
-
if (kind2 === "tts-prompt") {
|
|
872385
|
-
return {
|
|
872386
|
-
kind: kind2,
|
|
872387
|
-
mode: "create",
|
|
872388
|
-
title: "Speak Assistant Reply",
|
|
872389
|
-
selectedFieldIndex: 0,
|
|
872390
|
-
message: "Submit a normal assistant prompt and play the reply through configured live TTS.",
|
|
872391
|
-
fields: [
|
|
872392
|
-
{ id: "prompt", label: "Prompt", value: "", required: true, multiline: true, hint: "Assistant prompt to speak. Ctrl-J inserts a new line." }
|
|
872393
|
-
]
|
|
872394
|
-
};
|
|
872395
|
-
}
|
|
872396
|
-
if (kind2 === "image-input") {
|
|
872397
|
-
return {
|
|
872398
|
-
kind: kind2,
|
|
872399
|
-
mode: "create",
|
|
872400
|
-
title: "Attach Image Input",
|
|
872401
|
-
selectedFieldIndex: 0,
|
|
872402
|
-
message: "Attach an image to the next assistant turn. The existing image command validates file type and model support.",
|
|
872403
|
-
fields: [
|
|
872404
|
-
{ id: "path", label: "Image path", value: "", required: true, multiline: false, hint: "PNG, JPEG, WebP, or GIF path under the current workspace." },
|
|
872405
|
-
{ id: "prompt", label: "Prompt", value: "", required: false, multiline: true, hint: "Optional prompt. Ctrl-J inserts a new line." }
|
|
872406
|
-
]
|
|
872407
|
-
};
|
|
872408
|
-
}
|
|
872409
|
-
if (kind2 === "profile-template-export") {
|
|
872410
|
-
return {
|
|
872411
|
-
kind: kind2,
|
|
872412
|
-
mode: "create",
|
|
872413
|
-
title: "Export Agent Starter Template",
|
|
872414
|
-
selectedFieldIndex: 0,
|
|
872415
|
-
message: "Export a starter template JSON file for review and customization. Type yes on the final field to confirm.",
|
|
872416
|
-
fields: [
|
|
872417
|
-
{ id: "templateId", label: "Starter id", value: "", required: true, multiline: false, hint: "Existing starter id from /agent-profile templates." },
|
|
872418
|
-
{ id: "path", label: "Output path", value: "", required: true, multiline: false, hint: "Workspace-relative JSON path to write." },
|
|
872419
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-profile template export with --yes." }
|
|
872420
|
-
]
|
|
872421
|
-
};
|
|
872422
|
-
}
|
|
872423
|
-
if (kind2 === "profile-template-import") {
|
|
872424
|
-
return {
|
|
872425
|
-
kind: kind2,
|
|
872426
|
-
mode: "create",
|
|
872427
|
-
title: "Import Agent Starter Template",
|
|
872428
|
-
selectedFieldIndex: 0,
|
|
872429
|
-
message: "Import a reviewed starter template JSON file into this Agent home. Type yes on the final field to confirm.",
|
|
872430
|
-
fields: [
|
|
872431
|
-
{ id: "path", label: "Template path", value: "", required: true, multiline: false, hint: "Workspace-relative JSON path to import." },
|
|
872432
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-profile template import with --yes." }
|
|
872433
|
-
]
|
|
872434
|
-
};
|
|
872435
|
-
}
|
|
872436
|
-
if (kind2 === "skill-discovery-import") {
|
|
872437
|
-
return {
|
|
872438
|
-
kind: kind2,
|
|
872439
|
-
mode: "create",
|
|
872440
|
-
title: "Import Discovered Skill",
|
|
872441
|
-
selectedFieldIndex: 0,
|
|
872442
|
-
message: "Import one discovered SKILL.md or .md skill file into the Agent-local skill registry. Type yes on the final field to confirm.",
|
|
872443
|
-
fields: [
|
|
872444
|
-
{ id: "name", label: "Discovered skill", value: "", required: true, multiline: false, hint: "Name shown by /agent-skills discover." },
|
|
872445
|
-
{ id: "enabled", label: "Enable now", value: "yes", required: false, multiline: false, hint: "yes/no." },
|
|
872446
|
-
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-skills import-discovered with --yes." }
|
|
872447
|
-
]
|
|
872448
|
-
};
|
|
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
|
-
}
|
|
872478
|
-
return {
|
|
872479
|
-
kind: kind2,
|
|
872480
|
-
mode: "create",
|
|
872481
|
-
title: "Create Skill Bundle",
|
|
872482
|
-
selectedFieldIndex: 0,
|
|
872483
|
-
message: "Group existing local skills into a reviewable bundle that can be enabled together.",
|
|
872484
|
-
fields: [
|
|
872485
|
-
{ id: "name", label: "Bundle name", value: "", required: true, multiline: false, hint: "Short bundle name." },
|
|
872486
|
-
{ id: "description", label: "Description", value: "", required: true, multiline: false, hint: "One-line bundle summary." },
|
|
872487
|
-
{ id: "skills", label: "Skill ids", value: "", required: true, multiline: false, hint: "Comma-separated existing local skill ids." },
|
|
872488
|
-
{ id: "enabled", label: "Enable now", value: "yes", required: false, multiline: false, hint: "yes/no." }
|
|
872489
|
-
]
|
|
872490
|
-
};
|
|
872491
|
-
}
|
|
872492
872592
|
function buildAgentWorkspaceBasicCommandEditorSubmission(editor, readField, commandDispatchAvailable) {
|
|
872493
872593
|
if (!commandDispatchAvailable) {
|
|
872494
872594
|
return {
|
|
@@ -872815,6 +872915,100 @@ function buildAgentWorkspaceBasicCommandEditorSubmission(editor, readField, comm
|
|
|
872815
872915
|
}
|
|
872816
872916
|
};
|
|
872817
872917
|
}
|
|
872918
|
+
if (editor.kind === "profile-template-from-discovered") {
|
|
872919
|
+
if (!isAffirmative2(readField("confirm"))) {
|
|
872920
|
+
return {
|
|
872921
|
+
kind: "editor",
|
|
872922
|
+
editor: { ...editor, message: "Starter-from-discovered creation not confirmed. Type yes, then press Enter." },
|
|
872923
|
+
status: "Agent starter-from-discovered creation not confirmed."
|
|
872924
|
+
};
|
|
872925
|
+
}
|
|
872926
|
+
const parts2 = [
|
|
872927
|
+
"/agent-profile",
|
|
872928
|
+
"template",
|
|
872929
|
+
"from-discovered",
|
|
872930
|
+
quoteSlashCommandArg(readField("id"))
|
|
872931
|
+
];
|
|
872932
|
+
const name51 = readField("name");
|
|
872933
|
+
const description = readField("description");
|
|
872934
|
+
const persona = readField("persona");
|
|
872935
|
+
const skills = readField("skills");
|
|
872936
|
+
const routines = readField("routines");
|
|
872937
|
+
if (name51.length > 0)
|
|
872938
|
+
parts2.push("--name", quoteSlashCommandArg(name51));
|
|
872939
|
+
if (description.length > 0)
|
|
872940
|
+
parts2.push("--description", quoteSlashCommandArg(description));
|
|
872941
|
+
if (persona.length > 0)
|
|
872942
|
+
parts2.push("--persona", quoteSlashCommandArg(persona));
|
|
872943
|
+
if (skills.length > 0)
|
|
872944
|
+
parts2.push("--skills", quoteSlashCommandArg(skills));
|
|
872945
|
+
if (routines.length > 0)
|
|
872946
|
+
parts2.push("--routines", quoteSlashCommandArg(routines));
|
|
872947
|
+
if (isAffirmative2(readField("replace")))
|
|
872948
|
+
parts2.push("--replace");
|
|
872949
|
+
parts2.push("--yes");
|
|
872950
|
+
const command9 = parts2.join(" ");
|
|
872951
|
+
return {
|
|
872952
|
+
kind: "dispatch",
|
|
872953
|
+
command: command9,
|
|
872954
|
+
status: "Opening Agent starter-from-discovered creation.",
|
|
872955
|
+
actionResult: {
|
|
872956
|
+
kind: "dispatched",
|
|
872957
|
+
title: "Opening Agent starter-from-discovered creation",
|
|
872958
|
+
detail: "The workspace handed a confirmed starter creation command to the shell-owned command router.",
|
|
872959
|
+
command: command9,
|
|
872960
|
+
safety: "safe"
|
|
872961
|
+
}
|
|
872962
|
+
};
|
|
872963
|
+
}
|
|
872964
|
+
if (editor.kind === "profile-from-discovered") {
|
|
872965
|
+
if (!isAffirmative2(readField("confirm"))) {
|
|
872966
|
+
return {
|
|
872967
|
+
kind: "editor",
|
|
872968
|
+
editor: { ...editor, message: "Profile-from-discovered creation not confirmed. Type yes, then press Enter." },
|
|
872969
|
+
status: "Agent profile-from-discovered creation not confirmed."
|
|
872970
|
+
};
|
|
872971
|
+
}
|
|
872972
|
+
const parts2 = [
|
|
872973
|
+
"/agent-profile",
|
|
872974
|
+
"create-from-discovered",
|
|
872975
|
+
quoteSlashCommandArg(readField("profile"))
|
|
872976
|
+
];
|
|
872977
|
+
const templateId = readField("templateId");
|
|
872978
|
+
const name51 = readField("name");
|
|
872979
|
+
const description = readField("description");
|
|
872980
|
+
const persona = readField("persona");
|
|
872981
|
+
const skills = readField("skills");
|
|
872982
|
+
const routines = readField("routines");
|
|
872983
|
+
if (templateId.length > 0)
|
|
872984
|
+
parts2.push("--template-id", quoteSlashCommandArg(templateId));
|
|
872985
|
+
if (name51.length > 0)
|
|
872986
|
+
parts2.push("--name", quoteSlashCommandArg(name51));
|
|
872987
|
+
if (description.length > 0)
|
|
872988
|
+
parts2.push("--description", quoteSlashCommandArg(description));
|
|
872989
|
+
if (persona.length > 0)
|
|
872990
|
+
parts2.push("--persona", quoteSlashCommandArg(persona));
|
|
872991
|
+
if (skills.length > 0)
|
|
872992
|
+
parts2.push("--skills", quoteSlashCommandArg(skills));
|
|
872993
|
+
if (routines.length > 0)
|
|
872994
|
+
parts2.push("--routines", quoteSlashCommandArg(routines));
|
|
872995
|
+
if (isAffirmative2(readField("replace")))
|
|
872996
|
+
parts2.push("--replace");
|
|
872997
|
+
parts2.push("--yes");
|
|
872998
|
+
const command9 = parts2.join(" ");
|
|
872999
|
+
return {
|
|
873000
|
+
kind: "dispatch",
|
|
873001
|
+
command: command9,
|
|
873002
|
+
status: "Opening Agent profile-from-discovered creation.",
|
|
873003
|
+
actionResult: {
|
|
873004
|
+
kind: "dispatched",
|
|
873005
|
+
title: "Opening Agent profile-from-discovered creation",
|
|
873006
|
+
detail: "The workspace handed a confirmed discovered-behavior profile creation command to the shell-owned command router.",
|
|
873007
|
+
command: command9,
|
|
873008
|
+
safety: "safe"
|
|
873009
|
+
}
|
|
873010
|
+
};
|
|
873011
|
+
}
|
|
872818
873012
|
if (editor.kind === "skill-discovery-import") {
|
|
872819
873013
|
if (!isAffirmative2(readField("confirm"))) {
|
|
872820
873014
|
return {
|
|
@@ -872931,6 +873125,280 @@ function buildAgentWorkspaceBasicCommandEditorSubmission(editor, readField, comm
|
|
|
872931
873125
|
};
|
|
872932
873126
|
}
|
|
872933
873127
|
|
|
873128
|
+
// src/input/agent-workspace-basic-command-editors.ts
|
|
873129
|
+
function isAgentWorkspaceBasicCommandEditorKind(kind2) {
|
|
873130
|
+
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 === "profile-template-from-discovered" || kind2 === "profile-from-discovered" || kind2 === "mcp-server" || kind2 === "notify-webhook" || kind2 === "notify-webhook-remove" || kind2 === "notify-webhook-test";
|
|
873131
|
+
}
|
|
873132
|
+
function createAgentWorkspaceBasicCommandEditor(kind2) {
|
|
873133
|
+
if (kind2 === "knowledge-bookmarks") {
|
|
873134
|
+
return {
|
|
873135
|
+
kind: kind2,
|
|
873136
|
+
mode: "create",
|
|
873137
|
+
title: "Import Bookmarks into Agent Knowledge",
|
|
873138
|
+
selectedFieldIndex: 0,
|
|
873139
|
+
message: "Import a browser bookmark export into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
|
|
873140
|
+
fields: [
|
|
873141
|
+
{ id: "path", label: "Bookmark export path", value: "", required: true, multiline: false, hint: "Path to an HTML or JSON browser bookmark export." },
|
|
873142
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge import-bookmarks with --yes." }
|
|
873143
|
+
]
|
|
873144
|
+
};
|
|
873145
|
+
}
|
|
873146
|
+
if (kind2 === "knowledge-file") {
|
|
873147
|
+
return {
|
|
873148
|
+
kind: kind2,
|
|
873149
|
+
mode: "create",
|
|
873150
|
+
title: "Ingest File into Agent Knowledge",
|
|
873151
|
+
selectedFieldIndex: 0,
|
|
873152
|
+
message: "Import a local source-backed file into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
|
|
873153
|
+
fields: [
|
|
873154
|
+
{ id: "path", label: "File path", value: "", required: true, multiline: false, hint: "Path to a local document or text file to ingest." },
|
|
873155
|
+
{ id: "title", label: "Title", value: "", required: false, multiline: false, hint: "Optional source title." },
|
|
873156
|
+
{ id: "tags", label: "Tags", value: "", required: false, multiline: false, hint: "Comma-separated optional tags." },
|
|
873157
|
+
{ id: "folder", label: "Folder", value: "", required: false, multiline: false, hint: "Optional Agent Knowledge folder path." },
|
|
873158
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge ingest-file with --yes." }
|
|
873159
|
+
]
|
|
873160
|
+
};
|
|
873161
|
+
}
|
|
873162
|
+
if (kind2 === "knowledge-browser-history") {
|
|
873163
|
+
return {
|
|
873164
|
+
kind: kind2,
|
|
873165
|
+
mode: "create",
|
|
873166
|
+
title: "Import Browser History into Agent Knowledge",
|
|
873167
|
+
selectedFieldIndex: 0,
|
|
873168
|
+
message: "Import local browser history/bookmarks into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
|
|
873169
|
+
fields: [
|
|
873170
|
+
{ id: "browsers", label: "Browsers", value: "", required: false, multiline: false, hint: "Optional comma list: chrome, brave, edge, firefox, safari, etc." },
|
|
873171
|
+
{ id: "sources", label: "Sources", value: "history,bookmark", required: false, multiline: false, hint: "history, bookmark, or both." },
|
|
873172
|
+
{ id: "limit", label: "Limit", value: "250", required: false, multiline: false, hint: "Maximum browser entries to import." },
|
|
873173
|
+
{ id: "sinceDays", label: "Since days", value: "", required: false, multiline: false, hint: "Optional age window, such as 30." },
|
|
873174
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge import-browser-history with --yes." }
|
|
873175
|
+
]
|
|
873176
|
+
};
|
|
873177
|
+
}
|
|
873178
|
+
if (kind2 === "knowledge-connector-ingest") {
|
|
873179
|
+
return {
|
|
873180
|
+
kind: kind2,
|
|
873181
|
+
mode: "create",
|
|
873182
|
+
title: "Ingest Connector Input",
|
|
873183
|
+
selectedFieldIndex: 0,
|
|
873184
|
+
message: "Send explicit connector input into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
|
|
873185
|
+
fields: [
|
|
873186
|
+
{ id: "connectorId", label: "Connector id", value: "", required: true, multiline: false, hint: "Connector id from /knowledge connectors." },
|
|
873187
|
+
{ id: "input", label: "Input", value: "", required: false, multiline: true, hint: "Optional JSON or text input. Ctrl-J inserts a new line." },
|
|
873188
|
+
{ id: "path", label: "Path", value: "", required: false, multiline: false, hint: "Optional local path for connectors that read files." },
|
|
873189
|
+
{ id: "content", label: "Content", value: "", required: false, multiline: true, hint: "Optional raw content for connectors that accept text." },
|
|
873190
|
+
{ id: "allowPrivateHosts", label: "Allow private hosts", value: "no", required: false, multiline: false, hint: "yes/no. Defaults to no." },
|
|
873191
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge ingest-connector with --yes." }
|
|
873192
|
+
]
|
|
873193
|
+
};
|
|
873194
|
+
}
|
|
873195
|
+
if (kind2 === "mcp-server") {
|
|
873196
|
+
return {
|
|
873197
|
+
kind: kind2,
|
|
873198
|
+
mode: "create",
|
|
873199
|
+
title: "Add MCP Server",
|
|
873200
|
+
selectedFieldIndex: 0,
|
|
873201
|
+
message: "Add or update one MCP server from the Agent workspace. Type yes on the final field to confirm.",
|
|
873202
|
+
fields: [
|
|
873203
|
+
{ id: "name", label: "Server name", value: "", required: true, multiline: false, hint: "Letters, numbers, dot, underscore, and dash only." },
|
|
873204
|
+
{ id: "command", label: "Command", value: "", required: true, multiline: false, hint: "Executable command, such as bunx, npx, uvx, or a full local binary path." },
|
|
873205
|
+
{ id: "args", label: "Arguments", value: "", required: false, multiline: false, hint: "Optional command arguments. Quotes are supported." },
|
|
873206
|
+
{ id: "scope", label: "Scope", value: "", required: false, multiline: false, hint: "Optional. Defaults to project. Use project or global." },
|
|
873207
|
+
{ id: "role", label: "Role", value: "", required: false, multiline: false, hint: "Optional. general, docs, filesystem, git, database, browser, automation, ops, or remote." },
|
|
873208
|
+
{ id: "trust", label: "Trust mode", value: "", required: false, multiline: false, hint: "Optional. Defaults to constrained. Use constrained, ask-on-risk, or blocked. Use settings for allow-all." },
|
|
873209
|
+
{ id: "env", label: "Env refs", value: "", required: false, multiline: false, hint: "Comma-separated KEY=VALUE entries. Prefer secret refs, not raw secrets." },
|
|
873210
|
+
{ id: "paths", label: "Allowed paths", value: "", required: false, multiline: false, hint: "Comma-separated path allowlist entries." },
|
|
873211
|
+
{ id: "hosts", label: "Allowed hosts", value: "", required: false, multiline: false, hint: "Comma-separated host allowlist entries." },
|
|
873212
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /mcp add with --yes." }
|
|
873213
|
+
]
|
|
873214
|
+
};
|
|
873215
|
+
}
|
|
873216
|
+
if (kind2 === "notify-webhook") {
|
|
873217
|
+
return {
|
|
873218
|
+
kind: kind2,
|
|
873219
|
+
mode: "create",
|
|
873220
|
+
title: "Add Notification Webhook",
|
|
873221
|
+
selectedFieldIndex: 0,
|
|
873222
|
+
message: "Add one webhook notification target for explicit reminder/routine delivery. Type yes on the final field to confirm.",
|
|
873223
|
+
fields: [
|
|
873224
|
+
{ id: "url", label: "Webhook URL", value: "", required: true, multiline: false, hint: "HTTP(S) target, for example https://ntfy.sh/my-topic." },
|
|
873225
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /notify add with --yes." }
|
|
873226
|
+
]
|
|
873227
|
+
};
|
|
873228
|
+
}
|
|
873229
|
+
if (kind2 === "notify-webhook-remove") {
|
|
873230
|
+
return {
|
|
873231
|
+
kind: kind2,
|
|
873232
|
+
mode: "delete",
|
|
873233
|
+
title: "Remove Notification Webhook",
|
|
873234
|
+
selectedFieldIndex: 0,
|
|
873235
|
+
message: "Remove one configured webhook notification target. Type yes on the final field to confirm.",
|
|
873236
|
+
fields: [
|
|
873237
|
+
{ id: "url", label: "Webhook URL", value: "", required: true, multiline: false, hint: "Exact HTTP(S) webhook URL to remove from configured notification targets." },
|
|
873238
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /notify remove with --yes." }
|
|
873239
|
+
]
|
|
873240
|
+
};
|
|
873241
|
+
}
|
|
873242
|
+
if (kind2 === "notify-webhook-test") {
|
|
873243
|
+
return {
|
|
873244
|
+
kind: kind2,
|
|
873245
|
+
mode: "create",
|
|
873246
|
+
title: "Test Notification Webhooks",
|
|
873247
|
+
selectedFieldIndex: 0,
|
|
873248
|
+
message: "Send one test notification to configured webhook targets. Type yes on the final field to confirm.",
|
|
873249
|
+
fields: [
|
|
873250
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /notify test with --yes." }
|
|
873251
|
+
]
|
|
873252
|
+
};
|
|
873253
|
+
}
|
|
873254
|
+
if (kind2 === "tts-prompt") {
|
|
873255
|
+
return {
|
|
873256
|
+
kind: kind2,
|
|
873257
|
+
mode: "create",
|
|
873258
|
+
title: "Speak Assistant Reply",
|
|
873259
|
+
selectedFieldIndex: 0,
|
|
873260
|
+
message: "Submit a normal assistant prompt and play the reply through configured live TTS.",
|
|
873261
|
+
fields: [
|
|
873262
|
+
{ id: "prompt", label: "Prompt", value: "", required: true, multiline: true, hint: "Assistant prompt to speak. Ctrl-J inserts a new line." }
|
|
873263
|
+
]
|
|
873264
|
+
};
|
|
873265
|
+
}
|
|
873266
|
+
if (kind2 === "image-input") {
|
|
873267
|
+
return {
|
|
873268
|
+
kind: kind2,
|
|
873269
|
+
mode: "create",
|
|
873270
|
+
title: "Attach Image Input",
|
|
873271
|
+
selectedFieldIndex: 0,
|
|
873272
|
+
message: "Attach an image to the next assistant turn. The existing image command validates file type and model support.",
|
|
873273
|
+
fields: [
|
|
873274
|
+
{ id: "path", label: "Image path", value: "", required: true, multiline: false, hint: "PNG, JPEG, WebP, or GIF path under the current workspace." },
|
|
873275
|
+
{ id: "prompt", label: "Prompt", value: "", required: false, multiline: true, hint: "Optional prompt. Ctrl-J inserts a new line." }
|
|
873276
|
+
]
|
|
873277
|
+
};
|
|
873278
|
+
}
|
|
873279
|
+
if (kind2 === "profile-template-export") {
|
|
873280
|
+
return {
|
|
873281
|
+
kind: kind2,
|
|
873282
|
+
mode: "create",
|
|
873283
|
+
title: "Export Agent Starter Template",
|
|
873284
|
+
selectedFieldIndex: 0,
|
|
873285
|
+
message: "Export a starter template JSON file for review and customization. Type yes on the final field to confirm.",
|
|
873286
|
+
fields: [
|
|
873287
|
+
{ id: "templateId", label: "Starter id", value: "", required: true, multiline: false, hint: "Existing starter id from /agent-profile templates." },
|
|
873288
|
+
{ id: "path", label: "Output path", value: "", required: true, multiline: false, hint: "Workspace-relative JSON path to write." },
|
|
873289
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-profile template export with --yes." }
|
|
873290
|
+
]
|
|
873291
|
+
};
|
|
873292
|
+
}
|
|
873293
|
+
if (kind2 === "profile-template-import") {
|
|
873294
|
+
return {
|
|
873295
|
+
kind: kind2,
|
|
873296
|
+
mode: "create",
|
|
873297
|
+
title: "Import Agent Starter Template",
|
|
873298
|
+
selectedFieldIndex: 0,
|
|
873299
|
+
message: "Import a reviewed starter template JSON file into this Agent home. Type yes on the final field to confirm.",
|
|
873300
|
+
fields: [
|
|
873301
|
+
{ id: "path", label: "Template path", value: "", required: true, multiline: false, hint: "Workspace-relative JSON path to import." },
|
|
873302
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-profile template import with --yes." }
|
|
873303
|
+
]
|
|
873304
|
+
};
|
|
873305
|
+
}
|
|
873306
|
+
if (kind2 === "profile-template-from-discovered") {
|
|
873307
|
+
return {
|
|
873308
|
+
kind: kind2,
|
|
873309
|
+
mode: "create",
|
|
873310
|
+
title: "Create Starter from Discovered Behavior",
|
|
873311
|
+
selectedFieldIndex: 0,
|
|
873312
|
+
message: "Create an Agent-local starter template from reviewed discovered persona, skill, and routine markdown. Type yes on the final field to confirm.",
|
|
873313
|
+
fields: [
|
|
873314
|
+
{ id: "id", label: "Starter id", value: "", required: true, multiline: false, hint: "New local starter id, for example research-desk." },
|
|
873315
|
+
{ id: "name", label: "Starter name", value: "", required: false, multiline: false, hint: "Optional display name. Defaults to the selected persona name." },
|
|
873316
|
+
{ id: "description", label: "Description", value: "", required: false, multiline: false, hint: "Optional one-line summary." },
|
|
873317
|
+
{ id: "persona", label: "Persona", value: "", required: false, multiline: false, hint: "Optional discovered persona name/path. Blank uses the first discovered persona." },
|
|
873318
|
+
{ id: "skills", label: "Skills", value: "", required: false, multiline: false, hint: "all or comma-separated discovered skill names. Blank includes all." },
|
|
873319
|
+
{ id: "routines", label: "Routines", value: "", required: false, multiline: false, hint: "all or comma-separated discovered routine names. Blank includes all." },
|
|
873320
|
+
{ id: "replace", label: "Replace existing", value: "no", required: false, multiline: false, hint: "yes/no. Existing starter ids are protected unless this is yes." },
|
|
873321
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-profile template from-discovered with --yes." }
|
|
873322
|
+
]
|
|
873323
|
+
};
|
|
873324
|
+
}
|
|
873325
|
+
if (kind2 === "profile-from-discovered") {
|
|
873326
|
+
return {
|
|
873327
|
+
kind: kind2,
|
|
873328
|
+
mode: "create",
|
|
873329
|
+
title: "Create Profile from Discovered Behavior",
|
|
873330
|
+
selectedFieldIndex: 0,
|
|
873331
|
+
message: "Create a local starter template and isolated Agent profile from reviewed discovered behavior markdown. Type yes on the final field to confirm.",
|
|
873332
|
+
fields: [
|
|
873333
|
+
{ id: "profile", label: "Profile name", value: "", required: true, multiline: false, hint: "New isolated Agent profile name, for example research-desk." },
|
|
873334
|
+
{ id: "templateId", label: "Starter id", value: "", required: false, multiline: false, hint: "Optional local starter id. Blank uses the profile name." },
|
|
873335
|
+
{ id: "name", label: "Starter name", value: "", required: false, multiline: false, hint: "Optional display name for the generated starter." },
|
|
873336
|
+
{ id: "description", label: "Description", value: "", required: false, multiline: false, hint: "Optional one-line summary." },
|
|
873337
|
+
{ id: "persona", label: "Persona", value: "", required: false, multiline: false, hint: "Optional discovered persona name/path. Blank uses the first discovered persona." },
|
|
873338
|
+
{ id: "skills", label: "Skills", value: "", required: false, multiline: false, hint: "all or comma-separated discovered skill names. Blank includes all." },
|
|
873339
|
+
{ id: "routines", label: "Routines", value: "", required: false, multiline: false, hint: "all or comma-separated discovered routine names. Blank includes all." },
|
|
873340
|
+
{ id: "replace", label: "Replace starter", value: "no", required: false, multiline: false, hint: "yes/no. Existing starter ids are protected unless this is yes." },
|
|
873341
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-profile create-from-discovered with --yes." }
|
|
873342
|
+
]
|
|
873343
|
+
};
|
|
873344
|
+
}
|
|
873345
|
+
if (kind2 === "skill-discovery-import") {
|
|
873346
|
+
return {
|
|
873347
|
+
kind: kind2,
|
|
873348
|
+
mode: "create",
|
|
873349
|
+
title: "Import Discovered Skill",
|
|
873350
|
+
selectedFieldIndex: 0,
|
|
873351
|
+
message: "Import one discovered SKILL.md or .md skill file into the Agent-local skill registry. Type yes on the final field to confirm.",
|
|
873352
|
+
fields: [
|
|
873353
|
+
{ id: "name", label: "Discovered skill", value: "", required: true, multiline: false, hint: "Name shown by /agent-skills discover." },
|
|
873354
|
+
{ id: "enabled", label: "Enable now", value: "yes", required: false, multiline: false, hint: "yes/no." },
|
|
873355
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-skills import-discovered with --yes." }
|
|
873356
|
+
]
|
|
873357
|
+
};
|
|
873358
|
+
}
|
|
873359
|
+
if (kind2 === "persona-discovery-import") {
|
|
873360
|
+
return {
|
|
873361
|
+
kind: kind2,
|
|
873362
|
+
mode: "create",
|
|
873363
|
+
title: "Import Discovered Persona",
|
|
873364
|
+
selectedFieldIndex: 0,
|
|
873365
|
+
message: "Import one discovered persona markdown file into the Agent-local persona registry. Type yes on the final field to confirm.",
|
|
873366
|
+
fields: [
|
|
873367
|
+
{ id: "name", label: "Discovered persona", value: "", required: true, multiline: false, hint: "Name shown by /personas discover." },
|
|
873368
|
+
{ id: "use", label: "Use now", value: "yes", required: false, multiline: false, hint: "yes/no." },
|
|
873369
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /personas import-discovered with --yes." }
|
|
873370
|
+
]
|
|
873371
|
+
};
|
|
873372
|
+
}
|
|
873373
|
+
if (kind2 === "routine-discovery-import") {
|
|
873374
|
+
return {
|
|
873375
|
+
kind: kind2,
|
|
873376
|
+
mode: "create",
|
|
873377
|
+
title: "Import Discovered Routine",
|
|
873378
|
+
selectedFieldIndex: 0,
|
|
873379
|
+
message: "Import one discovered routine markdown file into the Agent-local routine registry. Type yes on the final field to confirm.",
|
|
873380
|
+
fields: [
|
|
873381
|
+
{ id: "name", label: "Discovered routine", value: "", required: true, multiline: false, hint: "Name shown by /routines discover." },
|
|
873382
|
+
{ id: "enabled", label: "Enable now", value: "yes", required: false, multiline: false, hint: "yes/no." },
|
|
873383
|
+
{ id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /routines import-discovered with --yes." }
|
|
873384
|
+
]
|
|
873385
|
+
};
|
|
873386
|
+
}
|
|
873387
|
+
return {
|
|
873388
|
+
kind: kind2,
|
|
873389
|
+
mode: "create",
|
|
873390
|
+
title: "Create Skill Bundle",
|
|
873391
|
+
selectedFieldIndex: 0,
|
|
873392
|
+
message: "Group existing local skills into a reviewable bundle that can be enabled together.",
|
|
873393
|
+
fields: [
|
|
873394
|
+
{ id: "name", label: "Bundle name", value: "", required: true, multiline: false, hint: "Short bundle name." },
|
|
873395
|
+
{ id: "description", label: "Description", value: "", required: true, multiline: false, hint: "One-line bundle summary." },
|
|
873396
|
+
{ id: "skills", label: "Skill ids", value: "", required: true, multiline: false, hint: "Comma-separated existing local skill ids." },
|
|
873397
|
+
{ id: "enabled", label: "Enable now", value: "yes", required: false, multiline: false, hint: "yes/no." }
|
|
873398
|
+
]
|
|
873399
|
+
};
|
|
873400
|
+
}
|
|
873401
|
+
|
|
872934
873402
|
// src/input/agent-workspace-knowledge-query-editor.ts
|
|
872935
873403
|
function createAgentKnowledgeQueryEditor(mode) {
|
|
872936
873404
|
return {
|
|
@@ -873354,6 +873822,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
873354
873822
|
{ id: "setup-provider-model", label: "Provider and model", detail: "Choose the provider/model route for normal assistant chat.", command: "/model", kind: "command", safety: "safe" },
|
|
873355
873823
|
{ id: "setup-agent-knowledge", label: "Agent Knowledge", detail: "Inspect the isolated Agent Knowledge store before ingesting source-backed material.", command: "/knowledge status", kind: "command", safety: "read-only" },
|
|
873356
873824
|
{ id: "setup-runtime-profiles", label: "Agent profiles", detail: "Browse starter templates for isolated Agent homes and operator identities.", command: "/agent-profile templates", kind: "command", safety: "read-only" },
|
|
873825
|
+
{ id: "setup-profile-from-discovered", label: "Profile from discovered behavior", detail: "Create an isolated Agent profile directly from reviewed local persona, skill, and routine files.", editorKind: "profile-from-discovered", kind: "editor", safety: "safe" },
|
|
873357
873826
|
{ id: "setup-personas", label: "Personas", detail: "Create or select the active local Agent persona.", targetCategoryId: "personas", kind: "workspace", safety: "safe" },
|
|
873358
873827
|
{ id: "setup-skills", label: "Skills", detail: "Create, review, and enable reusable local Agent skills.", targetCategoryId: "skills", kind: "workspace", safety: "safe" },
|
|
873359
873828
|
{ id: "setup-routines", label: "Routines", detail: "Create, review, and enable local Agent routines before any explicit schedule promotion.", targetCategoryId: "routines", kind: "workspace", safety: "safe" },
|
|
@@ -873445,6 +873914,8 @@ var AGENT_WORKSPACE_CATEGORIES = [
|
|
|
873445
873914
|
{ id: "runtime-profile-list", label: "List Agent profiles", detail: "List isolated Agent profile homes under this Agent home.", command: "/agent-profile list", kind: "command", safety: "read-only" },
|
|
873446
873915
|
{ id: "runtime-profile-template-export", label: "Export starter template", detail: "Open an in-workspace form that exports a starter template JSON file for review and customization.", editorKind: "profile-template-export", kind: "editor", safety: "safe" },
|
|
873447
873916
|
{ id: "runtime-profile-template-import", label: "Import starter template", detail: "Open an in-workspace form that imports a reviewed starter template JSON file into this Agent home.", editorKind: "profile-template-import", kind: "editor", safety: "safe" },
|
|
873917
|
+
{ id: "runtime-profile-template-from-discovered", label: "Starter from discovered behavior", detail: "Open an in-workspace form that creates one local starter template from reviewed discovered persona, skill, and routine files.", editorKind: "profile-template-from-discovered", kind: "editor", safety: "safe" },
|
|
873918
|
+
{ id: "runtime-profile-from-discovered", label: "Profile from discovered behavior", detail: "Open an in-workspace form that creates a local starter and isolated Agent profile from reviewed discovered behavior files.", editorKind: "profile-from-discovered", kind: "editor", safety: "safe" },
|
|
873448
873919
|
{ id: "runtime-profile-create", label: "Create Agent profile", detail: "Open an in-workspace form that creates an isolated Agent home from a built-in or local starter.", editorKind: "profile", kind: "editor", safety: "safe" },
|
|
873449
873920
|
{ id: "runtime-profile-template-edit", label: "Customize starter", detail: "Open the starter export form, edit the JSON file, then import it as a local starter.", editorKind: "profile-template-export", kind: "editor", safety: "safe" },
|
|
873450
873921
|
{ id: "runtime-profile-switch", label: "Switch Agent profile", detail: "Launch goodvibes-agent --agent-profile NAME to use that isolated Agent home. This workspace cannot switch the current process home after startup.", kind: "guidance", safety: "safe" }
|
|
@@ -874952,6 +875423,33 @@ function getOnboardingWizardVisibleFieldCount(viewportHeight) {
|
|
|
874952
875423
|
}
|
|
874953
875424
|
|
|
874954
875425
|
// src/input/onboarding/onboarding-wizard-operator-steps.ts
|
|
875426
|
+
function discoveryCount(discovery) {
|
|
875427
|
+
if (!discovery)
|
|
875428
|
+
return 0;
|
|
875429
|
+
return discovery.personas.count + discovery.skills.count + discovery.routines.count;
|
|
875430
|
+
}
|
|
875431
|
+
function discoverySummary(discovery) {
|
|
875432
|
+
if (!discovery || discoveryCount(discovery) === 0)
|
|
875433
|
+
return "No importable local behavior files found yet";
|
|
875434
|
+
return [
|
|
875435
|
+
`${discovery.personas.count} persona file(s)`,
|
|
875436
|
+
`${discovery.skills.count} skill file(s)`,
|
|
875437
|
+
`${discovery.routines.count} routine file(s)`
|
|
875438
|
+
].join("; ");
|
|
875439
|
+
}
|
|
875440
|
+
function discoverySample(discovery) {
|
|
875441
|
+
if (!discovery)
|
|
875442
|
+
return "";
|
|
875443
|
+
const names2 = [
|
|
875444
|
+
...discovery.personas.names,
|
|
875445
|
+
...discovery.skills.names,
|
|
875446
|
+
...discovery.routines.names
|
|
875447
|
+
].slice(0, 4);
|
|
875448
|
+
if (names2.length === 0)
|
|
875449
|
+
return "Use /personas discover, /agent-skills discover, and /routines discover after setup to rescan.";
|
|
875450
|
+
const remaining = discoveryCount(discovery) > names2.length ? `, +${discoveryCount(discovery) - names2.length} more` : "";
|
|
875451
|
+
return `Import candidates: ${names2.join(", ")}${remaining}.`;
|
|
875452
|
+
}
|
|
874955
875453
|
function buildCommunicationStep() {
|
|
874956
875454
|
return {
|
|
874957
875455
|
id: "agent-communication",
|
|
@@ -875077,15 +875575,17 @@ function buildAgentKnowledgeStep() {
|
|
|
875077
875575
|
]
|
|
875078
875576
|
};
|
|
875079
875577
|
}
|
|
875080
|
-
function buildLocalStateStep() {
|
|
875578
|
+
function buildLocalStateStep(discovery) {
|
|
875579
|
+
const discoveredCount = discoveryCount(discovery);
|
|
875081
875580
|
return {
|
|
875082
875581
|
id: "agent-local-state",
|
|
875083
875582
|
title: "Local memory and behavior",
|
|
875084
|
-
shortLabel: "
|
|
875085
|
-
description: "Review the Agent-local behavior model. Memory, personas, skills, routines, and Agent profiles stay local until a stable shared registry exists.",
|
|
875583
|
+
shortLabel: "Behavior",
|
|
875584
|
+
description: discoveredCount > 0 ? "Review importable Agent-local behavior files, then create an isolated profile from them or import individual records." : "Review the Agent-local behavior model. Memory, personas, skills, routines, and Agent profiles stay local until a stable shared registry exists.",
|
|
875086
875585
|
summaryTitle: "Local Agent state",
|
|
875087
875586
|
summaryLines: [
|
|
875088
875587
|
"Memory/personas/skills/routines: local Agent registries",
|
|
875588
|
+
`Discovered behavior files: ${discoverySummary(discovery)}`,
|
|
875089
875589
|
"Secrets: rejected or stored by secret reference",
|
|
875090
875590
|
"Profiles: isolated Agent homes"
|
|
875091
875591
|
],
|
|
@@ -875101,22 +875601,22 @@ function buildLocalStateStep() {
|
|
|
875101
875601
|
kind: "status",
|
|
875102
875602
|
id: "agent-local-state.personas",
|
|
875103
875603
|
label: "Personas",
|
|
875104
|
-
hint: "Use /personas to create and activate serial operating modes for the main conversation.",
|
|
875105
|
-
defaultValue: "Local registry"
|
|
875604
|
+
hint: discovery?.personas.count && discovery.personas.count > 0 ? `${discovery.personas.count} persona file(s) are available. Use the Profiles workspace to create a profile from discovered behavior, or preview individual files with /personas discover.` : "Use /personas to create and activate serial operating modes for the main conversation.",
|
|
875605
|
+
defaultValue: discovery?.personas.count && discovery.personas.count > 0 ? `${discovery.personas.count} discovered` : "Local registry"
|
|
875106
875606
|
},
|
|
875107
875607
|
{
|
|
875108
875608
|
kind: "status",
|
|
875109
875609
|
id: "agent-local-state.skills",
|
|
875110
875610
|
label: "Skills",
|
|
875111
|
-
hint: "Use /agent-skills and /skills local to manage reusable Agent procedures.",
|
|
875112
|
-
defaultValue: "Local registry"
|
|
875611
|
+
hint: discovery?.skills.count && discovery.skills.count > 0 ? `${discovery.skills.count} skill file(s) are available. Use the Profiles workspace to create a profile from discovered behavior, or preview individual files with /agent-skills discover.` : "Use /agent-skills and /skills local to manage reusable Agent procedures.",
|
|
875612
|
+
defaultValue: discovery?.skills.count && discovery.skills.count > 0 ? `${discovery.skills.count} discovered` : "Local registry"
|
|
875113
875613
|
},
|
|
875114
875614
|
{
|
|
875115
875615
|
kind: "status",
|
|
875116
875616
|
id: "agent-local-state.routines",
|
|
875117
875617
|
label: "Routines",
|
|
875118
|
-
hint: "Use /routines for reusable local procedures. Starting a routine prints steps in the main conversation and does not spawn hidden work.",
|
|
875119
|
-
defaultValue: "Local registry"
|
|
875618
|
+
hint: discovery?.routines.count && discovery.routines.count > 0 ? `${discovery.routines.count} routine file(s) are available. Use the Profiles workspace to create a profile from discovered behavior, or preview individual files with /routines discover. ${discoverySample(discovery)}` : "Use /routines for reusable local procedures. Starting a routine prints steps in the main conversation and does not spawn hidden work.",
|
|
875619
|
+
defaultValue: discovery?.routines.count && discovery.routines.count > 0 ? `${discovery.routines.count} discovered` : "Local registry"
|
|
875120
875620
|
}
|
|
875121
875621
|
]
|
|
875122
875622
|
};
|
|
@@ -875265,7 +875765,7 @@ function buildOnboardingWizardSteps(controller) {
|
|
|
875265
875765
|
buildCommunicationStep(),
|
|
875266
875766
|
buildToolsStep(),
|
|
875267
875767
|
buildAgentKnowledgeStep(),
|
|
875268
|
-
buildLocalStateStep(),
|
|
875768
|
+
buildLocalStateStep(controller.runtimeSnapshot?.localBehaviorDiscovery),
|
|
875269
875769
|
buildAutomationStep(),
|
|
875270
875770
|
buildVoiceMediaStep(),
|
|
875271
875771
|
buildDelegationPolicyStep(),
|
|
@@ -877778,7 +878278,7 @@ function handleProfilePickerToken(state4, token) {
|
|
|
877778
878278
|
}
|
|
877779
878279
|
|
|
877780
878280
|
// src/input/handler-picker-routes.ts
|
|
877781
|
-
import { readFileSync as
|
|
878281
|
+
import { readFileSync as readFileSync87 } from "fs";
|
|
877782
878282
|
|
|
877783
878283
|
// src/renderer/model-picker-overlay.ts
|
|
877784
878284
|
var MODEL_PICKER_CHROME_LINES = 7;
|
|
@@ -878070,7 +878570,7 @@ function handleFilePickerToken(state4, token) {
|
|
|
878070
878570
|
throw new Error("working directory is unavailable");
|
|
878071
878571
|
}
|
|
878072
878572
|
const resolvedPath3 = resolveAndValidatePath(selected, projectRoot);
|
|
878073
|
-
const data =
|
|
878573
|
+
const data = readFileSync87(resolvedPath3);
|
|
878074
878574
|
const base644 = data.toString("base64");
|
|
878075
878575
|
const mediaType = state4.mediaTypeFromExt(ext);
|
|
878076
878576
|
const filename = selected.split("/").pop() ?? selected;
|
|
@@ -881570,6 +882070,29 @@ function setupChecklistLines(snapshot2) {
|
|
|
881570
882070
|
}
|
|
881571
882071
|
return lines;
|
|
881572
882072
|
}
|
|
882073
|
+
function discoverySummaryLine(label, summary, command8) {
|
|
882074
|
+
if (summary.count === 0)
|
|
882075
|
+
return [];
|
|
882076
|
+
const names2 = summary.names.length > 0 ? ` ${summary.names.join(", ")}${summary.count > summary.names.length ? `, +${summary.count - summary.names.length} more` : ""}.` : "";
|
|
882077
|
+
return [
|
|
882078
|
+
{ text: `${label}: ${summary.count} discovered; project ${summary.projectLocalCount}; global ${summary.globalCount}.`, fg: FULLSCREEN_PALETTE.info, bold: true },
|
|
882079
|
+
{ text: ` ${command8} to preview, then use the import form after review.${names2}`, fg: FULLSCREEN_PALETTE.muted }
|
|
882080
|
+
];
|
|
882081
|
+
}
|
|
882082
|
+
function behaviorDiscoveryLines(snapshot2) {
|
|
882083
|
+
const lines = [
|
|
882084
|
+
...discoverySummaryLine("Discovered personas", snapshot2.discoveredBehavior.personas, "/personas discover"),
|
|
882085
|
+
...discoverySummaryLine("Discovered skills", snapshot2.discoveredBehavior.skills, "/agent-skills discover"),
|
|
882086
|
+
...discoverySummaryLine("Discovered routines", snapshot2.discoveredBehavior.routines, "/routines discover")
|
|
882087
|
+
];
|
|
882088
|
+
if (lines.length === 0)
|
|
882089
|
+
return [];
|
|
882090
|
+
return [
|
|
882091
|
+
{ text: "" },
|
|
882092
|
+
{ text: "Discovered Behavior Files", fg: FULLSCREEN_PALETTE.title, bold: true },
|
|
882093
|
+
...lines
|
|
882094
|
+
];
|
|
882095
|
+
}
|
|
881573
882096
|
function localLibraryLines(title, items, emptyText, selectedId) {
|
|
881574
882097
|
const lines = [
|
|
881575
882098
|
{ text: title, fg: FULLSCREEN_PALETTE.title, bold: true }
|
|
@@ -881650,7 +882173,7 @@ function snapshotLines(workspace, category, snapshot2) {
|
|
|
881650
882173
|
if (category.id === "home") {
|
|
881651
882174
|
base2.push({ text: `Chat route: ${snapshot2.provider} / ${snapshot2.modelDisplayName}`, fg: FULLSCREEN_PALETTE.info }, { text: `Session: ${snapshot2.sessionId}`, fg: FULLSCREEN_PALETTE.muted }, { text: `Policy: ${snapshot2.executionPolicy}; WRFC ${snapshot2.wrfcPolicy}`, fg: FULLSCREEN_PALETTE.good });
|
|
881652
882175
|
} else if (category.id === "setup") {
|
|
881653
|
-
base2.push({ text: `Connection: ${snapshot2.runtimeBaseUrl}`, fg: FULLSCREEN_PALETTE.info }, { text: "Agent role: interactive operator TUI; setup changes here are Agent-local.", fg: FULLSCREEN_PALETTE.good }, ...setupChecklistLines(snapshot2), { text: "" }, { text: `Workspace: ${snapshot2.workingDirectory}`, fg: FULLSCREEN_PALETTE.muted }, { text: `Home: ${snapshot2.homeDirectory}`, fg: FULLSCREEN_PALETTE.muted });
|
|
882176
|
+
base2.push({ text: `Connection: ${snapshot2.runtimeBaseUrl}`, fg: FULLSCREEN_PALETTE.info }, { text: "Agent role: interactive operator TUI; setup changes here are Agent-local.", fg: FULLSCREEN_PALETTE.good }, ...setupChecklistLines(snapshot2), ...behaviorDiscoveryLines(snapshot2), { text: "" }, { text: `Workspace: ${snapshot2.workingDirectory}`, fg: FULLSCREEN_PALETTE.muted }, { text: `Home: ${snapshot2.homeDirectory}`, fg: FULLSCREEN_PALETTE.muted });
|
|
881654
882177
|
} else if (category.id === "channels") {
|
|
881655
882178
|
const enabledCount = snapshot2.channels.filter((channel) => channel.enabled).length;
|
|
881656
882179
|
const readyCount = snapshot2.channels.filter((channel) => channel.ready).length;
|
|
@@ -883512,7 +884035,7 @@ function wireShellUiOpeners(options) {
|
|
|
883512
884035
|
|
|
883513
884036
|
// src/cli/entrypoint.ts
|
|
883514
884037
|
import { existsSync as existsSync85 } from "fs";
|
|
883515
|
-
import { join as
|
|
884038
|
+
import { join as join102 } from "path";
|
|
883516
884039
|
// src/cli/parser.ts
|
|
883517
884040
|
var COMMAND_ALIASES = {
|
|
883518
884041
|
run: "run",
|
|
@@ -883876,14 +884399,14 @@ function parseGoodVibesCli(argv, binary2 = "goodvibes-agent") {
|
|
|
883876
884399
|
};
|
|
883877
884400
|
}
|
|
883878
884401
|
// src/cli/help.ts
|
|
883879
|
-
import { existsSync as existsSync79, readFileSync as
|
|
883880
|
-
import { dirname as dirname63, join as
|
|
884402
|
+
import { existsSync as existsSync79, readFileSync as readFileSync88 } from "fs";
|
|
884403
|
+
import { dirname as dirname63, join as join95 } from "path";
|
|
883881
884404
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
883882
884405
|
function readJsonVersion(path7) {
|
|
883883
884406
|
try {
|
|
883884
884407
|
if (!existsSync79(path7))
|
|
883885
884408
|
return null;
|
|
883886
|
-
const parsed = JSON.parse(
|
|
884409
|
+
const parsed = JSON.parse(readFileSync88(path7, "utf-8"));
|
|
883887
884410
|
return typeof parsed.version === "string" ? parsed.version : null;
|
|
883888
884411
|
} catch {
|
|
883889
884412
|
return null;
|
|
@@ -883891,7 +884414,7 @@ function readJsonVersion(path7) {
|
|
|
883891
884414
|
}
|
|
883892
884415
|
function getPackageVersion() {
|
|
883893
884416
|
const here = dirname63(fileURLToPath4(import.meta.url));
|
|
883894
|
-
return readJsonVersion(
|
|
884417
|
+
return readJsonVersion(join95(here, "..", "..", "package.json")) ?? VERSION;
|
|
883895
884418
|
}
|
|
883896
884419
|
function renderGoodVibesVersion(binary2 = "goodvibes-agent") {
|
|
883897
884420
|
return `${binary2} ${getPackageVersion()}`;
|
|
@@ -884023,9 +884546,9 @@ var COMMAND_HELP = {
|
|
|
884023
884546
|
examples: ["providers", "providers inspect openai-subscriber", "providers use openai openai:gpt-5.4"]
|
|
884024
884547
|
},
|
|
884025
884548
|
profiles: {
|
|
884026
|
-
usage: ["profiles list", "profiles templates", "profiles templates export <id> <path> --yes", "profiles templates import <path> --yes", "profiles show <name>", "profiles create <name> [--template <id>] --yes", "profiles delete <name> --yes", "--agent-profile <name>"],
|
|
884549
|
+
usage: ["profiles list", "profiles templates", "profiles templates from-discovered <id> --yes", "profiles create-from-discovered <name> --yes", "profiles templates export <id> <path> --yes", "profiles templates import <path> --yes", "profiles show <name>", "profiles create <name> [--template <id>] --yes", "profiles delete <name> --yes", "--agent-profile <name>"],
|
|
884027
884550
|
summary: "Create and inspect isolated Agent profile homes, with starter templates for household, research, travel, operations, personal productivity, and local imported starters. A profile changes Agent-local config, sessions, memory, personas, skills, routines, and setup paths without changing connected GoodVibes services.",
|
|
884028
|
-
examples: ["profiles templates", "profiles templates export research ./research-starter.json --yes", "profiles templates import ./research-starter.json --yes", "profiles create household --template household --yes", "--agent-profile household status"]
|
|
884551
|
+
examples: ["profiles templates", "profiles create-from-discovered research-desk --yes", "profiles templates from-discovered research-desk --yes", "profiles templates export research ./research-starter.json --yes", "profiles templates import ./research-starter.json --yes", "profiles create household --template household --yes", "--agent-profile household status"]
|
|
884029
884552
|
},
|
|
884030
884553
|
personas: {
|
|
884031
884554
|
usage: [
|
|
@@ -884631,8 +885154,8 @@ function renderOnboardingCliStatus(options) {
|
|
|
884631
885154
|
`);
|
|
884632
885155
|
}
|
|
884633
885156
|
// src/cli/external-runtime.ts
|
|
884634
|
-
import { existsSync as existsSync80, readFileSync as
|
|
884635
|
-
import { join as
|
|
885157
|
+
import { existsSync as existsSync80, readFileSync as readFileSync89 } from "fs";
|
|
885158
|
+
import { join as join96 } from "path";
|
|
884636
885159
|
function isRecord29(value) {
|
|
884637
885160
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
884638
885161
|
}
|
|
@@ -884646,11 +885169,11 @@ function resolveBaseUrl2(configManager) {
|
|
|
884646
885169
|
return `http://${host}:${Number.isFinite(port) ? port : 3421}`;
|
|
884647
885170
|
}
|
|
884648
885171
|
function readOperatorToken(homeDirectory) {
|
|
884649
|
-
const path7 =
|
|
885172
|
+
const path7 = join96(homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
884650
885173
|
if (!existsSync80(path7))
|
|
884651
885174
|
return { token: null, path: path7 };
|
|
884652
885175
|
try {
|
|
884653
|
-
const parsed = JSON.parse(
|
|
885176
|
+
const parsed = JSON.parse(readFileSync89(path7, "utf-8"));
|
|
884654
885177
|
const token = isRecord29(parsed) && typeof parsed.token === "string" ? parsed.token : null;
|
|
884655
885178
|
return { token, path: path7 };
|
|
884656
885179
|
} catch {
|
|
@@ -885023,8 +885546,8 @@ function applyRuntimeCommandEndpointFlagOverrides(configManager, command8, flags
|
|
|
885023
885546
|
return [];
|
|
885024
885547
|
}
|
|
885025
885548
|
// src/cli/bundle-command.ts
|
|
885026
|
-
import { existsSync as existsSync82, mkdirSync as mkdirSync65, readFileSync as
|
|
885027
|
-
import { dirname as dirname64, join as
|
|
885549
|
+
import { existsSync as existsSync82, mkdirSync as mkdirSync65, readFileSync as readFileSync90, writeFileSync as writeFileSync56 } from "fs";
|
|
885550
|
+
import { dirname as dirname64, join as join98 } from "path";
|
|
885028
885551
|
|
|
885029
885552
|
// src/cli/provider-classification.ts
|
|
885030
885553
|
var SUBSCRIPTION_PROVIDERS = new Set([
|
|
@@ -885115,7 +885638,7 @@ function classifyProviderSetup(input) {
|
|
|
885115
885638
|
// src/cli/service-posture.ts
|
|
885116
885639
|
import { closeSync as closeSync4, existsSync as existsSync81, openSync as openSync4, readSync as readSync2, statSync as statSync21 } from "fs";
|
|
885117
885640
|
import net3 from "net";
|
|
885118
|
-
import { isAbsolute as isAbsolute13, join as
|
|
885641
|
+
import { isAbsolute as isAbsolute13, join as join97 } from "path";
|
|
885119
885642
|
|
|
885120
885643
|
// src/cli/redaction.ts
|
|
885121
885644
|
var REDACTED_VALUE = "<redacted>";
|
|
@@ -885285,7 +885808,7 @@ function resolveConfiguredLogPath(runtime3) {
|
|
|
885285
885808
|
const trimmed2 = value.trim();
|
|
885286
885809
|
if (!trimmed2)
|
|
885287
885810
|
return;
|
|
885288
|
-
return isAbsolute13(trimmed2) ? trimmed2 :
|
|
885811
|
+
return isAbsolute13(trimmed2) ? trimmed2 : join97(runtime3.homeDirectory, trimmed2);
|
|
885289
885812
|
}
|
|
885290
885813
|
function createExternalDaemonLifecycle(logPath) {
|
|
885291
885814
|
return {
|
|
@@ -885371,7 +885894,7 @@ function getNestedValue(source, key) {
|
|
|
885371
885894
|
}
|
|
885372
885895
|
function readJsonFile2(path7) {
|
|
885373
885896
|
try {
|
|
885374
|
-
return { ok: true, value: JSON.parse(
|
|
885897
|
+
return { ok: true, value: JSON.parse(readFileSync90(path7, "utf-8")) };
|
|
885375
885898
|
} catch (error51) {
|
|
885376
885899
|
return { ok: false, error: error51 instanceof Error ? error51.message : String(error51) };
|
|
885377
885900
|
}
|
|
@@ -885394,7 +885917,7 @@ function readAuthPosture(runtime3) {
|
|
|
885394
885917
|
});
|
|
885395
885918
|
const userStorePath = shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
|
|
885396
885919
|
const bootstrapCredentialPath = shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
|
|
885397
|
-
const operatorTokenPath =
|
|
885920
|
+
const operatorTokenPath = join98(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
885398
885921
|
return {
|
|
885399
885922
|
userStorePath,
|
|
885400
885923
|
userStorePresent: existsSync82(userStorePath),
|
|
@@ -885554,7 +886077,7 @@ async function handleBundleCommand(runtime3) {
|
|
|
885554
886077
|
}
|
|
885555
886078
|
// src/cli/management.ts
|
|
885556
886079
|
import { existsSync as existsSync84 } from "fs";
|
|
885557
|
-
import { join as
|
|
886080
|
+
import { join as join101 } from "path";
|
|
885558
886081
|
import { spawn as spawn5 } from "child_process";
|
|
885559
886082
|
import { networkInterfaces as networkInterfaces4 } from "os";
|
|
885560
886083
|
|
|
@@ -885581,7 +886104,7 @@ function formatProviderAuthRoute(route) {
|
|
|
885581
886104
|
|
|
885582
886105
|
// src/cli/management-commands.ts
|
|
885583
886106
|
import { mkdirSync as mkdirSync66, writeFileSync as writeFileSync57 } from "fs";
|
|
885584
|
-
import { dirname as dirname65, join as
|
|
886107
|
+
import { dirname as dirname65, join as join99 } from "path";
|
|
885585
886108
|
init_config8();
|
|
885586
886109
|
init_config8();
|
|
885587
886110
|
init_config8();
|
|
@@ -885898,7 +886421,7 @@ async function handleTasks(runtime3) {
|
|
|
885898
886421
|
});
|
|
885899
886422
|
}
|
|
885900
886423
|
async function renderPairing(runtime3) {
|
|
885901
|
-
const daemonHomeDir =
|
|
886424
|
+
const daemonHomeDir = join99(runtime3.homeDirectory, ".goodvibes", "daemon");
|
|
885902
886425
|
const tokenRecord = getOrCreateCompanionToken(GOODVIBES_AGENT_PAIRING_SURFACE, { daemonHomeDir });
|
|
885903
886426
|
const binding = resolveRuntimeEndpointBinding(runtime3.configManager, "controlPlane");
|
|
885904
886427
|
const daemonUrl = `http://${urlHostForBindHost2(binding.host)}:${binding.port}`;
|
|
@@ -886436,8 +886959,8 @@ var DELEGATION_METHOD = {
|
|
|
886436
886959
|
};
|
|
886437
886960
|
|
|
886438
886961
|
// src/cli/agent-knowledge-runtime.ts
|
|
886439
|
-
import { existsSync as existsSync83, readFileSync as
|
|
886440
|
-
import { join as
|
|
886962
|
+
import { existsSync as existsSync83, readFileSync as readFileSync91 } from "fs";
|
|
886963
|
+
import { join as join100 } from "path";
|
|
886441
886964
|
|
|
886442
886965
|
// node_modules/@pellux/goodvibes-sdk/dist/browser-scoped.js
|
|
886443
886966
|
init_dist();
|
|
@@ -886803,11 +887326,11 @@ function resolveDaemonConnection(runtime3) {
|
|
|
886803
887326
|
const host = String(runtime3.configManager.get("controlPlane.host") ?? "127.0.0.1");
|
|
886804
887327
|
const port = Number(runtime3.configManager.get("controlPlane.port") ?? 3421);
|
|
886805
887328
|
const baseUrl = `http://${host}:${Number.isFinite(port) ? port : 3421}`;
|
|
886806
|
-
const tokenPath =
|
|
887329
|
+
const tokenPath = join100(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
886807
887330
|
if (!existsSync83(tokenPath))
|
|
886808
887331
|
return { baseUrl, token: null, tokenPath };
|
|
886809
887332
|
try {
|
|
886810
|
-
const parsed = JSON.parse(
|
|
887333
|
+
const parsed = JSON.parse(readFileSync91(tokenPath, "utf-8"));
|
|
886811
887334
|
const token = isRecord31(parsed) && typeof parsed.token === "string" ? parsed.token : null;
|
|
886812
887335
|
return { baseUrl, token, tokenPath };
|
|
886813
887336
|
} catch {
|
|
@@ -888135,7 +888658,7 @@ Run goodvibes-agent skills discover to inspect available skill files.`, 1);
|
|
|
888135
888658
|
}
|
|
888136
888659
|
|
|
888137
888660
|
// src/cli/memory-command.ts
|
|
888138
|
-
import { mkdirSync as mkdirSync67, readFileSync as
|
|
888661
|
+
import { mkdirSync as mkdirSync67, readFileSync as readFileSync92, writeFileSync as writeFileSync58 } from "fs";
|
|
888139
888662
|
import { dirname as dirname66, resolve as resolve40 } from "path";
|
|
888140
888663
|
init_state3();
|
|
888141
888664
|
var VALID_CLASSES2 = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
|
|
@@ -888415,7 +888938,7 @@ function isMemoryBundle(value) {
|
|
|
888415
888938
|
return value.schemaVersion === "v1" && typeof value.exportedAt === "number" && (value.scope === "all" || typeof value.scope === "string" && isMemoryScope2(value.scope)) && typeof value.recordCount === "number" && typeof value.linkCount === "number" && Array.isArray(value.records) && value.records.every(isMemoryRecord) && Array.isArray(value.links) && value.links.every(isMemoryLink);
|
|
888416
888939
|
}
|
|
888417
888940
|
function readBundle(path7) {
|
|
888418
|
-
const parsed = JSON.parse(
|
|
888941
|
+
const parsed = JSON.parse(readFileSync92(path7, "utf-8"));
|
|
888419
888942
|
if (!isMemoryBundle(parsed))
|
|
888420
888943
|
throw new Error("Invalid Agent memory bundle.");
|
|
888421
888944
|
for (const record2 of parsed.records) {
|
|
@@ -888738,6 +889261,12 @@ function parseTemplate(args2) {
|
|
|
888738
889261
|
return normalized;
|
|
888739
889262
|
throw new Error(`Unknown Agent starter profile template: ${raw}. Use profiles templates to list starters.`);
|
|
888740
889263
|
}
|
|
889264
|
+
function parseCsvFlag2(args2, names2) {
|
|
889265
|
+
const raw = flagValue2(args2, names2);
|
|
889266
|
+
if (!raw)
|
|
889267
|
+
return;
|
|
889268
|
+
return raw.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
889269
|
+
}
|
|
888741
889270
|
function profileLine2(profile5) {
|
|
888742
889271
|
const created = profile5.createdAt ? ` created=${profile5.createdAt}` : "";
|
|
888743
889272
|
const starter = profile5.starterTemplateId ? ` starter=${profile5.starterTemplateId}` : "";
|
|
@@ -888788,6 +889317,29 @@ function renderProfilesResult(result2) {
|
|
|
888788
889317
|
` source: ${result2.data.template.source}`,
|
|
888789
889318
|
` use: goodvibes-agent profiles create <name> --template ${result2.data.template.id} --yes`
|
|
888790
889319
|
].join(`
|
|
889320
|
+
`);
|
|
889321
|
+
}
|
|
889322
|
+
if (result2.kind === "agent.profiles.template.from_discovered" && result2.data?.template) {
|
|
889323
|
+
return [
|
|
889324
|
+
`Agent starter template created from discovered behavior: ${result2.data.template.id}`,
|
|
889325
|
+
` name: ${result2.data.template.name}`,
|
|
889326
|
+
` persona: ${result2.data.template.personaName}`,
|
|
889327
|
+
` skills: ${result2.data.template.skillNames.join(", ")}`,
|
|
889328
|
+
` routines: ${result2.data.template.routineNames.join(", ")}`,
|
|
889329
|
+
` use: goodvibes-agent profiles create <name> --template ${result2.data.template.id} --yes`
|
|
889330
|
+
].join(`
|
|
889331
|
+
`);
|
|
889332
|
+
}
|
|
889333
|
+
if (result2.kind === "agent.profiles.create_from_discovered" && result2.data?.profile && result2.data.template) {
|
|
889334
|
+
return [
|
|
889335
|
+
`Agent profile created from discovered behavior: ${result2.data.profile.id}`,
|
|
889336
|
+
` home: ${result2.data.profile.homeDirectory}`,
|
|
889337
|
+
` starter: ${result2.data.template.id}`,
|
|
889338
|
+
` persona: ${result2.data.template.personaName}`,
|
|
889339
|
+
` skills: ${result2.data.template.skillNames.join(", ")}`,
|
|
889340
|
+
` routines: ${result2.data.template.routineNames.join(", ")}`,
|
|
889341
|
+
` launch: ${result2.data.nextCommand ?? `goodvibes-agent --agent-profile ${result2.data.profile.id}`}`
|
|
889342
|
+
].join(`
|
|
888791
889343
|
`);
|
|
888792
889344
|
}
|
|
888793
889345
|
const profile5 = result2.data?.profile;
|
|
@@ -888831,6 +889383,51 @@ async function handleProfilesCommand(runtime3) {
|
|
|
888831
889383
|
}
|
|
888832
889384
|
if (sub === "templates" || sub === "starters") {
|
|
888833
889385
|
const [templateAction, templateId, templatePath] = values2;
|
|
889386
|
+
if (templateAction === "from-discovered" || templateAction === "import-discovered") {
|
|
889387
|
+
if (!templateId) {
|
|
889388
|
+
const result5 = {
|
|
889389
|
+
ok: false,
|
|
889390
|
+
kind: "agent.profiles.error",
|
|
889391
|
+
error: "Usage: goodvibes-agent profiles templates from-discovered <id> [--name <name>] [--description <summary>] [--persona <name>] [--skills all|name,name] [--routines all|name,name] [--replace] --yes"
|
|
889392
|
+
};
|
|
889393
|
+
return {
|
|
889394
|
+
output: renderProfilesOutput(result5, runtime3.cli.flags.outputFormat),
|
|
889395
|
+
exitCode: 2
|
|
889396
|
+
};
|
|
889397
|
+
}
|
|
889398
|
+
if (!hasYes(rawRest)) {
|
|
889399
|
+
const result5 = {
|
|
889400
|
+
ok: false,
|
|
889401
|
+
kind: "agent.profiles.error",
|
|
889402
|
+
error: `Refusing to create Agent starter template ${templateId} from discovered behavior without --yes.`
|
|
889403
|
+
};
|
|
889404
|
+
return {
|
|
889405
|
+
output: renderProfilesOutput(result5, runtime3.cli.flags.outputFormat),
|
|
889406
|
+
exitCode: 2
|
|
889407
|
+
};
|
|
889408
|
+
}
|
|
889409
|
+
const template = await createAgentRuntimeProfileTemplateFromDiscovered({
|
|
889410
|
+
homeDirectory: runtime3.homeDirectory,
|
|
889411
|
+
workingDirectory: runtime3.workingDirectory
|
|
889412
|
+
}, {
|
|
889413
|
+
id: templateId,
|
|
889414
|
+
name: flagValue2(rawRest, ["--name"]) ?? undefined,
|
|
889415
|
+
description: flagValue2(rawRest, ["--description"]) ?? undefined,
|
|
889416
|
+
persona: flagValue2(rawRest, ["--persona"]) ?? undefined,
|
|
889417
|
+
skills: parseCsvFlag2(rawRest, ["--skills"]),
|
|
889418
|
+
routines: parseCsvFlag2(rawRest, ["--routines"]),
|
|
889419
|
+
replace: hasYes(rawRest) && rawRest.includes("--replace")
|
|
889420
|
+
});
|
|
889421
|
+
const result4 = {
|
|
889422
|
+
ok: true,
|
|
889423
|
+
kind: "agent.profiles.template.from_discovered",
|
|
889424
|
+
data: { template }
|
|
889425
|
+
};
|
|
889426
|
+
return {
|
|
889427
|
+
output: renderProfilesOutput(result4, runtime3.cli.flags.outputFormat),
|
|
889428
|
+
exitCode: 0
|
|
889429
|
+
};
|
|
889430
|
+
}
|
|
888834
889431
|
if (templateAction === "export") {
|
|
888835
889432
|
if (!templateId || !templatePath) {
|
|
888836
889433
|
const result5 = {
|
|
@@ -888977,6 +889574,58 @@ async function handleProfilesCommand(runtime3) {
|
|
|
888977
889574
|
exitCode: 0
|
|
888978
889575
|
};
|
|
888979
889576
|
}
|
|
889577
|
+
if (sub === "create-from-discovered" || sub === "create-discovered") {
|
|
889578
|
+
const name51 = values2[0];
|
|
889579
|
+
if (!name51) {
|
|
889580
|
+
const result4 = {
|
|
889581
|
+
ok: false,
|
|
889582
|
+
kind: "agent.profiles.error",
|
|
889583
|
+
error: "Usage: goodvibes-agent profiles create-from-discovered <name> [--template-id <id>] [--profile-name <display>] [--description <summary>] [--persona <name>] [--skills all|name,name] [--routines all|name,name] [--replace] --yes"
|
|
889584
|
+
};
|
|
889585
|
+
return {
|
|
889586
|
+
output: renderProfilesOutput(result4, runtime3.cli.flags.outputFormat),
|
|
889587
|
+
exitCode: 2
|
|
889588
|
+
};
|
|
889589
|
+
}
|
|
889590
|
+
if (!hasYes(rawRest)) {
|
|
889591
|
+
const result4 = {
|
|
889592
|
+
ok: false,
|
|
889593
|
+
kind: "agent.profiles.error",
|
|
889594
|
+
error: `Refusing to create Agent profile ${name51} from discovered behavior without --yes.`
|
|
889595
|
+
};
|
|
889596
|
+
return {
|
|
889597
|
+
output: renderProfilesOutput(result4, runtime3.cli.flags.outputFormat),
|
|
889598
|
+
exitCode: 2
|
|
889599
|
+
};
|
|
889600
|
+
}
|
|
889601
|
+
const created = await createAgentRuntimeProfileFromDiscovered({
|
|
889602
|
+
homeDirectory: runtime3.homeDirectory,
|
|
889603
|
+
workingDirectory: runtime3.workingDirectory
|
|
889604
|
+
}, {
|
|
889605
|
+
profileName: name51,
|
|
889606
|
+
templateId: flagValue2(rawRest, ["--template-id", "--starter-id"]) ?? undefined,
|
|
889607
|
+
name: flagValue2(rawRest, ["--profile-name", "--name"]) ?? undefined,
|
|
889608
|
+
description: flagValue2(rawRest, ["--description"]) ?? undefined,
|
|
889609
|
+
persona: flagValue2(rawRest, ["--persona"]) ?? undefined,
|
|
889610
|
+
skills: parseCsvFlag2(rawRest, ["--skills"]),
|
|
889611
|
+
routines: parseCsvFlag2(rawRest, ["--routines"]),
|
|
889612
|
+
replace: rawRest.includes("--replace")
|
|
889613
|
+
});
|
|
889614
|
+
const result3 = {
|
|
889615
|
+
ok: true,
|
|
889616
|
+
kind: "agent.profiles.create_from_discovered",
|
|
889617
|
+
data: {
|
|
889618
|
+
profile: created.profile,
|
|
889619
|
+
appliedTemplate: created.profile.starterTemplateApplication,
|
|
889620
|
+
template: created.template,
|
|
889621
|
+
nextCommand: `goodvibes-agent --agent-profile ${created.profile.id}`
|
|
889622
|
+
}
|
|
889623
|
+
};
|
|
889624
|
+
return {
|
|
889625
|
+
output: renderProfilesOutput(result3, runtime3.cli.flags.outputFormat),
|
|
889626
|
+
exitCode: 0
|
|
889627
|
+
};
|
|
889628
|
+
}
|
|
888980
889629
|
if (sub === "delete" || sub === "remove") {
|
|
888981
889630
|
const name51 = values2[0];
|
|
888982
889631
|
if (!name51) {
|
|
@@ -889498,7 +890147,7 @@ function readAuthPaths(runtime3) {
|
|
|
889498
890147
|
});
|
|
889499
890148
|
const userStorePath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
|
|
889500
890149
|
const bootstrapCredentialPath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
|
|
889501
|
-
const operatorTokenPath =
|
|
890150
|
+
const operatorTokenPath = join101(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
889502
890151
|
return {
|
|
889503
890152
|
userStorePath,
|
|
889504
890153
|
userStorePresent: existsSync84(userStorePath),
|
|
@@ -890013,7 +890662,7 @@ async function prepareShellCliRuntime(argv, roots, binary2 = "goodvibes-agent")
|
|
|
890013
890662
|
workingDirectory: bootstrapWorkingDir,
|
|
890014
890663
|
homeDirectory: bootstrapHomeDirectory
|
|
890015
890664
|
} = ownership;
|
|
890016
|
-
configureActivityLogger(
|
|
890665
|
+
configureActivityLogger(join102(bootstrapWorkingDir, ".goodvibes", "logs"));
|
|
890017
890666
|
const configManager = new ConfigManager({
|
|
890018
890667
|
workingDir: bootstrapWorkingDir,
|
|
890019
890668
|
homeDir: bootstrapHomeDirectory,
|
|
@@ -890064,7 +890713,7 @@ async function prepareShellCliRuntime(argv, roots, binary2 = "goodvibes-agent")
|
|
|
890064
890713
|
});
|
|
890065
890714
|
const userStorePath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
|
|
890066
890715
|
const bootstrapCredentialPath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
|
|
890067
|
-
const operatorTokenPath =
|
|
890716
|
+
const operatorTokenPath = join102(bootstrapHomeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
|
|
890068
890717
|
const onboardingMarkers = readOnboardingCheckMarkers(shellPaths3);
|
|
890069
890718
|
const service = await buildCliServicePosture({
|
|
890070
890719
|
configManager,
|
|
@@ -890202,7 +890851,7 @@ function applyInitialTuiCliState(options) {
|
|
|
890202
890851
|
|
|
890203
890852
|
// src/audio/player.ts
|
|
890204
890853
|
import { accessSync, constants as constants4 } from "fs";
|
|
890205
|
-
import { delimiter, join as
|
|
890854
|
+
import { delimiter, join as join103 } from "path";
|
|
890206
890855
|
import { spawn as spawn6 } from "child_process";
|
|
890207
890856
|
|
|
890208
890857
|
class LocalStreamingAudioPlayer {
|
|
@@ -890299,7 +890948,7 @@ function findExecutable(name51, env2) {
|
|
|
890299
890948
|
if (!dir)
|
|
890300
890949
|
continue;
|
|
890301
890950
|
for (const ext of extensions14) {
|
|
890302
|
-
const candidate =
|
|
890951
|
+
const candidate = join103(dir, `${name51}${ext}`);
|
|
890303
890952
|
try {
|
|
890304
890953
|
accessSync(candidate, constants4.X_OK);
|
|
890305
890954
|
return candidate;
|