@stigmer/ink 0.0.88
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/LICENSE +190 -0
- package/app/SessionApp.d.ts +42 -0
- package/app/SessionApp.d.ts.map +1 -0
- package/app/SessionApp.js +38 -0
- package/app/SessionApp.js.map +1 -0
- package/app/SessionView.d.ts +32 -0
- package/app/SessionView.d.ts.map +1 -0
- package/app/SessionView.js +58 -0
- package/app/SessionView.js.map +1 -0
- package/cli/stigmer-ink.d.ts +3 -0
- package/cli/stigmer-ink.d.ts.map +1 -0
- package/cli/stigmer-ink.js +117 -0
- package/cli/stigmer-ink.js.map +1 -0
- package/components/ApprovalPrompt.d.ts +21 -0
- package/components/ApprovalPrompt.d.ts.map +1 -0
- package/components/ApprovalPrompt.js +60 -0
- package/components/ApprovalPrompt.js.map +1 -0
- package/components/ExecutionProgress.d.ts +16 -0
- package/components/ExecutionProgress.d.ts.map +1 -0
- package/components/ExecutionProgress.js +47 -0
- package/components/ExecutionProgress.js.map +1 -0
- package/components/FollowUpInput.d.ts +19 -0
- package/components/FollowUpInput.d.ts.map +1 -0
- package/components/FollowUpInput.js +27 -0
- package/components/FollowUpInput.js.map +1 -0
- package/components/MessageEntry.d.ts +18 -0
- package/components/MessageEntry.d.ts.map +1 -0
- package/components/MessageEntry.js +42 -0
- package/components/MessageEntry.js.map +1 -0
- package/components/MessageThread.d.ts +31 -0
- package/components/MessageThread.d.ts.map +1 -0
- package/components/MessageThread.js +146 -0
- package/components/MessageThread.js.map +1 -0
- package/components/SubAgentBlock.d.ts +19 -0
- package/components/SubAgentBlock.d.ts.map +1 -0
- package/components/SubAgentBlock.js +73 -0
- package/components/SubAgentBlock.js.map +1 -0
- package/components/TodoList.d.ts +17 -0
- package/components/TodoList.d.ts.map +1 -0
- package/components/TodoList.js +43 -0
- package/components/TodoList.js.map +1 -0
- package/components/ToolCallGroup.d.ts +20 -0
- package/components/ToolCallGroup.d.ts.map +1 -0
- package/components/ToolCallGroup.js +51 -0
- package/components/ToolCallGroup.js.map +1 -0
- package/components/ToolCallItem.d.ts +14 -0
- package/components/ToolCallItem.d.ts.map +1 -0
- package/components/ToolCallItem.js +33 -0
- package/components/ToolCallItem.js.map +1 -0
- package/components/UsageWidget.d.ts +16 -0
- package/components/UsageWidget.d.ts.map +1 -0
- package/components/UsageWidget.js +18 -0
- package/components/UsageWidget.js.map +1 -0
- package/index.d.ts +16 -0
- package/index.d.ts.map +1 -0
- package/index.js +21 -0
- package/index.js.map +1 -0
- package/markdown.d.ts +21 -0
- package/markdown.d.ts.map +1 -0
- package/markdown.js +44 -0
- package/markdown.js.map +1 -0
- package/package.json +48 -0
- package/provider.d.ts +46 -0
- package/provider.d.ts.map +1 -0
- package/provider.js +33 -0
- package/provider.js.map +1 -0
- package/src/__tests__/components.test.tsx +162 -0
- package/src/__tests__/markdown.test.ts +46 -0
- package/src/app/SessionApp.tsx +74 -0
- package/src/app/SessionView.tsx +164 -0
- package/src/cli/stigmer-ink.tsx +148 -0
- package/src/components/ApprovalPrompt.tsx +139 -0
- package/src/components/ExecutionProgress.tsx +75 -0
- package/src/components/FollowUpInput.tsx +70 -0
- package/src/components/MessageEntry.tsx +80 -0
- package/src/components/MessageThread.tsx +264 -0
- package/src/components/SubAgentBlock.tsx +146 -0
- package/src/components/TodoList.tsx +75 -0
- package/src/components/ToolCallGroup.tsx +92 -0
- package/src/components/ToolCallItem.tsx +74 -0
- package/src/components/UsageWidget.tsx +35 -0
- package/src/index.ts +28 -0
- package/src/markdown.ts +48 -0
- package/src/provider.tsx +62 -0
- package/src/types/marked-terminal.d.ts +19 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import type { ToolCall } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
4
|
+
import { ToolCallStatus } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
5
|
+
|
|
6
|
+
/** Props for {@link ToolCallItem}. */
|
|
7
|
+
export interface ToolCallItemProps {
|
|
8
|
+
/** The tool call to render. */
|
|
9
|
+
readonly toolCall: ToolCall;
|
|
10
|
+
/** Whether to show the full args/result (expanded view). */
|
|
11
|
+
readonly expanded?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const STATUS_INDICATOR: Record<number, { symbol: string; color?: string }> = {
|
|
15
|
+
[ToolCallStatus.TOOL_CALL_RUNNING]: { symbol: "⠋", color: "yellow" },
|
|
16
|
+
[ToolCallStatus.TOOL_CALL_COMPLETED]: { symbol: "✓", color: "green" },
|
|
17
|
+
[ToolCallStatus.TOOL_CALL_FAILED]: { symbol: "✗", color: "red" },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Renders a single tool call with a status indicator, name, and
|
|
22
|
+
* optional expanded args/result preview.
|
|
23
|
+
*/
|
|
24
|
+
export function ToolCallItem({ toolCall, expanded = false }: ToolCallItemProps) {
|
|
25
|
+
const indicator = STATUS_INDICATOR[toolCall.status] ?? {
|
|
26
|
+
symbol: "○",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const serverSlug = toolCall.mcpServerSlug;
|
|
30
|
+
const label = serverSlug
|
|
31
|
+
? `${serverSlug}/${toolCall.name}`
|
|
32
|
+
: toolCall.name;
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Box flexDirection="column">
|
|
36
|
+
<Box gap={1}>
|
|
37
|
+
<Text color={indicator.color}>{indicator.symbol}</Text>
|
|
38
|
+
<Text>{label}</Text>
|
|
39
|
+
{toolCall.status === ToolCallStatus.TOOL_CALL_RUNNING && (
|
|
40
|
+
<Text dimColor>running</Text>
|
|
41
|
+
)}
|
|
42
|
+
</Box>
|
|
43
|
+
{expanded && toolCall.argsPreview && (
|
|
44
|
+
<Box paddingLeft={3}>
|
|
45
|
+
<Text dimColor wrap="truncate-end">
|
|
46
|
+
{toolCall.argsPreview}
|
|
47
|
+
</Text>
|
|
48
|
+
</Box>
|
|
49
|
+
)}
|
|
50
|
+
{expanded &&
|
|
51
|
+
toolCall.status === ToolCallStatus.TOOL_CALL_COMPLETED &&
|
|
52
|
+
toolCall.result && (
|
|
53
|
+
<Box paddingLeft={3}>
|
|
54
|
+
<Text dimColor wrap="truncate-end">
|
|
55
|
+
{truncateResult(toolCall.result)}
|
|
56
|
+
</Text>
|
|
57
|
+
</Box>
|
|
58
|
+
)}
|
|
59
|
+
{expanded &&
|
|
60
|
+
toolCall.status === ToolCallStatus.TOOL_CALL_FAILED &&
|
|
61
|
+
toolCall.error && (
|
|
62
|
+
<Box paddingLeft={3}>
|
|
63
|
+
<Text color="red">{toolCall.error}</Text>
|
|
64
|
+
</Box>
|
|
65
|
+
)}
|
|
66
|
+
</Box>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function truncateResult(result: string, maxLines = 5): string {
|
|
71
|
+
const lines = result.split("\n");
|
|
72
|
+
if (lines.length <= maxLines) return result;
|
|
73
|
+
return lines.slice(0, maxLines).join("\n") + `\n... (${lines.length - maxLines} more lines)`;
|
|
74
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
4
|
+
import { useSessionUsage, formatCost, formatTokenCount } from "@stigmer/react";
|
|
5
|
+
|
|
6
|
+
/** Props for {@link UsageWidget}. */
|
|
7
|
+
export interface UsageWidgetProps {
|
|
8
|
+
/** All executions for the current session (completed + active). */
|
|
9
|
+
readonly executions: readonly AgentExecution[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Compact terminal widget showing session-level token usage and cost.
|
|
14
|
+
*
|
|
15
|
+
* Aggregates per-message `LlmCallMetrics` across all executions
|
|
16
|
+
* in the session. Renders nothing when no usage data is available.
|
|
17
|
+
*
|
|
18
|
+
* Uses the headless {@link useSessionUsage} hook from `@stigmer/react`.
|
|
19
|
+
*/
|
|
20
|
+
export function UsageWidget({ executions }: UsageWidgetProps) {
|
|
21
|
+
const usage = useSessionUsage(executions);
|
|
22
|
+
|
|
23
|
+
if (!usage.hasUsage) return null;
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Box paddingLeft={1} gap={1}>
|
|
27
|
+
<Text dimColor>
|
|
28
|
+
{formatCost(usage.totalCostUsd)} · {formatTokenCount(usage.totalTokens)}{" "}
|
|
29
|
+
tokens · {usage.llmCallCount}{" "}
|
|
30
|
+
{usage.llmCallCount === 1 ? "call" : "calls"}
|
|
31
|
+
{usage.primaryModel ? ` · ${usage.primaryModel}` : ""}
|
|
32
|
+
</Text>
|
|
33
|
+
</Box>
|
|
34
|
+
);
|
|
35
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Provider
|
|
2
|
+
export { InkStigmerProvider, type InkStigmerProviderProps } from "./provider.js";
|
|
3
|
+
|
|
4
|
+
// Transport (re-exported from @stigmer/sdk/node)
|
|
5
|
+
export {
|
|
6
|
+
createNodeClient,
|
|
7
|
+
createNodeTransport,
|
|
8
|
+
type NodeClientConfig,
|
|
9
|
+
} from "@stigmer/sdk/node";
|
|
10
|
+
|
|
11
|
+
// Markdown
|
|
12
|
+
export { renderMarkdown } from "./markdown.js";
|
|
13
|
+
|
|
14
|
+
// Components
|
|
15
|
+
export { MessageEntry, type MessageEntryProps } from "./components/MessageEntry.js";
|
|
16
|
+
export { MessageThread, type MessageThreadProps } from "./components/MessageThread.js";
|
|
17
|
+
export { ToolCallItem, type ToolCallItemProps } from "./components/ToolCallItem.js";
|
|
18
|
+
export { ToolCallGroup, type ToolCallGroupProps } from "./components/ToolCallGroup.js";
|
|
19
|
+
export { SubAgentBlock, type SubAgentBlockProps } from "./components/SubAgentBlock.js";
|
|
20
|
+
export { TodoList, type TodoListProps } from "./components/TodoList.js";
|
|
21
|
+
export { ApprovalPrompt, type ApprovalPromptProps } from "./components/ApprovalPrompt.js";
|
|
22
|
+
export { ExecutionProgress, type ExecutionProgressProps } from "./components/ExecutionProgress.js";
|
|
23
|
+
export { FollowUpInput, type FollowUpInputProps } from "./components/FollowUpInput.js";
|
|
24
|
+
export { UsageWidget, type UsageWidgetProps } from "./components/UsageWidget.js";
|
|
25
|
+
|
|
26
|
+
// Composed views
|
|
27
|
+
export { SessionView, type SessionViewProps } from "./app/SessionView.js";
|
|
28
|
+
export { SessionApp, type SessionAppProps } from "./app/SessionApp.js";
|
package/src/markdown.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Marked } from "marked";
|
|
2
|
+
import { markedTerminal } from "marked-terminal";
|
|
3
|
+
|
|
4
|
+
let _marked: Marked | null = null;
|
|
5
|
+
|
|
6
|
+
function getMarked(width?: number): Marked {
|
|
7
|
+
if (_marked && !width) return _marked;
|
|
8
|
+
|
|
9
|
+
const instance = new Marked();
|
|
10
|
+
instance.use(
|
|
11
|
+
markedTerminal({
|
|
12
|
+
width: width ?? process.stdout.columns ?? 80,
|
|
13
|
+
reflowText: true,
|
|
14
|
+
showSectionPrefix: false,
|
|
15
|
+
}),
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
if (!width) _marked = instance;
|
|
19
|
+
return instance;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Render a markdown string to ANSI-styled terminal output.
|
|
24
|
+
*
|
|
25
|
+
* Uses `marked` with `marked-terminal` to produce styled text suitable
|
|
26
|
+
* for display in a terminal. Supports headings, code blocks (with syntax
|
|
27
|
+
* highlighting), lists, bold/italic, links, tables, and blockquotes.
|
|
28
|
+
*
|
|
29
|
+
* @param content - Raw markdown string.
|
|
30
|
+
* @param width - Terminal width for text wrapping. Defaults to `process.stdout.columns` or 80.
|
|
31
|
+
* @returns ANSI-styled string ready for terminal output.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { renderMarkdown } from "@stigmer/ink";
|
|
36
|
+
*
|
|
37
|
+
* const ansi = renderMarkdown("**Hello** from the agent!");
|
|
38
|
+
* process.stdout.write(ansi);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function renderMarkdown(content: string, width?: number): string {
|
|
42
|
+
const marked = getMarked(width);
|
|
43
|
+
const result = marked.parse(content);
|
|
44
|
+
if (typeof result !== "string") {
|
|
45
|
+
return content;
|
|
46
|
+
}
|
|
47
|
+
return result.trimEnd();
|
|
48
|
+
}
|
package/src/provider.tsx
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React, { type ReactNode } from "react";
|
|
2
|
+
import { StigmerContext, DeploymentModeContext } from "@stigmer/react";
|
|
3
|
+
import type { Stigmer, DeploymentMode } from "@stigmer/sdk";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Props for {@link InkStigmerProvider}.
|
|
7
|
+
*/
|
|
8
|
+
export interface InkStigmerProviderProps {
|
|
9
|
+
/** Pre-configured Stigmer client (use {@link createNodeClient} to create one). */
|
|
10
|
+
client: Stigmer;
|
|
11
|
+
|
|
12
|
+
/** Child components to render. */
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Deployment mode for feature gating.
|
|
17
|
+
* - `"cloud"`: All features available (default).
|
|
18
|
+
* - `"local"`: OSS feature subset only.
|
|
19
|
+
*/
|
|
20
|
+
deploymentMode?: DeploymentMode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Stigmer provider for Ink (terminal) environments.
|
|
25
|
+
*
|
|
26
|
+
* Provides the same React contexts as `StigmerProvider` from
|
|
27
|
+
* `@stigmer/react`, but without the DOM `<div>` wrapper used for
|
|
28
|
+
* CSS scoping (which is not applicable in a terminal).
|
|
29
|
+
*
|
|
30
|
+
* All hooks from `@stigmer/react` (`useStigmer`, `useSessionConversation`,
|
|
31
|
+
* `useExecutionStream`, etc.) work identically under this provider.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* import { render } from "ink";
|
|
36
|
+
* import { InkStigmerProvider, createNodeClient } from "@stigmer/ink";
|
|
37
|
+
*
|
|
38
|
+
* const client = createNodeClient({
|
|
39
|
+
* baseUrl: "https://api.stigmer.ai",
|
|
40
|
+
* apiKey: process.env.STIGMER_API_KEY,
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* render(
|
|
44
|
+
* <InkStigmerProvider client={client}>
|
|
45
|
+
* <MyTerminalApp />
|
|
46
|
+
* </InkStigmerProvider>
|
|
47
|
+
* );
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function InkStigmerProvider({
|
|
51
|
+
client,
|
|
52
|
+
children,
|
|
53
|
+
deploymentMode = "cloud",
|
|
54
|
+
}: InkStigmerProviderProps) {
|
|
55
|
+
return (
|
|
56
|
+
<StigmerContext.Provider value={client}>
|
|
57
|
+
<DeploymentModeContext.Provider value={deploymentMode}>
|
|
58
|
+
{children}
|
|
59
|
+
</DeploymentModeContext.Provider>
|
|
60
|
+
</StigmerContext.Provider>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare module "marked-terminal" {
|
|
2
|
+
import type { MarkedExtension } from "marked";
|
|
3
|
+
|
|
4
|
+
interface MarkedTerminalOptions {
|
|
5
|
+
width?: number;
|
|
6
|
+
reflowText?: boolean;
|
|
7
|
+
showSectionPrefix?: boolean;
|
|
8
|
+
tab?: number;
|
|
9
|
+
unescape?: boolean;
|
|
10
|
+
emoji?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function markedTerminal(
|
|
14
|
+
options?: MarkedTerminalOptions,
|
|
15
|
+
highlightOptions?: Record<string, unknown>,
|
|
16
|
+
): MarkedExtension;
|
|
17
|
+
|
|
18
|
+
export default class Renderer {}
|
|
19
|
+
}
|