@grafana/create-plugin 6.2.0-canary.2314.19503588692.0 → 6.2.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/CHANGELOG.md +12 -0
- package/dist/bin/run.js +3 -1
- package/dist/codemods/additions/additions.js +9 -0
- package/dist/codemods/additions/scripts/example-addition.js +47 -0
- package/dist/{migrations → codemods}/context.js +3 -2
- package/dist/codemods/migrations/manager.js +32 -0
- package/dist/codemods/migrations/migrations.js +50 -0
- package/dist/{migrations → codemods/migrations}/scripts/003-update-eslint-deprecation-rule.js +1 -1
- package/dist/{migrations → codemods/migrations}/scripts/004-eslint9-flat-config.js +1 -1
- package/dist/{migrations → codemods/migrations}/scripts/005-react-18-3.js +1 -1
- package/dist/{migrations → codemods/migrations}/scripts/007-remove-testing-library-types.js +1 -1
- package/dist/codemods/runner.js +33 -0
- package/dist/codemods/schema-parser.js +20 -0
- package/dist/{migrations → codemods}/utils.js +5 -16
- package/dist/commands/add.command.js +51 -0
- package/dist/commands/update.command.js +8 -42
- package/dist/utils/utils.checks.js +40 -0
- package/package.json +3 -2
- package/src/bin/run.ts +2 -1
- package/src/codemods/additions/additions.test.ts +17 -0
- package/src/codemods/additions/additions.ts +9 -0
- package/src/codemods/additions/scripts/example-addition.test.ts +92 -0
- package/src/codemods/additions/scripts/example-addition.ts +62 -0
- package/src/{migrations → codemods}/context.test.ts +10 -10
- package/src/{migrations → codemods}/context.ts +4 -2
- package/src/codemods/migrations/fixtures/migrations.ts +20 -0
- package/src/{migrations → codemods/migrations}/manager.test.ts +76 -77
- package/src/codemods/migrations/manager.ts +50 -0
- package/src/codemods/migrations/migrations.test.ts +17 -0
- package/src/codemods/migrations/migrations.ts +55 -0
- package/src/{migrations → codemods/migrations}/scripts/001-update-grafana-compose-extend.test.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/001-update-grafana-compose-extend.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/002-update-is-compatible-workflow.test.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/002-update-is-compatible-workflow.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/003-update-eslint-deprecation-rule.test.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/003-update-eslint-deprecation-rule.ts +2 -2
- package/src/{migrations → codemods/migrations}/scripts/004-eslint9-flat-config.test.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/004-eslint9-flat-config.ts +2 -2
- package/src/{migrations → codemods/migrations}/scripts/005-react-18-3.test.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/005-react-18-3.ts +2 -2
- package/src/{migrations → codemods/migrations}/scripts/006-webpack-nested-fix.test.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/006-webpack-nested-fix.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/007-remove-testing-library-types.test.ts +1 -1
- package/src/{migrations → codemods/migrations}/scripts/007-remove-testing-library-types.ts +2 -2
- package/src/codemods/runner.ts +51 -0
- package/src/codemods/schema-parser.ts +27 -0
- package/src/codemods/types.ts +16 -0
- package/src/{migrations → codemods}/utils.test.ts +5 -4
- package/src/{migrations → codemods}/utils.ts +8 -22
- package/src/commands/add.command.ts +56 -0
- package/src/commands/index.ts +1 -0
- package/src/commands/update.command.ts +9 -48
- package/src/utils/utils.checks.ts +47 -0
- package/dist/migrations/manager.js +0 -58
- package/dist/migrations/migrations.js +0 -43
- package/dist/migrations/scripts/example-migration.js +0 -25
- package/src/migrations/fixtures/migrations.ts +0 -19
- package/src/migrations/manager.ts +0 -82
- package/src/migrations/migrations.test.ts +0 -16
- package/src/migrations/migrations.ts +0 -55
- package/src/migrations/scripts/example-migration.test.ts +0 -40
- package/src/migrations/scripts/example-migration.ts +0 -34
- package/templates/panel/.config/AGENTS/fundamentals.md +0 -66
- package/templates/panel/AGENTS.md +0 -3
- /package/dist/{migrations → codemods/migrations}/scripts/001-update-grafana-compose-extend.js +0 -0
- /package/dist/{migrations → codemods/migrations}/scripts/002-update-is-compatible-workflow.js +0 -0
- /package/dist/{migrations → codemods/migrations}/scripts/006-webpack-nested-fix.js +0 -0
- /package/src/{migrations → codemods/migrations}/fixtures/foo/bar.ts +0 -0
- /package/src/{migrations → codemods/migrations}/fixtures/foo/baz.ts +0 -0
- /package/src/{migrations → codemods}/test-utils.ts +0 -0
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
function migrate(context) {
|
|
2
|
-
const rawPkgJson = context.getFile("./package.json") ?? "{}";
|
|
3
|
-
const packageJson = JSON.parse(rawPkgJson);
|
|
4
|
-
if (packageJson.scripts && packageJson.scripts.build) {
|
|
5
|
-
const buildScript = packageJson.scripts.build;
|
|
6
|
-
const pattern = /(webpack.+-c\s.+\.ts)\s(.+)/;
|
|
7
|
-
if (pattern.test(buildScript) && !buildScript.includes("--profile")) {
|
|
8
|
-
packageJson.scripts.build = buildScript.replace(pattern, `$1 --profile $2`);
|
|
9
|
-
}
|
|
10
|
-
context.updateFile("./package.json", JSON.stringify(packageJson, null, 2));
|
|
11
|
-
}
|
|
12
|
-
if (context.doesFileExist("./src/README.md")) {
|
|
13
|
-
context.deleteFile("./src/README.md");
|
|
14
|
-
}
|
|
15
|
-
if (!context.doesFileExist("./src/foo.json")) {
|
|
16
|
-
context.addFile("./src/foo.json", JSON.stringify({ foo: "bar" }));
|
|
17
|
-
}
|
|
18
|
-
if (context.doesFileExist(".eslintrc")) {
|
|
19
|
-
context.renameFile(".eslintrc", ".eslint.config.json");
|
|
20
|
-
}
|
|
21
|
-
context.readDir("./src");
|
|
22
|
-
return context;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export { migrate as default };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
migrations: {
|
|
3
|
-
'migration-key1': {
|
|
4
|
-
version: '5.0.0',
|
|
5
|
-
description: 'Update project to use new cache directory',
|
|
6
|
-
migrationScript: './5-0-0-cache-directory.js',
|
|
7
|
-
},
|
|
8
|
-
'migration-key2': {
|
|
9
|
-
version: '5.4.0',
|
|
10
|
-
description: 'Update project to use new cache directory',
|
|
11
|
-
migrationScript: './5-4-0-cache-directory.js',
|
|
12
|
-
},
|
|
13
|
-
'migration-key3': {
|
|
14
|
-
version: '6.0.0',
|
|
15
|
-
description: 'Update project to use new cache directory',
|
|
16
|
-
migrationScript: './5-4-0-cache-directory.js',
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
};
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { satisfies, gte } from 'semver';
|
|
2
|
-
import { Context } from './context.js';
|
|
3
|
-
import defaultMigrations, { MigrationMeta } from './migrations.js';
|
|
4
|
-
import { flushChanges, printChanges, migrationsDebug, formatFiles, installNPMDependencies } from './utils.js';
|
|
5
|
-
import { gitCommitNoVerify } from '../utils/utils.git.js';
|
|
6
|
-
import { setRootConfig } from '../utils/utils.config.js';
|
|
7
|
-
import { output } from '../utils/utils.console.js';
|
|
8
|
-
import { CURRENT_APP_VERSION } from '../utils/utils.version.js';
|
|
9
|
-
|
|
10
|
-
export type MigrationFn = (context: Context) => Context | Promise<Context>;
|
|
11
|
-
|
|
12
|
-
export function getMigrationsToRun(
|
|
13
|
-
fromVersion: string,
|
|
14
|
-
toVersion: string,
|
|
15
|
-
migrations: Record<string, MigrationMeta> = defaultMigrations.migrations
|
|
16
|
-
): Record<string, MigrationMeta> {
|
|
17
|
-
const semverRange = `${fromVersion} - ${toVersion}`;
|
|
18
|
-
|
|
19
|
-
const migrationsToRun = Object.entries(migrations)
|
|
20
|
-
.sort((a, b) => {
|
|
21
|
-
return gte(a[1].version, b[1].version) ? 1 : -1;
|
|
22
|
-
})
|
|
23
|
-
.reduce<Record<string, MigrationMeta>>((acc, [key, meta]) => {
|
|
24
|
-
if (satisfies(meta.version, semverRange)) {
|
|
25
|
-
acc[key] = meta;
|
|
26
|
-
}
|
|
27
|
-
return acc;
|
|
28
|
-
}, {});
|
|
29
|
-
|
|
30
|
-
return migrationsToRun;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
type RunMigrationsOptions = {
|
|
34
|
-
commitEachMigration?: boolean;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export async function runMigrations(migrations: Record<string, MigrationMeta>, options: RunMigrationsOptions = {}) {
|
|
38
|
-
const basePath = process.cwd();
|
|
39
|
-
const migrationList = Object.entries(migrations).map(
|
|
40
|
-
([key, migrationMeta]) => `${key} (${migrationMeta.description})`
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
const migrationListBody = migrationList.length > 0 ? output.bulletList(migrationList) : ['No migrations to run.'];
|
|
44
|
-
|
|
45
|
-
output.log({ title: 'Running the following migrations:', body: migrationListBody });
|
|
46
|
-
|
|
47
|
-
for (const [key, migration] of Object.entries(migrations)) {
|
|
48
|
-
try {
|
|
49
|
-
const context = await runMigration(migration, new Context(basePath));
|
|
50
|
-
const shouldCommit = options.commitEachMigration && context.hasChanges();
|
|
51
|
-
|
|
52
|
-
migrationsDebug(`context for "${key} (${migration.migrationScript})":`);
|
|
53
|
-
migrationsDebug('%O', context.listChanges());
|
|
54
|
-
|
|
55
|
-
await formatFiles(context);
|
|
56
|
-
flushChanges(context);
|
|
57
|
-
printChanges(context, key, migration);
|
|
58
|
-
|
|
59
|
-
installNPMDependencies(context);
|
|
60
|
-
|
|
61
|
-
if (shouldCommit) {
|
|
62
|
-
await gitCommitNoVerify(`chore: run create-plugin migration - ${key} (${migration.migrationScript})`);
|
|
63
|
-
}
|
|
64
|
-
} catch (error) {
|
|
65
|
-
if (error instanceof Error) {
|
|
66
|
-
throw new Error(`Error running migration "${key} (${migration.migrationScript})": ${error.message}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
setRootConfig({ version: CURRENT_APP_VERSION });
|
|
72
|
-
|
|
73
|
-
if (options.commitEachMigration) {
|
|
74
|
-
await gitCommitNoVerify(`chore: update .config/.cprc.json to version ${CURRENT_APP_VERSION}.`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export async function runMigration(migration: MigrationMeta, context: Context): Promise<Context> {
|
|
79
|
-
const module: { default: MigrationFn } = await import(migration.migrationScript);
|
|
80
|
-
|
|
81
|
-
return module.default(context);
|
|
82
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import defaultMigrations from './migrations.js';
|
|
4
|
-
|
|
5
|
-
describe('migrations json', () => {
|
|
6
|
-
// As migration scripts are imported dynamically when update is run we assert the path is valid
|
|
7
|
-
// Vitest 4 reimplemented it's workers which caused the previous dynamic import tests to fail.
|
|
8
|
-
// This test now only asserts that the source file exists.
|
|
9
|
-
Object.entries(defaultMigrations.migrations).forEach(([key, migration]) => {
|
|
10
|
-
it(`should have a valid migration script path for ${key}`, () => {
|
|
11
|
-
const migrationPathString = migration.migrationScript.replace('.js', '.ts');
|
|
12
|
-
const path = join(__dirname, migrationPathString);
|
|
13
|
-
expect(existsSync(path)).toBe(true);
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
});
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { LEGACY_UPDATE_CUTOFF_VERSION } from '../constants.js';
|
|
2
|
-
|
|
3
|
-
export type MigrationMeta = {
|
|
4
|
-
version: string;
|
|
5
|
-
description: string;
|
|
6
|
-
migrationScript: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
type Migrations = {
|
|
10
|
-
migrations: Record<string, MigrationMeta>;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
// Do not use LEGACY_UPDATE_CUTOFF_VERSION for new migrations. It was used to force migrations to run
|
|
14
|
-
// for those written before the switch to updates as migrations.
|
|
15
|
-
export default {
|
|
16
|
-
migrations: {
|
|
17
|
-
'001-update-grafana-compose-extend': {
|
|
18
|
-
version: LEGACY_UPDATE_CUTOFF_VERSION,
|
|
19
|
-
description: 'Update ./docker-compose.yaml to extend from ./.config/docker-compose-base.yaml.',
|
|
20
|
-
migrationScript: './scripts/001-update-grafana-compose-extend.js',
|
|
21
|
-
},
|
|
22
|
-
'002-update-is-compatible-workflow': {
|
|
23
|
-
version: LEGACY_UPDATE_CUTOFF_VERSION,
|
|
24
|
-
description:
|
|
25
|
-
'Update ./.github/workflows/is-compatible.yml to use is-compatible github action instead of calling levitate directly',
|
|
26
|
-
migrationScript: './scripts/002-update-is-compatible-workflow.js',
|
|
27
|
-
},
|
|
28
|
-
'003-update-eslint-deprecation-rule': {
|
|
29
|
-
version: LEGACY_UPDATE_CUTOFF_VERSION,
|
|
30
|
-
description: 'Replace deprecated eslint-plugin-deprecation with @typescript-eslint/no-deprecated rule.',
|
|
31
|
-
migrationScript: './scripts/003-update-eslint-deprecation-rule.js',
|
|
32
|
-
},
|
|
33
|
-
'004-eslint9-flat-config': {
|
|
34
|
-
version: LEGACY_UPDATE_CUTOFF_VERSION,
|
|
35
|
-
description: 'Migrate eslint config to flat config format and update devDependencies to latest versions.',
|
|
36
|
-
migrationScript: './scripts/004-eslint9-flat-config.js',
|
|
37
|
-
},
|
|
38
|
-
'005-react-18-3': {
|
|
39
|
-
version: '6.1.9',
|
|
40
|
-
description: 'Update React and ReactDOM 18.x versions to ^18.3.0 to surface React 19 compatibility issues.',
|
|
41
|
-
migrationScript: './scripts/005-react-18-3.js',
|
|
42
|
-
},
|
|
43
|
-
'006-webpack-nested-fix': {
|
|
44
|
-
version: '6.1.11',
|
|
45
|
-
description: 'Fix webpack variable replacement in nested plugins files.',
|
|
46
|
-
migrationScript: './scripts/006-webpack-nested-fix.js',
|
|
47
|
-
},
|
|
48
|
-
'007-remove-testing-library-types': {
|
|
49
|
-
version: '6.1.13',
|
|
50
|
-
description:
|
|
51
|
-
'Add setupTests.d.ts for @testing-library/jest-dom types and remove @types/testing-library__jest-dom npm package.',
|
|
52
|
-
migrationScript: './scripts/007-remove-testing-library-types.js',
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
} as Migrations;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import migrate from './example-migration.js';
|
|
2
|
-
import { createDefaultContext } from '../test-utils.js';
|
|
3
|
-
|
|
4
|
-
describe('Migration - append profile to webpack', () => {
|
|
5
|
-
test('should update the package.json', async () => {
|
|
6
|
-
const context = createDefaultContext();
|
|
7
|
-
|
|
8
|
-
context.updateFile(
|
|
9
|
-
'./package.json',
|
|
10
|
-
JSON.stringify({
|
|
11
|
-
scripts: {
|
|
12
|
-
build: 'webpack -c ./.config/webpack/webpack.config.ts --env production',
|
|
13
|
-
},
|
|
14
|
-
})
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
const updatedContext = await migrate(context);
|
|
18
|
-
|
|
19
|
-
expect(updatedContext.getFile('./package.json')).toMatch(
|
|
20
|
-
'webpack -c ./.config/webpack/webpack.config.ts --profile --env production'
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
expect(updatedContext.readDir('./src')).toEqual(['src/FOO.md', 'src/foo.json']);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('should not make additional changes when run multiple times', async () => {
|
|
27
|
-
const context = await createDefaultContext();
|
|
28
|
-
|
|
29
|
-
await context.updateFile(
|
|
30
|
-
'./package.json',
|
|
31
|
-
JSON.stringify({
|
|
32
|
-
scripts: {
|
|
33
|
-
build: 'webpack -c ./.config/webpack/webpack.config.ts --env production',
|
|
34
|
-
},
|
|
35
|
-
})
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
await expect(migrate).toBeIdempotent(context);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { Context } from '../context.js';
|
|
2
|
-
|
|
3
|
-
export default function migrate(context: Context): Context {
|
|
4
|
-
const rawPkgJson = context.getFile('./package.json') ?? '{}';
|
|
5
|
-
const packageJson = JSON.parse(rawPkgJson);
|
|
6
|
-
|
|
7
|
-
if (packageJson.scripts && packageJson.scripts.build) {
|
|
8
|
-
const buildScript = packageJson.scripts.build;
|
|
9
|
-
|
|
10
|
-
const pattern = /(webpack.+-c\s.+\.ts)\s(.+)/;
|
|
11
|
-
|
|
12
|
-
if (pattern.test(buildScript) && !buildScript.includes('--profile')) {
|
|
13
|
-
packageJson.scripts.build = buildScript.replace(pattern, `$1 --profile $2`);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
context.updateFile('./package.json', JSON.stringify(packageJson, null, 2));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (context.doesFileExist('./src/README.md')) {
|
|
20
|
-
context.deleteFile('./src/README.md');
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (!context.doesFileExist('./src/foo.json')) {
|
|
24
|
-
context.addFile('./src/foo.json', JSON.stringify({ foo: 'bar' }));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (context.doesFileExist('.eslintrc')) {
|
|
28
|
-
context.renameFile('.eslintrc', '.eslint.config.json');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
context.readDir('./src');
|
|
32
|
-
|
|
33
|
-
return context;
|
|
34
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
## Project overview
|
|
2
|
-
|
|
3
|
-
This repository contains a Grafana panel plugin, which adds a custom visualization that can be used in Grafana dashboards. Panel plugins are useful when you want to:
|
|
4
|
-
|
|
5
|
-
- Present data from Grafana data source queries in a new or specialized way
|
|
6
|
-
- Add custom interactivity, such as navigation or drill-downs
|
|
7
|
-
- Visualize or control external systems (for example, IoT devices or custom integrations)
|
|
8
|
-
|
|
9
|
-
### High-level anatomy of a Grafana panel plugin
|
|
10
|
-
|
|
11
|
-
A typical panel plugin has:
|
|
12
|
-
|
|
13
|
-
- A plugin **manifest** (`plugin.json`)
|
|
14
|
-
- Declares plugin ID, type (`panel`), name, version, and metadata
|
|
15
|
-
- Picked up by Grafana during boot time to register plugin.
|
|
16
|
-
|
|
17
|
-
- A **main module** (usually `src/module.ts` or `src/module.tsx`)
|
|
18
|
-
- Calls `new PanelPlugin(PanelComponent)` from `@grafana/data` and expose the instance from the module.
|
|
19
|
-
- Optionally wires in the options editor, panel migration handler, and panel defaults
|
|
20
|
-
|
|
21
|
-
- A panel React component (e.g. `src/components/Panel.tsx`)
|
|
22
|
-
- Renders the visualization
|
|
23
|
-
- Receives props such as `data`, `timeRange`, `width`, `height`, and `options`
|
|
24
|
-
- Works with Grafana data frames and field configuration APIs to read query results and settings.
|
|
25
|
-
|
|
26
|
-
## Goals for AI coding agents
|
|
27
|
-
|
|
28
|
-
When working on this project, AI agents should:
|
|
29
|
-
|
|
30
|
-
- Maintain the existing options schema unless a proper migration handler is implemented
|
|
31
|
-
- Follow idiomatic React and TypeScript practices consistent with Grafana’s official example plugins
|
|
32
|
-
- Treat AGENTS.md as the authoritative source. If anything in .config/AGENTS conflicts with this file, follow the instructions in AGENTS.md
|
|
33
|
-
|
|
34
|
-
## Repository layout (typical)
|
|
35
|
-
|
|
36
|
-
- `plugin.json` – Grafana plugin manifest (type: `panel`)
|
|
37
|
-
- `src/module.ts` – main plugin entry point (creates `PanelPlugin`)
|
|
38
|
-
- `src/components` – React components for the panel
|
|
39
|
-
- `src/types.ts` – TypeScript types for panel options and internal models
|
|
40
|
-
- `tests/` – End-to-end tests (if configured)
|
|
41
|
-
- `provisioning/` - Provisioning files used in the local development environment.
|
|
42
|
-
- `README.md` – Human-facing project documentation
|
|
43
|
-
|
|
44
|
-
## Coding guidelines
|
|
45
|
-
|
|
46
|
-
- Use **TypeScript** for all plugin code.
|
|
47
|
-
- Prefer **functional React components** and hooks.
|
|
48
|
-
- Use **Grafana UI components** (`@grafana/ui`) and **Grafana data APIs** (`@grafana/data`) or **Grafana runtime APIs** (`@grafana/runtime`) instead of custom UI or data abstractions whenever possible.
|
|
49
|
-
- Keep the panel responsive:
|
|
50
|
-
- Respect `width` and `height` props.
|
|
51
|
-
- Avoid fixed layout sizes that break in narrow panels or large screens.
|
|
52
|
-
- Avoid introducing new dependencies unless:
|
|
53
|
-
- They’re necessary
|
|
54
|
-
- They’re compatible with Grafana’s frontend environment and plugin guidelines
|
|
55
|
-
- If custom styling is needed, please using `Emotion`.
|
|
56
|
-
|
|
57
|
-
## Safety & constraints for agents
|
|
58
|
-
|
|
59
|
-
- Do **not** change `plugin.json` IDs or plugin type.
|
|
60
|
-
- Do **not** change anything in the `.config` folder.
|
|
61
|
-
- Do **not** add a backend to this plugin. A panel plugin is a frontend only plugin.
|
|
62
|
-
- Do **not** remove or break existing option fields without:
|
|
63
|
-
- Adding a migration handler, or
|
|
64
|
-
- Updating all usages and tests accordingly.
|
|
65
|
-
- Keep changes to public interfaces (options, field configs, panel props) backwards compatible where possible.
|
|
66
|
-
- When in doubt, mirror patterns from Grafana’s official panel plugin examples and docs.
|
/package/dist/{migrations → codemods/migrations}/scripts/001-update-grafana-compose-extend.js
RENAMED
|
File without changes
|
/package/dist/{migrations → codemods/migrations}/scripts/002-update-is-compatible-workflow.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|