@hasna/assistants 1.1.54 → 1.1.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -665,7 +665,7 @@ async function loadTextFile(path) {
665
665
  return null;
666
666
  }
667
667
  }
668
- var DEFAULT_SYSTEM_PROMPT = `You are Hasna Assistant, a helpful AI assistant running in the terminal.
668
+ var DEFAULT_SYSTEM_PROMPT = `You are a helpful AI assistant by Hasna, running in the terminal. Your name and capabilities are defined by your identity configuration \u2014 do not invent a name for yourself.
669
669
 
670
670
  ## Runtime Environment
671
671
  - Use **Bun** as the default runtime for JavaScript/TypeScript scripts
@@ -89084,7 +89084,7 @@ Not a git repository or git not available.
89084
89084
  context.setProjectContext(projectContext);
89085
89085
  }
89086
89086
  }
89087
- var VERSION2 = "1.1.54";
89087
+ var VERSION2 = "1.1.56";
89088
89088
  var init_builtin = __esm(async () => {
89089
89089
  init_src2();
89090
89090
  init_context3();
@@ -214961,6 +214961,42 @@ var init_migration = __esm(() => {
214961
214961
  init_validators();
214962
214962
  });
214963
214963
 
214964
+ // packages/core/src/config-store.ts
214965
+ function getConfigValue(key, scope = "global", scopeId = "") {
214966
+ try {
214967
+ const db = getDatabase();
214968
+ const row = db.query("SELECT value FROM config WHERE scope = ? AND scope_id = ? AND key = ?").get(scope, scopeId, key);
214969
+ return row?.value ?? null;
214970
+ } catch {
214971
+ return null;
214972
+ }
214973
+ }
214974
+ function setConfigValue(key, value, scope = "global", scopeId = "") {
214975
+ try {
214976
+ const db = getDatabase();
214977
+ db.prepare(`INSERT INTO config (scope, scope_id, key, value, updated_at)
214978
+ VALUES (?, ?, ?, ?, ?)
214979
+ ON CONFLICT (scope, scope_id, key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at`).run(scope, scopeId, key, value, new Date().toISOString());
214980
+ } catch {}
214981
+ }
214982
+ function isOnboardingCompleted() {
214983
+ const val = getConfigValue("onboardingCompleted");
214984
+ return val === "true";
214985
+ }
214986
+ function markOnboardingCompleted() {
214987
+ setConfigValue("onboardingCompleted", "true");
214988
+ }
214989
+ function isFirstGreetingShown() {
214990
+ const val = getConfigValue("firstGreetingShown");
214991
+ return val === "true";
214992
+ }
214993
+ function markFirstGreetingShown() {
214994
+ setConfigValue("firstGreetingShown", "true");
214995
+ }
214996
+ var init_config_store = __esm(async () => {
214997
+ await init_database();
214998
+ });
214999
+
214964
215000
  // packages/core/src/scheduler/index.ts
214965
215001
  var init_scheduler2 = __esm(async () => {
214966
215002
  init_cron();
@@ -215268,6 +215304,7 @@ __export(exports_src3, {
215268
215304
  setRuntime: () => setRuntime,
215269
215305
  setPaused: () => setPaused,
215270
215306
  setDnsLookupForTests: () => setDnsLookupForTests,
215307
+ setConfigValue: () => setConfigValue,
215271
215308
  setAutoRun: () => setAutoRun,
215272
215309
  setActiveWorkspaceId: () => setActiveWorkspaceId,
215273
215310
  sessionUpdateTool: () => sessionUpdateTool,
@@ -215385,6 +215422,8 @@ __export(exports_src3, {
215385
215422
  memoryRecallTool: () => memoryRecallTool,
215386
215423
  memoryListTool: () => memoryListTool,
215387
215424
  memoryForgetTool: () => memoryForgetTool,
215425
+ markOnboardingCompleted: () => markOnboardingCompleted,
215426
+ markFirstGreetingShown: () => markFirstGreetingShown,
215388
215427
  logsTools: () => logsTools,
215389
215428
  logsTailTool: () => logsTailTool,
215390
215429
  logsStatsTool: () => logsStatsTool,
@@ -215412,8 +215451,10 @@ __export(exports_src3, {
215412
215451
  isPaused: () => isPaused,
215413
215452
  isPathSafe: () => isPathSafe,
215414
215453
  isOpenAIConfigured: () => isOpenAIConfigured,
215454
+ isOnboardingCompleted: () => isOnboardingCompleted,
215415
215455
  isMigrated: () => isMigrated,
215416
215456
  isIpLiteral: () => isIpLiteral,
215457
+ isFirstGreetingShown: () => isFirstGreetingShown,
215417
215458
  isExaConfigured: () => isExaConfigured,
215418
215459
  isElevenLabsConfigured: () => isElevenLabsConfigured,
215419
215460
  isAutoRun: () => isAutoRun,
@@ -215474,6 +215515,7 @@ __export(exports_src3, {
215474
215515
  getDefaultCapabilities: () => getDefaultCapabilities,
215475
215516
  getDatabasePath: () => getDatabasePath,
215476
215517
  getDatabase: () => getDatabase,
215518
+ getConfigValue: () => getConfigValue,
215477
215519
  getConfigPath: () => getConfigPath,
215478
215520
  getConfigDir: () => getConfigDir,
215479
215521
  getCommandHistory: () => getCommandHistory,
@@ -215874,6 +215916,7 @@ var init_src3 = __esm(async () => {
215874
215916
  init_global_memory(),
215875
215917
  init_budget(),
215876
215918
  init_config(),
215919
+ init_config_store(),
215877
215920
  init_client4(),
215878
215921
  init_registry3(),
215879
215922
  init_store12(),
@@ -259240,37 +259283,15 @@ function ProcessingIndicator({
259240
259283
  init_src2();
259241
259284
  await init_build2();
259242
259285
  var jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
259243
- var MINI_LOGO = [
259244
- " \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588",
259245
- "\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ",
259246
- "\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588",
259247
- "\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588",
259248
- "\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588"
259249
- ];
259250
- var COLORS = ["#7dd3fc", "#38bdf8", "#0ea5e9", "#0284c7", "#0369a1"];
259251
259286
  function WelcomeBanner({ version: version5, model, directory }) {
259252
259287
  const homeDir = process.env.HOME || "";
259253
259288
  const displayDir = homeDir && directory.startsWith(homeDir) ? "~" + directory.slice(homeDir.length) : directory;
259254
259289
  const displayModel = getModelDisplayName(model);
259255
- const isWide2 = (process.stdout.columns || 80) >= 82;
259256
259290
  return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
259257
259291
  flexDirection: "column",
259258
259292
  marginBottom: 1,
259259
259293
  children: [
259260
- isWide2 ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
259261
- flexDirection: "column",
259262
- marginBottom: 0,
259263
- children: [
259264
- MINI_LOGO.map((line, i5) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text3, {
259265
- color: COLORS[i5],
259266
- children: line
259267
- }, i5, false, undefined, this)),
259268
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text3, {
259269
- dimColor: true,
259270
- children: " by "
259271
- }, undefined, false, undefined, this)
259272
- ]
259273
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
259294
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
259274
259295
  marginBottom: 0,
259275
259296
  children: [
259276
259297
  /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text3, {
@@ -259286,32 +259307,18 @@ function WelcomeBanner({ version: version5, model, directory }) {
259286
259307
  }, undefined, true, undefined, this),
259287
259308
  /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
259288
259309
  marginTop: 0,
259289
- children: [
259290
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text3, {
259291
- dimColor: true,
259292
- children: [
259293
- "v",
259294
- version5,
259295
- " "
259296
- ]
259297
- }, undefined, true, undefined, this),
259298
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text3, {
259299
- dimColor: true,
259300
- children: [
259301
- " ",
259302
- displayModel,
259303
- " "
259304
- ]
259305
- }, undefined, true, undefined, this),
259306
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text3, {
259307
- dimColor: true,
259308
- children: [
259309
- " ",
259310
- displayDir
259311
- ]
259312
- }, undefined, true, undefined, this)
259313
- ]
259314
- }, undefined, true, undefined, this)
259310
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text3, {
259311
+ dimColor: true,
259312
+ children: [
259313
+ "v",
259314
+ version5,
259315
+ " ",
259316
+ displayModel,
259317
+ " ",
259318
+ displayDir
259319
+ ]
259320
+ }, undefined, true, undefined, this)
259321
+ }, undefined, false, undefined, this)
259315
259322
  ]
259316
259323
  }, undefined, true, undefined, this);
259317
259324
  }
@@ -274482,13 +274489,13 @@ function useTypewriter(text, speed = 30, active = true) {
274482
274489
 
274483
274490
  // packages/terminal/src/hooks/useGradientCycle.ts
274484
274491
  var import_react65 = __toESM(require_react(), 1);
274485
- var COLORS2 = ["cyan", "blue", "magenta", "red", "yellow", "green"];
274492
+ var COLORS = ["cyan", "blue", "magenta", "red", "yellow", "green"];
274486
274493
  function useGradientCycle(intervalMs = 800) {
274487
274494
  const [index, setIndex] = import_react65.useState(0);
274488
274495
  const timerRef = import_react65.useRef(null);
274489
274496
  import_react65.useEffect(() => {
274490
274497
  timerRef.current = setInterval(() => {
274491
- setIndex((prev) => (prev + 1) % COLORS2.length);
274498
+ setIndex((prev) => (prev + 1) % COLORS.length);
274492
274499
  }, intervalMs);
274493
274500
  return () => {
274494
274501
  if (timerRef.current) {
@@ -274497,13 +274504,13 @@ function useGradientCycle(intervalMs = 800) {
274497
274504
  }
274498
274505
  };
274499
274506
  }, [intervalMs]);
274500
- return COLORS2[index];
274507
+ return COLORS[index];
274501
274508
  }
274502
274509
 
274503
274510
  // packages/terminal/src/components/OnboardingPanel.tsx
274504
274511
  init_src2();
274505
274512
  var jsx_dev_runtime32 = __toESM(require_jsx_dev_runtime(), 1);
274506
- var STEPS = ["welcome", "intro", "provider-select", "model-select", "api-key", "connectors", "connector-keys", "summary"];
274513
+ var STEPS = ["welcome", "intro", "provider-select", "model-select", "api-key", "connectors", "skills", "connector-keys", "summary"];
274507
274514
  var POPULAR_CONNECTORS = {
274508
274515
  notion: { desc: "Notion workspace", install: "bun add -g connect-notion" },
274509
274516
  gmail: { desc: "Gmail email", install: "bun add -g connect-gmail" },
@@ -274522,11 +274529,11 @@ var LOGO_LINES = [
274522
274529
  var GRADIENT_COLORS = ["#7dd3fc", "#38bdf8", "#0ea5e9", "#0284c7", "#0369a1"];
274523
274530
  var COMPACT_LOGO = "ASSISTANTS";
274524
274531
  var INTRO_FEATURES = [
274525
- "Chat with Claude AI directly in your terminal",
274526
- "Connect to your tools - Notion, Gmail, Google Drive & more",
274527
- "Learn skills to automate your workflows",
274528
- "Remember context across conversations",
274529
- "Run on schedules and respond to webhooks"
274532
+ "Chat with AI models - Claude, GPT, and more",
274533
+ "Install connectors to integrate Notion, Gmail, Google Drive & more",
274534
+ "Install skills to automate your workflows",
274535
+ "Persistent memory across conversations",
274536
+ "Schedules, webhooks, and autonomous operation"
274530
274537
  ];
274531
274538
  var MAX_VISIBLE_CONNECTORS = 5;
274532
274539
  function getVisibleRange5(selectedIndex, totalItems, maxVisible = MAX_VISIBLE_CONNECTORS) {
@@ -274599,7 +274606,8 @@ function OnboardingPanel({
274599
274606
  onCancel,
274600
274607
  existingApiKeys,
274601
274608
  existingModel,
274602
- discoveredConnectors
274609
+ discoveredConnectors,
274610
+ discoveredSkills
274603
274611
  }) {
274604
274612
  const [currentStep, setCurrentStep] = import_react66.useState("welcome");
274605
274613
  const initialProvider = existingModel && getProviderForModel(existingModel) || "anthropic";
@@ -274623,6 +274631,8 @@ function OnboardingPanel({
274623
274631
  const [isCompact, setIsCompact] = import_react66.useState(false);
274624
274632
  const [isSaving, setIsSaving] = import_react66.useState(false);
274625
274633
  const submitGuardRef = import_react66.useRef(false);
274634
+ const skillsList = discoveredSkills || [];
274635
+ const [selectedSkillIndex, setSelectedSkillIndex] = import_react66.useState(0);
274626
274636
  const selectedProvider = LLM_PROVIDERS[selectedProviderIndex]?.id || "anthropic";
274627
274637
  const providerModels = ALL_MODELS.filter((m5) => m5.provider === selectedProvider);
274628
274638
  const availableModels = providerModels.length > 0 ? providerModels : ALL_MODELS;
@@ -274670,7 +274680,7 @@ function OnboardingPanel({
274670
274680
  if (idx > 0) {
274671
274681
  let prevStep = STEPS[idx - 1];
274672
274682
  if (prevStep === "connector-keys" && connectorKeysNeeded.length === 0) {
274673
- prevStep = "connectors";
274683
+ prevStep = "skills";
274674
274684
  }
274675
274685
  setCurrentStep(prevStep);
274676
274686
  }
@@ -274686,12 +274696,13 @@ function OnboardingPanel({
274686
274696
  provider: selectedProvider,
274687
274697
  model: selectedModel ? selectedModel.id : existingModel || "",
274688
274698
  connectors: Array.from(enabledConnectors),
274689
- connectorKeys
274699
+ connectorKeys,
274700
+ skills: skillsList.map((s6) => s6.name)
274690
274701
  });
274691
274702
  } finally {
274692
274703
  setIsSaving(false);
274693
274704
  }
274694
- }, [apiKey, selectedModelIndex, enabledConnectors, connectorKeys, onComplete, isSaving, selectedProvider, availableModels, existingModel]);
274705
+ }, [apiKey, selectedModelIndex, enabledConnectors, connectorKeys, onComplete, isSaving, selectedProvider, availableModels, existingModel, skillsList]);
274695
274706
  const submitApiKey = import_react66.useCallback((value) => {
274696
274707
  if (submitGuardRef.current)
274697
274708
  return;
@@ -274806,6 +274817,15 @@ function OnboardingPanel({
274806
274817
  }
274807
274818
  break;
274808
274819
  }
274820
+ case "skills":
274821
+ if (key.upArrow) {
274822
+ setSelectedSkillIndex((prev) => Math.max(0, prev - 1));
274823
+ } else if (key.downArrow) {
274824
+ setSelectedSkillIndex((prev) => Math.min(Math.max(0, skillsList.length - 1), prev + 1));
274825
+ } else if (key.return) {
274826
+ goNext();
274827
+ }
274828
+ break;
274809
274829
  case "connector-keys":
274810
274830
  break;
274811
274831
  case "summary":
@@ -274821,6 +274841,8 @@ function OnboardingPanel({
274821
274841
  setCurrentStep("api-key");
274822
274842
  } else if (keyInput === "c") {
274823
274843
  setCurrentStep("connectors");
274844
+ } else if (keyInput === "s") {
274845
+ setCurrentStep("skills");
274824
274846
  }
274825
274847
  }
274826
274848
  break;
@@ -275201,16 +275223,37 @@ function OnboardingPanel({
275201
275223
  }, undefined, false, undefined, this),
275202
275224
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275203
275225
  bold: true,
275204
- children: "Connect your tools"
275226
+ children: "Connectors"
275205
275227
  }, undefined, false, undefined, this),
275206
275228
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275207
- flexDirection: "column",
275208
275229
  marginTop: 1,
275230
+ marginBottom: 1,
275231
+ flexDirection: "column",
275232
+ children: [
275233
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275234
+ color: "gray",
275235
+ children: "Connectors integrate external services. Install packages to add more."
275236
+ }, undefined, false, undefined, this),
275237
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275238
+ color: "gray",
275239
+ dimColor: true,
275240
+ children: [
275241
+ "Coming soon: ",
275242
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275243
+ color: "cyan",
275244
+ children: "bun add -g @hasna/connectors"
275245
+ }, undefined, false, undefined, this)
275246
+ ]
275247
+ }, undefined, true, undefined, this)
275248
+ ]
275249
+ }, undefined, true, undefined, this),
275250
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275251
+ flexDirection: "column",
275209
275252
  children: [
275210
275253
  visibleRange.hasMore.above > 0 && /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275211
275254
  dimColor: true,
275212
275255
  children: [
275213
- " \u2191 ",
275256
+ " ^ ",
275214
275257
  visibleRange.hasMore.above,
275215
275258
  " more above"
275216
275259
  ]
@@ -275249,9 +275292,9 @@ function OnboardingPanel({
275249
275292
  descDisplay
275250
275293
  ]
275251
275294
  }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275252
- color: "gray",
275295
+ dimColor: true,
275253
275296
  children: [
275254
- " ",
275297
+ " (not installed) ",
275255
275298
  connector.install
275256
275299
  ]
275257
275300
  }, undefined, true, undefined, this)
@@ -275261,7 +275304,7 @@ function OnboardingPanel({
275261
275304
  visibleRange.hasMore.below > 0 && /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275262
275305
  dimColor: true,
275263
275306
  children: [
275264
- " \u2193 ",
275307
+ " v ",
275265
275308
  visibleRange.hasMore.below,
275266
275309
  " more below"
275267
275310
  ]
@@ -275270,10 +275313,100 @@ function OnboardingPanel({
275270
275313
  }, undefined, true, undefined, this),
275271
275314
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275272
275315
  marginTop: 1,
275316
+ flexDirection: "column",
275317
+ children: [
275318
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275319
+ color: "gray",
275320
+ children: "Arrow keys to move, Space to toggle installed, Enter to continue"
275321
+ }, undefined, false, undefined, this),
275322
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275323
+ color: "gray",
275324
+ children: "Esc or B to go back"
275325
+ }, undefined, false, undefined, this)
275326
+ ]
275327
+ }, undefined, true, undefined, this)
275328
+ ]
275329
+ }, undefined, true, undefined, this);
275330
+ }
275331
+ if (currentStep === "skills") {
275332
+ return /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275333
+ flexDirection: "column",
275334
+ paddingX: 1,
275335
+ children: [
275336
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(ProgressBar, {
275337
+ step: stepIndex,
275338
+ total: STEPS.length
275339
+ }, undefined, false, undefined, this),
275340
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275341
+ bold: true,
275342
+ children: "Skills"
275343
+ }, undefined, false, undefined, this),
275344
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275345
+ marginTop: 1,
275346
+ marginBottom: 1,
275347
+ flexDirection: "column",
275348
+ children: [
275349
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275350
+ color: "gray",
275351
+ children: "Skills teach your assistant specialized workflows."
275352
+ }, undefined, false, undefined, this),
275353
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275354
+ color: "gray",
275355
+ dimColor: true,
275356
+ children: [
275357
+ "Coming soon: ",
275358
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275359
+ color: "cyan",
275360
+ children: "bun add -g @hasna/skills"
275361
+ }, undefined, false, undefined, this)
275362
+ ]
275363
+ }, undefined, true, undefined, this)
275364
+ ]
275365
+ }, undefined, true, undefined, this),
275366
+ skillsList.length > 0 ? /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275367
+ flexDirection: "column",
275368
+ children: skillsList.map((skill, i5) => {
275369
+ const isSelected = i5 === selectedSkillIndex;
275370
+ return /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275371
+ children: [
275372
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275373
+ color: isSelected ? "cyan" : "gray",
275374
+ children: isSelected ? "> " : " "
275375
+ }, undefined, false, undefined, this),
275376
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275377
+ color: "green",
275378
+ children: "[x]"
275379
+ }, undefined, false, undefined, this),
275380
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275381
+ children: [
275382
+ " /",
275383
+ skill.name
275384
+ ]
275385
+ }, undefined, true, undefined, this),
275386
+ skill.description && /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275387
+ color: "gray",
275388
+ children: [
275389
+ " ",
275390
+ skill.description.length > 40 ? skill.description.slice(0, 37) + "..." : skill.description
275391
+ ]
275392
+ }, undefined, true, undefined, this)
275393
+ ]
275394
+ }, skill.name, true, undefined, this);
275395
+ })
275396
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275397
+ marginBottom: 1,
275398
+ children: /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275399
+ dimColor: true,
275400
+ children: " No skills discovered. Add SKILL.md files to ~/.assistants/skills/"
275401
+ }, undefined, false, undefined, this)
275402
+ }, undefined, false, undefined, this),
275403
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275404
+ marginTop: 1,
275405
+ flexDirection: "column",
275273
275406
  children: [
275274
275407
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275275
275408
  color: "gray",
275276
- children: "Arrow keys to move, Space to toggle, Enter to continue"
275409
+ children: "Press Enter to continue..."
275277
275410
  }, undefined, false, undefined, this),
