@pellux/goodvibes-agent 1.1.2 → 1.1.4

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.
@@ -3884,7 +3884,7 @@ var init_mcp = __esm(() => {
3884
3884
  // node_modules/@pellux/goodvibes-sdk/dist/platform/version.js
3885
3885
  import { readFileSync as readFileSync3 } from "fs";
3886
3886
  import { join as join4 } from "path";
3887
- var version = "0.33.36", VERSION2;
3887
+ var version = "0.33.37", VERSION2;
3888
3888
  var init_version = __esm(() => {
3889
3889
  try {
3890
3890
  const pkg = JSON.parse(readFileSync3(join4(import.meta.dir, "..", "..", "package.json"), "utf-8"));
@@ -258777,7 +258777,7 @@ var FOUNDATION_METADATA;
258777
258777
  var init_foundation_metadata = __esm(() => {
258778
258778
  FOUNDATION_METADATA = {
258779
258779
  productId: "goodvibes",
258780
- productVersion: "0.33.36",
258780
+ productVersion: "0.33.37",
258781
258781
  operatorMethodCount: 279,
258782
258782
  operatorEventCount: 30,
258783
258783
  peerEndpointCount: 6
@@ -258792,7 +258792,7 @@ var init_operator_contract = __esm(() => {
258792
258792
  product: {
258793
258793
  id: "goodvibes",
258794
258794
  surface: "operator",
258795
- version: "0.33.36"
258795
+ version: "0.33.37"
258796
258796
  },
258797
258797
  auth: {
258798
258798
  modes: [
@@ -450372,6 +450372,23 @@ function createSchema2(db) {
450372
450372
  `);
450373
450373
  db.run(`CREATE INDEX IF NOT EXISTS idx_knowledge_schedules_job_id ON knowledge_schedules(job_id)`);
450374
450374
  }
450375
+ function getKnowledgeSchemaStatements() {
450376
+ const statements = [];
450377
+ createSchema2({
450378
+ run(sql) {
450379
+ const normalized = sql.trim();
450380
+ if (normalized.length > 0)
450381
+ statements.push(normalized);
450382
+ }
450383
+ });
450384
+ return statements;
450385
+ }
450386
+ function renderKnowledgeSchemaSql() {
450387
+ return `${getKnowledgeSchemaStatements().map((statement) => statement.endsWith(";") ? statement : `${statement};`).join(`
450388
+
450389
+ `)}
450390
+ `;
450391
+ }
450375
450392
  function rowObject(columns, values2) {
450376
450393
  return Object.fromEntries(columns.map((column, index) => [column, values2[index]]));
450377
450394
  }
@@ -763654,6 +763671,9 @@ var init_ingest = __esm(() => {
763654
763671
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/browser-history/index.js
763655
763672
  var init_browser_history = __esm(() => {
763656
763673
  init_ingest();
763674
+ init_discover();
763675
+ init_readers();
763676
+ init_paths2();
763657
763677
  });
763658
763678
 
763659
763679
  // node_modules/graphql/jsutils/devAssert.mjs
@@ -781293,6 +781313,7 @@ var init_semantic = __esm(() => {
781293
781313
  init_llm();
781294
781314
  init_gap_repair();
781295
781315
  init_service4();
781316
+ init_self_improvement();
781296
781317
  });
781297
781318
 
781298
781319
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/helpers.js
@@ -785261,8 +785282,40 @@ var init_map_view = __esm(() => {
785261
785282
  });
785262
785283
 
785263
785284
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/home-graph/types.js
785264
- var HOME_GRAPH_CAPABILITIES;
785285
+ var HOME_GRAPH_NODE_KINDS, HOME_GRAPH_RELATIONS, HOME_GRAPH_CAPABILITIES;
785265
785286
  var init_types15 = __esm(() => {
785287
+ HOME_GRAPH_NODE_KINDS = [
785288
+ "ha_home",
785289
+ "ha_entity",
785290
+ "ha_device",
785291
+ "ha_area",
785292
+ "ha_automation",
785293
+ "ha_script",
785294
+ "ha_scene",
785295
+ "ha_label",
785296
+ "ha_integration",
785297
+ "ha_room",
785298
+ "ha_device_passport",
785299
+ "ha_maintenance_item",
785300
+ "ha_troubleshooting_case",
785301
+ "ha_purchase",
785302
+ "ha_network_node"
785303
+ ];
785304
+ HOME_GRAPH_RELATIONS = [
785305
+ "controls",
785306
+ "located_in",
785307
+ "belongs_to_device",
785308
+ "has_manual",
785309
+ "has_receipt",
785310
+ "has_warranty",
785311
+ "has_issue",
785312
+ "fixed_by",
785313
+ "uses_battery",
785314
+ "connected_via",
785315
+ "part_of_network",
785316
+ "mentioned_by",
785317
+ "source_for"
785318
+ ];
785266
785319
  HOME_GRAPH_CAPABILITIES = [
785267
785320
  "knowledge-space-isolation",
785268
785321
  "snapshot-sync",
@@ -786669,6 +786722,7 @@ var init_service5 = __esm(() => {
786669
786722
  var init_home_graph = __esm(() => {
786670
786723
  init_service5();
786671
786724
  init_extension();
786725
+ init_types15();
786672
786726
  });
786673
786727
 
786674
786728
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/store-refinement.js
@@ -788996,10 +789050,14 @@ var init_service6 = __esm(() => {
788996
789050
  var init_project_planning = __esm(() => {
788997
789051
  init_service6();
788998
789052
  init_helpers3();
789053
+ init_readiness();
788999
789054
  });
789000
789055
 
789001
789056
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/persistence.js
789002
- var init_persistence = () => {};
789057
+ var init_persistence = __esm(() => {
789058
+ init_store_schema();
789059
+ init_store_load();
789060
+ });
789003
789061
 
789004
789062
  // node_modules/@pellux/goodvibes-sdk/dist/platform/knowledge/projections.js
789005
789063
  class KnowledgeProjectionService {
@@ -792507,21 +792565,21 @@ var init_service7 = __esm(() => {
792507
792565
  var exports_knowledge = {};
792508
792566
  __export(exports_knowledge, {
792509
792567
  withKnowledgeSpace: () => withKnowledgeSpace,
792510
- uniqKnowledgeValues: () => uniq3,
792511
- stabilizeKnowledgeText: () => stableText2,
792512
- runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement2,
792568
+ uniqKnowledgeValues: () => uniq2,
792569
+ stabilizeKnowledgeText: () => stableText,
792570
+ runKnowledgeSemanticSelfImprovement: () => runKnowledgeSemanticSelfImprovement,
792513
792571
  resolveProjectPlanningSpace: () => resolveProjectPlanningSpace,
792514
- resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir2,
792572
+ resolveKnowledgeDbPathFromControlPlaneDir: () => resolveKnowledgeDbPathFromControlPlaneDir,
792515
792573
  renderPacket: () => renderPacket,
792516
792574
  renderKnowledgeSchemaSql: () => renderKnowledgeSchemaSql,
792517
792575
  renderKnowledgeMap: () => renderKnowledgeMap,
792518
792576
  readKnowledgeSearchText: () => readKnowledgeSearchText,
792519
- readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile2,
792577
+ readBrowserKnowledgeProfile: () => readBrowserKnowledgeProfile,
792520
792578
  projectPlanningSourceId: () => projectPlanningSourceId,
792521
792579
  projectPlanningProjectIdFromPath: () => projectPlanningProjectIdFromPath,
792522
792580
  projectPlanningCanonicalUri: () => projectPlanningCanonicalUri,
792523
792581
  projectKnowledgeSpaceId: () => projectKnowledgeSpaceId,
792524
- parseKnowledgeJsonValue: () => parseJsonValue2,
792582
+ parseKnowledgeJsonValue: () => parseJsonValue,
792525
792583
  normalizeProjectId: () => normalizeProjectId,
792526
792584
  normalizeKnowledgeSpaceId: () => normalizeKnowledgeSpaceId,
792527
792585
  normalizeHomeAssistantInstallationId: () => normalizeHomeAssistantInstallationId,
@@ -792529,12 +792587,12 @@ __export(exports_knowledge, {
792529
792587
  materializeGeneratedKnowledgeProjection: () => materializeGeneratedKnowledgeProjection,
792530
792588
  looksLikeRawPdfPayload: () => looksLikeRawPdfPayload,
792531
792589
  looksBinaryLikeText: () => looksBinaryLikeText,
792532
- loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot2,
792590
+ loadKnowledgeStoreSnapshot: () => loadKnowledgeStoreSnapshot,
792533
792591
  listGeneratedKnowledgePages: () => listGeneratedKnowledgePages,
792534
- listBrowserKinds: () => listBrowserKinds2,
792592
+ listBrowserKinds: () => listBrowserKinds,
792535
792593
  knowledgeSpaceMetadata: () => knowledgeSpaceMetadata,
792536
792594
  knowledgePageSourceWeight: () => knowledgePageSourceWeight,
792537
- knowledgeNowMs: () => nowMs2,
792595
+ knowledgeNowMs: () => nowMs,
792538
792596
  knowledgeExtractionNeedsRefresh: () => knowledgeExtractionNeedsRefresh,
792539
792597
  isUsefulKnowledgePageSourceCandidate: () => isUsefulKnowledgePageSourceCandidate,
792540
792598
  isUsefulKnowledgePageSource: () => isUsefulKnowledgePageSource,
@@ -792554,12 +792612,12 @@ __export(exports_knowledge, {
792554
792612
  generatedKnowledgeSourceId: () => generatedKnowledgeSourceId,
792555
792613
  generatedKnowledgeCanonicalUri: () => generatedKnowledgeCanonicalUri,
792556
792614
  extractKnowledgeArtifact: () => extractKnowledgeArtifact,
792557
- evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness2,
792558
- discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles2,
792615
+ evaluateProjectPlanningReadiness: () => evaluateProjectPlanningReadiness,
792616
+ discoverBrowserKnowledgeProfiles: () => discoverBrowserKnowledgeProfiles,
792559
792617
  createWebKnowledgeGapRepairer: () => createWebKnowledgeGapRepairer,
792560
792618
  createProviderBackedKnowledgeSemanticLlm: () => createProviderBackedKnowledgeSemanticLlm,
792561
792619
  createMemoryApi: () => createMemoryApi,
792562
- createKnowledgeSchema: () => createSchema3,
792620
+ createKnowledgeSchema: () => createSchema2,
792563
792621
  createKnowledgeApi: () => createKnowledgeApi,
792564
792622
  createDefaultKnowledgeConnectorRegistry: () => createDefaultKnowledgeConnectorRegistry,
792565
792623
  compareKnowledgePageSources: () => compareKnowledgePageSources,
@@ -794998,7 +795056,7 @@ var init_delivery_manager = __esm(() => {
794998
795056
  });
794999
795057
 
795000
795058
  // node_modules/@pellux/goodvibes-sdk/dist/platform/automation/scheduler-capacity.js
795001
- function computeSchedulerCapacity(slotsTotal, runs, nowMs3 = Date.now()) {
795059
+ function computeSchedulerCapacity(slotsTotal, runs, nowMs2 = Date.now()) {
795002
795060
  let slotsInUse = 0;
795003
795061
  const queuedRuns = [];
795004
795062
  for (const run7 of runs) {
@@ -795008,7 +795066,7 @@ function computeSchedulerCapacity(slotsTotal, runs, nowMs3 = Date.now()) {
795008
795066
  queuedRuns.push(run7);
795009
795067
  }
795010
795068
  const queueDepth = queuedRuns.length;
795011
- const oldestQueuedAgeMs = queueDepth > 0 ? nowMs3 - Math.min(...queuedRuns.map((r6) => r6.queuedAt)) : null;
795069
+ const oldestQueuedAgeMs = queueDepth > 0 ? nowMs2 - Math.min(...queuedRuns.map((r6) => r6.queuedAt)) : null;
795012
795070
  return { slotsTotal, slotsInUse, queueDepth, oldestQueuedAgeMs };
795013
795071
  }
795014
795072
 
@@ -800211,8 +800269,8 @@ async function dispatchOpenAICompatibleRoutes(request2, context, pathPrefix = OP
800211
800269
  function handleListModels(context) {
800212
800270
  const created = Math.floor(Date.now() / 1000);
800213
800271
  const models = context.providerRegistry.listModels();
800214
- const current = tryGetCurrentModel(context.providerRegistry);
800215
- const ids = new Set(current ? ["goodvibes/current"] : []);
800272
+ const current = context.providerRegistry.getCurrentModel();
800273
+ const ids = new Set(["goodvibes/current"]);
800216
800274
  for (const model of models) {
800217
800275
  ids.add(model.registryKey);
800218
800276
  }
@@ -800222,7 +800280,7 @@ function handleListModels(context) {
800222
800280
  id,
800223
800281
  object: "model",
800224
800282
  created,
800225
- owned_by: id.startsWith("goodvibes/") ? "goodvibes" : modelOwnerFor(id, models, current?.provider ?? "goodvibes")
800283
+ owned_by: id.startsWith("goodvibes/") ? "goodvibes" : modelOwnerFor(id, models, current.provider)
800226
800284
  }))
800227
800285
  });
800228
800286
  }
@@ -800270,12 +800328,12 @@ async function handleChatCompletions(request2, context) {
800270
800328
  }
800271
800329
  }
800272
800330
  function resolveModel(registry3, requested) {
800331
+ const current = registry3.getCurrentModel();
800273
800332
  const raw = requested?.trim();
800274
800333
  if (!raw) {
800275
800334
  throw new Error("Missing required field: model.");
800276
800335
  }
800277
800336
  if (raw === "goodvibes/current") {
800278
- const current = registry3.getCurrentModel();
800279
800337
  return {
800280
800338
  provider: registry3.getForModel(current.registryKey, current.provider),
800281
800339
  providerId: current.provider,
@@ -800295,13 +800353,6 @@ function resolveModel(registry3, requested) {
800295
800353
  }
800296
800354
  throw new Error(raw.includes(":") ? `Model '${raw}' not found.` : `Model '${raw}' must be requested as a provider-qualified registryKey.`);
800297
800355
  }
800298
- function tryGetCurrentModel(registry3) {
800299
- try {
800300
- return registry3.getCurrentModel();
800301
- } catch {
800302
- return null;
800303
- }
800304
- }
800305
800356
  function prepareChatRequest(input) {
800306
800357
  const systemParts = [];
800307
800358
  const messages = [];
@@ -801311,58 +801362,14 @@ class DaemonHttpRouter {
801311
801362
  return handleGenericWebhookSurface(req, this.context.buildGenericWebhookAdapterContext());
801312
801363
  }
801313
801364
  }
801314
- function normalizeAgentKnowledgeAliasPayload(value) {
801315
- if (Array.isArray(value))
801316
- return value.map(normalizeAgentKnowledgeAliasPayload);
801317
- if (!value || typeof value !== "object")
801318
- return value;
801319
- const output = {};
801320
- let changed = false;
801321
- for (const [key, nested] of Object.entries(value)) {
801322
- if (AGENT_KNOWLEDGE_SCOPE_FIELDS.has(key) && nested === DEFAULT_KNOWLEDGE_SPACE_ID) {
801323
- output[key] = AGENT_KNOWLEDGE_PUBLIC_SPACE_ID;
801324
- changed = true;
801325
- continue;
801326
- }
801327
- const normalized = normalizeAgentKnowledgeAliasPayload(nested);
801328
- output[key] = normalized;
801329
- if (normalized !== nested)
801330
- changed = true;
801331
- }
801332
- return changed ? output : value;
801333
- }
801334
- async function normalizeAgentKnowledgeAliasResponse(response5) {
801335
- const contentType = response5.headers.get("content-type") ?? "";
801336
- if (!contentType.toLowerCase().includes("application/json"))
801337
- return response5;
801338
- let parsed;
801339
- try {
801340
- parsed = await response5.clone().json();
801341
- } catch {
801342
- return response5;
801343
- }
801344
- const normalized = normalizeAgentKnowledgeAliasPayload(parsed);
801345
- if (normalized === parsed)
801346
- return response5;
801347
- const headers = new Headers(response5.headers);
801348
- headers.delete("content-length");
801349
- headers.set("content-type", "application/json");
801350
- return Response.json(normalized, {
801351
- status: response5.status,
801352
- statusText: response5.statusText,
801353
- headers
801354
- });
801355
- }
801356
- async function dispatchAliasedKnowledgeRoutes(req, aliasPrefix, handlers) {
801365
+ function dispatchAliasedKnowledgeRoutes(req, aliasPrefix, handlers) {
801357
801366
  const url2 = new URL(req.url);
801358
801367
  if (!url2.pathname.startsWith(aliasPrefix))
801359
801368
  return null;
801360
801369
  const suffix = url2.pathname.slice(aliasPrefix.length);
801361
801370
  url2.pathname = `/api/knowledge${suffix}`;
801362
- const response5 = await dispatchDaemonApiRoutes(new Request(url2.toString(), req), handlers);
801363
- return response5 ? normalizeAgentKnowledgeAliasResponse(response5) : null;
801371
+ return dispatchDaemonApiRoutes(new Request(url2.toString(), req), handlers);
801364
801372
  }
801365
- var AGENT_KNOWLEDGE_PUBLIC_SPACE_ID, AGENT_KNOWLEDGE_SCOPE_FIELDS;
801366
801373
  var init_router = __esm(() => {
801367
801374
  init_schema();
801368
801375
  init_http_auth();
@@ -801397,8 +801404,6 @@ var init_router = __esm(() => {
801397
801404
  init_home_graph_routes();
801398
801405
  init_openai_compatible_routes();
801399
801406
  init_router_request_body();
801400
- AGENT_KNOWLEDGE_PUBLIC_SPACE_ID = goodVibesAgentKnowledgeSpaceId();
801401
- AGENT_KNOWLEDGE_SCOPE_FIELDS = new Set(["spaceId", "knowledgeSpaceId", "namespace"]);
801402
801407
  });
801403
801408
 
801404
801409
  // node_modules/@pellux/goodvibes-sdk/dist/platform/companion/companion-chat-persistence.js
@@ -817087,7 +817092,7 @@ var createStyledCell = (char, overrides = {}) => ({
817087
817092
  // src/version.ts
817088
817093
  import { readFileSync } from "fs";
817089
817094
  import { join } from "path";
817090
- var _version = "1.1.2";
817095
+ var _version = "1.1.4";
817091
817096
  try {
817092
817097
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, "..", "package.json"), "utf-8"));
817093
817098
  _version = typeof pkg.version === "string" ? pkg.version : _version;
@@ -839600,7 +839605,7 @@ var WORK_PLAN_STATUSES = [
839600
839605
  "failed",
839601
839606
  "cancelled"
839602
839607
  ];
839603
- function nowMs3() {
839608
+ function nowMs2() {
839604
839609
  return Date.now();
839605
839610
  }
839606
839611
  function isObject4(value) {
@@ -839706,7 +839711,7 @@ class WorkPlanStore {
839706
839711
  if (!normalizedTitle)
839707
839712
  throw new Error("Work plan item title is required.");
839708
839713
  const plan = this.readPlan();
839709
- const time4 = nowMs3();
839714
+ const time4 = nowMs2();
839710
839715
  const item = {
839711
839716
  id: createItemId(),
839712
839717
  title: normalizedTitle,
@@ -839730,7 +839735,7 @@ class WorkPlanStore {
839730
839735
  updateItem(idOrPrefix, patch2) {
839731
839736
  const plan = this.readPlan();
839732
839737
  const item = this.resolveItem(plan, idOrPrefix);
839733
- const time4 = nowMs3();
839738
+ const time4 = nowMs2();
839734
839739
  const nextStatus = patch2.status ?? item.status;
839735
839740
  const next = this.pruneItem({
839736
839741
  ...item,
@@ -839763,7 +839768,7 @@ class WorkPlanStore {
839763
839768
  removeItem(idOrPrefix) {
839764
839769
  const plan = this.readPlan();
839765
839770
  const item = this.resolveItem(plan, idOrPrefix);
839766
- const time4 = nowMs3();
839771
+ const time4 = nowMs2();
839767
839772
  const remaining = plan.items.filter((candidate) => candidate.id !== item.id);
839768
839773
  this.writePlan({
839769
839774
  ...plan,
@@ -839783,7 +839788,7 @@ class WorkPlanStore {
839783
839788
  ...plan,
839784
839789
  items: remaining,
839785
839790
  activeItemId: remaining[0]?.id,
839786
- updatedAt: nowMs3()
839791
+ updatedAt: nowMs2()
839787
839792
  });
839788
839793
  return removed;
839789
839794
  }
@@ -839822,7 +839827,7 @@ class WorkPlanStore {
839822
839827
  const parsed = JSON.parse(raw);
839823
839828
  if (!isObject4(parsed))
839824
839829
  return this.createEmptyPlan();
839825
- const time4 = nowMs3();
839830
+ const time4 = nowMs2();
839826
839831
  const createdAt = typeof parsed.createdAt === "number" ? parsed.createdAt : time4;
839827
839832
  const updatedAt = typeof parsed.updatedAt === "number" ? parsed.updatedAt : createdAt;
839828
839833
  const items = Array.isArray(parsed.items) ? parsed.items.map((item) => normalizeItem(item, createdAt)).filter((item) => item !== null) : [];
@@ -839841,7 +839846,7 @@ class WorkPlanStore {
839841
839846
  };
839842
839847
  }
839843
839848
  createEmptyPlan() {
839844
- const time4 = nowMs3();
839849
+ const time4 = nowMs2();
839845
839850
  return {
839846
839851
  id: createPlanId(this.options.projectId, this.options.projectRoot),
839847
839852
  projectId: this.options.projectId,
@@ -843045,11 +843050,50 @@ function createBrowserAgentSdk(options = {}) {
843045
843050
  return createBrowserKnowledgeSdkFromRoutes(AGENT_BROWSER_ROUTES, options);
843046
843051
  }
843047
843052
 
843053
+ // src/agent/knowledge-scope-alias.ts
843054
+ init_knowledge2();
843055
+ var AGENT_KNOWLEDGE_PUBLIC_SPACE_ID = goodVibesAgentKnowledgeSpaceId();
843056
+ var AGENT_KNOWLEDGE_SCOPE_FIELDS = new Set(["spaceId", "knowledgeSpaceId", "namespace"]);
843057
+ function isRecord23(value) {
843058
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
843059
+ }
843060
+ function isDefaultScopeValue(value) {
843061
+ return typeof value === "string" && value.trim().toLowerCase() === DEFAULT_KNOWLEDGE_SPACE_ID;
843062
+ }
843063
+ function normalizeAgentKnowledgeScopeAliases(value) {
843064
+ if (Array.isArray(value)) {
843065
+ let changed2 = false;
843066
+ const normalized = value.map((item) => {
843067
+ const next = normalizeAgentKnowledgeScopeAliases(item);
843068
+ if (next !== item)
843069
+ changed2 = true;
843070
+ return next;
843071
+ });
843072
+ return changed2 ? normalized : value;
843073
+ }
843074
+ if (!isRecord23(value))
843075
+ return value;
843076
+ let changed = false;
843077
+ const output2 = {};
843078
+ for (const [key, nested] of Object.entries(value)) {
843079
+ if (AGENT_KNOWLEDGE_SCOPE_FIELDS.has(key) && isDefaultScopeValue(nested)) {
843080
+ output2[key] = AGENT_KNOWLEDGE_PUBLIC_SPACE_ID;
843081
+ changed = true;
843082
+ continue;
843083
+ }
843084
+ const normalized = normalizeAgentKnowledgeScopeAliases(nested);
843085
+ output2[key] = normalized;
843086
+ if (normalized !== nested)
843087
+ changed = true;
843088
+ }
843089
+ return changed ? output2 : value;
843090
+ }
843091
+
843048
843092
  // src/runtime/connected-host-auth.ts
843049
843093
  import { createHash as createHash20 } from "crypto";
843050
843094
  import { existsSync as existsSync64, readFileSync as readFileSync68 } from "fs";
843051
843095
  import { join as join84 } from "path";
843052
- function isRecord23(value) {
843096
+ function isRecord24(value) {
843053
843097
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
843054
843098
  }
843055
843099
  function connectedHostOperatorTokenPath(homeDirectory) {
@@ -843077,7 +843121,7 @@ function readConnectedHostOperatorToken(homeDirectory) {
843077
843121
  return { path: path7, present: false, token: null };
843078
843122
  try {
843079
843123
  const parsed = JSON.parse(readFileSync68(path7, "utf-8"));
843080
- const token = isRecord23(parsed) && typeof parsed.token === "string" && parsed.token.trim().length > 0 ? parsed.token : null;
843124
+ const token = isRecord24(parsed) && typeof parsed.token === "string" && parsed.token.trim().length > 0 ? parsed.token : null;
843081
843125
  return { path: path7, present: true, token };
843082
843126
  } catch (error51) {
843083
843127
  return { path: path7, present: true, token: null, error: error51 instanceof Error ? error51.message : String(error51) };
@@ -843097,7 +843141,7 @@ function connectedHostTokenRequiredMessage(path7) {
843097
843141
  }
843098
843142
 
843099
843143
  // src/cli/agent-knowledge-runtime.ts
843100
- function isRecord24(value) {
843144
+ function isRecord25(value) {
843101
843145
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
843102
843146
  }
843103
843147
  function readPackageMetadata() {
@@ -843151,17 +843195,30 @@ async function classifyKnowledgeError(error51, connection5, route) {
843151
843195
  }
843152
843196
  return { ok: false, kind: "connected_host_error", error: message, baseUrl: connection5.baseUrl, route };
843153
843197
  }
843198
+ function normalizeAgentKnowledgeData(data) {
843199
+ return normalizeAgentKnowledgeScopeAliases(data);
843200
+ }
843154
843201
  function createAgentSdk(connection5) {
843155
- return createBrowserAgentSdk({
843202
+ const sdk = createBrowserAgentSdk({
843156
843203
  baseUrl: connection5.baseUrl,
843157
843204
  authToken: connection5.token
843158
843205
  });
843206
+ return {
843207
+ ...sdk,
843208
+ knowledge: {
843209
+ ...sdk.knowledge,
843210
+ ask: async (input) => normalizeAgentKnowledgeData(await sdk.knowledge.ask(input)),
843211
+ search: async (input) => normalizeAgentKnowledgeData(await sdk.knowledge.search(input)),
843212
+ status: async (input) => normalizeAgentKnowledgeData(await sdk.knowledge.status(input)),
843213
+ map: async (input) => normalizeAgentKnowledgeData(await sdk.knowledge.map(input))
843214
+ }
843215
+ };
843159
843216
  }
843160
- var AGENT_KNOWLEDGE_SCOPE_KEYS = new Set(["spaceid", "knowledgespaceid"]);
843217
+ var AGENT_KNOWLEDGE_SCOPE_KEYS = new Set(["spaceid", "knowledgespaceid", "namespace"]);
843161
843218
  var AGENT_KNOWLEDGE_SCOPE_TEXT_PATTERNS = [
843162
843219
  {
843163
843220
  label: "default knowledge scope id",
843164
- pattern: /["']?(?:knowledge[-_\s]*space[-_\s]*id|knowledgespaceid|space[-_\s]*id|spaceid)["']?\s*[:=]\s*["']?default["']?/i
843221
+ pattern: /["']?(?:knowledge[-_\s]*space[-_\s]*id|knowledgespaceid|space[-_\s]*id|spaceid|namespace)["']?\s*[:=]\s*["']?default["']?/i
843165
843222
  },
843166
843223
  { label: "host assistant payload marker", pattern: /home\s*assistant/i },
843167
843224
  { label: "host graph payload marker", pattern: /home\s*graph|homegraph/i }
@@ -843223,10 +843280,11 @@ function agentKnowledgeScopeContaminationFailure(connection5, route, finding) {
843223
843280
  };
843224
843281
  }
843225
843282
  function validateAgentKnowledgeData(data, connection5, method) {
843226
- const contamination = findAgentKnowledgeScopeContamination(data);
843283
+ const normalized = normalizeAgentKnowledgeData(data);
843284
+ const contamination = findAgentKnowledgeScopeContamination(normalized);
843227
843285
  if (contamination)
843228
843286
  return agentKnowledgeScopeContaminationFailure(connection5, method.route, contamination);
843229
- return { ok: true, kind: method.kind, route: method.route, data };
843287
+ return { ok: true, kind: method.kind, route: method.route, data: normalized };
843230
843288
  }
843231
843289
  async function postAgentKnowledgeJson(connection5, route, body2) {
843232
843290
  const response5 = await fetch(`${connection5.baseUrl}${route}`, {
@@ -843247,10 +843305,10 @@ async function postAgentKnowledgeJson(connection5, route, body2) {
843247
843305
  }
843248
843306
  }
843249
843307
  if (!response5.ok) {
843250
- const detail = isRecord24(parsed) && typeof parsed.error === "string" ? parsed.error : text;
843308
+ const detail = isRecord25(parsed) && typeof parsed.error === "string" ? parsed.error : text;
843251
843309
  throw new Error(`HTTP ${response5.status} ${response5.statusText}${detail ? `: ${detail}` : ""}`);
843252
843310
  }
843253
- return parsed;
843311
+ return normalizeAgentKnowledgeData(parsed);
843254
843312
  }
843255
843313
  function queryRoute(route, query2) {
843256
843314
  const params = new URLSearchParams;
@@ -843287,10 +843345,10 @@ async function getAgentKnowledgeJson(connection5, route, query2 = {}) {
843287
843345
  }
843288
843346
  }
843289
843347
  if (!response5.ok) {
843290
- const detail = isRecord24(parsed) && typeof parsed.error === "string" ? parsed.error : text;
843348
+ const detail = isRecord25(parsed) && typeof parsed.error === "string" ? parsed.error : text;
843291
843349
  throw new Error(`HTTP ${response5.status} ${response5.statusText}${detail ? `: ${detail}` : ""}`);
843292
843350
  }
843293
- return parsed;
843351
+ return normalizeAgentKnowledgeData(parsed);
843294
843352
  }
843295
843353
  function findDisallowedKnowledgeScopeFlag(args2) {
843296
843354
  const disallowed = [
@@ -843419,7 +843477,7 @@ var DELEGATION_METHOD = {
843419
843477
  };
843420
843478
 
843421
843479
  // src/cli/agent-knowledge-format.ts
843422
- function isRecord25(value) {
843480
+ function isRecord26(value) {
843423
843481
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
843424
843482
  }
843425
843483
  function readString31(record2, key) {
@@ -843460,14 +843518,14 @@ function formatAgentKnowledgeFailureKind(kind2) {
843460
843518
  return kind2.replace(/[_-]+/g, " ");
843461
843519
  }
843462
843520
  function sourceLine(value) {
843463
- const record2 = isRecord25(value) ? value : {};
843521
+ const record2 = isRecord26(value) ? value : {};
843464
843522
  const title = cleanInline(record2.title) || cleanInline(record2.canonicalUri) || cleanInline(record2.sourceUri) || cleanInline(record2.url) || cleanInline(record2.id) || "untitled";
843465
843523
  const type = cleanInline(record2.sourceType) || cleanInline(record2.type) || "source";
843466
843524
  const url2 = cleanInline(record2.canonicalUri) || cleanInline(record2.sourceUri) || cleanInline(record2.url);
843467
843525
  return url2 && url2 !== title ? `[${type}] ${title} (${url2})` : `[${type}] ${title}`;
843468
843526
  }
843469
843527
  function resultLine(value) {
843470
- const record2 = isRecord25(value) ? value : {};
843528
+ const record2 = isRecord26(value) ? value : {};
843471
843529
  const title = cleanInline(record2.title) || cleanInline(record2.id) || "untitled";
843472
843530
  const id = cleanInline(record2.id);
843473
843531
  const type = cleanInline(record2.type) || cleanInline(record2.kind) || cleanInline(record2.sourceType) || "result";
@@ -843484,7 +843542,7 @@ function resultLine(value) {
843484
843542
  ${snippet}` : parts2.join(" ");
843485
843543
  }
843486
843544
  function nodeLine(value) {
843487
- const record2 = isRecord25(value) ? value : {};
843545
+ const record2 = isRecord26(value) ? value : {};
843488
843546
  const id = cleanInline(record2.id);
843489
843547
  const kind2 = cleanInline(record2.kind) || "node";
843490
843548
  const title = cleanInline(record2.title) || id || "untitled";
@@ -843501,7 +843559,7 @@ function nodeLine(value) {
843501
843559
  ${summary}` : parts2.join(" ");
843502
843560
  }
843503
843561
  function issueLine(value) {
843504
- const record2 = isRecord25(value) ? value : {};
843562
+ const record2 = isRecord26(value) ? value : {};
843505
843563
  const id = cleanInline(record2.id) || "issue";
843506
843564
  const severity = cleanInline(record2.severity) || "unknown";
843507
843565
  const code2 = cleanInline(record2.code) || "issue";
@@ -843511,7 +843569,7 @@ function issueLine(value) {
843511
843569
  return ` - ${id} [${severity}] ${code2}${suffix}${message ? ` - ${message}` : ""}`;
843512
843570
  }
843513
843571
  function connectorLine(value) {
843514
- const record2 = isRecord25(value) ? value : {};
843572
+ const record2 = isRecord26(value) ? value : {};
843515
843573
  const id = cleanInline(record2.id) || "connector";
843516
843574
  const name51 = cleanInline(record2.displayName) || id;
843517
843575
  const sourceType = cleanInline(record2.sourceType);
@@ -843524,7 +843582,7 @@ function relatedKnowledgeCountsLine(relatedEdges, linkedSources, linkedNodes) {
843524
843582
  return ` related edges ${relatedEdges} linked sources ${linkedSources} linked nodes ${linkedNodes}`;
843525
843583
  }
843526
843584
  function formatStatus2(data) {
843527
- const record2 = isRecord25(data) ? data : {};
843585
+ const record2 = isRecord26(data) ? data : {};
843528
843586
  const ready = readBoolean7(record2, "ready");
843529
843587
  const sourceCount = readNumber8(record2, "sourceCount");
843530
843588
  const nodeCount = readNumber8(record2, "nodeCount");
@@ -843544,7 +843602,7 @@ function formatStatus2(data) {
843544
843602
  `);
843545
843603
  }
843546
843604
  function formatEntityList(data, kind2, limit3) {
843547
- const record2 = isRecord25(data) ? data : {};
843605
+ const record2 = isRecord26(data) ? data : {};
843548
843606
  const values2 = readArray2(record2, kind2);
843549
843607
  if (values2.length === 0) {
843550
843608
  return [
@@ -843563,7 +843621,7 @@ function formatEntityList(data, kind2, limit3) {
843563
843621
  `);
843564
843622
  }
843565
843623
  function formatItem(data, id) {
843566
- const record2 = isRecord25(data) ? data : {};
843624
+ const record2 = isRecord26(data) ? data : {};
843567
843625
  const source = record2.source;
843568
843626
  const node = record2.node;
843569
843627
  const issue2 = record2.issue;
@@ -843605,7 +843663,7 @@ function formatItem(data, id) {
843605
843663
  `);
843606
843664
  }
843607
843665
  function formatMap2(data) {
843608
- const record2 = isRecord25(data) ? data : {};
843666
+ const record2 = isRecord26(data) ? data : {};
843609
843667
  const sources = readArray2(record2, "sources");
843610
843668
  const nodes = readArray2(record2, "nodes");
843611
843669
  const edges = readArray2(record2, "edges");
@@ -843621,7 +843679,7 @@ function formatMap2(data) {
843621
843679
  `);
843622
843680
  }
843623
843681
  function formatConnectors(data) {
843624
- const record2 = isRecord25(data) ? data : {};
843682
+ const record2 = isRecord26(data) ? data : {};
843625
843683
  const connectors = readArray2(record2, "connectors");
843626
843684
  if (connectors.length === 0) {
843627
843685
  return [
@@ -843639,8 +843697,8 @@ function formatConnectors(data) {
843639
843697
  `);
843640
843698
  }
843641
843699
  function formatConnector(data, id) {
843642
- const record2 = isRecord25(data) ? data : {};
843643
- const connector = isRecord25(record2.connector) ? record2.connector : record2;
843700
+ const record2 = isRecord26(data) ? data : {};
843701
+ const connector = isRecord26(record2.connector) ? record2.connector : record2;
843644
843702
  const connectorId = cleanInline(connector.id) || id;
843645
843703
  const name51 = cleanInline(connector.displayName) || connectorId;
843646
843704
  const description = cleanInline(connector.description);
@@ -843659,7 +843717,7 @@ function formatConnector(data, id) {
843659
843717
  `);
843660
843718
  }
843661
843719
  function formatConnectorDoctor(data, id) {
843662
- const record2 = isRecord25(data) ? data : {};
843720
+ const record2 = isRecord26(data) ? data : {};
843663
843721
  const ready = readBoolean7(record2, "ready");
843664
843722
  const summary = cleanInline(record2.summary);
843665
843723
  const checks3 = readArray2(record2, "checks");
@@ -843670,7 +843728,7 @@ function formatConnectorDoctor(data, id) {
843670
843728
  summary ? ` summary ${summary}` : null,
843671
843729
  checks3.length > 0 ? " checks" : null,
843672
843730
  ...checks3.slice(0, 10).map((check2) => {
843673
- const item = isRecord25(check2) ? check2 : {};
843731
+ const item = isRecord26(check2) ? check2 : {};
843674
843732
  const checkId = cleanInline(item.id) || "check";
843675
843733
  const status = cleanInline(item.status) || "unknown";
843676
843734
  const label = cleanInline(item.label);
@@ -843684,8 +843742,8 @@ function formatConnectorDoctor(data, id) {
843684
843742
  `);
843685
843743
  }
843686
843744
  function formatAsk(data, query2) {
843687
- const record2 = isRecord25(data) ? data : {};
843688
- const answer = isRecord25(record2.answer) ? record2.answer : record2;
843745
+ const record2 = isRecord26(data) ? data : {};
843746
+ const answer = isRecord26(record2.answer) ? record2.answer : record2;
843689
843747
  const text = cleanInline(answer.text) || cleanInline(record2.answer) || "No answer returned.";
843690
843748
  const confidence = readNumber8(answer, "confidence") ?? readNumber8(record2, "confidence");
843691
843749
  const synthesized = readBoolean7(answer, "synthesized");
@@ -843710,7 +843768,7 @@ function formatAsk(data, query2) {
843710
843768
  `);
843711
843769
  }
843712
843770
  function formatSearch(data, query2) {
843713
- const record2 = isRecord25(data) ? data : {};
843771
+ const record2 = isRecord26(data) ? data : {};
843714
843772
  const items = readArray2(record2, "items");
843715
843773
  const results = items.length > 0 ? items : readArray2(record2, "results");
843716
843774
  if (results.length === 0) {
@@ -843729,8 +843787,8 @@ function formatSearch(data, query2) {
843729
843787
  `);
843730
843788
  }
843731
843789
  function formatIngest(data, target, label = "ingest-url", route = "/api/goodvibes-agent/knowledge/ingest/url", targetLabel = "url") {
843732
- const record2 = isRecord25(data) ? data : {};
843733
- const source = isRecord25(record2.source) ? record2.source : record2;
843790
+ const record2 = isRecord26(data) ? data : {};
843791
+ const source = isRecord26(record2.source) ? record2.source : record2;
843734
843792
  const sourceId = cleanInline(source.id);
843735
843793
  const canonicalUri = cleanInline(source.canonicalUri) || cleanInline(source.sourceUri) || target;
843736
843794
  const artifactId = cleanInline(record2.artifactId);
@@ -843744,7 +843802,7 @@ function formatIngest(data, target, label = "ingest-url", route = "/api/goodvibe
843744
843802
  `);
843745
843803
  }
843746
843804
  function formatBatchIngest(data, label) {
843747
- const record2 = isRecord25(data) ? data : {};
843805
+ const record2 = isRecord26(data) ? data : {};
843748
843806
  const imported = readNumber8(record2, "imported");
843749
843807
  const failed = readNumber8(record2, "failed");
843750
843808
  const sources = readArray2(record2, "sources");
@@ -843760,8 +843818,8 @@ function formatBatchIngest(data, label) {
843760
843818
  `);
843761
843819
  }
843762
843820
  function formatReindex(data) {
843763
- const record2 = isRecord25(data) ? data : {};
843764
- const status = isRecord25(record2.status) ? record2.status : {};
843821
+ const record2 = isRecord26(data) ? data : {};
843822
+ const status = isRecord26(record2.status) ? record2.status : {};
843765
843823
  return [
843766
843824
  "Agent Knowledge reindex complete",
843767
843825
  ` sources ${readNumber8(status, "sourceCount") ?? "unknown"}`,
@@ -844307,7 +844365,7 @@ var SECRET_PATTERNS2 = [
844307
844365
  /\bgh[pousr]_[A-Za-z0-9_]{16,}\b/i,
844308
844366
  /\b(?:password|passwd|api[_-]?key|token|secret)\s*[:=]\s*\S{6,}/i
844309
844367
  ];
844310
- function isRecord26(value) {
844368
+ function isRecord27(value) {
844311
844369
  return typeof value === "object" && value !== null && !Array.isArray(value);
844312
844370
  }
844313
844371
  function readString34(value, fallback = "") {
@@ -844352,7 +844410,7 @@ function assertNoSecretLikeText(fields, ownerLabel = "Agent local records") {
844352
844410
  }
844353
844411
  }
844354
844412
  function parsePersona(value) {
844355
- if (!isRecord26(value))
844413
+ if (!isRecord27(value))
844356
844414
  return null;
844357
844415
  const id = readString34(value.id).trim();
844358
844416
  const name51 = normalizeName(readString34(value.name));
@@ -844382,7 +844440,7 @@ function parsePersona(value) {
844382
844440
  }
844383
844441
  function parseStore(raw) {
844384
844442
  const parsed = JSON.parse(raw);
844385
- if (!isRecord26(parsed))
844443
+ if (!isRecord27(parsed))
844386
844444
  return { version: STORE_VERSION, activePersonaId: null, personas: [] };
844387
844445
  const personas = Array.isArray(parsed.personas) ? parsed.personas.map(parsePersona).filter((entry) => entry !== null) : [];
844388
844446
  const activePersonaId = readString34(parsed.activePersonaId).trim() || null;
@@ -844621,7 +844679,7 @@ function buildActivePersonaPrompt(shellPaths) {
844621
844679
  import { existsSync as existsSync66, mkdirSync as mkdirSync48, readFileSync as readFileSync70, renameSync as renameSync13, writeFileSync as writeFileSync42 } from "fs";
844622
844680
  import { dirname as dirname49 } from "path";
844623
844681
  var STORE_VERSION2 = 1;
844624
- function isRecord27(value) {
844682
+ function isRecord28(value) {
844625
844683
  return typeof value === "object" && value !== null && !Array.isArray(value);
844626
844684
  }
844627
844685
  function readString35(value, fallback = "") {
@@ -844665,7 +844723,7 @@ function assertNoNoteSecretLikeText(fields) {
844665
844723
  }
844666
844724
  }
844667
844725
  function parseNote(value) {
844668
- if (!isRecord27(value))
844726
+ if (!isRecord28(value))
844669
844727
  return null;
844670
844728
  const id = readString35(value.id).trim();
844671
844729
  const title = normalizeTitle(readString35(value.title));
@@ -844694,7 +844752,7 @@ function parseNote(value) {
844694
844752
  }
844695
844753
  function parseStore2(raw) {
844696
844754
  const parsed = JSON.parse(raw);
844697
- if (!isRecord27(parsed))
844755
+ if (!isRecord28(parsed))
844698
844756
  return { version: STORE_VERSION2, notes: [] };
844699
844757
  return {
844700
844758
  version: STORE_VERSION2,
@@ -844899,7 +844957,7 @@ import { dirname as dirname51 } from "path";
844899
844957
  import { accessSync, constants as constants4, existsSync as existsSync67, mkdirSync as mkdirSync49, readFileSync as readFileSync71, renameSync as renameSync14, writeFileSync as writeFileSync43 } from "fs";
844900
844958
  import { delimiter, dirname as dirname50, join as join85 } from "path";
844901
844959
  var STORE_VERSION3 = 1;
844902
- function isRecord28(value) {
844960
+ function isRecord29(value) {
844903
844961
  return typeof value === "object" && value !== null && !Array.isArray(value);
844904
844962
  }
844905
844963
  function readString36(value, fallback = "") {
@@ -844967,7 +845025,7 @@ function normalizeRequirements(values2) {
844967
845025
  function parseRequirements(value) {
844968
845026
  if (!Array.isArray(value))
844969
845027
  return [];
844970
- return normalizeRequirements(value.filter(isRecord28).map((entry) => ({
845028
+ return normalizeRequirements(value.filter(isRecord29).map((entry) => ({
844971
845029
  kind: readRequirementKind(entry.kind) ?? "env",
844972
845030
  name: readString36(entry.name).trim(),
844973
845031
  description: readString36(entry.description).trim()
@@ -844994,7 +845052,7 @@ function commandExists(command8, pathValue) {
844994
845052
  return pathValue.split(delimiter).filter(Boolean).some((pathEntry) => canExecute(join85(pathEntry, command8)));
844995
845053
  }
844996
845054
  function parseSkill(value) {
844997
- if (!isRecord28(value))
845055
+ if (!isRecord29(value))
844998
845056
  return null;
844999
845057
  const id = readString36(value.id).trim();
845000
845058
  const name51 = normalizeName2(readString36(value.name));
@@ -845025,7 +845083,7 @@ function parseSkill(value) {
845025
845083
  };
845026
845084
  }
845027
845085
  function parseBundle(value) {
845028
- if (!isRecord28(value))
845086
+ if (!isRecord29(value))
845029
845087
  return null;
845030
845088
  const id = readString36(value.id).trim();
845031
845089
  const name51 = normalizeName2(readString36(value.name));
@@ -845054,7 +845112,7 @@ function parseBundle(value) {
845054
845112
  }
845055
845113
  function parseStore3(raw) {
845056
845114
  const parsed = JSON.parse(raw);
845057
- if (!isRecord28(parsed))
845115
+ if (!isRecord29(parsed))
845058
845116
  return { version: STORE_VERSION3, skills: [], bundles: [] };
845059
845117
  return {
845060
845118
  version: STORE_VERSION3,
@@ -845544,7 +845602,7 @@ function buildEnabledSkillsPrompt(shellPaths) {
845544
845602
 
845545
845603
  // src/agent/routine-registry.ts
845546
845604
  var STORE_VERSION4 = 1;
845547
- function isRecord29(value) {
845605
+ function isRecord30(value) {
845548
845606
  return typeof value === "object" && value !== null && !Array.isArray(value);
845549
845607
  }
845550
845608
  function readString37(value, fallback = "") {
@@ -845558,7 +845616,7 @@ function readStringArray11(value) {
845558
845616
  function readRequirementArray(value) {
845559
845617
  if (!Array.isArray(value))
845560
845618
  return [];
845561
- const requirements = value.filter(isRecord29).map((entry) => ({
845619
+ const requirements = value.filter(isRecord30).map((entry) => ({
845562
845620
  kind: entry.kind === "command" ? "command" : "env",
845563
845621
  name: readString37(entry.name).trim(),
845564
845622
  description: readString37(entry.description).trim() || undefined
@@ -845595,7 +845653,7 @@ function nowIso4() {
845595
845653
  return new Date().toISOString();
845596
845654
  }
845597
845655
  function parseRoutine(value) {
845598
- if (!isRecord29(value))
845656
+ if (!isRecord30(value))
845599
845657
  return null;
845600
845658
  const id = readString37(value.id).trim();
845601
845659
  const name51 = normalizeName3(readString37(value.name));
@@ -845630,7 +845688,7 @@ function parseRoutine(value) {
845630
845688
  }
845631
845689
  function parseStore4(raw) {
845632
845690
  const parsed = JSON.parse(raw);
845633
- if (!isRecord29(parsed))
845691
+ if (!isRecord30(parsed))
845634
845692
  return { version: STORE_VERSION4, routines: [] };
845635
845693
  return {
845636
845694
  version: STORE_VERSION4,
@@ -846944,7 +847002,7 @@ function registerAgentMediaGenerateTool(registry5, mediaProviderRegistry, artifa
846944
847002
  }
846945
847003
 
846946
847004
  // src/tools/agent-notify-tool.ts
846947
- function isRecord30(value) {
847005
+ function isRecord31(value) {
846948
847006
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
846949
847007
  }
846950
847008
  function readString40(value) {
@@ -846955,7 +847013,7 @@ function readBoolean10(value) {
846955
847013
  }
846956
847014
  function configuredWebhookUrls(configManager) {
846957
847015
  const category = configManager.getCategory("notifications");
846958
- if (!isRecord30(category) || !Array.isArray(category.webhookUrls))
847016
+ if (!isRecord31(category) || !Array.isArray(category.webhookUrls))
846959
847017
  return [];
846960
847018
  return category.webhookUrls.filter((url2) => typeof url2 === "string").map((url2) => url2.trim()).filter((url2) => url2.length > 0);
846961
847019
  }
@@ -847107,7 +847165,7 @@ var OPERATOR_ACTIONS = {
847107
847165
  }
847108
847166
  };
847109
847167
  var OPERATOR_ACTION_IDS = Object.keys(OPERATOR_ACTIONS);
847110
- function isRecord31(value) {
847168
+ function isRecord32(value) {
847111
847169
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
847112
847170
  }
847113
847171
  function readOperatorActionString(value) {
@@ -847149,7 +847207,7 @@ function requestBody(args2, action2) {
847149
847207
  return Object.keys(out2).length > 0 ? out2 : null;
847150
847208
  }
847151
847209
  function buildOperatorActionRequest(rawArgs) {
847152
- if (!isRecord31(rawArgs))
847210
+ if (!isRecord32(rawArgs))
847153
847211
  return { ok: false, error: "Operator action arguments must be an object." };
847154
847212
  const args2 = rawArgs;
847155
847213
  if (!isOperatorActionId(args2.action)) {
@@ -847187,7 +847245,7 @@ function summarizeError2(error51) {
847187
847245
  return error51 instanceof Error ? error51.message : String(error51);
847188
847246
  }
847189
847247
  function classifyHttpFailure(methodId, path7, status, body2) {
847190
- const detail = isRecord31(body2) && typeof body2.error === "string" ? body2.error : "";
847248
+ const detail = isRecord32(body2) && typeof body2.error === "string" ? body2.error : "";
847191
847249
  return {
847192
847250
  ok: false,
847193
847251
  methodId,
@@ -847241,13 +847299,13 @@ async function postOperatorAction(connection5, request2) {
847241
847299
  }
847242
847300
  }
847243
847301
  function statusFromOperatorActionBody(body2) {
847244
- if (!isRecord31(body2))
847302
+ if (!isRecord32(body2))
847245
847303
  return "ok";
847246
847304
  const approval = body2.approval;
847247
- if (isRecord31(approval) && typeof approval.status === "string")
847305
+ if (isRecord32(approval) && typeof approval.status === "string")
847248
847306
  return approval.status;
847249
847307
  const run7 = body2.run;
847250
- if (isRecord31(run7) && typeof run7.status === "string")
847308
+ if (isRecord32(run7) && typeof run7.status === "string")
847251
847309
  return run7.status;
847252
847310
  if (typeof body2.status === "string")
847253
847311
  return body2.status;
@@ -847371,7 +847429,7 @@ function createAgentOperatorActionTool(shellPaths, configManager) {
847371
847429
  if (!request2.ok) {
847372
847430
  return { success: false, error: request2.error };
847373
847431
  }
847374
- const args2 = isRecord31(rawArgs) ? rawArgs : {};
847432
+ const args2 = isRecord32(rawArgs) ? rawArgs : {};
847375
847433
  const explicitUserRequest = readOperatorActionString(args2.explicitUserRequest);
847376
847434
  if (!explicitUserRequest) {
847377
847435
  return {
@@ -847414,23 +847472,23 @@ var OPERATOR_BRIEFING_ROUTES = [
847414
847472
  { id: "schedules.list", path: "/api/automation/schedules" },
847415
847473
  { id: "scheduler.capacity", path: "/api/runtime/scheduler" }
847416
847474
  ];
847417
- function isRecord32(value) {
847475
+ function isRecord33(value) {
847418
847476
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
847419
847477
  }
847420
847478
  function readRecord20(value, key) {
847421
- return isRecord32(value) && isRecord32(value[key]) ? value[key] : {};
847479
+ return isRecord33(value) && isRecord33(value[key]) ? value[key] : {};
847422
847480
  }
847423
847481
  function readArray3(value, key) {
847424
- return isRecord32(value) && Array.isArray(value[key]) ? value[key] : [];
847482
+ return isRecord33(value) && Array.isArray(value[key]) ? value[key] : [];
847425
847483
  }
847426
847484
  function readNumber9(value, key) {
847427
- if (!isRecord32(value))
847485
+ if (!isRecord33(value))
847428
847486
  return null;
847429
847487
  const candidate = value[key];
847430
847488
  return typeof candidate === "number" && Number.isFinite(candidate) ? candidate : null;
847431
847489
  }
847432
847490
  function readString41(value, key) {
847433
- if (!isRecord32(value))
847491
+ if (!isRecord33(value))
847434
847492
  return null;
847435
847493
  const candidate = value[key];
847436
847494
  return typeof candidate === "string" ? candidate : null;
@@ -847449,7 +847507,7 @@ async function readResponseBody2(response5) {
847449
847507
  }
847450
847508
  }
847451
847509
  function classifyHttpFailure2(route, status, body2) {
847452
- const detail = isRecord32(body2) && typeof body2.error === "string" ? body2.error : "";
847510
+ const detail = isRecord33(body2) && typeof body2.error === "string" ? body2.error : "";
847453
847511
  return {
847454
847512
  ok: false,
847455
847513
  route,
@@ -847483,7 +847541,7 @@ function formatWorkPlan(body2) {
847483
847541
  function formatApprovals(body2) {
847484
847542
  const approvals = readArray3(body2, "approvals");
847485
847543
  const pending = approvals.filter((entry) => readString41(entry, "status") === "pending").length;
847486
- return ` approvals: pending ${pending}; total ${approvals.length}; mode ${readString41(body2, "mode") ?? "unknown"}; awaiting decision ${readString41(body2, "awaitingDecision") ?? String(Boolean(isRecord32(body2) && body2.awaitingDecision))}`;
847544
+ return ` approvals: pending ${pending}; total ${approvals.length}; mode ${readString41(body2, "mode") ?? "unknown"}; awaiting decision ${readString41(body2, "awaitingDecision") ?? String(Boolean(isRecord33(body2) && body2.awaitingDecision))}`;
847487
847545
  }
847488
847546
  function formatAutomation(body2) {
847489
847547
  const totals = readRecord20(body2, "totals");
@@ -847493,7 +847551,7 @@ function formatAutomation(body2) {
847493
847551
  function formatSchedules(body2) {
847494
847552
  const jobs = readArray3(body2, "jobs");
847495
847553
  const runs = readArray3(body2, "runs");
847496
- const enabled = jobs.filter((entry) => isRecord32(entry) && entry.enabled === true).length;
847554
+ const enabled = jobs.filter((entry) => isRecord33(entry) && entry.enabled === true).length;
847497
847555
  return ` schedules: jobs ${jobs.length}; enabled ${enabled}; runs ${runs.length}`;
847498
847556
  }
847499
847557
  function formatCapacity(body2) {
@@ -847959,7 +848017,7 @@ function resolveReminderConnectedHostConnection(configManager, homeDirectory) {
847959
848017
  }
847960
848018
 
847961
848019
  // src/agent/reminder-schedule-format.ts
847962
- function isRecord33(value) {
848020
+ function isRecord34(value) {
847963
848021
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
847964
848022
  }
847965
848023
  function readString42(record2, key) {
@@ -848005,7 +848063,7 @@ function formatReminderSchedulePreview(preview4) {
848005
848063
  `);
848006
848064
  }
848007
848065
  function formatReminderScheduleSuccess(result2) {
848008
- const record2 = isRecord33(result2.schedule) ? result2.schedule : {};
848066
+ const record2 = isRecord34(result2.schedule) ? result2.schedule : {};
848009
848067
  const id = readString42(record2, "id") ?? "(unknown)";
848010
848068
  const status = readString42(record2, "status") ?? (record2.enabled === false ? "paused" : "enabled");
848011
848069
  return [
@@ -850525,7 +850583,7 @@ var recallCommand = {
850525
850583
  var KNOWLEDGE_REVIEW_ACTIONS = ["accept", "reject", "resolve", "reopen", "edit", "forget"];
850526
850584
  var BROWSER_KINDS = ["chrome", "chromium", "brave", "edge", "vivaldi", "arc", "opera", "firefox", "zen", "librewolf", "waterfox", "floorp", "safari", "orion", "epiphany"];
850527
850585
  var BROWSER_SOURCE_KINDS = ["history", "bookmark"];
850528
- function isRecord34(value) {
850586
+ function isRecord35(value) {
850529
850587
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
850530
850588
  }
850531
850589
  function requireAgentKnowledgeApi(context) {
@@ -850625,7 +850683,7 @@ function readJsonObjectFlag(args2, name51) {
850625
850683
  return;
850626
850684
  try {
850627
850685
  const parsed = JSON.parse(value);
850628
- return isRecord34(parsed) ? parsed : null;
850686
+ return isRecord35(parsed) ? parsed : null;
850629
850687
  } catch {
850630
850688
  return null;
850631
850689
  }
@@ -852071,7 +852129,7 @@ function parseRoutineSchedulePromotionArgs(args2) {
852071
852129
  }
852072
852130
 
852073
852131
  // src/agent/routine-schedule-format.ts
852074
- function isRecord35(value) {
852132
+ function isRecord36(value) {
852075
852133
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
852076
852134
  }
852077
852135
  function readString45(record2, key) {
@@ -852123,7 +852181,7 @@ function formatRoutineSchedulePreview(preview4) {
852123
852181
  `);
852124
852182
  }
852125
852183
  function formatRoutineScheduleSuccess(result2) {
852126
- const record2 = isRecord35(result2.schedule) ? result2.schedule : {};
852184
+ const record2 = isRecord36(result2.schedule) ? result2.schedule : {};
852127
852185
  const id = readString45(record2, "id") ?? "(unknown)";
852128
852186
  const status = readString45(record2, "status") ?? (record2.enabled === false ? "paused" : "enabled");
852129
852187
  return [
@@ -852244,7 +852302,7 @@ import { existsSync as existsSync69, mkdirSync as mkdirSync52, readFileSync as r
852244
852302
  import { dirname as dirname53 } from "path";
852245
852303
  init_automation2();
852246
852304
  var RECEIPT_STORE_VERSION = 1;
852247
- function isRecord36(value) {
852305
+ function isRecord37(value) {
852248
852306
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
852249
852307
  }
852250
852308
  function readString46(record2, key) {
@@ -852297,7 +852355,7 @@ function normalizeFailureKind(value) {
852297
852355
  return;
852298
852356
  }
852299
852357
  function readReceipt(value) {
852300
- if (!isRecord36(value))
852358
+ if (!isRecord37(value))
852301
852359
  return null;
852302
852360
  const id = readString46(value, "id")?.trim();
852303
852361
  const createdAt = readString46(value, "createdAt")?.trim();
@@ -852306,9 +852364,9 @@ function readReceipt(value) {
852306
852364
  const status = value.status === "created" || value.status === "failed" ? value.status : null;
852307
852365
  const scheduleKind = value.scheduleKind === "cron" || value.scheduleKind === "every" || value.scheduleKind === "at" ? value.scheduleKind : null;
852308
852366
  const scheduleValue2 = readString46(value, "scheduleValue")?.trim();
852309
- const target = isRecord36(value.target) ? value.target : {};
852367
+ const target = isRecord37(value.target) ? value.target : {};
852310
852368
  const deliveryTargets = Array.isArray(value.deliveryTargets) ? value.deliveryTargets.map((target2) => {
852311
- if (!isRecord36(target2))
852369
+ if (!isRecord37(target2))
852312
852370
  return null;
852313
852371
  const kind2 = target2.kind === "webhook" || target2.kind === "surface" || target2.kind === "integration" || target2.kind === "link" ? target2.kind : null;
852314
852372
  if (!kind2)
@@ -852356,7 +852414,7 @@ function readReceipt(value) {
852356
852414
  }
852357
852415
  function parseReceiptStore(raw) {
852358
852416
  const parsed = JSON.parse(raw);
852359
- if (!isRecord36(parsed))
852417
+ if (!isRecord37(parsed))
852360
852418
  return { version: RECEIPT_STORE_VERSION, receipts: [] };
852361
852419
  return {
852362
852420
  version: RECEIPT_STORE_VERSION,
@@ -852393,7 +852451,7 @@ function scheduleKind(payload) {
852393
852451
  throw new Error("Routine schedule payload is missing a schedule kind.");
852394
852452
  }
852395
852453
  function targetSummary(payload) {
852396
- return isRecord36(payload.target) ? {
852454
+ return isRecord37(payload.target) ? {
852397
852455
  kind: typeof payload.target.kind === "string" ? payload.target.kind : undefined,
852398
852456
  surfaceKind: typeof payload.target.surfaceKind === "string" ? payload.target.surfaceKind : undefined,
852399
852457
  preserveThread: typeof payload.target.preserveThread === "boolean" ? payload.target.preserveThread : undefined,
@@ -852401,10 +852459,10 @@ function targetSummary(payload) {
852401
852459
  } : {};
852402
852460
  }
852403
852461
  function deliveryMode(payload) {
852404
- return isRecord36(payload.delivery) && typeof payload.delivery.mode === "string" ? payload.delivery.mode : undefined;
852462
+ return isRecord37(payload.delivery) && typeof payload.delivery.mode === "string" ? payload.delivery.mode : undefined;
852405
852463
  }
852406
852464
  function resultScheduleRecord(result2) {
852407
- return result2.ok && isRecord36(result2.schedule) ? result2.schedule : {};
852465
+ return result2.ok && isRecord37(result2.schedule) ? result2.schedule : {};
852408
852466
  }
852409
852467
  function buildReceipt(existing, connection5, preview4, result2) {
852410
852468
  const createdAt = nowIso5();
@@ -852492,7 +852550,7 @@ function isoTime(value) {
852492
852550
  return Number.isFinite(time4) ? new Date(time4).toISOString() : null;
852493
852551
  }
852494
852552
  function readLiveScheduleDefinition(value) {
852495
- if (!isRecord36(value))
852553
+ if (!isRecord37(value))
852496
852554
  return {};
852497
852555
  if (value.kind === "cron") {
852498
852556
  return {
@@ -852518,7 +852576,7 @@ function readLiveScheduleDefinition(value) {
852518
852576
  return {};
852519
852577
  }
852520
852578
  function readLiveScheduleRecord(value) {
852521
- if (!isRecord36(value))
852579
+ if (!isRecord37(value))
852522
852580
  return null;
852523
852581
  const id = readString46(value, "id")?.trim();
852524
852582
  const name51 = readString46(value, "name")?.trim();
@@ -852541,7 +852599,7 @@ function readLiveScheduleRecord(value) {
852541
852599
  };
852542
852600
  }
852543
852601
  function readLiveSchedules(output6) {
852544
- const record2 = isRecord36(output6) ? output6 : {};
852602
+ const record2 = isRecord37(output6) ? output6 : {};
852545
852603
  const jobs = Array.isArray(record2.jobs) ? record2.jobs : [];
852546
852604
  return jobs.map(readLiveScheduleRecord).filter((schedule) => schedule !== null);
852547
852605
  }
@@ -858558,6 +858616,14 @@ function registerWorkPlanRuntimeCommands(registry5) {
858558
858616
  var AGENT_WORKSPACE_CATEGORY_IDS = [
858559
858617
  "home",
858560
858618
  "setup",
858619
+ "account-model",
858620
+ "assistant-behavior",
858621
+ "tools-permissions",
858622
+ "onboarding-display",
858623
+ "onboarding-channels",
858624
+ "onboarding-voice-media",
858625
+ "onboarding-context",
858626
+ "onboarding-verify",
858561
858627
  "research",
858562
858628
  "artifacts",
858563
858629
  "conversation",
@@ -859127,7 +859193,7 @@ var STARTER_TEMPLATES = [
859127
859193
  var PROFILE_CREATED_FILE = "profile.json";
859128
859194
  var PROFILE_SELECTION_FILE = "profile-selection.json";
859129
859195
  var PROFILE_ID_PATTERN = /^[a-z0-9](?:[a-z0-9._-]{0,62}[a-z0-9])?$/;
859130
- function isRecord37(value) {
859196
+ function isRecord38(value) {
859131
859197
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
859132
859198
  }
859133
859199
  function normalizeAgentRuntimeProfileId(value) {
@@ -859166,7 +859232,7 @@ function readAgentRuntimeProfileSelection(baseHomeDirectory) {
859166
859232
  return null;
859167
859233
  try {
859168
859234
  const raw = JSON.parse(readFileSync81(path7, "utf-8"));
859169
- if (!isRecord37(raw))
859235
+ if (!isRecord38(raw))
859170
859236
  return null;
859171
859237
  const profileId = raw.profileId;
859172
859238
  if (typeof profileId !== "string")
@@ -859211,10 +859277,10 @@ function readProfileStarterTemplate(homeDirectory) {
859211
859277
  return {};
859212
859278
  try {
859213
859279
  const raw = JSON.parse(readFileSync81(path7, "utf-8"));
859214
- if (!isRecord37(raw))
859280
+ if (!isRecord38(raw))
859215
859281
  return {};
859216
859282
  const starter = raw.starterTemplate;
859217
- if (!isRecord37(starter))
859283
+ if (!isRecord38(starter))
859218
859284
  return {};
859219
859285
  const id = starter.id;
859220
859286
  const name51 = starter.name;
@@ -859332,7 +859398,7 @@ function readTemplateTextBlock(value, field) {
859332
859398
  return value.trim();
859333
859399
  }
859334
859400
  function readTemplateObject(value, field) {
859335
- if (!isRecord37(value))
859401
+ if (!isRecord38(value))
859336
859402
  throw new Error(`Starter template ${field} must be an object.`);
859337
859403
  return value;
859338
859404
  }
@@ -861556,7 +861622,7 @@ var CHANNEL_FAILURE_LABELS = {
861556
861622
  connected_host_route_unavailable: "connected host route unavailable",
861557
861623
  connected_host_error: "connected host error"
861558
861624
  };
861559
- function isRecord38(value) {
861625
+ function isRecord39(value) {
861560
861626
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
861561
861627
  }
861562
861628
  function readString47(record2, key, fallback = "") {
@@ -861569,7 +861635,7 @@ function readBoolean14(record2, key, fallback = false) {
861569
861635
  }
861570
861636
  function readRecordArray(record2, key) {
861571
861637
  const value = record2[key];
861572
- return Array.isArray(value) ? value.filter(isRecord38) : [];
861638
+ return Array.isArray(value) ? value.filter(isRecord39) : [];
861573
861639
  }
861574
861640
  function readFlagValue3(args2, index, flag, errors4) {
861575
861641
  const value = args2[index + 1];
@@ -861638,7 +861704,7 @@ function resolveChannelConnectedHostConnection(context) {
861638
861704
  return { baseUrl: `http://${host}:${port}`, token: null, tokenPath };
861639
861705
  try {
861640
861706
  const parsed = JSON.parse(readFileSync82(tokenPath, "utf-8"));
861641
- const token = isRecord38(parsed) && typeof parsed.token === "string" ? parsed.token : null;
861707
+ const token = isRecord39(parsed) && typeof parsed.token === "string" ? parsed.token : null;
861642
861708
  return { baseUrl: `http://${host}:${port}`, token, tokenPath };
861643
861709
  } catch {
861644
861710
  return { baseUrl: `http://${host}:${port}`, token: null, tokenPath };
@@ -861669,7 +861735,7 @@ async function fetchChannelRoute(context, route) {
861669
861735
  }
861670
861736
  }
861671
861737
  if (!response5.ok) {
861672
- const detail = isRecord38(body2) && typeof body2.error === "string" ? body2.error : text;
861738
+ const detail = isRecord39(body2) && typeof body2.error === "string" ? body2.error : text;
861673
861739
  return {
861674
861740
  ok: false,
861675
861741
  route,
@@ -861759,7 +861825,7 @@ function printChannelDetail(print2, channel) {
861759
861825
  `));
861760
861826
  }
861761
861827
  function formatChannelAccounts(body2) {
861762
- const root = isRecord38(body2) ? body2 : {};
861828
+ const root = isRecord39(body2) ? body2 : {};
861763
861829
  const accounts = readRecordArray(root, "accounts");
861764
861830
  const lines = [
861765
861831
  "Channel Accounts",
@@ -861785,7 +861851,7 @@ function formatChannelAccounts(body2) {
861785
861851
  `);
861786
861852
  }
861787
861853
  function formatChannelPolicies(body2) {
861788
- const root = isRecord38(body2) ? body2 : {};
861854
+ const root = isRecord39(body2) ? body2 : {};
861789
861855
  const policies = readRecordArray(root, "policies");
861790
861856
  const lines = [
861791
861857
  "Channel Policies",
@@ -861810,7 +861876,7 @@ function formatChannelPolicies(body2) {
861810
861876
  `);
861811
861877
  }
861812
861878
  function formatChannelStatus(body2) {
861813
- const root = isRecord38(body2) ? body2 : {};
861879
+ const root = isRecord39(body2) ? body2 : {};
861814
861880
  const channels = readRecordArray(root, "channels");
861815
861881
  const lines = [
861816
861882
  "Connected Channel Status",
@@ -861834,7 +861900,7 @@ function formatChannelStatus(body2) {
861834
861900
  `);
861835
861901
  }
861836
861902
  function formatChannelDoctor(surface, body2) {
861837
- const root = isRecord38(body2) ? body2 : {};
861903
+ const root = isRecord39(body2) ? body2 : {};
861838
861904
  const checks3 = readRecordArray(root, "checks");
861839
861905
  const repairActions = readRecordArray(root, "repairActions");
861840
861906
  const lines = [
@@ -861858,7 +861924,7 @@ function formatChannelDoctor(surface, body2) {
861858
861924
  `);
861859
861925
  }
861860
861926
  function formatChannelSetup(surface, body2) {
861861
- const root = isRecord38(body2) ? body2 : {};
861927
+ const root = isRecord39(body2) ? body2 : {};
861862
861928
  const fields = readRecordArray(root, "fields");
861863
861929
  const secretTargets = readRecordArray(root, "secretTargets");
861864
861930
  const lines = [
@@ -864575,13 +864641,13 @@ function getNestedValue(source, key) {
864575
864641
  }
864576
864642
  return cursor;
864577
864643
  }
864578
- function isRecord39(value) {
864644
+ function isRecord40(value) {
864579
864645
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
864580
864646
  }
864581
864647
  function readJsonFile2(path7) {
864582
864648
  try {
864583
864649
  const value = JSON.parse(readFileSync87(path7, "utf-8"));
864584
- if (!isRecord39(value))
864650
+ if (!isRecord40(value))
864585
864651
  return { ok: false, error: "Bundle file must contain a JSON object." };
864586
864652
  return { ok: true, value };
864587
864653
  } catch (error51) {
@@ -866782,29 +866848,29 @@ function usage() {
866782
866848
  ].join(`
866783
866849
  `);
866784
866850
  }
866785
- function isRecord40(value) {
866851
+ function isRecord41(value) {
866786
866852
  return typeof value === "object" && value !== null && !Array.isArray(value);
866787
866853
  }
866788
866854
  function isStringArray6(value) {
866789
866855
  return Array.isArray(value) && value.every((entry) => typeof entry === "string");
866790
866856
  }
866791
866857
  function isProvenanceLink(value) {
866792
- if (!isRecord40(value))
866858
+ if (!isRecord41(value))
866793
866859
  return false;
866794
866860
  return typeof value.ref === "string" && typeof value.kind === "string" && isProvenanceKind(value.kind);
866795
866861
  }
866796
866862
  function isMemoryRecord(value) {
866797
- if (!isRecord40(value))
866863
+ if (!isRecord41(value))
866798
866864
  return false;
866799
866865
  return typeof value.id === "string" && typeof value.scope === "string" && isMemoryScope2(value.scope) && typeof value.cls === "string" && isMemoryClass2(value.cls) && typeof value.summary === "string" && (value.detail === undefined || typeof value.detail === "string") && isStringArray6(value.tags) && Array.isArray(value.provenance) && value.provenance.every(isProvenanceLink) && typeof value.reviewState === "string" && isReviewState(value.reviewState) && typeof value.confidence === "number" && typeof value.createdAt === "number" && typeof value.updatedAt === "number";
866800
866866
  }
866801
866867
  function isMemoryLink(value) {
866802
- if (!isRecord40(value))
866868
+ if (!isRecord41(value))
866803
866869
  return false;
866804
866870
  return typeof value.fromId === "string" && typeof value.toId === "string" && typeof value.relation === "string" && typeof value.createdAt === "number";
866805
866871
  }
866806
866872
  function isMemoryBundle(value) {
866807
- if (!isRecord40(value))
866873
+ if (!isRecord41(value))
866808
866874
  return false;
866809
866875
  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);
866810
866876
  }
@@ -869250,7 +869316,7 @@ async function handleDelegateCommand(runtime2) {
869250
869316
  surfaceKind: "goodvibes-agent",
869251
869317
  surfaceId: "goodvibes-agent-cli"
869252
869318
  });
869253
- const sessionId = isRecord24(created.session) && typeof created.session.id === "string" ? created.session.id : null;
869319
+ const sessionId = isRecord25(created.session) && typeof created.session.id === "string" ? created.session.id : null;
869254
869320
  if (!sessionId)
869255
869321
  throw new Error("sessions.create returned no session id.");
869256
869322
  const message = await sdk.operator.invoke("sessions.messages.create", {
@@ -887128,11 +887194,11 @@ function readLimit19(value, fallback) {
887128
887194
  return fallback;
887129
887195
  return Math.max(1, Math.min(100, Math.trunc(parsed)));
887130
887196
  }
887131
- function isRecord41(value) {
887197
+ function isRecord42(value) {
887132
887198
  return typeof value === "object" && value !== null && !Array.isArray(value);
887133
887199
  }
887134
887200
  function asRecord4(value) {
887135
- return isRecord41(value) ? value : {};
887201
+ return isRecord42(value) ? value : {};
887136
887202
  }
887137
887203
  function normalized(value) {
887138
887204
  return value.toLowerCase();
@@ -887227,7 +887293,7 @@ function summarizeJsonArtifact(artifactId, parsed) {
887227
887293
  };
887228
887294
  }
887229
887295
  if (artifactId === "release-readiness") {
887230
- const items = Array.isArray(root.items) ? root.items.filter(isRecord41) : [];
887296
+ const items = Array.isArray(root.items) ? root.items.filter(isRecord42) : [];
887231
887297
  return {
887232
887298
  gate: root.gate,
887233
887299
  checkedAt: root.checkedAt,
@@ -887398,7 +887464,7 @@ var QUALITY_DIMENSIONS = [
887398
887464
  "safetyBoundary",
887399
887465
  "releaseEvidence"
887400
887466
  ];
887401
- function isRecord42(value) {
887467
+ function isRecord43(value) {
887402
887468
  return typeof value === "object" && value !== null && !Array.isArray(value);
887403
887469
  }
887404
887470
  function readString65(value) {
@@ -887417,7 +887483,7 @@ function loadReleaseReadiness() {
887417
887483
  try {
887418
887484
  const source = readFileSync92(RELEASE_READINESS_PATH, "utf-8");
887419
887485
  const parsed = JSON.parse(source);
887420
- if (!isRecord42(parsed))
887486
+ if (!isRecord43(parsed))
887421
887487
  return { status: "unavailable", reason: `${RELEASE_READINESS_RELATIVE_PATH} must contain a JSON object.` };
887422
887488
  return { status: "available", root: parsed, source };
887423
887489
  } catch (error52) {
@@ -887426,10 +887492,10 @@ function loadReleaseReadiness() {
887426
887492
  }
887427
887493
  }
887428
887494
  function releaseReadinessItems(root) {
887429
- return Array.isArray(root.items) ? root.items.filter(isRecord42) : [];
887495
+ return Array.isArray(root.items) ? root.items.filter(isRecord43) : [];
887430
887496
  }
887431
887497
  function releaseReadinessSources(root) {
887432
- return Array.isArray(root.sources) ? root.sources.filter(isRecord42) : [];
887498
+ return Array.isArray(root.sources) ? root.sources.filter(isRecord43) : [];
887433
887499
  }
887434
887500
  function normalized2(value) {
887435
887501
  return value.toLowerCase();
@@ -887441,7 +887507,7 @@ function itemSearchText(item) {
887441
887507
  if (typeof value === "string")
887442
887508
  fields.push(value);
887443
887509
  }
887444
- if (isRecord42(item.quality)) {
887510
+ if (isRecord43(item.quality)) {
887445
887511
  fields.push(...Object.values(item.quality).filter((value) => typeof value === "string"));
887446
887512
  }
887447
887513
  return fields.join(`
@@ -887470,7 +887536,7 @@ function countBy2(items, key) {
887470
887536
  }
887471
887537
  function qualityDimensionCount(item) {
887472
887538
  const quality = item.quality;
887473
- if (!isRecord42(quality))
887539
+ if (!isRecord43(quality))
887474
887540
  return 0;
887475
887541
  return QUALITY_DIMENSIONS.filter((dimension2) => readString65(quality[dimension2])).length;
887476
887542
  }
@@ -887707,11 +887773,11 @@ function readLimit21(value, fallback) {
887707
887773
  return fallback;
887708
887774
  return Math.max(1, Math.min(500, Math.trunc(parsed)));
887709
887775
  }
887710
- function isRecord43(value) {
887776
+ function isRecord44(value) {
887711
887777
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
887712
887778
  }
887713
887779
  function readRecordArray2(value) {
887714
- return Array.isArray(value) ? value.filter(isRecord43) : [];
887780
+ return Array.isArray(value) ? value.filter(isRecord44) : [];
887715
887781
  }
887716
887782
  function readArray4(value) {
887717
887783
  return Array.isArray(value) ? value : [];
@@ -887719,7 +887785,7 @@ function readArray4(value) {
887719
887785
  function readNestedValue(source, path7) {
887720
887786
  let cursor = source;
887721
887787
  for (const part of path7.split(".")) {
887722
- if (!isRecord43(cursor))
887788
+ if (!isRecord44(cursor))
887723
887789
  return;
887724
887790
  cursor = cursor[part];
887725
887791
  }
@@ -887798,11 +887864,11 @@ function describeFinding(finding, includeParameters, lookup) {
887798
887864
  };
887799
887865
  }
887800
887866
  function buildTokenFindings(securitySnapshot) {
887801
- const audit = isRecord43(securitySnapshot?.audit) ? securitySnapshot.audit : null;
887867
+ const audit = isRecord44(securitySnapshot?.audit) ? securitySnapshot.audit : null;
887802
887868
  const results = readRecordArray2(audit?.results);
887803
887869
  return results.map((result2, index) => {
887804
- const scope = isRecord43(result2.scope) ? result2.scope : {};
887805
- const rotation = isRecord43(result2.rotation) ? result2.rotation : {};
887870
+ const scope = isRecord44(result2.scope) ? result2.scope : {};
887871
+ const rotation = isRecord44(result2.rotation) ? result2.rotation : {};
887806
887872
  const label = safeText(result2.label, `token-${index + 1}`);
887807
887873
  const scopeOutcome = safeText(scope.outcome);
887808
887874
  const rotationOutcome = safeText(rotation.outcome);
@@ -887852,7 +887918,7 @@ function buildPolicyFindings(context) {
887852
887918
  }
887853
887919
  };
887854
887920
  });
887855
- const preflight = isRecord43(policySnapshot.lastPreflightReview) ? policySnapshot.lastPreflightReview : null;
887921
+ const preflight = isRecord44(policySnapshot.lastPreflightReview) ? policySnapshot.lastPreflightReview : null;
887856
887922
  if (!preflight || safeText(preflight.status, "ok") === "ok")
887857
887923
  return findings;
887858
887924
  return [
@@ -887874,7 +887940,7 @@ function buildPolicyFindings(context) {
887874
887940
  function buildMcpFindings(securitySnapshot) {
887875
887941
  const mcpServers = readRecordArray2(securitySnapshot?.mcpServers);
887876
887942
  const recentMcpDecisions = readArray4(securitySnapshot?.recentMcpDecisions);
887877
- const attackPathReview = isRecord43(securitySnapshot?.attackPathReview) ? securitySnapshot.attackPathReview : buildMcpAttackPathReview2({ servers: mcpServers, recentDecisions: recentMcpDecisions });
887943
+ const attackPathReview = isRecord44(securitySnapshot?.attackPathReview) ? securitySnapshot.attackPathReview : buildMcpAttackPathReview2({ servers: mcpServers, recentDecisions: recentMcpDecisions });
887878
887944
  const attackFindings = readRecordArray2(attackPathReview.findings).map((finding, index) => {
887879
887945
  const serverName = safeText(finding.serverName, `server-${index + 1}`);
887880
887946
  const severityRaw = safeText(finding.severity, "warn").toLowerCase();
@@ -887978,7 +888044,7 @@ function buildIncidentFindings(securitySnapshot) {
887978
888044
  function readSecuritySnapshot(context) {
887979
888045
  try {
887980
888046
  const snapshot2 = context.platform.readModels?.security.getSnapshot();
887981
- return isRecord43(snapshot2) ? snapshot2 : null;
888047
+ return isRecord44(snapshot2) ? snapshot2 : null;
887982
888048
  } catch {
887983
888049
  return null;
887984
888050
  }
@@ -888016,8 +888082,8 @@ async function securityPostureSummary(context, args2) {
888016
888082
  policy: "Security read models are unavailable in this Agent context."
888017
888083
  };
888018
888084
  }
888019
- const audit = isRecord43(securitySnapshot.audit) ? securitySnapshot.audit : {};
888020
- const policy = isRecord43(securitySnapshot.policy) ? securitySnapshot.policy : {};
888085
+ const audit = isRecord44(securitySnapshot.audit) ? securitySnapshot.audit : {};
888086
+ const policy = isRecord44(securitySnapshot.policy) ? securitySnapshot.policy : {};
888021
888087
  const mcpServers = readRecordArray2(securitySnapshot.mcpServers);
888022
888088
  const plugins2 = readRecordArray2(securitySnapshot.plugins);
888023
888089
  const subscriptions = context.platform.subscriptionManager;
@@ -888053,7 +888119,7 @@ async function securityPostureSummary(context, args2) {
888053
888119
  servers: mcpServers.length,
888054
888120
  quarantined: countByString(mcpServers, "schemaFreshness", "quarantined"),
888055
888121
  elevated: countByString(mcpServers, "trustMode", "allow-all"),
888056
- attackPathFindings: readRecordArray2(isRecord43(securitySnapshot.attackPathReview) ? securitySnapshot.attackPathReview.findings : []).length
888122
+ attackPathFindings: readRecordArray2(isRecord44(securitySnapshot.attackPathReview) ? securitySnapshot.attackPathReview.findings : []).length
888057
888123
  },
888058
888124
  plugins: {
888059
888125
  total: plugins2.length,
@@ -888186,11 +888252,11 @@ function timestampForBundle(bundle) {
888186
888252
  return typeof value === "number" && Number.isFinite(value) ? value : null;
888187
888253
  }
888188
888254
  function summarizeSupportBundle(path7, bundle) {
888189
- const redaction = isRecord43(bundle.redaction) ? bundle.redaction : {};
888190
- const diagnostics = isRecord43(bundle.diagnostics) ? bundle.diagnostics : {};
888255
+ const redaction = isRecord44(bundle.redaction) ? bundle.redaction : {};
888256
+ const diagnostics = isRecord44(bundle.diagnostics) ? bundle.diagnostics : {};
888191
888257
  const timestamp2 = timestampForBundle(bundle);
888192
- const mcpSummary = isRecord43(bundle.mcpSummary) ? bundle.mcpSummary : {};
888193
- const pluginSummary = isRecord43(bundle.pluginSummary) ? bundle.pluginSummary : {};
888258
+ const mcpSummary = isRecord44(bundle.mcpSummary) ? bundle.mcpSummary : {};
888259
+ const pluginSummary = isRecord44(bundle.pluginSummary) ? bundle.pluginSummary : {};
888194
888260
  return {
888195
888261
  path: path7,
888196
888262
  type: summarizeBundleType(bundle),
@@ -888243,7 +888309,7 @@ function describeHarnessSupportBundle(context, args2) {
888243
888309
  usage: `Invalid bundle JSON at ${path7}: ${error52 instanceof Error ? error52.message : String(error52)}`
888244
888310
  };
888245
888311
  }
888246
- if (!isRecord43(parsed)) {
888312
+ if (!isRecord44(parsed)) {
888247
888313
  return {
888248
888314
  status: "missing_lookup",
888249
888315
  usage: `Invalid bundle JSON at ${path7}: expected a JSON object.`
@@ -889766,7 +889832,7 @@ var UI_SURFACES = [
889766
889832
  kind: "picker",
889767
889833
  summary: "Reasoning-effort selector for models that expose effort levels.",
889768
889834
  command: "/effort",
889769
- preferredModelRoute: `Use ${agentHarnessModes2("settings", "get_setting", "set_setting")} for provider.reasoningEffort when a concrete level is known, or mode:"run_workspace_action" setup-effort with confirmation.`,
889835
+ preferredModelRoute: `Use ${agentHarnessModes2("settings", "get_setting", "set_setting")} for provider.reasoningEffort when a concrete level is known, or mode:"run_workspace_action" setup-reasoning-effort with confirmation.`,
889770
889836
  available: (context) => typeof context.openReasoningEffortPicker === "function",
889771
889837
  open: (context) => {
889772
889838
  const surface = findSurfaceById("reasoning-effort-picker");
@@ -890238,6 +890304,14 @@ function activateAgentWorkspaceSelection(workspace, requestRender) {
890238
890304
  const action2 = workspace.selectedAction;
890239
890305
  if (!action2)
890240
890306
  return;
890307
+ if (action2.kind === "setting") {
890308
+ workspace.applySettingAction(action2, requestRender);
890309
+ return;
890310
+ }
890311
+ if (action2.kind === "settings-import") {
890312
+ workspace.importTuiSettings(requestRender);
890313
+ return;
890314
+ }
890241
890315
  if (action2.kind === "editor" && action2.editorKind) {
890242
890316
  const editor = createAgentWorkspaceEditor(action2.editorKind, {
890243
890317
  runtimeStarterTemplates: workspace.runtimeSnapshot?.runtimeStarterTemplates ?? [],
@@ -890327,7 +890401,7 @@ function activateAgentWorkspaceSelection(workspace, requestRender) {
890327
890401
  workspace.lastActionResult = {
890328
890402
  kind: "dispatched",
890329
890403
  title: `Opening ${action2.label}`,
890330
- detail: "The workspace handed this safe or read-only command to the shell-owned command router.",
890404
+ detail: "The workspace handed this command to the shell-owned command router.",
890331
890405
  command: action2.command,
890332
890406
  safety: action2.safety
890333
890407
  };
@@ -890392,6 +890466,21 @@ function handleGuidanceOrWorkspaceAction(workspace, action2) {
890392
890466
  };
890393
890467
  }
890394
890468
 
890469
+ // src/input/agent-workspace-category-actions.ts
890470
+ function settingAction(options) {
890471
+ return {
890472
+ id: options.id,
890473
+ label: options.label,
890474
+ detail: options.detail,
890475
+ kind: "setting",
890476
+ safety: "safe",
890477
+ settingKey: options.key,
890478
+ ...options.value !== undefined ? { settingValueHint: options.value } : {},
890479
+ ...options.visibleWhenKey !== undefined ? { visibleWhenSettingKey: options.visibleWhenKey } : {},
890480
+ ...options.visibleWhenValue !== undefined ? { visibleWhenSettingValue: options.visibleWhenValue } : {}
890481
+ };
890482
+ }
890483
+
890395
890484
  // src/input/agent-workspace-categories.ts
890396
890485
  var AGENT_WORKSPACE_CATEGORIES = [
890397
890486
  {
@@ -890404,7 +890493,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
890404
890493
  { id: "chat", label: "Continue assistant chat", detail: "Return to the main composer and type a normal message. Agent work stays serial in the main conversation.", kind: "guidance", safety: "safe" },
890405
890494
  { id: "brief", label: "Operator briefing", detail: "Show a concise Agent status and next-actions briefing without mutating the connected host.", command: "/brief", kind: "command", safety: "read-only" },
890406
890495
  { id: "model", label: "Choose model", detail: "Open the model/provider workspace for the Agent chat route.", command: "/model", kind: "command", safety: "safe" },
890407
- { id: "setup-home", label: "Setup checklist", detail: "Jump to the first-run checklist for provider, knowledge, personas, skills, routines, memory, channels, and voice/media.", targetCategoryId: "setup", kind: "workspace", safety: "safe" },
890496
+ { id: "setup-home", label: "Onboarding", detail: "Jump to first-run configuration for account, model, tools, channels, voice, local context, and finish.", targetCategoryId: "setup", kind: "workspace", safety: "safe" },
890408
890497
  { id: "channels-home", label: "Channels", detail: "Jump to companion pairing and channel readiness without changing connected-host routing.", targetCategoryId: "channels", kind: "workspace", safety: "read-only" },
890409
890498
  { id: "mode-show", label: "Interaction mode", detail: "Review Agent interaction noise level and per-domain verbosity.", command: "/mode show", kind: "command", safety: "read-only" },
890410
890499
  { id: "mode-preset", label: "Set interaction mode", detail: "Open a confirmed form for quiet, balanced, or operator interaction mode.", editorKind: "mode-preset", kind: "editor", safety: "safe" },
@@ -890428,61 +890517,225 @@ var AGENT_WORKSPACE_CATEGORIES = [
890428
890517
  },
890429
890518
  {
890430
890519
  id: "setup",
890431
- group: "START",
890432
- label: "Setup",
890433
- summary: "Configuration, auth, provider, and onboarding workspaces.",
890434
- detail: "Use this to configure the assistant: provider/model, setup checklist, Agent Knowledge, local behavior, channels, and voice/media. Changes here stay Agent-owned.",
890520
+ group: "ONBOARDING",
890521
+ label: "Start",
890522
+ summary: "Import existing GoodVibes preferences, choose a main model, and sign in.",
890523
+ detail: "Use this first. Every row either imports existing settings, edits a setting inline, or opens a concrete sign-in/provider form.",
890435
890524
  actions: [
890436
- { id: "config", label: "Open settings", detail: "Open the fullscreen Agent settings workspace.", command: "/config", kind: "command", safety: "safe" },
890437
- { id: "setup", label: "Setup workspace", detail: "Review Agent setup in this fullscreen workspace.", kind: "guidance", safety: "safe" },
890438
- { id: "setup-provider-model", label: "Provider and model", detail: "Choose the provider/model route for normal assistant chat.", command: "/model", kind: "command", safety: "safe" },
890439
- { id: "setup-model-pinned", label: "Pinned models", detail: "Inspect model favorites from the Agent TUI before changing model selection.", command: "/pin", kind: "command", safety: "read-only" },
890440
- { id: "setup-model-refresh", label: "Refresh model catalog", detail: "Refresh model catalog, benchmark, and token-limit metadata from the Agent TUI.", command: "/refresh-models", kind: "command", safety: "safe" },
890441
- { id: "setup-model-pin", label: "Pin model", detail: "Open a form that pins one model registry key for quick reuse.", editorKind: "model-pin", kind: "editor", safety: "safe" },
890442
- { id: "setup-model-unpin", label: "Unpin model", detail: "Open a form that removes one pinned model registry key.", editorKind: "model-unpin", kind: "editor", safety: "safe" },
890443
- { id: "setup-model-unpin-command", label: "Unpin model command", detail: "Use the direct unpin command when you already know the model registry key.", command: "/unpin", kind: "command", safety: "safe" },
890444
- { id: "setup-effort", label: "Reasoning effort", detail: "Open a form that sets reasoning effort for normal Agent chat turns when supported by the selected model.", editorKind: "effort-level", kind: "editor", safety: "safe" },
890445
- { id: "setup-effort-command", label: "Reasoning effort command", detail: "Show or set reasoning effort with the registry command when you already know the level.", command: "/effort", kind: "command", safety: "safe" },
890446
- { id: "setup-mode-show", label: "Interaction mode", detail: "Review current Agent interaction mode and domain verbosity.", command: "/mode show", kind: "command", safety: "read-only" },
890447
- { id: "setup-mode-preset", label: "Set interaction mode", detail: "Open a confirmed form for quiet, balanced, or operator interaction mode.", editorKind: "mode-preset", kind: "editor", safety: "safe" },
890448
- { id: "setup-mode-domain", label: "Set domain verbosity", detail: "Open a confirmed form for one interaction-domain verbosity override.", editorKind: "mode-domain", kind: "editor", safety: "safe" },
890449
- { id: "setup-compat", label: "Compatibility", detail: "Inspect connected-host compatibility and isolated Agent Knowledge route readiness.", command: "/compat", kind: "command", safety: "read-only" },
890450
- { id: "setup-agent-knowledge", label: "Agent Knowledge", detail: "Open isolated Agent Knowledge status, ask/search, ingest, source review, and reindex actions.", targetCategoryId: "knowledge", kind: "workspace", safety: "safe" },
890451
- { id: "setup-runtime-profiles", label: "Agent profiles", detail: "Open starter templates, isolated Agent homes, profile defaults, and profile import/export actions.", targetCategoryId: "profiles", kind: "workspace", safety: "safe" },
890452
- { 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" },
890453
- { id: "support-bundle-export", label: "Export support bundle", detail: "Open a confirmed form that exports a redacted Agent support bundle from the TUI workspace.", editorKind: "support-bundle-export", kind: "editor", safety: "safe" },
890454
- { id: "support-bundle-inspect", label: "Inspect support bundle", detail: "Open a form that inspects a redacted Agent support bundle before import or sharing.", editorKind: "support-bundle-inspect", kind: "editor", safety: "read-only" },
890455
- { id: "support-bundle-import", label: "Import support bundle", detail: "Open a confirmed form that imports reviewed, non-redacted config values from an Agent support bundle.", editorKind: "support-bundle-import", kind: "editor", safety: "safe" },
890456
- { id: "support-bundle-command", label: "Support bundle command", detail: "Use the support-bundle command for export, inspect, or import from inside the Agent TUI.", command: "/bundle", kind: "command", safety: "safe" },
890457
- { id: "setup-personas", label: "Personas", detail: "Create or select the active Agent-local persona.", targetCategoryId: "personas", kind: "workspace", safety: "safe" },
890458
- { id: "setup-skills", label: "Skills", detail: "Create, review, and enable reusable Agent-local skills.", targetCategoryId: "skills", kind: "workspace", safety: "safe" },
890459
- { id: "setup-routines", label: "Routines", detail: "Create, review, and enable Agent-local routines before any explicit schedule promotion.", targetCategoryId: "routines", kind: "workspace", safety: "safe" },
890460
- { id: "setup-memory", label: "Local memory", detail: "Open Agent-local memory creation, review, search, export/import, and maintenance actions. Secrets stay rejected or redacted.", targetCategoryId: "memory", kind: "workspace", safety: "safe" },
890461
- { id: "setup-notes", label: "Scratchpad notes", detail: "Open Agent-local notes for source triage and temporary context. Notes are not memory or Agent Knowledge.", targetCategoryId: "notes", kind: "workspace", safety: "safe" },
890462
- { id: "setup-channels", label: "Channels", detail: "Open companion pairing, channel readiness, delivery target, and notification setup.", targetCategoryId: "channels", kind: "workspace", safety: "safe" },
890463
- { id: "setup-tools", label: "Tools and MCP", detail: "Open MCP setup, trust review, and tool inventory.", targetCategoryId: "tools", kind: "workspace", safety: "safe" },
890464
- { id: "setup-voice-media", label: "Voice and media", detail: "Open voice, TTS, image input, media provider, and browser-tool setup actions.", targetCategoryId: "voice-media", kind: "workspace", safety: "safe" },
890465
- { id: "provider", label: "Provider status", detail: "Review provider/model posture.", command: "/provider", kind: "command", safety: "read-only" },
890466
- { id: "provider-use", label: "Use provider", detail: "Open a provider-id form that switches the Agent chat provider from the workspace.", editorKind: "provider-use", kind: "editor", safety: "safe" },
890467
- { id: "provider-inspect", label: "Inspect provider", detail: "Open a provider-id form for read-only provider auth/setup inspection.", editorKind: "provider-inspect", kind: "editor", safety: "read-only" },
890468
- { id: "provider-routes", label: "Inspect provider routes", detail: "Open a provider-id form for read-only route and fallback inspection.", editorKind: "provider-routes", kind: "editor", safety: "read-only" },
890469
- { id: "provider-account-repair", label: "Provider account repair", detail: "Open a provider-id form for read-only account repair guidance.", editorKind: "provider-account-repair", kind: "editor", safety: "read-only" },
890470
- { id: "provider-add", label: "Add custom provider", detail: "Open a confirmed form that adds one OpenAI-compatible custom provider for Agent model routing.", editorKind: "provider-add", kind: "editor", safety: "safe" },
890471
- { id: "provider-remove", label: "Remove custom provider", detail: "Open a confirmed form that removes one Agent custom provider config.", editorKind: "provider-remove", kind: "editor", safety: "safe" },
890472
- { id: "provider-accounts", label: "Provider accounts", detail: "Review provider account routes, subscription windows, and billing-path safety without starting login or repair flows.", command: "/accounts review", kind: "command", safety: "read-only" },
890473
- { id: "subscription-providers", label: "Subscription providers", detail: "Review provider subscription login routes without starting a login.", command: "/subscription providers", kind: "command", safety: "read-only" },
890474
- { id: "subscription-review", label: "Subscription review", detail: "Inspect active and pending provider subscription sessions without printing token values.", command: "/subscription review", kind: "command", safety: "read-only" },
890475
- { id: "subscription-inspect", label: "Inspect subscription provider", detail: "Open a provider-id form for read-only OAuth/subscription route inspection.", editorKind: "subscription-inspect", kind: "editor", safety: "read-only" },
890525
+ { id: "import-goodvibes-tui-settings", label: "Import GoodVibes settings", detail: "Copy existing GoodVibes TUI display, provider, behavior, permission, TTS, channel, helper, tool, release, and automation values into Agent-owned settings.", kind: "settings-import", safety: "safe" },
890526
+ settingAction({ id: "setup-provider-model", label: "Main model", detail: "Set the provider-qualified model used for normal assistant turns.", key: "provider.model" }),
890527
+ settingAction({ id: "setup-reasoning-effort", label: "Reasoning effort", detail: "Cycle the reasoning level used when the selected model supports it.", key: "provider.reasoningEffort" }),
890476
890528
  { id: "subscription-login-start", label: "Start subscription login", detail: "Open a confirmed form for one provider OAuth login start, with browser/manual completion controls.", editorKind: "subscription-login-start", kind: "editor", safety: "safe" },
890477
890529
  { id: "subscription-login-finish", label: "Finish subscription login", detail: "Open a confirmed form that stores one completed provider subscription session from a code or redirect URL.", editorKind: "subscription-login-finish", kind: "editor", safety: "safe" },
890478
890530
  { id: "subscription-logout", label: "Logout subscription", detail: "Open a confirmed form that removes one stored provider subscription session.", editorKind: "subscription-logout", kind: "editor", safety: "safe" },
890479
- { id: "subscription-bundle-export", label: "Export subscription bundle", detail: "Open a confirmed form that exports a redacted provider subscription bundle for setup review.", editorKind: "subscription-bundle-export", kind: "editor", safety: "safe" },
890480
- { id: "subscription-bundle-inspect", label: "Inspect subscription bundle", detail: "Open a form that inspects a provider subscription bundle before setup review.", editorKind: "subscription-bundle-inspect", kind: "editor", safety: "read-only" },
890481
- { id: "auth", label: "Auth review", detail: "Review authentication posture without printing token values.", command: "/auth review", kind: "command", safety: "read-only" },
890482
- { id: "auth-show", label: "Inspect provider auth", detail: "Open a provider-id form for read-only provider auth inspection.", editorKind: "auth-show", kind: "editor", safety: "read-only" },
890483
- { id: "auth-repair", label: "Auth repair guidance", detail: "Open a provider-id form that shows auth repair guidance without storing tokens or starting login.", editorKind: "auth-repair", kind: "editor", safety: "read-only" },
890484
- { id: "auth-bundle-export", label: "Export auth bundle", detail: "Open a confirmed form that exports a redacted auth review bundle.", editorKind: "auth-bundle-export", kind: "editor", safety: "safe" },
890485
- { id: "auth-bundle-inspect", label: "Inspect auth bundle", detail: "Open a form that inspects an auth review bundle before setup review.", editorKind: "auth-bundle-inspect", kind: "editor", safety: "read-only" }
890531
+ { id: "subscription-inspect", label: "Inspect subscription route", detail: "Inspect one provider subscription OAuth route before starting or finishing login.", editorKind: "subscription-inspect", kind: "editor", safety: "read-only" },
890532
+ { id: "subscription-bundle-export", label: "Export subscription bundle", detail: "Export a redacted provider subscription bundle for setup review.", editorKind: "subscription-bundle-export", kind: "editor", safety: "safe" },
890533
+ { id: "subscription-bundle-inspect", label: "Inspect subscription bundle", detail: "Inspect a provider subscription bundle before setup review.", editorKind: "subscription-bundle-inspect", kind: "editor", safety: "read-only" },
890534
+ { id: "provider-add", label: "Add custom provider", detail: "Add one OpenAI-compatible provider for Agent model routing.", editorKind: "provider-add", kind: "editor", safety: "safe" },
890535
+ { id: "secret-set-provider", label: "Store API secret", detail: "Store a provider or channel credential through the Agent secret manager.", editorKind: "secret-set", kind: "editor", safety: "safe" },
890536
+ settingAction({ id: "setup-secret-policy", label: "Secret storage policy", detail: "Choose whether secret persistence prefers or requires secure storage.", key: "storage.secretPolicy" }),
890537
+ settingAction({ id: "setup-save-history", label: "Save conversation history", detail: "Toggle local conversation history persistence.", key: "behavior.saveHistory" })
890538
+ ]
890539
+ },
890540
+ {
890541
+ id: "account-model",
890542
+ group: "ONBOARDING",
890543
+ label: "Account & Model",
890544
+ summary: "Model routing for chat, helpers, tools, embeddings, and spoken turns.",
890545
+ detail: "Use this after sign-in to make model routing explicit for each workload.",
890546
+ actions: [
890547
+ { id: "provider-use", label: "Switch provider", detail: "Open a provider-id form that switches the Agent chat provider.", editorKind: "provider-use", kind: "editor", safety: "safe" },
890548
+ { id: "provider-inspect", label: "Inspect provider auth", detail: "Inspect one provider auth/setup route without storing tokens or starting login.", editorKind: "provider-inspect", kind: "editor", safety: "read-only" },
890549
+ { id: "provider-routes", label: "Inspect provider routes", detail: "Inspect provider route and fallback posture for one provider.", editorKind: "provider-routes", kind: "editor", safety: "read-only" },
890550
+ { id: "provider-account-repair", label: "Provider repair guidance", detail: "Show provider account repair guidance without mutating credentials.", editorKind: "provider-account-repair", kind: "editor", safety: "read-only" },
890551
+ { id: "provider-remove", label: "Remove custom provider", detail: "Remove one Agent custom provider config after confirmation.", editorKind: "provider-remove", kind: "editor", safety: "safe" },
890552
+ { id: "model-refresh", label: "Refresh model catalog", detail: "Refresh model catalog, benchmark, and token-limit metadata.", command: "/refresh-models", kind: "command", safety: "safe" },
890553
+ { id: "model-pin", label: "Pin model", detail: "Pin one model registry key for quick reuse.", editorKind: "model-pin", kind: "editor", safety: "safe" },
890554
+ { id: "model-unpin", label: "Unpin model", detail: "Remove one pinned model registry key.", editorKind: "model-unpin", kind: "editor", safety: "safe" },
890555
+ { id: "auth-show", label: "Show provider auth", detail: "Inspect provider auth state without printing token values.", editorKind: "auth-show", kind: "editor", safety: "read-only" },
890556
+ { id: "auth-repair", label: "Auth repair guidance", detail: "Show auth repair guidance without storing tokens or starting login.", editorKind: "auth-repair", kind: "editor", safety: "read-only" },
890557
+ { id: "auth-bundle-export", label: "Export auth bundle", detail: "Export a redacted auth review bundle after confirmation.", editorKind: "auth-bundle-export", kind: "editor", safety: "safe" },
890558
+ { id: "auth-bundle-inspect", label: "Inspect auth bundle", detail: "Inspect an auth review bundle before setup review.", editorKind: "auth-bundle-inspect", kind: "editor", safety: "read-only" },
890559
+ settingAction({ id: "account-main-model", label: "Main model", detail: "Edit the provider-qualified model registry key for normal assistant turns.", key: "provider.model" }),
890560
+ settingAction({ id: "account-reasoning", label: "Reasoning effort", detail: "Cycle instant, low, medium, or high reasoning effort.", key: "provider.reasoningEffort" }),
890561
+ settingAction({ id: "account-embedding", label: "Embedding provider", detail: "Set the embedding provider used by local memory and retrieval.", key: "provider.embeddingProvider" }),
890562
+ settingAction({ id: "account-system-prompt", label: "System prompt file", detail: "Set an optional local system prompt file path.", key: "provider.systemPromptFile" }),
890563
+ settingAction({ id: "account-helper-enabled", label: "Enable helper model", detail: "Toggle dedicated helper routing for background utility work.", key: "helper.enabled" }),
890564
+ settingAction({ id: "account-helper-provider", label: "Helper provider", detail: "Set the helper provider id.", key: "helper.globalProvider", visibleWhenKey: "helper.enabled", visibleWhenValue: true }),
890565
+ settingAction({ id: "account-helper-model", label: "Helper model", detail: "Set the helper model registry key.", key: "helper.globalModel", visibleWhenKey: "helper.enabled", visibleWhenValue: true }),
890566
+ settingAction({ id: "account-tool-llm-enabled", label: "Enable tool LLM", detail: "Toggle a dedicated tool LLM for internal operations.", key: "tools.llmEnabled" }),
890567
+ settingAction({ id: "account-tool-provider", label: "Tool LLM provider", detail: "Set the provider for dedicated tool LLM calls.", key: "tools.llmProvider", visibleWhenKey: "tools.llmEnabled", visibleWhenValue: true }),
890568
+ settingAction({ id: "account-tool-model", label: "Tool LLM model", detail: "Set the model for dedicated tool LLM calls.", key: "tools.llmModel", visibleWhenKey: "tools.llmEnabled", visibleWhenValue: true }),
890569
+ settingAction({ id: "account-tts-llm-provider", label: "Spoken-turn provider", detail: "Set an optional provider override for spoken-response turns.", key: "tts.llmProvider" }),
890570
+ settingAction({ id: "account-tts-llm-model", label: "Spoken-turn model", detail: "Set an optional model override for spoken-response turns.", key: "tts.llmModel" })
890571
+ ]
890572
+ },
890573
+ {
890574
+ id: "assistant-behavior",
890575
+ group: "ONBOARDING",
890576
+ label: "Assistant Behavior",
890577
+ summary: "Interaction, context, notifications, and reasoning display.",
890578
+ detail: "Use this page to decide how much the assistant talks while it works and how it handles context pressure.",
890579
+ actions: [
890580
+ settingAction({ id: "behavior-hitl-mode", label: "Interaction mode", detail: "Cycle quiet, balanced, or operator interaction mode.", key: "behavior.hitlMode" }),
890581
+ settingAction({ id: "behavior-guidance-mode", label: "Guidance mode", detail: "Cycle off, minimal, or guided operational guidance.", key: "behavior.guidanceMode" }),
890582
+ settingAction({ id: "behavior-auto-compact", label: "Auto-compact threshold", detail: "Set the context percentage that triggers automatic compaction.", key: "behavior.autoCompactThreshold" }),
890583
+ settingAction({ id: "behavior-stale-context", label: "Context warnings", detail: "Toggle proactive warnings before compaction is required.", key: "behavior.staleContextWarnings" }),
890584
+ settingAction({ id: "behavior-notify-complete", label: "Notify on long turns", detail: "Toggle terminal and desktop notification when a long turn completes.", key: "behavior.notifyOnComplete" }),
890585
+ settingAction({ id: "behavior-return-context", label: "Resume summary mode", detail: "Cycle off, local, or assisted resume summaries.", key: "behavior.returnContextMode" }),
890586
+ settingAction({ id: "behavior-show-thinking", label: "Show thinking blocks", detail: "Toggle visible reasoning/thinking content when the provider returns it.", key: "display.showThinking" }),
890587
+ settingAction({ id: "behavior-show-reasoning-summary", label: "Show reasoning summary", detail: "Toggle visible reasoning summaries when supported.", key: "display.showReasoningSummary" })
890588
+ ]
890589
+ },
890590
+ {
890591
+ id: "tools-permissions",
890592
+ group: "ONBOARDING",
890593
+ label: "Tools & Permissions",
890594
+ summary: "Tool approval policy, MCP trust entry points, and secret handling.",
890595
+ detail: "Use this page to set how Agent asks before file, shell, network, MCP, workflow, and delegation operations.",
890596
+ actions: [
890597
+ settingAction({ id: "permissions-mode", label: "Permission mode", detail: "Cycle prompt, allow-all, or custom permission mode.", key: "permissions.mode" }),
890598
+ settingAction({ id: "permissions-write", label: "File writes", detail: "Cycle allow, prompt, or deny for file write operations.", key: "permissions.tools.write" }),
890599
+ settingAction({ id: "permissions-edit", label: "File edits", detail: "Cycle allow, prompt, or deny for edit and patch operations.", key: "permissions.tools.edit" }),
890600
+ settingAction({ id: "permissions-exec", label: "Shell commands", detail: "Cycle allow, prompt, or deny for shell execution.", key: "permissions.tools.exec" }),
890601
+ settingAction({ id: "permissions-fetch", label: "Network fetches", detail: "Cycle allow, prompt, or deny for outbound fetch requests.", key: "permissions.tools.fetch" }),
890602
+ settingAction({ id: "permissions-mcp", label: "MCP tools", detail: "Cycle allow, prompt, or deny for external MCP tool calls.", key: "permissions.tools.mcp" }),
890603
+ settingAction({ id: "permissions-agent", label: "Agent delegation", detail: "Cycle allow, prompt, or deny for subagent and delegation operations.", key: "permissions.tools.agent" }),
890604
+ settingAction({ id: "permissions-workflow", label: "Workflow automation", detail: "Cycle allow, prompt, or deny for multi-step workflow automation.", key: "permissions.tools.workflow" }),
890605
+ { id: "onboarding-mcp-server", label: "Add MCP server", detail: "Add or update one MCP server with command, args, role, trust, env refs, paths, and hosts.", editorKind: "mcp-server", kind: "editor", safety: "safe" },
890606
+ { id: "onboarding-secret-link", label: "Link secret reference", detail: "Link one config key to a goodvibes secret reference.", editorKind: "secret-link", kind: "editor", safety: "safe" },
890607
+ { id: "onboarding-secret-test", label: "Test secret reference", detail: "Check one stored secret reference without printing the value.", editorKind: "secret-test", kind: "editor", safety: "safe" }
890608
+ ]
890609
+ },
890610
+ {
890611
+ id: "onboarding-display",
890612
+ group: "ONBOARDING",
890613
+ label: "Interface",
890614
+ summary: "Display, streaming, operational messages, and release channel.",
890615
+ detail: "Use this page to make the terminal readable for normal daily work.",
890616
+ actions: [
890617
+ settingAction({ id: "display-stream", label: "Stream tokens", detail: "Toggle streaming assistant tokens as they arrive.", key: "display.stream" }),
890618
+ settingAction({ id: "display-theme", label: "Theme", detail: "Set the color theme name.", key: "display.theme" }),
890619
+ settingAction({ id: "display-line-numbers", label: "Line numbers", detail: "Cycle all, code-only, or off for assistant output line numbers.", key: "display.lineNumbers" }),
890620
+ settingAction({ id: "display-collapse-threshold", label: "Collapse threshold", detail: "Set the line count threshold for collapsed tool output.", key: "display.collapseThreshold" }),
890621
+ settingAction({ id: "display-token-speed", label: "Token speed counter", detail: "Toggle tokens-per-second while generating.", key: "display.showTokenSpeed" }),
890622
+ settingAction({ id: "display-tool-preview", label: "Tool call preview", detail: "Toggle partial tool-call preview while streaming.", key: "display.showToolPreview" }),
890623
+ settingAction({ id: "display-operational-messages", label: "Operational messages", detail: "Cycle panel, conversation, or both for tool and runtime messages.", key: "ui.operationalMessages" }),
890624
+ settingAction({ id: "display-system-messages", label: "System messages", detail: "Cycle panel, conversation, or both for system messages.", key: "ui.systemMessages" }),
890625
+ settingAction({ id: "display-release-channel", label: "Release channel", detail: "Cycle stable or preview for update flows.", key: "release.channel" })
890626
+ ]
890627
+ },
890628
+ {
890629
+ id: "onboarding-channels",
890630
+ group: "ONBOARDING",
890631
+ label: "Messaging",
890632
+ summary: "Messaging surfaces and settings for enabled channels.",
890633
+ detail: "Start by enabling the channels you want. Channel-specific fields appear below each enabled channel.",
890634
+ actions: [
890635
+ { id: "onboarding-pair-companion", label: "Pair companion app", detail: "Open the QR pairing view for companion access.", command: "/pair", kind: "command", safety: "safe" },
890636
+ settingAction({ id: "channel-ntfy-enabled", label: "Use ntfy", detail: "Toggle ntfy notifications and chat routing.", key: "surfaces.ntfy.enabled" }),
890637
+ settingAction({ id: "channel-ntfy-base-url", label: "ntfy base URL", detail: "Set the ntfy server URL.", key: "surfaces.ntfy.baseUrl", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
890638
+ settingAction({ id: "channel-ntfy-chat-topic", label: "ntfy chat topic", detail: "Set the topic routed into active terminal chat.", key: "surfaces.ntfy.chatTopic", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
890639
+ settingAction({ id: "channel-ntfy-agent-topic", label: "ntfy agent topic", detail: "Set the topic routed to Agent work.", key: "surfaces.ntfy.agentTopic", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
890640
+ settingAction({ id: "channel-ntfy-token", label: "ntfy token", detail: "Store the ntfy access token or secret reference.", key: "surfaces.ntfy.token", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
890641
+ settingAction({ id: "channel-ntfy-priority", label: "ntfy priority", detail: "Set default ntfy priority from 1 to 5.", key: "surfaces.ntfy.defaultPriority", visibleWhenKey: "surfaces.ntfy.enabled", visibleWhenValue: true }),
890642
+ settingAction({ id: "channel-slack-enabled", label: "Use Slack", detail: "Toggle Slack adapter configuration.", key: "surfaces.slack.enabled" }),
890643
+ settingAction({ id: "channel-slack-bot-token", label: "Slack bot token", detail: "Store the Slack bot token or secret reference.", key: "surfaces.slack.botToken", visibleWhenKey: "surfaces.slack.enabled", visibleWhenValue: true }),
890644
+ settingAction({ id: "channel-slack-signing-secret", label: "Slack signing secret", detail: "Store the Slack signing secret or secret reference.", key: "surfaces.slack.signingSecret", visibleWhenKey: "surfaces.slack.enabled", visibleWhenValue: true }),
890645
+ settingAction({ id: "channel-slack-default-channel", label: "Slack default channel", detail: "Set the default Slack channel for notifications and replies.", key: "surfaces.slack.defaultChannel", visibleWhenKey: "surfaces.slack.enabled", visibleWhenValue: true }),
890646
+ settingAction({ id: "channel-slack-workspace", label: "Slack workspace ID", detail: "Set the Slack workspace id for route binding.", key: "surfaces.slack.workspaceId", visibleWhenKey: "surfaces.slack.enabled", visibleWhenValue: true }),
890647
+ settingAction({ id: "channel-discord-enabled", label: "Use Discord", detail: "Toggle Discord adapter configuration.", key: "surfaces.discord.enabled" }),
890648
+ settingAction({ id: "channel-discord-bot-token", label: "Discord bot token", detail: "Store the Discord bot token or secret reference.", key: "surfaces.discord.botToken", visibleWhenKey: "surfaces.discord.enabled", visibleWhenValue: true }),
890649
+ settingAction({ id: "channel-discord-application", label: "Discord application ID", detail: "Set the Discord application id.", key: "surfaces.discord.applicationId", visibleWhenKey: "surfaces.discord.enabled", visibleWhenValue: true }),
890650
+ settingAction({ id: "channel-discord-public-key", label: "Discord public key", detail: "Set the Discord application public key.", key: "surfaces.discord.publicKey", visibleWhenKey: "surfaces.discord.enabled", visibleWhenValue: true }),
890651
+ settingAction({ id: "channel-discord-default-channel", label: "Discord default channel", detail: "Set the default Discord channel id.", key: "surfaces.discord.defaultChannelId", visibleWhenKey: "surfaces.discord.enabled", visibleWhenValue: true }),
890652
+ settingAction({ id: "channel-webhook-enabled", label: "Use webhooks", detail: "Toggle generic webhook delivery.", key: "surfaces.webhook.enabled" }),
890653
+ settingAction({ id: "channel-webhook-target", label: "Webhook target URL", detail: "Set the default outbound webhook target URL.", key: "surfaces.webhook.defaultTarget", visibleWhenKey: "surfaces.webhook.enabled", visibleWhenValue: true }),
890654
+ settingAction({ id: "channel-webhook-secret", label: "Webhook secret", detail: "Store the shared webhook secret or secret reference.", key: "surfaces.webhook.secret", visibleWhenKey: "surfaces.webhook.enabled", visibleWhenValue: true }),
890655
+ settingAction({ id: "channel-telegram-enabled", label: "Use Telegram", detail: "Toggle Telegram bot delivery.", key: "surfaces.telegram.enabled" }),
890656
+ settingAction({ id: "channel-telegram-bot-token", label: "Telegram bot token", detail: "Store the Telegram bot token or secret reference.", key: "surfaces.telegram.botToken", visibleWhenKey: "surfaces.telegram.enabled", visibleWhenValue: true }),
890657
+ settingAction({ id: "channel-telegram-chat", label: "Telegram chat ID", detail: "Set the default Telegram chat, group, or channel id.", key: "surfaces.telegram.defaultChatId", visibleWhenKey: "surfaces.telegram.enabled", visibleWhenValue: true }),
890658
+ settingAction({ id: "channel-telegram-mode", label: "Telegram mode", detail: "Cycle webhook or polling ingress mode.", key: "surfaces.telegram.mode", visibleWhenKey: "surfaces.telegram.enabled", visibleWhenValue: true }),
890659
+ settingAction({ id: "channel-googlechat-enabled", label: "Use Google Chat", detail: "Toggle Google Chat delivery.", key: "surfaces.googleChat.enabled" }),
890660
+ settingAction({ id: "channel-googlechat-webhook", label: "Google Chat webhook", detail: "Set the Google Chat webhook or app callback URL.", key: "surfaces.googleChat.webhookUrl", visibleWhenKey: "surfaces.googleChat.enabled", visibleWhenValue: true }),
890661
+ settingAction({ id: "channel-homeassistant-enabled", label: "Use home automation", detail: "Toggle home automation conversation and event delivery.", key: "surfaces.homeassistant.enabled" }),
890662
+ settingAction({ id: "channel-homeassistant-url", label: "Home automation URL", detail: "Set the home automation instance URL.", key: "surfaces.homeassistant.instanceUrl", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
890663
+ settingAction({ id: "channel-homeassistant-token", label: "Home automation token", detail: "Store the home automation access token or secret reference.", key: "surfaces.homeassistant.accessToken", visibleWhenKey: "surfaces.homeassistant.enabled", visibleWhenValue: true }),
890664
+ settingAction({ id: "channel-signal-enabled", label: "Use Signal", detail: "Toggle Signal bridge delivery.", key: "surfaces.signal.enabled" }),
890665
+ settingAction({ id: "channel-signal-bridge", label: "Signal bridge URL", detail: "Set the Signal bridge base URL.", key: "surfaces.signal.bridgeUrl", visibleWhenKey: "surfaces.signal.enabled", visibleWhenValue: true }),
890666
+ settingAction({ id: "channel-signal-recipient", label: "Signal recipient", detail: "Set the default Signal recipient or group.", key: "surfaces.signal.defaultRecipient", visibleWhenKey: "surfaces.signal.enabled", visibleWhenValue: true }),
890667
+ settingAction({ id: "channel-whatsapp-enabled", label: "Use WhatsApp", detail: "Toggle WhatsApp delivery.", key: "surfaces.whatsapp.enabled" }),
890668
+ settingAction({ id: "channel-whatsapp-provider", label: "WhatsApp provider", detail: "Cycle Meta Cloud API or bridge provider mode.", key: "surfaces.whatsapp.provider", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
890669
+ settingAction({ id: "channel-whatsapp-token", label: "WhatsApp access token", detail: "Store the WhatsApp provider access token or secret reference.", key: "surfaces.whatsapp.accessToken", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
890670
+ settingAction({ id: "channel-whatsapp-recipient", label: "WhatsApp recipient", detail: "Set the default WhatsApp recipient or chat id.", key: "surfaces.whatsapp.defaultRecipient", visibleWhenKey: "surfaces.whatsapp.enabled", visibleWhenValue: true }),
890671
+ settingAction({ id: "channel-imessage-enabled", label: "Use iMessage", detail: "Toggle iMessage bridge delivery.", key: "surfaces.imessage.enabled" }),
890672
+ settingAction({ id: "channel-imessage-bridge", label: "iMessage bridge URL", detail: "Set the iMessage bridge base URL.", key: "surfaces.imessage.bridgeUrl", visibleWhenKey: "surfaces.imessage.enabled", visibleWhenValue: true }),
890673
+ settingAction({ id: "channel-imessage-chat", label: "iMessage chat ID", detail: "Set the default iMessage chat id.", key: "surfaces.imessage.defaultChatId", visibleWhenKey: "surfaces.imessage.enabled", visibleWhenValue: true }),
890674
+ { id: "onboarding-notify-webhook", label: "Add notification webhook", detail: "Add one webhook target for explicit reminder and routine delivery.", editorKind: "notify-webhook", kind: "editor", safety: "safe" },
890675
+ { id: "onboarding-test-webhook", label: "Test notification webhooks", detail: "Send one confirmed test notification to configured webhook targets.", editorKind: "notify-webhook-test", kind: "editor", safety: "safe" }
890676
+ ]
890677
+ },
890678
+ {
890679
+ id: "onboarding-voice-media",
890680
+ group: "ONBOARDING",
890681
+ label: "Voice & Phone",
890682
+ summary: "Configure spoken replies, TTS routing, media prompts, and telephony.",
890683
+ detail: "Use this page for local voice, spoken-output defaults, image/media prompts, and SMS or phone-call delivery.",
890684
+ actions: [
890685
+ settingAction({ id: "voice-enabled", label: "Use voice controls", detail: "Toggle the optional local voice control surface.", key: "ui.voiceEnabled" }),
890686
+ settingAction({ id: "voice-tts-provider", label: "TTS provider", detail: "Set the default text-to-speech provider id.", key: "tts.provider" }),
890687
+ settingAction({ id: "voice-tts-voice", label: "TTS voice", detail: "Set the default text-to-speech voice id.", key: "tts.voice" }),
890688
+ { id: "voice-speak-prompt", label: "Try spoken prompt", detail: "Open a prompt form for a spoken assistant reply through configured TTS.", editorKind: "tts-prompt", kind: "editor", safety: "safe" },
890689
+ { id: "media-attach-image", label: "Attach image", detail: "Attach a local image path and optional prompt to the next assistant turn.", editorKind: "image-input", kind: "editor", safety: "safe" },
890690
+ { id: "onboarding-media-generate", label: "Generate media", detail: "Generate image or video artifacts through a configured media provider after confirmation.", editorKind: "media-generate", kind: "editor", safety: "safe" },
890691
+ settingAction({ id: "telephony-enabled", label: "Use telephony", detail: "Toggle SMS, voice call, or telephony bridge delivery.", key: "surfaces.telephony.enabled" }),
890692
+ settingAction({ id: "telephony-provider", label: "Telephony provider", detail: "Cycle direct provider or bridge mode.", key: "surfaces.telephony.provider", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
890693
+ settingAction({ id: "telephony-mode", label: "Telephony mode", detail: "Cycle SMS, voice call, or bridge delivery mode.", key: "surfaces.telephony.mode", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
890694
+ settingAction({ id: "telephony-account-sid", label: "Twilio account SID", detail: "Set the Twilio account SID for provider-direct delivery.", key: "surfaces.telephony.accountSid", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
890695
+ settingAction({ id: "telephony-auth-token", label: "Twilio auth token", detail: "Store the Twilio auth token or secret reference.", key: "surfaces.telephony.authToken", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
890696
+ settingAction({ id: "telephony-from", label: "Sender phone number", detail: "Set the default caller or sender phone number.", key: "surfaces.telephony.fromNumber", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
890697
+ settingAction({ id: "telephony-recipient", label: "Recipient phone number", detail: "Set the default telephony recipient number.", key: "surfaces.telephony.defaultRecipient", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
890698
+ settingAction({ id: "telephony-webhook-secret", label: "Telephony webhook secret", detail: "Store the shared telephony webhook secret or secret reference.", key: "surfaces.telephony.webhookSecret", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true }),
890699
+ settingAction({ id: "telephony-voice-language", label: "Voice language", detail: "Set the BCP-47 language code for voice-call text-to-speech.", key: "surfaces.telephony.voiceLanguage", visibleWhenKey: "surfaces.telephony.enabled", visibleWhenValue: true })
890700
+ ]
890701
+ },
890702
+ {
890703
+ id: "onboarding-context",
890704
+ group: "ONBOARDING",
890705
+ label: "Context",
890706
+ summary: "Local persona, memory, skills, routines, notes, and Agent Knowledge.",
890707
+ detail: "Use this page to make the assistant useful with durable local context and source-backed knowledge.",
890708
+ actions: [
890709
+ { id: "context-profile-from-discovered", label: "Profile from discovered files", detail: "Create an isolated Agent profile from reviewed local persona, skill, and routine files.", editorKind: "profile-from-discovered", kind: "editor", safety: "safe" },
890710
+ { id: "context-persona-discovery", label: "Import persona files", detail: "Import discovered persona files into the Agent persona registry.", editorKind: "persona-discovery-import", kind: "editor", safety: "safe" },
890711
+ { id: "context-skill-discovery", label: "Import skill files", detail: "Import discovered skill files into the Agent skill registry.", editorKind: "skill-discovery-import", kind: "editor", safety: "safe" },
890712
+ { id: "context-routine-discovery", label: "Import routine files", detail: "Import discovered routine files into the Agent routine registry.", editorKind: "routine-discovery-import", kind: "editor", safety: "safe" },
890713
+ { id: "context-create-persona", label: "Create persona", detail: "Create and optionally activate an Agent-local persona.", editorKind: "persona", kind: "editor", safety: "safe" },
890714
+ { id: "context-create-memory", label: "Create starter memory", detail: "Create one durable local memory record.", editorKind: "memory", kind: "editor", safety: "safe" },
890715
+ { id: "context-create-skill", label: "Create skill", detail: "Create one reusable Agent-local skill.", editorKind: "skill", kind: "editor", safety: "safe" },
890716
+ { id: "context-create-routine", label: "Create routine", detail: "Create one reusable Agent-local routine.", editorKind: "routine", kind: "editor", safety: "safe" },
890717
+ { id: "context-create-note", label: "Create note", detail: "Create one Agent-local scratchpad note.", editorKind: "note", kind: "editor", safety: "safe" },
890718
+ { id: "context-knowledge-url", label: "Ingest URL", detail: "Ingest a reviewed URL into isolated Agent Knowledge after confirmation.", editorKind: "knowledge-url", kind: "editor", safety: "safe" },
890719
+ { id: "context-knowledge-file", label: "Ingest file", detail: "Ingest a local file into isolated Agent Knowledge after confirmation.", editorKind: "knowledge-file", kind: "editor", safety: "safe" },
890720
+ { id: "context-knowledge-bookmarks", label: "Import bookmarks", detail: "Import a browser bookmark export into isolated Agent Knowledge.", editorKind: "knowledge-bookmarks", kind: "editor", safety: "safe" },
890721
+ { id: "context-knowledge-browser-history", label: "Import browser history", detail: "Import local browser history or bookmarks into isolated Agent Knowledge.", editorKind: "knowledge-browser-history", kind: "editor", safety: "safe" }
890722
+ ]
890723
+ },
890724
+ {
890725
+ id: "onboarding-verify",
890726
+ group: "ONBOARDING",
890727
+ label: "Verify",
890728
+ summary: "Review the configured runtime before finishing onboarding.",
890729
+ detail: "Use this page to inspect health, model/provider state, channels, MCP, and knowledge before applying the completion marker.",
890730
+ actions: [
890731
+ { id: "verify-brief", label: "Operator briefing", detail: "Show a concise status and next-action briefing.", command: "/brief", kind: "command", safety: "read-only" },
890732
+ { id: "verify-health", label: "Health review", detail: "Review local runtime and connected-host status.", command: "/health review", kind: "command", safety: "read-only" },
890733
+ { id: "verify-compat", label: "Compatibility", detail: "Inspect connected-host compatibility and Agent Knowledge route readiness.", command: "/compat", kind: "command", safety: "read-only" },
890734
+ { id: "verify-provider", label: "Provider status", detail: "Inspect provider/model routing state.", command: "/provider", kind: "command", safety: "read-only" },
890735
+ { id: "verify-subscription", label: "Subscription status", detail: "Inspect active and pending provider subscription sessions.", command: "/subscription review", kind: "command", safety: "read-only" },
890736
+ { id: "verify-channels", label: "Channel readiness", detail: "Inspect channel readiness and enabled-channel attention items.", command: "/channels attention", kind: "command", safety: "read-only" },
890737
+ { id: "verify-mcp", label: "MCP review", detail: "Inspect MCP server connection, role, trust, and quarantine posture.", command: "/mcp review", kind: "command", safety: "read-only" },
890738
+ { id: "verify-knowledge", label: "Knowledge status", detail: "Inspect isolated Agent Knowledge readiness and counts.", command: "/knowledge status", kind: "command", safety: "read-only" }
890486
890739
  ]
890487
890740
  },
890488
890741
  {
@@ -890956,7 +891209,9 @@ var AGENT_WORKSPACE_CATEGORIES = [
890956
891209
  { id: "host-auth-review", label: "Provider auth review", detail: "Review provider auth posture without printing token values.", command: "/auth review", kind: "command", safety: "read-only" },
890957
891210
  { id: "host-security", label: "Security review", detail: "Inspect token posture, MCP attack paths, policy lint, plugin risk, and incident pressure.", command: "/security review", kind: "command", safety: "read-only" },
890958
891211
  { id: "host-trust", label: "Trust review", detail: "Review permission, secret, plugin, and MCP trust posture without exporting bundles or changing trust.", command: "/trust review", kind: "command", safety: "read-only" },
890959
- { id: "host-support-bundle", label: "Support bundle", detail: "Open support bundle export, inspect, and import actions for host-facing setup review.", targetCategoryId: "setup", kind: "workspace", safety: "safe" },
891212
+ { id: "host-support-bundle-export", label: "Export support bundle", detail: "Export a redacted Agent support bundle from the Host page.", editorKind: "support-bundle-export", kind: "editor", safety: "safe" },
891213
+ { id: "host-support-bundle-inspect", label: "Inspect support bundle", detail: "Inspect a support bundle before import or sharing.", editorKind: "support-bundle-inspect", kind: "editor", safety: "read-only" },
891214
+ { id: "host-support-bundle-import", label: "Import support bundle", detail: "Import reviewed, non-redacted config values from a support bundle.", editorKind: "support-bundle-import", kind: "editor", safety: "safe" },
890960
891215
  { id: "host-telemetry", label: "Telemetry settings", detail: "Open telemetry payload policy settings for connected-host and Agent observability review.", command: "/config telemetry", kind: "command", safety: "safe" },
890961
891216
  { id: "host-config", label: "Control-plane settings", detail: "Open configuration controls for service, channels, tools, automation, provider, and storage posture.", command: "/config", kind: "command", safety: "safe" },
890962
891217
  { id: "host-safety", label: "Host mutation policy", detail: "Agent may inspect connected-host surfaces and run explicit confirmed actions, but does not silently create tasks, send channel messages, mutate auth, or start automation.", kind: "guidance", safety: "blocked" }
@@ -891008,9 +891263,7 @@ var AGENT_WORKSPACE_CATEGORIES = [
891008
891263
  label: "Finish",
891009
891264
  summary: "Acknowledge setup and close onboarding.",
891010
891265
  detail: "Use this final step after reviewing setup. Apply & close writes the user onboarding completion marker so normal future launches start in the main conversation.",
891011
- actions: [
891012
- { id: "onboarding-apply-close", label: "Apply & close", detail: "Acknowledge onboarding as finished, persist the user completion marker, and close the fullscreen Agent workspace.", kind: "onboarding-complete", safety: "safe" }
891013
- ]
891266
+ actions: [{ id: "onboarding-apply-close", label: "Apply & close", detail: "Acknowledge onboarding as finished, persist the user completion marker, and close the fullscreen Agent workspace.", kind: "onboarding-complete", safety: "safe" }]
891014
891267
  }
891015
891268
  ];
891016
891269
 
@@ -891222,7 +891475,7 @@ function readLimit26(value, fallback) {
891222
891475
  const parsed = typeof value === "string" && value.trim() ? Number(value) : value;
891223
891476
  if (typeof parsed !== "number" || !Number.isFinite(parsed))
891224
891477
  return fallback;
891225
- return Math.max(1, Math.min(500, Math.trunc(parsed)));
891478
+ return Math.max(1, Math.min(1000, Math.trunc(parsed)));
891226
891479
  }
891227
891480
  function readFieldMap3(value) {
891228
891481
  if (typeof value !== "object" || value === null || Array.isArray(value))
@@ -891386,7 +891639,7 @@ function describeWorkspaceActionSummary(category, action2) {
891386
891639
  function listWorkspaceActions(context, args2) {
891387
891640
  const query2 = readString72(args2.query);
891388
891641
  const categoryId = readString72(args2.categoryId || args2.category);
891389
- const limit3 = readLimit26(args2.limit, 500);
891642
+ const limit3 = readLimit26(args2.limit, 1000);
891390
891643
  const includeEditor = args2.includeParameters === true;
891391
891644
  const editorContext = includeEditor ? buildWorkspaceEditorContext(context, args2) : null;
891392
891645
  const source = query2 ? searchAgentWorkspaceActions(AGENT_WORKSPACE_CATEGORIES, query2).map((result2) => ({ category: result2.category, action: result2.action })) : allWorkspaceActions();
@@ -895536,6 +895789,254 @@ function buildAgentWorkspaceRequirements(readField) {
895536
895789
  commands: splitList5(readField("requiresCommands"))
895537
895790
  });
895538
895791
  }
895792
+
895793
+ // src/input/agent-workspace-settings.ts
895794
+ import { existsSync as existsSync87, readFileSync as readFileSync94 } from "fs";
895795
+ var GOODVIBES_TUI_SURFACE_ROOT = "tui";
895796
+ var TUI_IMPORTABLE_SETTING_PREFIXES = [
895797
+ "display.",
895798
+ "provider.",
895799
+ "behavior.",
895800
+ "storage.",
895801
+ "permissions.",
895802
+ "ui.",
895803
+ "tts.",
895804
+ "surfaces.",
895805
+ "helper.",
895806
+ "tools.",
895807
+ "release.",
895808
+ "automation."
895809
+ ];
895810
+ function isRecord45(value) {
895811
+ return typeof value === "object" && value !== null && !Array.isArray(value);
895812
+ }
895813
+ function readJsonRecord(path7) {
895814
+ if (!existsSync87(path7))
895815
+ return null;
895816
+ const parsed = JSON.parse(readFileSync94(path7, "utf-8"));
895817
+ return isRecord45(parsed) ? parsed : null;
895818
+ }
895819
+ function readNestedSettingValue(record2, key) {
895820
+ let cursor = record2;
895821
+ for (const part of key.split(".")) {
895822
+ if (!isRecord45(cursor) || !(part in cursor))
895823
+ return;
895824
+ cursor = cursor[part];
895825
+ }
895826
+ return cursor;
895827
+ }
895828
+ function canImportTuiSetting(key) {
895829
+ return !isExternalHostOwnedSettingKey(key) && TUI_IMPORTABLE_SETTING_PREFIXES.some((prefix) => key.startsWith(prefix));
895830
+ }
895831
+ function valuesMatch(left, right) {
895832
+ return JSON.stringify(left) === JSON.stringify(right);
895833
+ }
895834
+ function agentWorkspaceSettingSchema(context, key) {
895835
+ return context?.platform?.configManager?.getSchema().find((setting) => setting.key === key) ?? null;
895836
+ }
895837
+ function isAgentWorkspaceActionVisible(context, action2) {
895838
+ const key = action2.visibleWhenSettingKey?.trim();
895839
+ if (!key)
895840
+ return true;
895841
+ const configManager = context?.platform?.configManager;
895842
+ if (!configManager)
895843
+ return false;
895844
+ return configManager.get(key) === action2.visibleWhenSettingValue;
895845
+ }
895846
+ function buildAgentWorkspaceSettingActionEffect(context, action2) {
895847
+ const settingKey = action2.settingKey?.trim();
895848
+ const configManager = context?.platform?.configManager;
895849
+ if (!settingKey || !configManager) {
895850
+ return {
895851
+ kind: "result",
895852
+ status: "Setting is unavailable in this runtime.",
895853
+ result: {
895854
+ kind: "error",
895855
+ title: "Setting unavailable",
895856
+ detail: action2.detail,
895857
+ safety: action2.safety
895858
+ }
895859
+ };
895860
+ }
895861
+ const setting = agentWorkspaceSettingSchema(context, settingKey);
895862
+ if (!setting) {
895863
+ return {
895864
+ kind: "result",
895865
+ status: `Unknown setting: ${settingKey}`,
895866
+ result: {
895867
+ kind: "error",
895868
+ title: "Unknown setting",
895869
+ detail: `No Agent setting exists for ${settingKey}.`,
895870
+ safety: action2.safety
895871
+ }
895872
+ };
895873
+ }
895874
+ if (action2.settingValueHint !== undefined) {
895875
+ return { kind: "apply", setting, value: action2.settingValueHint };
895876
+ }
895877
+ const currentValue = configManager.get(setting.key);
895878
+ if (setting.type === "boolean") {
895879
+ return { kind: "apply", setting, value: !Boolean(currentValue) };
895880
+ }
895881
+ if (setting.type === "enum" && setting.enumValues && setting.enumValues.length > 0) {
895882
+ const currentIndex = Math.max(0, setting.enumValues.indexOf(String(currentValue)));
895883
+ return { kind: "apply", setting, value: setting.enumValues[(currentIndex + 1) % setting.enumValues.length] };
895884
+ }
895885
+ return {
895886
+ kind: "editor",
895887
+ editor: createSettingEditor(setting, String(currentValue ?? ""), action2),
895888
+ status: `Editing ${setting.key}.`,
895889
+ result: {
895890
+ kind: "guidance",
895891
+ title: `Edit ${setting.key}`,
895892
+ detail: setting.description,
895893
+ safety: action2.safety
895894
+ }
895895
+ };
895896
+ }
895897
+ async function applyAgentWorkspaceSettingValue(context, setting, value) {
895898
+ const configManager = context?.platform?.configManager;
895899
+ if (!configManager) {
895900
+ return {
895901
+ status: "Setting is unavailable in this runtime.",
895902
+ result: {
895903
+ kind: "error",
895904
+ title: `${setting.key} update failed`,
895905
+ detail: "The Agent workspace has no config manager for this runtime.",
895906
+ safety: "safe"
895907
+ }
895908
+ };
895909
+ }
895910
+ try {
895911
+ const result2 = await setHarnessSetting(configManager, context?.platform?.secretsManager, setting.key, value);
895912
+ return {
895913
+ status: `${result2.key} set.`,
895914
+ result: {
895915
+ kind: "refreshed",
895916
+ title: `${result2.key} updated`,
895917
+ detail: `Current value: ${String(result2.current)}`,
895918
+ safety: "safe"
895919
+ }
895920
+ };
895921
+ } catch (error53) {
895922
+ const detail = error53 instanceof Error ? error53.message : String(error53);
895923
+ return {
895924
+ status: detail,
895925
+ result: {
895926
+ kind: "error",
895927
+ title: `${setting.key} update failed`,
895928
+ detail,
895929
+ safety: "safe"
895930
+ }
895931
+ };
895932
+ }
895933
+ }
895934
+ async function importAgentWorkspaceTuiSettings(context) {
895935
+ const shellPaths3 = context?.workspace?.shellPaths;
895936
+ const configManager = context?.platform?.configManager;
895937
+ if (!shellPaths3 || !configManager) {
895938
+ return {
895939
+ status: "GoodVibes TUI settings import is unavailable in this runtime.",
895940
+ runtimeSnapshot: null,
895941
+ result: {
895942
+ kind: "error",
895943
+ title: "Import unavailable",
895944
+ detail: "The workspace cannot locate shell paths or the Agent config manager.",
895945
+ safety: "safe"
895946
+ }
895947
+ };
895948
+ }
895949
+ const sources = [
895950
+ { label: "user", path: shellPaths3.resolveUserPath(GOODVIBES_TUI_SURFACE_ROOT, "settings.json") },
895951
+ { label: "project", path: shellPaths3.resolveProjectPath(GOODVIBES_TUI_SURFACE_ROOT, "settings.json") }
895952
+ ];
895953
+ const values2 = new Map;
895954
+ const parseErrors = [];
895955
+ for (const source of sources) {
895956
+ try {
895957
+ const record2 = readJsonRecord(source.path);
895958
+ if (!record2)
895959
+ continue;
895960
+ for (const setting of configManager.getSchema()) {
895961
+ if (!canImportTuiSetting(setting.key))
895962
+ continue;
895963
+ const value = readNestedSettingValue(record2, setting.key);
895964
+ if (value !== undefined)
895965
+ values2.set(setting.key, { value, source: source.label });
895966
+ }
895967
+ } catch (error53) {
895968
+ parseErrors.push(`${source.label}: ${error53 instanceof Error ? error53.message : String(error53)}`);
895969
+ }
895970
+ }
895971
+ if (values2.size === 0) {
895972
+ const detail = parseErrors.length > 0 ? `No importable settings found. ${parseErrors.join("; ")}` : "No GoodVibes TUI settings file with importable Agent-owned settings was found.";
895973
+ return {
895974
+ status: "No GoodVibes TUI settings imported.",
895975
+ runtimeSnapshot: null,
895976
+ result: {
895977
+ kind: parseErrors.length > 0 ? "error" : "guidance",
895978
+ title: "Nothing imported",
895979
+ detail,
895980
+ safety: "safe"
895981
+ }
895982
+ };
895983
+ }
895984
+ const imported = [];
895985
+ const unchanged = [];
895986
+ const skipped = [];
895987
+ for (const [key, entry] of values2) {
895988
+ const setting = agentWorkspaceSettingSchema(context, key);
895989
+ if (!setting)
895990
+ continue;
895991
+ if (valuesMatch(configManager.get(setting.key), entry.value)) {
895992
+ unchanged.push(setting.key);
895993
+ continue;
895994
+ }
895995
+ try {
895996
+ await setHarnessSetting(configManager, context?.platform?.secretsManager, setting.key, entry.value);
895997
+ imported.push(`${setting.key} (${entry.source})`);
895998
+ } catch (error53) {
895999
+ skipped.push(`${setting.key}: ${error53 instanceof Error ? error53.message : String(error53)}`);
896000
+ }
896001
+ }
896002
+ return {
896003
+ status: imported.length > 0 ? `Imported ${imported.length} GoodVibes TUI setting(s).` : "No GoodVibes TUI settings changed.",
896004
+ runtimeSnapshot: context ? buildAgentWorkspaceRuntimeSnapshot(context) : null,
896005
+ result: {
896006
+ kind: skipped.length > 0 && imported.length === 0 ? "error" : imported.length > 0 ? "refreshed" : "guidance",
896007
+ title: imported.length > 0 ? "GoodVibes TUI settings imported" : "No settings changed",
896008
+ detail: [
896009
+ imported.length > 0 ? `Imported: ${imported.slice(0, 10).join(", ")}${imported.length > 10 ? `, +${imported.length - 10} more` : ""}.` : "",
896010
+ unchanged.length > 0 ? `${unchanged.length} setting(s) already matched.` : "",
896011
+ skipped.length > 0 ? `Skipped: ${skipped.slice(0, 5).join("; ")}${skipped.length > 5 ? `; +${skipped.length - 5} more` : ""}.` : "",
896012
+ parseErrors.length > 0 ? `Parse issues: ${parseErrors.join("; ")}.` : ""
896013
+ ].filter((line2) => line2.length > 0).join(" "),
896014
+ safety: "safe"
896015
+ }
896016
+ };
896017
+ }
896018
+ function createSettingEditor(setting, currentValue, action2) {
896019
+ const valueHint = setting.type === "number" ? "Enter a number." : setting.type === "string" ? "Enter a value. Leave empty to clear it." : setting.enumValues ? `Allowed values: ${setting.enumValues.join(", ")}.` : action2.detail;
896020
+ return {
896021
+ kind: "setting-set",
896022
+ mode: "update",
896023
+ recordId: setting.key,
896024
+ title: `Set ${setting.key}`,
896025
+ selectedFieldIndex: 0,
896026
+ message: action2.detail,
896027
+ fields: [
896028
+ {
896029
+ id: "value",
896030
+ label: setting.key,
896031
+ value: currentValue,
896032
+ required: false,
896033
+ multiline: false,
896034
+ hint: action2.settingValueHint ?? valueHint,
896035
+ redact: /(?:secret|token|password|api[-_.]?key|signing)/i.test(setting.key)
896036
+ }
896037
+ ]
896038
+ };
896039
+ }
895539
896040
  // src/input/agent-workspace-token.ts
895540
896041
  function handleAgentWorkspaceToken(workspace, token, handleEscape2, requestRender) {
895541
896042
  if (!workspace.active)
@@ -895639,14 +896140,7 @@ class AgentWorkspace {
895639
896140
  localEditor = null;
895640
896141
  actionSearchActive = false;
895641
896142
  actionSearchQuery = "";
895642
- selectedLibraryItemIndexes = {
895643
- memory: 0,
895644
- note: 0,
895645
- persona: 0,
895646
- skill: 0,
895647
- routine: 0,
895648
- profile: 0
895649
- };
896143
+ selectedLibraryItemIndexes = { memory: 0, note: 0, persona: 0, skill: 0, routine: 0, profile: 0 };
895650
896144
  context = null;
895651
896145
  dispatchCommand = null;
895652
896146
  dispatchPrompt = null;
@@ -895662,7 +896156,10 @@ class AgentWorkspace {
895662
896156
  this.localEditor = null;
895663
896157
  this.actionSearchActive = false;
895664
896158
  this.actionSearchQuery = "";
895665
- if (categoryId && !this.selectCategory(categoryId)) {
896159
+ if (!categoryId) {
896160
+ this.selectedCategoryIndex = 0;
896161
+ this.selectedActionIndex = 0;
896162
+ } else if (!this.selectCategory(categoryId)) {
895666
896163
  const normalized3 = categoryId.trim();
895667
896164
  this.status = `Unknown Agent workspace area: ${normalized3}`;
895668
896165
  this.lastActionResult = {
@@ -895693,7 +896190,7 @@ class AgentWorkspace {
895693
896190
  get actions() {
895694
896191
  if (this.actionSearchActive)
895695
896192
  return this.actionSearchResults.map((result2) => result2.action);
895696
- return this.selectedCategory.actions;
896193
+ return this.selectedCategory.actions.filter((action2) => isAgentWorkspaceActionVisible(this.context, action2));
895697
896194
  }
895698
896195
  get selectedAction() {
895699
896196
  return this.actions[this.selectedActionIndex] ?? null;
@@ -895704,7 +896201,13 @@ class AgentWorkspace {
895704
896201
  return this.selectedCategory;
895705
896202
  }
895706
896203
  get actionSearchResults() {
895707
- return this.actionSearchActive ? searchAgentWorkspaceActions(this.categories, this.actionSearchQuery) : [];
896204
+ if (!this.actionSearchActive)
896205
+ return [];
896206
+ const categories = this.categories.map((category) => ({
896207
+ ...category,
896208
+ actions: category.actions.filter((action2) => isAgentWorkspaceActionVisible(this.context, action2))
896209
+ }));
896210
+ return searchAgentWorkspaceActions(categories, this.actionSearchQuery);
895708
896211
  }
895709
896212
  get selectedActionSearchResult() {
895710
896213
  if (!this.actionSearchActive)
@@ -895761,11 +896264,7 @@ class AgentWorkspace {
895761
896264
  }
895762
896265
  this.runtimeSnapshot = buildAgentWorkspaceRuntimeSnapshot(this.context);
895763
896266
  this.status = "Runtime context refreshed.";
895764
- this.lastActionResult = {
895765
- kind: "refreshed",
895766
- title: "Runtime context refreshed",
895767
- detail: "Provider, model, session, local memory, runtime endpoint, and Agent knowledge route posture were re-read from the live command context."
895768
- };
896267
+ this.lastActionResult = { kind: "refreshed", title: "Runtime context refreshed", detail: "Provider, model, session, local memory, runtime endpoint, and Agent knowledge route posture were re-read from the live command context." };
895769
896268
  }
895770
896269
  cancelLocalEditor() {
895771
896270
  if (!this.localEditor)
@@ -895893,34 +896392,37 @@ class AgentWorkspace {
895893
896392
  return;
895894
896393
  }
895895
896394
  try {
895896
- const marker = {
895897
- scope: "user",
895898
- source: "wizard",
895899
- mode: "new",
895900
- workspaceRoot: shellPaths3.workingDirectory
895901
- };
896395
+ const marker = { scope: "user", source: "wizard", mode: "new", workspaceRoot: shellPaths3.workingDirectory };
895902
896396
  writeOnboardingCheckMarker(shellPaths3, marker);
895903
896397
  writeOnboardingCompletionMarker(shellPaths3, marker);
895904
896398
  this.status = "Onboarding applied and closed.";
895905
- this.lastActionResult = {
895906
- kind: "refreshed",
895907
- title: "Onboarding complete",
895908
- detail: "Saved the user onboarding completion marker. Future normal launches start in the main conversation.",
895909
- safety: "safe"
895910
- };
896399
+ this.lastActionResult = { kind: "refreshed", title: "Onboarding complete", detail: "Saved the user onboarding completion marker. Future normal launches start in the main conversation.", safety: "safe" };
895911
896400
  if (!this.context?.dismissAgentWorkspace?.())
895912
896401
  this.close();
895913
896402
  } catch (error53) {
895914
896403
  const detail = error53 instanceof Error ? error53.message : String(error53);
895915
896404
  this.status = "Onboarding completion failed.";
895916
- this.lastActionResult = {
895917
- kind: "error",
895918
- title: "Onboarding completion failed",
895919
- detail,
895920
- safety: "safe"
895921
- };
896405
+ this.lastActionResult = { kind: "error", title: "Onboarding completion failed", detail, safety: "safe" };
895922
896406
  }
895923
896407
  }
896408
+ applySettingAction(action2, requestRender) {
896409
+ const effect = buildAgentWorkspaceSettingActionEffect(this.context, action2);
896410
+ if (effect.kind === "result") {
896411
+ this.status = effect.status;
896412
+ this.lastActionResult = effect.result;
896413
+ return;
896414
+ }
896415
+ if (effect.kind === "editor") {
896416
+ this.localEditor = effect.editor;
896417
+ this.status = effect.status;
896418
+ this.lastActionResult = effect.result;
896419
+ return;
896420
+ }
896421
+ this.applySettingValue(effect.setting, effect.value, requestRender);
896422
+ }
896423
+ importTuiSettings(requestRender) {
896424
+ this.importTuiSettingsAsync(requestRender);
896425
+ }
895924
896426
  selectedItemForOperation(operation) {
895925
896427
  if (operation.startsWith("memory-"))
895926
896428
  return this.selectedLocalLibraryItem("memory");
@@ -895932,6 +896434,22 @@ class AgentWorkspace {
895932
896434
  return this.selectedLocalLibraryItem("skill");
895933
896435
  return this.selectedLocalLibraryItem("routine");
895934
896436
  }
896437
+ async applySettingValue(setting, value, requestRender) {
896438
+ const outcome = await applyAgentWorkspaceSettingValue(this.context, setting, value);
896439
+ this.runtimeSnapshot = this.context ? buildAgentWorkspaceRuntimeSnapshot(this.context) : this.runtimeSnapshot;
896440
+ this.clampSelection();
896441
+ this.status = outcome.status;
896442
+ this.lastActionResult = outcome.result;
896443
+ requestRender?.();
896444
+ }
896445
+ async importTuiSettingsAsync(requestRender) {
896446
+ const outcome = await importAgentWorkspaceTuiSettings(this.context);
896447
+ this.runtimeSnapshot = outcome.runtimeSnapshot ?? this.runtimeSnapshot;
896448
+ this.clampSelection();
896449
+ this.status = outcome.status;
896450
+ this.lastActionResult = outcome.result;
896451
+ requestRender?.();
896452
+ }
895935
896453
  memoryApi() {
895936
896454
  const memory = this.context?.clients?.agentKnowledgeApi?.memory;
895937
896455
  if (!memory)
@@ -896002,6 +896520,19 @@ class AgentWorkspace {
896002
896520
  requestRender?.();
896003
896521
  return;
896004
896522
  }
896523
+ if (editor.kind === "setting-set") {
896524
+ const setting = editor.recordId ? agentWorkspaceSettingSchema(this.context, editor.recordId) : null;
896525
+ if (!setting) {
896526
+ this.localEditor = { ...editor, message: "Unknown setting; cannot save." };
896527
+ this.status = "Unknown setting; cannot save.";
896528
+ requestRender?.();
896529
+ return;
896530
+ }
896531
+ const value = this.editorField("value");
896532
+ this.localEditor = null;
896533
+ this.applySettingValue(setting, value, requestRender);
896534
+ return;
896535
+ }
896005
896536
  if (editor.kind === "memory") {
896006
896537
  if (editor.mode === "delete") {
896007
896538
  try {
@@ -897600,7 +898131,7 @@ function handleProfilePickerToken(state4, token) {
897600
898131
  }
897601
898132
 
897602
898133
  // src/input/handler-picker-routes.ts
897603
- import { readFileSync as readFileSync94 } from "fs";
898134
+ import { readFileSync as readFileSync95 } from "fs";
897604
898135
 
897605
898136
  // src/renderer/model-picker-overlay.ts
897606
898137
  var MODEL_PICKER_CHROME_LINES = 7;
@@ -897892,7 +898423,7 @@ function handleFilePickerToken(state4, token) {
897892
898423
  throw new Error("working directory is unavailable");
897893
898424
  }
897894
898425
  const resolvedPath3 = resolveAndValidatePath(selected, projectRoot);
897895
- const data = readFileSync94(resolvedPath3);
898426
+ const data = readFileSync95(resolvedPath3);
897896
898427
  const base644 = data.toString("base64");
897897
898428
  const mediaType = state4.mediaTypeFromExt(ext);
897898
898429
  const filename = selected.split("/").pop() ?? selected;
@@ -902226,15 +902757,6 @@ function handleBlockingShellInput(options) {
902226
902757
  }
902227
902758
 
902228
902759
  // src/renderer/agent-workspace-style.ts
902229
- function safetyColor(action2) {
902230
- if (action2.safety === "safe")
902231
- return FULLSCREEN_PALETTE.good;
902232
- if (action2.safety === "read-only")
902233
- return FULLSCREEN_PALETTE.info;
902234
- if (action2.safety === "delegates")
902235
- return FULLSCREEN_PALETTE.warn;
902236
- return FULLSCREEN_PALETTE.bad;
902237
- }
902238
902760
  function actionResultColor(result2) {
902239
902761
  if (result2.kind === "blocked" || result2.kind === "error")
902240
902762
  return FULLSCREEN_PALETTE.bad;
@@ -902294,6 +902816,10 @@ function actionCommand(action2) {
902294
902816
  return action2.targetCategoryId ? `open ${action2.targetCategoryId}` : "(workspace)";
902295
902817
  if (action2.kind === "editor")
902296
902818
  return action2.editorKind ? `edit ${action2.editorKind}` : "(editor)";
902819
+ if (action2.kind === "setting")
902820
+ return action2.settingKey ? `set ${action2.settingKey}` : "set setting";
902821
+ if (action2.kind === "settings-import")
902822
+ return "import GoodVibes settings";
902297
902823
  if (action2.kind === "local-selection")
902298
902824
  return action2.selectionDelta && action2.selectionDelta < 0 ? "select previous" : "select next";
902299
902825
  if (action2.kind === "local-operation")
@@ -902321,8 +902847,8 @@ function compactText3(text, maxWidth = 104) {
902321
902847
  }
902322
902848
  function actionMetaLine(action2) {
902323
902849
  return {
902324
- text: `${actionCommand(action2)}; ${action2.safety}`,
902325
- fg: action2.kind === "command" ? FULLSCREEN_PALETTE.info : safetyColor(action2)
902850
+ text: `Does: ${actionCommand(action2)}`,
902851
+ fg: action2.safety === "blocked" ? FULLSCREEN_PALETTE.warn : action2.kind === "command" ? FULLSCREEN_PALETTE.info : FULLSCREEN_PALETTE.muted
902326
902852
  };
902327
902853
  }
902328
902854
  function setupAttentionItems(snapshot2, limit3) {
@@ -902343,7 +902869,7 @@ function setupOverviewLines(snapshot2) {
902343
902869
  const counts = setupCounts(snapshot2);
902344
902870
  const nextItems = setupAttentionItems(snapshot2, 3);
902345
902871
  const lines = [
902346
- { text: "Setup Overview", fg: FULLSCREEN_PALETTE.title, bold: true },
902872
+ { text: "Onboarding", fg: FULLSCREEN_PALETTE.title, bold: true },
902347
902873
  { text: `${counts.ready}/${snapshot2.setupChecklist.length} ready; ${counts.recommended} recommended; ${counts.optional} optional; ${counts.blocked} blocked.`, fg: counts.blocked > 0 ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.info },
902348
902874
  { text: `Chat: ${snapshot2.provider} / ${snapshot2.modelDisplayName}.`, fg: FULLSCREEN_PALETTE.info },
902349
902875
  { text: `Local: ${snapshot2.localPersonaCount} personas, ${snapshot2.localSkillCount} skills, ${snapshot2.localRoutineCount} routines, ${snapshot2.localMemoryCount} memories.`, fg: FULLSCREEN_PALETTE.info }
@@ -902491,7 +903017,7 @@ function snapshotLines(workspace, category, snapshot2) {
902491
903017
  const needsTarget = snapshot2.channels.filter((channel) => channel.setupState === "needs-target");
902492
903018
  const needsConfig = snapshot2.channels.filter((channel) => channel.setupState === "needs-config");
902493
903019
  const nextAttentionChannel = needsConfig[0] ?? needsTarget[0] ?? snapshot2.channels.find((channel) => !channel.enabled);
902494
- base2.push({ text: `API: ${snapshot2.runtimeBaseUrl}`, fg: FULLSCREEN_PALETTE.info }, companionAccessLine(snapshot2), { text: `Channels: ${readyCount}/${snapshot2.channels.length} ready; ${enabledCount} enabled; ${configuredDefaults} target(s).`, fg: FULLSCREEN_PALETTE.info }, { text: `Next: ${nextAttentionChannel ? `${nextAttentionChannel.label} - ${compactText3(nextAttentionChannel.nextStep)}` : "All enabled channels ready."}`, fg: nextAttentionChannel ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.good }, { text: "Safety: secrets hidden; sends require explicit action.", fg: FULLSCREEN_PALETTE.warn });
903020
+ base2.push({ text: `API: ${snapshot2.runtimeBaseUrl}`, fg: FULLSCREEN_PALETTE.info }, companionAccessLine(snapshot2), { text: `Channels: ${readyCount}/${snapshot2.channels.length} ready; ${enabledCount} enabled; ${configuredDefaults} target(s).`, fg: FULLSCREEN_PALETTE.info }, { text: `Next: ${nextAttentionChannel ? `${nextAttentionChannel.label} - ${compactText3(nextAttentionChannel.nextStep)}` : "All enabled channels ready."}`, fg: nextAttentionChannel ? FULLSCREEN_PALETTE.warn : FULLSCREEN_PALETTE.good }, { text: "Secrets hidden; sends require explicit action.", fg: FULLSCREEN_PALETTE.warn });
902495
903021
  } else if (category.id === "knowledge") {
902496
903022
  base2.push({ text: `Route: ${snapshot2.knowledgeRoute}; isolation ${snapshot2.knowledgeIsolation}.`, fg: FULLSCREEN_PALETTE.info }, { text: "Ask/search, ingest, review, reindex, and reports stay Agent-owned.", fg: FULLSCREEN_PALETTE.good }, { text: "Ingest requires explicit confirmation.", fg: FULLSCREEN_PALETTE.warn });
902497
903023
  } else if (category.id === "research") {
@@ -902634,9 +903160,8 @@ function buildActionRows(workspace, width, height) {
902634
903160
  if (workspace.localEditor)
902635
903161
  return buildEditorRows(workspace.localEditor, width, height);
902636
903162
  const rows = [];
902637
- const labelWidth = Math.min(28, Math.max(16, Math.floor(width * 0.3)));
902638
- const safetyWidth = 10;
902639
- const commandWidth = Math.max(10, width - labelWidth - safetyWidth - 9);
903163
+ const labelWidth = Math.min(34, Math.max(18, Math.floor(width * 0.38)));
903164
+ const commandWidth = Math.max(10, width - labelWidth - 6);
902640
903165
  if (workspace.actionSearchActive) {
902641
903166
  rows.push({
902642
903167
  text: ` Search: ${workspace.actionSearchQuery || "(type to filter actions)"}`,
@@ -902645,7 +903170,7 @@ function buildActionRows(workspace, width, height) {
902645
903170
  });
902646
903171
  }
902647
903172
  rows.push({
902648
- text: ` ${padDisplay(workspace.actionSearchActive ? "Result" : "Action", labelWidth)} ${padDisplay("Safety", safetyWidth)} ${padDisplay("Command", commandWidth)}`,
903173
+ text: ` ${padDisplay(workspace.actionSearchActive ? "Result" : "Action", labelWidth)} ${padDisplay("Does", commandWidth)}`,
902649
903174
  fg: FULLSCREEN_PALETTE.muted,
902650
903175
  bold: true
902651
903176
  });
@@ -902661,9 +903186,9 @@ function buildActionRows(workspace, width, height) {
902661
903186
  const label = searchResult ? `${searchResult.category.label} / ${action2.label}` : action2.label;
902662
903187
  const marker = selected ? GLYPHS.navigation.selected : " ";
902663
903188
  rows.push({
902664
- text: `${marker} ${padDisplay(label, labelWidth)} ${padDisplay(action2.safety, safetyWidth)} ${padDisplay(actionCommand(action2), commandWidth)}`,
903189
+ text: `${marker} ${padDisplay(label, labelWidth)} ${padDisplay(actionCommand(action2), commandWidth)}`,
902665
903190
  selected: selected && workspace.focusPane === "actions",
902666
- fg: safetyColor(action2),
903191
+ fg: action2.safety === "blocked" ? FULLSCREEN_PALETTE.warn : selected ? FULLSCREEN_PALETTE.text : FULLSCREEN_PALETTE.info,
902667
903192
  bold: selected
902668
903193
  });
902669
903194
  }
@@ -902712,7 +903237,7 @@ function renderAgentWorkspace(workspace, width, height) {
902712
903237
  title: "GoodVibes Agent / Operator Workspace",
902713
903238
  stateLabel: workspace.localEditor ? "Editor" : workspace.actionSearchActive ? "Search" : workspace.focusPane === "categories" ? "Categories" : "Actions",
902714
903239
  leftHeader: "Operator Areas",
902715
- mainHeader: workspace.actionSearchActive ? `Search actions \xB7 ${workspace.actions.length} result(s)` : `${category.label} \xB7 ${category.actions.length} action(s)`,
903240
+ mainHeader: workspace.actionSearchActive ? `Search actions \xB7 ${workspace.actions.length} result(s)` : `${category.label} \xB7 ${workspace.actions.length} action(s)`,
902716
903241
  leftRows: buildLeftRows2(workspace, metrics.bodyRows),
902717
903242
  contextRows: buildContextRows(workspace, category, action2, metrics.contextWidth),
902718
903243
  controlRows: buildActionRows(workspace, metrics.contextWidth, metrics.controlRows),
@@ -903139,7 +903664,7 @@ function wireShellUiOpeners(options) {
903139
903664
  }
903140
903665
 
903141
903666
  // src/cli/entrypoint.ts
903142
- import { existsSync as existsSync87 } from "fs";
903667
+ import { existsSync as existsSync88 } from "fs";
903143
903668
  import { join as join98 } from "path";
903144
903669
  // src/cli/status.ts
903145
903670
  function yesNo3(value) {
@@ -903747,9 +904272,9 @@ async function prepareShellCliRuntime(argv, roots, binary2 = "goodvibes-agent")
903747
904272
  onboardingMarkers,
903748
904273
  auth: {
903749
904274
  userStorePath,
903750
- userStorePresent: existsSync87(userStorePath),
904275
+ userStorePresent: existsSync88(userStorePath),
903751
904276
  bootstrapCredentialPath,
903752
- bootstrapCredentialPresent: existsSync87(bootstrapCredentialPath),
904277
+ bootstrapCredentialPresent: existsSync88(bootstrapCredentialPath),
903753
904278
  operatorTokenPath: effectiveOperatorTokenPath,
903754
904279
  operatorTokenPresent: externalRuntime.operatorToken.present
903755
904280
  },