umbrella-context 0.1.2 → 0.1.32

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 (68) hide show
  1. package/bin/um.js +2 -0
  2. package/dist/adapters/byterover-context-runtime-store.d.ts +15 -0
  3. package/dist/adapters/byterover-context-runtime-store.js +57 -0
  4. package/dist/adapters/byterover-runtime-bridge.d.ts +218 -0
  5. package/dist/adapters/byterover-runtime-bridge.js +343 -0
  6. package/dist/adapters/byterover-transport-task-store.d.ts +13 -0
  7. package/dist/adapters/byterover-transport-task-store.js +50 -0
  8. package/dist/adapters/umbrella-onboarding.d.ts +27 -0
  9. package/dist/adapters/umbrella-onboarding.js +79 -0
  10. package/dist/adapters/umbrella-provider-runtime.d.ts +38 -0
  11. package/dist/adapters/umbrella-provider-runtime.js +199 -0
  12. package/dist/adapters/vendor-byterover.d.ts +4 -0
  13. package/dist/adapters/vendor-byterover.js +19 -0
  14. package/dist/commands/activity.d.ts +2 -0
  15. package/dist/commands/activity.js +82 -0
  16. package/dist/commands/bridge.d.ts +2 -0
  17. package/dist/commands/bridge.js +40 -0
  18. package/dist/commands/catalog.d.ts +34 -0
  19. package/dist/commands/catalog.js +234 -0
  20. package/dist/commands/connect.js +14 -14
  21. package/dist/commands/connectors.d.ts +24 -0
  22. package/dist/commands/connectors.js +626 -0
  23. package/dist/commands/curate.d.ts +1 -0
  24. package/dist/commands/curate.js +48 -3
  25. package/dist/commands/debug.d.ts +2 -0
  26. package/dist/commands/debug.js +55 -0
  27. package/dist/commands/fix.js +54 -0
  28. package/dist/commands/hub.d.ts +22 -0
  29. package/dist/commands/hub.js +487 -0
  30. package/dist/commands/interactive.d.ts +2 -0
  31. package/dist/commands/interactive.js +970 -62
  32. package/dist/commands/locations.d.ts +1 -0
  33. package/dist/commands/locations.js +15 -12
  34. package/dist/commands/logout.d.ts +2 -0
  35. package/dist/commands/logout.js +34 -0
  36. package/dist/commands/model.d.ts +11 -0
  37. package/dist/commands/model.js +225 -0
  38. package/dist/commands/providers.d.ts +17 -0
  39. package/dist/commands/providers.js +379 -0
  40. package/dist/commands/pull.js +60 -1
  41. package/dist/commands/push.js +62 -2
  42. package/dist/commands/reset.d.ts +2 -0
  43. package/dist/commands/reset.js +35 -0
  44. package/dist/commands/restart.d.ts +2 -0
  45. package/dist/commands/restart.js +21 -0
  46. package/dist/commands/search.js +65 -1
  47. package/dist/commands/session.d.ts +2 -0
  48. package/dist/commands/session.js +241 -0
  49. package/dist/commands/setup.js +58 -56
  50. package/dist/commands/space.d.ts +12 -0
  51. package/dist/commands/space.js +138 -42
  52. package/dist/commands/status.d.ts +29 -0
  53. package/dist/commands/status.js +120 -19
  54. package/dist/commands/tasks.d.ts +2 -0
  55. package/dist/commands/tasks.js +95 -0
  56. package/dist/commands/transport.d.ts +2 -0
  57. package/dist/commands/transport.js +88 -0
  58. package/dist/commands/tree.d.ts +2 -0
  59. package/dist/commands/tree.js +98 -0
  60. package/dist/commands/tui.d.ts +2 -0
  61. package/dist/commands/tui.js +1273 -0
  62. package/dist/config.d.ts +23 -0
  63. package/dist/config.js +69 -0
  64. package/dist/index.js +41 -5
  65. package/dist/repo-state.d.ts +227 -1
  66. package/dist/repo-state.js +920 -4
  67. package/dist/umbrella.js +29 -5
  68. package/package.json +11 -3
@@ -1,52 +1,57 @@
1
1
  import chalk from "chalk";
2
2
  import prompts from "prompts";
3
3
  import { configManager } from "../config.js";
