@yannelli/paseo-linear-plugin 1.1.0-beta.0 → 1.1.0-beta.2
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/OVERVIEW.md +7 -3
- package/README.md +38 -11
- package/client/access.tsx +2 -1
- package/client/compat.ts +23 -5
- package/client/connect.tsx +3 -2
- package/client/graph-camera.tsx +219 -0
- package/client/graph-labels.ts +14 -4
- package/client/launch-guidance.tsx +86 -0
- package/client/launch-plan.ts +50 -2
- package/client/launch.tsx +10 -1
- package/client/live-agents.tsx +138 -23
- package/client/live-cursor.tsx +3 -1
- package/client/live-graph.tsx +159 -75
- package/client/live-header.tsx +29 -0
- package/client/live-panel.tsx +29 -8
- package/client/live-timeline.ts +38 -3
- package/client/pill.tsx +4 -3
- package/client/plugin-icon.tsx +43 -0
- package/client/settings-fields.tsx +11 -3
- package/client/settings-icon.tsx +228 -0
- package/client/settings-live.tsx +25 -1
- package/client/timeline-card.tsx +2 -1
- package/client/tool-buttons.tsx +68 -0
- package/client/ui.tsx +16 -7
- package/client/web.ts +91 -0
- package/index.client.tsx +9 -0
- package/index.server.ts +5 -1
- package/package.json +1 -1
- package/server/agent-hooks.ts +37 -0
- package/server/agent-runs.ts +15 -2
- package/server/agent-tools.ts +240 -0
- package/server/init.ts +1 -0
- package/server/live.ts +27 -1
- package/server/mcp-http.ts +152 -0
- package/server/stores.ts +8 -1
- package/server/subagent-logs.ts +146 -0
- package/shared/activity.ts +5 -1
- package/shared/agent-hooks.ts +68 -0
- package/shared/agent-tools.ts +130 -0
- package/shared/custom-icon.ts +148 -0
- package/shared/graph-camera.ts +93 -0
- package/shared/live.ts +43 -0
- package/shared/prompts.ts +49 -1
- package/shared/settings.ts +34 -0
package/shared/prompts.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { TOOLS_SERVER } from "./agent-tools";
|
|
1
2
|
import type { IssueDetail } from "./linear";
|
|
2
|
-
import type { AgentAction, LinearSettings, ProjectConfig } from "./settings";
|
|
3
|
+
import type { AgentAction, Guidance, LinearSettings, ProjectConfig } from "./settings";
|
|
3
4
|
import { todoConventionLine } from "./todo-sync";
|
|
4
5
|
|
|
5
6
|
export const DEFAULT_TEMPLATES: Record<AgentAction, string> = {
|
|
@@ -112,6 +113,47 @@ export interface ComposePromptInput {
|
|
|
112
113
|
project: ProjectConfig | null;
|
|
113
114
|
includeComments: boolean;
|
|
114
115
|
extraInstructions: string;
|
|
116
|
+
/** Launch options that add instructions; the project's saved ones when omitted. */
|
|
117
|
+
guidance?: Guidance;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** The instructions each guidance option adds, in prompt order. */
|
|
121
|
+
export function guidanceSections(issue: IssueDetail, guidance: Guidance): string[] {
|
|
122
|
+
const sections: string[] = [];
|
|
123
|
+
const example = issue.children[0]?.identifier ?? issue.identifier;
|
|
124
|
+
if (guidance.updateLinear) {
|
|
125
|
+
sections.push(
|
|
126
|
+
[
|
|
127
|
+
"Keep Linear current while you work:",
|
|
128
|
+
`- Start each todo with the issue key it is for, such as "${example}: add the form".`,
|
|
129
|
+
"- Mark a todo in progress when you start it and completed when it is done. Linear Live moves the issue from these todos.",
|
|
130
|
+
`- Use the ${TOOLS_SERVER} MCP tools: read_issue shows an issue, and edit_issue changes its description.`,
|
|
131
|
+
"- When you finish a task list item in a description, check it off: replace `- [ ] item` with `- [x] item`.",
|
|
132
|
+
"- When the plan changes, update the description. Do not post comments.",
|
|
133
|
+
].join("\n"),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
if (guidance.subagentKeys) {
|
|
137
|
+
sections.push(
|
|
138
|
+
[
|
|
139
|
+
"When you start a subagent:",
|
|
140
|
+
`- Begin its description and its prompt with the Linear issue key it works on, such as "${example}: review the form".`,
|
|
141
|
+
"- Tell it to put that key in the first line of its reply, and to state the new key if its work moves to another issue.",
|
|
142
|
+
].join("\n"),
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
if (guidance.paseoSubagents) {
|
|
146
|
+
sections.push(
|
|
147
|
+
[
|
|
148
|
+
"Hand off work to Paseo agents, not to your built-in subagent tool:",
|
|
149
|
+
`- Start each one with the ${TOOLS_SERVER} start_agent tool, one agent for each sub-issue. It runs on your provider and model.`,
|
|
150
|
+
"- Set its thinking to fit the task: low for search and reading, medium for routine edits, high for design, debugging, and review.",
|
|
151
|
+
`- Start its title with the issue key, such as "${example}: write the tests". Give the full task in its prompt, because it does not see your conversation.`,
|
|
152
|
+
"- Call wait_agent for each agent and read its result before you continue.",
|
|
153
|
+
].join("\n"),
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
return sections;
|
|
115
157
|
}
|
|
116
158
|
|
|
117
159
|
export function composePrompt(input: ComposePromptInput): string {
|
|
@@ -139,6 +181,8 @@ export function composePrompt(input: ComposePromptInput): string {
|
|
|
139
181
|
`Project steps:\n${steps.map((step, index) => `${index + 1}. ${step}`).join("\n")}`,
|
|
140
182
|
);
|
|
141
183
|
}
|
|
184
|
+
const guidance = input.guidance ?? project?.guidance;
|
|
185
|
+
if (guidance) sections.push(...guidanceSections(issue, guidance));
|
|
142
186
|
const extra = input.extraInstructions.trim();
|
|
143
187
|
if (extra) sections.push(`Additional instructions:\n${extra}`);
|
|
144
188
|
return sections.join("\n\n");
|
|
@@ -157,6 +201,10 @@ export const AGENT_LABELS = {
|
|
|
157
201
|
project: "linear.project",
|
|
158
202
|
explore: "linear.explore",
|
|
159
203
|
init: "linear.init",
|
|
204
|
+
/** The grant of the agent's Linear MCP tools, so a tool call can find its agent. */
|
|
205
|
+
tools: "linear.tools",
|
|
206
|
+
/** The grant whose start_agent call made this agent. */
|
|
207
|
+
startedBy: "linear.started-by",
|
|
160
208
|
} as const;
|
|
161
209
|
|
|
162
210
|
/** Agents the plugin starts for itself: explore and project setup. */
|
package/shared/settings.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defineRpc, defineSettings } from "@getpaseo/plugin";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { IconSettingsSchema } from "./custom-icon";
|
|
3
4
|
|
|
4
5
|
export const AGENT_ACTIONS = ["implement", "review"] as const;
|
|
5
6
|
export type AgentAction = (typeof AGENT_ACTIONS)[number];
|
|
@@ -12,6 +13,18 @@ const ActionOverrideSchema = z.object({
|
|
|
12
13
|
text: z.string().default(""),
|
|
13
14
|
});
|
|
14
15
|
|
|
16
|
+
/** Extra instructions the launch adds to the prompt. Saved per project. */
|
|
17
|
+
export const GuidanceSchema = z.object({
|
|
18
|
+
/** Keep Linear current: todos with sub-issue keys, and comments when a Linear tool exists. */
|
|
19
|
+
updateLinear: z.boolean().default(false),
|
|
20
|
+
/** Subagents state the issue key they work on. Claude agents also get a hook that tells them. */
|
|
21
|
+
subagentKeys: z.boolean().default(false),
|
|
22
|
+
/** Hand work to Paseo agents on the same provider, with thinking that fits the task. */
|
|
23
|
+
paseoSubagents: z.boolean().default(false),
|
|
24
|
+
});
|
|
25
|
+
export type Guidance = z.infer<typeof GuidanceSchema>;
|
|
26
|
+
export const GUIDANCE_KEYS = ["updateLinear", "subagentKeys", "paseoSubagents"] as const;
|
|
27
|
+
|
|
15
28
|
export const ProjectConfigSchema = z.object({
|
|
16
29
|
projectId: z.string(),
|
|
17
30
|
displayName: z.string(),
|
|
@@ -21,9 +34,20 @@ export const ProjectConfigSchema = z.object({
|
|
|
21
34
|
steps: z.array(z.string()).default([]),
|
|
22
35
|
implement: ActionOverrideSchema.prefault({}),
|
|
23
36
|
review: ActionOverrideSchema.prefault({}),
|
|
37
|
+
guidance: GuidanceSchema.prefault({}),
|
|
24
38
|
});
|
|
25
39
|
export type ProjectConfig = z.infer<typeof ProjectConfigSchema>;
|
|
26
40
|
|
|
41
|
+
/** Settings with a project's guidance saved, adding the project when it has no entry yet. */
|
|
42
|
+
export function withProjectGuidance(
|
|
43
|
+
values: LinearSettings,
|
|
44
|
+
project: { projectId: string; displayName: string; rootPath: string },
|
|
45
|
+
guidance: Guidance,
|
|
46
|
+
): LinearSettings {
|
|
47
|
+
const known = values.projects.find((entry) => entry.projectId === project.projectId);
|
|
48
|
+
return { ...values, projects: upsertProject(values, { ...(known ?? emptyProjectConfig(project)), guidance }) };
|
|
49
|
+
}
|
|
50
|
+
|
|
27
51
|
export const ISOLATIONS = ["worktree", "workspace"] as const;
|
|
28
52
|
export type Isolation = (typeof ISOLATIONS)[number];
|
|
29
53
|
|
|
@@ -31,6 +55,9 @@ export const MAPPING_MODES = ["semantic", "explore"] as const;
|
|
|
31
55
|
export type MappingMode = (typeof MAPPING_MODES)[number];
|
|
32
56
|
|
|
33
57
|
export const LIVE_VIEWS = ["map", "graph"] as const;
|
|
58
|
+
/** Auto follows the running agents; fit shows the whole graph. */
|
|
59
|
+
export const GRAPH_CAMERAS = ["auto", "fit"] as const;
|
|
60
|
+
export type GraphCamera = (typeof GRAPH_CAMERAS)[number];
|
|
34
61
|
export type LiveView = (typeof LIVE_VIEWS)[number];
|
|
35
62
|
|
|
36
63
|
export const linearSettings = defineSettings({
|
|
@@ -57,9 +84,14 @@ export const linearSettings = defineSettings({
|
|
|
57
84
|
enabled: z.boolean().default(true),
|
|
58
85
|
mapping: z.enum(MAPPING_MODES).default("semantic"),
|
|
59
86
|
exploreProvider: z.string().default(""),
|
|
87
|
+
/** Thinking option of the explore model; empty is the model's default. */
|
|
88
|
+
exploreEffort: z.string().default(""),
|
|
60
89
|
syncTodos: z.boolean().default(false),
|
|
61
90
|
view: z.enum(LIVE_VIEWS).default("map"),
|
|
62
91
|
issuesCollapsed: z.boolean().default(false),
|
|
92
|
+
graphCamera: z.enum(GRAPH_CAMERAS).default("auto"),
|
|
93
|
+
/** The wheel and drags scroll the page instead of moving the graph. */
|
|
94
|
+
graphLocked: z.boolean().default(false),
|
|
63
95
|
})
|
|
64
96
|
.prefault({}),
|
|
65
97
|
// Where the plugin works: every project, minus or plus per-project switches.
|
|
@@ -70,6 +102,8 @@ export const linearSettings = defineSettings({
|
|
|
70
102
|
})
|
|
71
103
|
.prefault({}),
|
|
72
104
|
projects: z.array(ProjectConfigSchema).default([]),
|
|
105
|
+
/** The icon of pills and other plugin places: built-in or the user's SVG. */
|
|
106
|
+
icon: IconSettingsSchema.prefault({}),
|
|
73
107
|
}),
|
|
74
108
|
});
|
|
75
109
|
|