@pellux/goodvibes-agent 0.1.113 → 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.
Files changed (31) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +4 -0
  3. package/dist/package/main.js +1659 -324
  4. package/docs/getting-started.md +4 -0
  5. package/package.json +1 -1
  6. package/src/agent/behavior-discovery-summary.ts +167 -0
  7. package/src/agent/persona-discovery.ts +117 -0
  8. package/src/agent/routine-discovery.ts +115 -0
  9. package/src/agent/runtime-profile-starters.ts +331 -0
  10. package/src/agent/runtime-profile.ts +150 -330
  11. package/src/cli/help.ts +11 -3
  12. package/src/cli/local-library-command.ts +81 -1
  13. package/src/cli/profiles-command.ts +128 -0
  14. package/src/cli/routines-command.ts +156 -1
  15. package/src/input/agent-workspace-basic-command-editor-submission.ts +534 -0
  16. package/src/input/agent-workspace-basic-command-editors.ts +77 -395
  17. package/src/input/agent-workspace-categories.ts +7 -0
  18. package/src/input/agent-workspace-command-editor.ts +4 -0
  19. package/src/input/agent-workspace-setup.ts +33 -13
  20. package/src/input/agent-workspace-snapshot.ts +6 -0
  21. package/src/input/agent-workspace-types.ts +6 -0
  22. package/src/input/commands/agent-runtime-profile-runtime.ts +73 -4
  23. package/src/input/commands/personas-runtime.ts +87 -2
  24. package/src/input/commands/routines-runtime.ts +87 -2
  25. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +46 -9
  26. package/src/input/onboarding/onboarding-wizard-steps.ts +1 -1
  27. package/src/renderer/agent-workspace.ts +26 -0
  28. package/src/runtime/onboarding/derivation.ts +20 -1
  29. package/src/runtime/onboarding/snapshot.ts +2 -0
  30. package/src/runtime/onboarding/types.ts +2 -0
  31. package/src/version.ts +1 -1
@@ -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.113";
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 join89 } from "path";
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 join86 } from "path";
851688
- var PROFILE_CREATED_FILE = "profile.json";
851689
- var PROFILE_ID_PATTERN = /^[a-z0-9](?:[a-z0-9._-]{0,62}[a-z0-9])?$/;
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 join86(baseHomeDirectory, ".goodvibes", "agent", "profile-homes");
852215
+ return join88(baseHomeDirectory, ".goodvibes", "agent", "profile-homes");
852026
852216
  }
852027
852217
  function getAgentRuntimeProfileTemplatesRoot(baseHomeDirectory) {
852028
- return join86(baseHomeDirectory, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "profile-starters");
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: join86(getAgentRuntimeProfilesRoot(baseHomeDirectory), id)
852224
+ homeDirectory: join88(getAgentRuntimeProfilesRoot(baseHomeDirectory), id)
852035
852225
  };
852036
852226
  }
852037
852227
  function readProfileCreatedAt(homeDirectory) {
852038
- const path7 = join86(homeDirectory, PROFILE_CREATED_FILE);
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 = join86(homeDirectory, PROFILE_CREATED_FILE);
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 join86(homeDirectory, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, folder, file2);
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(join86(root, entry))).filter((entry) => entry !== null).sort((left, right) => left.id.localeCompare(right.id));
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 = join86(root, `${parsed.id}.json`);
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(join86(root, entry)).isDirectory();
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(join86(resolution2.homeDirectory, PROFILE_CREATED_FILE), `${JSON.stringify({
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
- ctx.print("Usage: /agent-profile template [show <id>|export <id> <path> --yes|import <path> --yes]");
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
  }
@@ -852737,6 +853106,84 @@ function renderPersona(persona, activePersonaId) {
852737
853106
  ].filter(Boolean).join(`
852738
853107
  `);
852739
853108
  }
853109
+ function summarizeDiscoveredPersona(persona) {
853110
+ const description = persona.description ? ` - ${persona.description}` : "";
853111
+ return ` ${persona.name} ${persona.origin}${description}
853112
+ path: ${persona.path}`;
853113
+ }
853114
+ function renderDiscoveredPersonas(personas) {
853115
+ if (personas.length === 0) {
853116
+ return [
853117
+ "Discovered Agent persona files",
853118
+ " No persona markdown files found in project/global Agent persona folders.",
853119
+ " Search roots: .goodvibes/personas, .goodvibes/agent/personas, .goodvibes/agents, ~/.goodvibes/personas, ~/.goodvibes/agent/personas, ~/.goodvibes/agents"
853120
+ ].join(`
853121
+ `);
853122
+ }
853123
+ return [
853124
+ `Discovered Agent persona files (${personas.length})`,
853125
+ ...personas.map(summarizeDiscoveredPersona),
853126
+ "",
853127
+ "Import one with: /personas import-discovered <name> --yes"
853128
+ ].join(`
853129
+ `);
853130
+ }
853131
+ function discoveredPersonaLookupValues(persona) {
853132
+ const slug = persona.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
853133
+ const basename5 = persona.path.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
853134
+ return [persona.name, slug, persona.path, basename5].map((value) => value.trim().toLowerCase()).filter(Boolean);
853135
+ }
853136
+ function findDiscoveredPersona(personas, idOrName) {
853137
+ const lookup = idOrName.trim().toLowerCase();
853138
+ if (!lookup)
853139
+ return null;
853140
+ return personas.find((persona) => discoveredPersonaLookupValues(persona).includes(lookup)) ?? null;
853141
+ }
853142
+ function frontmatterList(persona, key) {
853143
+ const value = persona.frontmatter[key];
853144
+ if (!value)
853145
+ return [];
853146
+ return splitList(value);
853147
+ }
853148
+ async function importDiscoveredPersona(args2, ctx, personaRegistry) {
853149
+ const parsed = parsePersonaArgs(args2);
853150
+ const name51 = parsed.rest.join(" ").trim();
853151
+ if (!name51) {
853152
+ ctx.print("Usage: /personas import-discovered <name> [--use] --yes");
853153
+ return;
853154
+ }
853155
+ const discovered = findDiscoveredPersona(await discoverPersonas(requireShellPaths(ctx)), name51);
853156
+ if (!discovered) {
853157
+ ctx.print(`Unknown discovered Agent persona: ${name51}
853158
+ Run /personas discover to inspect available persona files.`);
853159
+ return;
853160
+ }
853161
+ if (!parsed.yes) {
853162
+ ctx.print([
853163
+ "Agent persona import preview",
853164
+ ` name: ${discovered.name}`,
853165
+ ` origin: ${discovered.origin}`,
853166
+ ` path: ${discovered.path}`,
853167
+ ` description: ${discovered.description || "(none)"}`,
853168
+ ` body characters: ${discovered.body.length}`,
853169
+ " next: rerun with --yes to import into the Agent-local persona registry"
853170
+ ].join(`
853171
+ `));
853172
+ return;
853173
+ }
853174
+ const persona = personaRegistry.create({
853175
+ name: discovered.name,
853176
+ description: discovered.description || `Imported persona from ${discovered.origin} markdown file.`,
853177
+ body: discovered.body,
853178
+ tags: frontmatterList(discovered, "tags"),
853179
+ triggers: frontmatterList(discovered, "triggers"),
853180
+ source: "imported",
853181
+ provenance: `discovered:${discovered.origin}:${discovered.path}`
853182
+ });
853183
+ if (parsed.flags.get("use") === "true")
853184
+ personaRegistry.setActive(persona.id);
853185
+ ctx.print(`Imported Agent persona ${persona.id}: ${persona.name}${parsed.flags.get("use") === "true" ? " (active)" : ""}`);
853186
+ }
852740
853187
  function requiredFlag(flags2, key) {
852741
853188
  const value = flags2.get(key)?.trim();
852742
853189
  if (!value)
@@ -852751,7 +853198,7 @@ function registerPersonasRuntimeCommands(registry5) {
852751
853198
  name: "personas",
852752
853199
  aliases: ["persona"],
852753
853200
  description: "Manage local GoodVibes Agent personas",
852754
- usage: "[list|search <query>|show <id>|create --name <name> --description <summary> --body <instructions>|update <id> [--name ...] [--description ...] [--body ...]|use <id>|active|clear|review <id>|stale <id> <reason...>|delete <id> --yes]",
853201
+ usage: "[list|discover|import-discovered <name> --yes|search <query>|show <id>|create --name <name> --description <summary> --body <instructions>|update <id> [--name ...] [--description ...] [--body ...]|use <id>|active|clear|review <id>|stale <id> <reason...>|delete <id> --yes]",
852755
853202
  async handler(args2, ctx) {
852756
853203
  const sub = (args2[0] ?? "list").toLowerCase();
852757
853204
  const registryStore = registryFromContext(ctx);
@@ -852760,6 +853207,14 @@ function registerPersonasRuntimeCommands(registry5) {
852760
853207
  ctx.print(renderList("Agent Personas", registryStore, registryStore.list()));
852761
853208
  return;
852762
853209
  }
853210
+ if (sub === "discover" || sub === "discovered") {
853211
+ ctx.print(renderDiscoveredPersonas(await discoverPersonas(requireShellPaths(ctx))));
853212
+ return;
853213
+ }
853214
+ if (sub === "import-discovered" || sub === "import-persona") {
853215
+ await importDiscoveredPersona(args2.slice(1), ctx, registryStore);
853216
+ return;
853217
+ }
852763
853218
  if (sub === "search") {
852764
853219
  const query2 = args2.slice(1).join(" ").trim();
852765
853220
  ctx.print(renderList(query2 ? `Agent Personas matching "${query2}"` : "Agent Personas", registryStore, registryStore.search(query2)));
@@ -852864,7 +853319,7 @@ function registerPersonasRuntimeCommands(registry5) {
852864
853319
  ctx.print(`Deleted Agent persona ${removed.id}: ${removed.name}`);
852865
853320
  return;
852866
853321
  }
852867
- ctx.print("Usage: /personas [list|search <query>|show <id>|create|update|use|active|clear|review|stale|delete]");
853322
+ ctx.print("Usage: /personas [list|discover|import-discovered|search <query>|show <id>|create|update|use|active|clear|review|stale|delete]");
852868
853323
  } catch (error51) {
852869
853324
  printError2(ctx, error51);
852870
853325
  }
@@ -852975,7 +853430,7 @@ function findDiscoveredSkill(skills, idOrName) {
852975
853430
  return null;
852976
853431
  return skills.find((skill) => discoveredSkillLookupValues(skill).includes(lookup)) ?? null;
852977
853432
  }
852978
- function frontmatterList(skill, key) {
853433
+ function frontmatterList2(skill, key) {
852979
853434
  const value = skill.frontmatter[key];
852980
853435
  if (!value)
852981
853436
  return [];
@@ -853011,8 +853466,8 @@ Run /agent-skills discover to inspect available skill files.`);
853011
853466
  name: discovered.name,
853012
853467
  description: discovered.description || `Imported skill from ${discovered.origin} skill file.`,
853013
853468
  procedure: discovered.body,
853014
- triggers: frontmatterList(discovered, "triggers"),
853015
- tags: frontmatterList(discovered, "tags"),
853469
+ triggers: frontmatterList2(discovered, "triggers"),
853470
+ tags: frontmatterList2(discovered, "tags"),
853016
853471
  enabled: parsed.flags.get("enabled") === "true",
853017
853472
  source: "imported",
853018
853473
  provenance: `discovered:${discovered.origin}:${discovered.path}`
@@ -853400,9 +853855,86 @@ function renderRoutine(routine) {
853400
853855
  ].filter(Boolean).join(`
853401
853856
  `);
853402
853857
  }
