nolo-cli 0.1.37 → 0.1.39

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.
Files changed (52) hide show
  1. package/agent-runtime/agentRecordConfig.ts +0 -14
  2. package/agent-runtime/hostAdapter.ts +0 -1
  3. package/agent-runtime/index.ts +24 -18
  4. package/agent-runtime/localDialogRead.ts +23 -0
  5. package/agent-runtime/localToolPolicy.ts +2 -7
  6. package/agent-runtime/localWorkspaceTools.ts +9 -0
  7. package/agent-runtime/noloWorkspaceTools.ts +371 -0
  8. package/agent-runtime/runtimeToolPolicy.ts +1 -3
  9. package/agent-runtime/types.ts +1 -1
  10. package/agentAliases.ts +6 -0
  11. package/agentRunCommand.ts +57 -65
  12. package/agentRuntimeLocal.ts +0 -7
  13. package/chat/messages/fetchMessages.ts +84 -0
  14. package/chat/messages/types.ts +185 -0
  15. package/cli/agentAliases.ts +6 -0
  16. package/cli/agentRunCommand.ts +57 -65
  17. package/cli/agentRuntimeLocal.ts +0 -7
  18. package/cli/cliEnvHelpers.ts +11 -7
  19. package/cli/client/agentRun.ts +123 -24
  20. package/cli/client/localRuntimeAdapter.ts +87 -59
  21. package/cli/connectorRunArtifact.ts +0 -1
  22. package/cli/dialogCommands.ts +572 -0
  23. package/cli/dialogInternalCommandEntries.ts +4 -0
  24. package/cli/machineWsRunDispatch.ts +29 -37
  25. package/cli/scriptCommandEntries.ts +0 -2
  26. package/cli/tui/readlineWorkspace.ts +69 -0
  27. package/cli/tui/session.ts +176 -1
  28. package/cliEnvHelpers.ts +11 -7
  29. package/client/agentConfigResolver.test.ts +2 -3
  30. package/client/agentRun.test.ts +185 -1
  31. package/client/agentRun.ts +123 -24
  32. package/client/localRuntimeAdapter.test.ts +90 -25
  33. package/client/localRuntimeAdapter.ts +87 -59
  34. package/connectorRunArtifact.ts +0 -1
  35. package/database/server/db.ts +99 -0
  36. package/database/server/ensureDbOpen.ts +12 -0
  37. package/database/server/memoryAuthorityStore.ts +133 -0
  38. package/database/server/serverStoreFactory.ts +118 -0
  39. package/dialogCommands.ts +572 -0
  40. package/dialogInternalCommandEntries.ts +4 -0
  41. package/machineWsRunDispatch.ts +29 -37
  42. package/package.json +10 -9
  43. package/scriptCommandEntries.ts +0 -2
  44. package/tui/readlineWorkspace.ts +69 -0
  45. package/tui/session.ts +176 -1
  46. package/agent-runtime/taskWorkspace.ts +0 -193
  47. package/agent-runtime/workspaceSession.ts +0 -76
  48. package/cli/client/taskWorktree.ts +0 -8
  49. package/cli/client/workspaceSession.ts +0 -11
  50. package/client/taskWorktree.ts +0 -8
  51. package/client/workspaceSession.test.ts +0 -57
  52. package/client/workspaceSession.ts +0 -11
@@ -5,6 +5,8 @@ import type {
5
5
  } from "../agentRuntimeLocal";
6
6
  import { request as httpRequest } from "node:http";
7
7
  import { request as httpsRequest } from "node:https";
8
+ import { dirname, join } from "node:path";
9
+ import { fileURLToPath } from "node:url";
8
10
  import {
9
11
  buildLocalWorkspacePolicyToolNames,
10
12
  buildLocalWorkspaceToolset,
@@ -40,19 +42,28 @@ import {
40
42
  } from "./hybridRecordStore";
41
43
  import { executeLocalToolWithPolicy } from "./localToolPolicy";
42
44
  import { taskRunFunctionSchema } from "../../ai/tools/agent/taskRunTool";
43
- import { prepareTaskWorktree } from "./taskWorktree";
44
45
  import {
45
- activateWorkspaceSession,
46
- createWorkspaceSession,
47
- formatWorkspaceSessionActivation,
48
- type WorkspaceSession,
49
- } from "./workspaceSession";
46
+ NOLO_DEFAULT_AGENT_ID,
47
+ NOLO_DEFAULT_AGENT_KEY,
48
+ } from "../agentAliases";
49
+ import {
50
+ buildNoloWorkspaceCliToolExecutors,
51
+ buildNoloWorkspaceOpenAiTools,
52
+ filterNoloWorkspaceToolNames,
53
+ NOLO_WORKSPACE_TOOL_NAMES,
54
+ NOLO_WORKSPACE_TOOL_PROMPT,
55
+ parseNoloWorkspaceToolArguments,
56
+ } from "../../agent-runtime/noloWorkspaceTools";
50
57
 
