march-cli 0.1.12 → 0.1.13

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 (32) hide show
  1. package/package.json +1 -1
  2. package/src/agent/command-exec-tool.mjs +42 -8
  3. package/src/agent/runner/runner-utils.mjs +6 -0
  4. package/src/agent/runner.mjs +16 -16
  5. package/src/agent/runtime/ipc/ipc-peer.mjs +99 -0
  6. package/src/agent/runtime/ipc/process-ipc-transport.mjs +16 -0
  7. package/src/agent/runtime/remote-runner-client.mjs +73 -0
  8. package/src/agent/runtime/remote-ui-client.mjs +19 -0
  9. package/src/agent/runtime/runner-ipc-target.mjs +126 -0
  10. package/src/agent/runtime/runner-process-client.mjs +47 -0
  11. package/src/agent/runtime/runner-process-entry.mjs +93 -0
  12. package/src/agent/runtime/ui-event-bridge.mjs +85 -0
  13. package/src/agent/tool-summary.mjs +112 -0
  14. package/src/agent/turn/turn-events.mjs +46 -0
  15. package/src/agent/turn/turn-runner.mjs +2 -1
  16. package/src/cli/commands/copy-command.mjs +16 -2
  17. package/src/cli/commands/status-command.mjs +7 -4
  18. package/src/cli/commands/thinking-command.mjs +10 -3
  19. package/src/cli/repl-loop.mjs +3 -1
  20. package/src/cli/startup/create-runtime-runner.mjs +61 -0
  21. package/src/cli/startup/startup-banner.mjs +64 -10
  22. package/src/cli/tui/layout/main-pane-layout.mjs +16 -7
  23. package/src/cli/tui/selection-screen.mjs +83 -34
  24. package/src/cli/tui/status/status-bar.mjs +154 -18
  25. package/src/cli/tui/tool-rendering.mjs +3 -113
  26. package/src/cli/tui/tui-handlers.mjs +1 -1
  27. package/src/cli/tui/ui-theme.mjs +14 -5
  28. package/src/cli/ui.mjs +1 -1
  29. package/src/context/engine.mjs +10 -9
  30. package/src/context/profiles.mjs +39 -0
  31. package/src/main.mjs +35 -29
  32. package/src/context/center-memory.mjs +0 -14
@@ -0,0 +1,39 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+
5
+ export function defaultProfilePaths() {
6
+ const root = join(homedir(), ".march", "memory", "profiles");
7
+ return {
8
+ agent: join(root, "agent.md"),
9
+ user: join(root, "user.md"),
10
+ };
11
+ }
12
+
13
+ export function ensureProfileFiles(paths = defaultProfilePaths()) {
14
+ for (const [kind, path] of Object.entries(paths)) {
15
+ if (!path || existsSync(path)) continue;
16
+ mkdirSync(dirname(path), { recursive: true });
17
+ writeFileSync(path, defaultProfileContent(kind), "utf8");
18
+ }
19
+ }
20
+
21
+ export function buildProfileLayers(paths) {
22
+ if (!paths) return [];
23
+ return [
24
+ buildProfileLayer("agent_profile", paths.agent),
25
+ buildProfileLayer("user_profile", paths.user),
26
+ ].filter(Boolean);
27
+ }
28
+
29
+ function buildProfileLayer(name, path) {
30
+ if (!path || !existsSync(path)) return null;
31
+ const content = readFileSync(path, "utf8").trimEnd();
32
+ if (!content.trim()) return null;
33
+ return { name, text: `[${name}]\n--- ${path} ---\n${content}` };
34
+ }
35
+
36
+ function defaultProfileContent(kind) {
37
+ const title = kind === "agent" ? "Agent Profile" : "User Profile";
38
+ return `# ${title}\n\n`;
39
+ }
package/src/main.mjs CHANGED
@@ -15,7 +15,7 @@ import { createStatusLineUpdater } from "./cli/status-line-updater.mjs";
15
15
  import { wireTuiHandlers } from "./cli/tui/tui-handlers.mjs";
16
16
  import { createMarchAuthStorage } from "./auth/storage.mjs";
17
17
  import { runLoginCommand } from "./auth/login-command.mjs";
18
- import { createRunner } from "./agent/runner.mjs";
18
+ import { createRuntimeRunner } from "./cli/startup/create-runtime-runner.mjs";
19
19
  import { createCliShellRuntime } from "./shell/cli-runtime.mjs";
20
20
  import { MarkdownMemoryStore } from "./memory/markdown-store.mjs";
21
21
  import { createMarkdownMemoryTools } from "./memory/markdown-tools.mjs";
@@ -23,14 +23,13 @@ import { loadDotEnv } from "./config/dotenv.mjs";
23
23
  import { loadConfig } from "./config/loader.mjs";
24
24
  import { discoverProjectExtensionPaths } from "./extensions/discovery.mjs";
25
25
  import { loadProjectLifecycleHookManifests } from "./extensions/lifecycle-manifest.mjs";
26
- import { resolvePiSessionManager } from "./session/pi-manager.mjs";
27
26
  import { loadOrCreateProjectId, resumeStartupSession } from "./cli/startup/startup-session.mjs";
28
27
  import { formatStartupBanner } from "./cli/startup/startup-banner.mjs";
29
28
  import { initializeMcp } from "./mcp/index.mjs";
30
29
  import { createWebToolsFromConfig } from "./web/tools.mjs";
31
30
  import { createModelContextDumper } from "./debug/model-context-dumper.mjs";
32
31
  import { createLogger, installProcessLogHandlers } from "./debug/logger.mjs";
33
- import { defaultCenterMemoryPath } from "./context/center-memory.mjs";
32
+ import { defaultProfilePaths, ensureProfileFiles } from "./context/profiles.mjs";
34
33
  import { runProviderConfigCommand } from "./provider/config-command.mjs";