853858
+ function summarizeDiscoveredRoutine(routine) {
853859
+ const description = routine.description ? ` - ${routine.description}` : "";
853860
+ return ` ${routine.name} ${routine.origin}${description}
853861
+ path: ${routine.path}`;
853862
+ }
853863
+ function renderDiscoveredRoutines(routines) {
853864
+ if (routines.length === 0) {
853865
+ return [
853866
+ "Discovered Agent routine files",
853867
+ " No routine markdown files found in project/global Agent routine folders.",
853868
+ " Search roots: .goodvibes/routines, .goodvibes/agent/routines, ~/.goodvibes/routines, ~/.goodvibes/agent/routines"
853869
+ ].join(`
853870
+ `);
853871
+ }
853872
+ return [
853873
+ `Discovered Agent routine files (${routines.length})`,
853874
+ ...routines.map(summarizeDiscoveredRoutine),
853875
+ "",
853876
+ "Import one with: /routines import-discovered <name> --yes"
853877
+ ].join(`
853878
+ `);
853879
+ }
853880
+ function discoveredRoutineLookupValues(routine) {
853881
+ const slug = routine.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
853882
+ const basename5 = routine.path.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
853883
+ return [routine.name, slug, routine.path, basename5].map((value) => value.trim().toLowerCase()).filter(Boolean);
853884
+ }
853885
+ function findDiscoveredRoutine(routines, idOrName) {
853886
+ const lookup = idOrName.trim().toLowerCase();
853887
+ if (!lookup)
853888
+ return null;
853889
+ return routines.find((routine) => discoveredRoutineLookupValues(routine).includes(lookup)) ?? null;
853890
+ }
853891
+ function frontmatterList3(routine, key) {
853892
+ const value = routine.frontmatter[key];
853893
+ if (!value)
853894
+ return [];
853895
+ return splitList3(value);
853896
+ }
853403
853897
  function printError4(ctx, error51) {
853404
853898
  ctx.print(`Error: ${error51 instanceof Error ? error51.message : String(error51)}`);
853405
853899
  }
853900
+ async function importDiscoveredRoutine(args2, ctx, routineRegistry) {
853901
+ const parsed = parseRoutineArgs(args2);
853902
+ const name51 = parsed.rest.join(" ").trim();
853903
+ if (!name51) {
853904
+ ctx.print("Usage: /routines import-discovered <name> [--enabled] --yes");
853905
+ return;
853906
+ }
853907
+ const discovered = findDiscoveredRoutine(await discoverRoutines(requireShellPaths(ctx)), name51);
853908
+ if (!discovered) {
853909
+ ctx.print(`Unknown discovered Agent routine: ${name51}
853910
+ Run /routines discover to inspect available routine files.`);
853911
+ return;
853912
+ }
853913
+ if (!parsed.yes) {
853914
+ ctx.print([
853915
+ "Agent routine import preview",
853916
+ ` name: ${discovered.name}`,
853917
+ ` origin: ${discovered.origin}`,
853918
+ ` path: ${discovered.path}`,
853919
+ ` description: ${discovered.description || "(none)"}`,
853920
+ ` steps characters: ${discovered.steps.length}`,
853921
+ " next: rerun with --yes to import into the Agent-local routine registry"
853922
+ ].join(`
853923
+ `));
853924
+ return;
853925
+ }
853926
+ const routine = routineRegistry.create({
853927
+ name: discovered.name,
853928
+ description: discovered.description || `Imported routine from ${discovered.origin} markdown file.`,
853929
+ steps: discovered.steps,
853930
+ tags: frontmatterList3(discovered, "tags"),
853931
+ triggers: frontmatterList3(discovered, "triggers"),
853932
+ enabled: parsed.flags.get("enabled") === "true",
853933
+ source: "imported",
853934
+ provenance: `discovered:${discovered.origin}:${discovered.path}`
853935
+ });
853936
+ ctx.print(`Imported Agent routine ${routine.id}: ${routine.name}${routine.enabled ? " (enabled)" : ""}`);
853937
+ }
853406
853938
  async function promoteRoutine(args2, routineRegistry, ctx) {
853407
853939
  const parsed = parseRoutineSchedulePromotionArgs(args2);
853408
853940
  if (parsed.errors.length > 0) {
@@ -853444,6 +853976,14 @@ async function runRoutinesRuntimeCommand(args2, ctx) {
853444
853976
  ctx.print(renderList3("Enabled Agent Routines", routineRegistry, snapshot.enabledRoutines));
853445
853977
  return;
853446
853978
  }
853979
+ if (sub === "discover" || sub === "discovered") {
853980
+ ctx.print(renderDiscoveredRoutines(await discoverRoutines(requireShellPaths(ctx))));
853981
+ return;
853982
+ }
853983
+ if (sub === "import-discovered" || sub === "import-routine") {
853984
+ await importDiscoveredRoutine(args2.slice(1), ctx, routineRegistry);
853985
+ return;
853986
+ }
853447
853987
  if (sub === "search") {
853448
853988
  const query2 = args2.slice(1).join(" ").trim();
853449
853989
  ctx.print(renderList3(query2 ? `Agent Routines matching "${query2}"` : "Agent Routines", routineRegistry, routineRegistry.search(query2)));
@@ -853579,7 +854119,7 @@ async function runRoutinesRuntimeCommand(args2, ctx) {
853579
854119
  ctx.print(`Deleted Agent routine ${removed.id}: ${removed.name}`);
853580
854120
  return;
853581
854121
  }
853582
- ctx.print("Usage: /routines [list|enabled|search|show|receipts|reconcile|receipt|create|update|enable|disable|start|review|stale|promote|delete]");
854122
+ ctx.print("Usage: /routines [list|enabled|discover|import-discovered|search|show|receipts|reconcile|receipt|create|update|enable|disable|start|review|stale|promote|delete]");
853583
854123
  } catch (error51) {
853584
854124
  printError4(ctx, error51);
853585
854125
  }
@@ -853589,14 +854129,14 @@ function registerRoutinesRuntimeCommands(registry5) {
853589
854129
  name: "routines",
853590
854130
  aliases: ["routine"],
853591
854131
  description: "Manage local GoodVibes Agent routines",
853592
- usage: "[list|enabled|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps>|update <id> [--name ...] [--description ...] [--steps ...]|enable <id>|disable <id>|start <id>|review <id>|stale <id> <reason...>|promote <id> --cron <expr> [--delivery-channel slack] --yes|delete <id> --yes]",
854132
+ usage: "[list|enabled|discover|import-discovered <name> --yes|search <query>|show <id>|receipts|reconcile|receipt <id>|create --name <name> --description <summary> --steps <steps>|update <id> [--name ...] [--description ...] [--steps ...]|enable <id>|disable <id>|start <id>|review <id>|stale <id> <reason...>|promote <id> --cron <expr> [--delivery-channel slack] --yes|delete <id> --yes]",
853593
854133
  handler: runRoutinesRuntimeCommand
853594
854134
  });
853595
854135
  }
853596
854136
 
853597
854137
  // src/input/commands/channels-runtime.ts
853598
854138
  import { existsSync as existsSync72, readFileSync as readFileSync79 } from "fs";
853599
- import { join as join87 } from "path";
854139
+ import { join as join89 } from "path";
853600
854140
 
853601
854141
  // src/input/agent-workspace-channels.ts
