Files
fusion/plugins/fusion-plugin-linear-import/src/LinearImportView.css
gsxdsm dfb6e5270d FN-7443: add bundled Linear import plugin
Add a plugin-owned Linear importer that creates Fusion tasks from Linear issues.

- Add the fusion-plugin-linear-import package with settings, Linear GraphQL client, import routes, tools, and dashboard UI.
- Bundle and register the Linear import plugin in the CLI and dashboard plugin view registry.
- Document bundled plugin authoring details and cover duplicate detection, routes, tools, UI, and packaging with tests.

Files changed:
 .changeset/fn-7443-linear-import-plugin.md         |   7 +
 docs/PLUGIN_AUTHORING.md                           |   7 +
 docs/task-management.md                            |   2 +
 packages/cli/src/__tests__/bundle-output.test.ts   |  22 ++
 .../__tests__/bundled-plugin-install.test.ts       |  29 +++
 packages/cli/src/plugins/bundled-plugin-install.ts |   1 +
 .../cli/src/plugins/staged-bundled-plugin-ids.ts   |   1 +
 packages/cli/tsup.config.ts                        |   8 +
 .../__tests__/registerBundledPluginViews.test.tsx  |   9 +-
 .../app/plugins/registerBundledPluginViews.ts      |  18 ++
 .../app/types/plugin-dashboard-views.d.ts          |   9 +
 .../src/__tests__/routes-plugin-registry.test.ts   |   5 +
 .../runtime-plugin-alias-regression.test.ts        |  12 +
 packages/dashboard/src/registry-manifest.json      |  10 +
 packages/dashboard/vite.config.ts                  |   8 +
 packages/dashboard/vitest.config.ts                |   8 +
 plugins/fusion-plugin-linear-import/README.md      |  75 ++++++
 plugins/fusion-plugin-linear-import/manifest.json  |  48 ++++
 plugins/fusion-plugin-linear-import/package.json   |  38 +++
 .../scripts/copy-css.mjs                           |  11 +
 .../src/LinearImportView.css                       | 167 +++++++++++++
 .../src/LinearImportView.tsx                       | 263 +++++++++++++++++++++
 .../src/__tests__/LinearImportView.test.tsx        | 124 ++++++++++
 .../src/__tests__/import-linear.test.ts            |  78 ++++++
 .../src/__tests__/linear-client.test.ts            |  81 +++++++
 .../src/__tests__/routes.test.ts                   |  90 +++++++
 .../src/__tests__/tools.test.ts                    |  79 +++++++
 .../src/dashboard-interop.d.ts                     |  13 +
 .../src/dashboard-view.tsx                         |  10 +
 .../src/import-linear.ts                           | 154 ++++++++++++
 plugins/fusion-plugin-linear-import/src/index.ts   |  45 ++++
 .../src/linear-client.ts                           | 247 +++++++++++++++++++
 plugins/fusion-plugin-linear-import/src/routes.ts  | 149 ++++++++++++
 .../fusion-plugin-linear-import/src/settings.ts    |  68 ++++++
 plugins/fusion-plugin-linear-import/src/tools.ts   | 138 +++++++++++
 plugins/fusion-plugin-linear-import/tsconfig.json  |  14 ++
 .../fusion-plugin-linear-import/vitest.config.ts   |  40 ++++
 pnpm-lock.yaml                                     |  40 ++++
 pnpm-workspace.yaml                                |   1 +
 39 files changed, 2128 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7443
Fusion-Task-Lineage: a016a9d4-84a4-4a0b-b9b6-b9a2886da49a
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 14:31:16 -07:00

168 lines
4.1 KiB
CSS

.linear-import-view {
display: flex;
flex-direction: column;
gap: var(--space-lg);
padding: var(--space-lg);
min-height: 0;
}
.linear-import-view__header {
display: flex;
justify-content: space-between;
gap: var(--space-md);
align-items: flex-start;
}
.linear-import-view__eyebrow,
.linear-import-view__meta,
.linear-import-view__empty,
.linear-import-view__helper {
color: var(--text-muted);
}
.linear-import-view__title {
margin: 0;
}
.linear-import-view__subtitle {
margin: var(--space-xs) 0 0;
color: var(--text-muted);
}
.linear-import-view__status {
display: inline-flex;
align-items: center;
gap: var(--space-xs);
border: var(--border-width) solid var(--border-color);
border-radius: var(--radius-pill);
padding: var(--space-xs) var(--space-sm);
font-size: var(--font-size-sm);
white-space: nowrap;
}
.linear-import-view__status--auth { color: var(--color-success); border-color: color-mix(in srgb, var(--color-success) 40%, var(--border-color)); }
.linear-import-view__status--warning { color: var(--color-warning); border-color: color-mix(in srgb, var(--color-warning) 40%, var(--border-color)); }
.linear-import-view__status--error { color: var(--color-error); border-color: color-mix(in srgb, var(--color-error) 40%, var(--border-color)); }
.linear-import-view__status--info { color: var(--color-info); border-color: color-mix(in srgb, var(--color-info) 40%, var(--border-color)); }
.linear-import-view__filters {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: var(--space-md);
align-items: end;
}
.linear-import-view__field {
display: flex;
flex-direction: column;
gap: var(--space-xs);
}
.linear-import-view__actions,
.linear-import-view__issue-actions {
display: flex;
flex-wrap: wrap;
gap: var(--space-sm);
}
.linear-import-view__content {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(18rem, 0.75fr);
gap: var(--space-lg);
min-height: 0;
}
.linear-import-view__issue-list {
display: flex;
flex-direction: column;
gap: var(--space-sm);
max-height: 55vh;
overflow: auto;
}
.linear-import-view__issue {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
gap: var(--space-sm);
align-items: start;
text-align: left;
width: 100%;
}
.linear-import-view__issue-main {
min-width: 0;
}
.linear-import-view__issue-title {
display: flex;
flex-wrap: wrap;
gap: var(--space-xs);
align-items: baseline;
margin: 0;
}
.linear-import-view__identifier {
color: var(--color-info);
font-weight: var(--font-weight-semibold, 600);
}
.linear-import-view__badges {
display: flex;
flex-wrap: wrap;
gap: var(--space-xs);
margin-top: var(--space-xs);
}
.linear-import-view__badge {
border: var(--border-width) solid var(--border-color);
border-radius: var(--radius-pill);
padding: 0 var(--space-xs);
color: var(--text-muted);
font-size: var(--font-size-sm);
}
.linear-import-view__preview {
display: flex;
flex-direction: column;
gap: var(--space-md);
min-width: 0;
}
.linear-import-view__preview-body {
white-space: pre-wrap;
overflow: auto;
max-height: 45vh;
color: var(--text-primary);
}
.linear-import-view__message {
border-radius: var(--radius-md);
padding: var(--space-md);
border: var(--border-width) solid var(--border-color);
}
.linear-import-view__message--error { color: var(--color-error); border-color: color-mix(in srgb, var(--color-error) 45%, var(--border-color)); }
.linear-import-view__message--success { color: var(--color-success); border-color: color-mix(in srgb, var(--color-success) 45%, var(--border-color)); }
.linear-import-view__message--info { color: var(--color-info); border-color: color-mix(in srgb, var(--color-info) 45%, var(--border-color)); }
@media (max-width: 48rem) {
.linear-import-view {
padding: var(--space-md);
}
.linear-import-view__header,
.linear-import-view__content {
grid-template-columns: 1fr;
display: grid;
}
.linear-import-view__filters {
grid-template-columns: 1fr;
}
.linear-import-view__issue-list,
.linear-import-view__preview-body {
max-height: none;
}
}