@smartledger.technology/openai-claw 0.1.0

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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/dist/agent.js +262 -0
  4. package/dist/agent.js.map +1 -0
  5. package/dist/autopr/index.js +127 -0
  6. package/dist/autopr/index.js.map +1 -0
  7. package/dist/client.js +199 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/commands/index.js +624 -0
  10. package/dist/commands/index.js.map +1 -0
  11. package/dist/config.js +71 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/cost.js +97 -0
  14. package/dist/cost.js.map +1 -0
  15. package/dist/eval/cli.js +32 -0
  16. package/dist/eval/cli.js.map +1 -0
  17. package/dist/eval/index.js +134 -0
  18. package/dist/eval/index.js.map +1 -0
  19. package/dist/hooks/index.js +69 -0
  20. package/dist/hooks/index.js.map +1 -0
  21. package/dist/index.js +246 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/input.js +96 -0
  24. package/dist/input.js.map +1 -0
  25. package/dist/mcp/index.js +135 -0
  26. package/dist/mcp/index.js.map +1 -0
  27. package/dist/memory/compaction.js +70 -0
  28. package/dist/memory/compaction.js.map +1 -0
  29. package/dist/memory/index.js +56 -0
  30. package/dist/memory/index.js.map +1 -0
  31. package/dist/notifications/index.js +80 -0
  32. package/dist/notifications/index.js.map +1 -0
  33. package/dist/permissions/index.js +104 -0
  34. package/dist/permissions/index.js.map +1 -0
  35. package/dist/planmode.js +12 -0
  36. package/dist/planmode.js.map +1 -0
  37. package/dist/plugins/index.js +239 -0
  38. package/dist/plugins/index.js.map +1 -0
  39. package/dist/prompts/system.js +148 -0
  40. package/dist/prompts/system.js.map +1 -0
  41. package/dist/rag/index.js +158 -0
  42. package/dist/rag/index.js.map +1 -0
  43. package/dist/self-review/index.js +157 -0
  44. package/dist/self-review/index.js.map +1 -0
  45. package/dist/session.js +113 -0
  46. package/dist/session.js.map +1 -0
  47. package/dist/skills/index.js +39 -0
  48. package/dist/skills/index.js.map +1 -0
  49. package/dist/subagent.js +128 -0
  50. package/dist/subagent.js.map +1 -0
  51. package/dist/subagents/index.js +61 -0
  52. package/dist/subagents/index.js.map +1 -0
  53. package/dist/tools/bash.js +94 -0
  54. package/dist/tools/bash.js.map +1 -0
  55. package/dist/tools/edit.js +64 -0
  56. package/dist/tools/edit.js.map +1 -0
  57. package/dist/tools/glob.js +34 -0
  58. package/dist/tools/glob.js.map +1 -0
  59. package/dist/tools/grep.js +87 -0
  60. package/dist/tools/grep.js.map +1 -0
  61. package/dist/tools/index.js +44 -0
  62. package/dist/tools/index.js.map +1 -0
  63. package/dist/tools/ls.js +39 -0
  64. package/dist/tools/ls.js.map +1 -0
  65. package/dist/tools/read.js +126 -0
  66. package/dist/tools/read.js.map +1 -0
  67. package/dist/tools/semantic.js +40 -0
  68. package/dist/tools/semantic.js.map +1 -0
  69. package/dist/tools/shell.js +131 -0
  70. package/dist/tools/shell.js.map +1 -0
  71. package/dist/tools/task.js +91 -0
  72. package/dist/tools/task.js.map +1 -0
  73. package/dist/tools/todo.js +64 -0
  74. package/dist/tools/todo.js.map +1 -0
  75. package/dist/tools/types.js +7 -0
  76. package/dist/tools/types.js.map +1 -0
  77. package/dist/tools/webfetch.js +62 -0
  78. package/dist/tools/webfetch.js.map +1 -0
  79. package/dist/tools/websearch.js +82 -0
  80. package/dist/tools/websearch.js.map +1 -0
  81. package/dist/tools/write.js +39 -0
  82. package/dist/tools/write.js.map +1 -0
  83. package/dist/ui/repl.js +203 -0
  84. package/dist/ui/repl.js.map +1 -0
  85. package/dist/ui/tui/App.js +234 -0
  86. package/dist/ui/tui/App.js.map +1 -0
  87. package/dist/ui/tui/Diff.js +38 -0
  88. package/dist/ui/tui/Diff.js.map +1 -0
  89. package/dist/ui/tui/MessageView.js +50 -0
  90. package/dist/ui/tui/MessageView.js.map +1 -0
  91. package/dist/ui/tui/PermissionPrompt.js +47 -0
  92. package/dist/ui/tui/PermissionPrompt.js.map +1 -0
  93. package/dist/ui/tui/SlashSuggest.js +36 -0
  94. package/dist/ui/tui/SlashSuggest.js.map +1 -0
  95. package/dist/ui/tui/StatusBar.js +31 -0
  96. package/dist/ui/tui/StatusBar.js.map +1 -0
  97. package/dist/ui/tui/highlight.js +66 -0
  98. package/dist/ui/tui/highlight.js.map +1 -0
  99. package/dist/ui/tui/index.js +12 -0
  100. package/dist/ui/tui/index.js.map +1 -0
  101. package/dist/ui/tui/markdown.js +46 -0
  102. package/dist/ui/tui/markdown.js.map +1 -0
  103. package/dist/ui/tui/types.js +2 -0
  104. package/dist/ui/tui/types.js.map +1 -0
  105. package/dist/web/index.js +195 -0
  106. package/dist/web/index.js.map +1 -0
  107. package/package.json +79 -0