853602
854142
  var AGENT_WORKSPACE_CHANNEL_SPECS = [
@@ -853807,7 +854347,7 @@ function resolveChannelDaemonConnection(context) {
853807
854347
  const host = typeof hostValue === "string" && hostValue.trim().length > 0 ? hostValue.trim() : "127.0.0.1";
853808
854348
  const port = typeof portValue === "number" && Number.isFinite(portValue) ? portValue : 3421;
853809
854349
  const homeDirectory = context.workspace?.shellPaths?.homeDirectory ?? process.env.HOME ?? "";
853810
- const tokenPath = join87(homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
854350
+ const tokenPath = join89(homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
853811
854351
  if (!existsSync72(tokenPath))
853812
854352
  return { baseUrl: `http://${host}:${port}`, token: null, tokenPath };
853813
854353
  try {
@@ -854132,6 +854672,143 @@ Use /channels list to see available channel ids.`);
854132
854672
  // src/input/agent-workspace-snapshot.ts
854133
854673
  import { basename as basename5, sep as sep3 } from "path";
854134
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
+
854135
854812
  // src/agent/memory-prompt.ts
854136
854813
  var DEFAULT_LIMIT = 10;
854137
854814
  var MIN_PROMPT_MEMORY_CONFIDENCE = 50;
@@ -854164,9 +854841,16 @@ function buildReviewedMemoryPrompt(memoryRegistry, limit3 = DEFAULT_LIMIT) {
854164
854841
  function setupStatusForCount(count, ready, empty) {
854165
854842
  return count > 0 ? ready : empty;
854166
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
+ }
854167
854850
  function buildAgentWorkspaceSetupChecklist(input) {
854168
854851
  const providerReady = input.provider !== "unknown" && input.model !== "unknown";
854169
854852
  const hasActivePersona = input.activePersonaName !== "(none)" && input.activePersonaName !== "(unavailable)";
854853
+ const discoveredBehaviorCount = input.discoveredPersonas.count + input.discoveredSkills.count + input.discoveredRoutines.count;
854170
854854
  return [
854171
854855
  {
854172
854856
  id: "runtime",
@@ -854192,30 +854876,30 @@ function buildAgentWorkspaceSetupChecklist(input) {
854192
854876
  {
854193
854877
  id: "profile",
854194
854878
  label: "Agent profile",
854195
- status: setupStatusForCount(input.runtimeProfileCount, "ready", "optional"),
854196
- 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.`,
854197
- 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"
854198
854882
  },
854199
854883
  {
854200
854884
  id: "persona",
854201
854885
  label: "Persona",
854202
854886
  status: hasActivePersona ? "ready" : "recommended",
854203
- detail: hasActivePersona ? `Active persona: ${input.activePersonaName}.` : "Create or choose a persona to make the assistant voice and policy explicit.",
854204
- 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"
854205
854889
  },
854206
854890
  {
854207
854891
  id: "skills",
854208
854892
  label: "Skills",
854209
- status: input.enabledSkillCount > 0 || input.enabledSkillBundleCount > 0 ? "ready" : input.skillCount > 0 || input.skillBundleCount > 0 ? "recommended" : "optional",
854210
- 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.",
854211
- 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"
854212
854896
  },
854213
854897
  {
854214
854898
  id: "routines",
854215
854899
  label: "Routines",
854216
- status: setupStatusForCount(input.enabledRoutineCount, "ready", input.routineCount > 0 ? "recommended" : "optional"),
854217
- detail: input.routineCount > 0 ? `${input.enabledRoutineCount}/${input.routineCount} local routine(s) enabled.` : "Create local routines first; promote schedules only with explicit confirmation.",
854218
- 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"
854219
854903
  },
854220
854904
  {
854221
854905
  id: "memory",
@@ -854592,6 +855276,7 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
854592
855276
  return { count: 0, enabled: 0, items: [] };
854593
855277
  }
854594
855278
  })();
855279
+ const discoveredBehavior = summarizeAgentBehaviorDiscovery(context.workspace?.shellPaths);
854595
855280
  const runtimeProfiles = (() => {
854596
855281
  try {
854597
855282
  return listAgentRuntimeProfiles(context.workspace?.shellPaths?.homeDirectory ?? "");
@@ -854678,6 +855363,9 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
854678
855363
  skillBundleCount: skillSnapshot.bundleCount,
854679
855364
  enabledSkillBundleCount: skillSnapshot.enabledBundleCount,
854680
855365
  activePersonaName: personaSnapshot.activeName,
855366
+ discoveredPersonas: discoveredBehavior.personas,
855367
+ discoveredSkills: discoveredBehavior.skills,
855368
+ discoveredRoutines: discoveredBehavior.routines,
854681
855369
  readyChannelCount: channels.filter((channel) => channel.ready).length,
854682
855370
  voiceProviderCount: voiceProviders.length,
854683
855371
  mediaProviderCount: mediaProviders.length,
@@ -854711,6 +855399,7 @@ function buildAgentWorkspaceRuntimeSnapshot(context) {
854711
855399
  localPersonaCount: personaSnapshot.count,
854712
855400
  activePersonaName: personaSnapshot.activeName,
854713
855401
  localPersonas: personaSnapshot.items,
855402
+ discoveredBehavior,
854714
855403
  knowledgeRoute: "/api/goodvibes-agent/knowledge",
854715
855404
  knowledgeIsolation: "agent-only",
854716
855405
  executionPolicy: "serial-proactive",
@@ -854902,8 +855591,8 @@ function registerBuiltinCommands(registry5) {
854902
855591
  }
854903
855592
 
854904
855593
  // src/input/input-history.ts
854905
- import { existsSync as existsSync73, mkdirSync as mkdirSync61, readFileSync as readFileSync80, writeFileSync as writeFileSync52 } from "fs";
854906
- import { dirname as dirname59, join as join88 } from "path";
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";
854907
855596
  class HistorySearch {
854908
855597
  getEntries;
854909
855598
  active = false;
@@ -854982,7 +855671,7 @@ function resolveHistoryPath2(options) {
854982
855671
  if (!userRoot) {
854983
855672
  throw new Error("InputHistory requires historyPath or an explicit userRoot/homeDirectory.");
854984
855673
  }
854985
- return join88(userRoot, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "input-history.json");
855674
+ return join91(userRoot, ".goodvibes", GOODVIBES_AGENT_SURFACE_ROOT, "input-history.json");
854986
855675
  }
854987
855676
 
854988
855677
  class InputHistory {
@@ -855063,7 +855752,7 @@ class InputHistory {
855063
855752
  load() {
855064
855753
  try {
855065
855754
  if (existsSync73(this.historyPath)) {
855066
- const raw = readFileSync80(this.historyPath, "utf-8");
855755
+ const raw = readFileSync81(this.historyPath, "utf-8");
855067
855756
  const parsed = JSON.parse(raw);
855068
855757
  if (Array.isArray(parsed)) {
855069
855758
  this.entries = parsed.map((entry) => this.normalizeStoredEntry(entry)).filter((entry) => entry !== null).slice(0, this.maxEntries);
@@ -860836,7 +861525,7 @@ function registerAgentPanels(manager5, deps) {
860836
861525
 
860837
861526
  // src/panels/builtin/session.ts
860838
861527
  import { networkInterfaces as networkInterfaces3 } from "os";
860839
- import { readFileSync as readFileSync81 } from "fs";
861528
+ import { readFileSync as readFileSync82 } from "fs";
860840
861529
 
860841
861530
  // src/panels/confirm-state.ts
860842
861531
  function handleConfirmInput(confirm, key) {
@@ -862412,7 +863101,7 @@ function getLocalNetworkIp2() {
862412
863101
  }
862413
863102
  function readBootstrapPassword(credentialPath) {
862414
863103
  try {
862415
- const content = readFileSync81(credentialPath, "utf-8");
863104
+ const content = readFileSync82(credentialPath, "utf-8");
862416
863105
  for (const line2 of content.split(`
862417
863106
  `)) {
862418
863107
  if (line2.startsWith("password=")) {
@@ -863784,7 +864473,7 @@ function createBootstrapShell(options) {
863784
864473
  hookActivityTracker: services.hookActivityTracker,
863785
864474
  hookWorkbench: services.hookWorkbench,
863786
864475
  mcpRegistry: services.mcpRegistry,
863787
- daemonHomeDir: join89(services.homeDirectory, ".goodvibes", "daemon")
864476
+ daemonHomeDir: join92(services.homeDirectory, ".goodvibes", "daemon")
863788
864477
  });
863789
864478
  services.panelManager.prewarmRegistered();
863790
864479
  const systemMessageRouter = createSystemMessageRouter(conversation, systemMessagesPanel, (kind2) => {
@@ -865730,7 +866419,7 @@ var verifyBundle2 = exports_security2.verifyBundle;
865730
866419
  var MAX_INPUT_LENGTH2 = exports_security2.MAX_INPUT_LENGTH;
865731
866420
  var MAX_TOKEN_COUNT2 = exports_security2.MAX_TOKEN_COUNT;
865732
866421
  // src/runtime/onboarding/state.ts
865733
- import { existsSync as existsSync74, mkdirSync as mkdirSync62, readFileSync as readFileSync82, writeFileSync as writeFileSync53 } from "fs";
866422
+ import { existsSync as existsSync74, mkdirSync as mkdirSync62, readFileSync as readFileSync83, writeFileSync as writeFileSync53 } from "fs";
865734
866423
  import { dirname as dirname60 } from "path";
865735
866424
  var ONBOARDING_RUNTIME_STATE_FILE = "onboarding-state.json";
865736
866425
  function resolveStatePath(shellPaths, scope) {
@@ -865776,7 +866465,7 @@ function readOnboardingRuntimeState(shellPaths, scope = "project") {
865776
866465
  };
865777
866466
  }
865778
866467
  try {
865779
- const parsed = JSON.parse(readFileSync82(path7, "utf-8"));
866468
+ const parsed = JSON.parse(readFileSync83(path7, "utf-8"));
865780
866469
  if (!isRuntimeStatePayload(parsed)) {
865781
866470
  return {
865782
866471
  scope,
@@ -866136,6 +866825,7 @@ async function collectOnboardingSnapshot(deps) {
866136
866825
  records: sortSurfaceRecords(surfaceResult.value)
866137
866826
  },
866138
866827
  providerAccounts: providerAccountsResult.value,
866828
+ localBehaviorDiscovery: summarizeAgentBehaviorDiscovery(deps.shellPaths),
866139
866829
  collectionIssues
866140
866830
  };
866141
866831
  }
@@ -866193,13 +866883,13 @@ var INBOUND_EVENT_SURFACE_KINDS = new Set([
866193
866883
  ]);
866194
866884
  // src/runtime/onboarding/apply.ts
866195
866885
  init_config8();
866196
- import { existsSync as existsSync76, mkdirSync as mkdirSync63, readFileSync as readFileSync83, rmSync as rmSync10, unlinkSync as unlinkSync12, writeFileSync as writeFileSync54 } from "fs";
866886
+ import { existsSync as existsSync76, mkdirSync as mkdirSync63, readFileSync as readFileSync84, rmSync as rmSync10, unlinkSync as unlinkSync12, writeFileSync as writeFileSync54 } from "fs";
866197
866887
  import { dirname as dirname61 } from "path";
866198
866888
 
866199
866889
  // src/runtime/onboarding/verify.ts
866200
866890
  init_config8();
866201
866891
  import { existsSync as existsSync75 } from "fs";
866202
- import { join as join90 } from "path";
866892
+ import { join as join93 } from "path";
866203
866893
  function getNow(deps) {
866204
866894
  return deps.clock?.() ?? Date.now();
866205
866895
  }
@@ -866280,7 +866970,7 @@ function verifyAuthOperation(_deps, operation) {
866280
866970
  }
866281
866971
  function verifyCreateAgentProfileOperation(deps, operation) {
866282
866972
  const resolution2 = resolveAgentRuntimeProfileHome(deps.shellPaths.homeDirectory, operation.name);
866283
- const ok3 = existsSync75(join90(resolution2.homeDirectory, "profile.json"));
866973
+ const ok3 = existsSync75(join93(resolution2.homeDirectory, "profile.json"));
866284
866974
  return {
866285
866975
  id: `agent-profile:${resolution2.id}`,
866286
866976
  status: ok3 ? "pass" : "fail",
@@ -866318,7 +867008,7 @@ function isPlainObject3(value) {
866318
867008
  function readJsonObject(path7) {
866319
867009
  if (!existsSync76(path7))
866320
867010
  return {};
866321
- const parsed = JSON.parse(readFileSync83(path7, "utf-8"));
867011
+ const parsed = JSON.parse(readFileSync84(path7, "utf-8"));
866322
867012
  if (!isPlainObject3(parsed))
866323
867013
  throw new Error(`Expected an object JSON payload at ${path7}.`);
866324
867014
  return parsed;
@@ -866353,7 +867043,7 @@ function restoreFile(path7, previous, reload) {
866353
867043
  reload?.();
866354
867044
  }
866355
867045
  function snapshotFileRollback(path7, reload) {
866356
- const previous = existsSync76(path7) ? readFileSync83(path7, "utf-8") : null;
867046
+ const previous = existsSync76(path7) ? readFileSync84(path7, "utf-8") : null;
866357
867047
  return () => restoreFile(path7, previous, reload);
866358
867048
  }
866359
867049
  async function runRollbacks(rollbacks) {
@@ -866516,7 +867206,7 @@ async function buildSecretRollbackAction(deps, operation) {
866516
867206
  throw new Error(`Secret storage locations for ${scope} scope are unavailable.`);
866517
867207
  const snapshots = locations.map((location) => ({
866518
867208
  path: location.path,
866519
- previous: existsSync76(location.path) ? readFileSync83(location.path, "utf-8") : null
867209
+ previous: existsSync76(location.path) ? readFileSync84(location.path, "utf-8") : null
866520
867210
  }));
866521
867211
  return () => {
866522
867212
  for (const snapshot of snapshots)
@@ -866736,7 +867426,7 @@ async function applyOnboardingRequest(deps, request2) {
866736
867426
  };
866737
867427
  }
866738
867428
  // src/runtime/onboarding/markers.ts
866739
- import { existsSync as existsSync77, mkdirSync as mkdirSync64, readFileSync as readFileSync84, writeFileSync as writeFileSync55 } from "fs";
867429
+ import { existsSync as existsSync77, mkdirSync as mkdirSync64, readFileSync as readFileSync85, writeFileSync as writeFileSync55 } from "fs";
866740
867430
  import { dirname as dirname62 } from "path";
866741
867431
  var ONBOARDING_CHECK_MARKER_FILE = "onboarding-checked.json";
866742
867432
  function resolveMarkerPath(shellPaths, scope) {
@@ -866783,7 +867473,7 @@ function readOnboardingCheckMarker(shellPaths, scope = "user") {
866783
867473
  if (!existsSync77(path7))
866784
867474
  return buildMissingMarkerState(scope, path7);
866785
867475
  try {
866786
- const parsed = JSON.parse(readFileSync84(path7, "utf-8"));
867476
+ const parsed = JSON.parse(readFileSync85(path7, "utf-8"));
866787
867477
  if (!isCheckMarkerPayload(parsed)) {
866788
867478
  return buildParseErrorState(scope, path7, "Invalid onboarding check marker payload.");
866789
867479
  }
@@ -866825,7 +867515,7 @@ function writeOnboardingCheckMarker(shellPaths, options = {}) {
866825
867515
  return readOnboardingCheckMarker(shellPaths, scope);
866826
867516
  }
866827
867517
  // src/input/handler-content-actions.ts
866828
- import { readFileSync as readFileSync85, existsSync as existsSync78 } from "fs";
867518
+ import { readFileSync as readFileSync86, existsSync as existsSync78 } from "fs";
866829
867519
  var MARKER_REGEX = /\[(TEXT|IMAGE): [^\]]+\]/g;
866830
867520
  var IMAGE_PREFIXES = [
866831
867521
  { prefix: "iVBORw0KGgo", mediaType: "image/png" },
@@ -866887,7 +867577,7 @@ function registerPaste(state4, content, projectRoot) {
866887
867577
  try {
866888
867578
  const resolvedPath3 = resolveAndValidatePath(trimmed2, projectRoot);
866889
867579
  if (existsSync78(resolvedPath3)) {
866890
- const data = readFileSync85(resolvedPath3);
867580
+ const data = readFileSync86(resolvedPath3);
866891
867581
  const base644 = data.toString("base64");
866892
867582
  const ext = trimmed2.slice(trimmed2.lastIndexOf("."));
866893
867583
  const mediaType = mediaTypeFromExt(ext);
@@ -866937,7 +867627,7 @@ function expandPrompt(pasteRegistry, imageRegistry, text, projectRoot) {
866937
867627
  const filePath = injectMatch[1];
866938
867628
  try {
866939
867629
  const resolvedPath3 = resolveAndValidatePath(filePath, projectRoot);
866940
- const content = readFileSync85(resolvedPath3, "utf-8");
867630
+ const content = readFileSync86(resolvedPath3, "utf-8");
866941
867631
  expanded = expanded.slice(0, injectMatch.index) + content + expanded.slice(injectMatch.index + injectMatch[0].length);
866942
867632
  injectRegex.lastIndex = injectMatch.index + content.length;
866943
867633
  } catch (err2) {
@@ -868337,7 +869027,7 @@ class AutocompleteEngine {
868337
869027
 
868338
869028
  // src/input/file-picker.ts
868339
869029
  import { readdir as readdir6 } from "fs/promises";
868340
- import { join as join91, relative as relative15 } from "path";
869030
+ import { join as join94, relative as relative15 } from "path";
868341
869031
 
868342
869032
  class FilePickerModal {
868343
869033
  shellPaths;
@@ -868470,7 +869160,7 @@ class FilePickerModal {
868470
869160
  continue;
868471
869161
  if (entry.name === "node_modules" || entry.name === "dist")
868472
869162
  continue;
868473
- const fullPath = join91(dir, entry.name);
869163
+ const fullPath = join94(dir, entry.name);
868474
869164
  const relPath = relative15(this.shellPaths.workingDirectory, fullPath);
868475
869165
  if (entry.isDirectory()) {
868476
869166
  files.push(relPath + "/");
@@ -871892,218 +872582,13 @@ function quoteSlashCommandArg(value) {
871892
872582
  return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
871893
872583
  }
871894
872584
 
871895
- // src/input/agent-workspace-basic-command-editors.ts
872585
+ // src/input/agent-workspace-basic-command-editor-submission.ts
871896
872586
  function isAffirmative2(value) {
871897
872587
  return /^(y|yes|true)$/i.test(value.trim());
871898
872588
  }
871899
872589
  function splitCommaList(value) {
871900
872590
  return value.split(",").map((entry) => entry.trim()).filter(Boolean);
871901
872591
  }
871902
- function isAgentWorkspaceBasicCommandEditorKind(kind2) {
871903
- return kind2 === "knowledge-bookmarks" || kind2 === "knowledge-file" || kind2 === "knowledge-browser-history" || kind2 === "knowledge-connector-ingest" || kind2 === "tts-prompt" || kind2 === "image-input" || kind2 === "skill-bundle" || kind2 === "skill-discovery-import" || kind2 === "profile-template-export" || kind2 === "profile-template-import" || kind2 === "mcp-server" || kind2 === "notify-webhook" || kind2 === "notify-webhook-remove" || kind2 === "notify-webhook-test";
871904
- }
871905
- function createAgentWorkspaceBasicCommandEditor(kind2) {
871906
- if (kind2 === "knowledge-bookmarks") {
871907
- return {
871908
- kind: kind2,
871909
- mode: "create",
871910
- title: "Import Bookmarks into Agent Knowledge",
871911
- selectedFieldIndex: 0,
871912
- message: "Import a browser bookmark export into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
871913
- fields: [
871914
- { id: "path", label: "Bookmark export path", value: "", required: true, multiline: false, hint: "Path to an HTML or JSON browser bookmark export." },
871915
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge import-bookmarks with --yes." }
871916
- ]
871917
- };
871918
- }
871919
- if (kind2 === "knowledge-file") {
871920
- return {
871921
- kind: kind2,
871922
- mode: "create",
871923
- title: "Ingest File into Agent Knowledge",
871924
- selectedFieldIndex: 0,
871925
- message: "Import a local source-backed file into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
871926
- fields: [
871927
- { id: "path", label: "File path", value: "", required: true, multiline: false, hint: "Path to a local document or text file to ingest." },
871928
- { id: "title", label: "Title", value: "", required: false, multiline: false, hint: "Optional source title." },
871929
- { id: "tags", label: "Tags", value: "", required: false, multiline: false, hint: "Comma-separated optional tags." },
871930
- { id: "folder", label: "Folder", value: "", required: false, multiline: false, hint: "Optional Agent Knowledge folder path." },
871931
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge ingest-file with --yes." }
871932
- ]
871933
- };
871934
- }
871935
- if (kind2 === "knowledge-browser-history") {
871936
- return {
871937
- kind: kind2,
871938
- mode: "create",
871939
- title: "Import Browser History into Agent Knowledge",
871940
- selectedFieldIndex: 0,
871941
- message: "Import local browser history/bookmarks into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
871942
- fields: [
871943
- { id: "browsers", label: "Browsers", value: "", required: false, multiline: false, hint: "Optional comma list: chrome, brave, edge, firefox, safari, etc." },
871944
- { id: "sources", label: "Sources", value: "history,bookmark", required: false, multiline: false, hint: "history, bookmark, or both." },
871945
- { id: "limit", label: "Limit", value: "250", required: false, multiline: false, hint: "Maximum browser entries to import." },
871946
- { id: "sinceDays", label: "Since days", value: "", required: false, multiline: false, hint: "Optional age window, such as 30." },
871947
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge import-browser-history with --yes." }
871948
- ]
871949
- };
871950
- }
871951
- if (kind2 === "knowledge-connector-ingest") {
871952
- return {
871953
- kind: kind2,
871954
- mode: "create",
871955
- title: "Ingest Connector Input",
871956
- selectedFieldIndex: 0,
871957
- message: "Send explicit connector input into the isolated Agent Knowledge segment. Type yes on the final field to confirm.",
871958
- fields: [
871959
- { id: "connectorId", label: "Connector id", value: "", required: true, multiline: false, hint: "Connector id from /knowledge connectors." },
871960
- { id: "input", label: "Input", value: "", required: false, multiline: true, hint: "Optional JSON or text input. Ctrl-J inserts a new line." },
871961
- { id: "path", label: "Path", value: "", required: false, multiline: false, hint: "Optional local path for connectors that read files." },
871962
- { id: "content", label: "Content", value: "", required: false, multiline: true, hint: "Optional raw content for connectors that accept text." },
871963
- { id: "allowPrivateHosts", label: "Allow private hosts", value: "no", required: false, multiline: false, hint: "yes/no. Defaults to no." },
871964
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /knowledge ingest-connector with --yes." }
871965
- ]
871966
- };
871967
- }
871968
- if (kind2 === "mcp-server") {
871969
- return {
871970
- kind: kind2,
871971
- mode: "create",
871972
- title: "Add MCP Server",
871973
- selectedFieldIndex: 0,
871974
- message: "Add or update one MCP server from the Agent workspace. Type yes on the final field to confirm.",
871975
- fields: [
871976
- { id: "name", label: "Server name", value: "", required: true, multiline: false, hint: "Letters, numbers, dot, underscore, and dash only." },
871977
- { id: "command", label: "Command", value: "", required: true, multiline: false, hint: "Executable command, such as bunx, npx, uvx, or a full local binary path." },
871978
- { id: "args", label: "Arguments", value: "", required: false, multiline: false, hint: "Optional command arguments. Quotes are supported." },
871979
- { id: "scope", label: "Scope", value: "", required: false, multiline: false, hint: "Optional. Defaults to project. Use project or global." },
871980
- { id: "role", label: "Role", value: "", required: false, multiline: false, hint: "Optional. general, docs, filesystem, git, database, browser, automation, ops, or remote." },
871981
- { 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." },
871982
- { id: "env", label: "Env refs", value: "", required: false, multiline: false, hint: "Comma-separated KEY=VALUE entries. Prefer secret refs, not raw secrets." },
871983
- { id: "paths", label: "Allowed paths", value: "", required: false, multiline: false, hint: "Comma-separated path allowlist entries." },
871984
- { id: "hosts", label: "Allowed hosts", value: "", required: false, multiline: false, hint: "Comma-separated host allowlist entries." },
871985
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /mcp add with --yes." }
871986
- ]
871987
- };
871988
- }
871989
- if (kind2 === "notify-webhook") {
871990
- return {
871991
- kind: kind2,
871992
- mode: "create",
871993
- title: "Add Notification Webhook",
871994
- selectedFieldIndex: 0,
871995
- message: "Add one webhook notification target for explicit reminder/routine delivery. Type yes on the final field to confirm.",
871996
- fields: [
871997
- { id: "url", label: "Webhook URL", value: "", required: true, multiline: false, hint: "HTTP(S) target, for example https://ntfy.sh/my-topic." },
871998
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /notify add with --yes." }
871999
- ]
872000
- };
872001
- }
872002
- if (kind2 === "notify-webhook-remove") {
872003
- return {
872004
- kind: kind2,
872005
- mode: "delete",
872006
- title: "Remove Notification Webhook",
872007
- selectedFieldIndex: 0,
872008
- message: "Remove one configured webhook notification target. Type yes on the final field to confirm.",
872009
- fields: [
872010
- { id: "url", label: "Webhook URL", value: "", required: true, multiline: false, hint: "Exact HTTP(S) webhook URL to remove from configured notification targets." },
872011
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /notify remove with --yes." }
872012
- ]
872013
- };
872014
- }
872015
- if (kind2 === "notify-webhook-test") {
872016
- return {
872017
- kind: kind2,
872018
- mode: "create",
872019
- title: "Test Notification Webhooks",
872020
- selectedFieldIndex: 0,
872021
- message: "Send one test notification to configured webhook targets. Type yes on the final field to confirm.",
872022
- fields: [
872023
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /notify test with --yes." }
872024
- ]
872025
- };
872026
- }
872027
- if (kind2 === "tts-prompt") {
872028
- return {
872029
- kind: kind2,
872030
- mode: "create",
872031
- title: "Speak Assistant Reply",
872032
- selectedFieldIndex: 0,
872033
- message: "Submit a normal assistant prompt and play the reply through configured live TTS.",
872034
- fields: [
872035
- { id: "prompt", label: "Prompt", value: "", required: true, multiline: true, hint: "Assistant prompt to speak. Ctrl-J inserts a new line." }
872036
- ]
872037
- };
872038
- }
872039
- if (kind2 === "image-input") {
872040
- return {
872041
- kind: kind2,
872042
- mode: "create",
872043
- title: "Attach Image Input",
872044
- selectedFieldIndex: 0,
872045
- message: "Attach an image to the next assistant turn. The existing image command validates file type and model support.",
872046
- fields: [
872047
- { id: "path", label: "Image path", value: "", required: true, multiline: false, hint: "PNG, JPEG, WebP, or GIF path under the current workspace." },
872048
- { id: "prompt", label: "Prompt", value: "", required: false, multiline: true, hint: "Optional prompt. Ctrl-J inserts a new line." }
872049
- ]
872050
- };
872051
- }
872052
- if (kind2 === "profile-template-export") {
872053
- return {
872054
- kind: kind2,
872055
- mode: "create",
872056
- title: "Export Agent Starter Template",
872057
- selectedFieldIndex: 0,
872058
- message: "Export a starter template JSON file for review and customization. Type yes on the final field to confirm.",
872059
- fields: [
872060
- { id: "templateId", label: "Starter id", value: "", required: true, multiline: false, hint: "Existing starter id from /agent-profile templates." },
872061
- { id: "path", label: "Output path", value: "", required: true, multiline: false, hint: "Workspace-relative JSON path to write." },
872062
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-profile template export with --yes." }
872063
- ]
872064
- };
872065
- }
872066
- if (kind2 === "profile-template-import") {
872067
- return {
872068
- kind: kind2,
872069
- mode: "create",
872070
- title: "Import Agent Starter Template",
872071
- selectedFieldIndex: 0,
872072
- message: "Import a reviewed starter template JSON file into this Agent home. Type yes on the final field to confirm.",
872073
- fields: [
872074
- { id: "path", label: "Template path", value: "", required: true, multiline: false, hint: "Workspace-relative JSON path to import." },
872075
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-profile template import with --yes." }
872076
- ]
872077
- };
872078
- }
872079
- if (kind2 === "skill-discovery-import") {
872080
- return {
872081
- kind: kind2,
872082
- mode: "create",
872083
- title: "Import Discovered Skill",
872084
- selectedFieldIndex: 0,
872085
- message: "Import one discovered SKILL.md or .md skill file into the Agent-local skill registry. Type yes on the final field to confirm.",
872086
- fields: [
872087
- { id: "name", label: "Discovered skill", value: "", required: true, multiline: false, hint: "Name shown by /agent-skills discover." },
872088
- { id: "enabled", label: "Enable now", value: "yes", required: false, multiline: false, hint: "yes/no." },
872089
- { id: "confirm", label: "Confirm", value: "", required: true, multiline: false, hint: "Type yes to run /agent-skills import-discovered with --yes." }
872090
- ]
872091
- };
872092
- }
872093
- return {
872094
- kind: kind2,
872095
- mode: "create",
872096
- title: "Create Skill Bundle",
872097
- selectedFieldIndex: 0,
872098
- message: "Group existing local skills into a reviewable bundle that can be enabled together.",
872099
- fields: [
872100
- { id: "name", label: "Bundle name", value: "", required: true, multiline: false, hint: "Short bundle name." },
872101
- { id: "description", label: "Description", value: "", required: true, multiline: false, hint: "One-line bundle summary." },
872102
- { id: "skills", label: "Skill ids", value: "", required: true, multiline: false, hint: "Comma-separated existing local skill ids." },
872103
- { id: "enabled", label: "Enable now", value: "yes", required: false, multiline: false, hint: "yes/no." }
872104
- ]
872105
- };
872106
- }
872107
872592
  function buildAgentWorkspaceBasicCommandEditorSubmission(editor, readField, commandDispatchAvailable) {
872108
872593
  if (!commandDispatchAvailable) {
872109
872594
  return {
@@ -872430,6 +872915,100 @@ function buildAgentWorkspaceBasicCommandEditorSubmission(editor, readField, comm
872430
872915
  }
872431
872916
  };
872432
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
+ }
872433
873012
  if (editor.kind === "skill-discovery-import") {
872434
873013
  if (!isAffirmative2(readField("confirm"))) {
872435
873014
  return {
@@ -872460,6 +873039,66 @@ function buildAgentWorkspaceBasicCommandEditorSubmission(editor, readField, comm
872460
873039
  }
872461
873040
  };
872462
873041
  }
873042
+ if (editor.kind === "persona-discovery-import") {
873043
+ if (!isAffirmative2(readField("confirm"))) {
873044
+ return {
873045
+ kind: "editor",
873046
+ editor: { ...editor, message: "Discovered persona import not confirmed. Type yes, then press Enter." },
873047
+ status: "Agent persona import not confirmed."
873048
+ };
873049
+ }
873050
+ const parts2 = [
873051
+ "/personas",
873052
+ "import-discovered",
873053
+ quoteSlashCommandArg(readField("name"))
873054
+ ];
873055
+ if (isAffirmative2(readField("use")))
873056
+ parts2.push("--use");
873057
+ parts2.push("--yes");
873058
+ const command9 = parts2.join(" ");
873059
+ return {
873060
+ kind: "dispatch",
873061
+ command: command9,
873062
+ status: "Opening discovered persona import.",
873063
+ actionResult: {
873064
+ kind: "dispatched",
873065
+ title: "Opening discovered persona import",
873066
+ detail: "The workspace handed a confirmed local persona import command to the shell-owned command router.",
873067
+ command: command9,
873068
+ safety: "safe"
873069
+ }
873070
+ };
873071
+ }
873072
+ if (editor.kind === "routine-discovery-import") {
873073
+ if (!isAffirmative2(readField("confirm"))) {
873074
+ return {
873075
+ kind: "editor",
873076
+ editor: { ...editor, message: "Discovered routine import not confirmed. Type yes, then press Enter." },
873077
+ status: "Agent routine import not confirmed."
873078
+ };
873079
+ }
873080
+ const parts2 = [
873081
+ "/routines",
873082
+ "import-discovered",
873083
+ quoteSlashCommandArg(readField("name"))
873084
+ ];
873085
+ if (isAffirmative2(readField("enabled")))
873086
+ parts2.push("--enabled");
873087
+ parts2.push("--yes");
873088
+ const command9 = parts2.join(" ");
873089
+ return {
873090
+ kind: "dispatch",
873091
+ command: command9,
873092
+ status: "Opening discovered routine import.",
873093
+ actionResult: {
873094
+ kind: "dispatched",
873095
+ title: "Opening discovered routine import",
873096
+ detail: "The workspace handed a confirmed local routine import command to the shell-owned command router.",
873097
+ command: command9,
873098
+ safety: "safe"
873099
+ }
873100
+ };
873101
+ }
872463
873102
  const commandParts = [
872464
873103
  "/agent-skills bundle create",
872465
873104
  "--name",
@@ -872486,6 +873125,280 @@ function buildAgentWorkspaceBasicCommandEditorSubmission(editor, readField, comm
872486
873125
  };
872487
873126
  }
872488
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
+
872489
873402
  // src/input/agent-workspace-knowledge-query-editor.ts
872490
873403
  function createAgentKnowledgeQueryEditor(mode) {
872491
873404
  return {
@@ -872909,6 +873822,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
872909
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" },
872910
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" },
872911
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" },
872912
873826
  { id: "setup-personas", label: "Personas", detail: "Create or select the active local Agent persona.", targetCategoryId: "personas", kind: "workspace", safety: "safe" },
872913
873827
  { id: "setup-skills", label: "Skills", detail: "Create, review, and enable reusable local Agent skills.", targetCategoryId: "skills", kind: "workspace", safety: "safe" },
872914
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" },
@@ -873000,6 +873914,8 @@ var AGENT_WORKSPACE_CATEGORIES = [
873000
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" },
873001
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" },
873002
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" },
873003
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" },
873004
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" },
873005
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" }
@@ -873034,6 +873950,8 @@ var AGENT_WORKSPACE_CATEGORIES = [
873034
873950
  actions: [
873035
873951
  { id: "personas-list", label: "List personas", detail: "Print the full local persona library.", command: "/personas list", kind: "command", safety: "read-only" },
873036
873952
  { id: "personas-active", label: "Show active persona", detail: "Inspect the active local persona applied to new turns.", command: "/personas active", kind: "command", safety: "read-only" },
873953
+ { id: "personas-discover", label: "Discover persona files", detail: "Scan project and global Agent persona folders for persona markdown without importing it.", command: "/personas discover", kind: "command", safety: "read-only" },
873954
+ { id: "personas-import-discovered", label: "Import discovered persona", detail: "Open an in-workspace form that imports one reviewed persona markdown file into the Agent-local persona registry after typed confirmation.", editorKind: "persona-discovery-import", kind: "editor", safety: "safe" },
873037
873955
  { id: "personas-prev", label: "Previous persona", detail: "Move the local persona selection up without changing active state.", localKind: "persona", selectionDelta: -1, kind: "local-selection", safety: "safe" },
873038
873956
  { id: "personas-next", label: "Next persona", detail: "Move the local persona selection down without changing active state.", localKind: "persona", selectionDelta: 1, kind: "local-selection", safety: "safe" },
873039
873957
  { id: "personas-create", label: "Create persona", detail: "Open an in-workspace form for a local persona that writes Agent-local state only.", editorKind: "persona", kind: "editor", safety: "safe" },
@@ -873076,6 +873994,8 @@ var AGENT_WORKSPACE_CATEGORIES = [
873076
873994
  actions: [
873077
873995
  { id: "routines-list", label: "List routines", detail: "Print the full local Agent routine library.", command: "/routines list", kind: "command", safety: "read-only" },
873078
873996
  { id: "routines-enabled", label: "Enabled routines", detail: "Show routines available for direct use.", command: "/routines enabled", kind: "command", safety: "read-only" },
873997
+ { id: "routines-discover", label: "Discover routine files", detail: "Scan project and global Agent routine folders for routine markdown without importing it.", command: "/routines discover", kind: "command", safety: "read-only" },
873998
+ { id: "routines-import-discovered", label: "Import discovered routine", detail: "Open an in-workspace form that imports one reviewed routine markdown file into the Agent-local routine registry after typed confirmation.", editorKind: "routine-discovery-import", kind: "editor", safety: "safe" },
873079
873999
  { id: "routines-prev", label: "Previous routine", detail: "Move the local routine selection up without changing enabled state.", localKind: "routine", selectionDelta: -1, kind: "local-selection", safety: "safe" },
873080
874000
  { id: "routines-next", label: "Next routine", detail: "Move the local routine selection down without changing enabled state.", localKind: "routine", selectionDelta: 1, kind: "local-selection", safety: "safe" },
873081
874001
  { id: "routines-create", label: "Create routine", detail: "Open an in-workspace form for a repeatable local workflow that writes Agent-local state only.", editorKind: "routine", kind: "editor", safety: "safe" },
@@ -874503,6 +875423,33 @@ function getOnboardingWizardVisibleFieldCount(viewportHeight) {
874503
875423
  }
874504
875424
 
874505
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
+ }
874506
875453
  function buildCommunicationStep() {
874507
875454
  return {
874508
875455
  id: "agent-communication",
@@ -874628,15 +875575,17 @@ function buildAgentKnowledgeStep() {
874628
875575
  ]
874629
875576
  };
874630
875577
  }
874631
- function buildLocalStateStep() {
875578
+ function buildLocalStateStep(discovery) {
875579
+ const discoveredCount = discoveryCount(discovery);
874632
875580
  return {
874633
875581
  id: "agent-local-state",
874634
875582
  title: "Local memory and behavior",
874635
- shortLabel: "Memory",
874636
- 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.",
874637
875585
  summaryTitle: "Local Agent state",
874638
875586
  summaryLines: [
874639
875587
  "Memory/personas/skills/routines: local Agent registries",
875588
+ `Discovered behavior files: ${discoverySummary(discovery)}`,
874640
875589
  "Secrets: rejected or stored by secret reference",
874641
875590
  "Profiles: isolated Agent homes"
874642
875591
  ],
@@ -874652,22 +875601,22 @@ function buildLocalStateStep() {
874652
875601
  kind: "status",
874653
875602
  id: "agent-local-state.personas",
874654
875603
  label: "Personas",
874655
- hint: "Use /personas to create and activate serial operating modes for the main conversation.",
874656
- 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"
874657
875606
  },
874658
875607
  {
874659
875608
  kind: "status",
874660
875609
  id: "agent-local-state.skills",
874661
875610
  label: "Skills",
874662
- hint: "Use /agent-skills and /skills local to manage reusable Agent procedures.",
874663
- 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"
874664
875613
  },
874665
875614
  {
874666
875615
  kind: "status",
874667
875616
  id: "agent-local-state.routines",
874668
875617
  label: "Routines",
874669
- hint: "Use /routines for reusable local procedures. Starting a routine prints steps in the main conversation and does not spawn hidden work.",
874670
- 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"
874671
875620
  }
874672
875621
  ]
874673
875622
  };
@@ -874816,7 +875765,7 @@ function buildOnboardingWizardSteps(controller) {
874816
875765
  buildCommunicationStep(),
874817
875766
  buildToolsStep(),
874818
875767
  buildAgentKnowledgeStep(),
874819
- buildLocalStateStep(),
875768
+ buildLocalStateStep(controller.runtimeSnapshot?.localBehaviorDiscovery),
874820
875769
  buildAutomationStep(),
874821
875770
  buildVoiceMediaStep(),
874822
875771
  buildDelegationPolicyStep(),
@@ -877329,7 +878278,7 @@ function handleProfilePickerToken(state4, token) {
877329
878278
  }
877330
878279
 
877331
878280
  // src/input/handler-picker-routes.ts
877332
- import { readFileSync as readFileSync86 } from "fs";
878281
+ import { readFileSync as readFileSync87 } from "fs";
877333
878282
 
877334
878283
  // src/renderer/model-picker-overlay.ts
877335
878284
  var MODEL_PICKER_CHROME_LINES = 7;
@@ -877621,7 +878570,7 @@ function handleFilePickerToken(state4, token) {
877621
878570
  throw new Error("working directory is unavailable");
877622
878571
  }
877623
878572
  const resolvedPath3 = resolveAndValidatePath(selected, projectRoot);
877624
- const data = readFileSync86(resolvedPath3);
878573
+ const data = readFileSync87(resolvedPath3);
877625
878574
  const base644 = data.toString("base64");
877626
878575
  const mediaType = state4.mediaTypeFromExt(ext);
877627
878576
  const filename = selected.split("/").pop() ?? selected;
@@ -881121,6 +882070,29 @@ function setupChecklistLines(snapshot2) {
881121
882070
  }
881122
882071
  return lines;
881123
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
+ }
881124
882096
  function localLibraryLines(title, items, emptyText, selectedId) {
881125
882097
  const lines = [
881126
882098
  { text: title, fg: FULLSCREEN_PALETTE.title, bold: true }
@@ -881201,7 +882173,7 @@ function snapshotLines(workspace, category, snapshot2) {
881201
882173
  if (category.id === "home") {
881202
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 });
881203
882175
  } else if (category.id === "setup") {
881204
- 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 });
881205
882177
  } else if (category.id === "channels") {
881206
882178
  const enabledCount = snapshot2.channels.filter((channel) => channel.enabled).length;
881207
882179
  const readyCount = snapshot2.channels.filter((channel) => channel.ready).length;
@@ -883063,7 +884035,7 @@ function wireShellUiOpeners(options) {
883063
884035
 
883064
884036
  // src/cli/entrypoint.ts
883065
884037
  import { existsSync as existsSync85 } from "fs";
883066
- import { join as join99 } from "path";
884038
+ import { join as join102 } from "path";
883067
884039
  // src/cli/parser.ts
883068
884040
  var COMMAND_ALIASES = {
883069
884041
  run: "run",
@@ -883427,14 +884399,14 @@ function parseGoodVibesCli(argv, binary2 = "goodvibes-agent") {
883427
884399
  };
883428
884400
  }
883429
884401
  // src/cli/help.ts
883430
- import { existsSync as existsSync79, readFileSync as readFileSync87 } from "fs";
883431
- import { dirname as dirname63, join as join92 } from "path";
884402
+ import { existsSync as existsSync79, readFileSync as readFileSync88 } from "fs";
884403
+ import { dirname as dirname63, join as join95 } from "path";
883432
884404
  import { fileURLToPath as fileURLToPath4 } from "url";
883433
884405
  function readJsonVersion(path7) {
883434
884406
  try {
883435
884407
  if (!existsSync79(path7))
883436
884408
  return null;
883437
- const parsed = JSON.parse(readFileSync87(path7, "utf-8"));
884409
+ const parsed = JSON.parse(readFileSync88(path7, "utf-8"));
883438
884410
  return typeof parsed.version === "string" ? parsed.version : null;
883439
884411
  } catch {
883440
884412
  return null;
@@ -883442,7 +884414,7 @@ function readJsonVersion(path7) {
883442
884414
  }
883443
884415
  function getPackageVersion() {
883444
884416
  const here = dirname63(fileURLToPath4(import.meta.url));
883445
- return readJsonVersion(join92(here, "..", "..", "package.json")) ?? VERSION;
884417
+ return readJsonVersion(join95(here, "..", "..", "package.json")) ?? VERSION;
883446
884418
  }
883447
884419
  function renderGoodVibesVersion(binary2 = "goodvibes-agent") {
883448
884420
  return `${binary2} ${getPackageVersion()}`;
@@ -883574,14 +884546,16 @@ var COMMAND_HELP = {
883574
884546
  examples: ["providers", "providers inspect openai-subscriber", "providers use openai openai:gpt-5.4"]
883575
884547
  },
883576
884548
  profiles: {
883577
- 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>"],
883578
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.",
883579
- 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"]
883580
884552
  },
883581
884553
  personas: {
883582
884554
  usage: [
883583
884555
  "personas list",
883584
884556
  "personas active",
884557
+ "personas discover",
884558
+ "personas import-discovered <name> [--use] --yes",
883585
884559
  "personas search <query>",
883586
884560
  "personas show <id>",
883587
884561
  "personas create --name <name> --description <summary> --body <instructions> [--tags a,b] [--triggers a,b] [--use]",
@@ -883595,6 +884569,8 @@ var COMMAND_HELP = {
883595
884569
  summary: "Manage Agent-local personas for the serial main conversation. Personas do not spawn worker agents.",
883596
884570
  examples: [
883597
884571
  "personas list",
884572
+ "personas discover",
884573
+ 'personas import-discovered "Travel Planner" --use --yes',
883598
884574
  'personas create --name "Travel Planner" --description "Plan trips" --body "Compare options before booking" --use',
883599
884575
  "personas review travel-planner",
883600
884576
  "personas delete travel-planner --yes"
@@ -883660,15 +884636,19 @@ var COMMAND_HELP = {
883660
884636
  usage: [
883661
884637
  "routines list",
883662
884638
  "routines enabled",
884639
+ "routines discover",
884640
+ "routines import-discovered <name> [--enabled] --yes",
883663
884641
  "routines show <id>",
883664
884642
  "routines receipts",
883665
884643
  "routines reconcile",
883666
884644
  "routines receipt <receipt-id>",
883667
884645
  "routines promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--timezone <tz>] [--name <schedule-name>] [--provider <id>] [--model <model>] [--delivery-channel <channel[:route[:label]]>|--delivery-route <route[:label]>|--delivery-webhook <url>|--delivery-link <url>] [--disabled] --yes"
883668
884646
  ],
883669
- summary: "Inspect Agent-local routines, review local promotion receipts, reconcile receipts against live connected schedules, and explicitly promote a reviewed routine into a GoodVibes schedule. Without --yes, promote only prints the schedules.create preview.",
884647
+ summary: "Inspect and import Agent-local routines, review local promotion receipts, reconcile receipts against live connected schedules, and explicitly promote a reviewed routine into a GoodVibes schedule. Without --yes, promote only prints the schedules.create preview.",
883670
884648
  examples: [
883671
884649
  "routines list",
884650
+ "routines discover",
884651
+ 'routines import-discovered "Daily Brief" --enabled --yes',
883672
884652
  "routines show daily-operations-sweep",
883673
884653
  "routines receipts",
883674
884654
  "routines reconcile",
@@ -884174,8 +885154,8 @@ function renderOnboardingCliStatus(options) {
884174
885154
  `);
884175
885155
  }
884176
885156
  // src/cli/external-runtime.ts
884177
- import { existsSync as existsSync80, readFileSync as readFileSync88 } from "fs";
884178
- import { join as join93 } from "path";
885157
+ import { existsSync as existsSync80, readFileSync as readFileSync89 } from "fs";
885158
+ import { join as join96 } from "path";
884179
885159
  function isRecord29(value) {
884180
885160
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
884181
885161
  }
@@ -884189,11 +885169,11 @@ function resolveBaseUrl2(configManager) {
884189
885169
  return `http://${host}:${Number.isFinite(port) ? port : 3421}`;
884190
885170
  }
884191
885171
  function readOperatorToken(homeDirectory) {
884192
- const path7 = join93(homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
885172
+ const path7 = join96(homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
884193
885173
  if (!existsSync80(path7))
884194
885174
  return { token: null, path: path7 };
884195
885175
  try {
884196
- const parsed = JSON.parse(readFileSync88(path7, "utf-8"));
885176
+ const parsed = JSON.parse(readFileSync89(path7, "utf-8"));
884197
885177
  const token = isRecord29(parsed) && typeof parsed.token === "string" ? parsed.token : null;
884198
885178
  return { token, path: path7 };
884199
885179
  } catch {
@@ -884566,8 +885546,8 @@ function applyRuntimeCommandEndpointFlagOverrides(configManager, command8, flags
884566
885546
  return [];
884567
885547
  }
884568
885548
  // src/cli/bundle-command.ts
884569
- import { existsSync as existsSync82, mkdirSync as mkdirSync65, readFileSync as readFileSync89, writeFileSync as writeFileSync56 } from "fs";
884570
- import { dirname as dirname64, join as join95 } from "path";
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";
884571
885551
 
884572
885552
  // src/cli/provider-classification.ts
884573
885553
  var SUBSCRIPTION_PROVIDERS = new Set([
@@ -884658,7 +885638,7 @@ function classifyProviderSetup(input) {
884658
885638
  // src/cli/service-posture.ts
884659
885639
  import { closeSync as closeSync4, existsSync as existsSync81, openSync as openSync4, readSync as readSync2, statSync as statSync21 } from "fs";
884660
885640
  import net3 from "net";
884661
- import { isAbsolute as isAbsolute13, join as join94 } from "path";
885641
+ import { isAbsolute as isAbsolute13, join as join97 } from "path";
884662
885642
 
884663
885643
  // src/cli/redaction.ts
884664
885644
  var REDACTED_VALUE = "<redacted>";
@@ -884828,7 +885808,7 @@ function resolveConfiguredLogPath(runtime3) {
884828
885808
  const trimmed2 = value.trim();
884829
885809
  if (!trimmed2)
884830
885810
  return;
884831
- return isAbsolute13(trimmed2) ? trimmed2 : join94(runtime3.homeDirectory, trimmed2);
885811
+ return isAbsolute13(trimmed2) ? trimmed2 : join97(runtime3.homeDirectory, trimmed2);
884832
885812
  }
884833
885813
  function createExternalDaemonLifecycle(logPath) {
884834
885814
  return {
@@ -884914,7 +885894,7 @@ function getNestedValue(source, key) {
884914
885894
  }
884915
885895
  function readJsonFile2(path7) {
884916
885896
  try {
884917
- return { ok: true, value: JSON.parse(readFileSync89(path7, "utf-8")) };
885897
+ return { ok: true, value: JSON.parse(readFileSync90(path7, "utf-8")) };
884918
885898
  } catch (error51) {
884919
885899
  return { ok: false, error: error51 instanceof Error ? error51.message : String(error51) };
884920
885900
  }
@@ -884937,7 +885917,7 @@ function readAuthPosture(runtime3) {
884937
885917
  });
884938
885918
  const userStorePath = shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
884939
885919
  const bootstrapCredentialPath = shellPaths.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
884940
- const operatorTokenPath = join95(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
885920
+ const operatorTokenPath = join98(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
884941
885921
  return {
884942
885922
  userStorePath,
884943
885923
  userStorePresent: existsSync82(userStorePath),
@@ -885097,7 +886077,7 @@ async function handleBundleCommand(runtime3) {
885097
886077
  }
885098
886078
  // src/cli/management.ts
885099
886079
  import { existsSync as existsSync84 } from "fs";
885100
- import { join as join98 } from "path";
886080
+ import { join as join101 } from "path";
885101
886081
  import { spawn as spawn5 } from "child_process";
885102
886082
  import { networkInterfaces as networkInterfaces4 } from "os";
885103
886083
 
@@ -885124,7 +886104,7 @@ function formatProviderAuthRoute(route) {
885124
886104
 
885125
886105
  // src/cli/management-commands.ts
885126
886106
  import { mkdirSync as mkdirSync66, writeFileSync as writeFileSync57 } from "fs";
885127
- import { dirname as dirname65, join as join96 } from "path";
886107
+ import { dirname as dirname65, join as join99 } from "path";
885128
886108
  init_config8();
885129
886109
  init_config8();
885130
886110
  init_config8();
@@ -885441,7 +886421,7 @@ async function handleTasks(runtime3) {
885441
886421
  });
885442
886422
  }
885443
886423
  async function renderPairing(runtime3) {
885444
- const daemonHomeDir = join96(runtime3.homeDirectory, ".goodvibes", "daemon");
886424
+ const daemonHomeDir = join99(runtime3.homeDirectory, ".goodvibes", "daemon");
885445
886425
  const tokenRecord = getOrCreateCompanionToken(GOODVIBES_AGENT_PAIRING_SURFACE, { daemonHomeDir });
885446
886426
  const binding = resolveRuntimeEndpointBinding(runtime3.configManager, "controlPlane");
885447
886427
  const daemonUrl = `http://${urlHostForBindHost2(binding.host)}:${binding.port}`;
@@ -885979,8 +886959,8 @@ var DELEGATION_METHOD = {
885979
886959
  };
885980
886960
 
885981
886961
  // src/cli/agent-knowledge-runtime.ts
885982
- import { existsSync as existsSync83, readFileSync as readFileSync90 } from "fs";
885983
- import { join as join97 } from "path";
886962
+ import { existsSync as existsSync83, readFileSync as readFileSync91 } from "fs";
886963
+ import { join as join100 } from "path";
885984
886964
 
885985
886965
  // node_modules/@pellux/goodvibes-sdk/dist/browser-scoped.js
885986
886966
  init_dist();
@@ -886346,11 +887326,11 @@ function resolveDaemonConnection(runtime3) {
886346
887326
  const host = String(runtime3.configManager.get("controlPlane.host") ?? "127.0.0.1");
886347
887327
  const port = Number(runtime3.configManager.get("controlPlane.port") ?? 3421);
886348
887328
  const baseUrl = `http://${host}:${Number.isFinite(port) ? port : 3421}`;
886349
- const tokenPath = join97(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
887329
+ const tokenPath = join100(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
886350
887330
  if (!existsSync83(tokenPath))
886351
887331
  return { baseUrl, token: null, tokenPath };
886352
887332
  try {
886353
- const parsed = JSON.parse(readFileSync90(tokenPath, "utf-8"));
887333
+ const parsed = JSON.parse(readFileSync91(tokenPath, "utf-8"));
886354
887334
  const token = isRecord31(parsed) && typeof parsed.token === "string" ? parsed.token : null;
886355
887335
  return { baseUrl, token, tokenPath };
886356
887336
  } catch {
@@ -887132,6 +888112,48 @@ function renderPersona2(persona, activePersonaId) {
887132
888112
  ].filter((line2) => Boolean(line2)).join(`
887133
888113
  `);
887134
888114
  }
888115
+ function summarizeDiscoveredPersona2(persona) {
888116
+ const description = persona.description ? ` - ${persona.description}` : "";
888117
+ return [
888118
+ ` ${persona.name} ${persona.origin}${description}`,
888119
+ ` path: ${persona.path}`
888120
+ ].join(`
888121
+ `);
888122
+ }
888123
+ function renderDiscoveredPersonaList(personas) {
888124
+ if (personas.length === 0) {
888125
+ return [
888126
+ "Discovered Agent persona files",
888127
+ " No persona markdown files found in Agent persona folders.",
888128
+ " Search roots: .goodvibes/personas, .goodvibes/agent/personas, .goodvibes/agents, ~/.goodvibes/personas, ~/.goodvibes/agent/personas, ~/.goodvibes/agents"
888129
+ ].join(`
888130
+ `);
888131
+ }
888132
+ return [
888133
+ `Discovered Agent persona files (${personas.length})`,
888134
+ ...personas.map(summarizeDiscoveredPersona2),
888135
+ "",
888136
+ "Import one with: goodvibes-agent personas import-discovered <name> --yes"
888137
+ ].join(`
888138
+ `);
888139
+ }
888140
+ function discoveredPersonaLookupValues2(persona) {
888141
+ const slug = persona.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
888142
+ const basename6 = persona.path.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
888143
+ return [persona.name, slug, persona.path, basename6].map((value) => value.trim().toLowerCase()).filter(Boolean);
888144
+ }
888145
+ function findDiscoveredPersona2(personas, idOrName) {
888146
+ const lookup = idOrName.trim().toLowerCase();
888147
+ if (!lookup)
888148
+ return null;
888149
+ return personas.find((persona) => discoveredPersonaLookupValues2(persona).includes(lookup)) ?? null;
888150
+ }
888151
+ function discoveredPersonaFrontmatterList(persona, key) {
888152
+ const value = persona.frontmatter[key];
888153
+ if (!value)
888154
+ return [];
888155
+ return value.split(",").map((entry) => entry.trim()).filter(Boolean);
888156
+ }
887135
888157
  function summarizeSkill2(skill) {
887136
888158
  const enabled = skill.enabled ? "enabled" : "disabled";
887137
888159
  const tags = skill.tags.length > 0 ? ` tags=${skill.tags.join(",")}` : "";
@@ -887255,7 +888277,7 @@ function renderBundle2(bundle) {
887255
888277
  `);
887256
888278
  }
887257
888279
  function usagePersonas() {
887258
- return "Usage: goodvibes-agent personas [list|active|search <query>|show <id>|create|update <id>|use <id>|clear|review <id>|stale <id> <reason>|delete <id> --yes]";
888280
+ return "Usage: goodvibes-agent personas [list|active|discover|import-discovered <name> --yes|search <query>|show <id>|create|update <id>|use <id>|clear|review <id>|stale <id> <reason>|delete <id> --yes]";
887259
888281
  }
887260
888282
  function usageSkills() {
887261
888283
  return "Usage: goodvibes-agent skills [list|enabled|active|discover|import-discovered <name> --yes|search <query>|show <id>|create|update <id>|enable <id>|disable <id>|review <id>|stale <id> <reason>|delete <id> --yes|bundle ...]";
@@ -887284,6 +888306,45 @@ async function handlePersonasCommand(runtime3) {
887284
888306
  return failure(runtime3, "agent.personas.active_missing", "No active Agent persona.", 1);
887285
888307
  return success3(runtime3, "agent.personas.active", active, renderPersona2(active, active.id));
887286
888308
  }
888309
+ if (normalized === "discover") {
888310
+ const discovered = await discoverPersonas(shellPaths(runtime3));
888311
+ return success3(runtime3, "agent.personas.discover", { personas: discovered }, renderDiscoveredPersonaList(discovered));
888312
+ }
888313
+ if (normalized === "import-discovered" || normalized === "import-persona") {
888314
+ const options = parseOptions(rest);
888315
+ const name51 = options.positionals.join(" ").trim();
888316
+ if (!name51)
888317
+ return failure(runtime3, "invalid_persona_command", "Usage: goodvibes-agent personas import-discovered <name> [--use] --yes", 2);
888318
+ const discovered = findDiscoveredPersona2(await discoverPersonas(shellPaths(runtime3)), name51);
888319
+ if (!discovered) {
888320
+ return failure(runtime3, "persona_discovery_not_found", `Unknown discovered Agent persona: ${name51}
888321
+ Run goodvibes-agent personas discover to inspect available persona files.`, 1);
888322
+ }
888323
+ if (!hasFlag3(options, "yes")) {
888324
+ return success3(runtime3, "agent.personas.import_discovered.preview", { persona: discovered }, [
888325
+ "Agent persona import preview",
888326
+ ` name: ${discovered.name}`,
888327
+ ` origin: ${discovered.origin}`,
888328
+ ` path: ${discovered.path}`,
888329
+ ` description: ${discovered.description || "(none)"}`,
888330
+ ` body characters: ${discovered.body.length}`,
888331
+ " next: rerun with --yes to import into the Agent-local persona registry"
888332
+ ].join(`
888333
+ `));
888334
+ }
888335
+ const persona = registry5.create({
888336
+ name: discovered.name,
888337
+ description: discovered.description || `Imported persona from ${discovered.origin} markdown file.`,
888338
+ body: discovered.body,
888339
+ tags: discoveredPersonaFrontmatterList(discovered, "tags"),
888340
+ triggers: discoveredPersonaFrontmatterList(discovered, "triggers"),
888341
+ source: "imported",
888342
+ provenance: `discovered:${discovered.origin}:${discovered.path}`
888343
+ });
888344
+ if (hasFlag3(options, "use"))
888345
+ registry5.setActive(persona.id);
888346
+ return success3(runtime3, "agent.personas.import_discovered", persona, `Imported Agent persona ${persona.id}: ${persona.name}${hasFlag3(options, "use") ? " (active)" : ""}`);
888347
+ }
887287
888348
  if (normalized === "search" || normalized === "find") {
887288
888349
  const query2 = rest.join(" ").trim();
887289
888350
  const results = registry5.search(query2);
@@ -887597,7 +888658,7 @@ Run goodvibes-agent skills discover to inspect available skill files.`, 1);
887597
888658
  }
887598
888659
 
887599
888660
  // src/cli/memory-command.ts
887600
- import { mkdirSync as mkdirSync67, readFileSync as readFileSync91, writeFileSync as writeFileSync58 } from "fs";
888661
+ import { mkdirSync as mkdirSync67, readFileSync as readFileSync92, writeFileSync as writeFileSync58 } from "fs";
887601
888662
  import { dirname as dirname66, resolve as resolve40 } from "path";
887602
888663
  init_state3();
887603
888664
  var VALID_CLASSES2 = ["decision", "constraint", "incident", "pattern", "fact", "risk", "runbook", "architecture", "ownership"];
@@ -887877,7 +888938,7 @@ function isMemoryBundle(value) {
887877
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);
887878
888939
  }
887879
888940
  function readBundle(path7) {
887880
- const parsed = JSON.parse(readFileSync91(path7, "utf-8"));
888941
+ const parsed = JSON.parse(readFileSync92(path7, "utf-8"));
887881
888942
  if (!isMemoryBundle(parsed))
887882
888943
  throw new Error("Invalid Agent memory bundle.");
887883
888944
  for (const record2 of parsed.records) {
@@ -888200,6 +889261,12 @@ function parseTemplate(args2) {
888200
889261
  return normalized;
888201
889262
  throw new Error(`Unknown Agent starter profile template: ${raw}. Use profiles templates to list starters.`);
888202
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
+ }
888203
889270
  function profileLine2(profile5) {
888204
889271
  const created = profile5.createdAt ? ` created=${profile5.createdAt}` : "";
888205
889272
  const starter = profile5.starterTemplateId ? ` starter=${profile5.starterTemplateId}` : "";
@@ -888250,6 +889317,29 @@ function renderProfilesResult(result2) {
888250
889317
  ` source: ${result2.data.template.source}`,
888251
889318
  ` use: goodvibes-agent profiles create <name> --template ${result2.data.template.id} --yes`
888252
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(`
888253
889343
  `);
888254
889344
  }
888255
889345
  const profile5 = result2.data?.profile;
@@ -888293,6 +889383,51 @@ async function handleProfilesCommand(runtime3) {
888293
889383
  }
888294
889384
  if (sub === "templates" || sub === "starters") {
888295
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
+ }
888296
889431
  if (templateAction === "export") {
888297
889432
  if (!templateId || !templatePath) {
888298
889433
  const result5 = {
@@ -888439,6 +889574,58 @@ async function handleProfilesCommand(runtime3) {
888439
889574
  exitCode: 0
888440
889575
  };
888441
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
+ }
888442
889629
  if (sub === "delete" || sub === "remove") {
888443
889630
  const name51 = values2[0];
888444
889631
  if (!name51) {
@@ -888511,17 +889698,87 @@ function routineRegistry(runtime3) {
888511
889698
  homeDirectory: runtime3.homeDirectory
888512
889699
  }));
888513
889700
  }
889701
+ function shellPaths2(runtime3) {
889702
+ return createShellPathService2({
889703
+ workingDirectory: runtime3.workingDirectory,
889704
+ homeDirectory: runtime3.homeDirectory
889705
+ });
889706
+ }
888514
889707
  function routineReceiptStore(runtime3) {
888515
889708
  return RoutineScheduleReceiptStore.fromShellPaths(createShellPathService2({
888516
889709
  workingDirectory: runtime3.workingDirectory,
888517
889710
  homeDirectory: runtime3.homeDirectory
888518
889711
  }));
888519
889712
  }
889713
+ function splitList6(value) {
889714
+ if (!value)
889715
+ return [];
889716
+ return value.split(",").map((entry) => entry.trim()).filter(Boolean);
889717
+ }
889718
+ function parseImportFlags(args2) {
889719
+ const positionals = [];
889720
+ let enabled = false;
889721
+ let yes = false;
889722
+ for (const arg of args2) {
889723
+ if (arg === "--enabled") {
889724
+ enabled = true;
889725
+ continue;
889726
+ }
889727
+ if (arg === "--yes") {
889728
+ yes = true;
889729
+ continue;
889730
+ }
889731
+ positionals.push(arg);
889732
+ }
889733
+ return { name: positionals.join(" ").trim(), enabled, yes };
889734
+ }
888520
889735
  function summarizeRoutine2(routine) {
888521
889736
  const enabled = routine.enabled ? "enabled" : "disabled";
888522
889737
  const tags = routine.tags.length > 0 ? ` tags=${routine.tags.join(",")}` : "";
888523
889738
  return ` ${routine.id} ${enabled} ${routine.reviewState} starts=${routine.startCount} ${routine.name} - ${routine.description}${tags}`;
888524
889739
  }
889740
+ function summarizeDiscoveredRoutine2(routine) {
889741
+ const description = routine.description ? ` - ${routine.description}` : "";
889742
+ return [
889743
+ ` ${routine.name} ${routine.origin}${description}`,
889744
+ ` path: ${routine.path}`
889745
+ ].join(`
889746
+ `);
889747
+ }
889748
+ function renderDiscoveredRoutineList(routines) {
889749
+ if (routines.length === 0) {
889750
+ return [
889751
+ "Discovered Agent routine files",
889752
+ " No routine markdown files found in Agent routine folders.",
889753
+ " Search roots: .goodvibes/routines, .goodvibes/agent/routines, ~/.goodvibes/routines, ~/.goodvibes/agent/routines"
889754
+ ].join(`
889755
+ `);
889756
+ }
889757
+ return [
889758
+ `Discovered Agent routine files (${routines.length})`,
889759
+ ...routines.map(summarizeDiscoveredRoutine2),
889760
+ "",
889761
+ "Import one with: goodvibes-agent routines import-discovered <name> --yes"
889762
+ ].join(`
889763
+ `);
889764
+ }
889765
+ function discoveredRoutineLookupValues2(routine) {
889766
+ const slug = routine.name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
889767
+ const basename6 = routine.path.split(/[\\/]/).pop()?.replace(/\.md$/i, "") ?? "";
889768
+ return [routine.name, slug, routine.path, basename6].map((value) => value.trim().toLowerCase()).filter(Boolean);
889769
+ }
889770
+ function findDiscoveredRoutine2(routines, idOrName) {
889771
+ const lookup = idOrName.trim().toLowerCase();
889772
+ if (!lookup)
889773
+ return null;
889774
+ return routines.find((routine) => discoveredRoutineLookupValues2(routine).includes(lookup)) ?? null;
889775
+ }
889776
+ function discoveredRoutineFrontmatterList(routine, key) {
889777
+ const value = routine.frontmatter[key];
889778
+ if (!value)
889779
+ return [];
889780
+ return splitList6(value);
889781
+ }
888525
889782
  function renderRoutineList(title, path7, routines) {
888526
889783
  if (routines.length === 0) {
888527
889784
  return [
@@ -888640,6 +889897,84 @@ async function handleRoutinesCommand(runtime3) {
888640
889897
  exitCode: 0
888641
889898
  };
888642
889899
  }
889900
+ if (normalized === "discover") {
889901
+ const discovered = await discoverRoutines(shellPaths2(runtime3));
889902
+ const value = {
889903
+ ok: true,
889904
+ kind: "agent.routines.discover",
889905
+ data: { routines: discovered }
889906
+ };
889907
+ return {
889908
+ output: jsonOrText3(runtime3, value, renderDiscoveredRoutineList(discovered)),
889909
+ exitCode: 0
889910
+ };
889911
+ }
889912
+ if (normalized === "import-discovered" || normalized === "import-routine") {
889913
+ const parsed = parseImportFlags(rest);
889914
+ if (!parsed.name) {
889915
+ const failure3 = {
889916
+ ok: false,
889917
+ kind: "invalid_routine_command",
889918
+ error: "Usage: goodvibes-agent routines import-discovered <name> [--enabled] --yes"
889919
+ };
889920
+ return {
889921
+ output: runtime3.cli.flags.outputFormat === "json" ? JSON.stringify(failure3, null, 2) : failure3.error,
889922
+ exitCode: 2
889923
+ };
889924
+ }
889925
+ const discovered = findDiscoveredRoutine2(await discoverRoutines(shellPaths2(runtime3)), parsed.name);
889926
+ if (!discovered) {
889927
+ const failure3 = {
889928
+ ok: false,
889929
+ kind: "routine_discovery_not_found",
889930
+ error: `Unknown discovered Agent routine: ${parsed.name}
889931
+ Run goodvibes-agent routines discover to inspect available routine files.`
889932
+ };
889933
+ return {
889934
+ output: runtime3.cli.flags.outputFormat === "json" ? JSON.stringify(failure3, null, 2) : failure3.error,
889935
+ exitCode: 1
889936
+ };
889937
+ }
889938
+ if (!parsed.yes) {
889939
+ const value2 = {
889940
+ ok: true,
889941
+ kind: "agent.routines.import_discovered.preview",
889942
+ data: { routine: discovered }
889943
+ };
889944
+ return {
889945
+ output: jsonOrText3(runtime3, value2, [
889946
+ "Agent routine import preview",
889947
+ ` name: ${discovered.name}`,
889948
+ ` origin: ${discovered.origin}`,
889949
+ ` path: ${discovered.path}`,
889950
+ ` description: ${discovered.description || "(none)"}`,
889951
+ ` steps characters: ${discovered.steps.length}`,
889952
+ " next: rerun with --yes to import into the Agent-local routine registry"
889953
+ ].join(`
889954
+ `)),
889955
+ exitCode: 0
889956
+ };
889957
+ }
889958
+ const routine = registry5.create({
889959
+ name: discovered.name,
889960
+ description: discovered.description || `Imported routine from ${discovered.origin} markdown file.`,
889961
+ steps: discovered.steps,
889962
+ tags: discoveredRoutineFrontmatterList(discovered, "tags"),
889963
+ triggers: discoveredRoutineFrontmatterList(discovered, "triggers"),
889964
+ enabled: parsed.enabled,
889965
+ source: "imported",
889966
+ provenance: `discovered:${discovered.origin}:${discovered.path}`
889967
+ });
889968
+ const value = {
889969
+ ok: true,
889970
+ kind: "agent.routines.import_discovered",
889971
+ data: routine
889972
+ };
889973
+ return {
889974
+ output: jsonOrText3(runtime3, value, `Imported Agent routine ${routine.id}: ${routine.name}${routine.enabled ? " (enabled)" : ""}`),
889975
+ exitCode: 0
889976
+ };
889977
+ }
888643
889978
  if (normalized === "show") {
888644
889979
  const id = rest[0];
888645
889980
  if (!id)
@@ -888704,7 +890039,7 @@ async function handleRoutinesCommand(runtime3) {
888704
890039
  return handleRoutinePromotion(runtime3, rest);
888705
890040
  }
888706
890041
  return {
888707
- output: "Usage: goodvibes-agent routines [list|enabled|show <id>|receipts|reconcile|receipt <id>|promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes]",
890042
+ output: "Usage: goodvibes-agent routines [list|enabled|discover|import-discovered <name> --yes|show <id>|receipts|reconcile|receipt <id>|promote <id> (--cron <expr>|--every <interval>|--at <iso-time>) [--delivery-channel <channel>|--delivery-route <route>|--delivery-webhook <url>] --yes]",
888708
890043
  exitCode: 2
888709
890044
  };
888710
890045
  }
@@ -888806,13 +890141,13 @@ async function withRuntimeServices(runtime3, fn) {
888806
890141
  }
888807
890142
  }
888808
890143
  function readAuthPaths(runtime3) {
888809
- const shellPaths2 = createShellPathService2({
890144
+ const shellPaths3 = createShellPathService2({
888810
890145
  workingDirectory: runtime3.workingDirectory,
888811
890146
  homeDirectory: runtime3.homeDirectory
888812
890147
  });
888813
- const userStorePath = shellPaths2.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
888814
- const bootstrapCredentialPath = shellPaths2.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
888815
- const operatorTokenPath = join98(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
890148
+ const userStorePath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
890149
+ const bootstrapCredentialPath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
890150
+ const operatorTokenPath = join101(runtime3.homeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
888816
890151
  return {
888817
890152
  userStorePath,
888818
890153
  userStorePresent: existsSync84(userStorePath),
@@ -889327,7 +890662,7 @@ async function prepareShellCliRuntime(argv, roots, binary2 = "goodvibes-agent")
889327
890662
  workingDirectory: bootstrapWorkingDir,
889328
890663
  homeDirectory: bootstrapHomeDirectory
889329
890664
  } = ownership;
889330
- configureActivityLogger(join99(bootstrapWorkingDir, ".goodvibes", "logs"));
890665
+ configureActivityLogger(join102(bootstrapWorkingDir, ".goodvibes", "logs"));
889331
890666
  const configManager = new ConfigManager({
889332
890667
  workingDir: bootstrapWorkingDir,
889333
890668
  homeDir: bootstrapHomeDirectory,
@@ -889372,14 +890707,14 @@ async function prepareShellCliRuntime(argv, roots, binary2 = "goodvibes-agent")
889372
890707
  process.exit(2);
889373
890708
  }
889374
890709
  if (cli.command === "status" || cli.command === "doctor" || cli.command === "onboarding" && cli.commandArgs[0] === "status") {
889375
- const shellPaths2 = createShellPathService2({
890710
+ const shellPaths3 = createShellPathService2({
889376
890711
  workingDirectory: bootstrapWorkingDir,
889377
890712
  homeDirectory: bootstrapHomeDirectory
889378
890713
  });
889379
- const userStorePath = shellPaths2.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
889380
- const bootstrapCredentialPath = shellPaths2.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
889381
- const operatorTokenPath = join99(bootstrapHomeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
889382
- const onboardingMarkers = readOnboardingCheckMarkers(shellPaths2);
890714
+ const userStorePath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-users.json");
890715
+ const bootstrapCredentialPath = shellPaths3.resolveUserPath(GOODVIBES_AGENT_SURFACE_ROOT, "auth-bootstrap.txt");
890716
+ const operatorTokenPath = join102(bootstrapHomeDirectory, ".goodvibes", "daemon", "operator-tokens.json");
890717
+ const onboardingMarkers = readOnboardingCheckMarkers(shellPaths3);
889383
890718
  const service = await buildCliServicePosture({
889384
890719
  configManager,
889385
890720
  workingDirectory: bootstrapWorkingDir,
@@ -889493,8 +890828,8 @@ function getInteractiveTerminalLaunchError(input) {
889493
890828
  `);
889494
890829
  }
889495
890830
  function applyInitialTuiCliState(options) {
889496
- const { cli, input, commandRegistry, commandContext, shellPaths: shellPaths2, render } = options;
889497
- const globalOnboardingMarker = readOnboardingCheckMarker(shellPaths2, "user");
890831
+ const { cli, input, commandRegistry, commandContext, shellPaths: shellPaths3, render } = options;
890832
+ const globalOnboardingMarker = readOnboardingCheckMarker(shellPaths3, "user");
889498
890833
  const seededPrompt = cli.flags.prompt ?? (cli.rawCommand === undefined && cli.positionals.length > 0 ? cli.positionals.join(" ") : undefined);
889499
890834
  if (cli.command === "onboarding") {
889500
890835
  input.openOnboardingWizard({ mode: "edit", reset: true });
@@ -889516,7 +890851,7 @@ function applyInitialTuiCliState(options) {
889516
890851
 
889517
890852
  // src/audio/player.ts
889518
890853
  import { accessSync, constants as constants4 } from "fs";
889519
- import { delimiter, join as join100 } from "path";
890854
+ import { delimiter, join as join103 } from "path";
889520
890855
  import { spawn as spawn6 } from "child_process";
889521
890856
 
889522
890857
  class LocalStreamingAudioPlayer {
@@ -889613,7 +890948,7 @@ function findExecutable(name51, env2) {
889613
890948
  if (!dir)
889614
890949
  continue;
889615
890950
  for (const ext of extensions14) {
889616
- const candidate = join100(dir, `${name51}${ext}`);
890951
+ const candidate = join103(dir, `${name51}${ext}`);
889617
890952
  try {
889618
890953
  accessSync(candidate, constants4.X_OK);
889619
890954
  return candidate;