275278
275411
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275279
275412
  color: "gray",
@@ -275350,6 +275483,7 @@ function OnboardingPanel({
275350
275483
  const selectedModel = availableModels[selectedModelIndex] || availableModels[0];
275351
275484
  const modelLabel = selectedModel ? `${selectedModel.name} (${getProviderLabel(selectedProvider)})` : "unknown";
275352
275485
  const connectorList = Array.from(enabledConnectors).join(", ") || "none";
275486
+ const skillsDisplay = skillsList.length > 0 ? skillsList.map((s6) => s6.name).join(", ") : "none";
275353
275487
  const modelDisplay = modelLabel.length > 24 ? modelLabel.slice(0, 21) + "..." : modelLabel.padEnd(24);
275354
275488
  return /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
275355
275489
  flexDirection: "column",
@@ -275421,6 +275555,17 @@ function OnboardingPanel({
275421
275555
  "\u2502"
275422
275556
  ]
275423
275557
  }, undefined, true, undefined, this),
275558
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275559
+ color: "gray",
275560
+ children: [
275561
+ "\u2502",
275562
+ " Skills: ",
275563
+ /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275564
+ children: skillsDisplay.length > 24 ? skillsDisplay.slice(0, 21) + "..." : skillsDisplay.padEnd(24)
275565
+ }, undefined, false, undefined, this),
275566
+ "\u2502"
275567
+ ]
275568
+ }, undefined, true, undefined, this),
275424
275569
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275425
275570
  color: "gray",
