nolo-cli 0.1.22 → 0.1.26
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 +25 -3
- package/agent-runtime/agentRecordConfig.ts +4 -0
- package/agent-runtime/hostAdapter.ts +2 -0
- package/agent-runtime/hybridRecordStore.ts +30 -9
- package/agent-runtime/index.ts +7 -0
- package/agent-runtime/localLoop.ts +14 -4
- package/agent-runtime/localToolPolicy.ts +22 -10
- package/agent-runtime/localWorkspaceTools.ts +140 -374
- package/agent-runtime/platformChatProvider.ts +3 -0
- package/agent-runtime/runtimeToolPolicy.ts +133 -0
- package/agent-runtime/types.ts +47 -0
- package/agentAliases.ts +1 -1
- package/agentCommandSupport.ts +77 -0
- package/agentInternalCommandEntries.ts +34 -0
- package/agentListCommands.ts +123 -0
- package/agentListHelpers.ts +187 -0
- package/agentMachineCommands.ts +402 -0
- package/agentRecordCommands.ts +141 -0
- package/agentRecordHelpers.ts +395 -0
- package/agentRunCommand.ts +75 -3
- package/agentRuntimeCommands.ts +7 -773
- package/ai/agent/_executeModel.ts +29 -3
- package/ai/agent/buildSystemPrompt.ts +17 -0
- package/ai/agent/cliChatClient.ts +38 -4
- package/ai/agent/cliExecutor.ts +304 -25
- package/ai/agent/createAgentSchema.ts +2 -2
- package/ai/agent/guidedCreation/assistant.ts +82 -0
- package/ai/agent/guidedCreation/capabilities.ts +84 -0
- package/ai/agent/guidedCreation/draft.ts +62 -0
- package/ai/agent/guidedCreation/types.ts +38 -0
- package/ai/agent/machineRunPermissions.ts +21 -3
- package/ai/agent/runtimeGuidance.ts +1 -1
- package/ai/agent/server/fetchPublicAgents.ts +6 -1
- package/ai/agent/streamAgentChatTurn.ts +593 -36
- package/ai/agent/web/useGuidedAgentCreation.ts +217 -0
- package/ai/ai.locale.ts +14 -2
- package/ai/chat/fetchUtils.native.ts +2 -0
- package/ai/chat/fetchUtils.ts +2 -0
- package/ai/chat/sendOpenAICompletionsRequest.ts +82 -1
- package/ai/chat/sendOpenAIResponseRequest.ts +65 -0
- package/ai/llm/getPricing.ts +14 -0
- package/ai/llm/kimi.ts +4 -1
- package/ai/llm/modelAvatar.ts +1 -0
- package/ai/llm/providers.ts +4 -1
- package/ai/llm/reasoningModels.ts +1 -0
- package/ai/taskRun/taskRunProtocol.ts +25 -10
- package/ai/token/modelUsageQuery.ts +17 -0
- package/ai/tools/agent/agentTools.ts +38 -0
- package/ai/tools/agent/prepareAgentDraftTool.ts +159 -0
- package/ai/tools/agent/startAgentDialogTool.ts +53 -0
- package/ai/tools/checkEnvTool.ts +52 -20
- package/ai/tools/convertMarxistsBookTool.ts +103 -0
- package/ai/tools/{execBashTool.ts → execShellTool.ts} +44 -161
- package/ai/tools/index.ts +24 -14
- package/ai/tools/marxistsOfflineBook.ts +253 -0
- package/ai/tools/modelUsageTools.ts +9 -2
- package/ai/tools/readTool.ts +31 -0
- package/ai/tools/toolApiClient.ts +35 -1
- package/ai/tools/toolNameAliases.ts +13 -0
- package/cliCommandAdapters.ts +28 -0
- package/cliCommandDispatch.ts +66 -0
- package/cliCommandFactories.ts +34 -0
- package/cliCommandTypes.ts +49 -0
- package/cliEnvHelpers.ts +44 -0
- package/client/agentRun.test.ts +330 -24
- package/client/agentRun.ts +117 -35
- package/client/hybridRecordStore.test.ts +42 -0
- package/client/hybridRecordStore.ts +11 -0
- package/client/localRuntimeAdapter.test.ts +191 -21
- package/client/localRuntimeAdapter.ts +99 -10
- package/client/localRuntimeDryRun.test.ts +5 -2
- package/client/taskRunPrompt.ts +1 -0
- package/commandRegistry.ts +11 -61
- package/connector-experimental/capabilities.ts +1 -0
- package/database/actions/common.ts +4 -3
- package/database/config.ts +19 -0
- package/database/server/coreDataProxy.ts +43 -26
- package/index.ts +54 -191
- package/internalCommandEntries.ts +12 -0
- package/machineCommands.ts +688 -64
- package/offlineMarxistsAgentCommand.ts +314 -0
- package/package.json +22 -2
- package/render/canvas/canvasEditContext.ts +127 -0
- package/render/canvas/canvasRuntime.ts +57 -0
- package/render/canvas/canvasSnapshotParser.ts +76 -0
- package/render/canvas/canvasTree.ts +308 -0
- package/render/canvas/types.ts +46 -0
- package/render/layout/deleteBehavior.ts +52 -0
- package/render/layout/mainLayoutSidebar.ts +17 -0
- package/render/layout/mainLayoutViewMode.ts +56 -0
- package/render/layout/topbarUtils.ts +87 -0
- package/render/layout/useDevReloadPending.ts +30 -0
- package/render/page/createPageAction.ts +183 -0
- package/render/page/docSlice.ts +468 -0
- package/render/page/server/createPage.ts +174 -0
- package/render/page/server/handleCreatePage.ts +91 -0
- package/render/page/server/index.ts +4 -0
- package/render/page/types.ts +17 -0
- package/render/page/useKeyboardSave.ts +48 -0
- package/render/styles/zIndex.ts +12 -0
- package/render/surf/WeatherIconStyles.ts +17 -0
- package/render/surf/color.ts +9 -0
- package/render/surf/config.ts +46 -0
- package/render/surf/screens/style.ts +1 -0
- package/render/surf/styles/ToggleButtonStyles.ts +8 -0
- package/render/surf/utils/groupedWeatherData.ts +32 -0
- package/render/surf/weatherUtils.ts +50 -0
- package/render/table/activityColumns.ts +6 -0
- package/render/table/createTableAction.ts +270 -0
- package/render/table/deleteTableAction.ts +129 -0
- package/render/table/fetchAndCacheTableRows.ts +174 -0
- package/render/table/tableSlice.ts +1106 -0
- package/render/table/tableView.ts +289 -0
- package/render/table/toolValueUtils.ts +363 -0
- package/render/table/types.ts +252 -0
- package/render/table/useCreateTable.ts +72 -0
- package/render/table/useTable.ts +61 -0
- package/render/table/utils/tableSerialization.ts +50 -0
- package/render/web/elements/artifactPreviewCode.ts +43 -0
- package/render/web/elements/artifactRuntimePreload.ts +52 -0
- package/render/web/elements/codeBlockAutoPreview.ts +10 -0
- package/render/web/elements/mermaidPreview.ts +21 -0
- package/render/web/ui/useInlineEdit.ts +135 -0
- package/runtimeDoctorCommands.ts +118 -0
- package/scriptCommandEntries.ts +71 -0
- package/systemInternalCommandEntries.ts +71 -0
- package/tableCommands.ts +42 -5
- package/workflowInternalCommandEntries.ts +11 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { resolveAgentRuntimeDecision } from "./agent-runtime/runtimeDecision";
|
|
2
|
+
import {
|
|
3
|
+
type AgentCommandDeps,
|
|
4
|
+
type LocalRuntimeProbeResult,
|
|
5
|
+
} from "./agentCommandSupport";
|
|
6
|
+
import {
|
|
7
|
+
resolveAuthToken,
|
|
8
|
+
resolveServerUrl,
|
|
9
|
+
type EnvLike,
|
|
10
|
+
} from "./cliEnvHelpers";
|
|
11
|
+
|
|
12
|
+
function detectLocalAgentConfig(env: EnvLike) {
|
|
13
|
+
return Boolean(readLocalAgentKey(env) || env.NOLO_AGENT_CACHE_READY);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function readLocalAgentKey(env: EnvLike) {
|
|
17
|
+
return env.NOLO_LOCAL_AGENT_KEY || env.NOLO_AGENT || "";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function detectLocalProvider(env: EnvLike) {
|
|
21
|
+
return Boolean(
|
|
22
|
+
env.OPENAI_API_KEY ||
|
|
23
|
+
env.ANTHROPIC_API_KEY ||
|
|
24
|
+
env.GOOGLE_API_KEY ||
|
|
25
|
+
env.NOLO_LOCAL_OPENAI_BASE_URL ||
|
|
26
|
+
env.OLLAMA_BASE_URL
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function detectProviderLabel(env: EnvLike) {
|
|
31
|
+
if (env.NOLO_LOCAL_OPENAI_BASE_URL) return `openai-compatible endpoint ${env.NOLO_LOCAL_OPENAI_BASE_URL}`;
|
|
32
|
+
if (env.OLLAMA_BASE_URL) return `ollama-compatible endpoint ${env.OLLAMA_BASE_URL}`;
|
|
33
|
+
if (env.OPENAI_API_KEY) return "openai via env OPENAI_API_KEY";
|
|
34
|
+
if (env.ANTHROPIC_API_KEY) return "anthropic via env ANTHROPIC_API_KEY";
|
|
35
|
+
if (env.GOOGLE_API_KEY) return "google via env GOOGLE_API_KEY";
|
|
36
|
+
return "missing";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function defaultLocalRuntimeProbe(env: EnvLike): Promise<LocalRuntimeProbeResult> {
|
|
40
|
+
const { resolveCliLocalRuntimeDbPath } = await import("./localRuntimeDb");
|
|
41
|
+
const dbPath = resolveCliLocalRuntimeDbPath({ env });
|
|
42
|
+
const agentKey = readLocalAgentKey(env);
|
|
43
|
+
try {
|
|
44
|
+
const { getDefaultCliLocalRuntimeDb } = await import("./localRuntimeDb");
|
|
45
|
+
const db = await getDefaultCliLocalRuntimeDb();
|
|
46
|
+
if (!agentKey) {
|
|
47
|
+
return { ok: true, dbPath, agentFound: false };
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
await db.get(agentKey);
|
|
51
|
+
return { ok: true, dbPath, agentFound: true, agentKey };
|
|
52
|
+
} catch {
|
|
53
|
+
return { ok: true, dbPath, agentFound: false, agentKey };
|
|
54
|
+
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
dbPath,
|
|
59
|
+
agentFound: false,
|
|
60
|
+
...(agentKey ? { agentKey } : {}),
|
|
61
|
+
error: error instanceof Error ? error.message : String(error),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function runDoctorRuntimeCommand(
|
|
67
|
+
_args: string[],
|
|
68
|
+
deps: AgentCommandDeps = {}
|
|
69
|
+
) {
|
|
70
|
+
const env = deps.env ?? process.env;
|
|
71
|
+
const output = deps.output ?? process.stdout;
|
|
72
|
+
const authToken = resolveAuthToken(env);
|
|
73
|
+
const serverUrl = resolveServerUrl(env);
|
|
74
|
+
const localProbe = await (deps.localRuntimeProbe ?? defaultLocalRuntimeProbe)(env);
|
|
75
|
+
const hasLocalAgentConfig = detectLocalAgentConfig(env) && localProbe.ok && localProbe.agentFound;
|
|
76
|
+
const hasLocalProvider = detectLocalProvider(env);
|
|
77
|
+
const missingLocalCapabilities = [
|
|
78
|
+
...(localProbe.ok ? [] : ["leveldb"]),
|
|
79
|
+
...(hasLocalAgentConfig ? [] : ["agent-config"]),
|
|
80
|
+
...(hasLocalProvider ? [] : ["provider"]),
|
|
81
|
+
];
|
|
82
|
+
const decision = resolveAgentRuntimeDecision({
|
|
83
|
+
requestedMode: "auto",
|
|
84
|
+
syncRequested: false,
|
|
85
|
+
host: "cli",
|
|
86
|
+
hasLocalAgentConfig,
|
|
87
|
+
hasLocalProvider,
|
|
88
|
+
hasLocalPersistence: true,
|
|
89
|
+
missingLocalCapabilities,
|
|
90
|
+
requiresServer: false,
|
|
91
|
+
serverFallbackAvailable: Boolean(authToken || env.NOLO_SERVER || env.BASE_URL),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
output.write(`Runtime: ${decision.mode}\n`);
|
|
95
|
+
output.write(`Reason: ${decision.reason}\n`);
|
|
96
|
+
output.write(`LevelDB: ${localProbe.ok ? "ok" : "failed"}\n`);
|
|
97
|
+
output.write(`DB path: ${localProbe.dbPath}\n`);
|
|
98
|
+
if (!localProbe.ok && localProbe.error) {
|
|
99
|
+
output.write(`DB error: ${localProbe.error}\n`);
|
|
100
|
+
}
|
|
101
|
+
if (localProbe.agentKey) {
|
|
102
|
+
output.write(`Agent config: ${localProbe.agentFound ? "found" : "missing"} (${localProbe.agentKey})\n`);
|
|
103
|
+
} else {
|
|
104
|
+
output.write("Agent config: missing (no local agent key)\n");
|
|
105
|
+
}
|
|
106
|
+
output.write(`Provider: ${hasLocalProvider ? "available" : "missing"} (${detectProviderLabel(env)})\n`);
|
|
107
|
+
output.write("Persistence: LevelDB local store\n");
|
|
108
|
+
output.write(`Sync: ${authToken ? "available" : "unavailable"}${authToken ? "" : " (not authenticated)"}\n`);
|
|
109
|
+
output.write(`Server fallback: ${decision.runnable && decision.mode === "server" ? serverUrl : authToken || env.NOLO_SERVER || env.BASE_URL ? serverUrl : "unavailable"}\n`);
|
|
110
|
+
if (decision.missingLocalCapabilities.length > 0) {
|
|
111
|
+
output.write("Missing local capabilities:\n");
|
|
112
|
+
for (const capability of decision.missingLocalCapabilities) {
|
|
113
|
+
output.write(`- ${capability}\n`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return decision.runnable ? 0 : 1;
|
|
118
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createScriptCommand, type CommandEntry } from "./cliCommandTypes";
|
|
2
|
+
|
|
3
|
+
function getDocScriptCommands(): CommandEntry[] {
|
|
4
|
+
return [
|
|
5
|
+
createScriptCommand(["doc", "create"], "createDoc.ts", "Create a normal doc"),
|
|
6
|
+
createScriptCommand(["doc", "read"], "readDoc.ts", "Read a normal doc"),
|
|
7
|
+
createScriptCommand(["doc", "update"], "updateDoc.ts", "Update a normal doc"),
|
|
8
|
+
createScriptCommand(["doc", "delete"], "deleteDoc.ts", "Delete a normal doc"),
|
|
9
|
+
createScriptCommand(["skill-doc", "create"], "createSkillDoc.ts", "Create a skill doc"),
|
|
10
|
+
createScriptCommand(["skill-doc", "read"], "readSkillDoc.ts", "Read a skill doc"),
|
|
11
|
+
createScriptCommand(["skill-doc", "update"], "updateSkillDoc.ts", "Update a skill doc"),
|
|
12
|
+
createScriptCommand(["skill-doc", "delete"], "deleteSkillDoc.ts", "Delete a skill doc"),
|
|
13
|
+
createScriptCommand(["skill", "create-doc"], "createSkillDoc.ts", "Create a skill-backed doc"),
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getSpaceScriptCommands(): CommandEntry[] {
|
|
18
|
+
return [
|
|
19
|
+
createScriptCommand(["dialog", "read"], "readDialog.ts", "Read a dialog"),
|
|
20
|
+
createScriptCommand(["dialog", "status"], "dialogStatus.ts", "Read compact dialog status"),
|
|
21
|
+
createScriptCommand(["space", "list"], "listSpaces.ts", "List joined spaces"),
|
|
22
|
+
createScriptCommand(["space", "read"], "readSpace.ts", "Read a space"),
|
|
23
|
+
createScriptCommand(["space", "delete"], "deleteSpaces.ts", "Delete spaces by safe filters"),
|
|
24
|
+
createScriptCommand(["space", "category"], "upsertSpaceCategory.ts", "Create or update a space category"),
|
|
25
|
+
createScriptCommand(["space", "content-category"], "setSpaceContentCategory.ts", "Move content into a space category"),
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getTableScriptCommands(): CommandEntry[] {
|
|
30
|
+
return [
|
|
31
|
+
createScriptCommand(["table", "add-column"], "tableData.ts", "Add one table column", ["--action", "add-column"]),
|
|
32
|
+
createScriptCommand(["table", "add-row"], "tableData.ts", "Add one table row", ["--action", "add-row"]),
|
|
33
|
+
createScriptCommand(["table", "add-rows"], "tableData.ts", "Add table rows", ["--action", "add-rows"]),
|
|
34
|
+
createScriptCommand(["table", "update-row"], "tableData.ts", "Update one table row", ["--action", "update-row"]),
|
|
35
|
+
createScriptCommand(["table", "update-rows"], "tableData.ts", "Update table rows", ["--action", "update-rows"]),
|
|
36
|
+
createScriptCommand(["table", "delete-row"], "tableData.ts", "Delete one table row", ["--action", "delete-row"]),
|
|
37
|
+
createScriptCommand(["table", "delete-rows"], "tableData.ts", "Delete table rows", ["--action", "delete-rows"]),
|
|
38
|
+
createScriptCommand(["table", "data"], "tableData.ts", "Low-level table row script bridge"),
|
|
39
|
+
createScriptCommand(["table", "meta"], "upsertTableMeta.ts", "Create or update table metadata"),
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getAgentScriptCommands(): CommandEntry[] {
|
|
44
|
+
return [
|
|
45
|
+
createScriptCommand(["agent", "unpublish"], "unpublishAgent.ts", "Remove an agent's public record"),
|
|
46
|
+
createScriptCommand(["agent", "dialogs"], "queryAgentDialogs.ts", "Inspect recent dialogs for an agent"),
|
|
47
|
+
createScriptCommand(["agent", "doctor"], "doctorAgentWorkspace.ts", "Audit agent workspace health"),
|
|
48
|
+
createScriptCommand(["agent", "create-custom"], "createCustomCodingAgent.ts", "Create a custom coding agent"),
|
|
49
|
+
createScriptCommand(["agent", "create-space"], "createSpaceAgents.ts", "Create or attach shared-space agents"),
|
|
50
|
+
createScriptCommand(["agent", "setup-demo"], "setupDemoAgent.ts", "Bootstrap demo publisher agents"),
|
|
51
|
+
createScriptCommand(["agent", "supervise"], "runAutonomousAgent.ts", "Run an agent in autonomous cycles"),
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getRuntimeScriptCommands(): CommandEntry[] {
|
|
56
|
+
return [
|
|
57
|
+
createScriptCommand(["llama"], "llamaServerSupervisor.ts", "Manage the llama.cpp runtime"),
|
|
58
|
+
createScriptCommand(["model-runtime"], "localModelRuntimeSupervisor.ts", "Manage local model runtime processes"),
|
|
59
|
+
createScriptCommand(["dev"], "devControl.ts", "Manage the local dev environment"),
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function getScriptCommandEntries(): CommandEntry[] {
|
|
64
|
+
return [
|
|
65
|
+
...getDocScriptCommands(),
|
|
66
|
+
...getSpaceScriptCommands(),
|
|
67
|
+
...getTableScriptCommands(),
|
|
68
|
+
...getAgentScriptCommands(),
|
|
69
|
+
...getRuntimeScriptCommands(),
|
|
70
|
+
];
|
|
71
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { runLoginCommand, runLogoutCommand, runWhoamiCommand } from "./authCommands";
|
|
2
|
+
import {
|
|
3
|
+
createEntrypointEnvCommand,
|
|
4
|
+
createEnvCommand,
|
|
5
|
+
} from "./cliCommandFactories";
|
|
6
|
+
import { createInternalCommand, type CommandEntry } from "./cliCommandTypes";
|
|
7
|
+
import { withDaemonShortcutArgs } from "./cliCommandDispatch";
|
|
8
|
+
import { DEFAULT_NOLO_SERVER_URL } from "./defaultServer";
|
|
9
|
+
import {
|
|
10
|
+
runMachineConnectCommand,
|
|
11
|
+
runMachineStatusCommand,
|
|
12
|
+
} from "./machineCommands";
|
|
13
|
+
import { runDoctorRuntimeCommand } from "./runtimeDoctorCommands";
|
|
14
|
+
import {
|
|
15
|
+
buildCliDoctorText,
|
|
16
|
+
buildCliVersionText,
|
|
17
|
+
runSelfUpdate,
|
|
18
|
+
} from "./updateCommands";
|
|
19
|
+
|
|
20
|
+
export function getSystemInternalCommandEntries(renderHelpText: () => string): CommandEntry[] {
|
|
21
|
+
return [
|
|
22
|
+
createEnvCommand(["doctor", "runtime"], "Diagnose local-first agent runtime selection", runDoctorRuntimeCommand),
|
|
23
|
+
createInternalCommand(["login"], "Log in to Nolo", (args) => Promise.resolve(runLoginCommand(args))),
|
|
24
|
+
createInternalCommand(["logout"], "Log out of Nolo", async () => runLogoutCommand()),
|
|
25
|
+
createInternalCommand(["whoami"], "Show the current login state", async () => runWhoamiCommand()),
|
|
26
|
+
createEntrypointEnvCommand(["connect"], "Send machine heartbeats or hold a connector websocket", runMachineConnectCommand),
|
|
27
|
+
createInternalCommand(["daemon"], "Run the connector daemon shortcut", (args, ctx) => {
|
|
28
|
+
const normalized = withDaemonShortcutArgs(args, ctx.env);
|
|
29
|
+
return runMachineConnectCommand(["--ws"], {
|
|
30
|
+
env: normalized.envOverride ?? ctx.env,
|
|
31
|
+
cliEntrypointPath: ctx.entrypointPath,
|
|
32
|
+
});
|
|
33
|
+
}),
|
|
34
|
+
createInternalCommand(["machine", "status"], "List machines registered to the current profile", (args, ctx) =>
|
|
35
|
+
runMachineStatusCommand(args, { env: ctx.env })
|
|
36
|
+
),
|
|
37
|
+
createInternalCommand(["doctor"], "Show CLI doctor information", async (_args, ctx) => {
|
|
38
|
+
console.log(
|
|
39
|
+
buildCliDoctorText({
|
|
40
|
+
packageName: ctx.packageInfo.name,
|
|
41
|
+
version: ctx.packageInfo.version,
|
|
42
|
+
entrypoint: ctx.entrypointPath,
|
|
43
|
+
serverUrl: ctx.env.NOLO_SERVER || ctx.env.BASE_URL || DEFAULT_NOLO_SERVER_URL,
|
|
44
|
+
profileName: ctx.env.NOLO_PROFILE || "local",
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
return 0;
|
|
48
|
+
}),
|
|
49
|
+
createInternalCommand(["update"], "Update the CLI", async () => runSelfUpdate()),
|
|
50
|
+
createInternalCommand(["version"], "Show CLI version", async (_args, ctx) => {
|
|
51
|
+
console.log(buildCliVersionText(ctx.packageInfo));
|
|
52
|
+
return 0;
|
|
53
|
+
}),
|
|
54
|
+
createInternalCommand(["--version"], "Show CLI version", async (_args, ctx) => {
|
|
55
|
+
console.log(buildCliVersionText(ctx.packageInfo));
|
|
56
|
+
return 0;
|
|
57
|
+
}),
|
|
58
|
+
createInternalCommand(["-v"], "Show CLI version", async (_args, ctx) => {
|
|
59
|
+
console.log(buildCliVersionText(ctx.packageInfo));
|
|
60
|
+
return 0;
|
|
61
|
+
}),
|
|
62
|
+
createInternalCommand(["--help"], "Show help", async () => {
|
|
63
|
+
console.log(renderHelpText());
|
|
64
|
+
return 0;
|
|
65
|
+
}),
|
|
66
|
+
createInternalCommand(["-h"], "Show help", async () => {
|
|
67
|
+
console.log(renderHelpText());
|
|
68
|
+
return 0;
|
|
69
|
+
}),
|
|
70
|
+
];
|
|
71
|
+
}
|
package/tableCommands.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_NOLO_SERVER_URL } from "./defaultServer";
|
|
2
|
+
import { includeTableActivityColumns } from "./render/table/activityColumns";
|
|
2
3
|
|
|
3
4
|
type EnvLike = Record<string, string | undefined>;
|
|
4
5
|
type OutputLike = { write(chunk: string): unknown };
|
|
@@ -34,10 +35,24 @@ function parseJsonOption<T>(args: string[], flag: string): T | undefined {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
function parseJsonOptionAlias<T>(args: string[], primaryFlag: string, aliasFlag: string): T | undefined {
|
|
39
|
+
const primary = readOption(args, primaryFlag);
|
|
40
|
+
const alias = readOption(args, aliasFlag);
|
|
41
|
+
const raw = primary || alias;
|
|
42
|
+
if (!raw) return undefined;
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(raw) as T;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
const usedFlag = primary ? primaryFlag : aliasFlag;
|
|
47
|
+
throw new Error(`${usedFlag} must be valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
37
51
|
function parseOutputMode(raw: string): OutputMode {
|
|
38
52
|
if (!raw) return "full";
|
|
53
|
+
if (raw === "json") return "raw";
|
|
39
54
|
if (raw === "full" || raw === "raw" || raw === "items" || raw === "jsonl") return raw;
|
|
40
|
-
throw new Error(`--output must be one of full, raw, items, jsonl; got ${raw}`);
|
|
55
|
+
throw new Error(`--output must be one of full, raw, items, json, jsonl; got ${raw}`);
|
|
41
56
|
}
|
|
42
57
|
|
|
43
58
|
function parseTableArg(raw: string): { tenantId?: string; tableId?: string } {
|
|
@@ -94,10 +109,26 @@ function formatOutput(input: { envelope: any; rawData: any; mode: OutputMode }):
|
|
|
94
109
|
return Array.isArray(items) ? items.map((item) => JSON.stringify(item)).join("\n") : JSON.stringify(items);
|
|
95
110
|
}
|
|
96
111
|
|
|
112
|
+
function mergeQueryShortcutFilters(args: string[], filters: Record<string, unknown> | undefined): Record<string, unknown> | undefined {
|
|
113
|
+
const row = readOption(args, "--row") || readOption(args, "--row-id");
|
|
114
|
+
const rowDbKey = readOption(args, "--row-dbkey");
|
|
115
|
+
const shortcutFilters: Record<string, unknown> = {};
|
|
116
|
+
if (row) {
|
|
117
|
+
if (row.startsWith("row-")) shortcutFilters.dbKey = row;
|
|
118
|
+
else shortcutFilters.rowId = row;
|
|
119
|
+
}
|
|
120
|
+
if (rowDbKey) shortcutFilters.dbKey = rowDbKey;
|
|
121
|
+
if (Object.keys(shortcutFilters).length === 0) return filters;
|
|
122
|
+
return {
|
|
123
|
+
...(filters ?? {}),
|
|
124
|
+
...shortcutFilters,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
97
128
|
function usage(): string {
|
|
98
129
|
return [
|
|
99
130
|
"Usage:",
|
|
100
|
-
" nolo table query --table <tableId|metaKey> [--tenant-id <userId>] [--filters <json>] [--columns <json-array>] [--no-base-fields] [--output full|raw|items|jsonl]",
|
|
131
|
+
" nolo table query --table <tableId|metaKey> [--tenant-id <userId>] [--filters <json>|--filter <json>] [--row <rowId|rowDbKey>] [--columns <json-array>] [--include-activity] [--no-base-fields] [--output full|raw|items|json|jsonl]",
|
|
101
132
|
"",
|
|
102
133
|
].join("\n");
|
|
103
134
|
}
|
|
@@ -117,7 +148,10 @@ export async function runTableQueryCommand(args: string[], deps: TableCommandDep
|
|
|
117
148
|
try {
|
|
118
149
|
outputMode = parseOutputMode(readOption(args, "--output"));
|
|
119
150
|
columns = parseJsonOption<string[]>(args, "--columns");
|
|
120
|
-
filters =
|
|
151
|
+
filters = mergeQueryShortcutFilters(
|
|
152
|
+
args,
|
|
153
|
+
parseJsonOptionAlias<Record<string, unknown>>(args, "--filters", "--filter")
|
|
154
|
+
);
|
|
121
155
|
} catch (error) {
|
|
122
156
|
output.write(`[nolo] table query failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
123
157
|
return 1;
|
|
@@ -127,6 +161,7 @@ export async function runTableQueryCommand(args: string[], deps: TableCommandDep
|
|
|
127
161
|
const authToken = resolveAuthToken(args, env);
|
|
128
162
|
const tenantId = readOption(args, "--tenant-id") || tableArg.tenantId || env.USER_ID || parseJwtTenantId(authToken);
|
|
129
163
|
const tableId = tableArg.tableId;
|
|
164
|
+
const hasSingleRowShortcut = Boolean(readOption(args, "--row") || readOption(args, "--row-id") || readOption(args, "--row-dbkey"));
|
|
130
165
|
if (!tenantId || !tableId) {
|
|
131
166
|
output.write(usage());
|
|
132
167
|
return 1;
|
|
@@ -149,9 +184,11 @@ export async function runTableQueryCommand(args: string[], deps: TableCommandDep
|
|
|
149
184
|
tenantId,
|
|
150
185
|
tableId,
|
|
151
186
|
filters: filters ?? {},
|
|
152
|
-
columns,
|
|
187
|
+
columns: hasFlag(args, "--include-activity")
|
|
188
|
+
? includeTableActivityColumns(columns)
|
|
189
|
+
: columns,
|
|
153
190
|
includeBaseFields: !hasFlag(args, "--no-base-fields"),
|
|
154
|
-
limit: Number(readOption(args, "--limit") || 20),
|
|
191
|
+
limit: Number(readOption(args, "--limit") || (hasSingleRowShortcut ? 1 : 20)),
|
|
155
192
|
offset: Number(readOption(args, "--offset") || 0),
|
|
156
193
|
sortBy: readOption(args, "--sort-by") || "updatedAt",
|
|
157
194
|
sortOrder: readOption(args, "--sort-order") === "asc" ? "asc" : "desc",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createEnvCommand } from "./cliCommandFactories";
|
|
2
|
+
import type { CommandEntry } from "./cliCommandTypes";
|
|
3
|
+
import { runTableQueryCommand } from "./tableCommands";
|
|
4
|
+
import { runTaskRunCommand } from "./taskRunCommand";
|
|
5
|
+
|
|
6
|
+
export function getWorkflowInternalCommandEntries(): CommandEntry[] {
|
|
7
|
+
return [
|
|
8
|
+
createEnvCommand(["table", "query"], "Query table rows", runTableQueryCommand),
|
|
9
|
+
createEnvCommand(["task-run"], "Update durable task-run state through the runner bridge", runTaskRunCommand),
|
|
10
|
+
];
|
|
11
|
+
}
|