ingestron 0.12.1 → 0.13.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/CHANGELOG.md +16 -0
- package/README.md +8 -6
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/build/cli/cli/operation-worker.js +2 -2
- package/build/cli/cli/output.js +2 -2
- package/build/cli/cli/plugin-resolution.d.ts +22 -0
- package/build/cli/cli/plugin-resolution.js +164 -0
- package/build/cli/cli/workflow-commands.js +20 -52
- package/build/cli/mcp/index.js +3 -2
- package/build/cli/version.d.ts +1 -0
- package/build/cli/version.js +1 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.13.1 — Node.js runtime compatibility
|
|
4
|
+
|
|
5
|
+
- Require Node 22.12 or newer instead of excluding newer major versions. CI tests
|
|
6
|
+
Node 22.12.0, 22.23.2 and 24.12.0, including installed CLI and MCP workflows.
|
|
7
|
+
- Pin core 0.12.1 so the transitive core package no longer warns on Node 24.
|
|
8
|
+
|
|
9
|
+
## 0.13.0 — simpler plugin installation
|
|
10
|
+
|
|
11
|
+
- CLI and MCP resolve official `github` and `local` names through shared adapter logic.
|
|
12
|
+
Omitted versions and `@latest` select qualified compatible releases, then pin exact
|
|
13
|
+
versions/commits. Repeated installs reuse locks; updates are explicit.
|
|
14
|
+
- Installation now only caches packages. Register project providers separately with
|
|
15
|
+
`plugin configure`; `--cache-only` remains accepted and `install --name` gives a
|
|
16
|
+
migration diagnostic. Existing full references and custom tag prefixes still work.
|
|
17
|
+
- Core remains pinned at 0.12.0; no source/provider runtime change is required.
|
|
18
|
+
|
|
3
19
|
## 0.12.1 — project-relative secret files
|
|
4
20
|
|
|
5
21
|
- Use `run --secrets-file .env` instead of `--env-file`. Node interprets the old
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ the CLI does not install a platform provider or connect to a cloud account.
|
|
|
10
10
|
|
|
11
11
|
## Get started
|
|
12
12
|
|
|
13
|
-
Use Node 22, Git and pnpm 10.15.0. Build the public source:
|
|
13
|
+
Use Node 22.12 or newer, Git and pnpm 10.15.0. Build the public source:
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
16
|
git clone https://github.com/ingestron/cli.git
|
|
@@ -29,13 +29,13 @@ To install this checkout's CLI in your terminal:
|
|
|
29
29
|
|
|
30
30
|
```sh
|
|
31
31
|
pnpm pack --pack-destination build/release
|
|
32
|
-
npm install --global ./build/release/ingestron-0.
|
|
32
|
+
npm install --global ./build/release/ingestron-0.13.1.tgz
|
|
33
33
|
ingestron --version
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
This source release prepares the npm package named `ingestron`; it does not claim
|
|
37
37
|
that the same CLI version is already published on npm. Its core dependency is the
|
|
38
|
-
public, exact version `@ingestron/core@0.12.
|
|
38
|
+
public, exact version `@ingestron/core@0.12.1`.
|
|
39
39
|
|
|
40
40
|
Follow the [five-minute quickstart](docs/quickstart.md) for a project you can keep.
|
|
41
41
|
|
|
@@ -45,12 +45,14 @@ Commands use resource groups such as `source`, `contract`, `flow`, `config` and
|
|
|
45
45
|
`plugin`. Installed plugins can add their own namespace:
|
|
46
46
|
|
|
47
47
|
```text
|
|
48
|
-
ingestron plugin install
|
|
48
|
+
ingestron plugin install local
|
|
49
|
+
ingestron plugin install github
|
|
49
50
|
ingestron <namespace> <resource> <verb> --input request.json
|
|
50
51
|
```
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
Installation caches an exact, qualified version without changing project configuration.
|
|
54
|
+
Use `github@1.32.1` for an explicit pin, or `plugin update github` to check for a newer
|
|
55
|
+
qualified release. Browse installed packages with `ingestron plugin browse`. Command help
|
|
54
56
|
shows the selected plugin's input schema without executing it.
|
|
55
57
|
|
|
56
58
|
- [Command reference](docs/commands.md) — implemented groups, options and errors.
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Keep package-network work off the presentation thread so progress reflects
|
|
2
2
|
* actual pending work. This worker uses the same JSON operations as MCP/Web. */
|
|
3
3
|
import { parentPort, workerData } from "node:worker_threads";
|
|
4
|
-
import {
|
|
5
|
-
parentPort.postMessage(
|
|
4
|
+
import { executePluginOperation } from "./plugin-resolution.js";
|
|
5
|
+
parentPort.postMessage(await executePluginOperation(workerData.context, workerData.operation, workerData.args));
|
package/build/cli/cli/output.js
CHANGED
|
@@ -54,7 +54,7 @@ export function terminal(result, verbose = false, args = {}) {
|
|
|
54
54
|
.map((p) => ` ${clean(p.id).padEnd(13)} ${clean(p.name)} [${clean(p.kindLabel)} · ${clean(p.availability)}]\n ${clean(p.description)}\n ${clean(p.url)}`)
|
|
55
55
|
.join("\n\n")
|
|
56
56
|
: "No installed plugins match this search.") +
|
|
57
|
-
"\n\nBrowse versions: ingestron plugin versions
|
|
57
|
+
"\n\nBrowse versions: ingestron plugin versions github\nGuided install: ingestron plugin install\nInstall: ingestron plugin install github");
|
|
58
58
|
case "plugin_versions":
|
|
59
59
|
return (lines(`Versions for ${value.provider}`, value.versions.map((v) => `${v.reference}${v.ambiguous ? " (conflicting tags; select a commit)" : ""}`), "No stable version tags found.") +
|
|
60
60
|
"\n\n" +
|
|
@@ -63,7 +63,7 @@ export function terminal(result, verbose = false, args = {}) {
|
|
|
63
63
|
case "packages_install":
|
|
64
64
|
return `${value.cached ? "Using cached" : "Installed"} plugin ${clean(friendlyReference(args.reference ?? value.reference ?? "package"))}.${value.informationFile ? `\nPlugin information and licence evidence: ${clean(value.informationFile)}` : ""}`;
|
|
65
65
|
case "packages_list":
|
|
66
|
-
return lines("Installed plugins", Object.keys(value.packages).map(friendlyReference), "No plugins installed.\nNext: ingestron plugin install
|
|
66
|
+
return lines("Installed plugins", Object.keys(value.packages).map(friendlyReference), "No plugins installed.\nNext: ingestron plugin install local");
|
|
67
67
|
case "source_list":
|
|
68
68
|
return lines("Sources", value.map((s) => `${s.id} ${s.type}${s.format ? "/" + s.format : ""} ${s.execution}`), "No sources configured.\nNext: ingestron source add <name> --type <type>");
|
|
69
69
|
case "source_show":
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Official-name convenience at the adapter boundary; core only receives exact references. */
|
|
2
|
+
import { type Context, type OperationName, type Result } from "@ingestron/core";
|
|
3
|
+
export declare const officialPlugins: {
|
|
4
|
+
readonly github: {
|
|
5
|
+
readonly repository: "ingestron/connectors";
|
|
6
|
+
readonly path: "connectors/github/connector.yaml";
|
|
7
|
+
readonly tagPrefix: "github-";
|
|
8
|
+
};
|
|
9
|
+
readonly local: {
|
|
10
|
+
readonly repository: "ingestron/provider-local";
|
|
11
|
+
readonly path: "plugin/provider.yaml";
|
|
12
|
+
readonly tagPrefix: "";
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export declare function officialName(reference: string): {
|
|
16
|
+
name: keyof typeof officialPlugins;
|
|
17
|
+
version: string;
|
|
18
|
+
} | undefined;
|
|
19
|
+
export declare function catalogueReleases(value: any, name: keyof typeof officialPlugins, host?: string): string[];
|
|
20
|
+
export declare function fetchCatalogue(): Promise<unknown>;
|
|
21
|
+
export declare function resolvePluginArgs(context: Context, operation: OperationName, args: any, catalogue?: typeof fetchCatalogue): Promise<any>;
|
|
22
|
+
export declare function executePluginOperation(context: Context, operation: OperationName, args?: any): Promise<Result>;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/** Official-name convenience at the adapter boundary; core only receives exact references. */
|
|
2
|
+
import { executeAsync, operationSchemas, } from "@ingestron/core";
|
|
3
|
+
import { check, packageLock, Problem } from "@ingestron/core/adapter";
|
|
4
|
+
import { coreVersion } from "../version.js";
|
|
5
|
+
export const officialPlugins = {
|
|
6
|
+
github: {
|
|
7
|
+
repository: "ingestron/connectors",
|
|
8
|
+
path: "connectors/github/connector.yaml",
|
|
9
|
+
tagPrefix: "github-",
|
|
10
|
+
},
|
|
11
|
+
local: {
|
|
12
|
+
repository: "ingestron/provider-local",
|
|
13
|
+
path: "plugin/provider.yaml",
|
|
14
|
+
tagPrefix: "",
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
const catalogueUrl = "https://raw.githubusercontent.com/ingestron/connectors/main/catalogue.json";
|
|
18
|
+
const stable = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
19
|
+
const compare = (a, b) => {
|
|
20
|
+
const x = a.split(".").map(Number), y = b.split(".").map(Number);
|
|
21
|
+
return y[0] - x[0] || y[1] - x[1] || y[2] - x[2];
|
|
22
|
+
};
|
|
23
|
+
export function officialName(reference) {
|
|
24
|
+
if (reference.includes("/"))
|
|
25
|
+
return undefined;
|
|
26
|
+
const [name, version, extra] = reference.split("@");
|
|
27
|
+
check(Object.hasOwn(officialPlugins, name), "PACKAGE", `Unknown official plugin '${name}'. Use github, local, or an explicit owner/repository reference.`);
|
|
28
|
+
check(extra === undefined &&
|
|
29
|
+
(version === undefined || version === "latest" || stable.test(version)), "PACKAGE", "Use a stable version, @latest, or omit the version for an official plugin");
|
|
30
|
+
return { name: name, version };
|
|
31
|
+
}
|
|
32
|
+
export function catalogueReleases(value, name, host = coreVersion) {
|
|
33
|
+
const identity = officialPlugins[name];
|
|
34
|
+
check(value?.apiVersion === "ingestron.catalogue/v1", "CATALOGUE", "Unsupported official catalogue format");
|
|
35
|
+
const entry = value.plugins?.[name];
|
|
36
|
+
check(entry &&
|
|
37
|
+
entry.repository === identity.repository &&
|
|
38
|
+
entry.path === identity.path &&
|
|
39
|
+
entry.tagPrefix === identity.tagPrefix &&
|
|
40
|
+
Array.isArray(entry.releases) &&
|
|
41
|
+
entry.releases.length <= 1000, "CATALOGUE", `Invalid official catalogue identity for ${name}`);
|
|
42
|
+
const seen = new Set();
|
|
43
|
+
for (const release of entry.releases) {
|
|
44
|
+
check(stable.test(release.version) &&
|
|
45
|
+
!seen.has(release.version) &&
|
|
46
|
+
Array.isArray(release.coreVersions) &&
|
|
47
|
+
release.coreVersions.length > 0 &&
|
|
48
|
+
release.coreVersions.every((v) => typeof v === "string" && stable.test(v)), "CATALOGUE", `Invalid qualified release for ${name}`);
|
|
49
|
+
seen.add(release.version);
|
|
50
|
+
}
|
|
51
|
+
return entry.releases
|
|
52
|
+
.filter((r) => r.coreVersions.includes(host))
|
|
53
|
+
.map((r) => r.version)
|
|
54
|
+
.sort(compare);
|
|
55
|
+
}
|
|
56
|
+
export async function fetchCatalogue() {
|
|
57
|
+
try {
|
|
58
|
+
const response = await fetch(catalogueUrl, {
|
|
59
|
+
signal: AbortSignal.timeout(10000),
|
|
60
|
+
redirect: "error",
|
|
61
|
+
});
|
|
62
|
+
check(response.ok && response.body, "CATALOGUE", "Official catalogue is unavailable; retry or install an explicit version");
|
|
63
|
+
const reader = response.body.getReader();
|
|
64
|
+
const chunks = [];
|
|
65
|
+
let size = 0;
|
|
66
|
+
try {
|
|
67
|
+
for (;;) {
|
|
68
|
+
const { value, done } = await reader.read();
|
|
69
|
+
if (done)
|
|
70
|
+
break;
|
|
71
|
+
size += value.length;
|
|
72
|
+
check(size <= 262144, "CATALOGUE", "Official catalogue exceeds the size limit");
|
|
73
|
+
chunks.push(value);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
await reader.cancel();
|
|
78
|
+
}
|
|
79
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (error instanceof Problem)
|
|
83
|
+
throw error;
|
|
84
|
+
throw new Problem("CATALOGUE", "Cannot read the official catalogue; retry or install an explicit version");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export async function resolvePluginArgs(context, operation, args, catalogue = fetchCatalogue) {
|
|
88
|
+
if (operation !== "packages_install" && operation !== "plugin_versions")
|
|
89
|
+
return args;
|
|
90
|
+
const field = operation === "packages_install" ? "reference" : "provider";
|
|
91
|
+
const alias = officialName(args[field]);
|
|
92
|
+
if (!alias)
|
|
93
|
+
return args;
|
|
94
|
+
const identity = officialPlugins[alias.name];
|
|
95
|
+
check(args.tagPrefix === undefined || args.tagPrefix === identity.tagPrefix, "OPTION", "Official plugin tag prefixes cannot be overridden; use an explicit reference for custom tags");
|
|
96
|
+
if (operation === "plugin_versions")
|
|
97
|
+
return {
|
|
98
|
+
...args,
|
|
99
|
+
provider: identity.repository,
|
|
100
|
+
tagPrefix: identity.tagPrefix,
|
|
101
|
+
};
|
|
102
|
+
// Check permissions before catalogue network access, just as core does before install.
|
|
103
|
+
check(context.allowWrite, "PERMISSION", "Package installation requires write access");
|
|
104
|
+
check(!(args.update && args.frozen), "PACKAGE", "Frozen installation cannot update packages");
|
|
105
|
+
const base = `${identity.repository}/${identity.path}@`;
|
|
106
|
+
let version = alias.version;
|
|
107
|
+
if (version === undefined || version === "latest") {
|
|
108
|
+
const installed = Object.keys(packageLock(context.root).packages)
|
|
109
|
+
.filter((r) => r.startsWith(base) && stable.test(r.slice(base.length)))
|
|
110
|
+
.map((r) => r.slice(base.length))
|
|
111
|
+
.sort(compare);
|
|
112
|
+
if (!args.update && installed.length)
|
|
113
|
+
version = installed[0];
|
|
114
|
+
else {
|
|
115
|
+
check(!args.frozen, "PACKAGE", "Frozen installation requires an existing exact lock; install an exact version first");
|
|
116
|
+
check(context.allowNetwork, "PERMISSION", "Latest plugin resolution requires explicit package-network access");
|
|
117
|
+
check(!args.fromGit, "OPTION", "Use an exact version with --from-git; latest selects official qualified releases");
|
|
118
|
+
const versions = catalogueReleases(await catalogue(), alias.name);
|
|
119
|
+
check(versions.length, "COMPATIBILITY", `No qualified ${alias.name} release supports core ${coreVersion}; update the CLI or select an explicitly compatible version`);
|
|
120
|
+
version = [...versions, ...installed].sort(compare)[0];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Even 'update' must never retarget an existing immutable version lock.
|
|
124
|
+
return {
|
|
125
|
+
...args,
|
|
126
|
+
reference: `${base}${version}`,
|
|
127
|
+
tagPrefix: identity.tagPrefix,
|
|
128
|
+
update: false,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export async function executePluginOperation(context, operation, args = {}) {
|
|
132
|
+
try {
|
|
133
|
+
if (operation === "packages_install" || operation === "plugin_versions") {
|
|
134
|
+
const parsed = operationSchemas[operation].safeParse(args);
|
|
135
|
+
check(parsed.success, "SCHEMA", "Invalid plugin operation arguments");
|
|
136
|
+
if (operation === "packages_install")
|
|
137
|
+
check(context.allowWrite, "PERMISSION", "Package installation requires write access");
|
|
138
|
+
check(context.allowNetwork || parsed.data?.fromGit, "PERMISSION", "Package access requires explicit package-network access");
|
|
139
|
+
args = await resolvePluginArgs(context, operation, parsed.data);
|
|
140
|
+
}
|
|
141
|
+
const result = await executeAsync(context, operation, args);
|
|
142
|
+
// Keep custom manifest paths in every returned installable reference.
|
|
143
|
+
if (operation === "plugin_versions" && result.ok) {
|
|
144
|
+
const identity = Object.values(officialPlugins).find((p) => p.repository === args.provider && p.tagPrefix === args.tagPrefix);
|
|
145
|
+
if (identity)
|
|
146
|
+
result.result.versions = result.result.versions.map((v) => ({
|
|
147
|
+
...v,
|
|
148
|
+
reference: `${identity.repository}/${identity.path}@${v.version}`,
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
const e = error instanceof Problem
|
|
155
|
+
? error
|
|
156
|
+
: new Problem("PACKAGE", "Plugin resolution failed; check the reference and catalogue");
|
|
157
|
+
return {
|
|
158
|
+
apiVersion: "ingestron.operation/v1",
|
|
159
|
+
operation,
|
|
160
|
+
ok: false,
|
|
161
|
+
diagnostics: [{ code: e.code, message: e.message }],
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
+
import { officialName } from "./plugin-resolution.js";
|
|
1
2
|
import { browsePlugins } from "./plugin-browser.js";
|
|
2
3
|
import * as prompts from "@clack/prompts";
|
|
3
4
|
import { friendlyReference } from "@ingestron/core/adapter";
|
|
4
|
-
import { existsSync } from "node:fs";
|
|
5
|
-
import { resolve } from "node:path";
|
|
6
|
-
import { packageYaml, resolvePackage } from "@ingestron/core/adapter";
|
|
7
|
-
import { execute, } from "@ingestron/core";
|
|
8
5
|
import { check } from "@ingestron/core/adapter";
|
|
9
6
|
/** Implemented CLI workflows over the versioned core operation API. */
|
|
10
7
|
export function workflowCommands(app, host) {
|
|
@@ -179,16 +176,19 @@ export function workflowCommands(app, host) {
|
|
|
179
176
|
.action((id) => run("run_status", { id }));
|
|
180
177
|
// Installation is explicit; browsing only inspects installed packages.
|
|
181
178
|
const installProvider = async (reference, options, update = false) => {
|
|
182
|
-
if (!reference
|
|
183
|
-
check(canPrompt(), "INPUT", "Choose an
|
|
179
|
+
if (!reference) {
|
|
180
|
+
check(canPrompt(), "INPUT", "Choose an official plugin: plugin install github or plugin install local; explicit owner/repository@version references also work.");
|
|
181
|
+
reference = await answer(prompts.text({
|
|
182
|
+
message: "Official plugin name or owner/repository",
|
|
183
|
+
validate: (value) => /^(github|local|[\w.-]+\/[\w.-]+)$/.test(value ?? "")
|
|
184
|
+
? undefined
|
|
185
|
+
: "Use github, local or owner/repository",
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
check(typeof reference === "string", "INPUT", "Choose a plugin reference");
|
|
189
|
+
if (reference.includes("/") && !reference.includes("@")) {
|
|
190
|
+
check(canPrompt(), "INPUT", "Explicit repositories require an exact version: owner/repository@1.2.3. Official names github and local can omit the version.");
|
|
184
191
|
check(!options.frozen, "OPTION", "Frozen installation requires an exact locked reference");
|
|
185
|
-
if (!reference)
|
|
186
|
-
reference = await answer(prompts.text({
|
|
187
|
-
message: "Plugin GitHub repository (owner/repository)",
|
|
188
|
-
validate: (value) => /^[\w.-]+\/[\w.-]+$/.test(value ?? "")
|
|
189
|
-
? undefined
|
|
190
|
-
: "Use owner/repository",
|
|
191
|
-
}));
|
|
192
192
|
const available = await perform("plugin_versions", {
|
|
193
193
|
provider: reference,
|
|
194
194
|
...(options.fromGit ? { fromGit: options.fromGit } : {}),
|
|
@@ -210,6 +210,8 @@ export function workflowCommands(app, host) {
|
|
|
210
210
|
}));
|
|
211
211
|
}
|
|
212
212
|
check(typeof reference === "string", "INPUT", "Choose a provider version");
|
|
213
|
+
officialName(reference);
|
|
214
|
+
check(!options.name, "OPTION", "Installation no longer configures projects. Use plugin configure <exact-reference> --name <configuration>.");
|
|
213
215
|
const result = await perform("packages_install", {
|
|
214
216
|
reference,
|
|
215
217
|
update,
|
|
@@ -221,41 +223,7 @@ export function workflowCommands(app, host) {
|
|
|
221
223
|
print(result);
|
|
222
224
|
return;
|
|
223
225
|
}
|
|
224
|
-
|
|
225
|
-
"ingestron.provider/v1",
|
|
226
|
-
"ingestron.connector/v1",
|
|
227
|
-
].includes(packageYaml(resolvePackage(context().root, result.result.reference).file)
|
|
228
|
-
.apiVersion);
|
|
229
|
-
if (options.cacheOnly ||
|
|
230
|
-
!provider ||
|
|
231
|
-
!existsSync(resolve(context().root, "project.yaml"))) {
|
|
232
|
-
print(result, { reference });
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
const proposal = execute(context(), "plugin_configure", {
|
|
236
|
-
reference,
|
|
237
|
-
update,
|
|
238
|
-
...(options.name ? { name: options.name } : {}),
|
|
239
|
-
});
|
|
240
|
-
if (!proposal.ok) {
|
|
241
|
-
print(proposal);
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
const applied = execute(context(), "apply", {
|
|
245
|
-
proposal: proposal.result,
|
|
246
|
-
});
|
|
247
|
-
if (!applied.ok) {
|
|
248
|
-
print(applied);
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
print({
|
|
252
|
-
...result,
|
|
253
|
-
result: {
|
|
254
|
-
...result.result,
|
|
255
|
-
configured: true,
|
|
256
|
-
files: applied.result.files,
|
|
257
|
-
},
|
|
258
|
-
}, { reference });
|
|
226
|
+
print(result, { reference: result.result.reference });
|
|
259
227
|
};
|
|
260
228
|
const plugin = app
|
|
261
229
|
.command("plugin")
|
|
@@ -288,7 +256,7 @@ export function workflowCommands(app, host) {
|
|
|
288
256
|
.action((id) => run("plugin_show", { id }));
|
|
289
257
|
plugin
|
|
290
258
|
.command("versions <provider>")
|
|
291
|
-
.description("List
|
|
259
|
+
.description("List stable tags for an official name or owner/repository; compatibility checked at install")
|
|
292
260
|
.option("--from-git <directory>", "Inspect a local Git repository")
|
|
293
261
|
.option("--tag-prefix <prefix>", "Component tag prefix in a shared repository")
|
|
294
262
|
.action(async (provider, options) => print(await perform("plugin_versions", { provider, ...options }, `Finding versions for ${provider}`)));
|
|
@@ -299,12 +267,12 @@ export function workflowCommands(app, host) {
|
|
|
299
267
|
for (const update of [false, true])
|
|
300
268
|
plugin
|
|
301
269
|
.command(`${update ? "update <reference>" : "install [reference]"}`)
|
|
302
|
-
.description("
|
|
270
|
+
.description("Cache a plugin without changing project configuration; official names default to latest qualified")
|
|
303
271
|
.option("--from-git <directory>", "Local Git source")
|
|
304
272
|
.option("--tag-prefix <prefix>", "Component tag prefix in a shared repository")
|
|
305
273
|
.option("--frozen", "Require an existing immutable lock")
|
|
306
|
-
.option("--name <configuration>", "
|
|
307
|
-
.option("--cache-only", "
|
|
274
|
+
.option("--name <configuration>", "Removed: use plugin configure --name instead")
|
|
275
|
+
.option("--cache-only", "Compatibility option; cache-only is now the default")
|
|
308
276
|
.action((reference, options) => installProvider(reference, options, update));
|
|
309
277
|
plugin
|
|
310
278
|
.command("configure <reference>")
|
package/build/cli/mcp/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
-
import { execute,
|
|
3
|
+
import { execute, operationSchemas } from "@ingestron/core";
|
|
4
|
+
import { executePluginOperation } from "../cli/plugin-resolution.js";
|
|
4
5
|
import { version } from "../version.js";
|
|
5
6
|
export function createServer(root, allowWrite = false, environment = "dev", allowNetwork = false, allowExecute = false) {
|
|
6
7
|
const server = new McpServer({ name: "ingestron", version }, {
|
|
@@ -32,7 +33,7 @@ export function createServer(root, allowWrite = false, environment = "dev", allo
|
|
|
32
33
|
["plugin_versions", "packages_install"].includes(name)),
|
|
33
34
|
},
|
|
34
35
|
}, async (request) => {
|
|
35
|
-
const result = await
|
|
36
|
+
const result = await executePluginOperation({ root, environment, allowWrite, allowNetwork, allowExecute }, name, request);
|
|
36
37
|
return {
|
|
37
38
|
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
38
39
|
isError: !result.ok,
|
package/build/cli/version.d.ts
CHANGED
package/build/cli/version.js
CHANGED
|
@@ -11,3 +11,4 @@ while (!existsSync(join(root, "package.json")) ||
|
|
|
11
11
|
root = parent;
|
|
12
12
|
}
|
|
13
13
|
export const version = JSON.parse(readFileSync(join(root, "package.json"), "utf8")).version;
|
|
14
|
+
export const coreVersion = JSON.parse(readFileSync(join(root, "package.json"), "utf8")).dependencies["@ingestron/core"];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ingestron",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Build repeatable data pipelines from reviewed contracts and versioned standards.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
"THIRD_PARTY_NOTICES.md"
|
|
21
21
|
],
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=22
|
|
23
|
+
"node": ">=22.12.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@clack/prompts": "1.7.0",
|
|
27
|
-
"@ingestron/core": "0.12.
|
|
27
|
+
"@ingestron/core": "0.12.1",
|
|
28
28
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
29
29
|
"commander": "15.0.0",
|
|
30
30
|
"yaml": "2.9.0"
|