@alasano/pi-linear 0.3.1 → 0.4.1
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 +19 -12
- package/extensions/client.ts +27 -6
- package/extensions/index.ts +60 -5
- package/extensions/params.ts +1 -1
- package/extensions/renderers/comments.ts +2 -2
- package/extensions/renderers/common.ts +2 -2
- package/extensions/renderers/documents.ts +2 -2
- package/extensions/renderers/initiatives.ts +2 -2
- package/extensions/renderers/issue-labels.ts +2 -2
- package/extensions/renderers/issue-relations.ts +2 -2
- package/extensions/renderers/issue-statuses.ts +2 -2
- package/extensions/renderers/issues.ts +2 -2
- package/extensions/renderers/milestones.ts +2 -2
- package/extensions/renderers/project-labels.ts +2 -2
- package/extensions/renderers/project-relations.ts +2 -2
- package/extensions/renderers/projects.ts +2 -2
- package/extensions/renderers/teams.ts +2 -2
- package/extensions/renderers/users.ts +2 -2
- package/extensions/renderers/workspaces.ts +2 -2
- package/extensions/settings.ts +3 -3
- package/extensions/tools/comments.ts +2 -2
- package/extensions/tools/documents.ts +2 -2
- package/extensions/tools/initiatives.ts +2 -2
- package/extensions/tools/issue-labels.ts +2 -2
- package/extensions/tools/issue-relations.ts +2 -2
- package/extensions/tools/issue-statuses.ts +2 -2
- package/extensions/tools/issues.ts +2 -2
- package/extensions/tools/milestones.ts +2 -2
- package/extensions/tools/project-labels.ts +2 -2
- package/extensions/tools/project-relations.ts +2 -2
- package/extensions/tools/projects.ts +2 -2
- package/extensions/tools/teams.ts +2 -2
- package/extensions/tools/users.ts +2 -2
- package/extensions/tools/workspaces.ts +2 -2
- package/extensions/util.ts +1 -1
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -34,27 +34,34 @@ pi install npm:@alasano/pi-linear
|
|
|
34
34
|
|
|
35
35
|
## Authentication
|
|
36
36
|
|
|
37
|
-
The extension
|
|
37
|
+
The extension can use either stored workspaces or the `LINEAR_API_KEY` environment variable. Stored workspaces are preferred by default so multi-account switching keeps working even if `LINEAR_API_KEY` is set globally.
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Use the `/linear-auth` command to manage workspaces and choose the auth preference:
|
|
40
40
|
|
|
41
|
-
| Command
|
|
42
|
-
|
|
|
43
|
-
| `/linear-auth add <name>`
|
|
44
|
-
| `/linear-auth remove <name>`
|
|
45
|
-
| `/linear-auth switch <name>`
|
|
46
|
-
| `/linear-auth
|
|
47
|
-
| `/linear-auth`
|
|
41
|
+
| Command | Description |
|
|
42
|
+
| ------------------------------------ | -------------------------------------------------------------------- |
|
|
43
|
+
| `/linear-auth add <name>` | Add a workspace with an API key (prompts for key) |
|
|
44
|
+
| `/linear-auth remove <name>` | Remove a workspace (shows selector if name omitted) |
|
|
45
|
+
| `/linear-auth switch <name>` | Switch active workspace and prefer stored workspaces |
|
|
46
|
+
| `/linear-auth prefer workspace\|env` | Choose whether stored workspaces or `LINEAR_API_KEY` are tried first |
|
|
47
|
+
| `/linear-auth status` | Show auth preference, active source, and configured workspaces |
|
|
48
|
+
| `/linear-auth` | Same as status |
|
|
48
49
|
|
|
49
50
|
When you add your first workspace, it becomes active automatically. Adding a second workspace prompts you to switch. After a `/reload` with two or more workspaces configured, the agent gets a `linear_switch_workspace` tool and can switch between them when asked.
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
Default auth resolution order (`/linear-auth prefer workspace`):
|
|
52
53
|
|
|
53
54
|
1. Active stored workspace (if any workspaces are configured)
|
|
54
|
-
2. `LINEAR_API_KEY` environment variable (fallback when no
|
|
55
|
+
2. `LINEAR_API_KEY` environment variable (fallback when no workspace is active)
|
|
55
56
|
3. Interactive prompt (asks you to set up a key)
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
Environment auth resolution order (`/linear-auth prefer env`):
|
|
59
|
+
|
|
60
|
+
1. `LINEAR_API_KEY` environment variable
|
|
61
|
+
2. Active stored workspace (fallback when `LINEAR_API_KEY` is not set)
|
|
62
|
+
3. Interactive prompt (asks you to set up a key)
|
|
63
|
+
|
|
64
|
+
Credentials and auth preference are stored at `~/.pi/agent/extensions/linear/credentials.json`.
|
|
58
65
|
|
|
59
66
|
## Tool settings
|
|
60
67
|
|
package/extensions/client.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExtensionContext } from '@
|
|
1
|
+
import type { ExtensionContext } from '@earendil-works/pi-coding-agent';
|
|
2
2
|
import { promises as fs } from 'node:fs';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
@@ -9,13 +9,20 @@ import { ISSUE_SELECTION } from './selections';
|
|
|
9
9
|
const LINEAR_GRAPHQL_ENDPOINT = 'https://api.linear.app/graphql';
|
|
10
10
|
const IDENTIFIER_PATTERN = /^([A-Z][A-Z0-9]*)-(\d+)$/i;
|
|
11
11
|
|
|
12
|
+
export type AuthPreference = 'workspace' | 'env';
|
|
13
|
+
|
|
12
14
|
export type WorkspaceCredentials = {
|
|
13
15
|
activeWorkspace: string | null;
|
|
16
|
+
authPreference: AuthPreference;
|
|
14
17
|
workspaces: Record<string, { apiKey: string }>;
|
|
15
18
|
};
|
|
16
19
|
|
|
20
|
+
function normalizeAuthPreference(value: unknown): AuthPreference {
|
|
21
|
+
return value === 'env' ? 'env' : 'workspace';
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
function emptyCredentials(): WorkspaceCredentials {
|
|
18
|
-
return { activeWorkspace: null, workspaces: {} };
|
|
25
|
+
return { activeWorkspace: null, authPreference: 'workspace', workspaces: {} };
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
export function getCredentialFilePath() {
|
|
@@ -38,6 +45,7 @@ export async function readCredentials(): Promise<WorkspaceCredentials> {
|
|
|
38
45
|
}
|
|
39
46
|
const activeWorkspace =
|
|
40
47
|
typeof parsed.activeWorkspace === 'string' ? parsed.activeWorkspace : null;
|
|
48
|
+
const authPreference = normalizeAuthPreference(parsed.authPreference);
|
|
41
49
|
const workspaces: Record<string, { apiKey: string }> = {};
|
|
42
50
|
for (const [name, entry] of Object.entries(parsed.workspaces)) {
|
|
43
51
|
if (
|
|
@@ -49,7 +57,7 @@ export async function readCredentials(): Promise<WorkspaceCredentials> {
|
|
|
49
57
|
workspaces[name] = { apiKey: (entry as { apiKey: string }).apiKey };
|
|
50
58
|
}
|
|
51
59
|
}
|
|
52
|
-
return { activeWorkspace, workspaces };
|
|
60
|
+
return { activeWorkspace, authPreference, workspaces };
|
|
53
61
|
} catch {
|
|
54
62
|
return emptyCredentials();
|
|
55
63
|
}
|
|
@@ -96,6 +104,14 @@ export async function switchWorkspace(name: string): Promise<WorkspaceCredential
|
|
|
96
104
|
throw new Error(`Workspace "${name}" does not exist.`);
|
|
97
105
|
}
|
|
98
106
|
creds.activeWorkspace = name;
|
|
107
|
+
creds.authPreference = 'workspace';
|
|
108
|
+
await writeCredentials(creds);
|
|
109
|
+
return creds;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export async function setAuthPreference(preference: AuthPreference): Promise<WorkspaceCredentials> {
|
|
113
|
+
const creds = await readCredentials();
|
|
114
|
+
creds.authPreference = preference;
|
|
99
115
|
await writeCredentials(creds);
|
|
100
116
|
return creds;
|
|
101
117
|
}
|
|
@@ -114,10 +130,15 @@ export async function resolveApiKey(
|
|
|
114
130
|
): Promise<{ apiKey?: string; source: 'env' | 'workspace' | 'none' }> {
|
|
115
131
|
const creds = await readCredentials();
|
|
116
132
|
const workspaceKey = getActiveApiKey(creds);
|
|
117
|
-
if (workspaceKey) return { apiKey: workspaceKey, source: 'workspace' };
|
|
118
|
-
|
|
119
133
|
const envApiKey = asString(process.env.LINEAR_API_KEY);
|
|
120
|
-
|
|
134
|
+
|
|
135
|
+
if (creds.authPreference === 'env') {
|
|
136
|
+
if (envApiKey) return { apiKey: envApiKey, source: 'env' };
|
|
137
|
+
if (workspaceKey) return { apiKey: workspaceKey, source: 'workspace' };
|
|
138
|
+
} else {
|
|
139
|
+
if (workspaceKey) return { apiKey: workspaceKey, source: 'workspace' };
|
|
140
|
+
if (envApiKey) return { apiKey: envApiKey, source: 'env' };
|
|
141
|
+
}
|
|
121
142
|
|
|
122
143
|
const promptIfMissing = options?.promptIfMissing ?? true;
|
|
123
144
|
if (promptIfMissing && ctx.hasUI) {
|
package/extensions/index.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { ExtensionAPI } from '@
|
|
1
|
+
import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
2
2
|
import {
|
|
3
3
|
readCredentials,
|
|
4
4
|
addWorkspace,
|
|
5
5
|
removeWorkspace,
|
|
6
6
|
switchWorkspace,
|
|
7
|
+
setAuthPreference,
|
|
7
8
|
listWorkspaceNames,
|
|
8
9
|
getActiveWorkspaceName,
|
|
9
10
|
resolveApiKey,
|
|
@@ -27,7 +28,8 @@ import { registerLinearSettings } from './settings';
|
|
|
27
28
|
|
|
28
29
|
export default async function linearExtension(pi: ExtensionAPI) {
|
|
29
30
|
pi.registerCommand('linear-auth', {
|
|
30
|
-
description:
|
|
31
|
+
description:
|
|
32
|
+
'Manage Linear workspace auth (usage: /linear-auth [add|remove|switch|prefer|status])',
|
|
31
33
|
handler: async (args, ctx) => {
|
|
32
34
|
const parts = args.trim().split(/\s+/);
|
|
33
35
|
const subcommand = parts[0]?.toLowerCase() || '';
|
|
@@ -145,7 +147,37 @@ export default async function linearExtension(pi: ExtensionAPI) {
|
|
|
145
147
|
}
|
|
146
148
|
|
|
147
149
|
await switchWorkspace(workspaceName);
|
|
148
|
-
ctx.ui.notify(`Active workspace: ${workspaceName}`, 'info');
|
|
150
|
+
ctx.ui.notify(`Active workspace: ${workspaceName}\nAuth preference: workspace`, 'info');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
case 'prefer': {
|
|
155
|
+
const preference = name.toLowerCase();
|
|
156
|
+
if (preference !== 'workspace' && preference !== 'env') {
|
|
157
|
+
ctx.ui.notify('Usage: /linear-auth prefer [workspace|env]', 'warning');
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const updated = await setAuthPreference(preference);
|
|
162
|
+
const envIsSet = Boolean(asString(process.env.LINEAR_API_KEY));
|
|
163
|
+
const active = getActiveWorkspaceName(updated);
|
|
164
|
+
const lines = [`Auth preference: ${preference}`];
|
|
165
|
+
|
|
166
|
+
if (preference === 'env') {
|
|
167
|
+
if (envIsSet) {
|
|
168
|
+
lines.push('LINEAR_API_KEY will be used before stored workspaces.');
|
|
169
|
+
} else if (active) {
|
|
170
|
+
lines.push('LINEAR_API_KEY is not set; falling back to the active workspace.');
|
|
171
|
+
} else {
|
|
172
|
+
lines.push('LINEAR_API_KEY is not set and no active workspace is configured.');
|
|
173
|
+
}
|
|
174
|
+
} else if (active) {
|
|
175
|
+
lines.push(`Workspace "${active}" will be used before LINEAR_API_KEY.`);
|
|
176
|
+
} else {
|
|
177
|
+
lines.push('No active workspace configured; falling back to LINEAR_API_KEY if set.');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
ctx.ui.notify(lines.join('\n'), preference === 'env' && !envIsSet ? 'warning' : 'info');
|
|
149
181
|
return;
|
|
150
182
|
}
|
|
151
183
|
|
|
@@ -157,6 +189,7 @@ export default async function linearExtension(pi: ExtensionAPI) {
|
|
|
157
189
|
});
|
|
158
190
|
const names = listWorkspaceNames(creds);
|
|
159
191
|
const active = getActiveWorkspaceName(creds);
|
|
192
|
+
const envIsSet = Boolean(asString(process.env.LINEAR_API_KEY));
|
|
160
193
|
|
|
161
194
|
let sourceLabel: string;
|
|
162
195
|
if (source === 'workspace') {
|
|
@@ -167,7 +200,7 @@ export default async function linearExtension(pi: ExtensionAPI) {
|
|
|
167
200
|
sourceLabel = 'none';
|
|
168
201
|
}
|
|
169
202
|
|
|
170
|
-
const lines = [`Auth source: ${sourceLabel}`];
|
|
203
|
+
const lines = [`Auth preference: ${creds.authPreference}`, `Auth source: ${sourceLabel}`];
|
|
171
204
|
if (names.length > 0) {
|
|
172
205
|
lines.push(
|
|
173
206
|
`Workspaces: ${names.map((n) => (n === active ? `${n} (active)` : n)).join(', ')}`,
|
|
@@ -176,12 +209,34 @@ export default async function linearExtension(pi: ExtensionAPI) {
|
|
|
176
209
|
lines.push('No workspaces configured');
|
|
177
210
|
}
|
|
178
211
|
|
|
212
|
+
if (creds.authPreference === 'workspace' && envIsSet) {
|
|
213
|
+
if (source === 'workspace') {
|
|
214
|
+
lines.push(
|
|
215
|
+
'LINEAR_API_KEY is set but not active. Run /linear-auth prefer env to use it.',
|
|
216
|
+
);
|
|
217
|
+
} else if (source === 'env') {
|
|
218
|
+
lines.push(
|
|
219
|
+
'No active workspace is configured, so LINEAR_API_KEY is being used as fallback.',
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
} else if (creds.authPreference === 'env' && names.length > 0) {
|
|
223
|
+
if (source === 'env') {
|
|
224
|
+
lines.push(
|
|
225
|
+
'Stored workspaces are available but not active. Run /linear-auth prefer workspace or /linear-auth switch <name> to use one.',
|
|
226
|
+
);
|
|
227
|
+
} else if (source === 'workspace') {
|
|
228
|
+
lines.push(
|
|
229
|
+
'LINEAR_API_KEY is not set, so the active workspace is being used as fallback.',
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
179
234
|
ctx.ui.notify(lines.join('\n'), source === 'none' ? 'warning' : 'info');
|
|
180
235
|
return;
|
|
181
236
|
}
|
|
182
237
|
|
|
183
238
|
default: {
|
|
184
|
-
ctx.ui.notify('Usage: /linear-auth [add|remove|switch|status]', 'warning');
|
|
239
|
+
ctx.ui.notify('Usage: /linear-auth [add|remove|switch|prefer|status]', 'warning');
|
|
185
240
|
}
|
|
186
241
|
}
|
|
187
242
|
},
|
package/extensions/params.ts
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
accentStyle,
|
|
9
9
|
asString,
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
type AgentToolResult,
|
|
4
4
|
type Theme,
|
|
5
5
|
type ToolRenderResultOptions,
|
|
6
|
-
} from '@
|
|
7
|
-
import { Text, truncateToWidth, visibleWidth } from '@
|
|
6
|
+
} from '@earendil-works/pi-coding-agent';
|
|
7
|
+
import { Text, truncateToWidth, visibleWidth } from '@earendil-works/pi-tui';
|
|
8
8
|
import {
|
|
9
9
|
getDefaultJsonView,
|
|
10
10
|
registerLinearResultRenderer,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
accentStyle,
|
|
9
9
|
asString,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
asString,
|
|
9
9
|
cleanOneLine,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
asString,
|
|
9
9
|
cleanOneLine,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
asString,
|
|
9
9
|
cleanOneLine,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
accentStyle,
|
|
9
9
|
asString,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import type { LinearIssue } from '../types';
|
|
8
8
|
import {
|
|
9
9
|
accentStyle,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
accentStyle,
|
|
9
9
|
asString,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
accentStyle,
|
|
9
9
|
asString,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
asString,
|
|
9
9
|
cleanOneLine,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
asString,
|
|
9
9
|
cleanOneLine,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
asString,
|
|
9
9
|
cleanOneLine,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
asString,
|
|
9
9
|
cleanOneLine,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
type AgentToolResult,
|
|
3
3
|
type Theme,
|
|
4
4
|
type ToolRenderResultOptions,
|
|
5
|
-
} from '@
|
|
6
|
-
import { Text } from '@
|
|
5
|
+
} from '@earendil-works/pi-coding-agent';
|
|
6
|
+
import { Text } from '@earendil-works/pi-tui';
|
|
7
7
|
import {
|
|
8
8
|
asString,
|
|
9
9
|
expandedJson,
|
package/extensions/settings.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
|
-
import type { ExtensionAPI, ExtensionContext } from '@
|
|
4
|
-
import { getAgentDir, getSettingsListTheme } from '@
|
|
5
|
-
import { type SettingItem, SettingsList } from '@
|
|
3
|
+
import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';
|
|
4
|
+
import { getAgentDir, getSettingsListTheme } from '@earendil-works/pi-coding-agent';
|
|
5
|
+
import { type SettingItem, SettingsList } from '@earendil-works/pi-tui';
|
|
6
6
|
import { invalidateLinearResultRenderers, setDefaultJsonView } from './renderers/state';
|
|
7
7
|
|
|
8
8
|
const SETTINGS_PATH = join(getAgentDir(), 'state', 'extensions', 'linear', 'tool-settings.json');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
4
|
import { PaginationParams, paginationVariables, FilterParam, RawInputParam } from '../params';
|
|
5
5
|
import { COMMENT_SELECTION } from '../selections';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL, resolveTeamId } from '../client';
|
|
4
4
|
import {
|
|
5
5
|
PaginationParams,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
4
|
import {
|
|
5
5
|
PaginationParams,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL, resolveTeamId } from '../client';
|
|
4
4
|
import {
|
|
5
5
|
PaginationParams,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL, resolveIssueId } from '../client';
|
|
4
4
|
import { PaginationParams, paginationVariables } from '../params';
|
|
5
5
|
import { ISSUE_RELATION_SELECTION } from '../selections';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
4
|
import { PaginationParams, paginationVariables, FilterParam } from '../params';
|
|
5
5
|
import { WORKFLOW_STATE_SELECTION } from '../selections';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
4
|
import { PaginationParams, paginationVariables, FilterParam, RawInputParam } from '../params';
|
|
5
5
|
import { MILESTONE_SELECTION } from '../selections';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
4
|
import { PaginationParams, paginationVariables, FilterParam, RawInputParam } from '../params';
|
|
5
5
|
import { PROJECT_LABEL_SELECTION } from '../selections';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
4
|
import { PaginationParams, paginationVariables } from '../params';
|
|
5
5
|
import { PROJECT_RELATION_SELECTION } from '../selections';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
4
|
import {
|
|
5
5
|
PaginationParams,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
4
|
import { PaginationParams, paginationVariables, FilterParam } from '../params';
|
|
5
5
|
import { TEAM_SELECTION } from '../selections';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
4
|
import { PaginationParams, paginationVariables, FilterParam, SortParam } from '../params';
|
|
5
5
|
import { USER_SELECTION } from '../selections';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineTool } from '@
|
|
2
|
-
import { Type } from '
|
|
1
|
+
import { defineTool } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import { Type } from 'typebox';
|
|
3
3
|
import { switchWorkspace, type WorkspaceCredentials } from '../client';
|
|
4
4
|
import {
|
|
5
5
|
renderLinearSwitchWorkspaceCall,
|
package/extensions/util.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alasano/pi-linear",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Linear integration for pi with 55+ tools, multi-workspace auth, and per-tool settings",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package"
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"type": "module",
|
|
15
15
|
"scripts": {
|
|
16
|
+
"test": "vitest run",
|
|
16
17
|
"typecheck": "tsc --noEmit"
|
|
17
18
|
},
|
|
18
19
|
"pi": {
|
|
@@ -27,12 +28,13 @@
|
|
|
27
28
|
"README.md"
|
|
28
29
|
],
|
|
29
30
|
"peerDependencies": {
|
|
30
|
-
"@
|
|
31
|
-
"@
|
|
32
|
-
"
|
|
33
|
-
"@sinclair/typebox": "*"
|
|
31
|
+
"@earendil-works/pi-coding-agent": ">=0.79.9",
|
|
32
|
+
"@earendil-works/pi-tui": ">=0.79.9",
|
|
33
|
+
"typebox": ">=1.1.38"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@
|
|
36
|
+
"@earendil-works/pi-coding-agent": "^0.79.9",
|
|
37
|
+
"@earendil-works/pi-tui": "^0.79.9",
|
|
38
|
+
"typebox": "^1.1.38"
|
|
37
39
|
}
|
|
38
40
|
}
|