madeby 0.3.4 → 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.
Files changed (2) hide show
  1. package/dist/madeby.mjs +93 -63
  2. package/package.json +1 -1
package/dist/madeby.mjs CHANGED
@@ -1882,58 +1882,55 @@ function whoCommand(args) {
1882
1882
  // src/init-repo.ts
1883
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 ACO_SENTINEL = "<!-- madeby:aco -->";
1886
- var GH_WORKFLOW = `name: Disclosure
1887
- on: pull_request
1888
- jobs:
1889
- madeby:
1890
- runs-on: ubuntu-latest
1891
- steps:
1892
- - uses: actions/checkout@v4
1893
- with:
1894
- fetch-depth: 0
1895
- - uses: MadeByFYI/MadeBy/packages/action@v0.2.0
1896
- `;
1897
- var AGENTS_CONVENTION = `# AGENTS.md \u2014 Authorship disclosure convention (ACO)
1898
- ${ACO_SENTINEL}
1899
-
1900
- This repository asks any AI agent \u2014 or a human working with one \u2014 to **disclose who authored the
1901
- changes they make**, per **ACO, the Authorship Certificate of Origin**
1902
- (https://github.com/MadeByFYI/MadeBy/blob/main/ACO.md).
1903
-
1904
- ## The rule
1905
-
1906
- When you author or modify content here, disclose the authorship **category** on your commit \u2014 one of:
1907
-
1908
- - \`human\` \u2014 a human authored it, no AI involvement.
1909
- - \`with_ai\` \u2014 a human authored it with disclosed AI assistance.
1910
- - \`ai\` \u2014 an AI agent authored it (a human remains accountable).
1911
-
1912
- Disclose **per commit, honestly** \u2014 the category describes what actually happened for that change.
1913
-
1914
- ## The one-line way (asserted tier \u2014 no keys, no setup)
1915
-
1916
- After you commit, run the matching command (works with no install via \`npx\`):
1917
-
1918
- | Category | Command |
1919
- |-----------|----------------------------------|
1920
- | \`human\` | \`npx madeby@latest me\` |
1921
- | \`with_ai\` | \`npx madeby@latest me --with-ai <tool>\` |
1922
- | \`ai\` | \`npx madeby@latest ai [tool]\` |
1923
-
1924
- Undisclosed content stays *unknown*, never guessed. See ACO for the standard.
1925
- `;
1926
- var ACO_SECTION = `
1927
- ${ACO_SENTINEL}
1928
- ## Authorship disclosure (ACO)
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)
1929
1890
 
1930
- Disclose who authored your changes, per [ACO](https://github.com/MadeByFYI/MadeBy/blob/main/ACO.md).
1931
- After committing, run the command for the honest category (no install needed):
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):
1932
1894
 
1933
1895
  - **ai** \u2014 an AI authored it (the committer stays accountable): \`npx madeby@latest ai [tool]\`
1934
1896
  - **with_ai** \u2014 a human authored it with AI assistance: \`npx madeby@latest me --with-ai [tool]\`
1935
1897
  - **human** \u2014 a human authored it: \`npx madeby@latest me\`
1898
+
1899
+ Disclose per commit, honestly. Undisclosed content stays *unknown*, never guessed.
1900
+ `;
1901
+ var ACO_BLOCK = `${ACO_OPEN}
1902
+ ${ACO_BODY}${ACO_CLOSE}
1936
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
+ }
1937
1934
  function writeIfAbsent(abs, rel, content, created, skipped) {
1938
1935
  if (existsSync4(abs)) {
1939
1936
  skipped.push(rel);
@@ -1951,25 +1948,36 @@ function ensureAco(abs, rel, res, opts) {
1951
1948
  res.created.push(rel);
1952
1949
  return;
1953
1950
  }
1954
- const current = readFileSync6(abs, "utf8");
1955
- if (current.includes(ACO_SENTINEL)) {
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 {
1956
1965
  res.skipped.push(rel);
1957
- return;
1958
1966
  }
1959
- const sep = current.endsWith("\n") ? "\n" : "\n\n";
1960
- writeFileSync2(abs, current + sep + ACO_SECTION);
1961
- res.merged.push(rel);
1962
1967
  }
1963
1968
  function initRepo(root, opts = {}) {
1964
1969
  const mode = opts.mode ?? "advisory";
1965
1970
  const host = opts.host ?? "github";
1971
+ const update = opts.update ?? false;
1966
1972
  const created = [];
1967
1973
  const skipped = [];
1968
1974
  const merged = [];
1969
- const res = { created, skipped, merged };
1975
+ const updated = [];
1976
+ const outdated = [];
1977
+ const res = { created, skipped, merged, updated, outdated };
1970
1978
  writeIfAbsent(join5(root, ".madeby", "policy.json"), ".madeby/policy.json", JSON.stringify({ version: 0, mode }, null, 2) + "\n", created, skipped);
1971
- ensureAco(join5(root, "AGENTS.md"), "AGENTS.md", res, { createIfAbsent: true });
1972
- ensureAco(join5(root, "CLAUDE.md"), "CLAUDE.md", res, { createIfAbsent: false });
1979
+ ensureAco(join5(root, "AGENTS.md"), "AGENTS.md", res, { createIfAbsent: true, update });
1980
+ ensureAco(join5(root, "CLAUDE.md"), "CLAUDE.md", res, { createIfAbsent: false, update });
1973
1981
  if (host === "github") {
1974
1982
  writeIfAbsent(join5(root, ".github", "workflows", "disclosure.yml"), ".github/workflows/disclosure.yml", GH_WORKFLOW, created, skipped);
1975
1983
  }
@@ -1980,6 +1988,12 @@ function initRepo(root, opts = {}) {
1980
1988
  if (merged.length > 0) {
1981
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.`);
1982
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).`);
1996
+ }
1983
1997
  if (host === "azure-devops") {
1984
1998
  nextSteps.push("Add the Azure Pipelines template (packages/action/azure-pipelines-disclosure.yml) and wire it as a PR build-validation branch policy.");
1985
1999
  } else if (host !== "github") {
@@ -1990,8 +2004,19 @@ function initRepo(root, opts = {}) {
1990
2004
  }
1991
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.");
1992
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.");
1993
- return { created, skipped, merged, policyMode: mode, host, nextSteps };
2007
+ return { created, skipped, merged, updated, outdated, policyMode: mode, host, nextSteps };
1994
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
+ `;
1995
2020
 
