@kya-os/cli 1.5.9 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/commands/dco.d.ts +18 -0
  2. package/dist/commands/dco.d.ts.map +1 -0
  3. package/dist/commands/dco.js +107 -0
  4. package/dist/commands/dco.js.map +1 -0
  5. package/dist/commands/init.d.ts +2 -0
  6. package/dist/commands/init.d.ts.map +1 -1
  7. package/dist/commands/init.js +76 -7
  8. package/dist/commands/init.js.map +1 -1
  9. package/dist/commands/register.d.ts +2 -0
  10. package/dist/commands/register.d.ts.map +1 -1
  11. package/dist/commands/register.js +50 -0
  12. package/dist/commands/register.js.map +1 -1
  13. package/dist/index.js +7 -0
  14. package/dist/utils/dco/agent-metadata.d.ts +24 -0
  15. package/dist/utils/dco/agent-metadata.d.ts.map +1 -0
  16. package/dist/utils/dco/agent-metadata.js +46 -0
  17. package/dist/utils/dco/agent-metadata.js.map +1 -0
  18. package/dist/utils/dco/claude-config.d.ts +45 -0
  19. package/dist/utils/dco/claude-config.d.ts.map +1 -0
  20. package/dist/utils/dco/claude-config.js +112 -0
  21. package/dist/utils/dco/claude-config.js.map +1 -0
  22. package/dist/utils/dco/fs-safe.d.ts +14 -0
  23. package/dist/utils/dco/fs-safe.d.ts.map +1 -0
  24. package/dist/utils/dco/fs-safe.js +20 -0
  25. package/dist/utils/dco/fs-safe.js.map +1 -0
  26. package/dist/utils/dco/git-config.d.ts +47 -0
  27. package/dist/utils/dco/git-config.d.ts.map +1 -0
  28. package/dist/utils/dco/git-config.js +159 -0
  29. package/dist/utils/dco/git-config.js.map +1 -0
  30. package/dist/utils/dco/github.d.ts +49 -0
  31. package/dist/utils/dco/github.d.ts.map +1 -0
  32. package/dist/utils/dco/github.js +154 -0
  33. package/dist/utils/dco/github.js.map +1 -0
  34. package/dist/utils/dco/paths.d.ts +16 -0
  35. package/dist/utils/dco/paths.d.ts.map +1 -0
  36. package/dist/utils/dco/paths.js +27 -0
  37. package/dist/utils/dco/paths.js.map +1 -0
  38. package/dist/utils/dco/render.d.ts +4 -0
  39. package/dist/utils/dco/render.d.ts.map +1 -0
  40. package/dist/utils/dco/render.js +52 -0
  41. package/dist/utils/dco/render.js.map +1 -0
  42. package/dist/utils/dco/setup.d.ts +47 -0
  43. package/dist/utils/dco/setup.d.ts.map +1 -0
  44. package/dist/utils/dco/setup.js +740 -0
  45. package/dist/utils/dco/setup.js.map +1 -0
  46. package/dist/utils/dco/ssh-key.d.ts +43 -0
  47. package/dist/utils/dco/ssh-key.d.ts.map +1 -0
  48. package/dist/utils/dco/ssh-key.js +176 -0
  49. package/dist/utils/dco/ssh-key.js.map +1 -0
  50. package/dist/utils/dco/status.d.ts +12 -0
  51. package/dist/utils/dco/status.d.ts.map +1 -0
  52. package/dist/utils/dco/status.js +238 -0
  53. package/dist/utils/dco/status.js.map +1 -0
  54. package/package.json +6 -5
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Slugs come from .mcpi/agent.json, AGENT_SLUG, or an interactive prompt.
3
+ * The file-based sources are attacker-influenceable in a cloned repo, and the
4
+ * slug becomes a filename under the keys directory, so every source must pass
5
+ * the same shape check the interactive prompt enforces.
6
+ */
7
+ export declare const SLUG_PATTERN: RegExp;
8
+ export declare function isValidSlug(slug: string): boolean;
9
+ /** Directory holding converted SSH signing keys, always absolute. */
10
+ export declare function keysDir(): string;
11
+ /**
12
+ * Path for a slug's private key. Throws on slugs that fail validation so a
13
+ * crafted slug can never traverse outside the keys directory.
14
+ */
15
+ export declare function signingKeyPath(slug: string): string;
16
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/utils/dco/paths.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,eAAO,MAAM,YAAY,QAAyB,CAAC;AAEnD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,qEAAqE;AACrE,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOnD"}
@@ -0,0 +1,27 @@
1
+ import { homedir } from "os";
2
+ import { join, resolve } from "path";
3
+ /**
4
+ * Slugs come from .mcpi/agent.json, AGENT_SLUG, or an interactive prompt.
5
+ * The file-based sources are attacker-influenceable in a cloned repo, and the
6
+ * slug becomes a filename under the keys directory, so every source must pass
7
+ * the same shape check the interactive prompt enforces.
8
+ */
9
+ export const SLUG_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
10
+ export function isValidSlug(slug) {
11
+ return SLUG_PATTERN.test(slug);
12
+ }
13
+ /** Directory holding converted SSH signing keys, always absolute. */
14
+ export function keysDir() {
15
+ return resolve(process.env.MCPI_KEYS_DIR || join(homedir(), ".mcpi", "keys"));
16
+ }
17
+ /**
18
+ * Path for a slug's private key. Throws on slugs that fail validation so a
19
+ * crafted slug can never traverse outside the keys directory.
20
+ */
21
+ export function signingKeyPath(slug) {
22
+ if (!isValidSlug(slug)) {
23
+ throw new Error(`Invalid agent slug "${slug}": must match ${SLUG_PATTERN} (lowercase letters, numbers, dashes)`);
24
+ }
25
+ return join(keysDir(), slug);
26
+ }
27
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/utils/dco/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAErC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAEnD,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,OAAO;IACrB,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,uBAAuB,IAAI,iBAAiB,YAAY,uCAAuC,CAChG,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DcoSetupResult } from "./setup.js";
2
+ /** Human-readable summary of a setup run, shared by `mcpi dco setup` and the register/init funnel. */
3
+ export declare function renderSetupResult(result: DcoSetupResult): void;
4
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/utils/dco/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAiB7D,sGAAsG;AACtG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAkD9D"}
@@ -0,0 +1,52 @@
1
+ import chalk from "chalk";
2
+ function statusLabel(status) {
3
+ switch (status) {
4
+ case "done":
5
+ return chalk.green("done");
6
+ case "skipped":
7
+ return chalk.gray("skipped");
8
+ case "would-change":
9
+ return chalk.cyan("would change");
10
+ case "action-required":
11
+ return chalk.yellow("action required");
12
+ case "failed":
13
+ return chalk.red("failed");
14
+ }
15
+ }
16
+ /** Human-readable summary of a setup run, shared by `mcpi dco setup` and the register/init funnel. */
17
+ export function renderSetupResult(result) {
18
+ console.log("");
19
+ if (result.agent) {
20
+ console.log(` ${chalk.bold("Agent:")} ${result.agent.name} ${chalk.gray(`(${result.agent.did})`)}`);
21
+ }
22
+ if (result.human) {
23
+ console.log(` ${chalk.bold("Human:")} ${result.human.name} ${chalk.gray(`<${result.human.email}>`)}`);
24
+ }
25
+ console.log("");
26
+ const width = Math.max(...result.steps.map((s) => s.title.length));
27
+ for (const step of result.steps) {
28
+ console.log(` ${step.title.padEnd(width)} ${statusLabel(step.status)}`);
29
+ if (step.detail && step.status !== "done" && step.status !== "skipped") {
30
+ console.log(` ${" ".repeat(width)} ${chalk.gray(step.detail)}`);
31
+ }
32
+ }
33
+ console.log("");
34
+ if (result.metadataPersistWarning) {
35
+ console.log(chalk.yellow(` Note: could not cache agent metadata to .mcpi/agent.json (${result.metadataPersistWarning}); a later non-interactive run may prompt again.`));
36
+ }
37
+ const dryRun = result.steps.some((s) => s.status === "would-change");
38
+ if (!result.ok) {
39
+ console.log(chalk.red(" Setup finished with failures. See details above."));
40
+ }
41
+ else if (dryRun) {
42
+ console.log(chalk.cyan(" Dry run: nothing was written. Re-run without --dry-run to apply."));
43
+ }
44
+ else if (result.actionRequired) {
45
+ console.log(chalk.yellow(" Setup finished, but some steps need your action. See details above."));
46
+ }
47
+ else if (result.agent) {
48
+ console.log(chalk.green(` Commits are now signed with your agent's identity key and attributed to ${result.agent.name}.`));
49
+ }
50
+ console.log("");
51
+ }
52
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/utils/dco/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,SAAS,WAAW,CAAC,MAA4B;IAC/C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7B,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,KAAK,cAAc;YACjB,OAAO,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACpC,KAAK,iBAAiB;YACpB,OAAO,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACzC,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CACT,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,CACxF,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CACT,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,CAC1F,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1E,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACvE,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,MAAM,CAAC,sBAAsB,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CACV,+DAA+D,MAAM,CAAC,sBAAsB,kDAAkD,CAC/I,CACF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC;IACrE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAC/E,CAAC;SAAM,IAAI,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CACjF,CAAC;IACJ,CAAC;SAAM,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CAAC,uEAAuE,CAAC,CACtF,CAAC;IACJ,CAAC;SAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CACT,6EAA6E,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,CAClG,CACF,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { type GitIdentity } from "./git-config.js";
2
+ export type StepStatus = "done" | "skipped" | "failed" | "action-required" | "would-change";
3
+ export interface StepResult {
4
+ id: string;
5
+ title: string;
6
+ status: StepStatus;
7
+ detail?: string;
8
+ }
9
+ export interface DcoAgentInfo {
10
+ did: string;
11
+ name: string;
12
+ slug: string;
13
+ url: string;
14
+ email: string;
15
+ }
16
+ export interface DcoSetupOptions {
17
+ cwd?: string;
18
+ /** Write git config globally instead of repo-local. */
19
+ global?: boolean;
20
+ /** Report every change without writing anything. */
21
+ dryRun?: boolean;
22
+ skipGithub?: boolean;
23
+ skipClaude?: boolean;
24
+ /** Overwrite conflicting pre-existing signing configuration. */
25
+ force?: boolean;
26
+ /** Allow interactive prompts (agent name fallback, scope refresh). */
27
+ interactive?: boolean;
28
+ }
29
+ export interface DcoSetupResult {
30
+ ok: boolean;
31
+ actionRequired: boolean;
32
+ steps: StepResult[];
33
+ agent?: DcoAgentInfo;
34
+ human?: GitIdentity;
35
+ privateKeyPath?: string;
36
+ fingerprint?: string;
37
+ /** Set when persisting resolved metadata to .mcpi/agent.json failed (non-fatal). */
38
+ metadataPersistWarning?: string;
39
+ }
40
+ /**
41
+ * Orchestrates the full DCO/attribution setup. Steps run in order; the three
42
+ * foundation steps (preflight, identities, key material) abort the run when
43
+ * they fail, everything after degrades independently so one broken layer
44
+ * never blocks the others.
45
+ */
46
+ export declare function runDcoSetup(options?: DcoSetupOptions): Promise<DcoSetupResult>;
47
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/utils/dco/setup.ts"],"names":[],"mappings":"AAmBA,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AAmBzB,MAAM,MAAM,UAAU,GAClB,MAAM,GACN,SAAS,GACT,QAAQ,GACR,iBAAiB,GACjB,cAAc,CAAC;AAEnB,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oFAAoF;IACpF,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AA2HD;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CA8oBzB"}