35
34
  import { runWebSearchConfigCommand } from "./web/config-command.mjs";
36
35
  import { createDesktopTurnNotifier } from "./notification/desktop-notifier.mjs";
@@ -49,6 +48,7 @@ export async function run(argv) {
49
48
  }
50
49
 
51
50
  const config = loadConfig(cwd);
51
+ const useRuntimeProcess = process.env.MARCH_RUNTIME_PROCESS !== "0";
52
52
  installNetworkEnvironment(config.network);
53
53
  if (args.command?.name === "login") {
54
54
  try {
@@ -103,14 +103,16 @@ export async function run(argv) {
103
103
  const modeState = createModeState();
104
104
  const namespace = loadOrCreateProjectId(projectMarchDir);
105
105
  const memoryRoot = resolveMemoryRoot(config.memoryRoot, stateRoot);
106
- const centerMemoryPath = defaultCenterMemoryPath();
106
+ const profilePaths = defaultProfilePaths();
107
+ ensureProfileFiles(profilePaths);
107
108
  const memoryStore = new MarkdownMemoryStore({ root: memoryRoot });
108
109
  const memoryTools = createMarkdownMemoryTools(memoryStore);
109
110
  const currentProject = basename(cwd);
110
111
  const shellRuntime = args.shellRuntime ? createCliShellRuntime({ cwd }) : null;
111
112
 
112
- // MCP: connect to configured MCP servers
113
- const mcpInit = await initializeMcp({ projectDir: cwd });
113
+ const mcpInit = useRuntimeProcess
114
+ ? { clientManager: null, mcpTools: [], mcpInjections: [], errors: [] }
115
+ : await initializeMcp({ projectDir: cwd });
114
116
  const { clientManager: mcpClientManager, mcpTools, mcpInjections } = mcpInit;
115
117
  for (const { server, error } of mcpInit.errors) {
116
118
  if (args.json) {
@@ -159,17 +161,33 @@ export async function run(argv) {
159
161
  let turnRunning = false;
160
162
  let refreshStatusBar = null;
161
163
 
162
- const runner = await createRunner({
164
+ const runnerOptions = {
163
165
  cwd,
164
166
  modelId: model,
165
167
  provider,
166
168
  serviceTier,
167
-
168
169
  providers: config.providers,
170
+ config,
169
171
  stateRoot,
170
- ui,
171
172
  memoryRoot,
172
- centerMemoryPath,
173
+ profilePaths,
174
+ namespace,
175
+ projectMarchDir,
176
+ extensionPaths,
177
+ permissionMode,
178
+ shellRuntime: Boolean(shellRuntime),
179
+ lifecycleHooks: lifecycleManifests.hooks,
180
+ lifecycleDiagnostics: lifecycleManifests.diagnostics,
181
+ modelContextDumper: {
182
+ enabled: args.dumpContext,
183
+ rootDir: contextDumpRoot,
184
+ },
185
+ };
186
+
187
+ const runner = await createRuntimeRunner({
188
+ useRuntimeProcess,
189
+ runnerOptions,
190
+ ui,
173
191
  memoryStore,
174
192
  memoryTools,
175
193
  shellRuntime,
@@ -177,29 +195,14 @@ export async function run(argv) {
177
195
  mcpInjections,
178
196
  mcpClientManager,
179
197
  webTools,
180
- namespace,
181
- projectMarchDir,
182
- extensionPaths,
183
- sessionManager: resolvePiSessionManager({
184
- cwd,
185
- projectMarchDir,
186
- enabled: usePiSessions,
187
- }),
188
- useRuntimeHost: usePiRuntimeHost,
189
- syncPiSidecar: usePiSessions || usePiRuntimeHost,
190
- lifecycleHooks: lifecycleManifests.hooks,
191
- lifecycleDiagnostics: lifecycleManifests.diagnostics,
198
+ usePiSessions,
199
+ usePiRuntimeHost,
192
200
  authStorage: authConfig.authStorage,
193
- maxTurns: config.maxTurns ?? undefined,
194
- trimBatch: config.trimBatch ?? undefined,
195
- hostedTools: config.hostedTools,
196
201
  permissionController,
197
202
  modelContextDumper,
198
203
  turnNotifier,
199
204
  logger,
200
- onModelPayload: ({ estimatedTokens }) => {
201
- refreshStatusBar?.({ contextTokens: estimatedTokens });
202
- },
205
+ refreshStatusBar: (...args) => refreshStatusBar?.(...args),
203
206
  });
204
207
 
205
208
  refreshStatusBar = createStatusLineUpdater({
@@ -209,7 +212,10 @@ export async function run(argv) {
209
212
  sessionSource,
210
213
  getMode: () => modeState.get(),
211
214
  });
212
- refreshStatusBar();
215
+ const initialContextTokens = typeof runner.estimateContextTokens === "function"
216
+ ? await runner.estimateContextTokens("")
217
+ : null;
218
+ refreshStatusBar(initialContextTokens ? { contextTokens: initialContextTokens } : undefined);
213
219
 
214
220
  wireTuiHandlers({
215
221
  ui,
@@ -1,14 +0,0 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import { homedir } from "node:os";
3
- import { join } from "node:path";
4
-
5
- export function defaultCenterMemoryPath() {
6
- return join(homedir(), ".march", "memory", "center.md");
7
- }
8
-
9
- export function buildCenterMemory(path = defaultCenterMemoryPath()) {
10
- if (!path || !existsSync(path)) return null;
11
- const content = readFileSync(path, "utf8").trimEnd();
12
- if (!content.trim()) return null;
13
- return `[center_memory]\n--- ${path} ---\n${content}`;
14
- }