toolfactory 0.1.2 → 0.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.
Files changed (98) hide show
  1. package/README.md +24 -1
  2. package/dist/commands.d.ts +1 -1
  3. package/dist/distribution/native.d.ts +50 -0
  4. package/dist/distribution/native.js +414 -0
  5. package/dist/distribution/native.test.d.ts +1 -0
  6. package/dist/distribution/native.test.js +127 -0
  7. package/dist/distribution/system.d.ts +57 -0
  8. package/dist/distribution/system.js +637 -0
  9. package/dist/distribution/system.test.d.ts +1 -0
  10. package/dist/distribution/system.test.js +116 -0
  11. package/dist/e2e.test.js +7 -1
  12. package/dist/hosts/openclaw.js +6 -2
  13. package/dist/hosts/vscode.d.ts +1 -0
  14. package/dist/hosts/vscode.js +67 -0
  15. package/dist/model.d.ts +62 -2
  16. package/dist/model.js +9 -0
  17. package/dist/ops.d.ts +52 -0
  18. package/dist/project/apply.d.ts +1 -1
  19. package/dist/project/apply.js +194 -17
  20. package/dist/project/apply.test.js +103 -0
  21. package/dist/project/gate.d.ts +17 -2
  22. package/dist/project/gate.js +68 -3
  23. package/dist/project/history.d.ts +29 -1
  24. package/dist/project/lock.d.ts +5 -0
  25. package/dist/project/lock.js +9 -0
  26. package/dist/surfaces/agent-plugins.js +5 -4
  27. package/dist/surfaces/agents.js +21 -3
  28. package/dist/surfaces/agents.test.js +12 -0
  29. package/dist/surfaces/claude.js +8 -3
  30. package/dist/surfaces/codex.js +8 -3
  31. package/dist/surfaces/codex.test.js +8 -8
  32. package/dist/surfaces/cursor.js +2 -2
  33. package/dist/surfaces/distribution.test.js +3 -3
  34. package/dist/surfaces/dsh.js +25 -6
  35. package/dist/surfaces/dsh.test.js +8 -3
  36. package/dist/surfaces/gemini.js +2 -2
  37. package/dist/surfaces/gemini.test.js +4 -4
  38. package/dist/surfaces/hermes-native.js +38 -9
  39. package/dist/surfaces/hermes-native.test.js +32 -11
  40. package/dist/surfaces/mcp-registry.js +43 -5
  41. package/dist/surfaces/mcp-registry.test.js +18 -0
  42. package/dist/surfaces/openclaw-native.js +10 -8
  43. package/dist/surfaces/openclaw-native.test.js +30 -0
  44. package/dist/surfaces/readme.d.ts +16 -0
  45. package/dist/surfaces/readme.js +7 -0
  46. package/dist/surfaces/registry.js +6 -0
  47. package/dist/surfaces/vscode-extension.d.ts +14 -0
  48. package/dist/surfaces/vscode-extension.js +312 -0
  49. package/dist/surfaces/vscode-extension.test.d.ts +1 -0
  50. package/dist/surfaces/vscode-extension.test.js +81 -0
  51. package/dist/surfaces/vscode-scaffold.d.ts +43 -0
  52. package/dist/surfaces/vscode-scaffold.js +43 -0
  53. package/dist/surfaces/workflows.js +49 -10
  54. package/dist/surfaces/workflows.test.js +3 -2
  55. package/dist/toolfactory/cli.js +1 -1
  56. package/dist/toolfactory/mcp.js +1 -1
  57. package/package.json +2 -1
  58. package/src/distribution/native.test.ts +161 -0
  59. package/src/distribution/native.ts +460 -0
  60. package/src/distribution/system.test.ts +136 -0
  61. package/src/distribution/system.ts +688 -0
  62. package/src/e2e.test.ts +7 -1
  63. package/src/hosts/openclaw.ts +4 -2
  64. package/src/hosts/vscode.ts +79 -0
  65. package/src/model.ts +15 -1
  66. package/src/project/apply.test.ts +120 -0
  67. package/src/project/apply.ts +257 -15
  68. package/src/project/gate.ts +96 -4
  69. package/src/project/lock.ts +12 -0
  70. package/src/surfaces/agent-plugins.ts +5 -4
  71. package/src/surfaces/agents.test.ts +16 -0
  72. package/src/surfaces/agents.ts +31 -3
  73. package/src/surfaces/claude.ts +7 -3
  74. package/src/surfaces/codex.test.ts +7 -7
  75. package/src/surfaces/codex.ts +8 -3
  76. package/src/surfaces/cursor.ts +2 -10
  77. package/src/surfaces/distribution.test.ts +2 -2
  78. package/src/surfaces/dsh.test.ts +8 -2
  79. package/src/surfaces/dsh.ts +26 -6
  80. package/src/surfaces/gemini.test.ts +3 -3
  81. package/src/surfaces/gemini.ts +1 -2
  82. package/src/surfaces/hermes-native.test.ts +39 -10
  83. package/src/surfaces/hermes-native.ts +41 -11
  84. package/src/surfaces/mcp-registry.test.ts +20 -0
  85. package/src/surfaces/mcp-registry.ts +46 -6
  86. package/src/surfaces/openclaw-native.test.ts +37 -0
  87. package/src/surfaces/openclaw-native.ts +49 -47
  88. package/src/surfaces/readme.ts +10 -0
  89. package/src/surfaces/registry.ts +6 -0
  90. package/src/surfaces/vscode-extension.test.ts +89 -0
  91. package/src/surfaces/vscode-extension.ts +345 -0
  92. package/src/surfaces/vscode-scaffold.ts +55 -0
  93. package/src/surfaces/workflows.test.ts +3 -4
  94. package/src/surfaces/workflows.ts +49 -10
  95. package/src/toolfactory/cli.ts +1 -1
  96. package/src/toolfactory/mcp.ts +1 -1
  97. package/web/dist/assets/{index-Spapkkvh.js → index-CVm6m4s0.js} +1 -1
  98. package/web/dist/index.html +1 -1