@@ -0,0 +1,36 @@
1
+ import React from "react";
2
+ import { Box, Text } from "ink";
3
+ import { builtinCommands } from "../../commands/index.js";
4
+ import { listSkills } from "../../skills/index.js";
5
+ export function SlashSuggest({ input, config }) {
6
+ if (!input.startsWith("/"))
7
+ return null;
8
+ const query = input.slice(1).toLowerCase();
9
+ const builtin = builtinCommands.map((c) => ({ name: c.name, desc: c.description }));
10
+ const skills = listSkills(config).map((s) => ({ name: s.name, desc: s.description }));
11
+ const all = [...builtin, ...skills];
12
+ const matches = (query === "" ? all : all.filter((c) => c.name.toLowerCase().startsWith(query))).slice(0, 8);
13
+ if (matches.length === 0)
14
+ return null;
15
+ return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, marginTop: 1 },
16
+ React.createElement(Text, { dimColor: true }, "commands (Tab to complete first match)"),
17
+ matches.map((m) => (React.createElement(Text, { key: m.name },
18
+ React.createElement(Text, { color: "cyan" },
19
+ "/",
20
+ m.name),
21
+ " ",
22
+ React.createElement(Text, { dimColor: true }, m.desc))))));
23
+ }
24
+ export function firstMatch(input, config) {
25
+ if (!input.startsWith("/"))
26
+ return null;
27
+ const query = input.slice(1).toLowerCase();
28
+ if (query === "")
29
+ return null;
30
+ const all = [
31
+ ...builtinCommands.map((c) => c.name),
32
+ ...listSkills(config).map((s) => s.name),
33
+ ];
34
+ return all.find((n) => n.toLowerCase().startsWith(query)) ?? null;
35
+ }
36
+ //# sourceMappingURL=SlashSuggest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlashSuggest.js","sourceRoot":"","sources":["../../../src/ui/tui/SlashSuggest.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,MAAM,UAAU,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAyC;IACnF,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACpF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACtF,MAAM,GAAG,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7G,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAC,OAAO,EAAC,WAAW,EAAC,MAAM,EAAC,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC;QAC1F,oBAAC,IAAI,IAAC,QAAQ,mDAA8C;QAC3D,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAClB,oBAAC,IAAI,IAAC,GAAG,EAAE,CAAC,CAAC,IAAI;YACf,oBAAC,IAAI,IAAC,KAAK,EAAC,MAAM;;gBAAG,CAAC,CAAC,IAAI,CAAQ;YAAC,GAAG;YACvC,oBAAC,IAAI,IAAC,QAAQ,UAAE,CAAC,CAAC,IAAI,CAAQ,CACzB,CACR,CAAC,CACE,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,MAAkB;IAC1D,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,GAAG,GAAG;QACV,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACrC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;KACzC,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC;AACpE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import path from "node:path";
3
+ import { Box, Text } from "ink";
4
+ import Spinner from "ink-spinner";
5
+ export function StatusBar({ config, busy, totalTokens, totalCostUSD, }) {
6
+ const cost = totalCostUSD > 0 ? ` $${totalCostUSD.toFixed(4)}` : "";
7
+ const wd = shortWorkdir(config.workdir);
8
+ return (React.createElement(Box, { marginTop: 1 },
9
+ React.createElement(Text, { dimColor: true },
10
+ busy ? React.createElement(Spinner, { type: "dots" }) : "●",
11
+ " ",
12
+ React.createElement(Text, { bold: true, color: "cyan" }, "openai-claw"),
13
+ " ",
14
+ React.createElement(Text, { dimColor: true },
15
+ "model=",
16
+ config.model,
17
+ " mode=",
18
+ config.permissionMode,
19
+ " wd=",
20
+ wd,
21
+ " tokens=",
22
+ totalTokens,
23
+ cost))));
24
+ }
25
+ function shortWorkdir(p) {
26
+ const parts = p.split(path.sep).filter(Boolean);
27
+ if (parts.length <= 2)
28
+ return p;
29
+ return `…/${parts.slice(-2).join("/")}`;
30
+ }
31
+ //# sourceMappingURL=StatusBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/ui/tui/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,OAAO,MAAM,aAAa,CAAC;AAGlC,MAAM,UAAU,SAAS,CAAC,EACxB,MAAM,EACN,IAAI,EACJ,WAAW,EACX,YAAY,GAMb;IACC,MAAM,IAAI,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,OAAO,CACL,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC;QACf,oBAAC,IAAI,IAAC,QAAQ;YACX,IAAI,CAAC,CAAC,CAAC,oBAAC,OAAO,IAAC,IAAI,EAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG;YAAE,GAAG;YAC1C,oBAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,MAAM,kBAAmB;YAAC,GAAG;YAC9C,oBAAC,IAAI,IAAC,QAAQ;;gBAAQ,MAAM,CAAC,KAAK;;gBAAQ,MAAM,CAAC,cAAc;;gBAAM,EAAE;;gBAAU,WAAW;gBAAE,IAAI,CAAQ,CACrG,CACH,CACP,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,OAAO,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { highlight, supportsLanguage } from "cli-highlight";
2
+ /**
3
+ * Heuristic syntax-highlight for tool outputs.
4
+ * - For Read tool: detect language from the file extension in the line-number block.
5
+ * - For others: return content unchanged.
6
+ */
7
+ export function highlightToolOutput(tool, content) {
8
+ if (tool !== "Read")
9
+ return content;
10
+ // Strip the leading " 1\t" line-number column produced by read.ts.
11
+ const lines = content.split("\n");
12
+ const stripped = [];
13
+ let hasNumbers = false;
14
+ for (const line of lines) {
15
+ const m = line.match(/^\s*\d+\t(.*)$/);
16
+ if (m) {
17
+ stripped.push(m[1]);
18
+ hasNumbers = true;
19
+ }
20
+ else {
21
+ stripped.push(line);
22
+ }
23
+ }
24
+ if (!hasNumbers)
25
+ return content;
26
+ // We don't know the language reliably from the content; default to typescript if it
27
+ // looks like code, else return uncolored.
28
+ const code = stripped.join("\n");
29
+ const lang = guessLanguage(code);
30
+ try {
31
+ const colored = highlight(code, { language: lang, ignoreIllegals: true });
32
+ // Re-attach line numbers from the original.
33
+ const out = [];
34
+ const colLines = colored.split("\n");
35
+ for (let i = 0; i < lines.length; i++) {
36
+ const m = lines[i].match(/^(\s*\d+\t)/);
37
+ if (m)
38
+ out.push(m[1] + (colLines[i] ?? ""));
39
+ else
40
+ out.push(lines[i]);
41
+ }
42
+ return out.join("\n");
43
+ }
44
+ catch {
45
+ return content;
46
+ }
47
+ }
48
+ function guessLanguage(code) {
49
+ if (/^\s*(import|export|function|const|let|class|interface|type)\b/m.test(code)) {
50
+ if (/\binterface\b|\btype\b\s*\w+\s*=/.test(code))
51
+ return "typescript";
52
+ return "javascript";
53
+ }
54
+ if (/^\s*(def|class|import|from)\b/m.test(code))
55
+ return "python";
56
+ if (/^\s*#include\b/m.test(code))
57
+ return "cpp";
58
+ if (/^\s*package\b/m.test(code))
59
+ return "go";
60
+ if (/^\s*\{[\s\S]*\}\s*$/.test(code) && /"\w+"\s*:/.test(code))
61
+ return "json";
62
+ if (/^\s*<[a-z!?]/i.test(code))
63
+ return "xml";
64
+ return supportsLanguage("plaintext") ? "plaintext" : "text";
65
+ }
66
+ //# sourceMappingURL=highlight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlight.js","sourceRoot":"","sources":["../../../src/ui/tui/highlight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import { render } from "ink";
3
+ import { HookRunner } from "../../hooks/index.js";
4
+ import { App } from "./App.js";
5
+ export async function startTui(opts) {
6
+ const hooks = new HookRunner(opts.config);
7
+ await hooks.run("SessionStart", { workdir: opts.config.workdir });
8
+ const ink = render(React.createElement(App, { agent: opts.agent, config: opts.config, permissions: opts.permissions, hooks: hooks }));
9
+ await ink.waitUntilExit();
10
+ await hooks.run("SessionEnd", {});
11
+ }
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/tui/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAI7B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAI9B;IACC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,MAAM,CAChB,oBAAC,GAAG,IAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,GAAI,CAC7F,CAAC;IACF,MAAM,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,MAAM,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { marked } from "marked";
2
+ import { markedTerminal } from "marked-terminal";
3
+ let configured = false;
4
+ function configure() {
5
+ if (configured)
6
+ return;
7
+ marked.use(markedTerminal({ width: process.stdout.columns ?? 100 }));
8
+ configured = true;
9
+ }
10
+ /**
11
+ * Render markdown to ANSI-styled text. Ink's <Text> will display ANSI codes
12
+ * directly. We trim trailing newlines so the box doesn't have a giant gap.
13
+ */
14
+ export function renderMarkdown(md) {
15
+ if (!md)
16
+ return "";
17
+ configure();
18
+ try {
19
+ const out = marked.parse(md);
20
+ return out.trimEnd();
21
+ }
22
+ catch {
23
+ return md;
24
+ }
25
+ }
26
+ /**
27
+ * Render a partial markdown stream. If the buffer contains an unmatched ``` we
28
+ * render everything before the open fence as full markdown, and append the
29
+ * still-open code block as raw text (no styling) so we don't fight marked over
30
+ * unfinished syntax. This keeps prose visually polished as it streams in while
31
+ * keeping in-progress code blocks legible.
32
+ */
33
+ export function renderStreamingMarkdown(md) {
34
+ if (!md)
35
+ return "";
36
+ const fenceMatches = md.match(/```/g) ?? [];
37
+ if (fenceMatches.length % 2 === 0) {
38
+ // All fences closed — safe to render as full markdown.
39
+ return renderMarkdown(md);
40
+ }
41
+ const openIdx = md.lastIndexOf("```");
42
+ const before = md.slice(0, openIdx);
43
+ const open = md.slice(openIdx);
44
+ return `${renderMarkdown(before)}\n${open}`;
45
+ }
46
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../../src/ui/tui/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,IAAI,UAAU,GAAG,KAAK,CAAC;AACvB,SAAS,SAAS;IAChB,IAAI,UAAU;QAAE,OAAO;IACvB,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,EAAE,CAAQ,CAAC,CAAC;IAC5E,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACnB,SAAS,EAAE,CAAC;IACZ,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAW,CAAC;QACvC,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAU;IAChD,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACnB,MAAM,YAAY,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC5C,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,uDAAuD;QACvD,OAAO,cAAc,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IACD,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/ui/tui/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,195 @@
1
+ import http from "node:http";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import chalk from "chalk";
5
+ import { listSessions, loadSession } from "../session.js";
6
+ import { readCostLog, costByDay, costByModel } from "../cost.js";
7
+ const INDEX_HTML = `<!doctype html>
8
+ <html lang="en"><head>
9
+ <meta charset="utf-8">
10
+ <title>openai-claw dashboard</title>
11
+ <style>
12
+ body { font: 14px/1.4 -apple-system, system-ui, Segoe UI, sans-serif; margin: 0; background: #0e1116; color: #d6deeb; }
13
+ header { padding: 12px 20px; border-bottom: 1px solid #1f242c; background: #161a22; display: flex; gap: 16px; align-items: center; }
14
+ header h1 { font-size: 16px; margin: 0; color: #82aaff; }
15
+ header span { color: #5c6773; font-size: 12px; }
16
+ nav { padding: 12px 20px; border-bottom: 1px solid #1f242c; display: flex; gap: 8px; }
17
+ nav button { background: #161a22; color: #d6deeb; border: 1px solid #2a313c; padding: 6px 12px; border-radius: 4px; cursor: pointer; font: inherit; }
18
+ nav button.active { background: #2a313c; }
19
+ main { padding: 20px; }
20
+ table { border-collapse: collapse; width: 100%; font-size: 13px; }
21
+ th, td { text-align: left; padding: 6px 10px; border-bottom: 1px solid #1f242c; }
22
+ th { color: #82aaff; font-weight: 600; }
23
+ tr:hover { background: #161a22; }
24
+ .num { font-variant-numeric: tabular-nums; text-align: right; }
25
+ .dim { color: #5c6773; }
26
+ pre.session { background: #161a22; padding: 12px; border-radius: 4px; max-height: 60vh; overflow: auto; white-space: pre-wrap; word-break: break-word; }
27
+ .card { background: #161a22; border: 1px solid #1f242c; padding: 12px 16px; border-radius: 4px; min-width: 200px; }
28
+ .row { display: flex; gap: 12px; flex-wrap: wrap; }
29
+ .big { font-size: 22px; color: #c3e88d; }
30
+ </style>
31
+ </head><body>
32
+ <header>
33
+ <h1>openai-claw</h1>
34
+ <span id="workdir"></span>
35
+ <span class="dim" id="updated"></span>
36
+ </header>
37
+ <nav>
38
+ <button id="tab-overview" class="active">Overview</button>
39
+ <button id="tab-sessions">Sessions</button>
40
+ <button id="tab-cost">Cost</button>
41
+ <button id="tab-evals">Evals</button>
42
+ </nav>
43
+ <main id="main"></main>
44
+ <script>
45
+ (async function () {
46
+ const $ = (sel) => document.querySelector(sel);
47
+ const main = $("#main");
48
+ const tabs = ["overview", "sessions", "cost", "evals"];
49
+ function setActive(t) {
50
+ for (const x of tabs) $("#tab-" + x).classList.toggle("active", x === t);
51
+ render(t);
52
+ }
53
+ for (const t of tabs) $("#tab-" + t).addEventListener("click", () => setActive(t));
54
+
55
+ async function fetchJSON(url) { const r = await fetch(url); return r.json(); }
56
+
57
+ const meta = await fetchJSON("/api/meta");
58
+ $("#workdir").textContent = meta.workdir;
59
+ $("#updated").textContent = new Date().toLocaleString();
60
+
61
+ async function render(t) {
62
+ if (t === "overview") return renderOverview();
63
+ if (t === "sessions") return renderSessions();
64
+ if (t === "cost") return renderCost();
65
+ if (t === "evals") return renderEvals();
66
+ }
67
+
68
+ async function renderOverview() {
69
+ const [sessions, cost, evals] = await Promise.all([
70
+ fetchJSON("/api/sessions"),
71
+ fetchJSON("/api/cost"),
72
+ fetchJSON("/api/evals"),
73
+ ]);
74
+ const totalUSD = (cost.entries || []).reduce((s, e) => s + e.costUSD, 0);
75
+ const totalTokens = (cost.entries || []).reduce((s, e) => s + e.prompt_tokens + e.completion_tokens, 0);
76
+ const cached = (cost.entries || []).reduce((s, e) => s + e.cached_tokens, 0);
77
+ const cachePct = totalTokens > 0 ? (cached / totalTokens * 100).toFixed(0) + "%" : "—";
78
+ const passRate = evals && evals.cases > 0 ? Math.round(100 * evals.passed / evals.cases) + "%" : "—";
79
+ main.innerHTML = \`
80
+ <div class="row">
81
+ <div class="card"><div class="dim">Sessions</div><div class="big">\${sessions.length}</div></div>
82
+ <div class="card"><div class="dim">Total cost</div><div class="big">$\${totalUSD.toFixed(4)}</div></div>
83
+ <div class="card"><div class="dim">Cache hit rate</div><div class="big">\${cachePct}</div></div>
84
+ <div class="card"><div class="dim">Eval pass rate</div><div class="big">\${passRate}</div></div>
85
+ </div>\`;
86
+ }
87
+
88
+ async function renderSessions() {
89
+ const sessions = await fetchJSON("/api/sessions");
90
+ if (!sessions.length) { main.innerHTML = '<p class="dim">(no sessions yet)</p>'; return; }
91
+ main.innerHTML = '<table><thead><tr><th>id</th><th>saved</th><th class="num">msgs</th><th>preview</th></tr></thead><tbody id="sb"></tbody></table><div id="detail"></div>';
92
+ const tb = $("#sb");
93
+ for (const s of sessions) {
94
+ const tr = document.createElement("tr");
95
+ tr.innerHTML = '<td><a href="#" data-id="' + s.id + '">' + s.id.slice(0, 24) + '…</a></td>' +
96
+ '<td class="dim">' + s.savedAt + '</td>' +
97
+ '<td class="num">' + s.messageCount + '</td>' +
98
+ '<td>' + (s.preview || "") + '</td>';
99
+ tr.querySelector("a").addEventListener("click", async (e) => {
100
+ e.preventDefault();
101
+ const data = await fetchJSON("/api/sessions/" + s.id);
102
+ const lines = (data.messages || []).map((m) => {
103
+ const c = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
104
+ return "[" + m.role + (m.name ? ":" + m.name : "") + "] " + (c || "").slice(0, 2000);
105
+ });
106
+ $("#detail").innerHTML = '<h3>' + s.id + '</h3><pre class="session">' + lines.join("\\n\\n").replace(/[<>&]/g, c => ({"<":"&lt;",">":"&gt;","&":"&amp;"}[c])) + '</pre>';
107
+ });
108
+ tb.appendChild(tr);
109
+ }
110
+ }
111
+
112
+ async function renderCost() {
113
+ const cost = await fetchJSON("/api/cost");
114
+ if (!cost.entries.length) { main.innerHTML = '<p class="dim">(no cost log yet)</p>'; return; }
115
+ let html = '<h3>By day</h3><table><thead><tr><th>date</th><th class="num">cost</th><th class="num">tokens</th><th class="num">turns</th></tr></thead><tbody>';
116
+ for (const d of cost.byDay) html += '<tr><td>' + d.date + '</td><td class="num">$' + d.costUSD.toFixed(4) + '</td><td class="num">' + d.tokens + '</td><td class="num">' + d.turns + '</td></tr>';
117
+ html += '</tbody></table><h3>By model</h3><table><thead><tr><th>model</th><th class="num">cost</th><th class="num">tokens</th><th class="num">turns</th></tr></thead><tbody>';
118
+ for (const m of cost.byModel) html += '<tr><td>' + m.model + '</td><td class="num">$' + m.costUSD.toFixed(4) + '</td><td class="num">' + m.tokens + '</td><td class="num">' + m.turns + '</td></tr>';
119
+ html += '</tbody></table>';
120
+ main.innerHTML = html;
121
+ }
122
+
123
+ async function renderEvals() {
124
+ const evals = await fetchJSON("/api/evals");
125
+ if (!evals || !evals.results) { main.innerHTML = '<p class="dim">(no eval report — run npm run eval first)</p>'; return; }
126
+ let html = '<p>' + evals.passed + '/' + evals.cases + ' passed at ' + evals.ranAt + ' (total $' + (evals.totalCostUSD || 0).toFixed(4) + ')</p>';
127
+ html += '<table><thead><tr><th>id</th><th>status</th><th class="num">turns</th><th class="num">ms</th><th class="num">cost</th><th>failures</th></tr></thead><tbody>';
128
+ for (const r of evals.results) {
129
+ const status = r.passed ? '<span style="color:#c3e88d">✓</span>' : '<span style="color:#ff5370">✗</span>';
130
+ html += '<tr><td>' + r.id + '</td><td>' + status + '</td><td class="num">' + r.turns + '</td><td class="num">' + r.durationMs + '</td><td class="num">$' + (r.costUSD || 0).toFixed(4) + '</td><td class="dim">' + (r.failures || []).join("; ") + '</td></tr>';
131
+ }
132
+ html += '</tbody></table>';
133
+ main.innerHTML = html;
134
+ }
135
+
136
+ setActive("overview");
137
+ })();
138
+ </script>
139
+ </body></html>`;
140
+ function sendJson(res, data, status = 200) {
141
+ res.writeHead(status, { "Content-Type": "application/json" });
142
+ res.end(JSON.stringify(data));
143
+ }
144
+ function sendHtml(res, html) {
145
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
146
+ res.end(html);
147
+ }
148
+ export async function startDashboard(config, port) {
149
+ const server = http.createServer((req, res) => {
150
+ const url = new URL(req.url || "/", `http://localhost:${port}`);
151
+ try {
152
+ if (url.pathname === "/")
153
+ return sendHtml(res, INDEX_HTML);
154
+ if (url.pathname === "/api/meta")
155
+ return sendJson(res, { workdir: config.workdir, model: config.model });
156
+ if (url.pathname === "/api/sessions")
157
+ return sendJson(res, listSessions(config));
158
+ if (url.pathname.startsWith("/api/sessions/")) {
159
+ const id = decodeURIComponent(url.pathname.slice("/api/sessions/".length));
160
+ const data = loadSession(config, id);
161
+ return sendJson(res, data ?? {});
162
+ }
163
+ if (url.pathname === "/api/cost") {
164
+ const entries = readCostLog(config);
165
+ return sendJson(res, {
166
+ entries,
167
+ byDay: costByDay(entries),
168
+ byModel: costByModel(entries),
169
+ });
170
+ }
171
+ if (url.pathname === "/api/evals") {
172
+ const file = path.join(config.workdir, "test", "eval-report.json");
173
+ if (!fs.existsSync(file))
174
+ return sendJson(res, {});
175
+ try {
176
+ return sendJson(res, JSON.parse(fs.readFileSync(file, "utf8")));
177
+ }
178
+ catch {
179
+ return sendJson(res, {});
180
+ }
181
+ }
182
+ res.writeHead(404);
183
+ res.end("not found");
184
+ }
185
+ catch (e) {
186
+ res.writeHead(500);
187
+ res.end(`server error: ${e?.message ?? e}`);
188
+ }
189
+ });
190
+ await new Promise((resolve) => server.listen(port, () => resolve()));
191
+ console.error(chalk.green(`dashboard listening on http://localhost:${port}`));
192
+ console.error(chalk.dim("Ctrl-C to stop"));
193
+ await new Promise(() => { }); // run until killed
194
+ }
195
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@smartledger.technology/openai-claw",
3
+ "version": "0.1.0",
4
+ "description": "A Claude Code clone powered by OpenAI gpt-5-nano",
5
+ "author": "Gregory J. Ward <codenlighten1@gmail.com> (CTO, SmartLedger.Technology)",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/codenlighten/openai-claw.git"
10
+ },
11
+ "homepage": "https://github.com/codenlighten/openai-claw#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/codenlighten/openai-claw/issues"
14
+ },
15
+ "keywords": [
16
+ "ai",
17
+ "openai",
18
+ "gpt",
19
+ "agent",
20
+ "cli",
21
+ "claude-code",
22
+ "tools",
23
+ "mcp"
24
+ ],
25
+ "type": "module",
26
+ "bin": {
27
+ "claw": "./dist/index.js"
28
+ },
29
+ "main": "./dist/index.js",
30
+ "scripts": {
31
+ "build": "tsc && chmod +x dist/index.js",
32
+ "dev": "tsx src/index.ts",
33
+ "start": "node dist/index.js",
34
+ "typecheck": "tsc --noEmit",
35
+ "clean": "rm -rf dist",
36
+ "prepare": "test -d dist || npm run build",
37
+ "test": "vitest run",
38
+ "eval": "tsx src/eval/cli.ts"
39
+ },
40
+ "dependencies": {
41
+ "@modelcontextprotocol/sdk": "^1.25.1",
42
+ "chalk": "^5.3.0",
43
+ "cli-highlight": "^2.1.11",
44
+ "diff": "^5.2.0",
45
+ "dotenv": "^17.2.3",
46
+ "fast-glob": "^3.3.2",
47
+ "gray-matter": "^4.0.3",
48
+ "html-to-text": "^9.0.5",
49
+ "ink": "^5.2.1",
50
+ "ink-spinner": "^5.0.0",
51
+ "ink-text-input": "^6.0.0",
52
+ "marked": "^15.0.12",
53
+ "marked-terminal": "^7.3.0",
54
+ "minimatch": "^10.1.1",
55
+ "openai": "^4.77.0",
56
+ "pdf-parse": "^2.4.5",
57
+ "react": "^18.3.1",
58
+ "yargs": "^17.7.2",
59
+ "zod": "^3.23.8"
60
+ },
61
+ "devDependencies": {
62
+ "@types/diff": "^5.2.1",
63
+ "@types/html-to-text": "^9.0.4",
64
+ "@types/node": "^20.14.0",
65
+ "@types/react": "^18.3.27",
66
+ "@types/yargs": "^17.0.32",
67
+ "tsx": "^4.16.0",
68
+ "typescript": "^5.5.0",
69
+ "vitest": "^4.0.16"
70
+ },
71
+ "engines": {
72
+ "node": ">=18"
73
+ },
74
+ "files": [
75
+ "dist",
76
+ "README.md",
77
+ "LICENSE"
78
+ ]
79
+ }