@aliou/pi-linkup 0.1.0 → 0.3.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.
- package/.github/workflows/publish.yml +8 -0
- package/AGENTS.md +48 -0
- package/CHANGELOG.md +13 -0
- package/package.json +3 -3
- package/src/commands/balance.ts +6 -4
- package/src/components/balance-renderer.ts +45 -0
- package/src/components/index.ts +6 -0
- package/src/index.ts +4 -0
- package/src/tools/web-answer.ts +1 -1
- package/src/tools/web-fetch.ts +1 -1
- package/src/tools/web-search.ts +1 -1
- package/src/types.ts +11 -0
|
@@ -4,6 +4,12 @@ on:
|
|
|
4
4
|
push:
|
|
5
5
|
branches:
|
|
6
6
|
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
skip-checks:
|
|
10
|
+
description: "Skip lint and typecheck"
|
|
11
|
+
type: boolean
|
|
12
|
+
default: false
|
|
7
13
|
|
|
8
14
|
concurrency:
|
|
9
15
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
@@ -11,6 +17,7 @@ concurrency:
|
|
|
11
17
|
|
|
12
18
|
jobs:
|
|
13
19
|
check:
|
|
20
|
+
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.skip-checks) }}
|
|
14
21
|
runs-on: ubuntu-latest
|
|
15
22
|
steps:
|
|
16
23
|
- uses: actions/checkout@v4
|
|
@@ -34,6 +41,7 @@ jobs:
|
|
|
34
41
|
publish:
|
|
35
42
|
name: Publish
|
|
36
43
|
needs: check
|
|
44
|
+
if: ${{ always() && (needs.check.result == 'success' || needs.check.result == 'skipped') }}
|
|
37
45
|
runs-on: ubuntu-latest
|
|
38
46
|
permissions:
|
|
39
47
|
contents: write
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# pi-linkup
|
|
2
|
+
|
|
3
|
+
Public Pi extension providing web search, answer, and fetch tools via the Linkup API. People could be using this, so consider backwards compatibility when making changes.
|
|
4
|
+
|
|
5
|
+
Pi is pre-1.0.0, so breaking changes can happen between Pi versions. This extension must stay up to date with Pi or things will break.
|
|
6
|
+
|
|
7
|
+
## Stack
|
|
8
|
+
|
|
9
|
+
- TypeScript (strict mode)
|
|
10
|
+
- pnpm 10.26.1
|
|
11
|
+
- Biome for linting/formatting
|
|
12
|
+
- Changesets for versioning
|
|
13
|
+
|
|
14
|
+
## Scripts
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm typecheck # Type check
|
|
18
|
+
pnpm lint # Lint (runs on pre-commit)
|
|
19
|
+
pnpm format # Format
|
|
20
|
+
pnpm changeset # Create changeset for versioning
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Structure
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
src/
|
|
27
|
+
index.ts # Extension entry, registers tools and commands
|
|
28
|
+
client.ts # Linkup API client
|
|
29
|
+
types.ts # Shared types
|
|
30
|
+
tools/ # Tool implementations
|
|
31
|
+
commands/ # Command implementations
|
|
32
|
+
skills/
|
|
33
|
+
linkup/SKILL.md # Skill docs for agents using this extension
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Conventions
|
|
37
|
+
|
|
38
|
+
- New tools: follow patterns in `src/tools/`
|
|
39
|
+
- API keys come from environment (`LINKUP_API_KEY`)
|
|
40
|
+
- Update `skills/linkup/SKILL.md` when tool behavior changes
|
|
41
|
+
|
|
42
|
+
## Versioning
|
|
43
|
+
|
|
44
|
+
Uses changesets. Run `pnpm changeset` before committing user-facing changes.
|
|
45
|
+
|
|
46
|
+
- `patch`: bug fixes
|
|
47
|
+
- `minor`: new features/tools
|
|
48
|
+
- `major`: breaking changes
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @aliou/pi-linkup
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e57f6fe: Enhanced balance command to show remaining requests per operation type (standard search, deep search, fetch with/without JS) using a themed custom message renderer instead of a transient notification.
|
|
8
|
+
|
|
9
|
+
## 0.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 2307674: Update pi packages to 0.51.0. Adapt tool execute signatures to new parameter order.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aliou/pi-linkup",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/aliou/pi-linkup"
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@biomejs/biome": "^2.3.13",
|
|
21
21
|
"@changesets/cli": "^2.27.11",
|
|
22
|
-
"@mariozechner/pi-coding-agent": "
|
|
23
|
-
"@mariozechner/pi-tui": "
|
|
22
|
+
"@mariozechner/pi-coding-agent": "0.51.0",
|
|
23
|
+
"@mariozechner/pi-tui": "0.51.0",
|
|
24
24
|
"@sinclair/typebox": "^0.34.48",
|
|
25
25
|
"@types/node": "^25.0.10",
|
|
26
26
|
"husky": "^9.1.7",
|
package/src/commands/balance.ts
CHANGED
|
@@ -9,10 +9,12 @@ export function registerBalanceCommand(pi: ExtensionAPI) {
|
|
|
9
9
|
|
|
10
10
|
try {
|
|
11
11
|
const response = await client.getBalance();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
pi.sendMessage({
|
|
13
|
+
customType: "linkup-balance",
|
|
14
|
+
content: `Linkup Balance: ${response.balance.toFixed(2)} credits`,
|
|
15
|
+
display: true,
|
|
16
|
+
details: { balance: response.balance },
|
|
17
|
+
});
|
|
16
18
|
} catch (error) {
|
|
17
19
|
const message =
|
|
18
20
|
error instanceof Error ? error.message : "Unknown error";
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { Box, Text } from "@mariozechner/pi-tui";
|
|
3
|
+
import { LINKUP_PRICING } from "../types";
|
|
4
|
+
|
|
5
|
+
export function registerBalanceRenderer(pi: ExtensionAPI) {
|
|
6
|
+
pi.registerMessageRenderer("linkup-balance", (message, _options, theme) => {
|
|
7
|
+
const details = message.details as { balance: number };
|
|
8
|
+
const balance = details.balance;
|
|
9
|
+
|
|
10
|
+
// Build header line
|
|
11
|
+
const header = [
|
|
12
|
+
theme.fg("accent", "Linkup"),
|
|
13
|
+
theme.fg("muted", " · "),
|
|
14
|
+
theme.fg("muted", `${balance} credits`),
|
|
15
|
+
].join("");
|
|
16
|
+
|
|
17
|
+
// Calculate remaining requests for each operation type
|
|
18
|
+
const remaining = {
|
|
19
|
+
standardSearch: Math.floor(balance / LINKUP_PRICING.standardSearch),
|
|
20
|
+
deepSearch: Math.floor(balance / LINKUP_PRICING.deepSearch),
|
|
21
|
+
fetchNoJs: Math.floor(balance / LINKUP_PRICING.fetchNoJs),
|
|
22
|
+
fetchWithJs: Math.floor(balance / LINKUP_PRICING.fetchWithJs),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Format number with locale string and ~ prefix
|
|
26
|
+
const fmt = (num: number): string => `~${num.toLocaleString()}`;
|
|
27
|
+
|
|
28
|
+
// Table rows with right-aligned numbers (padded to 7 chars)
|
|
29
|
+
const row = (num: number, label: string) =>
|
|
30
|
+
`${theme.fg("accent", fmt(num).padStart(7))} ${theme.fg("dim", label)}`;
|
|
31
|
+
|
|
32
|
+
const lines = [
|
|
33
|
+
header,
|
|
34
|
+
"",
|
|
35
|
+
row(remaining.standardSearch, "standard searches"),
|
|
36
|
+
row(remaining.deepSearch, "deep searches"),
|
|
37
|
+
row(remaining.fetchNoJs, "fetches (no JS)"),
|
|
38
|
+
row(remaining.fetchWithJs, "fetches (with JS)"),
|
|
39
|
+
].join("\n");
|
|
40
|
+
|
|
41
|
+
const box = new Box(1, 1, (t) => theme.bg("customMessageBg", t));
|
|
42
|
+
box.addChild(new Text(lines, 0, 0));
|
|
43
|
+
return box;
|
|
44
|
+
});
|
|
45
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { registerBalanceCommand } from "./commands/balance";
|
|
3
|
+
import { registerRenderers } from "./components";
|
|
3
4
|
import { registerWebAnswerTool } from "./tools/web-answer";
|
|
4
5
|
import { registerWebFetchTool } from "./tools/web-fetch";
|
|
5
6
|
import { registerWebSearchTool } from "./tools/web-search";
|
|
@@ -30,4 +31,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
30
31
|
|
|
31
32
|
// Register commands
|
|
32
33
|
registerBalanceCommand(pi);
|
|
34
|
+
|
|
35
|
+
// Register renderers
|
|
36
|
+
registerRenderers(pi);
|
|
33
37
|
}
|
package/src/tools/web-answer.ts
CHANGED
package/src/tools/web-fetch.ts
CHANGED
package/src/tools/web-search.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -32,3 +32,14 @@ export interface LinkupErrorResponse {
|
|
|
32
32
|
message?: string;
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Credit cost per request by operation type.
|
|
38
|
+
* Source: https://docs.linkup.so/pages/documentation/development/pricing
|
|
39
|
+
*/
|
|
40
|
+
export const LINKUP_PRICING = {
|
|
41
|
+
standardSearch: 0.005,
|
|
42
|
+
deepSearch: 0.05,
|
|
43
|
+
fetchNoJs: 0.001,
|
|
44
|
+
fetchWithJs: 0.005,
|
|
45
|
+
} as const;
|