@@ -0,0 +1,116 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { systemPackageConfigSchema, systemPackageJobs, systemPackageSteps, systemPublishJobs, systemRegistryRows, } from "./system.js";
3
+ function project(entries, surfaces = entries.map((entry) => entry.id)) {
4
+ return {
5
+ root: "/local/never-in-output",
6
+ tool: {
7
+ schemaVersion: 1,
8
+ identity: "package.json",
9
+ binding: "typescript",
10
+ surfaces: surfaces,
11
+ bundle: { runtime: "package" },
12
+ tests: { examples: {} },
13
+ systemPackages: entries,
14
+ },
15
+ identity: { name: "tool", version: "1.2.3" },
16
+ identityExtra: {},
17
+ operations: [],
18
+ toolfactoryVersion: "0.1.0",
19
+ };
20
+ }
21
+ const choco = {
22
+ id: "chocolatey",
23
+ path: "packaging/choco",
24
+ identity: "tool.nuspec",
25
+ name: "tool",
26
+ versionCommand: "node -p \"require('./tool.nuspec.version.json').version\"",
27
+ };
28
+ describe("system packages", () => {
29
+ it("requires real catalog/repository configuration", () => {
30
+ expect(() => systemPackageConfigSchema.parse({ ...choco, id: "apt" })).toThrow(/PPA/);
31
+ expect(() => systemPackageConfigSchema.parse({
32
+ id: "scoop",
33
+ path: "packaging/scoop",
34
+ identity: "tool.json",
35
+ name: "tool",
36
+ versionCommand: "Get-Content VERSION",
37
+ buildCommand: "./build.ps1",
38
+ asset: "../tool.zip",
39
+ bucket: "acme/scoop-bucket",
40
+ bucketName: "acme",
41
+ catalogPath: "bucket/tool.json",
42
+ })).toThrow(/path must stay/);
43
+ expect(() => systemPackageSteps(project([], ["chocolatey"]))).toThrow(/exactly one/);
44
+ });
45
+ it("packages with checkout-relative paths", () => {
46
+ const steps = systemPackageSteps(project([choco]), { local: false });
47
+ expect(steps.at(-1)?.run).toContain("choco pack 'packaging/choco/tool.nuspec'");
48
+ expect(steps.at(-1)?.run).not.toContain("/local/never-in-output");
49
+ });
50
+ it("stages a non-root WinGet manifest directory and Debian source changes portably", () => {
51
+ const winget = {
52
+ id: "winget",
53
+ path: "packaging/winget",
54
+ identity: "manifests/a/acme/tool/1.2.3",
55
+ name: "Acme.Tool",
56
+ versionCommand: "cat VERSION",
57
+ buildCommand: "./build-installer.ps1",
58
+ asset: "dist/tool.msi",
59
+ };
60
+ const apt = {
61
+ id: "apt",
62
+ path: "packaging/debian/source",
63
+ identity: "debian/control",
64
+ name: "tool",
65
+ versionCommand: "dpkg-parsechangelog -S Version | cut -d- -f1",
66
+ ppa: "acme/tool",
67
+ buildDependencies: ["debhelper"],
68
+ };
69
+ const steps = systemPackageSteps(project([winget, apt]), { local: false });
70
+ expect(steps.find((step) => step.name === "WinGet catalog submission")?.run).toContain("test -d 'packaging/winget/manifests/a/acme/tool/1.2.3'");
71
+ const debian = steps.find((step) => step.name === "Debian source package")?.run;
72
+ expect(debian).toContain("find 'packaging/debian/source/..'");
73
+ expect(debian).toContain("'dist/release/system/apt'");
74
+ expect(debian).not.toContain("../dist/release");
75
+ });
76
+ it("gates direct jobs and commits author-controlled Homebrew metadata after release", () => {
77
+ const brew = {
78
+ id: "homebrew",
79
+ path: "packaging/brew",
80
+ identity: "tool.rb",
81
+ name: "tool",
82
+ versionCommand: "grep VERSION tool.rb",
83
+ buildCommand: "make release-archive",
84
+ asset: "dist/tool.tar.gz",
85
+ tap: "acme/homebrew-tap",
86
+ catalogPath: "Formula/tool.rb",
87
+ };
88
+ const jobs = systemPublishJobs(project([choco, brew]), "release-assets", "${{ needs.gate.outputs.sha }}");
89
+ expect(jobs["publish-chocolatey"]?.if).toBe("needs.gate.outputs.chocolatey == 'true'");
90
+ expect(jobs["publish-homebrew"]?.needs).toEqual(["gate", "release"]);
91
+ expect(JSON.stringify(jobs["publish-homebrew"])).toContain("git -C .system-catalog push");
92
+ expect(JSON.stringify(jobs["publish-homebrew"])).toContain("system-homebrew");
93
+ expect(JSON.stringify(jobs["publish-homebrew"])).toContain("toolfactory-postrelease/tap");
94
+ expect(JSON.stringify(jobs["publish-chocolatey"])).toContain("system-chocolatey");
95
+ expect(JSON.stringify(jobs)).not.toContain("/local/never-in-output");
96
+ expect(systemRegistryRows(project([choco])).at(0)?.secrets).toEqual(["CHOCOLATEY_API_KEY"]);
97
+ });
98
+ it("uses dedicated native runners and upload names instead of the Ubuntu package job", () => {
99
+ const brew = {
100
+ id: "homebrew",
101
+ path: "packaging/brew",
102
+ identity: "tool.rb",
103
+ name: "tool",
104
+ versionCommand: "grep VERSION tool.rb",
105
+ buildCommand: "make release-archive",
106
+ asset: "dist/tool.tar.gz",
107
+ tap: "acme/homebrew-tap",
108
+ catalogPath: "Formula/tool.rb",
109
+ };
110
+ const jobs = systemPackageJobs(project([choco, brew]), "${{ github.sha }}");
111
+ expect(jobs["system-homebrew"]?.["runs-on"]).toBe("macos-latest");
112
+ expect(jobs["system-chocolatey"]?.["runs-on"]).toBe("windows-latest");
113
+ expect(JSON.stringify(jobs["system-chocolatey"])).toContain("system-chocolatey");
114
+ expect(JSON.stringify(jobs)).not.toContain("/local/never-in-output");
115
+ });
116
+ });
package/dist/e2e.test.js CHANGED
@@ -119,6 +119,12 @@ describe.skipIf(!existsSync(repoNodeModules))("confluence: a walked tree equals
119
119
  await commands.introspect(fresh);
120
120
  authorProse(fresh);
121
121
  commands.build(fresh);
122
- expect(tree(walked)).toEqual(tree(fresh));
122
+ const walkedTree = tree(walked);
123
+ // Deselecting a region surface preserves its author-owned scaffold, including an empty
124
+ // Docker ignore file. All managed bytes still converge with the freshly generated tree.
125
+ expect(walkedTree[".dockerignore"]).toContain("# tf:dockerignore# /tf:dockerignore");
126
+ expect(walkedTree[".dockerignore"]).not.toContain("node_modules/");
127
+ delete walkedTree[".dockerignore"];
128
+ expect(walkedTree).toEqual(tree(fresh));
123
129
  });
