@serviceme/devtools-core 2.0.2 → 2.0.4

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 (56) hide show
  1. package/dist/{device-CDDcwDY6.mjs → device-BVcUUQ9t.mjs} +54 -19
  2. package/dist/device-BVcUUQ9t.mjs.map +1 -0
  3. package/dist/device-DCo0rgUt.mjs +793 -0
  4. package/dist/device-DCo0rgUt.mjs.map +1 -0
  5. package/dist/{device-DuAYH8bk.js → device-ihxrFR-w.js} +52 -17
  6. package/dist/device-ihxrFR-w.js.map +1 -0
  7. package/dist/device-uFAQxlNt.js +874 -0
  8. package/dist/device-uFAQxlNt.js.map +1 -0
  9. package/dist/device-yWpY_Zds.js +874 -0
  10. package/dist/device-yWpY_Zds.js.map +1 -0
  11. package/dist/device.d.mts +1 -1
  12. package/dist/device.d.ts +1 -1
  13. package/dist/device.js +1 -1
  14. package/dist/device.mjs +1 -1
  15. package/dist/{index-BI11AfMH.d.ts → index-DGXYp8J5.d.mts} +30 -15
  16. package/dist/{index-BI11AfMH.d.mts → index-DGXYp8J5.d.ts} +30 -15
  17. package/dist/index.d.mts +13 -82
  18. package/dist/index.d.ts +13 -82
  19. package/dist/index.js +72 -138
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +74 -135
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/skill-linker.js +1 -1
  24. package/dist/skill-linker.mjs +1 -1
  25. package/dist/{submit-Cg7wSa3x.mjs → submit-6zQPPrOJ.mjs} +2 -2
  26. package/dist/{submit-Cg7wSa3x.mjs.map → submit-6zQPPrOJ.mjs.map} +1 -1
  27. package/dist/submit-BTdbGEAd.mjs +84 -0
  28. package/dist/submit-BTdbGEAd.mjs.map +1 -0
  29. package/dist/submit-CW9schoc.js +98 -0
  30. package/dist/submit-CW9schoc.js.map +1 -0
  31. package/dist/submit-Dy0KTHzm.js +98 -0
  32. package/dist/submit-Dy0KTHzm.js.map +1 -0
  33. package/dist/submit.js +1 -1
  34. package/dist/submit.mjs +1 -1
  35. package/dist/toolbox-BV7vLGXZ.js +614 -0
  36. package/dist/toolbox-BV7vLGXZ.js.map +1 -0
  37. package/dist/{toolbox-CbfxpNg-.mjs → toolbox-BxgnUyDU.mjs} +2 -2
  38. package/dist/{toolbox-CbfxpNg-.mjs.map → toolbox-BxgnUyDU.mjs.map} +1 -1
  39. package/dist/toolbox-GSWMRdts.js +614 -0
  40. package/dist/toolbox-GSWMRdts.js.map +1 -0
  41. package/dist/toolbox-UG4dA2TI.mjs +540 -0
  42. package/dist/toolbox-UG4dA2TI.mjs.map +1 -0
  43. package/dist/toolbox.js +1 -1
  44. package/dist/toolbox.mjs +1 -1
  45. package/dist/userHome-B97jBm5O.mjs +196 -0
  46. package/dist/userHome-B97jBm5O.mjs.map +1 -0
  47. package/dist/userHome-Baz205B7.js +498 -0
  48. package/dist/userHome-Baz205B7.js.map +1 -0
  49. package/dist/userHome-CLlsXCvW.js +518 -0
  50. package/dist/userHome-CLlsXCvW.js.map +1 -0
  51. package/dist/{userHome-CcnAQPG1.mjs → userHome-DOMLiHy7.mjs} +2 -4
  52. package/dist/userHome-DOMLiHy7.mjs.map +1 -0
  53. package/package.json +2 -2
  54. package/dist/device-CDDcwDY6.mjs.map +0 -1
  55. package/dist/device-DuAYH8bk.js.map +0 -1
  56. package/dist/userHome-CcnAQPG1.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.js");
3
- const require_userHome = require("./userHome-BquDeFVE.js");
3
+ const require_userHome = require("./userHome-Baz205B7.js");
4
4
  let node_fs_promises = require("node:fs/promises");
5
5
  node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises);
6
6
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { R as getRepoDir, j as getHomeDir } from "./userHome-CcnAQPG1.mjs";
1
+ import { A as getHomeDir, L as getRepoDir } from "./userHome-B97jBm5O.mjs";
2
2
  import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
4
  //#region src/skill-linker/index.ts
@@ -1,4 +1,4 @@
1
- import { R as getRepoDir } from "./userHome-CcnAQPG1.mjs";
1
+ import { L as getRepoDir } from "./userHome-DOMLiHy7.mjs";
2
2
  import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
4
  //#region src/submit/types.ts
