nolo-cli 0.1.38 → 0.1.40

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 (65) hide show
  1. package/README.md +4 -4
  2. package/agent-runtime/agentRecordConfig.ts +0 -14
  3. package/agent-runtime/dialogWritePlan.ts +39 -0
  4. package/agent-runtime/hostAdapter.ts +4 -1
  5. package/agent-runtime/hybridRecordStore.ts +1 -1
  6. package/agent-runtime/index.ts +39 -18
  7. package/agent-runtime/localDialogRead.ts +23 -0
  8. package/agent-runtime/localLoop.ts +87 -7
  9. package/agent-runtime/localToolPolicy.ts +1 -17
  10. package/agent-runtime/localWorkspaceTools.ts +51 -110
  11. package/agent-runtime/noloWorkspaceTools.ts +371 -0
  12. package/agent-runtime/runtimeToolPolicy.ts +3 -14
  13. package/agent-runtime/runtimeToolSurface.ts +198 -0
  14. package/agent-runtime/types.ts +2 -1
  15. package/agentAliases.ts +8 -1
  16. package/agentRunCommand.ts +65 -95
  17. package/agentRuntimeLocal.ts +1 -7
  18. package/ai/agent/cliExecutor.ts +249 -34
  19. package/chat/messages/fetchMessages.ts +84 -0
  20. package/chat/messages/types.ts +185 -0
  21. package/cli/agentAliases.ts +8 -1
  22. package/cli/agentRunCommand.ts +65 -95
  23. package/cli/agentRuntimeLocal.ts +1 -7
  24. package/cli/cliEnvHelpers.ts +11 -7
  25. package/cli/client/agentRun.ts +94 -93
  26. package/cli/client/localRuntimeAdapter.ts +250 -69
  27. package/cli/commandRegistry.ts +2 -2
  28. package/cli/connectorRunArtifact.ts +0 -1
  29. package/cli/dialogCommands.ts +572 -0
  30. package/cli/dialogInternalCommandEntries.ts +4 -0
  31. package/cli/machineWsRunDispatch.ts +76 -39
  32. package/cli/offlineMarxistsAgentCommand.ts +6 -4
  33. package/cli/scriptCommandEntries.ts +0 -2
  34. package/cli/tui/readlineWorkspace.ts +69 -0
  35. package/cli/tui/session.ts +176 -1
  36. package/cliEnvHelpers.ts +11 -7
  37. package/client/agentConfigResolver.test.ts +4 -5
  38. package/client/agentRun.test.ts +307 -57
  39. package/client/agentRun.ts +94 -93
  40. package/client/localRuntimeAdapter.test.ts +332 -53
  41. package/client/localRuntimeAdapter.ts +250 -69
  42. package/client/localRuntimeDryRun.test.ts +23 -9
  43. package/client/localToolPolicy.test.ts +4 -4
  44. package/commandRegistry.ts +2 -2
  45. package/connectorRunArtifact.ts +0 -1
  46. package/database/server/db.ts +99 -0
  47. package/database/server/ensureDbOpen.ts +12 -0
  48. package/database/server/levelAuthorityStore.ts +20 -1
  49. package/database/server/memoryAuthorityStore.ts +133 -0
  50. package/database/server/serverStoreFactory.ts +118 -0
  51. package/dialogCommands.ts +572 -0
  52. package/dialogInternalCommandEntries.ts +4 -0
  53. package/machineWsRunDispatch.ts +76 -39
  54. package/offlineMarxistsAgentCommand.ts +6 -4
  55. package/package.json +11 -9
  56. package/scriptCommandEntries.ts +0 -2
  57. package/tui/readlineWorkspace.ts +69 -0
  58. package/tui/session.ts +176 -1
  59. package/agent-runtime/taskWorkspace.ts +0 -193
  60. package/agent-runtime/workspaceSession.ts +0 -76
  61. package/cli/client/taskWorktree.ts +0 -8
  62. package/cli/client/workspaceSession.ts +0 -11
  63. package/client/taskWorktree.ts +0 -8
  64. package/client/workspaceSession.test.ts +0 -57
  65. package/client/workspaceSession.ts +0 -11