4
- import { ensureRepoContext } from "../repo-state.js";
5
- import { getCliSetup, getCompanyContextSummary, toContextSpaces } from "../umbrella.js";
6
- export function spaceCommand(cli) {
7
- cli
8
- .command("space <action> [space]", "List or switch context spaces for the current company")
9
- .action(async (action, spaceArg) => {
10
- const config = configManager.config;
11
- if (!config) {
12
- console.log(chalk.red("Not configured. Run: umbrella-context setup"));
13
- return;
14
- }
15
- if (!config.umbrellaUrl) {
16
- console.log(chalk.red("No Umbrella URL saved for this device. Run umbrella-context setup to enable space commands."));
17
- return;
18
- }
19
- const normalizedAction = action.toLowerCase();
20
- const summary = await getCompanyContextSummary(config.umbrellaUrl, config.companyId);
21
- const spaces = toContextSpaces(summary);
22
- if (normalizedAction === "list") {
23
- console.log(chalk.bold(`\n Spaces for ${config.companyName}\n`));
24
- spaces.forEach((entry, index) => {
25
- const active = entry.id === config.projectId ? " (active)" : "";
26
- const primary = entry.isPrimary ? " [core]" : "";
27
- console.log(` ${index + 1}. ${entry.name}${primary}${active}`);
28
- });
29
- return;
30
- }
31
- if (normalizedAction !== "switch") {
32
- console.log(chalk.red("Use either 'umbrella-context space list' or 'umbrella-context space switch'."));
33
- return;
34
- }
35
- let chosen = spaces.find((entry) => entry.id === spaceArg || entry.name.toLowerCase() === (spaceArg ?? "").toLowerCase()) ?? null;
36
- if (!chosen) {
4
+ import { ensureRepoContext, recordSessionEvent, setSessionPanel } from "../repo-state.js";
5
+ import { pullCommandAction } from "./pull.js";
6
+ import { createContextSpace, getCliSetup, getCompanyContextSummary, toContextSpaces } from "../umbrella.js";
7
+ export async function spaceCommandAction(action, spaceArg) {
8
+ const config = configManager.config;
9
+ if (!config) {
10
+ console.log(chalk.red("Not configured. Run: umbrella-context setup"));
11
+ return;
12
+ }
13
+ if (!config.umbrellaUrl) {
14
+ console.log(chalk.red("No Umbrella URL saved for this device. Run umbrella-context setup to enable space commands."));
15
+ return;
16
+ }
17
+ const normalizedAction = action.toLowerCase();
18
+ const summary = await getCompanyContextSummary(config.umbrellaUrl, config.companyId);
19
+ const spaces = toContextSpaces(summary);
20
+ if (normalizedAction === "list") {
21
+ await setSessionPanel("space", "list");
22
+ console.log(chalk.bold(`\n Spaces for ${config.companyName}\n`));
23
+ spaces.forEach((entry, index) => {
24
+ const active = entry.id === config.projectId ? " (active)" : "";
25
+ const primary = entry.isPrimary ? " [core]" : "";
26
+ console.log(` ${index + 1}. ${entry.name}${primary}${active}`);
27
+ });
28
+ return {
29
+ action: "list",
30
+ changed: false,
31
+ companyName: config.companyName,
32
+ currentSpaceName: config.projectName,
33
+ spaces,
34
+ };
35
+ }
36
+ if (normalizedAction === "create") {
37
+ let nextName = spaceArg?.trim() ?? "";
38
+ if (!nextName) {
37
39
  const answer = await prompts({
38
- type: "select",
40
+ type: "text",
39
41
  name: "value",
40
- message: "Choose a context space",
41
- choices: spaces.map((entry) => ({
42
- title: entry.isPrimary ? `${entry.name} (core)` : entry.name,
43
- value: entry.id,
44
- })),
42
+ message: `Name the new space for ${config.companyName}`,
45
43
  });
46
- chosen = spaces.find((entry) => entry.id === answer.value) ?? null;
44
+ nextName = answer.value?.trim() ?? "";
47
45
  }
46
+ if (!nextName) {
47
+ console.log(chalk.yellow("\n No space name provided."));
48
+ return;
49
+ }
50
+ const created = await createContextSpace(config.umbrellaUrl, config.companyId, nextName);
51
+ const createdSpaces = toContextSpaces(created);
52
+ const chosen = createdSpaces.find((entry) => entry.id === created.activeProjectId) ?? null;
48
53
  if (!chosen) {
49
- console.log(chalk.yellow("\n No space selected."));
54
+ console.log(chalk.red("\n The new space was created, but the CLI could not find it in the returned summary."));
50
55
  return;
51
56
  }
52
57
  const setup = await getCliSetup(config.umbrellaUrl, config.companyId, chosen.id);
@@ -70,6 +75,97 @@ export function spaceCommand(cli) {
70
75
  updatedAt: new Date().toISOString(),
71
76
  });
72
77
  await ensureRepoContext(configManager.config);
73
- console.log(chalk.green(`\n Switched to ${setup.companyName} / ${setup.activeSpaceName}`));
78
+ await setSessionPanel("space", setup.activeSpaceName);
79
+ await recordSessionEvent({
80
+ kind: "space",
81
+ title: `Created and switched to ${setup.activeSpaceName}`,
82
+ detail: `The repo is now linked to the new ${setup.companyName} space ${setup.activeSpaceName}.`,
83
+ panel: "space",
84
+ focus: setup.activeSpaceName,
85
+ status: "success",
86
+ });
87
+ console.log(chalk.green(`\n Created and switched to ${setup.companyName} / ${setup.activeSpaceName}`));
88
+ console.log(chalk.gray(" Pulling the latest shared Context snapshot for this space..."));
89
+ await pullCommandAction();
90
+ return {
91
+ action: "create",
92
+ changed: true,
93
+ companyName: setup.companyName,
94
+ currentSpaceName: setup.activeSpaceName,
95
+ spaces: createdSpaces,
96
+ };
97
+ }
98
+ if (normalizedAction !== "switch") {
99
+ console.log(chalk.red("Use: umbrella-context space list | switch | create"));
100
+ return;
101
+ }
102
+ let chosen = spaces.find((entry) => entry.id === spaceArg || entry.name.toLowerCase() === (spaceArg ?? "").toLowerCase()) ?? null;
103
+ if (!chosen) {
104
+ const answer = await prompts({
105
+ type: "select",
106
+ name: "value",
107
+ message: "Choose a context space",
108
+ choices: spaces.map((entry) => ({
109
+ title: entry.isPrimary ? `${entry.name} (core)` : entry.name,
110
+ value: entry.id,
111
+ })),
112
+ });
113
+ chosen = spaces.find((entry) => entry.id === answer.value) ?? null;
114
+ }
115
+ if (!chosen) {
116
+ console.log(chalk.yellow("\n No space selected."));
117
+ return;
118
+ }
119
+ const setup = await getCliSetup(config.umbrellaUrl, config.companyId, chosen.id);
120
+ configManager.set({
121
+ umbrellaUrl: config.umbrellaUrl,
122
+ serverUrl: setup.baseUrl,
123
+ apiKey: setup.apiKey,
124
+ companyId: setup.companyId,
125
+ companyName: setup.companyName,
126
+ workspaceId: setup.workspaceId,
127
+ workspaceName: setup.workspaceName,
128
+ projectId: setup.activeSpaceId,
129
+ projectName: setup.activeSpaceName,
130
+ });
131
+ configManager.upsertLocation({
132
+ repoRoot: process.cwd(),
133
+ companyId: setup.companyId,
134
+ companyName: setup.companyName,
135
+ projectId: setup.activeSpaceId,
136
+ projectName: setup.activeSpaceName,
137
+ updatedAt: new Date().toISOString(),
138
+ });
139
+ await ensureRepoContext(configManager.config);
140
+ await setSessionPanel("space", setup.activeSpaceName);
141
+ await recordSessionEvent({
142
+ kind: "space",
143
+ title: `Switched repo to ${setup.activeSpaceName}`,
144
+ detail: `The active Context space for ${setup.companyName} is now ${setup.activeSpaceName}.`,
145
+ panel: "space",
146
+ focus: setup.activeSpaceName,
147
+ status: "success",
148
+ });
149
+ console.log(chalk.green(`\n Switched to ${setup.companyName} / ${setup.activeSpaceName}`));
150
+ console.log(chalk.gray(" Pulling the latest shared Context snapshot for this space..."));
151
+ await pullCommandAction();
152
+ return {
153
+ action: "switch",
154
+ changed: true,
155
+ companyName: setup.companyName,
156
+ currentSpaceName: setup.activeSpaceName,
157
+ spaces,
158
+ };
159
+ }
160
+ export function spaceCommand(cli) {
161
+ cli
162
+ .command("space <action> [space]", "List, switch, or create context spaces for the current company")
163
+ .action(async (action, spaceArg) => {
164
+ try {
165
+ await spaceCommandAction(action, spaceArg);
166
+ }
167
+ catch (err) {
168
+ console.log(chalk.red(`Could not load spaces: ${err.message}`));
169
+ }
74
170
  });
75
171
  }
@@ -1,2 +1,31 @@
1
+ export type StatusSnapshot = {
2
+ companyName: string;
3
+ spaceName: string;
4
+ umbrellaUrl: string | null;
5
+ serverUrl: string;
6
+ currentDirectory: string;
7
+ repoRoot: string;
8
+ umDir: string;
9
+ pendingCount: number;
10
+ pulledContextCount: number;
11
+ pulledFixCount: number;
12
+ lastPushAt: string;
13
+ lastPullAt: string;
14
+ hubEntriesCount: number;
15
+ connectorsCount: number;
16
+ mcpConfigured: boolean;
17
+ latestConnectorRun: string;
18
+ providerLabel: string;
19
+ modelLabel: string;
20
+ currentPanel: string;
21
+ currentFocus: string;
22
+ latestEvent: string;
23
+ transportStatus: string;
24
+ transportQueue: number;
25
+ transportActiveTask: string;
26
+ contextTreeSummary: string;
27
+ nextSteps: string[];
28
+ };
29
+ export declare function getStatusSnapshot(): Promise<StatusSnapshot>;
1
30
  export declare function statusCommandAction(): Promise<void>;
2
31
  export declare function statusCommand(cli: any): void;
@@ -1,29 +1,130 @@
1
1
  import chalk from "chalk";
2
+ import { promises as fs } from "fs";
3
+ import path from "path";
2
4
  import { configManager } from "../config.js";
3
- import { getPendingMemories, getPulledFixes, getPulledMemories, getRepoContext } from "../repo-state.js";
4
- export async function statusCommandAction() {
5
+ import { getConnectorRuns, getContextTreeState, getInstalledConnectors, getInstalledHubEntries, getPendingMemories, getPulledFixes, getPulledMemories, getRepoContext, ensureSessionState, getTransportState, } from "../repo-state.js";
6
+ export async function getStatusSnapshot() {
5
7
  const config = configManager.config;
6
8
  if (!config) {
7
- console.log(chalk.red("Not configured. Run: umbrella-context setup"));
8
- return;
9
+ throw new Error("Not configured. Run: umbrella-context setup");
9
10
  }
10
11
  const { repoRoot, state, umDir } = await getRepoContext();
11
- const pending = await getPendingMemories();
12
- const pulledMemories = await getPulledMemories();
13
- const pulledFixes = await getPulledFixes();
12
+ const session = await ensureSessionState();
13
+ const latestEvent = session.events?.[0] ?? null;
14
+ const [pending, pulledMemories, pulledFixes, connectors, hubEntries, connectorRuns, transport, contextTree] = await Promise.all([
15
+ getPendingMemories(),
16
+ getPulledMemories(),
17
+ getPulledFixes(),
18
+ getInstalledConnectors(),
19
+ getInstalledHubEntries(),
20
+ getConnectorRuns(),
21
+ getTransportState(),
22
+ getContextTreeState(),
23
+ ]);
24
+ const activeProvider = configManager.providers.find((entry) => entry.id === config.activeProvider) ?? null;
25
+ const latestConnectorRun = connectorRuns[0] ?? null;
26
+ let mcpConfigured = false;
27
+ try {
28
+ const repoMcp = JSON.parse(await fs.readFile(path.join(repoRoot, ".mcp.json"), "utf8"));
29
+ mcpConfigured = Boolean(repoMcp?.mcpServers?.["umbrella-context"]);
30
+ }
31
+ catch {
32
+ mcpConfigured = false;
33
+ }
34
+ const nextSteps = [];
35
+ if (pending.length > 0)
36
+ nextSteps.push(`Run "umbrella-context push" to share ${pending.length} local draft${pending.length === 1 ? "" : "s"}.`);
37
+ if (!activeProvider || !config.activeModel) {
38
+ nextSteps.push('Finish runtime setup with "umbrella-context providers setup".');
39
+ }
40
+ if (!mcpConfigured)
41
+ nextSteps.push('Install the MCP bridge with "umbrella-context connectors install codex-mcp".');
42
+ if (connectors.length === 0)
43
+ nextSteps.push('Add a first repo connector with "umbrella-context connectors install".');
44
+ if (hubEntries.length === 0)
45
+ nextSteps.push('Browse reusable bundles with "umbrella-context hub list".');
46
+ return {
47
+ companyName: config.companyName,
48
+ spaceName: config.projectName,
49
+ umbrellaUrl: config.umbrellaUrl ?? null,
50
+ serverUrl: config.serverUrl,
51
+ currentDirectory: process.cwd(),
52
+ repoRoot,
53
+ umDir,
54
+ pendingCount: pending.length,
55
+ pulledContextCount: pulledMemories.length,
56
+ pulledFixCount: pulledFixes.length,
57
+ lastPushAt: state?.lastPushAt ?? "Never",
58
+ lastPullAt: state?.lastPullAt ?? "Never",
59
+ hubEntriesCount: hubEntries.length,
60
+ connectorsCount: connectors.length,
61
+ mcpConfigured,
62
+ latestConnectorRun: latestConnectorRun
63
+ ? `${latestConnectorRun.connectorName} (${latestConnectorRun.status}) at ${latestConnectorRun.ranAt}`
64
+ : "Never",
65
+ providerLabel: activeProvider ? `${activeProvider.name} (${activeProvider.kind})` : "Not connected",
66
+ modelLabel: config.activeModel ?? "Not selected",
67
+ currentPanel: session.currentPanel ?? "Home",
68
+ currentFocus: session.currentFocus ?? "None",
69
+ latestEvent: latestEvent ? `${latestEvent.title} (${latestEvent.status})` : "No session events yet",
70
+ transportStatus: transport?.status ?? "unknown",
71
+ transportQueue: transport?.queue.length ?? 0,
72
+ transportActiveTask: transport?.activeTaskId ?? "None",
73
+ contextTreeSummary: contextTree?.summaryHandle ?? "No context tree summary yet",
74
+ nextSteps,
75
+ };
76
+ }
77
+ export async function statusCommandAction() {
78
+ let snapshot;
79
+ try {
80
+ snapshot = await getStatusSnapshot();
81
+ }
82
+ catch (err) {
83
+ console.log(chalk.red(err.message));
84
+ return;
85
+ }
14
86
  console.log(chalk.bold("\n Umbrella Context Status\n"));
15
- console.log(` Company: ${config.companyName}`);
16
- console.log(` Space: ${config.projectName}`);
17
- console.log(` Umbrella: ${config.umbrellaUrl ?? "Not saved"}`);
18
- console.log(` Server: ${config.serverUrl}`);
19
- console.log(` Current Directory: ${process.cwd()}`);
20
- console.log(` Repo Root: ${repoRoot}`);
21
- console.log(` Local Context Folder: ${umDir}`);
22
- console.log(` Pending Local Context: ${pending.length}`);
23
- console.log(` Pulled Context Snapshot: ${pulledMemories.length}`);
24
- console.log(` Pulled Known Fixes: ${pulledFixes.length}`);
25
- console.log(` Last Push: ${state?.lastPushAt ?? "Never"}`);
26
- console.log(` Last Pull: ${state?.lastPullAt ?? "Never"}`);
87
+ console.log(chalk.cyan(" Connection"));
88
+ console.log(` Company: ${snapshot.companyName}`);
89
+ console.log(` Space: ${snapshot.spaceName}`);
90
+ console.log(` Umbrella: ${snapshot.umbrellaUrl ?? "Not saved"}`);
91
+ console.log(` Context Backend: ${snapshot.serverUrl}`);
92
+ console.log("");
93
+ console.log(chalk.cyan(" Local Repo"));
94
+ console.log(` Current Directory: ${snapshot.currentDirectory}`);
95
+ console.log(` Repo Root: ${snapshot.repoRoot}`);
96
+ console.log(` Local Context Folder: ${snapshot.umDir}`);
97
+ console.log(` Pending Local Context: ${snapshot.pendingCount}`);
98
+ console.log(` Pulled Context Snapshot: ${snapshot.pulledContextCount}`);
99
+ console.log(` Pulled Known Fixes: ${snapshot.pulledFixCount}`);
100
+ console.log(` Last Push: ${snapshot.lastPushAt}`);
101
+ console.log(` Last Pull: ${snapshot.lastPullAt}`);
102
+ console.log("");
103
+ console.log(chalk.cyan(" Repo Ecosystem"));
104
+ console.log(` Hub Entries Installed: ${snapshot.hubEntriesCount}`);
105
+ console.log(` Connectors Installed: ${snapshot.connectorsCount}`);
106
+ console.log(` Repo MCP Wired: ${snapshot.mcpConfigured ? "Yes" : "No"}`);
107
+ console.log(` Last Connector Run: ${snapshot.latestConnectorRun}`);
108
+ console.log("");
109
+ console.log(chalk.cyan(" Model Runtime"));
110
+ console.log(` Provider: ${snapshot.providerLabel}`);
111
+ console.log(` Model: ${snapshot.modelLabel}`);
112
+ console.log(` Session Panel: ${snapshot.currentPanel}`);
113
+ console.log(` Session Focus: ${snapshot.currentFocus}`);
114
+ console.log(` Latest Session Event: ${snapshot.latestEvent}`);
115
+ console.log(` Transport Status: ${snapshot.transportStatus}`);
116
+ console.log(` Transport Queue: ${snapshot.transportQueue}`);
117
+ console.log(` Active Task: ${snapshot.transportActiveTask}`);
118
+ console.log("");
119
+ console.log(chalk.cyan(" Context Tree"));
120
+ console.log(` Summary: ${snapshot.contextTreeSummary}`);
121
+ if (snapshot.nextSteps.length > 0) {
122
+ console.log("");
123
+ console.log(chalk.cyan(" Suggested Next Steps"));
124
+ snapshot.nextSteps.forEach((step) => {
125
+ console.log(` - ${step}`);
126
+ });
127
+ }
27
128
  }
28
129
  export function statusCommand(cli) {
29
130
  cli.command("status", "Show the current repo, company, space, and local sync state").action(async () => {
@@ -0,0 +1,2 @@
1
+ export declare function tasksCommandAction(action?: string, target?: string): Promise<void>;
2
+ export declare function tasksCommand(cli: any): void;
@@ -0,0 +1,95 @@
1
+ import chalk from "chalk";
2
+ import { getTaskById, getTasks, getTransportState, setSessionPanel } from "../repo-state.js";
3
+ export async function tasksCommandAction(action, target) {
4
+ await setSessionPanel("tasks", action === "inspect" ? target ?? "inspect" : "list");
5
+ const [tasks, transport] = await Promise.all([getTasks(), getTransportState()]);
6
+ if ((action ?? "list") === "inspect") {
7
+ const defaultTask = (transport?.activeTaskId ? await getTaskById(transport.activeTaskId) : null) ??
8
+ tasks[0] ??
9
+ null;
10
+ const task = target ? await getTaskById(target) : defaultTask;
11
+ if (!task) {
12
+ console.log(chalk.yellow("\n No task found to inspect."));
13
+ return;
14
+ }
15
+ console.log(chalk.bold(`\n Task ${task.id}\n`));
16
+ console.log(` Kind: ${task.kind}`);
17
+ console.log(` Title: ${task.title}`);
18
+ console.log(` Status: ${task.status}`);
19
+ console.log(` Created: ${new Date(task.createdAt).toLocaleString()}`);
20
+ console.log(` Started: ${task.startedAt ? new Date(task.startedAt).toLocaleString() : "Not started"}`);
21
+ console.log(` Finished: ${task.finishedAt ? new Date(task.finishedAt).toLocaleString() : "Not finished"}`);
22
+ console.log(` Focus: ${task.focus ?? "None"}`);
23
+ console.log(` Panel: ${task.panel ?? "None"}`);
24
+ console.log(` Session: ${task.sessionId ?? "None"}`);
25
+ console.log(` Result: ${task.result ?? "No final result yet"}`);
26
+ console.log(` Reasoning items: ${task.reasoningContents?.length ?? 0}`);
27
+ console.log(` Tool calls: ${task.toolCalls?.length ?? 0}`);
28
+ if (task.detail) {
29
+ console.log("");
30
+ console.log(chalk.cyan(" Detail"));
31
+ console.log(` ${task.detail}`);
32
+ }
33
+ if (task.streamingContent) {
34
+ console.log("");
35
+ console.log(chalk.cyan(" Streaming"));
36
+ console.log(` ${task.streamingContent}`);
37
+ }
38
+ if ((task.reasoningContents?.length ?? 0) > 0) {
39
+ console.log("");
40
+ console.log(chalk.cyan(" Reasoning"));
41
+ task.reasoningContents?.forEach((item, index) => {
42
+ console.log(` ${index + 1}. ${item.content}`);
43
+ console.log(chalk.gray(` ${new Date(item.timestamp).toLocaleString()}${item.isThinking ? " | thinking" : ""}`));
44
+ });
45
+ }
46
+ if ((task.toolCalls?.length ?? 0) > 0) {
47
+ console.log("");
48
+ console.log(chalk.cyan(" Tool Calls"));
49
+ task.toolCalls?.forEach((call, index) => {
50
+ console.log(` ${index + 1}. ${call.toolName} (${call.status})`);
51
+ console.log(chalk.gray(` ${new Date(call.timestamp).toLocaleString()}`));
52
+ console.log(chalk.gray(` args: ${JSON.stringify(call.args)}`));
53
+ if (call.result !== undefined) {
54
+ console.log(chalk.gray(` result: ${JSON.stringify(call.result)}`));
55
+ }
56
+ if (call.error) {
57
+ console.log(chalk.red(` error: ${call.error}`));
58
+ }
59
+ });
60
+ }
61
+ return;
62
+ }
63
+ console.log(chalk.bold("\n Local Context Tasks\n"));
64
+ if (transport) {
65
+ console.log(chalk.cyan(" Transport"));
66
+ console.log(` Status: ${transport.status}`);
67
+ console.log(` Active task: ${transport.activeTaskId ?? "None"}`);
68
+ console.log(` Queue: ${transport.queue.length}`);
69
+ console.log(` Stats: queued=${transport.stats.queued} running=${transport.stats.running} completed=${transport.stats.completed} failed=${transport.stats.failed}`);
70
+ console.log("");
71
+ }
72
+ if (tasks.length === 0) {
73
+ console.log(chalk.yellow(" No local tasks yet."));
74
+ console.log(chalk.gray(" Ask a question, save a local note, or run push/pull to create task history."));
75
+ return;
76
+ }
77
+ tasks.slice(0, 20).forEach((task, index) => {
78
+ console.log(` ${index + 1}. [${task.kind}] ${task.title}`);
79
+ console.log(chalk.gray(` Status: ${task.status} | Updated: ${new Date(task.updatedAt).toLocaleString()}`));
80
+ if (task.detail) {
81
+ console.log(chalk.gray(` ${task.detail}`));
82
+ }
83
+ if (task.result) {
84
+ console.log(chalk.gray(` Result: ${task.result}`));
85
+ }
86
+ if (task.toolCalls?.length) {
87
+ console.log(chalk.gray(` Tool calls: ${task.toolCalls.length}`));
88
+ }
89
+ });
90
+ }
91
+ export function tasksCommand(cli) {
92
+ cli.command("tasks [action] [target]", "Show or inspect the local .um task history for this repo").action(async (action, target) => {
93
+ await tasksCommandAction(action, target);
94
+ });
95
+ }
@@ -0,0 +1,2 @@
1
+ export declare function transportCommandAction(action?: string, target?: string): Promise<void>;
2
+ export declare function transportCommand(cli: any): void;
@@ -0,0 +1,88 @@
1
+ import chalk from "chalk";
2
+ import { getTaskById, getTransportState, setSessionPanel } from "../repo-state.js";
3
+ export async function transportCommandAction(action, target) {
4
+ const transport = await getTransportState();
5
+ const mode = (action ?? "status").toLowerCase();
6
+ await setSessionPanel("transport", mode === "inspect" ? target ?? "inspect" : mode);
7
+ if (mode === "events" || mode === "timeline") {
8
+ console.log(chalk.bold("\n Transport Timeline\n"));
9
+ if (transport.events.length === 0) {
10
+ console.log(chalk.yellow(" No transport events recorded yet."));
11
+ return;
12
+ }
13
+ transport.events.slice(0, 20).forEach((event, index) => {
14
+ console.log(` ${index + 1}. [${event.kind}] ${event.title}`);
15
+ console.log(chalk.gray(` ${new Date(event.at).toLocaleString()} | ${event.status}`));
16
+ if (event.detail) {
17
+ console.log(chalk.gray(` ${event.detail}`));
18
+ }
19
+ });
20
+ return;
21
+ }
22
+ if (mode === "inspect") {
23
+ const taskId = target ?? transport.activeTaskId ?? transport.queue[0]?.id ?? null;
24
+ if (!taskId) {
25
+ console.log(chalk.yellow("\n No transport-linked task is available to inspect."));
26
+ return;
27
+ }
28
+ const task = await getTaskById(taskId);
29
+ if (!task) {
30
+ console.log(chalk.yellow(`\n Task ${taskId} is no longer available in local task history.`));
31
+ return;
32
+ }
33
+ const relatedEvents = transport.events.filter((event) => event.taskId === taskId);
34
+ console.log(chalk.bold(`\n Transport Inspect for ${task.title}\n`));
35
+ console.log(` Task ID: ${task.id}`);
36
+ console.log(` Status: ${task.status}`);
37
+ console.log(` Kind: ${task.kind}`);
38
+ console.log(` Queue position: ${Math.max(transport.queue.findIndex((item) => item.id === taskId), 0) + 1}`);
39
+ console.log(` Related events: ${relatedEvents.length}`);
40
+ if (relatedEvents.length > 0) {
41
+ console.log("");
42
+ console.log(chalk.cyan(" Event Timeline"));
43
+ relatedEvents.forEach((event, index) => {
44
+ console.log(` ${index + 1}. [${event.kind}] ${event.title}`);
45
+ console.log(chalk.gray(` ${new Date(event.at).toLocaleString()} | ${event.status}`));
46
+ if (event.detail) {
47
+ console.log(chalk.gray(` ${event.detail}`));
48
+ }
49
+ });
50
+ }
51
+ return;
52
+ }
53
+ console.log(chalk.bold("\n Transport Engine\n"));
54
+ console.log(` Status: ${transport.status}`);
55
+ console.log(` Active task: ${transport.activeTaskId ?? "None"}`);
56
+ console.log(` Queue: ${transport.queue.length}`);
57
+ console.log(` Stats: queued=${transport.stats.queued} running=${transport.stats.running} completed=${transport.stats.completed} failed=${transport.stats.failed}`);
58
+ console.log(` Subscriptions: ${transport.subscriptions.join(", ")}`);
59
+ console.log(` Last push: ${transport.lastPushAt ?? "Never"}`);
60
+ console.log(` Last pull: ${transport.lastPullAt ?? "Never"}`);
61
+ console.log(` Last runtime check: ${transport.lastRuntimeCheckAt ?? "Never"}`);
62
+ if (Object.keys(transport.taskKinds ?? {}).length > 0) {
63
+ console.log(` Task kinds: ${Object.entries(transport.taskKinds)
64
+ .map(([kind, count]) => `${kind}=${count}`)
65
+ .join(", ")}`);
66
+ }
67
+ console.log("");
68
+ if (transport.queue.length > 0) {
69
+ console.log(chalk.cyan(" Queue"));
70
+ transport.queue.forEach((task, index) => {
71
+ console.log(` ${index + 1}. [${task.kind}] ${task.title} (${task.status})`);
72
+ });
73
+ console.log("");
74
+ }
75
+ if (transport.events.length > 0) {
76
+ console.log(chalk.cyan(" Recent events"));
77
+ transport.events.slice(0, 8).forEach((event, index) => {
78
+ console.log(` ${index + 1}. [${event.kind}] ${event.title}`);
79
+ });
80
+ }
81
+ }
82
+ export function transportCommand(cli) {
83
+ cli
84
+ .command("transport [action] [target]", "Show the live local transport engine and timeline")
85
+ .action(async (action, target) => {
86
+ await transportCommandAction(action, target);
87
+ });
88
+ }
@@ -0,0 +1,2 @@
1
+ export declare function treeCommandAction(action?: string): Promise<void>;
2
+ export declare function treeCommand(cli: any): void;