@@ -81,4 +81,4 @@ var SubmitClient = class {
81
81
  //#endregion
82
82
  export { SubmitError as n, SubmitClient as t };
83
83
 
84
- //# sourceMappingURL=submit-Cg7wSa3x.mjs.map
84
+ //# sourceMappingURL=submit-6zQPPrOJ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"submit-Cg7wSa3x.mjs","names":[],"sources":["../src/submit/types.ts","../src/submit/index.ts"],"sourcesContent":["/**\n * Skill & Agent v2 — SubmitClient Types (M4)\n *\n * Mirrors the server's POST /api/v1/skills/validate contract (M2\n * SubmitApi). Defined here as a separate types file so the test\n * fixtures + the client can both import without circular deps.\n */\n\n/** Reasons the server may deny a submission. */\nexport type DenyReason =\n\t| \"repo_not_writable\"\n\t| \"file_too_large\"\n\t| \"path_traversal\"\n\t| \"invalid_frontmatter\"\n\t| \"name_conflict\"\n\t/** Local-client-side errors that don't come from the server. */\n\t| \"network_error\"\n\t| \"write_error\"\n\t| \"commit_error\"\n\t| \"push_error\"\n\t| \"unknown\";\n\n/** Request payload. Identical to the server's SubmitValidationRequest. */\nexport interface SubmitValidationRequest {\n\trepoId: string;\n\tskillName: string;\n\tfiles: Array<{ path: string; content: string }>;\n}\n\n/** Response payload. Identical to the server's SubmitValidationResponse. */\nexport interface SubmitValidationResponse {\n\tallow: boolean;\n\treason?: DenyReason;\n\tdetail?: string;\n}\n\n/** Sentinel error thrown by SubmitClient.submit() / validate(). */\nexport class SubmitError extends Error {\n\treadonly reason: DenyReason;\n\treadonly detail: string;\n\treadonly status?: number;\n\n\tconstructor(reason: DenyReason, detail: string, options?: { status?: number }) {\n\t\tsuper(`submit failed (${reason}): ${detail}`);\n\t\tthis.name = \"SubmitError\";\n\t\tthis.reason = reason;\n\t\tthis.detail = detail;\n\t\tthis.status = options?.status;\n\t}\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { GitClient } from \"../git-client\";\nimport { getRepoDir } from \"../paths/userHome\";\nimport type { SkillFile } from \"../skill-store/types\";\nimport type { SubmitValidationRequest, SubmitValidationResponse } from \"./types\";\nimport { SubmitError } from \"./types\";\n\n// Re-export so consumers (bridge handlers, CLI commands) can detect\n// SubmitError via `instanceof` without reaching into the internal\n// `./types` module.\nexport { SubmitError } from \"./types\";\n\n/**\n * Skill & Agent v2 — SubmitClient (M4)\n *\n * SubmitClient orchestrates the \"validate then push\" flow described\n * in docs/architecture/skill-agent-v2-repo.md §5.7:\n *\n * 1. **validate** — POST the candidate files to the server's\n * `/api/v1/skills/validate` endpoint (5 deny reasons: repo_not_\n * writable, file_too_large, path_traversal, invalid_frontmatter,\n * name_conflict).\n * 2. **write** — materialize the files into the local repo clone at\n * `~/.serviceme/repos/<repoId>/skills/<name>/` (or `agents/`).\n * 3. **commit** — `git add . && git commit -m \"feat(skills): add <name>\"`.\n * 4. **push** — `git push origin <branch>` via the server proxy.\n *\n * The client is intentionally thin: it does NOT do its own validation\n * (the server is the gate), and it does NOT cache anything across\n * calls. The single source of truth for \"is this submission allowed?\"\n * is the server's validate endpoint.\n *\n * @see docs/architecture/skill-agent-v2-repo.md §5.7 SubmitClient\n */\n\nexport interface SubmitOptions {\n\t/** Override the server's validate URL. Defaults to `http://localhost:3000/api/v1`. */\n\tserverBaseUrl?: string;\n\t/** Override the branch to push. Defaults to the repo's `branch` field. */\n\tbranch?: string;\n\t/** Skip the actual push (for tests + dry-runs). When true, step 4 returns a synthetic PushResult. */\n\tskipPush?: boolean;\n}\n\nexport interface SubmitResult {\n\trepoId: string;\n\tskillName: string;\n\tcommitSha: string;\n\tpushedRef?: string;\n\tpushedSha?: string;\n}\n\nexport interface SubmitClientOptions {\n\tgitClient: GitClient;\n\t/** Lookup the default branch for a repo (config-driven). */\n\tgetRepoBranch?: (repoId: string) => string | undefined;\n\t/** HTTP fetch impl (defaults to the global `fetch`). */\n\tfetcher?: typeof fetch;\n\t/** Default server base URL when no override is supplied. */\n\tdefaultServerBaseUrl?: string;\n}\n\nexport class SubmitClient {\n\tprivate readonly git: GitClient;\n\tprivate readonly getRepoBranch: (repoId: string) => string | undefined;\n\tprivate readonly fetcher: typeof fetch;\n\tprivate readonly defaultServerBaseUrl: string;\n\n\tconstructor(opts: SubmitClientOptions) {\n\t\tthis.git = opts.gitClient;\n\t\tthis.getRepoBranch = opts.getRepoBranch ?? (() => undefined);\n\t\tthis.fetcher = opts.fetcher ?? (globalThis.fetch as typeof fetch);\n\t\tthis.defaultServerBaseUrl = opts.defaultServerBaseUrl ?? \"http://localhost:3000\";\n\t}\n\n\t/**\n\t * Validate-only path. Useful for the UI's \"Save Draft\" flow which\n\t * wants to surface validation errors without committing or pushing.\n\t */\n\tasync validate(req: SubmitValidationRequest): Promise<SubmitValidationResponse> {\n\t\tconst url = `${this.defaultServerBaseUrl}/api/v1/skills/validate`;\n\t\tconst res = await this.fetcher(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(req),\n\t\t});\n\t\tif (!res.ok) {\n\t\t\tthrow new SubmitError(\"network_error\", `validate request failed: HTTP ${res.status}`);\n\t\t}\n\t\treturn (await res.json()) as SubmitValidationResponse;\n\t}\n\n\t/**\n\t * Full submit pipeline. Throws `SubmitError` on:\n\t * - validate deny (reason echoed)\n\t * - network failure (network_error)\n\t * - local write failure\n\t * - commit/push failure\n\t */\n\tasync submit(\n\t\trepoId: string,\n\t\tskillName: string,\n\t\tfiles: SkillFile[],\n\t\topts: SubmitOptions = {}\n\t): Promise<SubmitResult> {\n\t\t// (1) Validate\n\t\tconst v = await this.validate({ repoId, skillName, files });\n\t\tif (!v.allow) {\n\t\t\tthrow new SubmitError(v.reason ?? \"unknown\", v.detail ?? \"validation denied\");\n\t\t}\n\n\t\t// (2) Write files into the local repo clone\n\t\tconst localRepoPath = getRepoDir(repoId);\n\t\tconst targetDir = path.join(localRepoPath, \"skills\", skillName);\n\t\tawait fs.mkdir(targetDir, { recursive: true });\n\t\tfor (const f of files) {\n\t\t\tconst full = path.join(targetDir, f.path);\n\t\t\tawait fs.mkdir(path.dirname(full), { recursive: true });\n\t\t\tconst tmp = `${full}.${process.pid}.${Date.now()}.tmp`;\n\t\t\tawait fs.writeFile(tmp, f.content, \"utf8\");\n\t\t\tawait fs.rename(tmp, full);\n\t\t}\n\n\t\t// (3) Commit (convention: `feat(skills): add <name>`)\n\t\tconst commitMessage = `feat(skills): add ${skillName}`;\n\t\tconst { commitSha } = await this.git.commit(localRepoPath, commitMessage);\n\n\t\t// (4) Push\n\t\tlet pushedRef: string | undefined;\n\t\tlet pushedSha: string | undefined;\n\t\tif (!opts.skipPush) {\n\t\t\tconst branch = opts.branch ?? this.getRepoBranch(repoId) ?? \"main\";\n\t\t\tconst pushResult = await this.git.push(repoId, localRepoPath, branch);\n\t\t\tpushedRef = pushResult.ref;\n\t\t\tpushedSha = pushResult.commitSha;\n\t\t}\n\n\t\treturn {\n\t\t\trepoId,\n\t\t\tskillName,\n\t\t\tcommitSha,\n\t\t\tpushedRef,\n\t\t\tpushedSha,\n\t\t};\n\t}\n}\n"],"mappings":";;;;;AAqCA,IAAa,cAAb,cAAiC,MAAM;CAKtC,YAAY,QAAoB,QAAgB,SAA+B;EAC9E,MAAM,kBAAkB,OAAO,KAAK,QAAQ;EAC5C,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,SAAS;EACd,KAAK,SAAS,SAAS;CACxB;AACD;;;ACcA,IAAa,eAAb,MAA0B;CAMzB,YAAY,MAA2B;EACtC,KAAK,MAAM,KAAK;EAChB,KAAK,gBAAgB,KAAK,wBAAwB,KAAA;EAClD,KAAK,UAAU,KAAK,WAAY,WAAW;EAC3C,KAAK,uBAAuB,KAAK,wBAAwB;CAC1D;;;;;CAMA,MAAM,SAAS,KAAiE;EAC/E,MAAM,MAAM,GAAG,KAAK,qBAAqB;EACzC,MAAM,MAAM,MAAM,KAAK,QAAQ,KAAK;GACnC,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU,GAAG;EACzB,CAAC;EACD,IAAI,CAAC,IAAI,IACR,MAAM,IAAI,YAAY,iBAAiB,iCAAiC,IAAI,QAAQ;EAErF,OAAQ,MAAM,IAAI,KAAK;CACxB;;;;;;;;CASA,MAAM,OACL,QACA,WACA,OACA,OAAsB,CAAC,GACC;EAExB,MAAM,IAAI,MAAM,KAAK,SAAS;GAAE;GAAQ;GAAW;EAAM,CAAC;EAC1D,IAAI,CAAC,EAAE,OACN,MAAM,IAAI,YAAY,EAAE,UAAU,WAAW,EAAE,UAAU,mBAAmB;EAI7E,MAAM,gBAAgB,WAAW,MAAM;EACvC,MAAM,YAAY,KAAK,KAAK,eAAe,UAAU,SAAS;EAC9D,MAAM,GAAG,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;EAC7C,KAAK,MAAM,KAAK,OAAO;GACtB,MAAM,OAAO,KAAK,KAAK,WAAW,EAAE,IAAI;GACxC,MAAM,GAAG,MAAM,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;GACtD,MAAM,MAAM,GAAG,KAAK,GAAG,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;GACjD,MAAM,GAAG,UAAU,KAAK,EAAE,SAAS,MAAM;GACzC,MAAM,GAAG,OAAO,KAAK,IAAI;EAC1B;EAGA,MAAM,gBAAgB,qBAAqB;EAC3C,MAAM,EAAE,cAAc,MAAM,KAAK,IAAI,OAAO,eAAe,aAAa;EAGxE,IAAI;EACJ,IAAI;EACJ,IAAI,CAAC,KAAK,UAAU;GACnB,MAAM,SAAS,KAAK,UAAU,KAAK,cAAc,MAAM,KAAK;GAC5D,MAAM,aAAa,MAAM,KAAK,IAAI,KAAK,QAAQ,eAAe,MAAM;GACpE,YAAY,WAAW;GACvB,YAAY,WAAW;EACxB;EAEA,OAAO;GACN;GACA;GACA;GACA;GACA;EACD;CACD;AACD"}
1
+ {"version":3,"file":"submit-6zQPPrOJ.mjs","names":[],"sources":["../src/submit/types.ts","../src/submit/index.ts"],"sourcesContent":["/**\n * Skill & Agent v2 — SubmitClient Types (M4)\n *\n * Mirrors the server's POST /api/v1/skills/validate contract (M2\n * SubmitApi). Defined here as a separate types file so the test\n * fixtures + the client can both import without circular deps.\n */\n\n/** Reasons the server may deny a submission. */\nexport type DenyReason =\n\t| \"repo_not_writable\"\n\t| \"file_too_large\"\n\t| \"path_traversal\"\n\t| \"invalid_frontmatter\"\n\t| \"name_conflict\"\n\t/** Local-client-side errors that don't come from the server. */\n\t| \"network_error\"\n\t| \"write_error\"\n\t| \"commit_error\"\n\t| \"push_error\"\n\t| \"unknown\";\n\n/** Request payload. Identical to the server's SubmitValidationRequest. */\nexport interface SubmitValidationRequest {\n\trepoId: string;\n\tskillName: string;\n\tfiles: Array<{ path: string; content: string }>;\n}\n\n/** Response payload. Identical to the server's SubmitValidationResponse. */\nexport interface SubmitValidationResponse {\n\tallow: boolean;\n\treason?: DenyReason;\n\tdetail?: string;\n}\n\n/** Sentinel error thrown by SubmitClient.submit() / validate(). */\nexport class SubmitError extends Error {\n\treadonly reason: DenyReason;\n\treadonly detail: string;\n\treadonly status?: number;\n\n\tconstructor(reason: DenyReason, detail: string, options?: { status?: number }) {\n\t\tsuper(`submit failed (${reason}): ${detail}`);\n\t\tthis.name = \"SubmitError\";\n\t\tthis.reason = reason;\n\t\tthis.detail = detail;\n\t\tthis.status = options?.status;\n\t}\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { GitClient } from \"../git-client\";\nimport { getRepoDir } from \"../paths/userHome\";\nimport type { SkillFile } from \"../skill-store/types\";\nimport type { SubmitValidationRequest, SubmitValidationResponse } from \"./types\";\nimport { SubmitError } from \"./types\";\n\n// Re-export so consumers (bridge handlers, CLI commands) can detect\n// SubmitError via `instanceof` without reaching into the internal\n// `./types` module.\nexport { SubmitError } from \"./types\";\n\n/**\n * Skill & Agent v2 — SubmitClient (M4)\n *\n * SubmitClient orchestrates the \"validate then push\" flow described\n * in docs/architecture/skill-agent-v2-repo.md §5.7:\n *\n * 1. **validate** — POST the candidate files to the server's\n * `/api/v1/skills/validate` endpoint (5 deny reasons: repo_not_\n * writable, file_too_large, path_traversal, invalid_frontmatter,\n * name_conflict).\n * 2. **write** — materialize the files into the local repo clone at\n * `~/.serviceme/repos/<repoId>/skills/<name>/` (or `agents/`).\n * 3. **commit** — `git add . && git commit -m \"feat(skills): add <name>\"`.\n * 4. **push** — `git push origin <branch>` via the server proxy.\n *\n * The client is intentionally thin: it does NOT do its own validation\n * (the server is the gate), and it does NOT cache anything across\n * calls. The single source of truth for \"is this submission allowed?\"\n * is the server's validate endpoint.\n *\n * @see docs/architecture/skill-agent-v2-repo.md §5.7 SubmitClient\n */\n\nexport interface SubmitOptions {\n\t/** Override the server's validate URL. Defaults to `http://localhost:3000/api/v1`. */\n\tserverBaseUrl?: string;\n\t/** Override the branch to push. Defaults to the repo's `branch` field. */\n\tbranch?: string;\n\t/** Skip the actual push (for tests + dry-runs). When true, step 4 returns a synthetic PushResult. */\n\tskipPush?: boolean;\n}\n\nexport interface SubmitResult {\n\trepoId: string;\n\tskillName: string;\n\tcommitSha: string;\n\tpushedRef?: string;\n\tpushedSha?: string;\n}\n\nexport interface SubmitClientOptions {\n\tgitClient: GitClient;\n\t/** Lookup the default branch for a repo (config-driven). */\n\tgetRepoBranch?: (repoId: string) => string | undefined;\n\t/** HTTP fetch impl (defaults to the global `fetch`). */\n\tfetcher?: typeof fetch;\n\t/** Default server base URL when no override is supplied. */\n\tdefaultServerBaseUrl?: string;\n}\n\nexport class SubmitClient {\n\tprivate readonly git: GitClient;\n\tprivate readonly getRepoBranch: (repoId: string) => string | undefined;\n\tprivate readonly fetcher: typeof fetch;\n\tprivate readonly defaultServerBaseUrl: string;\n\n\tconstructor(opts: SubmitClientOptions) {\n\t\tthis.git = opts.gitClient;\n\t\tthis.getRepoBranch = opts.getRepoBranch ?? (() => undefined);\n\t\tthis.fetcher = opts.fetcher ?? (globalThis.fetch as typeof fetch);\n\t\tthis.defaultServerBaseUrl = opts.defaultServerBaseUrl ?? \"http://localhost:3000\";\n\t}\n\n\t/**\n\t * Validate-only path. Useful for the UI's \"Save Draft\" flow which\n\t * wants to surface validation errors without committing or pushing.\n\t */\n\tasync validate(req: SubmitValidationRequest): Promise<SubmitValidationResponse> {\n\t\tconst url = `${this.defaultServerBaseUrl}/api/v1/skills/validate`;\n\t\tconst res = await this.fetcher(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(req),\n\t\t});\n\t\tif (!res.ok) {\n\t\t\tthrow new SubmitError(\"network_error\", `validate request failed: HTTP ${res.status}`);\n\t\t}\n\t\treturn (await res.json()) as SubmitValidationResponse;\n\t}\n\n\t/**\n\t * Full submit pipeline. Throws `SubmitError` on:\n\t * - validate deny (reason echoed)\n\t * - network failure (network_error)\n\t * - local write failure\n\t * - commit/push failure\n\t */\n\tasync submit(\n\t\trepoId: string,\n\t\tskillName: string,\n\t\tfiles: SkillFile[],\n\t\topts: SubmitOptions = {}\n\t): Promise<SubmitResult> {\n\t\t// (1) Validate\n\t\tconst v = await this.validate({ repoId, skillName, files });\n\t\tif (!v.allow) {\n\t\t\tthrow new SubmitError(v.reason ?? \"unknown\", v.detail ?? \"validation denied\");\n\t\t}\n\n\t\t// (2) Write files into the local repo clone\n\t\tconst localRepoPath = getRepoDir(repoId);\n\t\tconst targetDir = path.join(localRepoPath, \"skills\", skillName);\n\t\tawait fs.mkdir(targetDir, { recursive: true });\n\t\tfor (const f of files) {\n\t\t\tconst full = path.join(targetDir, f.path);\n\t\t\tawait fs.mkdir(path.dirname(full), { recursive: true });\n\t\t\tconst tmp = `${full}.${process.pid}.${Date.now()}.tmp`;\n\t\t\tawait fs.writeFile(tmp, f.content, \"utf8\");\n\t\t\tawait fs.rename(tmp, full);\n\t\t}\n\n\t\t// (3) Commit (convention: `feat(skills): add <name>`)\n\t\tconst commitMessage = `feat(skills): add ${skillName}`;\n\t\tconst { commitSha } = await this.git.commit(localRepoPath, commitMessage);\n\n\t\t// (4) Push\n\t\tlet pushedRef: string | undefined;\n\t\tlet pushedSha: string | undefined;\n\t\tif (!opts.skipPush) {\n\t\t\tconst branch = opts.branch ?? this.getRepoBranch(repoId) ?? \"main\";\n\t\t\tconst pushResult = await this.git.push(repoId, localRepoPath, branch);\n\t\t\tpushedRef = pushResult.ref;\n\t\t\tpushedSha = pushResult.commitSha;\n\t\t}\n\n\t\treturn {\n\t\t\trepoId,\n\t\t\tskillName,\n\t\t\tcommitSha,\n\t\t\tpushedRef,\n\t\t\tpushedSha,\n\t\t};\n\t}\n}\n"],"mappings":";;;;;AAqCA,IAAa,cAAb,cAAiC,MAAM;CAKtC,YAAY,QAAoB,QAAgB,SAA+B;EAC9E,MAAM,kBAAkB,OAAO,KAAK,QAAQ;EAC5C,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,SAAS;EACd,KAAK,SAAS,SAAS;CACxB;AACD;;;ACcA,IAAa,eAAb,MAA0B;CAMzB,YAAY,MAA2B;EACtC,KAAK,MAAM,KAAK;EAChB,KAAK,gBAAgB,KAAK,wBAAwB,KAAA;EAClD,KAAK,UAAU,KAAK,WAAY,WAAW;EAC3C,KAAK,uBAAuB,KAAK,wBAAwB;CAC1D;;;;;CAMA,MAAM,SAAS,KAAiE;EAC/E,MAAM,MAAM,GAAG,KAAK,qBAAqB;EACzC,MAAM,MAAM,MAAM,KAAK,QAAQ,KAAK;GACnC,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU,GAAG;EACzB,CAAC;EACD,IAAI,CAAC,IAAI,IACR,MAAM,IAAI,YAAY,iBAAiB,iCAAiC,IAAI,QAAQ;EAErF,OAAQ,MAAM,IAAI,KAAK;CACxB;;;;;;;;CASA,MAAM,OACL,QACA,WACA,OACA,OAAsB,CAAC,GACC;EAExB,MAAM,IAAI,MAAM,KAAK,SAAS;GAAE;GAAQ;GAAW;EAAM,CAAC;EAC1D,IAAI,CAAC,EAAE,OACN,MAAM,IAAI,YAAY,EAAE,UAAU,WAAW,EAAE,UAAU,mBAAmB;EAI7E,MAAM,gBAAgB,WAAW,MAAM;EACvC,MAAM,YAAY,KAAK,KAAK,eAAe,UAAU,SAAS;EAC9D,MAAM,GAAG,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;EAC7C,KAAK,MAAM,KAAK,OAAO;GACtB,MAAM,OAAO,KAAK,KAAK,WAAW,EAAE,IAAI;GACxC,MAAM,GAAG,MAAM,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;GACtD,MAAM,MAAM,GAAG,KAAK,GAAG,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;GACjD,MAAM,GAAG,UAAU,KAAK,EAAE,SAAS,MAAM;GACzC,MAAM,GAAG,OAAO,KAAK,IAAI;EAC1B;EAGA,MAAM,gBAAgB,qBAAqB;EAC3C,MAAM,EAAE,cAAc,MAAM,KAAK,IAAI,OAAO,eAAe,aAAa;EAGxE,IAAI;EACJ,IAAI;EACJ,IAAI,CAAC,KAAK,UAAU;GACnB,MAAM,SAAS,KAAK,UAAU,KAAK,cAAc,MAAM,KAAK;GAC5D,MAAM,aAAa,MAAM,KAAK,IAAI,KAAK,QAAQ,eAAe,MAAM;GACpE,YAAY,WAAW;GACvB,YAAY,WAAW;EACxB;EAEA,OAAO;GACN;GACA;GACA;GACA;GACA;EACD;CACD;AACD"}
@@ -0,0 +1,84 @@
1
+ import { L as getRepoDir } from "./userHome-B97jBm5O.mjs";
2
+ import * as fs from "node:fs/promises";
3
+ import * as path from "node:path";
4
+ //#region src/submit/types.ts
5
+ /** Sentinel error thrown by SubmitClient.submit() / validate(). */
6
+ var SubmitError = class extends Error {
7
+ constructor(reason, detail, options) {
8
+ super(`submit failed (${reason}): ${detail}`);
9
+ this.name = "SubmitError";
10
+ this.reason = reason;
11
+ this.detail = detail;
12
+ this.status = options?.status;
13
+ }
14
+ };
15
+ //#endregion
16
+ //#region src/submit/index.ts
17
+ var SubmitClient = class {
18
+ constructor(opts) {
19
+ this.git = opts.gitClient;
20
+ this.getRepoBranch = opts.getRepoBranch ?? (() => void 0);
21
+ this.fetcher = opts.fetcher ?? globalThis.fetch;
22
+ this.defaultServerBaseUrl = opts.defaultServerBaseUrl ?? "http://localhost:3000";
23
+ }
24
+ /**
25
+ * Validate-only path. Useful for the UI's "Save Draft" flow which
26
+ * wants to surface validation errors without committing or pushing.
27
+ */
28
+ async validate(req) {
29
+ const url = `${this.defaultServerBaseUrl}/api/v1/skills/validate`;
30
+ const res = await this.fetcher(url, {
31
+ method: "POST",
32
+ headers: { "content-type": "application/json" },
33
+ body: JSON.stringify(req)
34
+ });
35
+ if (!res.ok) throw new SubmitError("network_error", `validate request failed: HTTP ${res.status}`);
36
+ return await res.json();
37
+ }
38
+ /**
39
+ * Full submit pipeline. Throws `SubmitError` on:
40
+ * - validate deny (reason echoed)
41
+ * - network failure (network_error)
42
+ * - local write failure
43
+ * - commit/push failure
44
+ */
45
+ async submit(repoId, skillName, files, opts = {}) {
46
+ const v = await this.validate({
47
+ repoId,
48
+ skillName,
49
+ files
50
+ });
51
+ if (!v.allow) throw new SubmitError(v.reason ?? "unknown", v.detail ?? "validation denied");
52
+ const localRepoPath = getRepoDir(repoId);
53
+ const targetDir = path.join(localRepoPath, "skills", skillName);
54
+ await fs.mkdir(targetDir, { recursive: true });
55
+ for (const f of files) {
56
+ const full = path.join(targetDir, f.path);
57
+ await fs.mkdir(path.dirname(full), { recursive: true });
58
+ const tmp = `${full}.${process.pid}.${Date.now()}.tmp`;
59
+ await fs.writeFile(tmp, f.content, "utf8");
60
+ await fs.rename(tmp, full);
61
+ }
62
+ const commitMessage = `feat(skills): add ${skillName}`;
63
+ const { commitSha } = await this.git.commit(localRepoPath, commitMessage);
64
+ let pushedRef;
65
+ let pushedSha;
66
+ if (!opts.skipPush) {
67
+ const branch = opts.branch ?? this.getRepoBranch(repoId) ?? "main";
68
+ const pushResult = await this.git.push(repoId, localRepoPath, branch);
69
+ pushedRef = pushResult.ref;
70
+ pushedSha = pushResult.commitSha;
71
+ }
72
+ return {
73
+ repoId,
74
+ skillName,
75
+ commitSha,
76
+ pushedRef,
77
+ pushedSha
78
+ };
79
+ }
80
+ };
81
+ //#endregion
82
+ export { SubmitError as n, SubmitClient as t };
83
+
84
+ //# sourceMappingURL=submit-BTdbGEAd.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit-BTdbGEAd.mjs","names":[],"sources":["../src/submit/types.ts","../src/submit/index.ts"],"sourcesContent":["/**\n * Skill & Agent v2 — SubmitClient Types (M4)\n *\n * Mirrors the server's POST /api/v1/skills/validate contract (M2\n * SubmitApi). Defined here as a separate types file so the test\n * fixtures + the client can both import without circular deps.\n */\n\n/** Reasons the server may deny a submission. */\nexport type DenyReason =\n\t| \"repo_not_writable\"\n\t| \"file_too_large\"\n\t| \"path_traversal\"\n\t| \"invalid_frontmatter\"\n\t| \"name_conflict\"\n\t/** Local-client-side errors that don't come from the server. */\n\t| \"network_error\"\n\t| \"write_error\"\n\t| \"commit_error\"\n\t| \"push_error\"\n\t| \"unknown\";\n\n/** Request payload. Identical to the server's SubmitValidationRequest. */\nexport interface SubmitValidationRequest {\n\trepoId: string;\n\tskillName: string;\n\tfiles: Array<{ path: string; content: string }>;\n}\n\n/** Response payload. Identical to the server's SubmitValidationResponse. */\nexport interface SubmitValidationResponse {\n\tallow: boolean;\n\treason?: DenyReason;\n\tdetail?: string;\n}\n\n/** Sentinel error thrown by SubmitClient.submit() / validate(). */\nexport class SubmitError extends Error {\n\treadonly reason: DenyReason;\n\treadonly detail: string;\n\treadonly status?: number;\n\n\tconstructor(reason: DenyReason, detail: string, options?: { status?: number }) {\n\t\tsuper(`submit failed (${reason}): ${detail}`);\n\t\tthis.name = \"SubmitError\";\n\t\tthis.reason = reason;\n\t\tthis.detail = detail;\n\t\tthis.status = options?.status;\n\t}\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { GitClient } from \"../git-client\";\nimport { getRepoDir } from \"../paths/userHome\";\nimport type { SkillFile } from \"../skill-store/types\";\nimport type { SubmitValidationRequest, SubmitValidationResponse } from \"./types\";\nimport { SubmitError } from \"./types\";\n\n// Re-export so consumers (bridge handlers, CLI commands) can detect\n// SubmitError via `instanceof` without reaching into the internal\n// `./types` module.\nexport { SubmitError } from \"./types\";\n\n/**\n * Skill & Agent v2 — SubmitClient (M4)\n *\n * SubmitClient orchestrates the \"validate then push\" flow described\n * in docs/architecture/skill-agent-v2-repo.md §5.7:\n *\n * 1. **validate** — POST the candidate files to the server's\n * `/api/v1/skills/validate` endpoint (5 deny reasons: repo_not_\n * writable, file_too_large, path_traversal, invalid_frontmatter,\n * name_conflict).\n * 2. **write** — materialize the files into the local repo clone at\n * `~/.serviceme/repos/<repoId>/skills/<name>/` (or `agents/`).\n * 3. **commit** — `git add . && git commit -m \"feat(skills): add <name>\"`.\n * 4. **push** — `git push origin <branch>` via the server proxy.\n *\n * The client is intentionally thin: it does NOT do its own validation\n * (the server is the gate), and it does NOT cache anything across\n * calls. The single source of truth for \"is this submission allowed?\"\n * is the server's validate endpoint.\n *\n * @see docs/architecture/skill-agent-v2-repo.md §5.7 SubmitClient\n */\n\nexport interface SubmitOptions {\n\t/** Override the server's validate URL. Defaults to `http://localhost:3000/api/v1`. */\n\tserverBaseUrl?: string;\n\t/** Override the branch to push. Defaults to the repo's `branch` field. */\n\tbranch?: string;\n\t/** Skip the actual push (for tests + dry-runs). When true, step 4 returns a synthetic PushResult. */\n\tskipPush?: boolean;\n}\n\nexport interface SubmitResult {\n\trepoId: string;\n\tskillName: string;\n\tcommitSha: string;\n\tpushedRef?: string;\n\tpushedSha?: string;\n}\n\nexport interface SubmitClientOptions {\n\tgitClient: GitClient;\n\t/** Lookup the default branch for a repo (config-driven). */\n\tgetRepoBranch?: (repoId: string) => string | undefined;\n\t/** HTTP fetch impl (defaults to the global `fetch`). */\n\tfetcher?: typeof fetch;\n\t/** Default server base URL when no override is supplied. */\n\tdefaultServerBaseUrl?: string;\n}\n\nexport class SubmitClient {\n\tprivate readonly git: GitClient;\n\tprivate readonly getRepoBranch: (repoId: string) => string | undefined;\n\tprivate readonly fetcher: typeof fetch;\n\tprivate readonly defaultServerBaseUrl: string;\n\n\tconstructor(opts: SubmitClientOptions) {\n\t\tthis.git = opts.gitClient;\n\t\tthis.getRepoBranch = opts.getRepoBranch ?? (() => undefined);\n\t\tthis.fetcher = opts.fetcher ?? (globalThis.fetch as typeof fetch);\n\t\tthis.defaultServerBaseUrl = opts.defaultServerBaseUrl ?? \"http://localhost:3000\";\n\t}\n\n\t/**\n\t * Validate-only path. Useful for the UI's \"Save Draft\" flow which\n\t * wants to surface validation errors without committing or pushing.\n\t */\n\tasync validate(req: SubmitValidationRequest): Promise<SubmitValidationResponse> {\n\t\tconst url = `${this.defaultServerBaseUrl}/api/v1/skills/validate`;\n\t\tconst res = await this.fetcher(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(req),\n\t\t});\n\t\tif (!res.ok) {\n\t\t\tthrow new SubmitError(\"network_error\", `validate request failed: HTTP ${res.status}`);\n\t\t}\n\t\treturn (await res.json()) as SubmitValidationResponse;\n\t}\n\n\t/**\n\t * Full submit pipeline. Throws `SubmitError` on:\n\t * - validate deny (reason echoed)\n\t * - network failure (network_error)\n\t * - local write failure\n\t * - commit/push failure\n\t */\n\tasync submit(\n\t\trepoId: string,\n\t\tskillName: string,\n\t\tfiles: SkillFile[],\n\t\topts: SubmitOptions = {}\n\t): Promise<SubmitResult> {\n\t\t// (1) Validate\n\t\tconst v = await this.validate({ repoId, skillName, files });\n\t\tif (!v.allow) {\n\t\t\tthrow new SubmitError(v.reason ?? \"unknown\", v.detail ?? \"validation denied\");\n\t\t}\n\n\t\t// (2) Write files into the local repo clone\n\t\tconst localRepoPath = getRepoDir(repoId);\n\t\tconst targetDir = path.join(localRepoPath, \"skills\", skillName);\n\t\tawait fs.mkdir(targetDir, { recursive: true });\n\t\tfor (const f of files) {\n\t\t\tconst full = path.join(targetDir, f.path);\n\t\t\tawait fs.mkdir(path.dirname(full), { recursive: true });\n\t\t\tconst tmp = `${full}.${process.pid}.${Date.now()}.tmp`;\n\t\t\tawait fs.writeFile(tmp, f.content, \"utf8\");\n\t\t\tawait fs.rename(tmp, full);\n\t\t}\n\n\t\t// (3) Commit (convention: `feat(skills): add <name>`)\n\t\tconst commitMessage = `feat(skills): add ${skillName}`;\n\t\tconst { commitSha } = await this.git.commit(localRepoPath, commitMessage);\n\n\t\t// (4) Push\n\t\tlet pushedRef: string | undefined;\n\t\tlet pushedSha: string | undefined;\n\t\tif (!opts.skipPush) {\n\t\t\tconst branch = opts.branch ?? this.getRepoBranch(repoId) ?? \"main\";\n\t\t\tconst pushResult = await this.git.push(repoId, localRepoPath, branch);\n\t\t\tpushedRef = pushResult.ref;\n\t\t\tpushedSha = pushResult.commitSha;\n\t\t}\n\n\t\treturn {\n\t\t\trepoId,\n\t\t\tskillName,\n\t\t\tcommitSha,\n\t\t\tpushedRef,\n\t\t\tpushedSha,\n\t\t};\n\t}\n}\n"],"mappings":";;;;;AAqCA,IAAa,cAAb,cAAiC,MAAM;CAKtC,YAAY,QAAoB,QAAgB,SAA+B;EAC9E,MAAM,kBAAkB,OAAO,KAAK,QAAQ;EAC5C,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,SAAS;EACd,KAAK,SAAS,SAAS;CACxB;AACD;;;ACcA,IAAa,eAAb,MAA0B;CAMzB,YAAY,MAA2B;EACtC,KAAK,MAAM,KAAK;EAChB,KAAK,gBAAgB,KAAK,wBAAwB,KAAA;EAClD,KAAK,UAAU,KAAK,WAAY,WAAW;EAC3C,KAAK,uBAAuB,KAAK,wBAAwB;CAC1D;;;;;CAMA,MAAM,SAAS,KAAiE;EAC/E,MAAM,MAAM,GAAG,KAAK,qBAAqB;EACzC,MAAM,MAAM,MAAM,KAAK,QAAQ,KAAK;GACnC,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU,GAAG;EACzB,CAAC;EACD,IAAI,CAAC,IAAI,IACR,MAAM,IAAI,YAAY,iBAAiB,iCAAiC,IAAI,QAAQ;EAErF,OAAQ,MAAM,IAAI,KAAK;CACxB;;;;;;;;CASA,MAAM,OACL,QACA,WACA,OACA,OAAsB,CAAC,GACC;EAExB,MAAM,IAAI,MAAM,KAAK,SAAS;GAAE;GAAQ;GAAW;EAAM,CAAC;EAC1D,IAAI,CAAC,EAAE,OACN,MAAM,IAAI,YAAY,EAAE,UAAU,WAAW,EAAE,UAAU,mBAAmB;EAI7E,MAAM,gBAAgB,WAAW,MAAM;EACvC,MAAM,YAAY,KAAK,KAAK,eAAe,UAAU,SAAS;EAC9D,MAAM,GAAG,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;EAC7C,KAAK,MAAM,KAAK,OAAO;GACtB,MAAM,OAAO,KAAK,KAAK,WAAW,EAAE,IAAI;GACxC,MAAM,GAAG,MAAM,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;GACtD,MAAM,MAAM,GAAG,KAAK,GAAG,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;GACjD,MAAM,GAAG,UAAU,KAAK,EAAE,SAAS,MAAM;GACzC,MAAM,GAAG,OAAO,KAAK,IAAI;EAC1B;EAGA,MAAM,gBAAgB,qBAAqB;EAC3C,MAAM,EAAE,cAAc,MAAM,KAAK,IAAI,OAAO,eAAe,aAAa;EAGxE,IAAI;EACJ,IAAI;EACJ,IAAI,CAAC,KAAK,UAAU;GACnB,MAAM,SAAS,KAAK,UAAU,KAAK,cAAc,MAAM,KAAK;GAC5D,MAAM,aAAa,MAAM,KAAK,IAAI,KAAK,QAAQ,eAAe,MAAM;GACpE,YAAY,WAAW;GACvB,YAAY,WAAW;EACxB;EAEA,OAAO;GACN;GACA;GACA;GACA;GACA;EACD;CACD;AACD"}
@@ -0,0 +1,98 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.js");
2
+ const require_userHome = require("./userHome-Baz205B7.js");
3
+ let node_fs_promises = require("node:fs/promises");
4
+ node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises);
5
+ let node_path = require("node:path");
6
+ node_path = require_rolldown_runtime.__toESM(node_path);
7
+ //#region src/submit/types.ts
8
+ /** Sentinel error thrown by SubmitClient.submit() / validate(). */
9
+ var SubmitError = class extends Error {
10
+ constructor(reason, detail, options) {
11
+ super(`submit failed (${reason}): ${detail}`);
12
+ this.name = "SubmitError";
13
+ this.reason = reason;
14
+ this.detail = detail;
15
+ this.status = options?.status;
16
+ }
17
+ };
18
+ //#endregion
19
+ //#region src/submit/index.ts
20
+ var SubmitClient = class {
21
+ constructor(opts) {
22
+ this.git = opts.gitClient;
23
+ this.getRepoBranch = opts.getRepoBranch ?? (() => void 0);
24
+ this.fetcher = opts.fetcher ?? globalThis.fetch;
25
+ this.defaultServerBaseUrl = opts.defaultServerBaseUrl ?? "http://localhost:3000";
26
+ }
27
+ /**
28
+ * Validate-only path. Useful for the UI's "Save Draft" flow which
29
+ * wants to surface validation errors without committing or pushing.
30
+ */
31
+ async validate(req) {
32
+ const url = `${this.defaultServerBaseUrl}/api/v1/skills/validate`;
33
+ const res = await this.fetcher(url, {
34
+ method: "POST",
35
+ headers: { "content-type": "application/json" },
36
+ body: JSON.stringify(req)
37
+ });
38
+ if (!res.ok) throw new SubmitError("network_error", `validate request failed: HTTP ${res.status}`);
39
+ return await res.json();
40
+ }
41
+ /**
42
+ * Full submit pipeline. Throws `SubmitError` on:
43
+ * - validate deny (reason echoed)
44
+ * - network failure (network_error)
45
+ * - local write failure
46
+ * - commit/push failure
47
+ */
48
+ async submit(repoId, skillName, files, opts = {}) {
49
+ const v = await this.validate({
50
+ repoId,
51
+ skillName,
52
+ files
53
+ });
54
+ if (!v.allow) throw new SubmitError(v.reason ?? "unknown", v.detail ?? "validation denied");
55
+ const localRepoPath = require_userHome.getRepoDir(repoId);
56
+ const targetDir = node_path.join(localRepoPath, "skills", skillName);
57
+ await node_fs_promises.mkdir(targetDir, { recursive: true });
58
+ for (const f of files) {
59
+ const full = node_path.join(targetDir, f.path);
60
+ await node_fs_promises.mkdir(node_path.dirname(full), { recursive: true });
61
+ const tmp = `${full}.${process.pid}.${Date.now()}.tmp`;
62
+ await node_fs_promises.writeFile(tmp, f.content, "utf8");
63
+ await node_fs_promises.rename(tmp, full);
64
+ }
65
+ const commitMessage = `feat(skills): add ${skillName}`;
66
+ const { commitSha } = await this.git.commit(localRepoPath, commitMessage);
67
+ let pushedRef;
68
+ let pushedSha;
69
+ if (!opts.skipPush) {
70
+ const branch = opts.branch ?? this.getRepoBranch(repoId) ?? "main";
71
+ const pushResult = await this.git.push(repoId, localRepoPath, branch);
72
+ pushedRef = pushResult.ref;
73
+ pushedSha = pushResult.commitSha;
74
+ }
75
+ return {
76
+ repoId,
77
+ skillName,
78
+ commitSha,
79
+ pushedRef,
80
+ pushedSha
81
+ };
82
+ }
83
+ };
84
+ //#endregion
85
+ Object.defineProperty(exports, "SubmitClient", {
86
+ enumerable: true,
87
+ get: function() {
88
+ return SubmitClient;
89
+ }
90
+ });
91
+ Object.defineProperty(exports, "SubmitError", {
92
+ enumerable: true,
93
+ get: function() {
94
+ return SubmitError;
95
+ }
96
+ });
97
+
98
+ //# sourceMappingURL=submit-CW9schoc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit-CW9schoc.js","names":["getRepoDir","path","fs"],"sources":["../src/submit/types.ts","../src/submit/index.ts"],"sourcesContent":["/**\n * Skill & Agent v2 — SubmitClient Types (M4)\n *\n * Mirrors the server's POST /api/v1/skills/validate contract (M2\n * SubmitApi). Defined here as a separate types file so the test\n * fixtures + the client can both import without circular deps.\n */\n\n/** Reasons the server may deny a submission. */\nexport type DenyReason =\n\t| \"repo_not_writable\"\n\t| \"file_too_large\"\n\t| \"path_traversal\"\n\t| \"invalid_frontmatter\"\n\t| \"name_conflict\"\n\t/** Local-client-side errors that don't come from the server. */\n\t| \"network_error\"\n\t| \"write_error\"\n\t| \"commit_error\"\n\t| \"push_error\"\n\t| \"unknown\";\n\n/** Request payload. Identical to the server's SubmitValidationRequest. */\nexport interface SubmitValidationRequest {\n\trepoId: string;\n\tskillName: string;\n\tfiles: Array<{ path: string; content: string }>;\n}\n\n/** Response payload. Identical to the server's SubmitValidationResponse. */\nexport interface SubmitValidationResponse {\n\tallow: boolean;\n\treason?: DenyReason;\n\tdetail?: string;\n}\n\n/** Sentinel error thrown by SubmitClient.submit() / validate(). */\nexport class SubmitError extends Error {\n\treadonly reason: DenyReason;\n\treadonly detail: string;\n\treadonly status?: number;\n\n\tconstructor(reason: DenyReason, detail: string, options?: { status?: number }) {\n\t\tsuper(`submit failed (${reason}): ${detail}`);\n\t\tthis.name = \"SubmitError\";\n\t\tthis.reason = reason;\n\t\tthis.detail = detail;\n\t\tthis.status = options?.status;\n\t}\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { GitClient } from \"../git-client\";\nimport { getRepoDir } from \"../paths/userHome\";\nimport type { SkillFile } from \"../skill-store/types\";\nimport type { SubmitValidationRequest, SubmitValidationResponse } from \"./types\";\nimport { SubmitError } from \"./types\";\n\n// Re-export so consumers (bridge handlers, CLI commands) can detect\n// SubmitError via `instanceof` without reaching into the internal\n// `./types` module.\nexport { SubmitError } from \"./types\";\n\n/**\n * Skill & Agent v2 — SubmitClient (M4)\n *\n * SubmitClient orchestrates the \"validate then push\" flow described\n * in docs/architecture/skill-agent-v2-repo.md §5.7:\n *\n * 1. **validate** — POST the candidate files to the server's\n * `/api/v1/skills/validate` endpoint (5 deny reasons: repo_not_\n * writable, file_too_large, path_traversal, invalid_frontmatter,\n * name_conflict).\n * 2. **write** — materialize the files into the local repo clone at\n * `~/.serviceme/repos/<repoId>/skills/<name>/` (or `agents/`).\n * 3. **commit** — `git add . && git commit -m \"feat(skills): add <name>\"`.\n * 4. **push** — `git push origin <branch>` via the server proxy.\n *\n * The client is intentionally thin: it does NOT do its own validation\n * (the server is the gate), and it does NOT cache anything across\n * calls. The single source of truth for \"is this submission allowed?\"\n * is the server's validate endpoint.\n *\n * @see docs/architecture/skill-agent-v2-repo.md §5.7 SubmitClient\n */\n\nexport interface SubmitOptions {\n\t/** Override the server's validate URL. Defaults to `http://localhost:3000/api/v1`. */\n\tserverBaseUrl?: string;\n\t/** Override the branch to push. Defaults to the repo's `branch` field. */\n\tbranch?: string;\n\t/** Skip the actual push (for tests + dry-runs). When true, step 4 returns a synthetic PushResult. */\n\tskipPush?: boolean;\n}\n\nexport interface SubmitResult {\n\trepoId: string;\n\tskillName: string;\n\tcommitSha: string;\n\tpushedRef?: string;\n\tpushedSha?: string;\n}\n\nexport interface SubmitClientOptions {\n\tgitClient: GitClient;\n\t/** Lookup the default branch for a repo (config-driven). */\n\tgetRepoBranch?: (repoId: string) => string | undefined;\n\t/** HTTP fetch impl (defaults to the global `fetch`). */\n\tfetcher?: typeof fetch;\n\t/** Default server base URL when no override is supplied. */\n\tdefaultServerBaseUrl?: string;\n}\n\nexport class SubmitClient {\n\tprivate readonly git: GitClient;\n\tprivate readonly getRepoBranch: (repoId: string) => string | undefined;\n\tprivate readonly fetcher: typeof fetch;\n\tprivate readonly defaultServerBaseUrl: string;\n\n\tconstructor(opts: SubmitClientOptions) {\n\t\tthis.git = opts.gitClient;\n\t\tthis.getRepoBranch = opts.getRepoBranch ?? (() => undefined);\n\t\tthis.fetcher = opts.fetcher ?? (globalThis.fetch as typeof fetch);\n\t\tthis.defaultServerBaseUrl = opts.defaultServerBaseUrl ?? \"http://localhost:3000\";\n\t}\n\n\t/**\n\t * Validate-only path. Useful for the UI's \"Save Draft\" flow which\n\t * wants to surface validation errors without committing or pushing.\n\t */\n\tasync validate(req: SubmitValidationRequest): Promise<SubmitValidationResponse> {\n\t\tconst url = `${this.defaultServerBaseUrl}/api/v1/skills/validate`;\n\t\tconst res = await this.fetcher(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(req),\n\t\t});\n\t\tif (!res.ok) {\n\t\t\tthrow new SubmitError(\"network_error\", `validate request failed: HTTP ${res.status}`);\n\t\t}\n\t\treturn (await res.json()) as SubmitValidationResponse;\n\t}\n\n\t/**\n\t * Full submit pipeline. Throws `SubmitError` on:\n\t * - validate deny (reason echoed)\n\t * - network failure (network_error)\n\t * - local write failure\n\t * - commit/push failure\n\t */\n\tasync submit(\n\t\trepoId: string,\n\t\tskillName: string,\n\t\tfiles: SkillFile[],\n\t\topts: SubmitOptions = {}\n\t): Promise<SubmitResult> {\n\t\t// (1) Validate\n\t\tconst v = await this.validate({ repoId, skillName, files });\n\t\tif (!v.allow) {\n\t\t\tthrow new SubmitError(v.reason ?? \"unknown\", v.detail ?? \"validation denied\");\n\t\t}\n\n\t\t// (2) Write files into the local repo clone\n\t\tconst localRepoPath = getRepoDir(repoId);\n\t\tconst targetDir = path.join(localRepoPath, \"skills\", skillName);\n\t\tawait fs.mkdir(targetDir, { recursive: true });\n\t\tfor (const f of files) {\n\t\t\tconst full = path.join(targetDir, f.path);\n\t\t\tawait fs.mkdir(path.dirname(full), { recursive: true });\n\t\t\tconst tmp = `${full}.${process.pid}.${Date.now()}.tmp`;\n\t\t\tawait fs.writeFile(tmp, f.content, \"utf8\");\n\t\t\tawait fs.rename(tmp, full);\n\t\t}\n\n\t\t// (3) Commit (convention: `feat(skills): add <name>`)\n\t\tconst commitMessage = `feat(skills): add ${skillName}`;\n\t\tconst { commitSha } = await this.git.commit(localRepoPath, commitMessage);\n\n\t\t// (4) Push\n\t\tlet pushedRef: string | undefined;\n\t\tlet pushedSha: string | undefined;\n\t\tif (!opts.skipPush) {\n\t\t\tconst branch = opts.branch ?? this.getRepoBranch(repoId) ?? \"main\";\n\t\t\tconst pushResult = await this.git.push(repoId, localRepoPath, branch);\n\t\t\tpushedRef = pushResult.ref;\n\t\t\tpushedSha = pushResult.commitSha;\n\t\t}\n\n\t\treturn {\n\t\t\trepoId,\n\t\t\tskillName,\n\t\t\tcommitSha,\n\t\t\tpushedRef,\n\t\t\tpushedSha,\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;AAqCA,IAAa,cAAb,cAAiC,MAAM;CAKtC,YAAY,QAAoB,QAAgB,SAA+B;EAC9E,MAAM,kBAAkB,OAAO,KAAK,QAAQ;EAC5C,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,SAAS;EACd,KAAK,SAAS,SAAS;CACxB;AACD;;;ACcA,IAAa,eAAb,MAA0B;CAMzB,YAAY,MAA2B;EACtC,KAAK,MAAM,KAAK;EAChB,KAAK,gBAAgB,KAAK,wBAAwB,KAAA;EAClD,KAAK,UAAU,KAAK,WAAY,WAAW;EAC3C,KAAK,uBAAuB,KAAK,wBAAwB;CAC1D;;;;;CAMA,MAAM,SAAS,KAAiE;EAC/E,MAAM,MAAM,GAAG,KAAK,qBAAqB;EACzC,MAAM,MAAM,MAAM,KAAK,QAAQ,KAAK;GACnC,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU,GAAG;EACzB,CAAC;EACD,IAAI,CAAC,IAAI,IACR,MAAM,IAAI,YAAY,iBAAiB,iCAAiC,IAAI,QAAQ;EAErF,OAAQ,MAAM,IAAI,KAAK;CACxB;;;;;;;;CASA,MAAM,OACL,QACA,WACA,OACA,OAAsB,CAAC,GACC;EAExB,MAAM,IAAI,MAAM,KAAK,SAAS;GAAE;GAAQ;GAAW;EAAM,CAAC;EAC1D,IAAI,CAAC,EAAE,OACN,MAAM,IAAI,YAAY,EAAE,UAAU,WAAW,EAAE,UAAU,mBAAmB;EAI7E,MAAM,gBAAgBA,iBAAAA,WAAW,MAAM;EACvC,MAAM,YAAYC,UAAK,KAAK,eAAe,UAAU,SAAS;EAC9D,MAAMC,iBAAG,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;EAC7C,KAAK,MAAM,KAAK,OAAO;GACtB,MAAM,OAAOD,UAAK,KAAK,WAAW,EAAE,IAAI;GACxC,MAAMC,iBAAG,MAAMD,UAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;GACtD,MAAM,MAAM,GAAG,KAAK,GAAG,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;GACjD,MAAMC,iBAAG,UAAU,KAAK,EAAE,SAAS,MAAM;GACzC,MAAMA,iBAAG,OAAO,KAAK,IAAI;EAC1B;EAGA,MAAM,gBAAgB,qBAAqB;EAC3C,MAAM,EAAE,cAAc,MAAM,KAAK,IAAI,OAAO,eAAe,aAAa;EAGxE,IAAI;EACJ,IAAI;EACJ,IAAI,CAAC,KAAK,UAAU;GACnB,MAAM,SAAS,KAAK,UAAU,KAAK,cAAc,MAAM,KAAK;GAC5D,MAAM,aAAa,MAAM,KAAK,IAAI,KAAK,QAAQ,eAAe,MAAM;GACpE,YAAY,WAAW;GACvB,YAAY,WAAW;EACxB;EAEA,OAAO;GACN;GACA;GACA;GACA;GACA;EACD;CACD;AACD"}
@@ -0,0 +1,98 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.js");
2
+ const require_userHome = require("./userHome-CLlsXCvW.js");
3
+ let node_fs_promises = require("node:fs/promises");
4
+ node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises);
5
+ let node_path = require("node:path");
6
+ node_path = require_rolldown_runtime.__toESM(node_path);
7
+ //#region src/submit/types.ts
8
+ /** Sentinel error thrown by SubmitClient.submit() / validate(). */
9
+ var SubmitError = class extends Error {
10
+ constructor(reason, detail, options) {
11
+ super(`submit failed (${reason}): ${detail}`);
12
+ this.name = "SubmitError";
13
+ this.reason = reason;
14
+ this.detail = detail;
15
+ this.status = options?.status;
16
+ }
17
+ };
18
+ //#endregion
19
+ //#region src/submit/index.ts
20
+ var SubmitClient = class {
21
+ constructor(opts) {
22
+ this.git = opts.gitClient;
23
+ this.getRepoBranch = opts.getRepoBranch ?? (() => void 0);
24
+ this.fetcher = opts.fetcher ?? globalThis.fetch;
25
+ this.defaultServerBaseUrl = opts.defaultServerBaseUrl ?? "http://localhost:3000";
26
+ }
27
+ /**
28
+ * Validate-only path. Useful for the UI's "Save Draft" flow which
29
+ * wants to surface validation errors without committing or pushing.
30
+ */
31
+ async validate(req) {
32
+ const url = `${this.defaultServerBaseUrl}/api/v1/skills/validate`;
33
+ const res = await this.fetcher(url, {
34
+ method: "POST",
35
+ headers: { "content-type": "application/json" },
36
+ body: JSON.stringify(req)
37
+ });
38
+ if (!res.ok) throw new SubmitError("network_error", `validate request failed: HTTP ${res.status}`);
39
+ return await res.json();
40
+ }
41
+ /**
42
+ * Full submit pipeline. Throws `SubmitError` on:
43
+ * - validate deny (reason echoed)
44
+ * - network failure (network_error)
45
+ * - local write failure
46
+ * - commit/push failure
47
+ */
48
+ async submit(repoId, skillName, files, opts = {}) {
49
+ const v = await this.validate({
50
+ repoId,
51
+ skillName,
52
+ files
53
+ });
54
+ if (!v.allow) throw new SubmitError(v.reason ?? "unknown", v.detail ?? "validation denied");
55
+ const localRepoPath = require_userHome.getRepoDir(repoId);
56
+ const targetDir = node_path.join(localRepoPath, "skills", skillName);
57
+ await node_fs_promises.mkdir(targetDir, { recursive: true });
58
+ for (const f of files) {
59
+ const full = node_path.join(targetDir, f.path);
60
+ await node_fs_promises.mkdir(node_path.dirname(full), { recursive: true });
61
+ const tmp = `${full}.${process.pid}.${Date.now()}.tmp`;
62
+ await node_fs_promises.writeFile(tmp, f.content, "utf8");
63
+ await node_fs_promises.rename(tmp, full);
64
+ }
65
+ const commitMessage = `feat(skills): add ${skillName}`;
66
+ const { commitSha } = await this.git.commit(localRepoPath, commitMessage);
67
+ let pushedRef;
68
+ let pushedSha;
69
+ if (!opts.skipPush) {
70
+ const branch = opts.branch ?? this.getRepoBranch(repoId) ?? "main";
71
+ const pushResult = await this.git.push(repoId, localRepoPath, branch);
72
+ pushedRef = pushResult.ref;
73
+ pushedSha = pushResult.commitSha;
74
+ }
75
+ return {
76
+ repoId,
77
+ skillName,
78
+ commitSha,
79
+ pushedRef,
80
+ pushedSha
81
+ };
82
+ }
83
+ };
84
+ //#endregion
85
+ Object.defineProperty(exports, "SubmitClient", {
86
+ enumerable: true,
87
+ get: function() {
88
+ return SubmitClient;
89
+ }
90
+ });
91
+ Object.defineProperty(exports, "SubmitError", {
92
+ enumerable: true,
93
+ get: function() {
94
+ return SubmitError;
95
+ }
96
+ });
97
+
98
+ //# sourceMappingURL=submit-Dy0KTHzm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit-Dy0KTHzm.js","names":["getRepoDir","path","fs"],"sources":["../src/submit/types.ts","../src/submit/index.ts"],"sourcesContent":["/**\n * Skill & Agent v2 — SubmitClient Types (M4)\n *\n * Mirrors the server's POST /api/v1/skills/validate contract (M2\n * SubmitApi). Defined here as a separate types file so the test\n * fixtures + the client can both import without circular deps.\n */\n\n/** Reasons the server may deny a submission. */\nexport type DenyReason =\n\t| \"repo_not_writable\"\n\t| \"file_too_large\"\n\t| \"path_traversal\"\n\t| \"invalid_frontmatter\"\n\t| \"name_conflict\"\n\t/** Local-client-side errors that don't come from the server. */\n\t| \"network_error\"\n\t| \"write_error\"\n\t| \"commit_error\"\n\t| \"push_error\"\n\t| \"unknown\";\n\n/** Request payload. Identical to the server's SubmitValidationRequest. */\nexport interface SubmitValidationRequest {\n\trepoId: string;\n\tskillName: string;\n\tfiles: Array<{ path: string; content: string }>;\n}\n\n/** Response payload. Identical to the server's SubmitValidationResponse. */\nexport interface SubmitValidationResponse {\n\tallow: boolean;\n\treason?: DenyReason;\n\tdetail?: string;\n}\n\n/** Sentinel error thrown by SubmitClient.submit() / validate(). */\nexport class SubmitError extends Error {\n\treadonly reason: DenyReason;\n\treadonly detail: string;\n\treadonly status?: number;\n\n\tconstructor(reason: DenyReason, detail: string, options?: { status?: number }) {\n\t\tsuper(`submit failed (${reason}): ${detail}`);\n\t\tthis.name = \"SubmitError\";\n\t\tthis.reason = reason;\n\t\tthis.detail = detail;\n\t\tthis.status = options?.status;\n\t}\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { GitClient } from \"../git-client\";\nimport { getRepoDir } from \"../paths/userHome\";\nimport type { SkillFile } from \"../skill-store/types\";\nimport type { SubmitValidationRequest, SubmitValidationResponse } from \"./types\";\nimport { SubmitError } from \"./types\";\n\n// Re-export so consumers (bridge handlers, CLI commands) can detect\n// SubmitError via `instanceof` without reaching into the internal\n// `./types` module.\nexport { SubmitError } from \"./types\";\n\n/**\n * Skill & Agent v2 — SubmitClient (M4)\n *\n * SubmitClient orchestrates the \"validate then push\" flow described\n * in docs/architecture/skill-agent-v2-repo.md §5.7:\n *\n * 1. **validate** — POST the candidate files to the server's\n * `/api/v1/skills/validate` endpoint (5 deny reasons: repo_not_\n * writable, file_too_large, path_traversal, invalid_frontmatter,\n * name_conflict).\n * 2. **write** — materialize the files into the local repo clone at\n * `~/.serviceme/repos/<repoId>/skills/<name>/` (or `agents/`).\n * 3. **commit** — `git add . && git commit -m \"feat(skills): add <name>\"`.\n * 4. **push** — `git push origin <branch>` via the server proxy.\n *\n * The client is intentionally thin: it does NOT do its own validation\n * (the server is the gate), and it does NOT cache anything across\n * calls. The single source of truth for \"is this submission allowed?\"\n * is the server's validate endpoint.\n *\n * @see docs/architecture/skill-agent-v2-repo.md §5.7 SubmitClient\n */\n\nexport interface SubmitOptions {\n\t/** Override the server's validate URL. Defaults to `http://localhost:3000/api/v1`. */\n\tserverBaseUrl?: string;\n\t/** Override the branch to push. Defaults to the repo's `branch` field. */\n\tbranch?: string;\n\t/** Skip the actual push (for tests + dry-runs). When true, step 4 returns a synthetic PushResult. */\n\tskipPush?: boolean;\n}\n\nexport interface SubmitResult {\n\trepoId: string;\n\tskillName: string;\n\tcommitSha: string;\n\tpushedRef?: string;\n\tpushedSha?: string;\n}\n\nexport interface SubmitClientOptions {\n\tgitClient: GitClient;\n\t/** Lookup the default branch for a repo (config-driven). */\n\tgetRepoBranch?: (repoId: string) => string | undefined;\n\t/** HTTP fetch impl (defaults to the global `fetch`). */\n\tfetcher?: typeof fetch;\n\t/** Default server base URL when no override is supplied. */\n\tdefaultServerBaseUrl?: string;\n}\n\nexport class SubmitClient {\n\tprivate readonly git: GitClient;\n\tprivate readonly getRepoBranch: (repoId: string) => string | undefined;\n\tprivate readonly fetcher: typeof fetch;\n\tprivate readonly defaultServerBaseUrl: string;\n\n\tconstructor(opts: SubmitClientOptions) {\n\t\tthis.git = opts.gitClient;\n\t\tthis.getRepoBranch = opts.getRepoBranch ?? (() => undefined);\n\t\tthis.fetcher = opts.fetcher ?? (globalThis.fetch as typeof fetch);\n\t\tthis.defaultServerBaseUrl = opts.defaultServerBaseUrl ?? \"http://localhost:3000\";\n\t}\n\n\t/**\n\t * Validate-only path. Useful for the UI's \"Save Draft\" flow which\n\t * wants to surface validation errors without committing or pushing.\n\t */\n\tasync validate(req: SubmitValidationRequest): Promise<SubmitValidationResponse> {\n\t\tconst url = `${this.defaultServerBaseUrl}/api/v1/skills/validate`;\n\t\tconst res = await this.fetcher(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(req),\n\t\t});\n\t\tif (!res.ok) {\n\t\t\tthrow new SubmitError(\"network_error\", `validate request failed: HTTP ${res.status}`);\n\t\t}\n\t\treturn (await res.json()) as SubmitValidationResponse;\n\t}\n\n\t/**\n\t * Full submit pipeline. Throws `SubmitError` on:\n\t * - validate deny (reason echoed)\n\t * - network failure (network_error)\n\t * - local write failure\n\t * - commit/push failure\n\t */\n\tasync submit(\n\t\trepoId: string,\n\t\tskillName: string,\n\t\tfiles: SkillFile[],\n\t\topts: SubmitOptions = {}\n\t): Promise<SubmitResult> {\n\t\t// (1) Validate\n\t\tconst v = await this.validate({ repoId, skillName, files });\n\t\tif (!v.allow) {\n\t\t\tthrow new SubmitError(v.reason ?? \"unknown\", v.detail ?? \"validation denied\");\n\t\t}\n\n\t\t// (2) Write files into the local repo clone\n\t\tconst localRepoPath = getRepoDir(repoId);\n\t\tconst targetDir = path.join(localRepoPath, \"skills\", skillName);\n\t\tawait fs.mkdir(targetDir, { recursive: true });\n\t\tfor (const f of files) {\n\t\t\tconst full = path.join(targetDir, f.path);\n\t\t\tawait fs.mkdir(path.dirname(full), { recursive: true });\n\t\t\tconst tmp = `${full}.${process.pid}.${Date.now()}.tmp`;\n\t\t\tawait fs.writeFile(tmp, f.content, \"utf8\");\n\t\t\tawait fs.rename(tmp, full);\n\t\t}\n\n\t\t// (3) Commit (convention: `feat(skills): add <name>`)\n\t\tconst commitMessage = `feat(skills): add ${skillName}`;\n\t\tconst { commitSha } = await this.git.commit(localRepoPath, commitMessage);\n\n\t\t// (4) Push\n\t\tlet pushedRef: string | undefined;\n\t\tlet pushedSha: string | undefined;\n\t\tif (!opts.skipPush) {\n\t\t\tconst branch = opts.branch ?? this.getRepoBranch(repoId) ?? \"main\";\n\t\t\tconst pushResult = await this.git.push(repoId, localRepoPath, branch);\n\t\t\tpushedRef = pushResult.ref;\n\t\t\tpushedSha = pushResult.commitSha;\n\t\t}\n\n\t\treturn {\n\t\t\trepoId,\n\t\t\tskillName,\n\t\t\tcommitSha,\n\t\t\tpushedRef,\n\t\t\tpushedSha,\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;AAqCA,IAAa,cAAb,cAAiC,MAAM;CAKtC,YAAY,QAAoB,QAAgB,SAA+B;EAC9E,MAAM,kBAAkB,OAAO,KAAK,QAAQ;EAC5C,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,SAAS;EACd,KAAK,SAAS,SAAS;CACxB;AACD;;;ACcA,IAAa,eAAb,MAA0B;CAMzB,YAAY,MAA2B;EACtC,KAAK,MAAM,KAAK;EAChB,KAAK,gBAAgB,KAAK,wBAAwB,KAAA;EAClD,KAAK,UAAU,KAAK,WAAY,WAAW;EAC3C,KAAK,uBAAuB,KAAK,wBAAwB;CAC1D;;;;;CAMA,MAAM,SAAS,KAAiE;EAC/E,MAAM,MAAM,GAAG,KAAK,qBAAqB;EACzC,MAAM,MAAM,MAAM,KAAK,QAAQ,KAAK;GACnC,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU,GAAG;EACzB,CAAC;EACD,IAAI,CAAC,IAAI,IACR,MAAM,IAAI,YAAY,iBAAiB,iCAAiC,IAAI,QAAQ;EAErF,OAAQ,MAAM,IAAI,KAAK;CACxB;;;;;;;;CASA,MAAM,OACL,QACA,WACA,OACA,OAAsB,CAAC,GACC;EAExB,MAAM,IAAI,MAAM,KAAK,SAAS;GAAE;GAAQ;GAAW;EAAM,CAAC;EAC1D,IAAI,CAAC,EAAE,OACN,MAAM,IAAI,YAAY,EAAE,UAAU,WAAW,EAAE,UAAU,mBAAmB;EAI7E,MAAM,gBAAgBA,iBAAAA,WAAW,MAAM;EACvC,MAAM,YAAYC,UAAK,KAAK,eAAe,UAAU,SAAS;EAC9D,MAAMC,iBAAG,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;EAC7C,KAAK,MAAM,KAAK,OAAO;GACtB,MAAM,OAAOD,UAAK,KAAK,WAAW,EAAE,IAAI;GACxC,MAAMC,iBAAG,MAAMD,UAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;GACtD,MAAM,MAAM,GAAG,KAAK,GAAG,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;GACjD,MAAMC,iBAAG,UAAU,KAAK,EAAE,SAAS,MAAM;GACzC,MAAMA,iBAAG,OAAO,KAAK,IAAI;EAC1B;EAGA,MAAM,gBAAgB,qBAAqB;EAC3C,MAAM,EAAE,cAAc,MAAM,KAAK,IAAI,OAAO,eAAe,aAAa;EAGxE,IAAI;EACJ,IAAI;EACJ,IAAI,CAAC,KAAK,UAAU;GACnB,MAAM,SAAS,KAAK,UAAU,KAAK,cAAc,MAAM,KAAK;GAC5D,MAAM,aAAa,MAAM,KAAK,IAAI,KAAK,QAAQ,eAAe,MAAM;GACpE,YAAY,WAAW;GACvB,YAAY,WAAW;EACxB;EAEA,OAAO;GACN;GACA;GACA;GACA;GACA;EACD;CACD;AACD"}
package/dist/submit.js CHANGED
@@ -1,4 +1,4 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_submit = require("./submit-CltE6YOZ.js");
2
+ const require_submit = require("./submit-CW9schoc.js");
3
3
  exports.SubmitClient = require_submit.SubmitClient;
4
4
  exports.SubmitError = require_submit.SubmitError;
package/dist/submit.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as SubmitError, t as SubmitClient } from "./submit-Cg7wSa3x.mjs";
1
+ import { n as SubmitError, t as SubmitClient } from "./submit-BTdbGEAd.mjs";
2
2
  export { SubmitClient, SubmitError };