nolo-cli 0.1.4 → 0.1.6

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/README.md CHANGED
@@ -21,6 +21,12 @@ Inside `nolo`, normal text continues the current dialog after the first agent
21
21
  reply. Use `/new` when you want a clean dialog. Response token details stay
22
22
  hidden by default; set `NOLO_SHOW_USAGE=1` when debugging usage.
23
23
 
24
+ Nolo is intentionally not trying to copy coding-only CLIs one-for-one. Claude
25
+ Code, Codex CLI, and Copilot CLI are strongest when a developer is already
26
+ inside a codebase. Nolo's CLI should sit between ordinary users and developers:
27
+ one assistant by default, with specialist agents, docs, tables, dialogs, and
28
+ synced workspace data one slash command away.
29
+
24
30
  ## Usage
25
31
 
26
32
  ```bash
@@ -85,6 +91,8 @@ Inside the future TUI, the same actions should be available as slash commands:
85
91
  ```text
86
92
  /agent list
87
93
  /agent switch ops
94
+ /agents
95
+ /switch 2
88
96
  /dialog open latest
89
97
  /doc list
90
98
  /table query builtin-dialog-probe-runs
@@ -131,9 +131,9 @@ async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string)
131
131
 
132
132
  const content = String(data?.content ?? data?.message ?? "").trim();
133
133
  if (content) {
134
- options.output.write(`\n${options.agentName}\n${content}\n`);
134
+ options.output.write(`\n${options.agentName} > ${content}\n`);
135
135
  } else {
136
- options.output.write(`\n${options.agentName}\n(no text response)\n`);
136
+ options.output.write(`\n${options.agentName} > (no text response)\n`);
137
137
  }
138
138
 
139
139
  const usage = formatUsage(data?.usage, data?.dialogId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nolo-cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "description": "Agent-first terminal workspace for Nolo",
6
6
  "bin": {
package/tui/session.ts CHANGED
@@ -1,16 +1,25 @@
1
1
  export const DEFAULT_TUI_AGENT_KEY = "agent-pub-01NOLOAPPBLD000000019KCKT0";
2
2
  export const DEFAULT_TUI_SERVER_URL = "http://127.0.0.1:38123";
3
3
 
4
- const KNOWN_AGENT_ALIASES: Record<string, { name: string; key: string }> = {
5
- nolo: {
4
+ const KNOWN_AGENTS: Array<{
5
+ name: string;
6
+ key: string;
7
+ description: string;
8
+ }> = [
9
+ {
6
10
  name: "nolo",
7
11
  key: "agent-pub-01NOLOAPPBLD000000019KCKT0",
12
+ description: "one assistant that routes work across your agents and data",
8
13
  },
9
- "app-builder": {
14
+ {
10
15
  name: "app-builder",
11
16
  key: "agent-pub-01APPBUILDER00000001YAII3I",
17
+ description: "builds web apps, tools, charts, and product prototypes",
12
18
  },
13
- };
19
+ ];
20
+
21
+ const KNOWN_AGENT_ALIASES: Record<string, { name: string; key: string }> =
22
+ Object.fromEntries(KNOWN_AGENTS.map((agent) => [agent.name, agent]));
14
23
 
15
24
  function shortenDialogId(dialogId: string) {
16
25
  return dialogId.length > 12
@@ -73,29 +82,26 @@ export function createInitialTuiState(env: EnvLike = process.env): TuiState {
73
82
  export function renderStatusLine(state: TuiState) {
74
83
  const docs =
75
84
  state.attachedDocs.length > 0
76
- ? state.attachedDocs.join(", ")
77
- : "0 attached";
85
+ ? String(state.attachedDocs.length)
86
+ : "0";
78
87
 
79
88
  return [
80
89
  `agent ${state.agentName}`,
81
90
  `dialog ${resolveDialogLabel(state)}`,
82
91
  `docs ${docs}`,
83
92
  `profile ${state.profileName}`,
84
- ...(state.cliVersion ? [`version ${state.cliVersion}`] : []),
85
93
  ].join(" | ");
86
94
  }
87
95
 
88
96
  export function renderWelcome(state: TuiState) {
97
+ const docs = state.attachedDocs.length > 0
98
+ ? `${state.attachedDocs.length} attached`
99
+ : "none";
89
100
  return [
90
101
  "",
91
- "Nolo workspace",
92
- "--------------",
93
- `agent ${state.agentName}`,
94
- `dialog ${resolveDialogLabel(state)}`,
95
- `docs ${state.attachedDocs.length ? state.attachedDocs.join(", ") : "none"}`,
96
- `profile ${state.profileName}`,
97
- `server ${state.serverUrl}`,
98
- ...(state.cliVersion ? [`version ${state.cliVersion}`] : []),
102
+ `Nolo workspace${state.cliVersion ? ` nolo ${state.cliVersion}` : ""}`,
103
+ `agent ${state.agentName} | dialog ${resolveDialogLabel(state)} | docs ${docs} | profile ${state.profileName}`,
104
+ `server ${state.serverUrl}`,
99
105
  "",
100
106
  "Tell nolo what you want. Use /help for commands. Use /version if this install feels stale.",
101
107
  "",
@@ -112,6 +118,7 @@ export function renderTuiHelp() {
112
118
  " /help Show this help",
113
119
  " /new Start a fresh dialog",
114
120
  " /agent Show the current agent",
121
+ " /agents List built-in agent shortcuts",
115
122
  " /switch <agent> Switch the current agent",
116
123
  " /dialog Show the current dialog",
117
124
  " /doc List attached docs",
@@ -126,11 +133,26 @@ export function renderTuiHelp() {
126
133
  ].join("\n");
127
134
  }
128
135
 
136
+ export function renderKnownAgents() {
137
+ return [
138
+ "Agents:",
139
+ ...KNOWN_AGENTS.map(
140
+ (agent, index) =>
141
+ ` ${index + 1} ${agent.name.padEnd(11)} ${agent.description}`
142
+ ),
143
+ "",
144
+ "Tip: stay on nolo for the one-assistant feel; switch only when you want a specialist directly.",
145
+ ].join("\n");
146
+ }
147
+
129
148
  function resolveSwitchTarget(rawTarget: string) {
130
149
  const target = rawTarget.trim();
150
+ if (/^\d+$/.test(target)) {
151
+ const agent = KNOWN_AGENTS[Number(target) - 1];
152
+ return agent ? { name: agent.name, key: agent.key } : null;
153
+ }
131
154
  const alias = KNOWN_AGENT_ALIASES[target.toLowerCase()];
132
155
  if (alias) return alias;
133
- if (/^\d+$/.test(target)) return null;
134
156
  if (target.startsWith("agent-") || target.startsWith("agent-pub-")) {
135
157
  return { name: target, key: target };
136
158
  }
@@ -180,6 +202,11 @@ export function handleTuiInput(input: string, state: TuiState): TuiInputResult {
180
202
  nextState: state,
181
203
  output: `Current agent: ${state.agentName} (${state.agentKey})`,
182
204
  };
205
+ case "/agents":
206
+ return {
207
+ nextState: state,
208
+ output: renderKnownAgents(),
209
+ };
183
210
  case "/switch": {
184
211
  if (!argText) {
185
212
  return {