madeby 0.3.3 → 0.3.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/dist/madeby.mjs +113 -48
- package/package.json +1 -1
package/dist/madeby.mjs
CHANGED
|
@@ -1880,47 +1880,57 @@ function whoCommand(args) {
|
|
|
1880
1880
|
}
|
|
1881
1881
|
|
|
1882
1882
|
// src/init-repo.ts
|
|
1883
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
1883
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as writeFileSync2 } from "node:fs";
|
|
1884
1884
|
import { dirname as dirname2, join as join5 } from "node:path";
|
|
1885
|
-
var
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
steps:
|
|
1891
|
-
- uses: actions/checkout@v4
|
|
1892
|
-
with:
|
|
1893
|
-
fetch-depth: 0
|
|
1894
|
-
- uses: MadeByFYI/MadeBy/packages/action@v0.2.0
|
|
1895
|
-
`;
|
|
1896
|
-
var AGENTS_CONVENTION = `# AGENTS.md \u2014 Authorship disclosure convention (ACO)
|
|
1897
|
-
|
|
1898
|
-
This repository asks any AI agent \u2014 or a human working with one \u2014 to **disclose who authored the
|
|
1899
|
-
changes they make**, per **ACO, the Authorship Certificate of Origin**
|
|
1900
|
-
(https://github.com/MadeByFYI/MadeBy/blob/main/ACO.md).
|
|
1901
|
-
|
|
1902
|
-
## The rule
|
|
1903
|
-
|
|
1904
|
-
When you author or modify content here, disclose the authorship **category** on your commit \u2014 one of:
|
|
1905
|
-
|
|
1906
|
-
- \`human\` \u2014 a human authored it, no AI involvement.
|
|
1907
|
-
- \`with_ai\` \u2014 a human authored it with disclosed AI assistance.
|
|
1908
|
-
- \`ai\` \u2014 an AI agent authored it (a human remains accountable).
|
|
1885
|
+
var ACO_VERSION = 1;
|
|
1886
|
+
var ACO_OPEN = `<!-- madeby:aco v${ACO_VERSION} -->`;
|
|
1887
|
+
var ACO_CLOSE = `<!-- /madeby:aco -->`;
|
|
1888
|
+
var ACO_OPEN_RE = /<!-- madeby:aco(?: v(\d+))? -->/;
|
|
1889
|
+
var ACO_BODY = `## Authorship disclosure (ACO)
|
|
1909
1890
|
|
|
1910
|
-
|
|
1891
|
+
When you author or modify content here, **disclose who authored it** \u2014 per
|
|
1892
|
+
[ACO, the Authorship Certificate of Origin](https://github.com/MadeByFYI/MadeBy/blob/main/ACO.md).
|
|
1893
|
+
After you commit, run the command for the honest category (no install, no setup):
|
|
1911
1894
|
|
|
1912
|
-
|
|
1895
|
+
- **ai** \u2014 an AI authored it (the committer stays accountable): \`npx madeby@latest ai [tool]\`
|
|
1896
|
+
- **with_ai** \u2014 a human authored it with AI assistance: \`npx madeby@latest me --with-ai [tool]\`
|
|
1897
|
+
- **human** \u2014 a human authored it: \`npx madeby@latest me\`
|
|
1913
1898
|
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
| Category | Command |
|
|
1917
|
-
|-----------|----------------------------------|
|
|
1918
|
-
| \`human\` | \`npx madeby@latest me\` |
|
|
1919
|
-
| \`with_ai\` | \`npx madeby@latest me --with-ai <tool>\` |
|
|
1920
|
-
| \`ai\` | \`npx madeby@latest ai [tool]\` |
|
|
1921
|
-
|
|
1922
|
-
Undisclosed content stays *unknown*, never guessed. See ACO for the standard.
|
|
1899
|
+
Disclose per commit, honestly. Undisclosed content stays *unknown*, never guessed.
|
|
1923
1900
|
`;
|
|
1901
|
+
var ACO_BLOCK = `${ACO_OPEN}
|
|
1902
|
+
${ACO_BODY}${ACO_CLOSE}
|
|
1903
|
+
`;
|
|
1904
|
+
var AGENTS_CONVENTION = `# AGENTS.md
|
|
1905
|
+
|
|
1906
|
+
${ACO_BLOCK}`;
|
|
1907
|
+
var ACO_SECTION = `
|
|
1908
|
+
${ACO_BLOCK}`;
|
|
1909
|
+
function findAcoBlock(content) {
|
|
1910
|
+
const m = ACO_OPEN_RE.exec(content);
|
|
1911
|
+
if (!m) return null;
|
|
1912
|
+
const start = m.index;
|
|
1913
|
+
const version = m[1] !== void 0 ? Number(m[1]) : null;
|
|
1914
|
+
const closeIdx = content.indexOf(ACO_CLOSE, start);
|
|
1915
|
+
let end;
|
|
1916
|
+
if (closeIdx !== -1) {
|
|
1917
|
+
end = closeIdx + ACO_CLOSE.length;
|
|
1918
|
+
if (content[end] === "\n") end += 1;
|
|
1919
|
+
} else {
|
|
1920
|
+
end = content.length;
|
|
1921
|
+
}
|
|
1922
|
+
return { version, start, end };
|
|
1923
|
+
}
|
|
1924
|
+
function acoStatus(content) {
|
|
1925
|
+
const loc = findAcoBlock(content);
|
|
1926
|
+
if (!loc) return "absent";
|
|
1927
|
+
if (loc.version === null || loc.version < ACO_VERSION) return "outdated";
|
|
1928
|
+
if (loc.version > ACO_VERSION) return "newer";
|
|
1929
|
+
return "current";
|
|
1930
|
+
}
|
|
1931
|
+
function replaceAcoBlock(content, loc) {
|
|
1932
|
+
return content.slice(0, loc.start) + ACO_BLOCK + content.slice(loc.end);
|
|
1933
|
+
}
|
|
1924
1934
|
function writeIfAbsent(abs, rel, content, created, skipped) {
|
|
1925
1935
|
if (existsSync4(abs)) {
|
|
1926
1936
|
skipped.push(rel);
|
|
@@ -1930,21 +1940,59 @@ function writeIfAbsent(abs, rel, content, created, skipped) {
|
|
|
1930
1940
|
writeFileSync2(abs, content);
|
|
1931
1941
|
created.push(rel);
|
|
1932
1942
|
}
|
|
1943
|
+
function ensureAco(abs, rel, res, opts) {
|
|
1944
|
+
if (!existsSync4(abs)) {
|
|
1945
|
+
if (!opts.createIfAbsent) return;
|
|
1946
|
+
mkdirSync2(dirname2(abs), { recursive: true });
|
|
1947
|
+
writeFileSync2(abs, AGENTS_CONVENTION);
|
|
1948
|
+
res.created.push(rel);
|
|
1949
|
+
return;
|
|
1950
|
+
}
|
|
1951
|
+
const content = readFileSync6(abs, "utf8");
|
|
1952
|
+
const status = acoStatus(content);
|
|
1953
|
+
if (status === "absent") {
|
|
1954
|
+
const sep = content.endsWith("\n") ? "" : "\n";
|
|
1955
|
+
writeFileSync2(abs, content + sep + ACO_SECTION);
|
|
1956
|
+
res.merged.push(rel);
|
|
1957
|
+
} else if (status === "outdated") {
|
|
1958
|
+
if (opts.update) {
|
|
1959
|
+
writeFileSync2(abs, replaceAcoBlock(content, findAcoBlock(content)));
|
|
1960
|
+
res.updated.push(rel);
|
|
1961
|
+
} else {
|
|
1962
|
+
res.outdated.push(rel);
|
|
1963
|
+
}
|
|
1964
|
+
} else {
|
|
1965
|
+
res.skipped.push(rel);
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1933
1968
|
function initRepo(root, opts = {}) {
|
|
1934
1969
|
const mode = opts.mode ?? "advisory";
|
|
1935
1970
|
const host = opts.host ?? "github";
|
|
1971
|
+
const update = opts.update ?? false;
|
|
1936
1972
|
const created = [];
|
|
1937
1973
|
const skipped = [];
|
|
1974
|
+
const merged = [];
|
|
1975
|
+
const updated = [];
|
|
1976
|
+
const outdated = [];
|
|
1977
|
+
const res = { created, skipped, merged, updated, outdated };
|
|
1938
1978
|
writeIfAbsent(join5(root, ".madeby", "policy.json"), ".madeby/policy.json", JSON.stringify({ version: 0, mode }, null, 2) + "\n", created, skipped);
|
|
1939
|
-
|
|
1979
|
+
ensureAco(join5(root, "AGENTS.md"), "AGENTS.md", res, { createIfAbsent: true, update });
|
|
1980
|
+
ensureAco(join5(root, "CLAUDE.md"), "CLAUDE.md", res, { createIfAbsent: false, update });
|
|
1940
1981
|
if (host === "github") {
|
|
1941
1982
|
writeIfAbsent(join5(root, ".github", "workflows", "disclosure.yml"), ".github/workflows/disclosure.yml", GH_WORKFLOW, created, skipped);
|
|
1942
1983
|
}
|
|
1943
1984
|
const nextSteps = ["Commit the created files."];
|
|
1944
1985
|
if (created.includes("AGENTS.md")) {
|
|
1945
|
-
nextSteps.push("An AGENTS.md ACO convention was added \u2014 agents that read it disclose authorship (e.g. 'npx madeby@latest
|
|
1946
|
-
}
|
|
1947
|
-
|
|
1986
|
+
nextSteps.push("An AGENTS.md ACO convention was added \u2014 agents that read it disclose authorship (e.g. 'npx madeby@latest ai [tool]'). Tune it to your repo's tools.");
|
|
1987
|
+
}
|
|
1988
|
+
if (merged.length > 0) {
|
|
1989
|
+
nextSteps.push(`Merged the ACO disclosure rule into your existing ${merged.join(" + ")} \u2014 review the appended "Authorship disclosure (ACO)" section and tune it to your repo.`);
|
|
1990
|
+
}
|
|
1991
|
+
if (updated.length > 0) {
|
|
1992
|
+
nextSteps.push(`Refreshed an outdated ACO convention in ${updated.join(" + ")} to the current version \u2014 review the change before committing.`);
|
|
1993
|
+
}
|
|
1994
|
+
if (outdated.length > 0) {
|
|
1995
|
+
nextSteps.push(`${outdated.join(" + ")} carries an OUTDATED ACO convention \u2014 run 'madeby init --update' to refresh it in place (only the ACO block changes).`);
|
|
1948
1996
|
}
|
|
1949
1997
|
if (host === "azure-devops") {
|
|
1950
1998
|
nextSteps.push("Add the Azure Pipelines template (packages/action/azure-pipelines-disclosure.yml) and wire it as a PR build-validation branch policy.");
|
|
@@ -1956,8 +2004,19 @@ function initRepo(root, opts = {}) {
|
|
|
1956
2004
|
}
|
|
1957
2005
|
nextSteps.push("Contributors disclose origin with a Co-Authored-By / Generated-by trailer (AI), an Authored-by-human trailer ('madeby me'), an Authored-by-ai trailer ('madeby ai' \u2014 AI authored, committer accountable), a DCO Signed-off-by, or a signed commit. Evidence upgrade: 'madeby ai --witness' records your own AI session's witnessed spans.");
|
|
1958
2006
|
nextSteps.push("Existing history is accounted for honestly, not fabricated: run 'madeby check' over full history to recognize what's already disclosed; pre-adoption commits stay unknown. See madeby://guide/backfill.");
|
|
1959
|
-
return { created, skipped, policyMode: mode, host, nextSteps };
|
|
2007
|
+
return { created, skipped, merged, updated, outdated, policyMode: mode, host, nextSteps };
|
|
1960
2008
|
}
|
|
2009
|
+
var GH_WORKFLOW = `name: Disclosure
|
|
2010
|
+
on: pull_request
|
|
2011
|
+
jobs:
|
|
2012
|
+
madeby:
|
|
2013
|
+
runs-on: ubuntu-latest
|
|
2014
|
+
steps:
|
|
2015
|
+
- uses: actions/checkout@v4
|
|
2016
|
+
with:
|
|
2017
|
+
fetch-depth: 0
|
|
2018
|
+
- uses: MadeByFYI/MadeBy/packages/action@v0.2.0
|
|
2019
|
+
`;
|
|
1961
2020
|
|
|
1962
2021
|
// src/commands/init.ts
|
|
1963
2022
|
function initCommand(args) {
|
|
@@ -1968,10 +2027,14 @@ function initCommand(args) {
|
|
|
1968
2027
|
return;
|
|
1969
2028
|
}
|
|
1970
2029
|
const mode = args.includes("--required") ? "required" : "advisory";
|
|
2030
|
+
const update = args.includes("--update");
|
|
1971
2031
|
const hostIdx = args.indexOf("--host");
|
|
1972
2032
|
const host = hostIdx >= 0 ? args[hostIdx + 1] : void 0;
|
|
1973
|
-
const r = initRepo(root, { mode, host });
|
|
2033
|
+
const r = initRepo(root, { mode, host, update });
|
|
1974
2034
|
for (const f of r.created) console.log(` + ${f}`);
|
|
2035
|
+
for (const f of r.merged) console.log(` ~ ${f} (merged in the ACO rule)`);
|
|
2036
|
+
for (const f of r.updated) console.log(` \u2191 ${f} (ACO convention refreshed to the current version)`);
|
|
2037
|
+
for (const f of r.outdated) console.log(` ! ${f} (ACO convention OUTDATED \u2014 run 'madeby init --update')`);
|
|
1975
2038
|
for (const f of r.skipped) console.log(` \xB7 ${f} (exists \u2014 left as-is)`);
|
|
1976
2039
|
console.log(`
|
|
1977
2040
|
madeby init \u2014 policy: ${r.policyMode}, host: ${r.host}`);
|
|
@@ -1983,7 +2046,7 @@ madeby init \u2014 policy: ${r.policyMode}, host: ${r.host}`);
|
|
|
1983
2046
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
1984
2047
|
import { createInterface } from "node:readline";
|
|
1985
2048
|
var DEFAULT_PROTOCOL = "2024-11-05";
|
|
1986
|
-
var SERVER_INFO = { name: "madeby", version: "0.3.
|
|
2049
|
+
var SERVER_INFO = { name: "madeby", version: "0.3.5" };
|
|
1987
2050
|
function rootFor(path) {
|
|
1988
2051
|
const cwd = path && path.length ? path : process.cwd();
|
|
1989
2052
|
return execFileSync6("git", ["-C", cwd, "-c", "core.quotePath=false", "rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
|
|
@@ -1998,16 +2061,17 @@ var repoInput = {
|
|
|
1998
2061
|
var TOOLS = [
|
|
1999
2062
|
{
|
|
2000
2063
|
name: "init",
|
|
2001
|
-
description: "Align a repository with MadeBy in one call: create .madeby/policy.json (advisory by default \u2014 reports, never fails) and the CI disclosure check for the host (github default; azure-devops guided). Idempotent \u2014 never clobbers an existing policy or workflow. Returns the files created/skipped and the recommended next steps. Read the resources: madeby://guide/align (full workflow), madeby://guide/enforce (make the check required \u2014 the host's control plane, exact commands), madeby://guide/backfill (account for existing history honestly \u2014 never fabricate).",
|
|
2064
|
+
description: "Align a repository with MadeBy in one call: create .madeby/policy.json (advisory by default \u2014 reports, never fails) and the CI disclosure check for the host (github default; azure-devops guided). Idempotent \u2014 never clobbers an existing policy or workflow. Returns the files created/skipped and the recommended next steps. Read the resources: madeby://guide/align (full workflow), madeby://guide/enforce (make the check required \u2014 the host's control plane, exact commands), madeby://guide/backfill (account for existing history honestly \u2014 never fabricate). The ACO convention block is versioned: the result flags an `outdated` AGENTS.md/CLAUDE.md (drift); call again with update:true to refresh just that block in place \u2014 how an agent keeps the convention current.",
|
|
2002
2065
|
inputSchema: {
|
|
2003
2066
|
type: "object",
|
|
2004
2067
|
properties: {
|
|
2005
2068
|
path: { type: "string", description: "path to the repo (default: the server's working directory)" },
|
|
2006
2069
|
mode: { enum: ["advisory", "required"], description: "policy mode to seed (default: advisory)" },
|
|
2007
|
-
host: { type: "string", description: "CI host to wire: github (default) or azure-devops" }
|
|
2070
|
+
host: { type: "string", description: "CI host to wire: github (default) or azure-devops" },
|
|
2071
|
+
update: { type: "boolean", description: "refresh an outdated ACO convention block in place (drift update); default false (report only)" }
|
|
2008
2072
|
}
|
|
2009
2073
|
},
|
|
2010
|
-
handler: (args) => initRepo(rootFor(args.path), { mode: args.mode, host: args.host })
|
|
2074
|
+
handler: (args) => initRepo(rootFor(args.path), { mode: args.mode, host: args.host, update: args.update })
|
|
2011
2075
|
},
|
|
2012
2076
|
{
|
|
2013
2077
|
name: "check",
|
|
@@ -2270,8 +2334,9 @@ function help() {
|
|
|
2270
2334
|
console.log(`madeby \u2014 verifiable content provenance ("made by whom?")
|
|
2271
2335
|
|
|
2272
2336
|
Usage:
|
|
2273
|
-
madeby init Set MadeBy up: write .madeby/policy.json + the
|
|
2274
|
-
|
|
2337
|
+
madeby init Set MadeBy up: write .madeby/policy.json + the ACO AGENTS.md convention
|
|
2338
|
+
+ the CI disclosure check. --update refreshes an outdated ACO block in
|
|
2339
|
+
place; --required to enforce now; --host azure-devops for Azure Pipelines.
|
|
2275
2340
|
madeby check [<range>] The gate: do commits meet .madeby/policy.json? (a verdict \u2014 exit
|
|
2276
2341
|
code gates). <range> e.g. origin/main..HEAD; in CI it's auto-detected.
|
|
2277
2342
|
--json for a machine-readable result.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "madeby",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"mcpName": "io.github.MadeByFYI/madeby",
|
|
5
5
|
"description": "Disclose AI authorship of code. `npx madeby ai` adds an Authored-by-ai git trailer; AI coding agents disclose per the ACO standard (human/with_ai/ai) from an AGENTS.md convention. Disclosure, not detection. Gate PRs with `madeby check`.",
|
|
6
6
|
"license": "MIT",
|