@pimote/sdk 0.13.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/LICENSE +21 -0
- package/README.md +193 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/panels/detect.d.ts +11 -0
- package/dist/panels/detect.js +48 -0
- package/dist/panels/index.d.ts +2 -0
- package/dist/panels/index.js +1 -0
- package/dist/panels/types.d.ts +37 -0
- package/dist/panels/types.js +1 -0
- package/dist/projects/index.d.ts +1 -0
- package/dist/projects/index.js +1 -0
- package/dist/projects/types.d.ts +77 -0
- package/dist/projects/types.js +1 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Antoine Lennartz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# @pimote/sdk
|
|
2
|
+
|
|
3
|
+
Pimote's extensibility SDK — everything a [pi](https://github.com/mariozechner/pi-coding-agent) extension imports to talk to [pimote](https://github.com/alennartz/pimote). One subpath module per extension seam:
|
|
4
|
+
|
|
5
|
+
- **`@pimote/sdk/panels`** — push structured card data to the pimote web client
|
|
6
|
+
- **`@pimote/sdk/projects`** — contribute project discovery and creation to pimote's project layer
|
|
7
|
+
|
|
8
|
+
The root `@pimote/sdk` import re-exports both modules.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @pimote/sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Requires `@earendil-works/pi-coding-agent` as an optional peer dependency (already present in any pi extension; only the panels seam imports from it).
|
|
17
|
+
|
|
18
|
+
## Panels — `@pimote/sdk/panels`
|
|
19
|
+
|
|
20
|
+
Push structured card data from pi extensions to the pimote web client.
|
|
21
|
+
|
|
22
|
+
When your extension is running inside pimote, `detect()` returns a handle for sending cards to the panel UI. When running in a normal pi terminal session, it returns `null` — your extension keeps working either way.
|
|
23
|
+
|
|
24
|
+
### Usage
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { detect } from '@pimote/sdk/panels';
|
|
28
|
+
import type { ExtensionFactory } from '@earendil-works/pi-coding-agent';
|
|
29
|
+
|
|
30
|
+
const extension: ExtensionFactory = (pi) => {
|
|
31
|
+
const panels = detect(pi, 'my-extension');
|
|
32
|
+
|
|
33
|
+
if (panels) {
|
|
34
|
+
// Running inside pimote — push cards to the web UI
|
|
35
|
+
panels.updateCards([
|
|
36
|
+
{
|
|
37
|
+
id: 'status',
|
|
38
|
+
color: 'success',
|
|
39
|
+
header: { title: 'Build', tag: 'passed' },
|
|
40
|
+
body: [{ content: 'All 42 tests passed', style: 'text' }],
|
|
41
|
+
footer: ['2.3s'],
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Rest of your extension — works in both pimote and regular pi
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default extension;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### API
|
|
53
|
+
|
|
54
|
+
#### `detect(pi, key)`
|
|
55
|
+
|
|
56
|
+
Detects whether the extension is running inside pimote.
|
|
57
|
+
|
|
58
|
+
- **`pi`** — The `ExtensionAPI` object passed to your extension factory.
|
|
59
|
+
- **`key`** — A unique namespace string for your extension's cards. Cards from different keys don't interfere with each other.
|
|
60
|
+
|
|
61
|
+
Returns a `PanelHandle` if running inside pimote, or `null` otherwise.
|
|
62
|
+
|
|
63
|
+
Calling `detect()` again with the same key deactivates the previous handle (its methods become no-ops) and returns a new one.
|
|
64
|
+
|
|
65
|
+
#### `PanelHandle`
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
interface PanelHandle {
|
|
69
|
+
/** Replace all cards for this namespace. Previous cards are discarded. */
|
|
70
|
+
updateCards(cards: Card[]): void;
|
|
71
|
+
/** Remove all cards for this namespace. */
|
|
72
|
+
clear(): void;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### `Card`
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
interface Card {
|
|
80
|
+
id: string;
|
|
81
|
+
color?: 'accent' | 'success' | 'warning' | 'error' | 'muted';
|
|
82
|
+
header: {
|
|
83
|
+
title: string;
|
|
84
|
+
tag?: string;
|
|
85
|
+
};
|
|
86
|
+
body?: BodySection[];
|
|
87
|
+
footer?: string[];
|
|
88
|
+
href?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface BodySection {
|
|
92
|
+
content: string;
|
|
93
|
+
style: 'text' | 'code' | 'secondary';
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
- **`id`** — Unique identifier for the card within your namespace.
|
|
98
|
+
- **`color`** — Optional color theme for the card.
|
|
99
|
+
- **`header.title`** — Card title, always visible.
|
|
100
|
+
- **`header.tag`** — Optional short label displayed next to the title.
|
|
101
|
+
- **`body`** — Optional content sections, each with a style (`text`, `code`, or `secondary`).
|
|
102
|
+
- **`footer`** — Optional array of short strings displayed at the bottom.
|
|
103
|
+
- **`href`** — Optional same-origin URL. When set, the client renders the
|
|
104
|
+
entire card as a clickable link (same-tab navigation). Use for cards
|
|
105
|
+
that point at a hosted resource — e.g. a bundle served by pimote's
|
|
106
|
+
static-host tool.
|
|
107
|
+
|
|
108
|
+
### How it works
|
|
109
|
+
|
|
110
|
+
Detection uses pi's EventBus for a synchronous in-process round-trip — pimote's server listens for `pimote:detect:request` and responds on `pimote:detect:response`. Card updates are emitted on the `pimote:panels` channel, which pimote's session manager picks up and pushes to the web client over WebSocket.
|
|
111
|
+
|
|
112
|
+
When pimote isn't present, the EventBus emit fires with no listener, `detect()` returns `null`, and there's zero overhead.
|
|
113
|
+
|
|
114
|
+
## Projects — `@pimote/sdk/projects`
|
|
115
|
+
|
|
116
|
+
Type-only module for user-authored project-source modules: pimote scans a project-sources directory (default `~/.config/pimote/project-sources`, configurable via `projectSourcesDir`), dynamic-imports every JS/TS module it finds, and collects each module's exported `sources` and `creators` arrays. Sources contribute repos and multi-repo projects to pimote's project layer; creators make new project directories from user-supplied form params.
|
|
117
|
+
|
|
118
|
+
### Writing a module
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
// ~/.config/pimote/project-sources/my-source.ts
|
|
122
|
+
import type { ProjectSource, ProjectCreator } from '@pimote/sdk/projects';
|
|
123
|
+
|
|
124
|
+
export const sources: ProjectSource[] = [
|
|
125
|
+
{
|
|
126
|
+
id: 'my-source',
|
|
127
|
+
async list() {
|
|
128
|
+
return [
|
|
129
|
+
{
|
|
130
|
+
kind: 'repo',
|
|
131
|
+
path: '/home/me/work/api',
|
|
132
|
+
name: 'api',
|
|
133
|
+
branch: 'main',
|
|
134
|
+
dirty: false,
|
|
135
|
+
ahead: 0,
|
|
136
|
+
behind: 0,
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
export const creators: ProjectCreator[] = [
|
|
144
|
+
{
|
|
145
|
+
id: 'my-creator',
|
|
146
|
+
describe() {
|
|
147
|
+
return { label: 'New API project', paramSchema: { name: 'string', tags: 'string[]' } };
|
|
148
|
+
},
|
|
149
|
+
async create(params) {
|
|
150
|
+
const path = `/home/me/work/${String(params.name)}`;
|
|
151
|
+
// ... scaffold the project directory ...
|
|
152
|
+
return { path };
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
];
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### `ProjectSource`
|
|
159
|
+
|
|
160
|
+
The discovery seam. `list()` is called on cache miss and must return the current entries without mutating anything. The optional `onProjectOpen(projectPath)` hook is awaited before any open of a listed entry proceeds — whether the target exists on disk or not, and from every open path (row click, new session, manager tool). Sources self-filter by path: probe the disk and scaffold if the entry is theirs and missing; do other open-time work otherwise. A thrown error aborts the open and surfaces the message to the user.
|
|
161
|
+
|
|
162
|
+
### `ProjectCreator`
|
|
163
|
+
|
|
164
|
+
The creation seam. `describe()` returns the human-readable form for the creation UI — a `label` plus a `paramSchema` mapping param names to `'string' | 'string[]'`. `create(params)` receives the user-supplied params, makes the project directory, and returns its `{ path }`.
|
|
165
|
+
|
|
166
|
+
### Entry shapes
|
|
167
|
+
|
|
168
|
+
`list()` returns `SourceEntry[]` — a repo or a multi-repo project:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
/** Feeds a single-repo project. Extends `RepoInfo`. */
|
|
172
|
+
interface RepoSourceEntry extends RepoInfo {
|
|
173
|
+
kind: 'repo';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Feeds a multi-repo project over member paths. */
|
|
177
|
+
interface MultiRepoSourceEntry {
|
|
178
|
+
kind: 'project';
|
|
179
|
+
path: string;
|
|
180
|
+
name: string;
|
|
181
|
+
memberPaths: string[];
|
|
182
|
+
/** Source-contributed tags; shown to the user but not user-removable. */
|
|
183
|
+
tags?: string[];
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### `RepoInfo`
|
|
188
|
+
|
|
189
|
+
Repo facts as contributed by sources: `path`, `name`, `branch` (`string | null`), `dirty`, `ahead`, `behind`, and optional `lastActivity` (epoch ms), `missing` (repo path no longer exists on disk), and `tags`. It mirrors pimote's wire `RepoInfo` type — same name, same fields — so extension authors can write `interface MyEntry extends RepoInfo` against the SDK alone.
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import type { PanelHandle } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Detect whether running inside pimote. Returns a scoped handle for pushing
|
|
5
|
+
* card data, or null if not in pimote.
|
|
6
|
+
*
|
|
7
|
+
* Each key gets an independent namespace — cards from different keys don't
|
|
8
|
+
* interfere. Calling detect() again with the same key deactivates the
|
|
9
|
+
* previous handle (its methods become no-ops) and returns a new one.
|
|
10
|
+
*/
|
|
11
|
+
export declare function detect(pi: ExtensionAPI, key: string): PanelHandle | null;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Tracks active state per key so re-detection deactivates the old handle.
|
|
2
|
+
* Scoped per ExtensionAPI instance (one per pi session) via a WeakMap, so two
|
|
3
|
+
* sessions in the same process that detect() the same key don't deactivate
|
|
4
|
+
* each other's handles. */
|
|
5
|
+
const handlesByApi = new WeakMap();
|
|
6
|
+
/**
|
|
7
|
+
* Detect whether running inside pimote. Returns a scoped handle for pushing
|
|
8
|
+
* card data, or null if not in pimote.
|
|
9
|
+
*
|
|
10
|
+
* Each key gets an independent namespace — cards from different keys don't
|
|
11
|
+
* interfere. Calling detect() again with the same key deactivates the
|
|
12
|
+
* previous handle (its methods become no-ops) and returns a new one.
|
|
13
|
+
*/
|
|
14
|
+
export function detect(pi, key) {
|
|
15
|
+
// Synchronous detection round-trip
|
|
16
|
+
let detected = false;
|
|
17
|
+
const unsub = pi.events.on('pimote:detect:response', () => {
|
|
18
|
+
detected = true;
|
|
19
|
+
});
|
|
20
|
+
pi.events.emit('pimote:detect:request', {});
|
|
21
|
+
unsub();
|
|
22
|
+
if (!detected)
|
|
23
|
+
return null;
|
|
24
|
+
// Deactivate previous handle for this key (scoped to this pi instance)
|
|
25
|
+
let handles = handlesByApi.get(pi);
|
|
26
|
+
if (!handles) {
|
|
27
|
+
handles = new Map();
|
|
28
|
+
handlesByApi.set(pi, handles);
|
|
29
|
+
}
|
|
30
|
+
const prev = handles.get(key);
|
|
31
|
+
if (prev)
|
|
32
|
+
prev.active = false;
|
|
33
|
+
// Create new handle state
|
|
34
|
+
const state = { active: true };
|
|
35
|
+
handles.set(key, state);
|
|
36
|
+
return {
|
|
37
|
+
updateCards(cards) {
|
|
38
|
+
if (!state.active)
|
|
39
|
+
return;
|
|
40
|
+
pi.events.emit('pimote:panels', { type: 'cards', namespace: key, cards });
|
|
41
|
+
},
|
|
42
|
+
clear() {
|
|
43
|
+
if (!state.active)
|
|
44
|
+
return;
|
|
45
|
+
pi.events.emit('pimote:panels', { type: 'clear', namespace: key });
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { detect } from './detect.js';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type CardColor = 'accent' | 'success' | 'warning' | 'error' | 'muted';
|
|
2
|
+
export type BodySectionStyle = 'text' | 'code' | 'secondary';
|
|
3
|
+
export interface BodySection {
|
|
4
|
+
content: string;
|
|
5
|
+
style: BodySectionStyle;
|
|
6
|
+
}
|
|
7
|
+
export interface Card {
|
|
8
|
+
id: string;
|
|
9
|
+
color?: CardColor;
|
|
10
|
+
header: {
|
|
11
|
+
title: string;
|
|
12
|
+
tag?: string;
|
|
13
|
+
};
|
|
14
|
+
body?: BodySection[];
|
|
15
|
+
footer?: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Optional same-origin URL. When present, the client renders the entire
|
|
18
|
+
* card as a clickable link (same-tab navigation). Kept in lock-step with
|
|
19
|
+
* the protocol `Card` type in `shared/src/protocol.ts`.
|
|
20
|
+
*/
|
|
21
|
+
href?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface PanelHandle {
|
|
24
|
+
/** Replace this handle's cards. Full snapshot — previous cards for this namespace are discarded. */
|
|
25
|
+
updateCards(cards: Card[]): void;
|
|
26
|
+
/** Remove all cards for this namespace. */
|
|
27
|
+
clear(): void;
|
|
28
|
+
}
|
|
29
|
+
/** Message shapes emitted on the 'pimote:panels' EventBus channel. */
|
|
30
|
+
export type PanelMessage = {
|
|
31
|
+
type: 'cards';
|
|
32
|
+
namespace: string;
|
|
33
|
+
cards: Card[];
|
|
34
|
+
} | {
|
|
35
|
+
type: 'clear';
|
|
36
|
+
namespace: string;
|
|
37
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { ProjectSource, ProjectCreator, ProjectCreatorDescriptor, ProjectCreatorParamType, SourceEntry, RepoSourceEntry, MultiRepoSourceEntry, RepoInfo } from './types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo facts as contributed by sources. Twin of the wire `RepoInfo` in
|
|
3
|
+
* shared/src/protocol.ts — drift-guarded by server/src/sdk-twins.ts.
|
|
4
|
+
*/
|
|
5
|
+
export interface RepoInfo {
|
|
6
|
+
path: string;
|
|
7
|
+
name: string;
|
|
8
|
+
branch: string | null;
|
|
9
|
+
dirty: boolean;
|
|
10
|
+
/** Commits ahead of upstream; 0 when unknown. */
|
|
11
|
+
ahead: number;
|
|
12
|
+
behind: number;
|
|
13
|
+
/** Epoch ms of last session activity in this repo, when known. */
|
|
14
|
+
lastActivity?: number;
|
|
15
|
+
/** True when the repo path no longer exists on disk (deleted member, broken symlink). */
|
|
16
|
+
missing?: boolean;
|
|
17
|
+
/** Effective tags (user + source-contributed). Absent when untagged. */
|
|
18
|
+
tags?: string[];
|
|
19
|
+
}
|
|
20
|
+
/** Human-readable parameter type for a creator form field. */
|
|
21
|
+
export type ProjectCreatorParamType = 'string' | 'string[]';
|
|
22
|
+
/** A repo entry contributed to the discovery index (feeds single-repo projects). */
|
|
23
|
+
export interface RepoSourceEntry extends RepoInfo {
|
|
24
|
+
kind: 'repo';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A multi-repo project entry contributed to the project layer. `memberPaths`
|
|
28
|
+
* are concrete paths that may not exist on disk yet; the server derives
|
|
29
|
+
* existence state itself — sources never flag "virtual".
|
|
30
|
+
*/
|
|
31
|
+
export interface MultiRepoSourceEntry {
|
|
32
|
+
kind: 'project';
|
|
33
|
+
path: string;
|
|
34
|
+
name: string;
|
|
35
|
+
memberPaths: string[];
|
|
36
|
+
/** Source-contributed tags; shown to the user but not user-removable. */
|
|
37
|
+
tags?: string[];
|
|
38
|
+
}
|
|
39
|
+
/** Anything a source lists: a repo, or a multi-repo project over member paths. */
|
|
40
|
+
export type SourceEntry = RepoSourceEntry | MultiRepoSourceEntry;
|
|
41
|
+
/**
|
|
42
|
+
* Extensible discovery seam: a source contributes repos and multi-repo
|
|
43
|
+
* projects to the project layer. Built in: the filesystem walker over
|
|
44
|
+
* configured roots. User-authored sources are dynamic-imported from the
|
|
45
|
+
* configured project-sources directory.
|
|
46
|
+
*/
|
|
47
|
+
export interface ProjectSource {
|
|
48
|
+
readonly id: string;
|
|
49
|
+
/** Discover entries; called on cache miss. Must not mutate anything. */
|
|
50
|
+
list(): Promise<SourceEntry[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Awaited before any open of a listed entry proceeds — whether the target
|
|
53
|
+
* exists on disk or not, and from every open path (row click, new session,
|
|
54
|
+
* manager tool). Sources self-filter by path: probe the disk and scaffold
|
|
55
|
+
* if the entry is theirs and missing; do other open-time work otherwise.
|
|
56
|
+
* A thrown error aborts the open and surfaces the message to the user.
|
|
57
|
+
*/
|
|
58
|
+
onProjectOpen?(projectPath: string): Promise<void>;
|
|
59
|
+
}
|
|
60
|
+
/** Human-readable description of a creator's form, for the creation UI. */
|
|
61
|
+
export interface ProjectCreatorDescriptor {
|
|
62
|
+
label: string;
|
|
63
|
+
paramSchema: Record<string, ProjectCreatorParamType>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Extensible creation seam: a creator makes a new project directory from
|
|
67
|
+
* user-supplied params. Built in: mkdir + git init. User-authored creators
|
|
68
|
+
* are dynamic-imported from the configured project-sources directory.
|
|
69
|
+
*/
|
|
70
|
+
export interface ProjectCreator {
|
|
71
|
+
readonly id: string;
|
|
72
|
+
/** Human-readable description for the creation UI. */
|
|
73
|
+
describe(): ProjectCreatorDescriptor;
|
|
74
|
+
create(params: Record<string, unknown>): Promise<{
|
|
75
|
+
path: string;
|
|
76
|
+
}>;
|
|
77
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pimote/sdk",
|
|
3
|
+
"version": "0.13.0",
|
|
4
|
+
"description": "Pimote extensibility SDK: panel cards and project discovery/creation seams for pi extensions",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Antoine Lennartz <alennartz@gmail.com>",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/alennartz/pimote.git",
|
|
11
|
+
"directory": "packages/sdk"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/alennartz/pimote/tree/main/packages/sdk#readme",
|
|
14
|
+
"bugs": "https://github.com/alennartz/pimote/issues",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"pi",
|
|
17
|
+
"pimote",
|
|
18
|
+
"extension",
|
|
19
|
+
"sdk",
|
|
20
|
+
"projects",
|
|
21
|
+
"panels",
|
|
22
|
+
"cards"
|
|
23
|
+
],
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./dist/index.js",
|
|
26
|
+
"./panels": "./dist/panels/index.js",
|
|
27
|
+
"./projects": "./dist/projects/index.js"
|
|
28
|
+
},
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc",
|
|
37
|
+
"dev": "tsc --watch",
|
|
38
|
+
"test": "vitest",
|
|
39
|
+
"prepublishOnly": "npm run build"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@earendil-works/pi-coding-agent": "^0.99.2"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"@earendil-works/pi-coding-agent": {
|
|
46
|
+
"optional": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@earendil-works/pi-coding-agent": "^0.99.2",
|
|
51
|
+
"typescript": "^6.0.2",
|
|
52
|
+
"vitest": "^4.1.2"
|
|
53
|
+
}
|
|
54
|
+
}
|