nolo-cli 0.1.32 → 0.1.34

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 (234) hide show
  1. package/README.md +4 -10
  2. package/agent-runtime/agentRecordConfig.ts +10 -0
  3. package/agent-runtime/hostAdapter.ts +10 -1
  4. package/agent-runtime/index.ts +9 -20
  5. package/agent-runtime/localLoop.ts +49 -2
  6. package/agent-runtime/localToolPolicy.ts +76 -34
  7. package/agent-runtime/localWorkspaceTools.ts +30 -333
  8. package/agent-runtime/openAiCompatibleProvider.ts +7 -3
  9. package/agent-runtime/openAiCompatibleProviderConfig.ts +15 -26
  10. package/agent-runtime/platformChatProvider.ts +47 -73
  11. package/agent-runtime/providerResolution.ts +244 -0
  12. package/agent-runtime/runtimeToolPolicy.ts +77 -29
  13. package/agent-runtime/shellCommandPolicy.ts +120 -0
  14. package/agentAliases.ts +14 -83
  15. package/agentCommandSupport.ts +3 -6
  16. package/agentInternalCommandEntries.ts +4 -13
  17. package/agentListCommands.ts +18 -27
  18. package/agentMachineCommands.ts +40 -336
  19. package/agentPullCommand.ts +30 -55
  20. package/agentRecordCommands.ts +84 -1
  21. package/agentRecordHelpers.ts +102 -186
  22. package/agentRunCommand.ts +438 -107
  23. package/agentRuntimeLocal.ts +2 -9
  24. package/ai/agent/cliExecutor.ts +19 -323
  25. package/ai/tools/toolNameAliases.ts +70 -0
  26. package/authCommands.ts +2 -36
  27. package/cli/agentAliases.ts +14 -83
  28. package/cli/agentCommandSupport.ts +3 -6
  29. package/cli/agentInternalCommandEntries.ts +4 -13
  30. package/cli/agentListCommands.ts +18 -27
  31. package/cli/agentMachineCommands.ts +40 -336
  32. package/cli/agentPullCommand.ts +30 -55
  33. package/cli/agentRecordCommands.ts +84 -1
  34. package/cli/agentRecordHelpers.ts +102 -186
  35. package/cli/agentRunCommand.ts +438 -107
  36. package/cli/agentRuntimeLocal.ts +2 -9
  37. package/cli/authCommands.ts +2 -36
  38. package/cli/cliCommandDispatch.ts +2 -2
  39. package/cli/cliEnvHelpers.ts +34 -107
  40. package/cli/client/agentRun.ts +854 -57
  41. package/cli/client/localRuntimeAdapter.ts +59 -159
  42. package/cli/client/streamingOutput.ts +3 -1
  43. package/cli/client/taskRunPrompt.ts +24 -7
  44. package/cli/commandRegistry.ts +4 -5
  45. package/cli/connectorRunArtifact.ts +10 -34
  46. package/cli/connectorWebSocketTarget.ts +6 -10
  47. package/cli/internalCommandEntries.ts +0 -8
  48. package/cli/localRuntimeDb.ts +2 -39
  49. package/cli/machineCommands.ts +189 -190
  50. package/cli/machineDaemonCommands.ts +165 -9
  51. package/cli/machineHeartbeatCommands.ts +2 -1
  52. package/cli/machineStatusCommands.ts +13 -5
  53. package/cli/machineWatchCommands.ts +1 -1
  54. package/cli/machineWsRunDispatch.ts +30 -44
  55. package/cli/machineWsSession.ts +0 -2
  56. package/cli/offlineMarxistsAgentCommand.ts +314 -0
  57. package/cli/runtimeDoctorCommands.ts +72 -15
  58. package/cli/scriptCommandEntries.ts +45 -5
  59. package/cli/tableCommands.ts +133 -33
  60. package/cli/taskRunCommand.ts +211 -16
  61. package/cli/tui/session.ts +372 -43
  62. package/cli/workflowInternalCommandEntries.ts +0 -20
  63. package/cliCommandDispatch.ts +2 -2
  64. package/cliEnvHelpers.ts +34 -107
  65. package/client/agentConfigResolver.test.ts +2 -0
  66. package/client/agentRun.test.ts +12 -208
  67. package/client/agentRun.ts +854 -57
  68. package/client/localProviderResolver.test.ts +26 -2
  69. package/client/localRuntimeAdapter.test.ts +296 -171
  70. package/client/localRuntimeAdapter.ts +59 -159
  71. package/client/localToolPolicy.test.ts +4 -28
  72. package/client/streamingOutput.ts +3 -1
  73. package/client/taskRunPrompt.ts +24 -7
  74. package/commandRegistry.ts +4 -5
  75. package/connectorRunArtifact.ts +10 -34
  76. package/connectorWebSocketTarget.ts +6 -10
  77. package/database/server/serverStoreFactory.ts +2 -8
  78. package/internalCommandEntries.ts +0 -8
  79. package/localRuntimeDb.ts +2 -39
  80. package/machineCommands.ts +189 -190
  81. package/machineDaemonCommands.ts +165 -9
  82. package/machineHeartbeatCommands.ts +2 -1
  83. package/machineStatusCommands.ts +13 -5
  84. package/machineWatchCommands.ts +1 -1
  85. package/machineWsRunDispatch.ts +30 -44
  86. package/machineWsSession.ts +0 -2
  87. package/offlineMarxistsAgentCommand.ts +314 -0
  88. package/package.json +52 -188
  89. package/runtimeDoctorCommands.ts +72 -15
  90. package/scriptCommandEntries.ts +45 -5
  91. package/tableCommands.ts +133 -33
  92. package/taskRunCommand.ts +211 -16
  93. package/tui/session.ts +372 -43
  94. package/workflowInternalCommandEntries.ts +0 -20
  95. package/agent-runtime/dialogStatus.ts +0 -139
  96. package/agent-runtime/hostRuntimeConfig.ts +0 -86
  97. package/agentCreateCustomCommands.ts +0 -278
  98. package/agentDialogsCommands.ts +0 -227
  99. package/agentDoctorCommands.ts +0 -203
  100. package/agentRunLocalWorkspace.ts +0 -182
  101. package/agentRunParsing.ts +0 -298
  102. package/agentSuperviseCommands.ts +0 -8
  103. package/agentUnpublishCommands.ts +0 -113
  104. package/ai/agent/agentRunDialogLineage.ts +0 -56
  105. package/ai/policy/types.ts +0 -64
  106. package/ai/skills/skillSummaryMarker.ts +0 -26
  107. package/app/types.ts +0 -358
  108. package/build.ts +0 -16
  109. package/buildPublish.ts +0 -138
  110. package/buildPublishArtifactAssembly.ts +0 -724
  111. package/buildPublishImportAnalysis.ts +0 -242
  112. package/chat/messages/fetchMessages.ts +0 -84
  113. package/chat/messages/types.ts +0 -185
  114. package/cli/agentCreateCustomCommands.ts +0 -278
  115. package/cli/agentDialogsCommands.ts +0 -227
  116. package/cli/agentDoctorCommands.ts +0 -203
  117. package/cli/agentRunLocalWorkspace.ts +0 -182
  118. package/cli/agentRunParsing.ts +0 -298
  119. package/cli/agentSuperviseCommands.ts +0 -8
  120. package/cli/agentUnpublishCommands.ts +0 -113
  121. package/cli/buildPublish.ts +0 -138
  122. package/cli/buildPublishArtifactAssembly.ts +0 -724
  123. package/cli/buildPublishImportAnalysis.ts +0 -242
  124. package/cli/cliIoTypes.ts +0 -3
  125. package/cli/cliRuntimeDoctorReport.ts +0 -193
  126. package/cli/client/agentRunInput.ts +0 -10
  127. package/cli/client/agentRunLocalExecution.ts +0 -124
  128. package/cli/client/agentRunLocalExecutor.ts +0 -179
  129. package/cli/client/agentRunRuntimeSelection.ts +0 -145
  130. package/cli/client/agentRunServerTransport.ts +0 -397
  131. package/cli/client/agentRunTaskRunRecorder.ts +0 -176
  132. package/cli/customCodingAgentFlow.ts +0 -208
  133. package/cli/customCodingAgentRecord.ts +0 -179
  134. package/cli/dialogDataAccess.ts +0 -186
  135. package/cli/dialogInternalCommandEntries.ts +0 -11
  136. package/cli/dialogReadCommands.ts +0 -180
  137. package/cli/dialogReadHelpers.ts +0 -226
  138. package/cli/dialogStatusCommands.ts +0 -123
  139. package/cli/docInternalCommandEntries.ts +0 -20
  140. package/cli/hybridReadHelpers.ts +0 -109
  141. package/cli/machineCommandPrompts.ts +0 -79
  142. package/cli/machineCommandResolution.ts +0 -43
  143. package/cli/noloReadBridgePrompt.ts +0 -16
  144. package/cli/pageCreateCommands.ts +0 -219
  145. package/cli/pageDeleteCommands.ts +0 -167
  146. package/cli/pageReadCommands.ts +0 -151
  147. package/cli/pageUpdateCommands.ts +0 -249
  148. package/cli/pageWriteHelpers.ts +0 -209
  149. package/cli/publishPackage.ts +0 -36
  150. package/cli/runtimeInternalCommandEntries.ts +0 -15
  151. package/cli/runtimePassthroughCommands.ts +0 -22
  152. package/cli/scriptPassthroughHelpers.ts +0 -28
  153. package/cli/secretScanHelpers.ts +0 -31
  154. package/cli/spaceAttachCommands.ts +0 -134
  155. package/cli/spaceCategoryCommands.ts +0 -263
  156. package/cli/spaceCommands.ts +0 -295
  157. package/cli/spaceDeleteCommands.ts +0 -312
  158. package/cli/spaceInternalCommandEntries.ts +0 -21
  159. package/cli/spaceMutationHelpers.ts +0 -135
  160. package/cli/spaceReadCommands.ts +0 -323
  161. package/cli/tableDataOutput.ts +0 -41
  162. package/cli/tableDataSafety.ts +0 -26
  163. package/cli/tableMetaCommands.ts +0 -307
  164. package/cli/tableMutationCommands.ts +0 -266
  165. package/cli/tableQueryParsing.ts +0 -90
  166. package/cli/tableQueryRequest.ts +0 -53
  167. package/cli/taskRunActions.ts +0 -122
  168. package/cli/taskRunParsing.ts +0 -86
  169. package/cli/taskRunPromptShared.ts +0 -55
  170. package/cli/tui/tuiCatalog.ts +0 -22
  171. package/cli/tui/tuiCommandInterpreter.ts +0 -253
  172. package/cli/tui/tuiPresentation.ts +0 -146
  173. package/cliIoTypes.ts +0 -3
  174. package/cliRuntimeDoctorReport.ts +0 -193
  175. package/client/agentRunInput.ts +0 -10
  176. package/client/agentRunLocalExecution.test.ts +0 -123
  177. package/client/agentRunLocalExecution.ts +0 -124
  178. package/client/agentRunLocalExecutor.ts +0 -179
  179. package/client/agentRunRuntimeSelection.test.ts +0 -159
  180. package/client/agentRunRuntimeSelection.ts +0 -145
  181. package/client/agentRunServerTransport.ts +0 -397
  182. package/client/agentRunTaskRunRecorder.ts +0 -176
  183. package/connector-experimental/daemonLauncher.ts +0 -223
  184. package/create/space/spaceKeys.ts +0 -65
  185. package/create/types.ts +0 -21
  186. package/customCodingAgentFlow.ts +0 -208
  187. package/customCodingAgentRecord.ts +0 -179
  188. package/database/keys.ts +0 -765
  189. package/database/tombstones.ts +0 -52
  190. package/database/utils/ulid.ts +0 -1
  191. package/dialogDataAccess.ts +0 -186
  192. package/dialogInternalCommandEntries.ts +0 -11
  193. package/dialogReadCommands.ts +0 -180
  194. package/dialogReadHelpers.ts +0 -226
  195. package/dialogStatusCommands.ts +0 -123
  196. package/docInternalCommandEntries.ts +0 -20
  197. package/hybridReadHelpers.ts +0 -109
  198. package/machineCommandPrompts.ts +0 -79
  199. package/machineCommandResolution.ts +0 -43
  200. package/noloReadBridgePrompt.ts +0 -16
  201. package/pageCreateCommands.ts +0 -219
  202. package/pageDeleteCommands.ts +0 -167
  203. package/pageReadCommands.ts +0 -151
  204. package/pageUpdateCommands.ts +0 -249
  205. package/pageWriteHelpers.ts +0 -209
  206. package/publishPackage.ts +0 -36
  207. package/runtimeInternalCommandEntries.ts +0 -15
  208. package/runtimePassthroughCommands.ts +0 -22
  209. package/scriptPassthroughHelpers.ts +0 -28
  210. package/secretScanHelpers.ts +0 -31
  211. package/share/helpers.ts +0 -302
  212. package/share/keys.ts +0 -243
  213. package/share/types.ts +0 -100
  214. package/spaceAttachCommands.ts +0 -134
  215. package/spaceCategoryCommands.ts +0 -263
  216. package/spaceCommands.ts +0 -295
  217. package/spaceDeleteCommands.ts +0 -312
  218. package/spaceInternalCommandEntries.ts +0 -21
  219. package/spaceMutationHelpers.ts +0 -135
  220. package/spaceReadCommands.ts +0 -323
  221. package/tableDataOutput.ts +0 -41
  222. package/tableDataSafety.ts +0 -26
  223. package/tableMetaCommands.ts +0 -307
  224. package/tableMutationCommands.ts +0 -266
  225. package/tableQueryParsing.ts +0 -90
  226. package/tableQueryRequest.ts +0 -53
  227. package/taskRunActions.ts +0 -122
  228. package/taskRunParsing.ts +0 -86
  229. package/taskRunPromptShared.ts +0 -55
  230. package/tui/tuiCatalog.ts +0 -22
  231. package/tui/tuiCommandInterpreter.test.ts +0 -169
  232. package/tui/tuiCommandInterpreter.ts +0 -253
  233. package/tui/tuiPresentation.test.ts +0 -154
  234. package/tui/tuiPresentation.ts +0 -146