51
58
  type EnvLike = Record<string, string | undefined>;
52
59
  type FetchInput = Parameters<typeof fetch>[0];
53
60
  type FetchInit = Parameters<typeof fetch>[1];
54
61
  const TRANSIENT_FETCH_MAX_ATTEMPTS = 8;
55
62
  const TRANSIENT_FETCH_RETRY_BASE_DELAY_MS = 250;
63
+ export const BUILTIN_NOLO_AGENT_ID = NOLO_DEFAULT_AGENT_ID;
64
+ export const BUILTIN_NOLO_AGENT_KEY = NOLO_DEFAULT_AGENT_KEY;
65
+ const CLI_DIR = dirname(fileURLToPath(import.meta.url));
66
+ const CLI_ENTRYPOINT = join(CLI_DIR, "..", "index.ts");
56
67
 
57
68
  export type CliLocalRuntimeDb = CliKvDb;
58
69
 
@@ -64,9 +75,7 @@ export type CliLocalRuntimeAdapterDeps = {
64
75
  createId?: () => string;
65
76
  fetchImpl?: typeof fetch;
66
77
  cwd?: string;
67
- useCwdAsTaskWorkspaceBase?: boolean;
68
78
  output?: { write(chunk: string): unknown };
69
- prepareTaskWorktree?: typeof prepareTaskWorktree;
70
79
  localToolExecutors?: Record<string, (call: any) => Promise<{ content: string; metadata?: Record<string, unknown> }>>;
71
80
  sleep?: (ms: number) => Promise<void>;
72
81
  loopbackRequest?: (input: FetchInput, init?: FetchInit) => Promise<Response>;
@@ -85,7 +94,7 @@ function resolveLocalUserId(env: EnvLike) {
85
94
  }
86
95
 
87
96
  function shellModeEnabled(env: EnvLike) {
88
- return ["worktree", "dangerous", "1", "true"].includes(env.NOLO_LOCAL_SHELL_MODE || "");
97
+ return env.NOLO_LOCAL_SHELL_MODE === "worktree";
89
98
  }
90
99
 
91
100
  function parseLocalToolBudgets(env: EnvLike) {
@@ -246,6 +255,17 @@ function logLocalRuntimeDiagnostic(event: string, fields: Record<string, unknown
246
255
  console.error(`[nolo-local-runtime] ${event} ${JSON.stringify(fields)}`);
247
256
  }
248
257
 
258
+ function summarizeOpenAiToolNames(tools: Array<Record<string, unknown>>) {
259
+ return tools
260
+ .map((tool) => {
261
+ const fn = tool.function;
262
+ return fn && typeof fn === "object" && "name" in fn && typeof fn.name === "string"
263
+ ? fn.name
264
+ : null;
265
+ })
266
+ .filter((name): name is string => Boolean(name));
267
+ }
268
+
249
269
  function buildOpenAiTools(args: { toolNames?: string[]; env: EnvLike }) {
250
270
  const toolset = buildLocalWorkspaceToolsetForEnv(args);
251
271
  return [
@@ -254,6 +274,7 @@ function buildOpenAiTools(args: { toolNames?: string[]; env: EnvLike }) {
254
274
  exposeShellTools: toolset.exposeShellTools,
255
275
  }),
256
276
  ...buildServerPlatformOpenAiTools({ toolNames: args.toolNames }),
277
+ ...buildNoloWorkspaceOpenAiTools({ toolNames: args.toolNames }),
257
278
  ];
258
279
  }
259
280
 
@@ -272,6 +293,7 @@ function buildLocalPolicyToolNames(args: { toolNames?: string[]; env: EnvLike })
272
293
  exposeShellTools: shellModeEnabled(args.env),
273
294
  }),
274
295
  ...((args.toolNames ?? []).includes("taskRun") ? ["taskRun"] : []),
296
+ ...filterNoloWorkspaceToolNames(args.toolNames),
275
297
  ];
276
298
  }
277
299
 
@@ -287,13 +309,44 @@ function buildServerPlatformOpenAiTools(args: { toolNames?: string[] }) {
287
309
  ];
288
310
  }
289
311
 