1996
2021
  // src/commands/init.ts
1997
2022
  function initCommand(args) {
@@ -2002,11 +2027,14 @@ function initCommand(args) {
2002
2027
  return;
2003
2028
  }
2004
2029
  const mode = args.includes("--required") ? "required" : "advisory";
2030
+ const update = args.includes("--update");
2005
2031
  const hostIdx = args.indexOf("--host");
2006
2032
  const host = hostIdx >= 0 ? args[hostIdx + 1] : void 0;
2007
- const r = initRepo(root, { mode, host });
2033
+ const r = initRepo(root, { mode, host, update });
2008
2034
  for (const f of r.created) console.log(` + ${f}`);
2009
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')`);
2010
2038
  for (const f of r.skipped) console.log(` \xB7 ${f} (exists \u2014 left as-is)`);
2011
2039
  console.log(`
2012
2040
  madeby init \u2014 policy: ${r.policyMode}, host: ${r.host}`);
@@ -2018,7 +2046,7 @@ madeby init \u2014 policy: ${r.policyMode}, host: ${r.host}`);
2018
2046
  import { execFileSync as execFileSync6 } from "node:child_process";
2019
2047
  import { createInterface } from "node:readline";
2020
2048
  var DEFAULT_PROTOCOL = "2024-11-05";
2021
- var SERVER_INFO = { name: "madeby", version: "0.3.4" };
2049
+ var SERVER_INFO = { name: "madeby", version: "0.3.5" };
2022
2050
  function rootFor(path) {
2023
2051
  const cwd = path && path.length ? path : process.cwd();
2024
2052
  return execFileSync6("git", ["-C", cwd, "-c", "core.quotePath=false", "rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
@@ -2033,16 +2061,17 @@ var repoInput = {
2033
2061
  var TOOLS = [
2034
2062
  {
2035
2063
  name: "init",
2036
- 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.",
2037
2065
  inputSchema: {
2038
2066
  type: "object",
2039
2067
  properties: {
2040
2068
  path: { type: "string", description: "path to the repo (default: the server's working directory)" },
2041
2069
  mode: { enum: ["advisory", "required"], description: "policy mode to seed (default: advisory)" },
2042
- 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)" }
2043
2072
  }
2044
2073
  },
2045
- 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 })
2046
2075
  },
2047
2076
  {
2048
2077
  name: "check",
@@ -2305,8 +2334,9 @@ function help() {
2305
2334
  console.log(`madeby \u2014 verifiable content provenance ("made by whom?")
2306
2335
 
2307
2336
  Usage:
2308
- madeby init Set MadeBy up: write .madeby/policy.json + the CI disclosure check.
2309
- --required to enforce now; --host azure-devops for Azure Pipelines.
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.
2310
2340
  madeby check [<range>] The gate: do commits meet .madeby/policy.json? (a verdict \u2014 exit
2311
2341
  code gates). <range> e.g. origin/main..HEAD; in CI it's auto-detected.
2312
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.4",
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",