275426
275571
  children: [
@@ -275454,7 +275599,7 @@ function OnboardingPanel({
275454
275599
  children: [
275455
275600
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275456
275601
  color: "gray",
275457
- children: "Edit: (P)rovider (M)odel (K)ey (C)onnectors"
275602
+ children: "Edit: (P)rovider (M)odel (K)ey (C)onnectors (S)kills"
275458
275603
  }, undefined, false, undefined, this),
275459
275604
  /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Text3, {
275460
275605
  color: "gray",
@@ -286420,6 +286565,7 @@ function App2({ cwd: cwd3, version: version5 }) {
286420
286565
  const isProcessingRef = import_react84.useRef(isProcessing);
286421
286566
  const currentToolCallRef = import_react84.useRef(currentToolCall);
286422
286567
  const hasPendingToolsRef = import_react84.useRef(false);
286568
+ const pendingFirstGreetingRef = import_react84.useRef(false);
286423
286569
  const inputRef = import_react84.useRef(null);
286424
286570
  const isPanelOpen = showOnboardingPanel || showRecoveryPanel || showConnectorsPanel || showTasksPanel || showSchedulesPanel || showSkillsPanel || showAssistantsPanel || showIdentityPanel || showMemoryPanel || showHooksPanel || showGuardrailsPanel || showBudgetPanel || showModelPanel || showAssistantsRegistryPanel || showConfigPanel || showWebhooksPanel || showChannelsPanel || showPeoplePanel || showContactsPanel || showTelephonyPanel || showOrdersPanel || showJobsPanel || showDocsPanel || showMessagesPanel || showProjectsPanel || showPlansPanel || showWalletPanel || showSecretsPanel || showWorkspacePanel || showAssistantsDashboard || showSwarmPanel || showLogsPanel || showHeartbeatPanel || showResumePanel;
286425
286571
  const processingStartTimeRef = import_react84.useRef(processingStartTime);
@@ -287670,6 +287816,21 @@ function App2({ cwd: cwd3, version: version5 }) {
287670
287816
  }
287671
287817
  initStateRef.current = "done";
287672
287818
  setIsInitializing(false);
287819
+ if (pendingFirstGreetingRef.current) {
287820
+ pendingFirstGreetingRef.current = false;
287821
+ markFirstGreetingShown();
287822
+ setTimeout(() => {
287823
+ const greetingPrompt = [
287824
+ "This is the user's very first interaction with you after completing setup.",
287825
+ "Greet them warmly and briefly introduce yourself.",
287826
+ "You are their personal AI assistant, made by Hasna.",
287827
+ "Tell them you're ready to help and ask what they'd like to do.",
287828
+ "Keep it short and friendly (2-3 sentences max).",
287829
+ 'Do NOT say your name is "Hasna Assistant" \u2014 you are simply their assistant.'
287830
+ ].join(" ");
287831
+ session.client.send(greetingPrompt).catch(() => {});
287832
+ }, 300);
287833
+ }
287673
287834
  }, [cwd3, registry3, handleChunk, finalizeResponse2, resetTurnState, loadSessionMetadata, beginAskUser, beginInterview, workspaceBaseDir]);
287674
287835
  const handleRecover = import_react84.useCallback((session) => {
287675
287836
  setShowRecoveryPanel(false);
@@ -287749,7 +287910,13 @@ function App2({ cwd: cwd3, version: version5 }) {
287749
287910
  };
287750
287911
  writeFileSync12(configPath, JSON.stringify(newConfig, null, 2), "utf-8");
287751
287912
  await loadConfigFiles();
287913
+ try {
287914
+ markOnboardingCompleted();
287915
+ } catch {}
287752
287916
  process.env[envName] = result.apiKey;
287917
+ if (!isFirstGreetingShown()) {
287918
+ pendingFirstGreetingRef.current = true;
287919
+ }
287753
287920
  setShowOnboardingPanel(false);
287754
287921
  }, [loadConfigFiles, workspaceBaseDir]);
287755
287922
  const handleOnboardingCancel = import_react84.useCallback(() => {
@@ -287776,20 +287943,24 @@ function App2({ cwd: cwd3, version: version5 }) {
287776
287943
  return;
287777
287944
  }
287778
287945
  try {
287779
- const configPath = join43(workspaceBaseDir || getConfigDir(), "config.json");
287780
- const { existsSync: existsSync27, readFileSync: readFileSync16 } = await import("fs");
287781
287946
  let needsOnboarding = false;
287782
- if (!existsSync27(configPath)) {
287783
- needsOnboarding = true;
287947
+ if (isOnboardingCompleted()) {
287948
+ needsOnboarding = false;
287784
287949
  } else {
287785
- try {
287786
- const raw = readFileSync16(configPath, "utf-8");
287787
- const parsed = JSON.parse(raw);
287788
- if (!parsed.onboardingCompleted) {
287950
+ const configPath = join43(workspaceBaseDir || getConfigDir(), "config.json");
287951
+ const { existsSync: existsSync27, readFileSync: readFileSync16 } = await import("fs");
287952
+ if (!existsSync27(configPath)) {
287953
+ needsOnboarding = true;
287954
+ } else {
287955
+ try {
287956
+ const raw = readFileSync16(configPath, "utf-8");
287957
+ const parsed = JSON.parse(raw);
287958
+ if (!parsed.onboardingCompleted) {
287959
+ needsOnboarding = true;
287960
+ }
287961
+ } catch {
287789
287962
  needsOnboarding = true;
287790
287963
  }
287791
- } catch {
287792
- needsOnboarding = true;
287793
287964
  }
287794
287965
  }
287795
287966
  if (needsOnboarding) {
@@ -288646,7 +288817,8 @@ function App2({ cwd: cwd3, version: version5 }) {
288646
288817
  onComplete: handleOnboardingComplete,
288647
288818
  onCancel: handleOnboardingCancel,
288648
288819
  existingApiKeys: existingKeys,
288649
- discoveredConnectors: discoveredNames
288820
+ discoveredConnectors: discoveredNames,
288821
+ discoveredSkills: []
288650
288822
  }, undefined, false, undefined, this);
288651
288823
  }
288652
288824
  if (showRecoveryPanel && recoverableSessions.length > 0) {
@@ -290896,7 +291068,7 @@ Interactive Mode:
290896
291068
  // packages/terminal/src/index.tsx
290897
291069
  var jsx_dev_runtime52 = __toESM(require_jsx_dev_runtime(), 1);
290898
291070
  setRuntime(bunRuntime);
290899
- var VERSION4 = "1.1.54";
291071
+ var VERSION4 = "1.1.56";
290900
291072
  var SYNC_START = "\x1B[?2026h";
290901
291073
  var SYNC_END = "\x1B[?2026l";
290902
291074
  function enableSynchronizedOutput() {
@@ -291015,4 +291187,4 @@ export {
291015
291187
  main
291016
291188
  };
291017
291189
 
291018
- //# debugId=FC1EA89048010C4A64756E2164756E21
291190
+ //# debugId=B1A3529A1AEEA71664756E2164756E21