nolo-cli 0.1.5 → 0.1.7

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,9 @@ 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
96
+ /context
88
97
  /dialog open latest
89
98
  /doc list
90
99
  /table query builtin-dialog-probe-runs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nolo-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
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
@@ -108,7 +117,9 @@ export function renderTuiHelp() {
108
117
  "Commands:",
109
118
  " /help Show this help",
110
119
  " /new Start a fresh dialog",
120
+ " /context Show workspace context and next actions",
111
121
  " /agent Show the current agent",
122
+ " /agents List built-in agent shortcuts",
112
123
  " /switch <agent> Switch the current agent",
113
124
  " /dialog Show the current dialog",
114
125
  " /doc List attached docs",
@@ -123,11 +134,46 @@ export function renderTuiHelp() {
123
134
  ].join("\n");
124
135
  }
125
136
 
137
+ export function renderContextPanel(state: TuiState) {
138
+ const docs = state.attachedDocs.length
139
+ ? state.attachedDocs.join(", ")
140
+ : "none";
141
+ return [
142
+ "Workspace context",
143
+ "-----------------",
144
+ `agent ${state.agentName}`,
145
+ `dialog ${resolveDialogLabel(state)}`,
146
+ `docs ${docs}`,
147
+ `profile ${state.profileName}`,
148
+ `server ${state.serverUrl}`,
149
+ "",
150
+ "Next:",
151
+ " /agents see specialist shortcuts",
152
+ " /doc attach <doc> add working context",
153
+ " /new start a clean dialog",
154
+ ].join("\n");
155
+ }
156
+
157
+ export function renderKnownAgents() {
158
+ return [
159
+ "Agents:",
160
+ ...KNOWN_AGENTS.map(
161
+ (agent, index) =>
162
+ ` ${index + 1} ${agent.name.padEnd(11)} ${agent.description}`
163
+ ),
164
+ "",
165
+ "Tip: stay on nolo for the one-assistant feel; switch only when you want a specialist directly.",
166
+ ].join("\n");
167
+ }
168
+
126
169
  function resolveSwitchTarget(rawTarget: string) {
127
170
  const target = rawTarget.trim();
171
+ if (/^\d+$/.test(target)) {
172
+ const agent = KNOWN_AGENTS[Number(target) - 1];
173
+ return agent ? { name: agent.name, key: agent.key } : null;
174
+ }
128
175
  const alias = KNOWN_AGENT_ALIASES[target.toLowerCase()];
129
176
  if (alias) return alias;
130
- if (/^\d+$/.test(target)) return null;
131
177
  if (target.startsWith("agent-") || target.startsWith("agent-pub-")) {
132
178
  return { name: target, key: target };
133
179
  }
@@ -159,6 +205,9 @@ export function handleTuiInput(input: string, state: TuiState): TuiInputResult {
159
205
  switch (command) {
160
206
  case "/help":
161
207
  return { nextState: state, output: renderTuiHelp() };
208
+ case "/context":
209
+ case "/ctx":
210
+ return { nextState: state, output: renderContextPanel(state) };
162
211
  case "/exit":
163
212
  case "/quit":
164
213
  return { nextState: state, output: "Bye.", action: { type: "exit" } };
@@ -177,6 +226,11 @@ export function handleTuiInput(input: string, state: TuiState): TuiInputResult {
177
226
  nextState: state,
178
227
  output: `Current agent: ${state.agentName} (${state.agentKey})`,
179
228
  };
229
+ case "/agents":
230
+ return {
231
+ nextState: state,
232
+ output: renderKnownAgents(),
233
+ };
180
234
  case "/switch": {
181
235
  if (!argText) {
182
236
  return {