290
- function parseToolArguments(raw: string) {
291
- try {
292
- const parsed = JSON.parse(raw || "{}");
293
- return parsed && typeof parsed === "object" ? parsed : {};
294
- } catch {
295
- return {};
296
- }
312
+ function buildCliWorkspaceToolExecutors(args: {
313
+ env: EnvLike;
314
+ cliEntrypoint?: string;
315
+ }) {
316
+ return buildNoloWorkspaceCliToolExecutors({
317
+ cliEntrypoint: args.cliEntrypoint ?? CLI_ENTRYPOINT,
318
+ env: args.env,
319
+ metadataKind: "cliWorkspaceTool",
320
+ });
321
+ }
322
+
323
+ export function isBuiltinNoloAgentRef(ref: unknown) {
324
+ if (typeof ref !== "string") return false;
325
+ const normalized = ref.trim();
326
+ return (
327
+ normalized === BUILTIN_NOLO_AGENT_KEY ||
328
+ normalized === BUILTIN_NOLO_AGENT_ID ||
329
+ normalized.endsWith(`-${BUILTIN_NOLO_AGENT_ID}`)
330
+ );
331
+ }
332
+
333
+ function isBuiltinNoloAgentConfig(agentConfig: AgentRuntimeAgentConfig | null | undefined) {
334
+ const key = agentConfig?.key || agentConfig?.rawRecord?.dbKey || agentConfig?.rawRecord?.agentKey;
335
+ const id = agentConfig?.rawRecord?.id;
336
+ return isBuiltinNoloAgentRef(key) || isBuiltinNoloAgentRef(id);
337
+ }
338
+
339
+ function withBuiltinNoloCliTools(agentConfig: AgentRuntimeAgentConfig | null) {
340
+ if (!agentConfig || !isBuiltinNoloAgentConfig(agentConfig)) return agentConfig;
341
+ const toolNames = [...new Set([...(agentConfig.toolNames ?? []), ...NOLO_WORKSPACE_TOOL_NAMES])];
342
+ return {
343
+ ...agentConfig,
344
+ toolNames,
345
+ prompt: [
346
+ agentConfig.prompt?.trim() ?? "",
347
+ NOLO_WORKSPACE_TOOL_PROMPT,
348
+ ].filter(Boolean).join("\n\n"),
349
+ };
297
350
  }
298
351
 
299
352
  function resolveRuntimeServerUrl(env: EnvLike) {
@@ -320,7 +373,7 @@ function buildServerPlatformToolExecutors(args: {
320
373
  "Content-Type": "application/json",
321
374
  Authorization: `Bearer ${authToken}`,
322
375
  },
323
- body: JSON.stringify(parseToolArguments(call.arguments)),
376
+ body: JSON.stringify(parseNoloWorkspaceToolArguments(call.arguments)),
324
377
  });
325
378
  const text = await response.text().catch(() => "");
326
379
  if (!response.ok) {
@@ -352,17 +405,13 @@ function buildLocalToolExecutors(args: {
352
405
  env: args.env,
353
406
  fetchImpl: args.fetchImpl,
354
407
  }),
408
+ ...buildCliWorkspaceToolExecutors({
409
+ env: args.env,
410
+ }),
355
411
  ...(args.localToolExecutors ?? {}),
356
412
  };
357
413
  }
358
414
 