124
130
  });
@@ -56,9 +56,13 @@ function missing(scaffold, ours, path, skip) {
56
56
  }
57
57
  function planned(files, path) {
58
58
  const file = files.find((candidate) => candidate.path === `${HOST_DIR}/${path}`);
59
- if (file?.kind !== "file")
59
+ if (!file)
60
60
  throw new Error(`the openclaw surface no longer plans ${path}`);
61
- return file.content;
61
+ if (file.kind === "file")
62
+ return file.content;
63
+ if (file.kind === "merge" && file.format === "json")
64
+ return JSON.stringify(file.patch, null, 2);
65
+ throw new Error(`the openclaw surface no longer plans ${path} as JSON`);
62
66
  }
63
67
  /** Human-readable drift lines; empty means the generator still mirrors upstream. */
64
68
  export function scaffoldDrift(project) {
@@ -0,0 +1 @@
1
+ export declare function scaffoldDrift(): string[];
@@ -0,0 +1,67 @@
1
+ /** Verify the extension scaffold against Microsoft's generator, without touching the checkout. */
2
+ import { execFileSync } from "node:child_process";
3
+ import { mkdtempSync, readFileSync, rmSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { argv } from "node:process";
7
+ import { fileURLToPath } from "node:url";
8
+ import { ESBUILD, ESLINT, GITIGNORE, IGNORE, LAUNCH, TASKS, VSCODE_GENERATOR, VSCODE_SCAFFOLD, } from "../surfaces/vscode-scaffold.js";
9
+ export function scaffoldDrift() {
10
+ const root = mkdtempSync(join(tmpdir(), "toolfactory-vscode-scaffold-"));
11
+ const target = join(root, "probe");
12
+ try {
13
+ execFileSync("npx", [
14
+ "--yes",
15
+ "--package",
16
+ "yo",
17
+ "--package",
18
+ `generator-code@${VSCODE_GENERATOR}`,
19
+ "--",
20
+ "yo",
21
+ "code",
22
+ target,
23
+ "--extensionType",
24
+ "ts",
25
+ "--extensionDisplayName",
26
+ "ToolFactory Probe",
27
+ "--extensionId",
28
+ "tf-probe",
29
+ "--extensionDescription",
30
+ "ToolFactory scaffold probe",
31
+ "--pkgManager",
32
+ "npm",
33
+ "--bundler",
34
+ "esbuild",
35
+ "--gitInit",
36
+ "false",
37
+ "--skip-install",
38
+ "--skipOpen",
39
+ "--quick",
40
+ ], { stdio: "pipe", cwd: root });
41
+ const pkg = JSON.parse(readFileSync(join(target, "package.json"), "utf8"));
42
+ const drift = Object.entries(VSCODE_SCAFFOLD)
43
+ .filter(([key, expected]) => JSON.stringify(pkg[key]) !== JSON.stringify(expected))
44
+ .map(([key]) => `package.json ${key}`);
45
+ for (const [path, expected] of [
46
+ ["esbuild.js", ESBUILD],
47
+ ["eslint.config.mjs", ESLINT],
48
+ [".vscodeignore", IGNORE],
49
+ [".gitignore", GITIGNORE],
50
+ [".vscode/launch.json", LAUNCH],
51
+ [".vscode/tasks.json", TASKS],
52
+ ]) {
53
+ if (readFileSync(join(target, path), "utf8") !== expected)
54
+ drift.push(path);
55
+ }
56
+ return drift;
57
+ }
58
+ finally {
59
+ rmSync(root, { recursive: true, force: true });
60
+ }
61
+ }
62
+ if (argv[1] === fileURLToPath(import.meta.url)) {
63
+ const drift = scaffoldDrift();
64
+ if (drift.length)
65
+ throw new Error(`VS Code scaffold drifted: ${drift.join(", ")}`);
66
+ process.stdout.write("VS Code scaffold matches generator-code.\n");
67
+ }
package/dist/model.d.ts CHANGED
@@ -10,7 +10,7 @@ import { z } from "zod";
10
10
  export declare const CAPABILITIES: readonly ["net", "fs", "shell", "secret", "browser", "model", "user-input", "channel"];
11
11
  export type Capability = (typeof CAPABILITIES)[number];
12
12
  export declare const PORTABLE_CAPABILITIES: ReadonlySet<Capability>;
13
- export declare const SURFACE_IDS: readonly ["skill", "agent-plugins", "claude", "codex", "cursor", "mcp", "mcp-registry", "cli", "npm", "pypi", "openclaw-native", "hermes-native", "clawhub", "web", "dsh", "workflows", "agents", "readme", "gemini", "mcpb", "browser-extension"];
13
+ export declare const SURFACE_IDS: readonly ["skill", "agent-plugins", "claude", "codex", "cursor", "mcp", "mcp-registry", "cli", "npm", "pypi", "openclaw-native", "hermes-native", "clawhub", "web", "dsh", "workflows", "agents", "readme", "gemini", "mcpb", "browser-extension", "vscode-extension", "cargo", "nuget", "maven-central", "rubygems", "packagist", "go-module", "homebrew", "winget", "scoop", "chocolatey", "apt", "rpm"];
14
14
  export type SurfaceId = (typeof SURFACE_IDS)[number];
15
15
  export declare const BINDINGS: readonly ["typescript", "python"];
16
16
  export type Binding = (typeof BINDINGS)[number];
@@ -41,6 +41,12 @@ export declare const ToolConfigSchema: z.ZodObject<{
41
41
  none: "none";
42
42
  }>>;
43
43
  surfaces: z.ZodArray<z.ZodEnum<{
44
+ homebrew: "homebrew";
45
+ winget: "winget";
46
+ scoop: "scoop";
47
+ chocolatey: "chocolatey";
48
+ apt: "apt";
49
+ rpm: "rpm";
44
50
  skill: "skill";
45
51
  "agent-plugins": "agent-plugins";
46
52
  claude: "claude";
@@ -62,6 +68,13 @@ export declare const ToolConfigSchema: z.ZodObject<{
62
68
  gemini: "gemini";
63
69
  mcpb: "mcpb";
64
70
  "browser-extension": "browser-extension";
71
+ "vscode-extension": "vscode-extension";
72
+ cargo: "cargo";
73
+ nuget: "nuget";
74
+ "maven-central": "maven-central";
75
+ rubygems: "rubygems";
76
+ packagist: "packagist";
77
+ "go-module": "go-module";
65
78
  }>>;
66
79
  kernel: z.ZodOptional<z.ZodObject<{
67
80
  command: z.ZodString;
@@ -99,6 +112,48 @@ export declare const ToolConfigSchema: z.ZodObject<{
99
112
  hermes: z.ZodOptional<z.ZodObject<{
100
113
  toolset: z.ZodOptional<z.ZodString>;
101
114
  }, z.core.$strip>>;
115
+ vscode: z.ZodOptional<z.ZodObject<{
116
+ publisher: z.ZodOptional<z.ZodString>;
117
+ marketplace: z.ZodDefault<z.ZodBoolean>;
118
+ openvsx: z.ZodDefault<z.ZodBoolean>;
119
+ }, z.core.$strip>>;
120
+ nativePackages: z.ZodOptional<z.ZodArray<z.ZodObject<{
121
+ id: z.ZodEnum<{
122
+ cargo: "cargo";
123
+ nuget: "nuget";
124
+ "maven-central": "maven-central";
125
+ rubygems: "rubygems";
126
+ packagist: "packagist";
127
+ "go-module": "go-module";
128
+ }>;
129
+ path: z.ZodString;
130
+ identity: z.ZodString;
131
+ name: z.ZodString;
132
+ versionCommand: z.ZodOptional<z.ZodString>;
133
+ }, z.core.$strict>>>;
134
+ systemPackages: z.ZodOptional<z.ZodArray<z.ZodObject<{
135
+ id: z.ZodEnum<{
136
+ homebrew: "homebrew";
137
+ winget: "winget";
138
+ scoop: "scoop";
139
+ chocolatey: "chocolatey";
140
+ apt: "apt";
141
+ rpm: "rpm";
142
+ }>;
143
+ path: z.ZodString;
144
+ identity: z.ZodString;
145
+ name: z.ZodString;
146
+ versionCommand: z.ZodString;
147
+ buildCommand: z.ZodOptional<z.ZodString>;
148
+ buildDependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
149
+ asset: z.ZodOptional<z.ZodString>;
150
+ tap: z.ZodOptional<z.ZodString>;
151
+ bucket: z.ZodOptional<z.ZodString>;
152
+ bucketName: z.ZodOptional<z.ZodString>;
153
+ catalogPath: z.ZodOptional<z.ZodString>;
154
+ ppa: z.ZodOptional<z.ZodString>;
155
+ coprProject: z.ZodOptional<z.ZodString>;
156
+ }, z.core.$strict>>>;
102
157
  openclaw: z.ZodOptional<z.ZodObject<{
103
158
  registers: z.ZodOptional<z.ZodArray<z.ZodObject<{
104
159
  api: z.ZodString;
@@ -183,10 +238,15 @@ export interface RegionFile {
183
238
  export interface MergeFile {
184
239
  kind: "merge";
185
240
  path: string;
186
- format: "json" | "toml";
241
+ format: "json" | "toml" | "yaml";
187
242
  patch: Record<string, unknown>;
188
243
  /** Dotted paths inside `patch` whose object toolfactory owns whole: replaced, never merged. */
189
244
  owned?: string[];
245
+ /**
246
+ * Arrays whose entries are shared by a stable identifier. Toolfactory replaces only entries it
247
+ * previously wrote, preserves the author's other entries, and rejects an id collision.
248
+ */
249
+ keyedArrays?: Record<string, string>;
190
250
  }
191
251
  export type PlannedFile = FullFile | RegionFile | MergeFile;
192
252
  export interface Command {
package/dist/model.js CHANGED
@@ -7,6 +7,9 @@
7
7
  * rest is derived and written in-tree, tracked by a lock file.
8
8
  */
9
9
  import { z } from "zod";
10
+ import { NATIVE_PACKAGE_IDS, nativePackageConfigSchema } from "./distribution/native.js";
11
+ import { SYSTEM_PACKAGE_IDS, systemPackageConfigSchema } from "./distribution/system.js";
12
+ import { vscodeConfigSchema } from "./surfaces/vscode-extension.js";
10
13
  export const CAPABILITIES = [
11
14
  "net",
12
15
  "fs",
@@ -45,6 +48,9 @@ export const SURFACE_IDS = [
45
48
  "gemini",
46
49
  "mcpb",
47
50
  "browser-extension",
51
+ "vscode-extension",
52
+ ...NATIVE_PACKAGE_IDS,
53
+ ...SYSTEM_PACKAGE_IDS,
48
54
  ];
49
55
  export const BINDINGS = ["typescript", "python"];
50
56
  /**
@@ -146,6 +152,9 @@ export const ToolConfigSchema = z
146
152
  .optional()
147
153
  .describe("Privacy-policy URLs of the services this tool talks to; Anthropic's Connectors Directory submission requires them in the MCPB manifest."),
148
154
  hermes: z.object({ toolset: z.string().optional() }).optional(),
155
+ vscode: vscodeConfigSchema.optional(),
156
+ nativePackages: z.array(nativePackageConfigSchema).optional(),
157
+ systemPackages: z.array(systemPackageConfigSchema).optional(),
149
158
  openclaw: z
150
159
  .object({
151
160
  registers: z
package/dist/ops.d.ts CHANGED
@@ -16,6 +16,12 @@ export declare const operations: (import("./toolfactory/types.js").Operation<z.Z
16
16
  none: "none";
17
17
  }>>;
18
18
  surfaces: z.ZodOptional<z.ZodArray<z.ZodEnum<{
19
+ homebrew: "homebrew";
20
+ winget: "winget";
21
+ scoop: "scoop";
22
+ chocolatey: "chocolatey";
23
+ apt: "apt";
24
+ rpm: "rpm";
19
25
  skill: "skill";
20
26
  "agent-plugins": "agent-plugins";
21
27
  claude: "claude";
@@ -37,6 +43,13 @@ export declare const operations: (import("./toolfactory/types.js").Operation<z.Z
37
43
  gemini: "gemini";
38
44
  mcpb: "mcpb";
39
45
  "browser-extension": "browser-extension";
46
+ "vscode-extension": "vscode-extension";
47
+ cargo: "cargo";
48
+ nuget: "nuget";
49
+ "maven-central": "maven-central";
50
+ rubygems: "rubygems";
51
+ packagist: "packagist";
52
+ "go-module": "go-module";
40
53
  }>>>;
41
54
  description: z.ZodOptional<z.ZodString>;
42
55
  license: z.ZodOptional<z.ZodString>;
@@ -86,6 +99,12 @@ export declare const operations: (import("./toolfactory/types.js").Operation<z.Z
86
99
  }, z.core.$strip>> | import("./toolfactory/types.js").Operation<z.ZodObject<{
87
100
  root: z.ZodDefault<z.ZodString>;
88
101
  surface: z.ZodOptional<z.ZodEnum<{
102
+ homebrew: "homebrew";
103
+ winget: "winget";
104
+ scoop: "scoop";
105
+ chocolatey: "chocolatey";
106
+ apt: "apt";
107
+ rpm: "rpm";
89
108
  skill: "skill";
90
109
  "agent-plugins": "agent-plugins";
91
110
  claude: "claude";
@@ -107,6 +126,13 @@ export declare const operations: (import("./toolfactory/types.js").Operation<z.Z
107
126
  gemini: "gemini";
108
127
  mcpb: "mcpb";
109
128
  "browser-extension": "browser-extension";
129
+ "vscode-extension": "vscode-extension";
130
+ cargo: "cargo";
131
+ nuget: "nuget";
132
+ "maven-central": "maven-central";
133
+ rubygems: "rubygems";
134
+ packagist: "packagist";
135
+ "go-module": "go-module";
110
136
  }>>;
111
137
  }, z.core.$strip>, z.ZodObject<{
112
138
  outcomes: z.ZodArray<z.ZodObject<{
@@ -138,6 +164,12 @@ export declare const operations: (import("./toolfactory/types.js").Operation<z.Z
138
164
  }, z.core.$strip>> | import("./toolfactory/types.js").Operation<z.ZodObject<{
139
165
  root: z.ZodDefault<z.ZodString>;
140
166
  surface: z.ZodEnum<{
167
+ homebrew: "homebrew";
168
+ winget: "winget";
169
+ scoop: "scoop";
170
+ chocolatey: "chocolatey";
171
+ apt: "apt";
172
+ rpm: "rpm";
141
173
  skill: "skill";
142
174
  "agent-plugins": "agent-plugins";
143
175
  claude: "claude";
@@ -159,6 +191,13 @@ export declare const operations: (import("./toolfactory/types.js").Operation<z.Z
159
191
  gemini: "gemini";
160
192
  mcpb: "mcpb";
161
193
  "browser-extension": "browser-extension";
194
+ "vscode-extension": "vscode-extension";
195
+ cargo: "cargo";
196
+ nuget: "nuget";
197
+ "maven-central": "maven-central";
198
+ rubygems: "rubygems";
199
+ packagist: "packagist";
200
+ "go-module": "go-module";
162
201
  }>;
163
202
  }, z.core.$strip>, z.ZodObject<{
164
203
  adopted: z.ZodArray<z.ZodString>;
@@ -209,6 +248,12 @@ export declare const operations: (import("./toolfactory/types.js").Operation<z.Z
209
248
  }, z.core.$strip>, z.ZodObject<{
210
249
  from: z.ZodOptional<z.ZodString>;
211
250
  dropped: z.ZodArray<z.ZodEnum<{
251
+ homebrew: "homebrew";
252
+ winget: "winget";
253
+ scoop: "scoop";
254
+ chocolatey: "chocolatey";
255
+ apt: "apt";
256
+ rpm: "rpm";
212
257
  skill: "skill";
213
258
  "agent-plugins": "agent-plugins";
214
259
  claude: "claude";
@@ -230,6 +275,13 @@ export declare const operations: (import("./toolfactory/types.js").Operation<z.Z
230
275
  gemini: "gemini";
231
276
  mcpb: "mcpb";
232
277
  "browser-extension": "browser-extension";
278
+ "vscode-extension": "vscode-extension";
279
+ cargo: "cargo";
280
+ nuget: "nuget";
281
+ "maven-central": "maven-central";
282
+ rubygems: "rubygems";
283
+ packagist: "packagist";
284
+ "go-module": "go-module";
233
285
  }>>;
234
286
  steps: z.ZodArray<z.ZodObject<{
235
287
  name: z.ZodString;
@@ -23,7 +23,7 @@ export declare function deepMerge(base: Record<string, unknown>, patch: Record<s
23
23
  /** The values a merge file owns, read back out of a document; an owned object comes back whole. */
24
24
  export declare function pickPatch(document: Record<string, unknown>, patch: Record<string, unknown>, owned?: string[], prefix?: string): Record<string, unknown>;
25
25
  /** The dotted paths a patch writes: one per leaf value, and one per object it owns whole. */
26
- export declare function patchKeys(patch: Record<string, unknown>, owned?: string[], prefix?: string): string[];
26
+ export declare function patchKeys(patch: Record<string, unknown>, owned?: string[], keyedArrays?: Record<string, string>, prefix?: string): string[];
27
27
  /** Uninstall dotted paths from a document, pruning the objects the removal empties. */
28
28
  export declare function removeKeys(document: Record<string, unknown>, keys: readonly string[]): boolean;
29
29
  /** The content toolfactory manages, as one string for hashing and comparison. */