@@ -0,0 +1,12 @@
1
+ export type DbWithOpenStatus = {
2
+ status?: string | null;
3
+ open(): Promise<unknown>;
4
+ };
5
+
6
+ export async function ensureDbOpen(db: DbWithOpenStatus) {
7
+ if (db.status === "open") {
8
+ return;
9
+ }
10
+
11
+ await db.open();
12
+ }
@@ -48,6 +48,25 @@ export function createLevelAuthorityStore(
48
48
  const levelDb: LevelLike = typeof source === "string"
49
49
  ? new Level<string, any>(source, { valueEncoding: safeJsonEncoding })
50
50
  : source;
51
+ const writeBatchOps = async (ops: AuthorityBatchOperation[]) => {
52
+ const result = levelDb.batch(ops);
53
+ if (result && typeof (result as any).then === "function") {
54
+ await result;
55
+ return;
56
+ }
57
+ if (result && typeof (result as any).write === "function") {
58
+ for (const op of ops) {
59
+ if (op.type === "put") {
60
+ (result as LevelBatchWriterLike).put(op.key, op.value);
61
+ } else {
62
+ (result as LevelBatchWriterLike).del(op.key);
63
+ }
64
+ }
65
+ await (result as LevelBatchWriterLike).write();
66
+ return;
67
+ }
68
+ throw new Error("Level backing does not support batch writes");
69
+ };
51
70
 
52
71
  return {
53
72
  get location() {
@@ -72,7 +91,7 @@ export function createLevelAuthorityStore(
72
91
  await levelDb.del(key);
73
92
  },
74
93
  async batchWrite(ops: AuthorityBatchOperation[]) {
75
- await levelDb.batch(ops);
94
+ await writeBatchOps(ops);
76
95
  },
77
96
  createBatch(): AuthorityBatchWriter {
78
97
  const batch = levelDb.batch();
@@ -0,0 +1,133 @@
1
+ import type {
2
+ AuthorityBatchOperation,
3
+ AuthorityBatchWriter,
4
+ AuthorityIteratorOptions,
5
+ AuthorityStore,
6
+ } from "./authorityStoreTypes";
7
+
8
+ type MemoryEntry = {
9
+ key: string;
10
+ value: unknown;
11
+ };
12
+
13
+ const createNotFoundError = () => {
14
+ const error = new Error("NotFound") as Error & { notFound: true };
15
+ error.notFound = true;
16
+ return error;
17
+ };
18
+
19
+ class MemoryAuthorityBacking {
20
+ readonly location: string;
21
+ status: "closed" | "open" = "closed";
22
+ private readonly data = new Map<string, unknown>();
23
+
24
+ constructor(location: string) {
25
+ this.location = location;
26
+ }
27
+
28
+ async open() {
29
+ this.status = "open";
30
+ }
31
+
32
+ async close() {
33
+ this.status = "closed";
34
+ }
35
+
36
+ async get<T = any>(key: string): Promise<T> {
37
+ if (!this.data.has(key)) {
38
+ throw createNotFoundError();
39
+ }
40
+ return this.data.get(key) as T;
41
+ }
42
+
43
+ async put(key: string, value: unknown) {
44
+ this.data.set(key, value);
45
+ }
46
+
47
+ async del(key: string) {
48
+ this.data.delete(key);
49
+ }
50
+
51
+ async batchWrite(ops: AuthorityBatchOperation[]) {
52
+ for (const op of ops) {
53
+ if (op.type === "put") {
54
+ this.data.set(op.key, op.value);
55
+ } else {
56
+ this.data.delete(op.key);
57
+ }
58
+ }
59
+ }
60
+
61
+ createBatch(): AuthorityBatchWriter {
62
+ const buffered: AuthorityBatchOperation[] = [];
63
+ return {
64
+ put(key: string, value: unknown) {
65
+ buffered.push({ type: "put", key, value });
66
+ },
67
+ del(key: string) {
68
+ buffered.push({ type: "del", key });
69
+ },
70
+ write: async () => {
71
+ await this.batchWrite(buffered);
72
+ },
73
+ };
74
+ }
75
+
76
+ async *iterator(
77
+ options: AuthorityIteratorOptions = {}
78
+ ): AsyncIterableIterator<[string, unknown]> {
79
+ const entries: MemoryEntry[] = Array.from(this.data.entries())
80
+ .sort(([left], [right]) => left.localeCompare(right))
81
+ .map(([key, value]) => ({ key, value }));
82
+
83
+ if (options.reverse) {
84
+ entries.reverse();
85
+ }
86
+
87
+ for (const entry of entries) {
88
+ if (options.gte && entry.key < options.gte) continue;
89
+ if (options.lte && entry.key > options.lte) continue;
90
+ if (options.lt && entry.key >= options.lt) continue;
91
+ yield [entry.key, entry.value];
92
+ }
93
+ }
94
+ }
95
+
96
+ export function createMemoryAuthorityStore(
97
+ location = ":memory:"
98
+ ): AuthorityStore {
99
+ const backing = new MemoryAuthorityBacking(location);
100
+
101
+ return {
102
+ get location() {
103
+ return backing.location;
104
+ },
105
+ get status() {
106
+ return backing.status;
107
+ },
108
+ async open() {
109
+ await backing.open();
110
+ },
111
+ async close() {
112
+ await backing.close();
113
+ },
114
+ async get<T = any>(key: string) {
115
+ return backing.get<T>(key);
116
+ },
117
+ async put(key: string, value: unknown) {
118
+ await backing.put(key, value);
119
+ },
120
+ async del(key: string) {
121
+ await backing.del(key);
122
+ },
123
+ async batchWrite(ops: AuthorityBatchOperation[]) {
124
+ await backing.batchWrite(ops);
125
+ },
126
+ createBatch() {
127
+ return backing.createBatch();
128
+ },
129
+ iterator(options: AuthorityIteratorOptions = {}) {
130
+ return backing.iterator(options);
131
+ },
132
+ };
133
+ }
@@ -0,0 +1,118 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { Level } from "level";
4
+
5
+ import type { AuthorityStore } from "./authorityStoreTypes";
6
+ import { createLegacyServerDb, type LegacyServerDb } from "./legacyServerDb";
7
+ import { createLevelAuthorityStore } from "./levelAuthorityStore";
8
+ import { createMemoryAuthorityStore } from "./memoryAuthorityStore";
9
+
10
+ export type ServerStoreDriver = "level" | "memory";
11
+
12
+ export type ServerStoreFactoryEnv = {
13
+ NOLO_SERVER_AUTHORITY_DRIVER?: string | undefined;
14
+ };
15
+
16
+ export const safeJsonEncoding = {
17
+ name: "safe-json",
18
+ format: "utf8" as const,
19
+ encode: (data: any) => JSON.stringify(data),
20
+ decode: (data: string) => {
21
+ try {
22
+ return JSON.parse(data);
23
+ } catch {
24
+ console.warn("[LevelDB] Corrupted value:", data?.substring?.(0, 60));
25
+ return null;
26
+ }
27
+ },
28
+ };
29
+
30
+ export type ServerStoreRuntime = {
31
+ authorityStore: AuthorityStore;
32
+ serverDb: LegacyServerDb;
33
+ };
34
+
35
+ export type ServerStoreFactoryOptions = {
36
+ driver?: ServerStoreDriver;
37
+ env?: ServerStoreFactoryEnv;
38
+ globalScope?: Record<string, unknown>;
39
+ };
40
+
41
+ export function ensureServerDbDirectory(dbPath: string) {
42
+ const dir = path.dirname(dbPath);
43
+ if (!fs.existsSync(dir)) {
44
+ fs.mkdirSync(dir, { recursive: true });
45
+ }
46
+ }
47
+
48
+ export function createLevelBackedAuthorityStore(dbPath: string): AuthorityStore {
49
+ const levelDb = new Level<string, any>(dbPath, {
50
+ valueEncoding: safeJsonEncoding,
51
+ });
52
+ return createLevelAuthorityStore(levelDb);
53
+ }
54
+
55
+ export function resolveServerStoreDriver(
56
+ env: ServerStoreFactoryEnv = process.env
57
+ ): ServerStoreDriver {
58
+ const rawDriver = env.NOLO_SERVER_AUTHORITY_DRIVER?.trim().toLowerCase();
59
+ if (!rawDriver) return "level";
60
+ if (rawDriver === "level") return "level";
61
+ if (rawDriver === "memory") return "memory";
62
+ throw new Error(`Unsupported server authority store driver: ${rawDriver}`);
63
+ }
64
+
65
+ export function createAuthorityStoreForDriver(
66
+ driver: ServerStoreDriver,
67
+ dbPath: string
68
+ ): AuthorityStore {
69
+ switch (driver) {
70
+ case "level":
71
+ return createLevelBackedAuthorityStore(dbPath);
72
+ case "memory":
73
+ return createMemoryAuthorityStore(dbPath);
74
+ }
75
+ }
76
+
77
+ export function getOrCreateServerStoreRuntime(
78
+ dbPath: string,
79
+ options: ServerStoreFactoryOptions = {}
80
+ ): ServerStoreRuntime {
81
+ const globalScope =
82
+ options.globalScope ?? (globalThis as Record<string, unknown>);
83
+ const driver = options.driver ?? resolveServerStoreDriver(options.env);
84
+ const cachedDriver = globalScope.__serverAuthorityStoreDriver;
85
+
86
+ ensureServerDbDirectory(dbPath);
87
+
88
+ if (
89
+ globalScope.__serverAuthorityStore &&
90
+ typeof cachedDriver === "string" &&
91
+ cachedDriver !== driver
92
+ ) {
93
+ throw new Error(
94
+ `Server authority store already initialized with driver ${cachedDriver}, cannot reuse it for ${driver}`
95
+ );
96
+ }
97
+
98
+ if (!globalScope.__serverAuthorityStore) {
99
+ globalScope.__serverAuthorityStore = createAuthorityStoreForDriver(
100
+ driver,
101
+ dbPath
102
+ );
103
+ globalScope.__serverAuthorityStoreDriver = driver;
104
+ } else if (!cachedDriver) {
105
+ globalScope.__serverAuthorityStoreDriver = driver;
106
+ }
107
+
108
+ const authorityStore = globalScope.__serverAuthorityStore as AuthorityStore;
109
+
110
+ if (!globalScope.__serverDb) {
111
+ globalScope.__serverDb = createLegacyServerDb(authorityStore);
112
+ }
113
+
114
+ return {
115
+ authorityStore,
116
+ serverDb: globalScope.__serverDb as LegacyServerDb,
117
+ };
118
+ }