@kal-elsam/kairo-runtime 0.2.2 → 0.3.0

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.
@@ -2,9 +2,15 @@ import { stdin as input, stdout as output } from "node:process";
2
2
  import { resolveHomeDir } from "./paths.js";
3
3
  import { canUseOrchestratorShell } from "./ink/orchestrator-state.js";
4
4
  import { runOrchestratorInk as defaultRunOrchestratorInk } from "./ink/run-orchestrator-ink.js";
5
+ import { createFullscreenSession } from "./ink/fullscreen-session.js";
5
6
  import { formatCliCommand } from "./brand/cli.js";
6
7
  import { BRAND } from "./brand/index.js";
7
8
  import { buildReadOnlyDiagnostics, shouldExecutePlan } from "./action-planner.js";
9
+ import { runHarnessSetup as defaultRunHarnessSetup } from "./setup.js";
10
+ import {
11
+ INITIAL_EXPERIENCE,
12
+ hasConfiguredGlobalState
13
+ } from "./initial-experience.js";
8
14
 
9
15
  export { canUseOrchestratorShell };
10
16
 
@@ -23,7 +29,12 @@ export async function runOrchestratorShell({
23
29
  packageManifest,
24
30
  workspaceRoot,
25
31
  interactive = Boolean(input.isTTY && output.isTTY),
26
- runOrchestratorInkImpl = defaultRunOrchestratorInk
32
+ initialMode = INITIAL_EXPERIENCE.DASHBOARD,
33
+ shellCapable = canUseOrchestratorShell({ interactive }),
34
+ runOrchestratorInkImpl = defaultRunOrchestratorInk,
35
+ runHarnessSetupImpl = defaultRunHarnessSetup,
36
+ fullscreenSession = null,
37
+ stdout = output
27
38
  }) {
28
39
  if (!interactive) {
29
40
  throw new Error(
@@ -31,30 +42,75 @@ export async function runOrchestratorShell({
31
42
  );
32
43
  }
33
44
 
34
- if (!canUseOrchestratorShell({ interactive })) {
45
+ if (!shellCapable) {
35
46
  throw new Error(
36
47
  `Interactive shell requires a capable TTY. Use ${formatCliCommand("runs list")} or explicit commands.`
37
48
  );
38
49
  }
39
50
 
40
51
  const homeDir = resolveHomeDir();
41
- const outcome = await runOrchestratorInkImpl({
42
- homeDir,
43
- workspaceRoot,
44
- packageRoot,
45
- packageName: packageManifest.name,
46
- cliVersion: packageManifest.version
52
+ const ownsSession = !fullscreenSession;
53
+ const session = fullscreenSession ?? createFullscreenSession({
54
+ stdout,
55
+ enabled: Boolean(stdout?.isTTY)
47
56
  });
48
57
 
49
- if (outcome.error) {
50
- throw outcome.error;
58
+ if (ownsSession) {
59
+ session.enter();
51
60
  }
52
61
 
53
- return {
54
- cancelled: Boolean(outcome.cancelled),
55
- wrote: false,
56
- action: outcome.action ?? null
57
- };
62
+ let setupOutcome = null;
63
+
64
+ try {
65
+ if (initialMode === INITIAL_EXPERIENCE.ONBOARDING) {
66
+ setupOutcome = await runHarnessSetupImpl({
67
+ packageRoot,
68
+ packageName: packageManifest.name,
69
+ cliVersion: packageManifest.version,
70
+ homeDir,
71
+ workspaceRoot,
72
+ onboarding: true,
73
+ interactive: true,
74
+ fullscreenSession: session
75
+ });
76
+
77
+ if (setupOutcome?.cancelled) {
78
+ return {
79
+ cancelled: true,
80
+ wrote: false,
81
+ action: null,
82
+ initialMode,
83
+ setup: setupOutcome
84
+ };
85
+ }
86
+ }
87
+
88
+ const outcome = await runOrchestratorInkImpl({
89
+ homeDir,
90
+ workspaceRoot,
91
+ packageRoot,
92
+ packageName: packageManifest.name,
93
+ cliVersion: packageManifest.version,
94
+ hasGlobalState: hasConfiguredGlobalState(homeDir),
95
+ fullscreenSession: session
96
+ });
97
+
98
+ if (outcome.error) {
99
+ throw outcome.error;
100
+ }
101
+
102
+ return {
103
+ cancelled: Boolean(outcome.cancelled),
104
+ wrote: Boolean(setupOutcome && !setupOutcome.cancelled),
105
+ action: outcome.action ?? null,
106
+ initialMode,
107
+ setup: setupOutcome
108
+ };
109
+ } finally {
110
+ if (ownsSession) {
111
+ session.leave();
112
+ }
113
+ }
58
114
  }
59
115
 
60
116
  export async function runOrchestratorDiagnostics({
@@ -1,5 +1,5 @@
1
1
  import { stdin as input, stdout as output } from "node:process";
2
- import { BRAND } from "./brand/index.js";
2
+ import { BRAND, ONBOARDING_COPY } from "./brand/index.js";
3
3
  import { installGlobalHarness } from "./global-installer.js";
4
4
  import {
5
5
  assertExplicitApplyConsent,
@@ -59,11 +59,13 @@ export async function runHarnessSetup({
59
59
  confirmExplicit = false,
60
60
  json = false,
61
61
  simple = false,
62
+ onboarding = false,
62
63
  interactive = Boolean(input.isTTY && output.isTTY),
63
64
  createPrompt = createReadlinePrompt,
64
65
  runSetupInkImpl = defaultRunSetupInk,
65
66
  runSetupWizardImpl = defaultRunSetupWizard,
66
- inkCapable = canUseSetupInk({ interactive })
67
+ inkCapable = canUseSetupInk({ interactive }),
68
+ fullscreenSession = null
67
69
  }) {
68
70
  const routing = { interactive, simple, inkCapable, dryRun, yes, confirm, json, agents, components, noDefaultComponents };
69
71
  const useInk = evaluateSetupInk(routing);
@@ -76,7 +78,7 @@ export async function runHarnessSetup({
76
78
  let usedInk = false;
77
79
 
78
80
  if (!useInk && !useWizard) {
79
- printSetupIntro({ homeDir });
81
+ printSetupIntro({ homeDir, onboarding });
80
82
  }
81
83
 
82
84
  const setupUiArgs = {
@@ -86,13 +88,15 @@ export async function runHarnessSetup({
86
88
  packageName,
87
89
  cliVersion,
88
90
  dryRun,
91
+ onboarding,
89
92
  preflight,
90
93
  yes,
91
94
  confirm,
92
95
  preflightExplicit,
93
96
  yesExplicit,
94
97
  confirmExplicit,
95
- interactive
98
+ interactive,
99
+ fullscreenSession
96
100
  };
97
101
 
98
102
  if (useInk) {
@@ -254,11 +258,17 @@ export async function runHarnessSetup({
254
258
  return { cancelled: false, result, usedWizard, usedInk };
255
259
  }
256
260
 
257
- function printSetupIntro({ homeDir }) {
261
+ function printSetupIntro({ homeDir, onboarding = false }) {
258
262
  const detected = detectInstalledAdapters({ homeDir });
259
263
 
260
- console.log(`${BRAND.displayName} setup — local AI ecosystem configurator`);
261
- console.log("Configures and coordinates local agents. Does not install the AI apps themselves.");
264
+ if (onboarding) {
265
+ console.log(ONBOARDING_COPY.welcomeTitle);
266
+ console.log(ONBOARDING_COPY.purpose);
267
+ console.log(ONBOARDING_COPY.safety);
268
+ } else {
269
+ console.log(`${BRAND.displayName} setup — local AI ecosystem configurator`);
270
+ console.log("Configures and coordinates local agents. Does not install the AI apps themselves.");
271
+ }
262
272
  console.log("");
263
273
  console.log(`Detected agents: ${detected.join(", ") || "none"}`);
264
274
  console.log(`Supported agents: ${GLOBAL_AGENT_IDS.join(", ")}`);