@monosmith/plugin-sdk 2.0.0-beta.4 → 2.0.0-beta.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monosmith/plugin-sdk",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.5",
4
4
  "description": "The TypeScript SDK for writing smith plugins: the protocol's types, the serve loop, a test host, the conformance checks, templating and key-order-keeping JSON editing. No runtime dependencies.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -175,6 +175,28 @@ export const protocolSchema = {
175
175
  "capability": "dependencies",
176
176
  "notification": false
177
177
  },
178
+ "dependencies/link": {
179
+ "description": "Makes a project depend on a library of the same workspace and language, in the ecosystem's own form, then installs or locks as that needs.",
180
+ "params": {
181
+ "$ref": "#/$defs/LinkParams"
182
+ },
183
+ "result": {
184
+ "$ref": "#/$defs/LinkResult"
185
+ },
186
+ "capability": "link",
187
+ "notification": false
188
+ },
189
+ "dependencies/unlink": {
190
+ "description": "Removes the dependency of a project on a library of the same workspace.",
191
+ "params": {
192
+ "$ref": "#/$defs/UnlinkParams"
193
+ },
194
+ "result": {
195
+ "$ref": "#/$defs/DependencyResult"
196
+ },
197
+ "capability": "link",
198
+ "notification": false
199
+ },
178
200
  "dependencies/declared": {
179
201
  "description": "Lists the dependencies the manifests of the plugin's projects declare.",
180
202
  "params": {
@@ -589,6 +611,10 @@ export const protocolSchema = {
589
611
  "type": "boolean",
590
612
  "description": "Dependencies installs and uninstalls packages in its projects."
591
613
  },
614
+ "link": {
615
+ "type": "boolean",
616
+ "description": "Link makes a project depend on a library of the same workspace in the ecosystem's own form (a workspace dependency, a path dependency, a project reference), and takes it out again. A plugin without it is refused by the host with one sentence that tells the user to add the dependency by hand."
617
+ },
592
618
  "declarations": {
593
619
  "type": "boolean",
594
620
  "description": "Declarations lists and rewrites declared dependency specs (sync, up)."
@@ -692,6 +718,21 @@ export const protocolSchema = {
692
718
  "description": {
693
719
  "type": "string"
694
720
  },
721
+ "title": {
722
+ "type": "string",
723
+ "description": "Title is the name shown to a person (\"Electron\" for electron). Without it the name is shown."
724
+ },
725
+ "aliases": {
726
+ "type": "array",
727
+ "items": {
728
+ "type": "string"
729
+ },
730
+ "description": "Aliases are words that find the choice when a person searches the catalogue (smith compose): \"desktop\", \"serverless\", \"web\"."
731
+ },
732
+ "layer": {
733
+ "type": "string",
734
+ "description": "Layer is where the choice sits in the stack of a project: \"framework\", \"shell\" (a desktop shell), \"host\" (where cloud code runs), \"test\", \"lint\", \"style\" or a layer of the plugin's own. Without it the layer is the axis. It is for display and grouping: the axis decides conflicts."
735
+ },
695
736
  "language": {
696
737
  "type": "string",
697
738
  "description": "Language is the language plugin the choice applies to (\"node\")."
@@ -714,6 +755,10 @@ export const protocolSchema = {
714
755
  "type": "boolean",
715
756
  "description": "Default marks the choice the host adds when a selection needs its axis and has no choice on it."
716
757
  },
758
+ "suggested": {
759
+ "type": "boolean",
760
+ "description": "Suggested marks the choice an asker pre-selects on its axis. The solver never adds it by itself: an axis that a choice needs and that has no Default is asked, and the person answers (ADR 0072)."
761
+ },
717
762
  "many": {
718
763
  "type": "boolean",
719
764
  "description": "Many allows the choice next to other choices of its axis that are Many too. By default a selection has one choice per axis."
@@ -1589,6 +1634,13 @@ export const protocolSchema = {
1589
1634
  "$ref": "#/$defs/Choice"
1590
1635
  },
1591
1636
  "description": "Choices are the options on an axis (framework, test, style) the plugin owns. The host lists them (smith choices) and checks a selection of them (smith add --with). Absent means the plugin owns none."
1637
+ },
1638
+ "tools": {
1639
+ "type": "array",
1640
+ "items": {
1641
+ "$ref": "#/$defs/ToolNeed"
1642
+ },
1643
+ "description": "Tools are the programs the plugin needs on the person's machine. The host detects them and, when one is missing, presents the ways to get it (smith tools). Absent means the plugin declares none."
1592
1644
  }
1593
1645
  },
1594
1646
  "required": [
@@ -1685,6 +1737,94 @@ export const protocolSchema = {
1685
1737
  }
1686
1738
  }
1687
1739
  },
1740
+ "LinkOption": {
1741
+ "description": "LinkOption is one way to write the dependency, with its consequence in words a person who read no manual can follow.",
1742
+ "type": "object",
1743
+ "properties": {
1744
+ "spec": {
1745
+ "type": "string",
1746
+ "description": "Spec is the value passed back in LinkParams.Spec."
1747
+ },
1748
+ "label": {
1749
+ "type": "string",
1750
+ "description": "Label is the option in a few words."
1751
+ },
1752
+ "meaning": {
1753
+ "type": "string",
1754
+ "description": "Meaning says what happens with this option."
1755
+ }
1756
+ },
1757
+ "required": [
1758
+ "spec",
1759
+ "label",
1760
+ "meaning"
1761
+ ]
1762
+ },
1763
+ "LinkParams": {
1764
+ "description": "LinkParams asks a plugin to make Project depend on Library, a lib or package of the same workspace and language, in the ecosystem's own form, and to install or lock as that needs. The host has checked that both exist, that the languages match, that Library is not an app, and that the link makes no cycle; the plugin answers with an error that names the file when it cannot write the dependency.",
1765
+ "type": "object",
1766
+ "properties": {
1767
+ "project": {
1768
+ "$ref": "#/$defs/Project",
1769
+ "description": "Project is the project that gains the dependency."
1770
+ },
1771
+ "library": {
1772
+ "$ref": "#/$defs/Project",
1773
+ "description": "Library is the project it depends on."
1774
+ },
1775
+ "quiet": {
1776
+ "type": "boolean",
1777
+ "description": "Quiet keeps the package manager's output unless it fails."
1778
+ },
1779
+ "plan": {
1780
+ "type": "boolean",
1781
+ "description": "Plan asks for the plan only: the plugin writes nothing and answers with the manifest, the line it would write and the choices the user has."
1782
+ },
1783
+ "spec": {
1784
+ "type": "string",
1785
+ "description": "Spec is the version range the user chose from LinkResult.Options; empty means the plugin's default, or the form the workspace already uses."
1786
+ }
1787
+ },
1788
+ "required": [
1789
+ "project",
1790
+ "library"
1791
+ ]
1792
+ },
1793
+ "LinkResult": {
1794
+ "description": "LinkResult is what a link wrote, or with LinkParams.Plan would write.",
1795
+ "type": "object",
1796
+ "properties": {
1797
+ "files": {
1798
+ "type": "array",
1799
+ "items": {
1800
+ "type": "string"
1801
+ },
1802
+ "description": "Files are the workspace-relative files changed (or to be changed)."
1803
+ },
1804
+ "notes": {
1805
+ "type": "array",
1806
+ "items": {
1807
+ "type": "string"
1808
+ },
1809
+ "description": "Notes are for the user."
1810
+ },
1811
+ "manifest": {
1812
+ "type": "string",
1813
+ "description": "Manifest is the file the dependency goes into, workspace-relative."
1814
+ },
1815
+ "line": {
1816
+ "type": "string",
1817
+ "description": "Line is the dependency as it is written there, for the plan shown before anything is written (\"@acme/core\": \"*\")."
1818
+ },
1819
+ "options": {
1820
+ "type": "array",
1821
+ "items": {
1822
+ "$ref": "#/$defs/LinkOption"
1823
+ },
1824
+ "description": "Options are the real choices of the range written, with the default first. Empty when the ecosystem has none, or the workspace already follows a convention (then Line shows it)."
1825
+ }
1826
+ }
1827
+ },
1688
1828
  "PackageStore": {
1689
1829
  "description": "PackageStore is where a package manager keeps what it downloaded (npm's ~/.npm, Go's module cache). A generated pipeline restores it before setup and saves it after a run, keyed on Files, so `npm ci` or `go mod download` fetches only what changed. A pull request from a fork restores it and never writes the base repository's cache.",
1690
1830
  "type": "object",
@@ -2402,6 +2542,121 @@ export const protocolSchema = {
2402
2542
  "command"
2403
2543
  ]
2404
2544
  },
2545
+ "ToolInstall": {
2546
+ "description": "ToolInstall is one way to get a tool with a package manager. Manager is one of: \"winget\", \"brew\", \"brew-cask\", \"apt\", \"dnf\", \"pacman\", \"npm\", \"uv\", \"fnm\" and \"rustup\". The host builds the exact command from the manager and Package; Package may hold {major} and {major.minor}, which the pinned or suggested version fills. The language's own installers (uv, fnm, rustup) are offered only when they are already on the machine.",
2547
+ "type": "object",
2548
+ "properties": {
2549
+ "manager": {
2550
+ "type": "string"
2551
+ },
2552
+ "package": {
2553
+ "type": "string"
2554
+ },
2555
+ "note": {
2556
+ "type": "string",
2557
+ "description": "Note adds a sentence the person needs before choosing (\"a new terminal is needed\")."
2558
+ }
2559
+ },
2560
+ "required": [
2561
+ "manager",
2562
+ "package"
2563
+ ]
2564
+ },
2565
+ "ToolNeed": {
2566
+ "description": "ToolNeed is a program on the person's machine that a plugin needs to build, test or run its projects (Python, the .NET SDK, Docker). A plugin publishes the tools it needs in InitializeResult.Tools. The host detects them, and when one is missing it presents the ways to get it (ADR 0077): it never installs in silence. The plugin writes facts only (what the tool is, how to detect it, how each system gets it); the host decides how to ask.",
2567
+ "type": "object",
2568
+ "properties": {
2569
+ "name": {
2570
+ "type": "string",
2571
+ "description": "Name identifies the tool across plugins and in commands (smith tools install python). Two plugins that need the same tool use the same Name."
2572
+ },
2573
+ "title": {
2574
+ "type": "string",
2575
+ "description": "Title is what the tool is called in text: \"Python\", \"the .NET SDK\". Doctor words the check \"<Title> is installed\"."
2576
+ },
2577
+ "why": {
2578
+ "type": "string",
2579
+ "description": "Why says in plain words what smith needs the tool for."
2580
+ },
2581
+ "consequence": {
2582
+ "type": "string",
2583
+ "description": "Consequence says what stops working while the tool is missing, as the end of a sentence that starts \"If you skip it, \": \"smith test and smith build fail for the python projects\"."
2584
+ },
2585
+ "program": {
2586
+ "type": "string",
2587
+ "description": "Program is the program that carries the tool on PATH (\"python3\")."
2588
+ },
2589
+ "alternatives": {
2590
+ "type": "array",
2591
+ "items": {
2592
+ "type": "string"
2593
+ },
2594
+ "description": "Alternatives are other programs that also count (\"python\", \"py\")."
2595
+ },
2596
+ "versionArgs": {
2597
+ "type": "array",
2598
+ "items": {
2599
+ "type": "string"
2600
+ },
2601
+ "description": "VersionArgs are the arguments that make Program print its version. Absent means --version."
2602
+ },
2603
+ "pins": {
2604
+ "type": "array",
2605
+ "items": {
2606
+ "$ref": "#/$defs/ToolVersionPin"
2607
+ },
2608
+ "description": "Pins are the files where a workspace pins the version it wants. The first pin the host finds gives the version range. Absent means any version counts."
2609
+ },
2610
+ "choice": {
2611
+ "type": "string",
2612
+ "description": "Choice limits the tool to stacks that have this choice (\"azure-functions\"): the tool is not needed by a project built without it. Absent means every project of the plugin needs it."
2613
+ },
2614
+ "systems": {
2615
+ "type": "array",
2616
+ "items": {
2617
+ "type": "string"
2618
+ },
2619
+ "description": "Systems limits the tool to these systems, named as Go names them (\"windows\", \"darwin\", \"linux\"): the Xcode Command Line Tools exist only on \"darwin\". Absent means every system."
2620
+ },
2621
+ "suggested": {
2622
+ "type": "string",
2623
+ "description": "Suggested is the version smith installs when no pin says one: \"3.13\". It fills {major} and {major.minor} in the install entries."
2624
+ },
2625
+ "optional": {
2626
+ "type": "boolean",
2627
+ "description": "Optional marks a tool whose absence only costs a feature (running a function app locally). Doctor reports it as a warning, not a failure."
2628
+ },
2629
+ "install": {
2630
+ "type": "array",
2631
+ "items": {
2632
+ "$ref": "#/$defs/ToolInstall"
2633
+ },
2634
+ "description": "Install are the ways to get the tool, per package manager and system."
2635
+ },
2636
+ "download": {
2637
+ "type": "string",
2638
+ "description": "Download is the official page of the tool, for the person who installs it by hand or has no package manager."
2639
+ },
2640
+ "source": {
2641
+ "type": "string",
2642
+ "description": "Source is the address of the page the Install entries were checked against."
2643
+ },
2644
+ "checked": {
2645
+ "type": "string",
2646
+ "description": "Checked is the date (YYYY-MM-DD) the entries were last checked."
2647
+ }
2648
+ },
2649
+ "required": [
2650
+ "name",
2651
+ "title",
2652
+ "why",
2653
+ "consequence",
2654
+ "program",
2655
+ "download",
2656
+ "source",
2657
+ "checked"
2658
+ ]
2659
+ },
2405
2660
  "ToolPin": {
2406
2661
  "description": "ToolPin is a tool the plugin installs at a pinned version (in CI, the dev container, the venv) against the newest release; informational.",
2407
2662
  "type": "object",
@@ -2426,6 +2681,23 @@ export const protocolSchema = {
2426
2681
  "pinned"
2427
2682
  ]
2428
2683
  },
2684
+ "ToolVersionPin": {
2685
+ "description": "ToolVersionPin names a file that pins the version of a tool and how to read it. Format is one of: \"text\" (the first word of the file, as in .nvmrc and .python-version), \"go-mod\" (the toolchain line, else the go line), \"pyproject\" (requires-python), \"global-json\" (sdk.version) and \"rust-toolchain\" (the channel).",
2686
+ "type": "object",
2687
+ "properties": {
2688
+ "file": {
2689
+ "type": "string",
2690
+ "description": "File is the base name of the file, looked up at the workspace root and in the folders of the projects that use the tool."
2691
+ },
2692
+ "format": {
2693
+ "type": "string"
2694
+ }
2695
+ },
2696
+ "required": [
2697
+ "file",
2698
+ "format"
2699
+ ]
2700
+ },
2429
2701
  "Toolchain": {
2430
2702
  "description": "Toolchain is a runtime the pipeline must install, and how. Plugins asking for the same name share one setup step (the first plugin's).",
2431
2703
  "type": "object",
@@ -2477,6 +2749,22 @@ export const protocolSchema = {
2477
2749
  "packages"
2478
2750
  ]
2479
2751
  },
2752
+ "UnlinkParams": {
2753
+ "description": "UnlinkParams asks a plugin to remove the dependency of Project on Library. Notes of the result say so when the manifest held no such dependency.",
2754
+ "type": "object",
2755
+ "properties": {
2756
+ "project": {
2757
+ "$ref": "#/$defs/Project"
2758
+ },
2759
+ "library": {
2760
+ "$ref": "#/$defs/Project"
2761
+ }
2762
+ },
2763
+ "required": [
2764
+ "project",
2765
+ "library"
2766
+ ]
2767
+ },
2480
2768
  "VersionParams": {
2481
2769
  "description": "VersionParams asks a plugin to record a new version in a project manifest.",
2482
2770
  "type": "object",
@@ -177,6 +177,13 @@ export interface Capabilities {
177
177
  published?: boolean;
178
178
  /** Dependencies installs and uninstalls packages in its projects. */
179
179
  dependencies?: boolean;
180
+ /**
181
+ * Link makes a project depend on a library of the same workspace in the ecosystem's own form (a
182
+ * workspace dependency, a path dependency, a project reference), and takes it out again. A plugin
183
+ * without it is refused by the host with one sentence that tells the user to add the dependency
184
+ * by hand.
185
+ */
186
+ link?: boolean;
180
187
  /** Declarations lists and rewrites declared dependency specs (sync, up). */
181
188
  declarations?: boolean;
182
189
  /** Latest reports the newest releases of dependencies and pinned tools. */
@@ -272,6 +279,19 @@ export interface Choice {
272
279
  */
273
280
  name: string;
274
281
  description?: string;
282
+ /** Title is the name shown to a person ("Electron" for electron). Without it the name is shown. */
283
+ title?: string;
284
+ /**
285
+ * Aliases are words that find the choice when a person searches the catalogue (smith compose):
286
+ * "desktop", "serverless", "web".
287
+ */
288
+ aliases?: string[];
289
+ /**
290
+ * Layer is where the choice sits in the stack of a project: "framework", "shell" (a desktop
291
+ * shell), "host" (where cloud code runs), "test", "lint", "style" or a layer of the plugin's own.
292
+ * Without it the layer is the axis. It is for display and grouping: the axis decides conflicts.
293
+ */
294
+ layer?: string;
275
295
  /** Language is the language plugin the choice applies to ("node"). */
276
296
  language: string;
277
297
  /**
@@ -287,6 +307,12 @@ export interface Choice {
287
307
  needs?: string[];
288
308
  /** Default marks the choice the host adds when a selection needs its axis and has no choice on it. */
289
309
  default?: boolean;
310
+ /**
311
+ * Suggested marks the choice an asker pre-selects on its axis. The solver never adds it by
312
+ * itself: an axis that a choice needs and that has no Default is asked, and the person answers
313
+ * (ADR 0072).
314
+ */
315
+ suggested?: boolean;
290
316
  /**
291
317
  * Many allows the choice next to other choices of its axis that are Many too. By default a
292
318
  * selection has one choice per axis.
@@ -773,6 +799,12 @@ export interface InitializeResult {
773
799
  * owns none.
774
800
  */
775
801
  choices?: Choice[];
802
+ /**
803
+ * Tools are the programs the plugin needs on the person's machine. The host detects them and,
804
+ * when one is missing, presents the ways to get it (smith tools). Absent means the plugin
805
+ * declares none.
806
+ */
807
+ tools?: ToolNeed[];
776
808
  }
777
809
  /**
778
810
  * Input is one input of an ActionStep. Values are written as quoted YAML strings, except true and
@@ -825,6 +857,62 @@ export interface LatestResult {
825
857
  unreachable?: Record<string, string>;
826
858
  tools?: ToolPin[];
827
859
  }
860
+ /**
861
+ * LinkOption is one way to write the dependency, with its consequence in words a person who read no
862
+ * manual can follow.
863
+ */
864
+ export interface LinkOption {
865
+ /** Spec is the value passed back in LinkParams.Spec. */
866
+ spec: string;
867
+ /** Label is the option in a few words. */
868
+ label: string;
869
+ /** Meaning says what happens with this option. */
870
+ meaning: string;
871
+ }
872
+ /**
873
+ * LinkParams asks a plugin to make Project depend on Library, a lib or package of the same
874
+ * workspace and language, in the ecosystem's own form, and to install or lock as that needs. The
875
+ * host has checked that both exist, that the languages match, that Library is not an app, and that
876
+ * the link makes no cycle; the plugin answers with an error that names the file when it cannot
877
+ * write the dependency.
878
+ */
879
+ export interface LinkParams {
880
+ /** Project is the project that gains the dependency. */
881
+ project: Project;
882
+ /** Library is the project it depends on. */
883
+ library: Project;
884
+ /** Quiet keeps the package manager's output unless it fails. */
885
+ quiet?: boolean;
886
+ /**
887
+ * Plan asks for the plan only: the plugin writes nothing and answers with the manifest, the line
888
+ * it would write and the choices the user has.
889
+ */
890
+ plan?: boolean;
891
+ /**
892
+ * Spec is the version range the user chose from LinkResult.Options; empty means the plugin's
893
+ * default, or the form the workspace already uses.
894
+ */
895
+ spec?: string;
896
+ }
897
+ /** LinkResult is what a link wrote, or with LinkParams.Plan would write. */
898
+ export interface LinkResult {
899
+ /** Files are the workspace-relative files changed (or to be changed). */
900
+ files?: string[];
901
+ /** Notes are for the user. */
902
+ notes?: string[];
903
+ /** Manifest is the file the dependency goes into, workspace-relative. */
904
+ manifest?: string;
905
+ /**
906
+ * Line is the dependency as it is written there, for the plan shown before anything is written
907
+ * ("@acme/core": "*").
908
+ */
909
+ line?: string;
910
+ /**
911
+ * Options are the real choices of the range written, with the default first. Empty when the
912
+ * ecosystem has none, or the workspace already follows a convention (then Line shows it).
913
+ */
914
+ options?: LinkOption[];
915
+ }
828
916
  /**
829
917
  * PackageStore is where a package manager keeps what it downloaded (npm's ~/.npm, Go's module
830
918
  * cache). A generated pipeline restores it before setup and saves it after a run, keyed on Files,
@@ -1258,6 +1346,87 @@ export interface Task {
1258
1346
  /** ServeTimeout is how long to wait for ServeURL, as a Go duration ("60s"); empty means 60s. */
1259
1347
  serveTimeout?: string;
1260
1348
  }
1349
+ /**
1350
+ * ToolInstall is one way to get a tool with a package manager. Manager is one of: "winget", "brew",
1351
+ * "brew-cask", "apt", "dnf", "pacman", "npm", "uv", "fnm" and "rustup". The host builds the exact
1352
+ * command from the manager and Package; Package may hold {major} and {major.minor}, which the
1353
+ * pinned or suggested version fills. The language's own installers (uv, fnm, rustup) are offered
1354
+ * only when they are already on the machine.
1355
+ */
1356
+ export interface ToolInstall {
1357
+ manager: string;
1358
+ package: string;
1359
+ /** Note adds a sentence the person needs before choosing ("a new terminal is needed"). */
1360
+ note?: string;
1361
+ }
1362
+ /**
1363
+ * ToolNeed is a program on the person's machine that a plugin needs to build, test or run its
1364
+ * projects (Python, the .NET SDK, Docker). A plugin publishes the tools it needs in
1365
+ * InitializeResult.Tools. The host detects them, and when one is missing it presents the ways to
1366
+ * get it (ADR 0077): it never installs in silence. The plugin writes facts only (what the tool is,
1367
+ * how to detect it, how each system gets it); the host decides how to ask.
1368
+ */
1369
+ export interface ToolNeed {
1370
+ /**
1371
+ * Name identifies the tool across plugins and in commands (smith tools install python). Two
1372
+ * plugins that need the same tool use the same Name.
1373
+ */
1374
+ name: string;
1375
+ /**
1376
+ * Title is what the tool is called in text: "Python", "the .NET SDK". Doctor words the check
1377
+ * "<Title> is installed".
1378
+ */
1379
+ title: string;
1380
+ /** Why says in plain words what smith needs the tool for. */
1381
+ why: string;
1382
+ /**
1383
+ * Consequence says what stops working while the tool is missing, as the end of a sentence that
1384
+ * starts "If you skip it, ": "smith test and smith build fail for the python projects".
1385
+ */
1386
+ consequence: string;
1387
+ /** Program is the program that carries the tool on PATH ("python3"). */
1388
+ program: string;
1389
+ /** Alternatives are other programs that also count ("python", "py"). */
1390
+ alternatives?: string[];
1391
+ /** VersionArgs are the arguments that make Program print its version. Absent means --version. */
1392
+ versionArgs?: string[];
1393
+ /**
1394
+ * Pins are the files where a workspace pins the version it wants. The first pin the host finds
1395
+ * gives the version range. Absent means any version counts.
1396
+ */
1397
+ pins?: ToolVersionPin[];
1398
+ /**
1399
+ * Choice limits the tool to stacks that have this choice ("azure-functions"): the tool is not
1400
+ * needed by a project built without it. Absent means every project of the plugin needs it.
1401
+ */
1402
+ choice?: string;
1403
+ /**
1404
+ * Systems limits the tool to these systems, named as Go names them ("windows", "darwin",
1405
+ * "linux"): the Xcode Command Line Tools exist only on "darwin". Absent means every system.
1406
+ */
1407
+ systems?: string[];
1408
+ /**
1409
+ * Suggested is the version smith installs when no pin says one: "3.13". It fills {major} and
1410
+ * {major.minor} in the install entries.
1411
+ */
1412
+ suggested?: string;
1413
+ /**
1414
+ * Optional marks a tool whose absence only costs a feature (running a function app locally).
1415
+ * Doctor reports it as a warning, not a failure.
1416
+ */
1417
+ optional?: boolean;
1418
+ /** Install are the ways to get the tool, per package manager and system. */
1419
+ install?: ToolInstall[];
1420
+ /**
1421
+ * Download is the official page of the tool, for the person who installs it by hand or has no
1422
+ * package manager.
1423
+ */
1424
+ download: string;
1425
+ /** Source is the address of the page the Install entries were checked against. */
1426
+ source: string;
1427
+ /** Checked is the date (YYYY-MM-DD) the entries were last checked. */
1428
+ checked: string;
1429
+ }
1261
1430
  /**
1262
1431
  * ToolPin is a tool the plugin installs at a pinned version (in CI, the dev container, the venv)
1263
1432
  * against the newest release; informational.
@@ -1270,6 +1439,20 @@ export interface ToolPin {
1270
1439
  /** Newer is true when Latest is a release the pin does not cover. */
1271
1440
  newer?: boolean;
1272
1441
  }
1442
+ /**
1443
+ * ToolVersionPin names a file that pins the version of a tool and how to read it. Format is one of:
1444
+ * "text" (the first word of the file, as in .nvmrc and .python-version), "go-mod" (the toolchain
1445
+ * line, else the go line), "pyproject" (requires-python), "global-json" (sdk.version) and
1446
+ * "rust-toolchain" (the channel).
1447
+ */
1448
+ export interface ToolVersionPin {
1449
+ /**
1450
+ * File is the base name of the file, looked up at the workspace root and in the folders of the
1451
+ * projects that use the tool.
1452
+ */
1453
+ file: string;
1454
+ format: string;
1455
+ }
1273
1456
  /**
1274
1457
  * Toolchain is a runtime the pipeline must install, and how. Plugins asking for the same name share
1275
1458
  * one setup step (the first plugin's).
@@ -1297,6 +1480,14 @@ export interface UninstallParams {
1297
1480
  project: Project;
1298
1481
  packages: string[];
1299
1482
  }
1483
+ /**
1484
+ * UnlinkParams asks a plugin to remove the dependency of Project on Library. Notes of the result
1485
+ * say so when the manifest held no such dependency.
1486
+ */
1487
+ export interface UnlinkParams {
1488
+ project: Project;
1489
+ library: Project;
1490
+ }
1300
1491
  /** VersionParams asks a plugin to record a new version in a project manifest. */
1301
1492
  export interface VersionParams {
1302
1493
  project: Project;
@@ -1433,6 +1624,21 @@ export interface ProtocolMethods {
1433
1624
  result: DependencyResult;
1434
1625
  capability: 'dependencies';
1435
1626
  };
1627
+ /**
1628
+ * Makes a project depend on a library of the same workspace and language, in the ecosystem's own
1629
+ * form, then installs or locks as that needs.
1630
+ */
1631
+ 'dependencies/link': {
1632
+ params: LinkParams;
1633
+ result: LinkResult;
1634
+ capability: 'link';
1635
+ };
1636
+ /** Removes the dependency of a project on a library of the same workspace. */
1637
+ 'dependencies/unlink': {
1638
+ params: UnlinkParams;
1639
+ result: DependencyResult;
1640
+ capability: 'link';
1641
+ };
1436
1642
  /** Lists the dependencies the manifests of the plugin's projects declare. */
1437
1643
  'dependencies/declared': {
1438
1644
  params: DeclaredParams;
package/serve/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { serve, serveStreams } from './serve.use-case.ts';
2
2
  export { capabilitiesOf, implementsMethod } from './capabilities-of.algorithm.ts';
3
- export type { APISurfaceReader, Awaitable, Cancellable, CIContributor, ComponentLister, Contributor, DeclarationEditor, DependencyManager, Deriver, Discoverer, DoctorContributor, Generator, KindChanger, LatestReader, Plugin, PluginDescription, Publisher, RegistryReader, Remover, SmithPlugin, Versioner, } from './plugin.contract.ts';
3
+ export type { APISurfaceReader, Awaitable, Cancellable, CIContributor, ComponentLister, Contributor, DeclarationEditor, DependencyManager, Deriver, Discoverer, DoctorContributor, Generator, KindChanger, LatestReader, Linker, Plugin, PluginDescription, Publisher, RegistryReader, Remover, SmithPlugin, Versioner, } from './plugin.contract.ts';
4
4
  export type { FrameSink, ServeStreams } from './protocol-streams.contract.ts';
@@ -20,6 +20,8 @@ export const PLUGIN_MEMBERS = {
20
20
  'published': { member: 'published', requires: ['published'] },
21
21
  'dependencies/install': { member: 'install', requires: ['install', 'uninstall'] },
22
22
  'dependencies/uninstall': { member: 'uninstall', requires: ['install', 'uninstall'] },
23
+ 'dependencies/link': { member: 'link', requires: ['link', 'unlink'] },
24
+ 'dependencies/unlink': { member: 'unlink', requires: ['link', 'unlink'] },
23
25
  'dependencies/declared': { member: 'declared', requires: ['declared', 'rewrite'] },
24
26
  'dependencies/rewrite': { member: 'rewrite', requires: ['declared', 'rewrite'] },
25
27
  'dependencies/latest': { member: 'latest', requires: ['latest'] },
@@ -1,4 +1,4 @@
1
- import type { DeriveParams, DeriveResult, APISurfaceParams, APISurfaceResult, ChangeKindParams, ChangeKindResult, CIParams, CIResult, ComponentsParams, ComponentsResult, ContributeParams, ContributeResult, DeclaredParams, DeclaredResult, DependencyResult, DiscoverParams, DiscoverResult, DoctorParams, DoctorResult, GenerateParams, GenerateResult, InitializeParams, InitializeResult, InstallParams, LatestParams, LatestResult, PublishedParams, PublishedResult, PublishParams, PublishResult, RemoveParams, RemoveResult, RewriteParams, UninstallParams, VersionParams, VersionResult } from '../protocol/index.ts';
1
+ import type { DeriveParams, DeriveResult, APISurfaceParams, APISurfaceResult, ChangeKindParams, ChangeKindResult, CIParams, CIResult, ComponentsParams, ComponentsResult, ContributeParams, ContributeResult, DeclaredParams, DeclaredResult, DependencyResult, DiscoverParams, DiscoverResult, DoctorParams, DoctorResult, GenerateParams, GenerateResult, InitializeParams, InitializeResult, InstallParams, LatestParams, LatestResult, LinkParams, LinkResult, PublishedParams, PublishedResult, PublishParams, PublishResult, RemoveParams, RemoveResult, RewriteParams, UninstallParams, UnlinkParams, VersionParams, VersionResult } from '../protocol/index.ts';
2
2
  /** A result now or later: every method of a plugin may be `async`. */
3
3
  export type Awaitable<T> = T | Promise<T>;
4
4
  /** What a plugin says about itself. The serve loop fills in `protocolVersion` and `capabilities`. */
@@ -61,6 +61,11 @@ export interface DependencyManager {
61
61
  install: (params: InstallParams, signal: AbortSignal) => Awaitable<DependencyResult>;
62
62
  uninstall: (params: UninstallParams, signal: AbortSignal) => Awaitable<DependencyResult>;
63
63
  }
64
+ /** `dependencies/link` and `dependencies/unlink`: both, or the capability is not advertised. */
65
+ export interface Linker {
66
+ link: (params: LinkParams, signal: AbortSignal) => Awaitable<LinkResult>;
67
+ unlink: (params: UnlinkParams, signal: AbortSignal) => Awaitable<DependencyResult>;
68
+ }
64
69
  /** `dependencies/declared` and `dependencies/rewrite`: both, or the capability is not advertised. */
65
70
  export interface DeclarationEditor {
66
71
  declared: (params: DeclaredParams, signal: AbortSignal) => Awaitable<DeclaredResult>;
@@ -93,4 +98,4 @@ export interface Cancellable {
93
98
  * from `cancellable`. How many requests it can work on at once is declared in
94
99
  * `describe`'s `concurrency`: omit it for one at a time, in order.
95
100
  */
96
- export type SmithPlugin = Plugin & Partial<Discoverer & Generator & Versioner & Publisher & RegistryReader & CIContributor & DoctorContributor & Remover & KindChanger & ComponentLister & Deriver & APISurfaceReader & DependencyManager & DeclarationEditor & LatestReader & Contributor & Cancellable>;
101
+ export type SmithPlugin = Plugin & Partial<Discoverer & Generator & Versioner & Publisher & RegistryReader & CIContributor & DoctorContributor & Remover & KindChanger & ComponentLister & Deriver & APISurfaceReader & DependencyManager & Linker & DeclarationEditor & LatestReader & Contributor & Cancellable>;