@@ -1,176 +0,0 @@
1
- import { join } from "node:path";
2
-
3
- import type { EnvLike } from "../cliEnvHelpers";
4
- import type { OutputLike } from "../cliIoTypes";
5
- import {
6
- classifyTaskRunReviewStatus,
7
- type TaskRunToolEvidence,
8
- } from "./agentRunLocalExecution";
9
- import type { TaskRunPromptContext } from "./taskRunPrompt";
10
-
11
- type TaskRunAgentRole = "pm" | "frontend" | "fullstack" | "reviewer" | "codex";
12
- type TaskRunStatus = "running" | "completed" | "failed";
13
-
14
- type TaskRunRecorderOptionShape = {
15
- agentName: string;
16
- agentKey: string;
17
- serverUrl: string;
18
- scriptDir: string;
19
- env: EnvLike;
20
- output: OutputLike;
21
- taskRunContext?: TaskRunPromptContext;
22
- taskRunRecorder?: unknown;
23
- };
24
-
25
- export type TaskRunRecorderArgs<
26
- TOptions extends TaskRunRecorderOptionShape = TaskRunRecorderOptionShape,
27
- > = {
28
- options: TOptions;
29
- status: TaskRunStatus;
30
- dialogId?: string;
31
- resultSummary?: string;
32
- errorCode?: string;
33
- toolEvidence?: TaskRunToolEvidence;
34
- };
35
-
36
- export type TaskRunRecorder<
37
- TOptions extends TaskRunRecorderOptionShape = TaskRunRecorderOptionShape,
38
- > = (args: TaskRunRecorderArgs<TOptions>) => Promise<void>;
39
-
40
- export function inferTaskRunAgentRole(agentRef: string): TaskRunAgentRole {
41
- const normalized = agentRef.toLowerCase();
42
- if (normalized.includes("project-manager") || normalized.includes("manager")) return "pm";
43
- if (normalized.includes("frontend")) return "frontend";
44
- if (normalized.includes("fullstack")) return "fullstack";
45
- if (normalized.includes("review")) return "reviewer";
46
- return "codex";
47
- }
48
-
49
- export async function runTaskRunCli<TOptions extends TaskRunRecorderOptionShape>(args: {
50
- options: TOptions;
51
- cliArgs: string[];
52
- }) {
53
- const scriptPath = join(args.options.scriptDir, "taskRun.ts");
54
- const proc = Bun.spawn({
55
- cmd: [process.execPath, scriptPath, ...args.cliArgs],
56
- stdout: "pipe",
57
- stderr: "pipe",
58
- env: {
59
- ...process.env,
60
- ...args.options.env,
61
- BASE_URL: args.options.serverUrl,
62
- },
63
- });
64
- const [stdout, stderr, exitCode] = await Promise.all([
65
- new Response(proc.stdout).text(),
66
- new Response(proc.stderr).text(),
67
- proc.exited,
68
- ]);
69
- if (exitCode !== 0) {
70
- throw new Error((stderr || stdout || `taskRun.ts exited ${exitCode}`).trim());
71
- }
72
- }
73
-
74
- export async function defaultTaskRunRecorder<TOptions extends TaskRunRecorderOptionShape>(
75
- args: TaskRunRecorderArgs<TOptions>
76
- ) {
77
- const context = args.options.taskRunContext;
78
- if (!context?.rowDbKey) return;
79
- const role = inferTaskRunAgentRole(args.options.agentName || args.options.agentKey);
80
- if (role === "reviewer" && args.status !== "running") {
81
- await runTaskRunCli({
82
- options: args.options,
83
- cliArgs: [
84
- "request-review",
85
- "--row-dbkey",
86
- context.rowDbKey,
87
- "--base-url",
88
- args.options.serverUrl,
89
- "--reviewer-agent-key",
90
- args.options.agentKey,
91
- ...(context.artifactIds?.length ? ["--artifact-ids", context.artifactIds.join(",")] : []),
92
- ...(args.dialogId ? ["--dialog-id", args.dialogId] : []),
93
- ],
94
- });
95
- }
96
- await runTaskRunCli({
97
- options: args.options,
98
- cliArgs: [
99
- "record-agent-run",
100
- "--row-dbkey",
101
- context.rowDbKey,
102
- "--base-url",
103
- args.options.serverUrl,
104
- "--agent-key",
105
- args.options.agentKey,
106
- "--role",
107
- role,
108
- "--run-status",
109
- args.status,
110
- ...(context.workItemId ? ["--work-item-id", context.workItemId] : []),
111
- ...(args.dialogId ? ["--dialog-id", args.dialogId] : []),
112
- ...(args.resultSummary ? ["--result-summary", args.resultSummary.slice(0, 240)] : []),
113
- ...(args.errorCode ? ["--error-code", args.errorCode] : []),
114
- ...(args.toolEvidence?.toolsUsed?.length
115
- ? ["--tools-used", args.toolEvidence.toolsUsed.join(",")]
116
- : []),
117
- ...(args.toolEvidence?.summary
118
- ? ["--tool-trace-summary", JSON.stringify(args.toolEvidence.summary)]
119
- : []),
120
- ],
121
- });
122
- if (context.workItemId && args.dialogId) {
123
- await runTaskRunCli({
124
- options: args.options,
125
- cliArgs: [
126
- "update-work-item",
127
- "--row-dbkey",
128
- context.rowDbKey,
129
- "--base-url",
130
- args.options.serverUrl,
131
- "--id",
132
- context.workItemId,
133
- "--dialog-ids",
134
- args.dialogId,
135
- ],
136
- });
137
- }
138
- if (role === "reviewer" && args.status !== "running") {
139
- const reviewStatus =
140
- args.status === "failed" ? "blocked" : classifyTaskRunReviewStatus(args.resultSummary);
141
- if (reviewStatus) {
142
- await runTaskRunCli({
143
- options: args.options,
144
- cliArgs: [
145
- "review-result",
146
- "--row-dbkey",
147
- context.rowDbKey,
148
- "--base-url",
149
- args.options.serverUrl,
150
- "--review-status",
151
- reviewStatus,
152
- "--reviewer-agent-key",
153
- args.options.agentKey,
154
- ...(context.artifactIds?.length ? ["--artifact-ids", context.artifactIds.join(",")] : []),
155
- ...(args.dialogId ? ["--dialog-id", args.dialogId] : []),
156
- ],
157
- });
158
- }
159
- }
160
- }
161
-
162
- export async function recordTaskRunOutcome<TOptions extends TaskRunRecorderOptionShape>(
163
- args: TaskRunRecorderArgs<TOptions>
164
- ) {
165
- if (!args.options.taskRunContext?.rowDbKey) return;
166
- try {
167
- const recorder =
168
- (args.options.taskRunRecorder as TaskRunRecorder<TOptions> | undefined) ??
169
- ((nextArgs: TaskRunRecorderArgs<TOptions>) => defaultTaskRunRecorder(nextArgs));
170
- await recorder(args);
171
- } catch (error) {
172
- args.options.output.write(
173
- `[nolo] task-run writeback failed: ${error instanceof Error ? error.message : String(error)}\n`
174
- );
175
- }
176
- }
@@ -1,223 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { existsSync, mkdirSync, openSync, readFileSync, realpathSync } from "node:fs";
3
- import { homedir } from "node:os";
4
- import { dirname, isAbsolute, join, relative, resolve } from "node:path";
5
-
6
- export type ConnectorDaemonEnv = Record<string, string | undefined>;
7
-
8
- export type ConnectorDaemonOutput = {
9
- write(chunk: string): void;
10
- };
11
-
12
- type PackageJson = {
13
- name?: string;
14
- workspaces?: string[] | { packages?: string[] };
15
- };
16
-
17
- const CONNECTOR_RUNTIME_WORKSPACE_PACKAGES = new Set([
18
- "connector-experimental",
19
- "ai",
20
- ]);
21
-
22
- function readJsonFile<T>(path: string): T | null {
23
- try {
24
- return JSON.parse(readFileSync(path, "utf8")) as T;
25
- } catch {
26
- return null;
27
- }
28
- }
29
-
30
- function getWorkspacePatterns(packageJson: PackageJson) {
31
- if (Array.isArray(packageJson.workspaces)) return packageJson.workspaces;
32
- return packageJson.workspaces?.packages ?? [];
33
- }
34
-
35
- function normalizePath(path: string) {
36
- const resolved = resolve(path);
37
- return process.platform === "win32" ? resolved.toLowerCase() : resolved;
38
- }
39
-
40
- function isInsideOrSame(path: string, parent: string) {
41
- const relativePath = relative(parent, path);
42
- return relativePath === "" || (!relativePath.startsWith("..") && !isAbsolute(relativePath));
43
- }
44
-
45
- function findWorkspaceRoot(startPath: string) {
46
- let current = resolve(startPath);
47
- while (true) {
48
- const packageJsonPath = join(current, "package.json");
49
- if (existsSync(packageJsonPath)) {
50
- const packageJson = readJsonFile<PackageJson>(packageJsonPath);
51
- if (packageJson && getWorkspacePatterns(packageJson).length > 0) {
52
- return current;
53
- }
54
- }
55
- const parent = dirname(current);
56
- if (parent === current) return null;
57
- current = parent;
58
- }
59
- }
60
-
61
- export function validateConnectorWorkspaceLinks(cwd: string) {
62
- const repoRoot = findWorkspaceRoot(cwd);
63
- if (!repoRoot) return [];
64
-
65
- const rootPackageJson = readJsonFile<PackageJson>(join(repoRoot, "package.json"));
66
- if (!rootPackageJson) return [];
67
-
68
- const normalizedRepoRoot = normalizePath(realpathSync(repoRoot));
69
- const errors: string[] = [];
70
-
71
- for (const pattern of getWorkspacePatterns(rootPackageJson)) {
72
- if (!pattern.endsWith("/*")) continue;
73
- const workspaceParent = join(repoRoot, pattern.slice(0, -2));
74
- if (!existsSync(workspaceParent)) continue;
75
-
76
- for (const entry of Array.from(new Bun.Glob("*/package.json").scanSync({ cwd: workspaceParent }))) {
77
- const packageDir = join(workspaceParent, dirname(entry));
78
- const packageJson = readJsonFile<PackageJson>(join(workspaceParent, entry));
79
- if (!packageJson?.name || !CONNECTOR_RUNTIME_WORKSPACE_PACKAGES.has(packageJson.name)) {
80
- continue;
81
- }
82
-
83
- const linkPath = join(repoRoot, "node_modules", ...packageJson.name.split("/"));
84
- if (!existsSync(linkPath)) {
85
- errors.push(`${linkPath} is missing. Run bun install in ${repoRoot}.`);
86
- continue;
87
- }
88
-
89
- const actualPath = normalizePath(realpathSync(linkPath));
90
- const expectedPath = normalizePath(realpathSync(packageDir));
91
- if (!isInsideOrSame(actualPath, normalizedRepoRoot)) {
92
- errors.push(
93
- `${linkPath} points outside this checkout: ${actualPath}. Run bun install in ${repoRoot}.`,
94
- );
95
- continue;
96
- }
97
- if (actualPath !== expectedPath) {
98
- errors.push(
99
- `${linkPath} points at ${actualPath}, expected ${expectedPath}. Run bun install in ${repoRoot}.`,
100
- );
101
- }
102
- }
103
- }
104
-
105
- return errors;
106
- }
107
-
108
- export async function checkConnectorWorkspaceLinks(
109
- cwd: string,
110
- output: ConnectorDaemonOutput,
111
- validateWorkspaceLinks: (cwd: string) => string[] | Promise<string[]>,
112
- ) {
113
- const errors = await validateWorkspaceLinks(cwd);
114
- if (errors.length === 0) return true;
115
- output.write(
116
- [
117
- "[nolo] Connector workspace package links are unsafe.",
118
- "The connector would import workspace packages from a different checkout, so machine capabilities and runtime behavior may be stale.",
119
- ...errors,
120
- "",
121
- ].join("\n"),
122
- );
123
- return false;
124
- }
125
-
126
- export function resolveDaemonLogPath(env: ConnectorDaemonEnv) {
127
- return env.NOLO_CONNECT_LOG || join(homedir(), ".nolo", "logs", "connector.log");
128
- }
129
-
130
- export function buildConnectorDaemonEnv(env: ConnectorDaemonEnv, cwd: string) {
131
- return {
132
- ...env,
133
- NOLO_CONNECTOR_WORKDIR: env.NOLO_CONNECTOR_WORKDIR?.trim() || cwd,
134
- NOLO_AGENT_WORKDIR: env.NOLO_AGENT_WORKDIR?.trim() || cwd,
135
- NOLO_LOCAL_WORKTREE: env.NOLO_LOCAL_WORKTREE?.trim() || cwd,
136
- };
137
- }
138
-
139
- function firstNonEmptyValue(...values: Array<string | undefined>) {
140
- for (const value of values) {
141
- if (typeof value === "string" && value.trim()) return value.trim();
142
- }
143
- return "";
144
- }
145
-
146
- export function buildDaemonCommand(
147
- cliEntrypointPath: string | undefined,
148
- env: ConnectorDaemonEnv,
149
- fallbackEntrypointPath = import.meta.path,
150
- ) {
151
- const command = [process.execPath, cliEntrypointPath || fallbackEntrypointPath, "connect", "--ws"];
152
- const serverUrl = firstNonEmptyValue(env.NOLO_SERVER, env.NOLO_SERVER_URL, env.BASE_URL);
153
- const authToken = firstNonEmptyValue(
154
- env.NOLO_MACHINE_API_KEY,
155
- env.AUTH_TOKEN,
156
- env.AUTH,
157
- env.BENCHMARK_AUTH_TOKEN,
158
- );
159
- if (serverUrl) {
160
- command.push("--server-url", serverUrl);
161
- }
162
- if (authToken) {
163
- command.push("--api-key", authToken);
164
- }
165
- return command;
166
- }
167
-
168
- export function defaultSpawnDaemon(args: {
169
- cmd: string[];
170
- cwd: string;
171
- env: ConnectorDaemonEnv;
172
- logPath: string;
173
- }) {
174
- mkdirSync(dirname(args.logPath), { recursive: true });
175
- const out = openSync(args.logPath, "a");
176
- const env = Object.fromEntries(
177
- Object.entries(args.env).filter((entry): entry is [string, string] => typeof entry[1] === "string")
178
- );
179
- const proc = spawn(args.cmd[0], args.cmd.slice(1), {
180
- cwd: args.cwd,
181
- env,
182
- detached: true,
183
- stdio: ["ignore", out, out],
184
- });
185
- proc.unref();
186
- return { pid: proc.pid };
187
- }
188
-
189
- export type ConnectorDaemonDeps = {
190
- env?: ConnectorDaemonEnv;
191
- output?: ConnectorDaemonOutput;
192
- cliEntrypointPath?: string;
193
- cwd?: string;
194
- fallbackEntrypointPath?: string;
195
- validateWorkspaceLinks?: (cwd: string) => string[] | Promise<string[]>;
196
- spawnDaemon?: (args: {
197
- cmd: string[];
198
- cwd: string;
199
- env: ConnectorDaemonEnv;
200
- logPath: string;
201
- }) => { pid?: number };
202
- };
203
-
204
- export async function runConnectorDaemon(deps: ConnectorDaemonDeps = {}) {
205
- const env = deps.env ?? process.env;
206
- const output = deps.output ?? process.stdout;
207
- const cwd = deps.cwd ?? process.cwd();
208
- const validateWorkspaceLinks = deps.validateWorkspaceLinks ?? validateConnectorWorkspaceLinks;
209
-
210
- if (!(await checkConnectorWorkspaceLinks(cwd, output, validateWorkspaceLinks))) {
211
- return 1;
212
- }
213
-
214
- const logPath = resolveDaemonLogPath(env);
215
- const result = (deps.spawnDaemon ?? defaultSpawnDaemon)({
216
- cmd: buildDaemonCommand(deps.cliEntrypointPath, env, deps.fallbackEntrypointPath),
217
- cwd,
218
- env: buildConnectorDaemonEnv(env, cwd),
219
- logPath,
220
- });
221
- output.write(`Connector daemon started${result.pid ? ` pid=${result.pid}` : ""}. Log: ${logPath}\n`);
222
- return 0;
223
- }
@@ -1,65 +0,0 @@
1
- const SEPARATOR = "-";
2
- const SPACE_PREFIX = "space";
3
- const SPACE_PREFIX_WITH_SEPARATOR = `${SPACE_PREFIX}${SEPARATOR}`;
4
-
5
- export const normalizeSpaceId = (spaceId: string) => {
6
- if (!spaceId) return spaceId;
7
- return spaceId.startsWith(SPACE_PREFIX_WITH_SEPARATOR)
8
- ? spaceId.slice(SPACE_PREFIX_WITH_SEPARATOR.length)
9
- : spaceId;
10
- };
11
-
12
- export const createSpaceKey = {
13
- // 空间基础信息的key
14
- space: (spaceId: string) => {
15
- return [SPACE_PREFIX, normalizeSpaceId(spaceId)].join(SEPARATOR);
16
- },
17
-
18
- // 空间成员的key
19
- member: (userId: string, spaceId: string) => {
20
- return [SPACE_PREFIX, "member", userId, normalizeSpaceId(spaceId)].join(
21
- SEPARATOR
22
- );
23
- },
24
-
25
- // 查询用户所在的所有空间的范围
26
- memberRange: (userId: string) => {
27
- return {
28
- start: [SPACE_PREFIX, "member", userId, ""].join(SEPARATOR),
29
- end: [SPACE_PREFIX, "member", userId, "\uffff"].join(SEPARATOR),
30
- };
31
- },
32
-
33
- /**
34
- * 预留:未来若出现“按用户、按空间、且必须跨设备同步”的空间级偏好,
35
- * 统一使用这个 key family。当前产品主链不要依赖它。
36
- */
37
- setting: (userId: string, spaceId: string) => {
38
- return [SPACE_PREFIX, "setting", userId, normalizeSpaceId(spaceId)].join(
39
- SEPARATOR
40
- );
41
- },
42
-
43
- /**
44
- * 预留:未来如确实需要批量读取空间级远端偏好,再使用这个范围。
45
- */
46
- settingRange: (userId: string) => {
47
- return {
48
- start: [SPACE_PREFIX, "setting", userId, ""].join(SEPARATOR),
49
- end: [SPACE_PREFIX, "setting", userId, "\uffff"].join(SEPARATOR),
50
- };
51
- },
52
-
53
- // 从成员key中提取空间key
54
- spaceFromMember: (memberKey: string) => {
55
- const parts = memberKey.split(SEPARATOR);
56
- const spaceId = parts[parts.length - 1];
57
- return [SPACE_PREFIX, spaceId].join(SEPARATOR);
58
- },
59
-
60
- // 从成员key中提取空间ID
61
- spaceIdFromMember: (memberKey: string) => {
62
- const parts = memberKey.split(SEPARATOR);
63
- return parts[parts.length - 1];
64
- },
65
- };
package/create/types.ts DELETED
@@ -1,21 +0,0 @@
1
- // create/types.ts
2
- export enum DataType {
3
- AGENT = "agent",
4
- CYBOT = "cybot",
5
- DOC = "page",
6
- DIALOG = "dialog",
7
- NOTIFICATION = "notification",
8
- MSG = "msg",
9
- TOKEN = "token",
10
- SPACE = "space",
11
- TRANSACTION = "transaction",
12
- SETTING = "setting",
13
- TASK = "task",
14
-
15
- TABLE = "table",
16
- TABLE_ROW = "table_row",
17
- FILE = "file",
18
- IMAGE = "image",
19
- APP = "app",
20
- EMAIL = "email",
21
- }
@@ -1,208 +0,0 @@
1
- export type CodingAgentServerEntry = {
2
- baseUrl: string;
3
- userId: string;
4
- authToken: string;
5
- };
6
-
7
- export type CodingAgentWriteResult = {
8
- privateKey: string;
9
- contentKey: string;
10
- };
11
-
12
- export type CodingAgentVerifyResult = {
13
- dialogId: string;
14
- content: string;
15
- };
16
-
17
- export type CodingAgentFlowDeps = {
18
- ensureAccess: (args: {
19
- baseUrl: string;
20
- seed: string;
21
- username: string;
22
- locale: string;
23
- }) => Promise<{ userId: string; authToken: string }>;
24
- ensureAccessOnBases: (args: {
25
- baseUrl: string;
26
- seed: string;
27
- username: string;
28
- locale: string;
29
- }) => Promise<CodingAgentServerEntry[]>;
30
- upsertAgentRecordOnBases: (args: {
31
- serverEntries: CodingAgentServerEntry[];
32
- agentRecord: Record<string, any>;
33
- }) => Promise<CodingAgentWriteResult[]>;
34
- attachAgentToSpace: (args: {
35
- baseUrl: string;
36
- userId: string;
37
- authToken: string;
38
- spaceId: string;
39
- contentKey: string;
40
- title: string;
41
- }) => Promise<void>;
42
- verifyAgentResponse: (args: {
43
- baseUrl: string;
44
- authToken: string;
45
- agentKey: string;
46
- prompt: string;
47
- expected: string;
48
- maxRounds: number;
49
- }) => Promise<CodingAgentVerifyResult>;
50
- resolveTargetSpaceId: (spaceId?: string) => string | undefined;
51
- now?: () => number;
52
- };
53
-
54
- export type CreateCodingAgentFromRecordOptions = {
55
- baseUrl: string;
56
- spaceId?: string;
57
- localCoreBaseUrl?: string;
58
- seed?: string;
59
- username?: string;
60
- locale?: string;
61
- agentId: string;
62
- skipVerify?: boolean;
63
- verifyPrompt?: string;
64
- expectedResponse?: string;
65
- verifyRounds?: number;
66
- syncAllBases?: boolean;
67
- buildRecord: (args: {
68
- userId: string;
69
- now: number;
70
- agentId: string;
71
- }) => Record<string, any>;
72
- };
73
-
74
- export function normalizeCodingAgentBaseUrl(baseUrl: string): string {
75
- return baseUrl.replace(/\/+$/, "");
76
- }
77
-
78
- export function splitCodingAgentServerEntries(
79
- serverEntries: CodingAgentServerEntry[],
80
- attachBaseUrl: string
81
- ) {
82
- const normalizedAttachBaseUrl = normalizeCodingAgentBaseUrl(attachBaseUrl);
83
- const runtimeEntries = serverEntries.map((entry) => ({
84
- ...entry,
85
- baseUrl: normalizeCodingAgentBaseUrl(entry.baseUrl),
86
- }));
87
- const attachEntries = runtimeEntries.filter(
88
- (entry) => entry.baseUrl === normalizedAttachBaseUrl
89
- );
90
-
91
- return {
92
- runtimeEntries,
93
- attachEntries,
94
- needsAttachLogin: attachEntries.length === 0,
95
- };
96
- }
97
-
98
- export async function createCodingAgentFromRecord(
99
- options: CreateCodingAgentFromRecordOptions,
100
- deps: CodingAgentFlowDeps
101
- ) {
102
- const {
103
- baseUrl,
104
- spaceId,
105
- localCoreBaseUrl,
106
- seed = process.env.AGENT_SEED ?? "nolo-platform-demo-account-v1",
107
- username = process.env.AGENT_USER ?? "platform-demo",
108
- locale = process.env.AGENT_LOCALE ?? "zh-CN",
109
- agentId,
110
- skipVerify = false,
111
- verifyPrompt = "只回复 OK",
112
- expectedResponse = "OK",
113
- verifyRounds = 2,
114
- syncAllBases = true,
115
- buildRecord,
116
- } = options;
117
-
118
- const attachSpaceId = deps.resolveTargetSpaceId(spaceId);
119
- const attachBaseUrl = normalizeCodingAgentBaseUrl(localCoreBaseUrl ?? baseUrl);
120
- const serverEntries = syncAllBases
121
- ? await deps.ensureAccessOnBases({
122
- baseUrl,
123
- seed,
124
- username,
125
- locale,
126
- })
127
- : [
128
- {
129
- baseUrl,
130
- ...(await deps.ensureAccess({
131
- baseUrl,
132
- seed,
133
- username,
134
- locale,
135
- })),
136
- },
137
- ];
138
- const entryPlan = splitCodingAgentServerEntries(serverEntries, attachBaseUrl);
139
- const attachEntries = entryPlan.needsAttachLogin
140
- ? [
141
- {
142
- baseUrl: attachBaseUrl,
143
- ...(await deps.ensureAccess({
144
- baseUrl: attachBaseUrl,
145
- seed,
146
- username,
147
- locale,
148
- })),
149
- },
150
- ]
151
- : entryPlan.attachEntries;
152
- const allEntries = [
153
- ...entryPlan.runtimeEntries,
154
- ...attachEntries.filter(
155
- (attachEntry) =>
156
- !entryPlan.runtimeEntries.some((runtimeEntry) => runtimeEntry.baseUrl === attachEntry.baseUrl)
157
- ),
158
- ];
159
- const primaryEntry = allEntries[0];
160
- const { userId, authToken } = primaryEntry;
161
- const now = deps.now?.() ?? Date.now();
162
- const agentRecord = buildRecord({
163
- userId,
164
- now,
165
- agentId,
166
- });
167
-
168
- const [{ privateKey, contentKey }] = await deps.upsertAgentRecordOnBases({
169
- serverEntries: allEntries,
170
- agentRecord,
171
- });
172
- if (attachSpaceId) {
173
- for (const entry of attachEntries) {
174
- await deps.attachAgentToSpace({
175
- baseUrl: entry.baseUrl,
176
- userId,
177
- authToken: entry.authToken,
178
- spaceId: attachSpaceId,
179
- contentKey,
180
- title: agentRecord.name ?? agentId,
181
- });
182
- }
183
- }
184
-
185
- const verify = skipVerify
186
- ? { dialogId: "", content: "SKIPPED" }
187
- : await deps.verifyAgentResponse({
188
- baseUrl: primaryEntry.baseUrl,
189
- authToken,
190
- agentKey: privateKey,
191
- prompt: verifyPrompt,
192
- expected: expectedResponse,
193
- maxRounds: verifyRounds,
194
- });
195
-
196
- return {
197
- userId,
198
- authToken,
199
- agentId,
200
- privateKey,
201
- agentUrl: `${primaryEntry.baseUrl}/${privateKey}`,
202
- spaceId: attachSpaceId,
203
- verify,
204
- replicatedBases: allEntries.map((entry) => entry.baseUrl),
205
- verifiedBase: primaryEntry.baseUrl,
206
- agentRecord,
207
- };
208
- }