359
- function readLocalWorkspaceMode(agentConfig: AgentRuntimeAgentConfig | null) {
360
- if (agentConfig?.localWorkspaceMode === "task-worktree") return "task-worktree";
361
- const runtimeBinding = agentConfig?.runtimeBinding;
362
- const value = runtimeBinding?.localWorkspaceMode ?? runtimeBinding?.workspaceMode;
363
- return value === "task-worktree" ? "task-worktree" : "current";
364
- }
365
-
366
415
  async function resolveStore(deps: CliLocalRuntimeAdapterDeps) {
367
416
  if (deps.store) return deps.store;
368
417
  return createCliHybridRecordStore({
@@ -437,51 +486,25 @@ export function createCliLocalRuntimeAdapter(
437
486
  const localToolBudgets = parseLocalToolBudgets(deps.env);
438
487
  const localToolUsage = new Map<string, number>();
439
488
  let activeAgentToolNames: string[] = [];
440
- let workspaceSession: WorkspaceSession = createWorkspaceSession(
441
- deps.useCwdAsTaskWorkspaceBase
442
- ? { defaultCwd: deps.cwd }
443
- : { cwd: deps.cwd }
444
- );
489
+ const workspaceRoot = deps.cwd ?? process.cwd();
445
490
  let runtimeToolExecutionLimits: ReturnType<typeof resolveLocalWorkspaceExecutorOptionsFromPolicy> = {};
446
491
  let localToolExecutors = buildLocalToolExecutors({
447
- workspaceRoot: workspaceSession.workspaceRoot,
492
+ workspaceRoot,
448
493
  env: deps.env,
449
494
  fetchImpl,
450
495
  localToolExecutors: deps.localToolExecutors,
451
496
  ...runtimeToolExecutionLimits,
452
497
  });
453
498
 
454
- async function activateAgentWorkspaceSession(args: {
455
- agentRef: string;
456
- agentConfig: AgentRuntimeAgentConfig | null;
457
- }) {
458
- const previousWorkspaceRoot = workspaceSession.workspaceRoot;
459
- workspaceSession = await activateWorkspaceSession(workspaceSession, {
460
- agentKey: args.agentConfig?.key ?? args.agentRef,
461
- mode: readLocalWorkspaceMode(args.agentConfig),
462
- env: deps.env,
463
- prepareTaskWorkspace: deps.prepareTaskWorktree,
464
- });
465
- if (workspaceSession.workspaceRoot === previousWorkspaceRoot) return;
466
- localToolExecutors = buildLocalToolExecutors({
467
- workspaceRoot: workspaceSession.workspaceRoot,
468
- env: deps.env,
469
- fetchImpl,
470
- localToolExecutors: deps.localToolExecutors,
471
- ...runtimeToolExecutionLimits,
472
- });
473
- deps.output?.write(formatWorkspaceSessionActivation(workspaceSession));
474
- }
475
-
476
499
  return {
477
500
  host: "cli",
478
501
  capabilities: ["leveldb-agent-config", "local-provider", "leveldb-persistence", "local-tools"],
479
502
  loadAgentConfig: async (agentRef) => {
480
- const agentConfig = await readAgentFromStore({
503
+ const agentConfig = withBuiltinNoloCliTools(await readAgentFromStore({
481
504
  agentRef,
482
505
  store: await resolveStore(deps),
483
506
  userId,
484
- });
507
+ }));
485
508
  const requestedToolNames = agentConfig
486
509
  ? resolveRequestedRuntimeToolNames({ agentConfig })
487
510
  : [];
@@ -492,9 +515,8 @@ export function createCliLocalRuntimeAdapter(
492
515
  runtimeToolExecutionLimits = resolveLocalWorkspaceExecutorOptionsFromPolicy(
493
516
  resolveCurrentRunRuntimeToolPolicy(agentConfig),
494
517
  );
495
- await activateAgentWorkspaceSession({ agentRef, agentConfig });
496
518
  localToolExecutors = buildLocalToolExecutors({
497
- workspaceRoot: workspaceSession.workspaceRoot,
519
+ workspaceRoot,
498
520
  env: deps.env,
499
521
  fetchImpl,
500
522
  localToolExecutors: deps.localToolExecutors,
@@ -512,7 +534,7 @@ export function createCliLocalRuntimeAdapter(
512
534
  userId,
513
535
  now,
514
536
  createId,
515
- cwd: workspaceSession.workspaceRoot,
537
+ cwd: workspaceRoot,
516
538
  }),
517
539
  resolveProvider: async (agentConfig) => {
518
540
  if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
@@ -558,6 +580,9 @@ export function createCliLocalRuntimeAdapter(
558
580
  model: providerConfig.model,
559
581
  messageCount: messages.length,
560
582
  toolCount: tools.length,
583
+ requestedToolNames,
584
+ openAiToolNames: summarizeOpenAiToolNames(tools),
585
+ shellMode: deps.env.NOLO_LOCAL_SHELL_MODE ?? null,
561
586
  timeoutMs: options?.timeoutMs ?? null,
562
587
  });
563
588
  const res = await fetchWithTransientRetry(fetchImpl, request.url, {
@@ -627,6 +652,9 @@ export function createCliLocalRuntimeAdapter(
627
652
  model: providerConfig.model,
628
653
  messageCount: messages.length,
629
654
  toolCount: tools.length,
655
+ requestedToolNames,
656
+ openAiToolNames: summarizeOpenAiToolNames(tools),
657
+ shellMode: deps.env.NOLO_LOCAL_SHELL_MODE ?? null,
630
658
  timeoutMs: options?.timeoutMs ?? null,
631
659
  });
632
660
  const res = await fetchWithTransientRetry(fetchImpl, request.url, {
@@ -672,8 +700,8 @@ export function createCliLocalRuntimeAdapter(
672
700
  ...result,
673
701
  metadata: {
674
702
  ...(result.metadata ?? {}),
675
- workspaceRoot: workspaceSession.workspaceRoot,
676
- workspaceKind: workspaceSession.kind,
703
+ workspaceRoot,
704
+ workspaceKind: "current",
677
705
  },
678
706
  };
679
707
  },
@@ -32,7 +32,6 @@ export function resolveConnectorRunCwd(args: {
32
32
  const explicit =
33
33
  args.env?.NOLO_CONNECTOR_WORKDIR ||
34
34
  args.env?.NOLO_AGENT_WORKDIR ||
35
- args.env?.NOLO_LOCAL_WORKTREE ||
36
35
  "";
37
36
  const candidate = explicit || args.policy.writableRoots[0] || args.fallbackCwd || process.cwd();
38
37
  const cwd = normalizePath(candidate);