toolfactory 0.1.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/README.md +166 -0
- package/dist/bindings/index.d.ts +23 -0
- package/dist/bindings/index.js +29 -0
- package/dist/bindings/python.d.ts +33 -0
- package/dist/bindings/python.js +805 -0
- package/dist/bindings/python.test.d.ts +1 -0
- package/dist/bindings/python.test.js +316 -0
- package/dist/bindings/typescript.d.ts +39 -0
- package/dist/bindings/typescript.js +758 -0
- package/dist/bindings/typescript.test.d.ts +1 -0
- package/dist/bindings/typescript.test.js +264 -0
- package/dist/commands.d.ts +188 -0
- package/dist/commands.js +662 -0
- package/dist/commands.test.d.ts +1 -0
- package/dist/commands.test.js +215 -0
- package/dist/e2e.test.d.ts +1 -0
- package/dist/e2e.test.js +124 -0
- package/dist/hosts/browser.d.ts +10 -0
- package/dist/hosts/browser.js +94 -0
- package/dist/hosts/github.d.ts +66 -0
- package/dist/hosts/github.js +247 -0
- package/dist/hosts/openclaw.d.ts +4 -0
- package/dist/hosts/openclaw.js +94 -0
- package/dist/hosts/template.d.ts +15 -0
- package/dist/hosts/template.js +142 -0
- package/dist/hosts/web.d.ts +4 -0
- package/dist/hosts/web.js +89 -0
- package/dist/identity/name.d.ts +20 -0
- package/dist/identity/name.js +33 -0
- package/dist/identity/name.test.d.ts +1 -0
- package/dist/identity/name.test.js +37 -0
- package/dist/identity/read.d.ts +9 -0
- package/dist/identity/read.js +106 -0
- package/dist/identity/read.test.d.ts +1 -0
- package/dist/identity/read.test.js +76 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/introspect/index.d.ts +15 -0
- package/dist/introspect/index.js +63 -0
- package/dist/model.d.ts +236 -0
- package/dist/model.js +214 -0
- package/dist/ops.d.ts +255 -0
- package/dist/ops.js +297 -0
- package/dist/project/apply.d.ts +35 -0
- package/dist/project/apply.js +360 -0
- package/dist/project/apply.test.d.ts +1 -0
- package/dist/project/apply.test.js +285 -0
- package/dist/project/gate.d.ts +129 -0
- package/dist/project/gate.js +597 -0
- package/dist/project/history.d.ts +62 -0
- package/dist/project/history.js +41 -0
- package/dist/project/load.d.ts +21 -0
- package/dist/project/load.js +82 -0
- package/dist/project/lock.d.ts +28 -0
- package/dist/project/lock.js +42 -0
- package/dist/project/plan.d.ts +5 -0
- package/dist/project/plan.js +96 -0
- package/dist/report/coverage.d.ts +22 -0
- package/dist/report/coverage.js +72 -0
- package/dist/report/coverage.test.d.ts +1 -0
- package/dist/report/coverage.test.js +93 -0
- package/dist/surfaces/agent-plugins.d.ts +10 -0
- package/dist/surfaces/agent-plugins.js +36 -0
- package/dist/surfaces/agents.d.ts +35 -0
- package/dist/surfaces/agents.js +609 -0
- package/dist/surfaces/agents.template.d.ts +8 -0
- package/dist/surfaces/agents.template.js +21 -0
- package/dist/surfaces/agents.test.d.ts +1 -0
- package/dist/surfaces/agents.test.js +181 -0
- package/dist/surfaces/browser-extension.d.ts +101 -0
- package/dist/surfaces/browser-extension.js +1034 -0
- package/dist/surfaces/browser-extension.test.d.ts +1 -0
- package/dist/surfaces/browser-extension.test.js +145 -0
- package/dist/surfaces/claude.d.ts +2 -0
- package/dist/surfaces/claude.js +81 -0
- package/dist/surfaces/codex.d.ts +13 -0
- package/dist/surfaces/codex.js +101 -0
- package/dist/surfaces/codex.test.d.ts +1 -0
- package/dist/surfaces/codex.test.js +67 -0
- package/dist/surfaces/cursor.d.ts +2 -0
- package/dist/surfaces/cursor.js +50 -0
- package/dist/surfaces/distribution.test.d.ts +1 -0
- package/dist/surfaces/distribution.test.js +146 -0
- package/dist/surfaces/dsh.d.ts +25 -0
- package/dist/surfaces/dsh.js +147 -0
- package/dist/surfaces/dsh.test.d.ts +1 -0
- package/dist/surfaces/dsh.test.js +100 -0
- package/dist/surfaces/external.d.ts +9 -0
- package/dist/surfaces/external.js +4 -0
- package/dist/surfaces/gemini.d.ts +29 -0
- package/dist/surfaces/gemini.js +68 -0
- package/dist/surfaces/gemini.test.d.ts +1 -0
- package/dist/surfaces/gemini.test.js +74 -0
- package/dist/surfaces/hermes-native.d.ts +53 -0
- package/dist/surfaces/hermes-native.js +507 -0
- package/dist/surfaces/hermes-native.test.d.ts +1 -0
- package/dist/surfaces/hermes-native.test.js +156 -0
- package/dist/surfaces/kernel.d.ts +5 -0
- package/dist/surfaces/kernel.js +63 -0
- package/dist/surfaces/mcp-registry.d.ts +19 -0
- package/dist/surfaces/mcp-registry.js +160 -0
- package/dist/surfaces/mcp-registry.test.d.ts +1 -0
- package/dist/surfaces/mcp-registry.test.js +79 -0
- package/dist/surfaces/mcpb.d.ts +11 -0
- package/dist/surfaces/mcpb.js +118 -0
- package/dist/surfaces/mcpb.test.d.ts +1 -0
- package/dist/surfaces/mcpb.test.js +104 -0
- package/dist/surfaces/npm.d.ts +6 -0
- package/dist/surfaces/npm.js +72 -0
- package/dist/surfaces/openclaw-native.d.ts +93 -0
- package/dist/surfaces/openclaw-native.js +956 -0
- package/dist/surfaces/openclaw-native.test.d.ts +1 -0
- package/dist/surfaces/openclaw-native.test.js +246 -0
- package/dist/surfaces/pypi.d.ts +5 -0
- package/dist/surfaces/pypi.js +82 -0
- package/dist/surfaces/readme.d.ts +7 -0
- package/dist/surfaces/readme.js +181 -0
- package/dist/surfaces/registry.d.ts +6 -0
- package/dist/surfaces/registry.js +73 -0
- package/dist/surfaces/shared.d.ts +49 -0
- package/dist/surfaces/shared.js +112 -0
- package/dist/surfaces/skill.d.ts +7 -0
- package/dist/surfaces/skill.js +118 -0
- package/dist/surfaces/skill.test.d.ts +1 -0
- package/dist/surfaces/skill.test.js +87 -0
- package/dist/surfaces/web.d.ts +97 -0
- package/dist/surfaces/web.js +1285 -0
- package/dist/surfaces/web.test.d.ts +1 -0
- package/dist/surfaces/web.test.js +255 -0
- package/dist/surfaces/workflows.d.ts +2 -0
- package/dist/surfaces/workflows.js +809 -0
- package/dist/surfaces/workflows.test.d.ts +1 -0
- package/dist/surfaces/workflows.test.js +563 -0
- package/dist/toolfactory/cli.d.ts +2 -0
- package/dist/toolfactory/cli.js +65 -0
- package/dist/toolfactory/config.d.ts +3 -0
- package/dist/toolfactory/config.js +27 -0
- package/dist/toolfactory/mcp.d.ts +37 -0
- package/dist/toolfactory/mcp.js +269 -0
- package/dist/toolfactory/types.d.ts +31 -0
- package/dist/toolfactory/types.js +10 -0
- package/dist/toolfactory/web.d.ts +4 -0
- package/dist/toolfactory/web.js +40 -0
- package/dist/validate/agent-plugins.d.ts +5 -0
- package/dist/validate/agent-plugins.js +46 -0
- package/package.json +68 -0
- package/schemas/agent-plugins/mcp.schema.json +120 -0
- package/schemas/agent-plugins/plugin.schema.json +65 -0
- package/src/bindings/index.ts +47 -0
- package/src/bindings/python.test.ts +374 -0
- package/src/bindings/python.ts +862 -0
- package/src/bindings/typescript.test.ts +329 -0
- package/src/bindings/typescript.ts +818 -0
- package/src/commands.test.ts +253 -0
- package/src/commands.ts +886 -0
- package/src/e2e.test.ts +169 -0
- package/src/hosts/browser.ts +106 -0
- package/src/hosts/github.ts +321 -0
- package/src/hosts/openclaw.ts +110 -0
- package/src/hosts/template.ts +149 -0
- package/src/hosts/web.ts +111 -0
- package/src/identity/name.test.ts +43 -0
- package/src/identity/name.ts +39 -0
- package/src/identity/read.test.ts +92 -0
- package/src/identity/read.ts +119 -0
- package/src/index.ts +11 -0
- package/src/introspect/index.ts +72 -0
- package/src/model.ts +386 -0
- package/src/ops.ts +333 -0
- package/src/project/apply.test.ts +348 -0
- package/src/project/apply.ts +417 -0
- package/src/project/gate.ts +717 -0
- package/src/project/history.ts +46 -0
- package/src/project/load.ts +104 -0
- package/src/project/lock.ts +54 -0
- package/src/project/plan.ts +101 -0
- package/src/report/coverage.test.ts +108 -0
- package/src/report/coverage.ts +113 -0
- package/src/surfaces/agent-plugins.ts +47 -0
- package/src/surfaces/agents.template.ts +32 -0
- package/src/surfaces/agents.test.ts +206 -0
- package/src/surfaces/agents.ts +729 -0
- package/src/surfaces/browser-extension.test.ts +175 -0
- package/src/surfaces/browser-extension.ts +1095 -0
- package/src/surfaces/claude.ts +99 -0
- package/src/surfaces/codex.test.ts +71 -0
- package/src/surfaces/codex.ts +105 -0
- package/src/surfaces/cursor.ts +62 -0
- package/src/surfaces/distribution.test.ts +166 -0
- package/src/surfaces/dsh.test.ts +110 -0
- package/src/surfaces/dsh.ts +159 -0
- package/src/surfaces/external.ts +13 -0
- package/src/surfaces/gemini.test.ts +80 -0
- package/src/surfaces/gemini.ts +84 -0
- package/src/surfaces/hermes-native.test.ts +179 -0
- package/src/surfaces/hermes-native.ts +584 -0
- package/src/surfaces/kernel.ts +68 -0
- package/src/surfaces/mcp-registry.test.ts +99 -0
- package/src/surfaces/mcp-registry.ts +190 -0
- package/src/surfaces/mcpb.test.ts +112 -0
- package/src/surfaces/mcpb.ts +130 -0
- package/src/surfaces/npm.ts +78 -0
- package/src/surfaces/openclaw-native.test.ts +283 -0
- package/src/surfaces/openclaw-native.ts +1070 -0
- package/src/surfaces/pypi.ts +84 -0
- package/src/surfaces/readme.ts +218 -0
- package/src/surfaces/registry.ts +79 -0
- package/src/surfaces/shared.ts +140 -0
- package/src/surfaces/skill.test.ts +103 -0
- package/src/surfaces/skill.ts +136 -0
- package/src/surfaces/web.test.ts +303 -0
- package/src/surfaces/web.ts +1310 -0
- package/src/surfaces/workflows.test.ts +677 -0
- package/src/surfaces/workflows.ts +936 -0
- package/src/toolfactory/cli.ts +74 -0
- package/src/toolfactory/config.ts +33 -0
- package/src/toolfactory/mcp.ts +311 -0
- package/src/toolfactory/types.ts +52 -0
- package/src/toolfactory/web.ts +45 -0
- package/src/validate/agent-plugins.ts +53 -0
- package/web/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/web/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/web/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/web/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/web/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/web/dist/assets/index-CCXhQKK3.css +2 -0
- package/web/dist/assets/index-D1PwZ3qS.js +10 -0
- package/web/dist/index.html +14 -0
package/dist/ops.js
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* toolfactory's own operations. toolfactory is a tool built with toolfactory: this file is
|
|
3
|
+
* the author-owned operation module, and `src/toolfactory/{cli,mcp}.ts` are generated from
|
|
4
|
+
* it by `toolfactory build`, exactly as for any other tool.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import * as commands from "./commands.js";
|
|
8
|
+
import { BINDINGS, SURFACE_IDS } from "./model.js";
|
|
9
|
+
import { operation } from "./toolfactory/types.js";
|
|
10
|
+
const root = z
|
|
11
|
+
.string()
|
|
12
|
+
.default(".")
|
|
13
|
+
.describe("Project root (directory containing dev.toolfactory/)");
|
|
14
|
+
const surfaceId = z.enum(SURFACE_IDS);
|
|
15
|
+
export const operations = [
|
|
16
|
+
operation({
|
|
17
|
+
name: "init",
|
|
18
|
+
description: "Create a new tool: dev.toolfactory/tool.json, the authored identity file, the kernel scaffold for the chosen language, and the first build of every selected surface.",
|
|
19
|
+
input: z.object({
|
|
20
|
+
root,
|
|
21
|
+
name: z
|
|
22
|
+
.string()
|
|
23
|
+
.describe("Tool name: lowercase letters, digits, hyphens, dots (Agent Plugins rule)"),
|
|
24
|
+
binding: z.enum(BINDINGS).describe("Language of the core logic: typescript or python"),
|
|
25
|
+
runtime: z
|
|
26
|
+
.enum(["kernel", "none"])
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("`none` creates an instruction-only skill/Codex plugin with no executable payload"),
|
|
29
|
+
surfaces: z
|
|
30
|
+
.array(surfaceId)
|
|
31
|
+
.min(1)
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Surfaces to generate. Default: the skills-first minimum — skill, agent-plugins, mcp, cli and the binding's package registry; every host-specific plugin is opt-in."),
|
|
34
|
+
description: z.string().optional().describe("One-line description"),
|
|
35
|
+
license: z.string().optional().describe("SPDX license identifier"),
|
|
36
|
+
repository: z
|
|
37
|
+
.string()
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("Source repository URL (GitHub URL enables the MCP Registry name)"),
|
|
40
|
+
author: z.string().optional().describe("Author name"),
|
|
41
|
+
keywords: z
|
|
42
|
+
.array(z.string())
|
|
43
|
+
.optional()
|
|
44
|
+
.describe("Activation triggers for hosts that key off them (Kiro Powers, Agent Plugins); defaults to [name]"),
|
|
45
|
+
git: z
|
|
46
|
+
.boolean()
|
|
47
|
+
.default(true)
|
|
48
|
+
.describe("git init when the directory is not a repository yet, and make the first commit"),
|
|
49
|
+
setup: z
|
|
50
|
+
.boolean()
|
|
51
|
+
.default(true)
|
|
52
|
+
.describe("Run .agents/setup: render the harness adapters, install the git hooks, install dependencies"),
|
|
53
|
+
repo: z
|
|
54
|
+
.string()
|
|
55
|
+
.optional()
|
|
56
|
+
.describe("owner/name of a GitHub repository to create with gh and push to"),
|
|
57
|
+
public: z.boolean().default(false).describe("Create that repository public, not private"),
|
|
58
|
+
dryRun: z
|
|
59
|
+
.boolean()
|
|
60
|
+
.default(false)
|
|
61
|
+
.describe("Print the gh invocations instead of running them"),
|
|
62
|
+
reviewers: z
|
|
63
|
+
.array(z.string())
|
|
64
|
+
.default([])
|
|
65
|
+
.describe("GitHub logins that must approve a live run, when the repository gets a live tier"),
|
|
66
|
+
}),
|
|
67
|
+
output: z.object({
|
|
68
|
+
written: z.array(z.string()),
|
|
69
|
+
agentConfig: z.object({ setup: z.boolean(), harnesses: z.array(z.string()) }),
|
|
70
|
+
repository: z
|
|
71
|
+
.object({
|
|
72
|
+
repository: z.string(),
|
|
73
|
+
visibility: z.string(),
|
|
74
|
+
topics: z.array(z.string()),
|
|
75
|
+
secrets: z.array(z.string()),
|
|
76
|
+
commands: z.array(z.string()),
|
|
77
|
+
dryRun: z.boolean(),
|
|
78
|
+
})
|
|
79
|
+
.optional(),
|
|
80
|
+
nextSteps: z.array(z.string()),
|
|
81
|
+
}),
|
|
82
|
+
annotations: { idempotentHint: true },
|
|
83
|
+
requires: ["shell", "net", "fs"],
|
|
84
|
+
handler: async (args) => commands.init(args),
|
|
85
|
+
}),
|
|
86
|
+
operation({
|
|
87
|
+
name: "introspect",
|
|
88
|
+
description: "Spawn the kernel MCP server, list its tools, and snapshot them to dev.toolfactory/ops.json.",
|
|
89
|
+
input: z.object({ root }),
|
|
90
|
+
output: z.object({ path: z.string(), changed: z.boolean(), operations: z.number() }),
|
|
91
|
+
annotations: { idempotentHint: true },
|
|
92
|
+
handler: async ({ root }) => {
|
|
93
|
+
const { path, changed, ops } = await commands.introspect(root);
|
|
94
|
+
return { path, changed, operations: ops.tools.length };
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
operation({
|
|
98
|
+
name: "build",
|
|
99
|
+
description: "Generate every selected surface in-tree from the identity file and the operation snapshot, and refresh the lock.",
|
|
100
|
+
input: z.object({ root }),
|
|
101
|
+
output: z.object({
|
|
102
|
+
written: z.array(z.string()),
|
|
103
|
+
deleted: z.array(z.string()),
|
|
104
|
+
unchanged: z.array(z.string()),
|
|
105
|
+
manual: z.array(z.string()),
|
|
106
|
+
stripped: z
|
|
107
|
+
.array(z.string())
|
|
108
|
+
.describe("Region files whose generated regions were emptied because their surface is no longer selected; the authored remainder stays."),
|
|
109
|
+
nudge: z
|
|
110
|
+
.string()
|
|
111
|
+
.optional()
|
|
112
|
+
.describe("One line when a surface that published somewhere was deselected since the last tag, pointing at `unpublish`."),
|
|
113
|
+
}),
|
|
114
|
+
annotations: { idempotentHint: true },
|
|
115
|
+
handler: async ({ root }) => commands.build(root).result,
|
|
116
|
+
}),
|
|
117
|
+
operation({
|
|
118
|
+
name: "check",
|
|
119
|
+
description: "Fail if the operation snapshot or any generated file drifted from the code (the CI drift gate).",
|
|
120
|
+
input: z.object({ root }),
|
|
121
|
+
output: z.object({ ok: z.literal(true) }),
|
|
122
|
+
annotations: { readOnlyHint: true },
|
|
123
|
+
handler: async ({ root }) => {
|
|
124
|
+
await commands.check(root);
|
|
125
|
+
return { ok: true };
|
|
126
|
+
},
|
|
127
|
+
}),
|
|
128
|
+
operation({
|
|
129
|
+
name: "validate",
|
|
130
|
+
description: "Run each selected surface's own upstream validator (agentskills, claude plugin validate, MCP Inspector, openclaw, hermes, npm pack, uv build).",
|
|
131
|
+
input: z.object({ root, surface: surfaceId.optional().describe("Only this surface") }),
|
|
132
|
+
output: z.object({
|
|
133
|
+
outcomes: z.array(z.object({ label: z.string(), command: z.string(), ok: z.boolean() })),
|
|
134
|
+
}),
|
|
135
|
+
annotations: { readOnlyHint: true },
|
|
136
|
+
handler: async ({ root, surface }) => ({
|
|
137
|
+
outcomes: commands
|
|
138
|
+
.validate(root, surface)
|
|
139
|
+
.map(({ label, command, ok }) => ({ label, command, ok })),
|
|
140
|
+
}),
|
|
141
|
+
}),
|
|
142
|
+
operation({
|
|
143
|
+
name: "coverage",
|
|
144
|
+
description: "The operation × surface verdict matrix: native, bridged, degraded, or excluded, with reasons.",
|
|
145
|
+
input: z.object({ root }),
|
|
146
|
+
output: z.object({
|
|
147
|
+
surfaces: z.array(z.string()),
|
|
148
|
+
rows: z.array(z.object({
|
|
149
|
+
operation: z.string(),
|
|
150
|
+
verdicts: z.record(z.string(), z.object({ kind: z.string(), reason: z.string().optional() })),
|
|
151
|
+
})),
|
|
152
|
+
}),
|
|
153
|
+
annotations: { readOnlyHint: true },
|
|
154
|
+
handler: async ({ root }) => commands.coverage(root),
|
|
155
|
+
}),
|
|
156
|
+
operation({
|
|
157
|
+
name: "adopt",
|
|
158
|
+
description: "Stop regenerating one file; it becomes the author's (recorded as manual in the lock).",
|
|
159
|
+
input: z.object({ root, path: z.string().describe("Repo-relative path of a generated file") }),
|
|
160
|
+
output: z.object({ adopted: z.string() }),
|
|
161
|
+
handler: async ({ root, path }) => {
|
|
162
|
+
commands.adopt(root, path);
|
|
163
|
+
return { adopted: path };
|
|
164
|
+
},
|
|
165
|
+
}),
|
|
166
|
+
operation({
|
|
167
|
+
name: "unadopt",
|
|
168
|
+
description: "Return an adopted file to toolfactory and regenerate it.",
|
|
169
|
+
input: z.object({ root, path: z.string().describe("Repo-relative path of an adopted file") }),
|
|
170
|
+
output: z.object({ regenerated: z.string() }),
|
|
171
|
+
handler: async ({ root, path }) => {
|
|
172
|
+
commands.unadopt(root, path);
|
|
173
|
+
return { regenerated: path };
|
|
174
|
+
},
|
|
175
|
+
}),
|
|
176
|
+
operation({
|
|
177
|
+
name: "eject",
|
|
178
|
+
description: "Adopt every file a surface owns, so the author takes it over entirely.",
|
|
179
|
+
input: z.object({ root, surface: surfaceId }),
|
|
180
|
+
output: z.object({ adopted: z.array(z.string()) }),
|
|
181
|
+
handler: async ({ root, surface }) => ({ adopted: commands.eject(root, surface) }),
|
|
182
|
+
}),
|
|
183
|
+
operation({
|
|
184
|
+
name: "bootstrap-repo",
|
|
185
|
+
description: "Prepare the GitHub repository from the local .env: the `live-tests` environment with its required reviewers and the sensitive config keys inside it, the release registries' tokens at repository scope, GitHub Pages with source = Actions, and npm's trusted publisher. Values go to `gh` on stdin and are never returned.",
|
|
186
|
+
input: z.object({
|
|
187
|
+
root,
|
|
188
|
+
reviewers: z
|
|
189
|
+
.array(z.string())
|
|
190
|
+
.default([])
|
|
191
|
+
.describe("GitHub logins that must approve a live run"),
|
|
192
|
+
dryRun: z
|
|
193
|
+
.boolean()
|
|
194
|
+
.default(false)
|
|
195
|
+
.describe("Print the gh invocations instead of running them"),
|
|
196
|
+
}),
|
|
197
|
+
output: z.object({
|
|
198
|
+
repository: z.string(),
|
|
199
|
+
environment: z.string(),
|
|
200
|
+
reviewers: z.array(z.string()),
|
|
201
|
+
secrets: z.array(z.string()).describe("Names written, never values"),
|
|
202
|
+
missing: z.array(z.string()).describe("Declared names the local .env has no value for"),
|
|
203
|
+
commands: z.array(z.string()),
|
|
204
|
+
manual: z.array(z.string()).describe("The one-time human steps no API can do"),
|
|
205
|
+
dryRun: z.boolean(),
|
|
206
|
+
}),
|
|
207
|
+
requires: ["shell", "net", "secret"],
|
|
208
|
+
handler: async (args) => commands.bootstrapRepo(args),
|
|
209
|
+
}),
|
|
210
|
+
operation({
|
|
211
|
+
name: "secrets",
|
|
212
|
+
description: "Every credential this project's surfaces need — the tool's own sensitive config keys and the release registries' tokens — with where each one is set, whether it is present locally and on GitHub, and (check) whether the registry accepts it. Never a value.",
|
|
213
|
+
input: z.object({
|
|
214
|
+
root,
|
|
215
|
+
action: z
|
|
216
|
+
.enum(["status", "check"])
|
|
217
|
+
.default("status")
|
|
218
|
+
.describe("status: the inventory. check: run each registry's own credential probe."),
|
|
219
|
+
key: z.string().optional().describe("Only this secret"),
|
|
220
|
+
}),
|
|
221
|
+
output: z.object({
|
|
222
|
+
secrets: z.array(z.object({
|
|
223
|
+
name: z.string(),
|
|
224
|
+
kind: z.enum(["config", "release"]),
|
|
225
|
+
required: z.boolean(),
|
|
226
|
+
needs: z.array(z.string()),
|
|
227
|
+
local: z.boolean(),
|
|
228
|
+
github: z.boolean().optional(),
|
|
229
|
+
url: z.string().optional(),
|
|
230
|
+
howTo: z.array(z.string()),
|
|
231
|
+
check: z.object({ ok: z.boolean(), command: z.string() }).optional(),
|
|
232
|
+
})),
|
|
233
|
+
manual: z.array(z.string()),
|
|
234
|
+
}),
|
|
235
|
+
annotations: { readOnlyHint: true },
|
|
236
|
+
requires: ["shell", "net", "secret"],
|
|
237
|
+
handler: async (args) => commands.secrets(args),
|
|
238
|
+
}),
|
|
239
|
+
operation({
|
|
240
|
+
name: "unpublish",
|
|
241
|
+
description: "Retract what a deselected surface used to publish. Git is the ledger: the previous tag's dev.toolfactory/tool.json says what was selected then, and every registry row that lost its surface is checked for the version that tag published and then retracted with the registry's own CLI — or reported with the exact page, where there is no API.",
|
|
242
|
+
input: z.object({
|
|
243
|
+
root,
|
|
244
|
+
ref: z
|
|
245
|
+
.string()
|
|
246
|
+
.default("HEAD")
|
|
247
|
+
.describe("Diff against the tag before this ref (the release passes the tag being cut)"),
|
|
248
|
+
dryRun: z.boolean().default(false).describe("List the retractions instead of running them"),
|
|
249
|
+
hard: z
|
|
250
|
+
.boolean()
|
|
251
|
+
.default(false)
|
|
252
|
+
.describe("Use the destructive retraction where one exists (npm unpublish --force)"),
|
|
253
|
+
}),
|
|
254
|
+
output: z.object({
|
|
255
|
+
from: z.string().optional(),
|
|
256
|
+
dropped: z.array(surfaceId),
|
|
257
|
+
steps: z.array(z.object({ name: z.string(), run: z.string() })),
|
|
258
|
+
ran: z
|
|
259
|
+
.array(z.object({ name: z.string(), ok: z.boolean(), durationMs: z.number() }))
|
|
260
|
+
.optional(),
|
|
261
|
+
}),
|
|
262
|
+
requires: ["shell", "net", "secret"],
|
|
263
|
+
handler: async ({ root, ref, dryRun, hard }) => commands.unpublish(root, { ref, dryRun, hard }),
|
|
264
|
+
}),
|
|
265
|
+
operation({
|
|
266
|
+
name: "gate",
|
|
267
|
+
description: "Run the gate here, in order: build, the drift check, every selected surface's upstream validator, the author's checks and tests, and the credential-free host end-to-end. The same step list the generated ci.yml renders, so a project with no CI has the identical gate.",
|
|
268
|
+
input: z.object({ root }),
|
|
269
|
+
output: z.object({
|
|
270
|
+
steps: z.array(z.object({ name: z.string(), ok: z.boolean(), durationMs: z.number() })),
|
|
271
|
+
}),
|
|
272
|
+
requires: ["shell", "net", "fs"],
|
|
273
|
+
handler: async ({ root }) => commands.gate(root),
|
|
274
|
+
}),
|
|
275
|
+
operation({
|
|
276
|
+
name: "package",
|
|
277
|
+
description: "Build every release asset into dist/release/ — npm tarball, Python distributions, OpenClaw plugin tarball, plugin bundle zip, web build, coverage — by the same steps the release workflow's package job runs. Publishing stays a CI concern.",
|
|
278
|
+
input: z.object({ root }),
|
|
279
|
+
output: z.object({
|
|
280
|
+
steps: z.array(z.object({ name: z.string(), ok: z.boolean(), durationMs: z.number() })),
|
|
281
|
+
}),
|
|
282
|
+
requires: ["shell", "net", "fs"],
|
|
283
|
+
handler: async ({ root }) => commands.packageRelease(root),
|
|
284
|
+
}),
|
|
285
|
+
operation({
|
|
286
|
+
name: "doctor",
|
|
287
|
+
description: "Report which upstream CLIs this machine can delegate to (git, gh, npm, uv, claude, openclaw, clawhub, hermes, uvx, agentskills, MCP Inspector, docker).",
|
|
288
|
+
input: z.object({}),
|
|
289
|
+
output: z.object({
|
|
290
|
+
toolfactory: z.string(),
|
|
291
|
+
node: z.string(),
|
|
292
|
+
tools: z.record(z.string(), z.string()),
|
|
293
|
+
}),
|
|
294
|
+
annotations: { readOnlyHint: true },
|
|
295
|
+
handler: async () => commands.doctor(),
|
|
296
|
+
}),
|
|
297
|
+
];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PlannedFile, Region } from "../model.js";
|
|
2
|
+
import { type Markers } from "./lock.js";
|
|
3
|
+
export interface Drift {
|
|
4
|
+
path: string;
|
|
5
|
+
kind: "missing" | "changed" | "orphan" | "unmarked";
|
|
6
|
+
}
|
|
7
|
+
export interface ApplyResult {
|
|
8
|
+
written: string[];
|
|
9
|
+
deleted: string[];
|
|
10
|
+
unchanged: string[];
|
|
11
|
+
manual: string[];
|
|
12
|
+
/** Region files a deselected surface stopped writing: emptied of their regions and kept, because everything outside the markers is the author's. */
|
|
13
|
+
stripped: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function extractRegions(text: string, file: {
|
|
16
|
+
regions: readonly Markers[];
|
|
17
|
+
}): string[] | undefined;
|
|
18
|
+
export declare function replaceRegions(text: string, file: {
|
|
19
|
+
regions: readonly Region[];
|
|
20
|
+
}): string | undefined;
|
|
21
|
+
/** Objects merge key by key, except the paths a merge file owns whole, which are replaced. */
|
|
22
|
+
export declare function deepMerge(base: Record<string, unknown>, patch: Record<string, unknown>, owned?: string[], prefix?: string): Record<string, unknown>;
|
|
23
|
+
/** The values a merge file owns, read back out of a document; an owned object comes back whole. */
|
|
24
|
+
export declare function pickPatch(document: Record<string, unknown>, patch: Record<string, unknown>, owned?: string[], prefix?: string): Record<string, unknown>;
|
|
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[];
|
|
27
|
+
/** Uninstall dotted paths from a document, pruning the objects the removal empties. */
|
|
28
|
+
export declare function removeKeys(document: Record<string, unknown>, keys: readonly string[]): boolean;
|
|
29
|
+
/** The content toolfactory manages, as one string for hashing and comparison. */
|
|
30
|
+
export declare function managedContent(file: PlannedFile): string;
|
|
31
|
+
/** Compare a plan to the tree without writing. */
|
|
32
|
+
export declare function check(root: string, plan: PlannedFile[], toolfactoryVersion: string): Drift[];
|
|
33
|
+
/** Write a plan to the tree and refresh the lock. */
|
|
34
|
+
export declare function apply(root: string, plan: PlannedFile[], toolfactoryVersion: string): ApplyResult;
|
|
35
|
+
export declare function setState(root: string, path: string, state: "generated" | "manual", toolfactoryVersion: string): void;
|