@agimon-ai/doompi-grep 0.0.1-alpha.2 → 0.0.1-alpha.20

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 CHANGED
@@ -16,7 +16,7 @@ packages use the same hashline protocol.
16
16
  ## Requirements
17
17
 
18
18
  - Node.js 22.19.0 or newer
19
- - Pi 0.84.2 and Pi TUI 0.84.2
19
+ - Pi 0.84.4 and Pi TUI 0.84.4
20
20
 
21
21
  ## Install
22
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/doompi-grep",
3
- "version": "0.0.1-alpha.2",
3
+ "version": "0.0.1-alpha.20",
4
4
  "description": "Snapshot-bound hashline grep for Pi and DoomPi.",
5
5
  "keywords": [
6
6
  "ai",
@@ -14,10 +14,20 @@
14
14
  "pi-package"
15
15
  ],
16
16
  "homepage": "https://agimon.ai",
17
+ "bugs": {
18
+ "url": "https://github.com/AgiFlow/doompi/issues"
19
+ },
17
20
  "license": "MIT",
18
21
  "author": "Vuong Ngo",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/AgiFlow/doompi.git",
25
+ "directory": "packages/default/doompi-grep"
26
+ },
19
27
  "files": [
20
- "dist"
28
+ "dist",
29
+ "src/web",
30
+ "src/exports/webClient.ts"
21
31
  ],
22
32
  "type": "module",
23
33
  "main": "./dist/index.cjs",
@@ -41,23 +51,30 @@
41
51
  },
42
52
  "dependencies": {
43
53
  "@deepseek-ai/cordis": "4.0.1",
44
- "typebox": "1.3.16",
45
- "@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.30",
46
- "@agimon-ai/doompi-ui": "0.0.1-alpha.30",
47
- "@agimon-ai/doompi-hashline": "0.0.1-alpha.2"
54
+ "typebox": "1.3.19",
55
+ "@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.47",
56
+ "@agimon-ai/doompi-ui": "0.0.1-alpha.48",
57
+ "@agimon-ai/doompi-hashline": "0.0.1-alpha.19",
58
+ "@agimon-ai/doompi-web-components": "0.0.1-alpha.8",
59
+ "@agimon-ai/doompi-web-contracts": "0.0.1-alpha.11"
48
60
  },
49
61
  "devDependencies": {
50
- "@earendil-works/pi-coding-agent": "0.84.2",
51
- "@earendil-works/pi-tui": "0.84.2",
52
- "@types/node": "26.2.0",
62
+ "@earendil-works/pi-coding-agent": "0.84.4",
63
+ "@earendil-works/pi-tui": "0.84.4",
64
+ "@tanstack/react-store": "0.11.1",
65
+ "@tanstack/store": "0.11.1",
66
+ "@types/node": "26.4.0",
67
+ "@types/react": "19.2.18",
53
68
  "@vitest/coverage-v8": "4.1.11",
69
+ "@vscode/ripgrep": "1.18.0",
70
+ "react": "19.2.8",
54
71
  "tsdown": "0.22.14",
55
72
  "typescript": "7.0.2",
56
73
  "vitest": "4.1.11"
57
74
  },
58
75
  "peerDependencies": {
59
- "@earendil-works/pi-coding-agent": "0.84.2",
60
- "@earendil-works/pi-tui": "0.84.2"
76
+ "@earendil-works/pi-coding-agent": "0.84.4",
77
+ "@earendil-works/pi-tui": "0.84.4"
61
78
  },
62
79
  "peerDependenciesMeta": {
63
80
  "@earendil-works/pi-coding-agent": {
@@ -70,6 +87,11 @@
70
87
  "engines": {
71
88
  "node": ">=22.19.0"
72
89
  },
90
+ "doompiWeb": {
91
+ "pluginId": "grep",
92
+ "channels": [],
93
+ "client": "./src/exports/webClient.ts"
94
+ },
73
95
  "pi": {
74
96
  "extensions": [
75
97
  "./dist/extensions/pi.mjs"
@@ -78,7 +100,7 @@
78
100
  "scripts": {
79
101
  "build": "tsdown",
80
102
  "test": "vitest --run",
81
- "typecheck": "tsc --noEmit",
103
+ "typecheck": "tsc --noEmit && tsc --noEmit -p src/web/tsconfig.json",
82
104
  "lint": "oxlint . && oxfmt . --check",
83
105
  "fixcode": "oxlint . --fix && oxfmt ."
84
106
  }
@@ -0,0 +1 @@
1
+ export { webPlugin } from '../web/index.ts';
@@ -0,0 +1,65 @@
1
+ import {
2
+ HashlineLines,
3
+ hashlineBody,
4
+ MessageItem,
5
+ MessageItemBody,
6
+ MessageItemHeader,
7
+ MessageItemStatus,
8
+ resultTextLines,
9
+ toolTone,
10
+ } from '@agimon-ai/doompi-web-components';
11
+ import type { ToolMessageRenderProps } from '@agimon-ai/doompi-web-contracts';
12
+ import { grepCallView } from './grepToolView.ts';
13
+
14
+ /**
15
+ * The grep tool's timeline item, the web half of its renderCall and
16
+ * renderResult: the call summary in the header and the anchored lines with
17
+ * a line-number gutter in the body, collapsed to the TUI's budget until the
18
+ * item expands. A failure shows the tool's message in red instead.
19
+ */
20
+ export function GrepToolMessage({ args, result, output, running, isError }: ToolMessageRenderProps) {
21
+ const view = grepCallView(args);
22
+ const collapsed = result === null || isError ? null : hashlineBody(result, output, 'grep', false);
23
+ return (
24
+ <MessageItem tone={toolTone({ running, isError })} expandable={collapsed !== null && collapsed.hidden > 0}>
25
+ {({ expanded }) => {
26
+ const body =
27
+ result === null || isError ? null : expanded ? hashlineBody(result, output, 'grep', true) : collapsed;
28
+ return (
29
+ <>
30
+ <MessageItemHeader title="grep">
31
+ <span data-testid="tool-call-grep" className="flex min-w-0 flex-1 items-center gap-2">
32
+ <span className="truncate text-doom-text">{view.pattern}</span>
33
+ {view.details.length > 0 ? (
34
+ <span className="shrink-0 text-doom-faint">· {view.details.join(' · ')}</span>
35
+ ) : null}
36
+ </span>
37
+ </MessageItemHeader>
38
+ {isError ? (
39
+ <MessageItemBody data-testid="tool-result-grep" className="flex flex-col">
40
+ <MessageItemStatus tone="error">failed</MessageItemStatus>
41
+ {resultTextLines(result, output).map((line, index) => (
42
+ <span key={`${String(index)}-${line}`} className="whitespace-pre-wrap break-words text-doom-red">
43
+ {line}
44
+ </span>
45
+ ))}
46
+ </MessageItemBody>
47
+ ) : body === null ? (
48
+ running ? (
49
+ <MessageItemBody data-testid="tool-result-grep">
50
+ <MessageItemStatus tone="running">running</MessageItemStatus>
51
+ </MessageItemBody>
52
+ ) : null
53
+ ) : body.shown.length === 0 && body.notice === undefined ? null : (
54
+ <MessageItemBody data-testid="tool-result-grep" className="flex flex-col gap-1">
55
+ <HashlineLines lines={body.shown} gutter={body.gutter} />
56
+ {body.hidden > 0 ? <MessageItemStatus expands>{body.hidden} more lines</MessageItemStatus> : null}
57
+ {body.notice !== undefined ? <span className="text-doom-faint">{body.notice}</span> : null}
58
+ </MessageItemBody>
59
+ )}
60
+ </>
61
+ );
62
+ }}
63
+ </MessageItem>
64
+ );
65
+ }
@@ -0,0 +1,21 @@
1
+ import { compactDetails } from '@agimon-ai/doompi-web-components';
2
+
3
+ export interface GrepCallView {
4
+ readonly pattern: string;
5
+ /** Search path, glob, case flag, and limit, as the TUI's call heading lists them. */
6
+ readonly details: readonly string[];
7
+ }
8
+
9
+ /** What the grep call heading shows: the pattern, then where and how it searched. */
10
+ export function grepCallView(args: Readonly<Record<string, unknown>>): GrepCallView {
11
+ const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) ? args.limit : undefined;
12
+ return {
13
+ pattern: typeof args.pattern === 'string' ? args.pattern : '',
14
+ details: compactDetails([
15
+ typeof args.path === 'string' && args.path.length > 0 ? args.path : '.',
16
+ typeof args.glob === 'string' ? args.glob : undefined,
17
+ args.ignoreCase === true ? 'ignore case' : undefined,
18
+ limit === undefined ? undefined : `${limit} matches`,
19
+ ]),
20
+ };
21
+ }
@@ -0,0 +1,11 @@
1
+ import { defineWebPlugin } from '@agimon-ai/doompi-web-contracts';
2
+ import { GrepToolMessage } from './GrepToolMessage.tsx';
3
+
4
+ /**
5
+ * This package's cockpit presence: the grep tool's timeline card, the web
6
+ * half of the TUI's renderCall and renderResult for hashline searches.
7
+ */
8
+ export const webPlugin = defineWebPlugin({
9
+ id: 'grep',
10
+ toolRenderers: [{ tools: ['grep'], message: GrepToolMessage }],
11
+ });
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2023", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "jsx": "react-jsx",
8
+ "strict": true,
9
+ "noImplicitAny": true,
10
+ "noUnusedLocals": true,
11
+ "noUnusedParameters": true,
12
+ "noImplicitReturns": true,
13
+ "noFallthroughCasesInSwitch": true,
14
+ "noEmit": true,
15
+ "resolveJsonModule": true,
16
+ "esModuleInterop": true,
17
+ "skipLibCheck": true,
18
+ "allowImportingTsExtensions": true,
19
+ "forceConsistentCasingInFileNames": true,
20
+ "types": ["node"]
21
+ },
22
+ "include": [".", "../types", "../exports/webClient.ts"]
23
+ }