@kya-os/cli 1.7.0 → 2.0.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 (161) hide show
  1. package/dist/commands/build.js +2 -2
  2. package/dist/commands/build.js.map +1 -1
  3. package/dist/commands/check.js +3 -3
  4. package/dist/commands/check.js.map +1 -1
  5. package/dist/commands/checkpoint-init.d.ts +32 -0
  6. package/dist/commands/checkpoint-init.d.ts.map +1 -0
  7. package/dist/commands/checkpoint-init.js +521 -0
  8. package/dist/commands/checkpoint-init.js.map +1 -0
  9. package/dist/commands/claim.js +2 -2
  10. package/dist/commands/claim.js.map +1 -1
  11. package/dist/commands/dco.d.ts +38 -1
  12. package/dist/commands/dco.d.ts.map +1 -1
  13. package/dist/commands/dco.js +180 -7
  14. package/dist/commands/dco.js.map +1 -1
  15. package/dist/commands/dev.js +1 -1
  16. package/dist/commands/dev.js.map +1 -1
  17. package/dist/commands/doctor.d.ts.map +1 -1
  18. package/dist/commands/doctor.js +18 -24
  19. package/dist/commands/doctor.js.map +1 -1
  20. package/dist/commands/env.js +6 -6
  21. package/dist/commands/env.js.map +1 -1
  22. package/dist/commands/identity.js +3 -3
  23. package/dist/commands/identity.js.map +1 -1
  24. package/dist/commands/init.d.ts.map +1 -1
  25. package/dist/commands/init.js +103 -65
  26. package/dist/commands/init.js.map +1 -1
  27. package/dist/commands/register.d.ts +1 -1
  28. package/dist/commands/register.d.ts.map +1 -1
  29. package/dist/commands/register.js +35 -7
  30. package/dist/commands/register.js.map +1 -1
  31. package/dist/commands/rotate.js +4 -4
  32. package/dist/commands/rotate.js.map +1 -1
  33. package/dist/commands/start.js +3 -3
  34. package/dist/commands/start.js.map +1 -1
  35. package/dist/commands/status.js +1 -1
  36. package/dist/commands/status.js.map +1 -1
  37. package/dist/commands/verify.js +6 -6
  38. package/dist/commands/verify.js.map +1 -1
  39. package/dist/dco.d.ts +4 -0
  40. package/dist/dco.d.ts.map +1 -0
  41. package/dist/dco.js +21 -0
  42. package/dist/dco.js.map +1 -0
  43. package/dist/index.js +18 -15
  44. package/dist/utils/checkpoint-api.d.ts +86 -0
  45. package/dist/utils/checkpoint-api.d.ts.map +1 -0
  46. package/dist/utils/checkpoint-api.js +196 -0
  47. package/dist/utils/checkpoint-api.js.map +1 -0
  48. package/dist/utils/checkpoint-env.d.ts +23 -0
  49. package/dist/utils/checkpoint-env.d.ts.map +1 -0
  50. package/dist/utils/checkpoint-env.js +59 -0
  51. package/dist/utils/checkpoint-env.js.map +1 -0
  52. package/dist/utils/checkpoint-scaffold.d.ts +61 -0
  53. package/dist/utils/checkpoint-scaffold.d.ts.map +1 -0
  54. package/dist/utils/checkpoint-scaffold.js +268 -0
  55. package/dist/utils/checkpoint-scaffold.js.map +1 -0
  56. package/dist/utils/cli-kit/browser.d.ts +24 -0
  57. package/dist/utils/cli-kit/browser.d.ts.map +1 -0
  58. package/dist/utils/cli-kit/browser.js +58 -0
  59. package/dist/utils/cli-kit/browser.js.map +1 -0
  60. package/dist/utils/cli-kit/claim-polling.d.ts +18 -0
  61. package/dist/utils/cli-kit/claim-polling.d.ts.map +1 -0
  62. package/dist/utils/{claim-polling.js → cli-kit/claim-polling.js} +19 -26
  63. package/dist/utils/cli-kit/claim-polling.js.map +1 -0
  64. package/dist/utils/cli-kit/diagnostics.d.ts +9 -0
  65. package/dist/utils/cli-kit/diagnostics.d.ts.map +1 -0
  66. package/dist/utils/cli-kit/diagnostics.js +11 -0
  67. package/dist/utils/cli-kit/diagnostics.js.map +1 -0
  68. package/dist/utils/cli-kit/fs-safe.d.ts +14 -0
  69. package/dist/utils/cli-kit/fs-safe.d.ts.map +1 -0
  70. package/dist/utils/cli-kit/fs-safe.js +20 -0
  71. package/dist/utils/cli-kit/fs-safe.js.map +1 -0
  72. package/dist/utils/cli-kit/index.d.ts +15 -0
  73. package/dist/utils/cli-kit/index.d.ts.map +1 -0
  74. package/dist/utils/cli-kit/index.js +10 -0
  75. package/dist/utils/cli-kit/index.js.map +1 -0
  76. package/dist/utils/cli-kit/json-file.d.ts +21 -0
  77. package/dist/utils/cli-kit/json-file.d.ts.map +1 -0
  78. package/dist/utils/cli-kit/json-file.js +51 -0
  79. package/dist/utils/cli-kit/json-file.js.map +1 -0
  80. package/dist/utils/cli-kit/marker-block.d.ts +26 -0
  81. package/dist/utils/cli-kit/marker-block.d.ts.map +1 -0
  82. package/dist/utils/cli-kit/marker-block.js +61 -0
  83. package/dist/utils/cli-kit/marker-block.js.map +1 -0
  84. package/dist/utils/cli-kit/paths.d.ts +15 -0
  85. package/dist/utils/cli-kit/paths.d.ts.map +1 -0
  86. package/dist/utils/cli-kit/paths.js +21 -0
  87. package/dist/utils/cli-kit/paths.js.map +1 -0
  88. package/dist/utils/cli-kit/secure-storage.d.ts +14 -0
  89. package/dist/utils/cli-kit/secure-storage.d.ts.map +1 -0
  90. package/dist/utils/cli-kit/secure-storage.js +20 -0
  91. package/dist/utils/cli-kit/secure-storage.js.map +1 -0
  92. package/dist/utils/cli-kit/step-report.d.ts +16 -0
  93. package/dist/utils/cli-kit/step-report.d.ts.map +1 -0
  94. package/dist/utils/cli-kit/step-report.js +36 -0
  95. package/dist/utils/cli-kit/step-report.js.map +1 -0
  96. package/dist/utils/dco/agent-metadata.d.ts +1 -1
  97. package/dist/utils/dco/agent-metadata.js +1 -1
  98. package/dist/utils/dco/agent-metadata.js.map +1 -1
  99. package/dist/utils/dco/claude-config.d.ts +18 -8
  100. package/dist/utils/dco/claude-config.d.ts.map +1 -1
  101. package/dist/utils/dco/claude-config.js +33 -79
  102. package/dist/utils/dco/claude-config.js.map +1 -1
  103. package/dist/utils/dco/dispatch.d.ts +59 -0
  104. package/dist/utils/dco/dispatch.d.ts.map +1 -0
  105. package/dist/utils/dco/dispatch.js +332 -0
  106. package/dist/utils/dco/dispatch.js.map +1 -0
  107. package/dist/utils/dco/git-config.d.ts.map +1 -1
  108. package/dist/utils/dco/git-config.js +5 -3
  109. package/dist/utils/dco/git-config.js.map +1 -1
  110. package/dist/utils/dco/github.d.ts +8 -0
  111. package/dist/utils/dco/github.d.ts.map +1 -1
  112. package/dist/utils/dco/github.js +11 -0
  113. package/dist/utils/dco/github.js.map +1 -1
  114. package/dist/utils/dco/paths.d.ts +1 -8
  115. package/dist/utils/dco/paths.d.ts.map +1 -1
  116. package/dist/utils/dco/paths.js +3 -12
  117. package/dist/utils/dco/paths.js.map +1 -1
  118. package/dist/utils/dco/render.d.ts +1 -1
  119. package/dist/utils/dco/render.d.ts.map +1 -1
  120. package/dist/utils/dco/render.js +4 -21
  121. package/dist/utils/dco/render.js.map +1 -1
  122. package/dist/utils/dco/resolve-agent.d.ts +54 -0
  123. package/dist/utils/dco/resolve-agent.d.ts.map +1 -0
  124. package/dist/utils/dco/resolve-agent.js +164 -0
  125. package/dist/utils/dco/resolve-agent.js.map +1 -0
  126. package/dist/utils/dco/setup.d.ts +10 -7
  127. package/dist/utils/dco/setup.d.ts.map +1 -1
  128. package/dist/utils/dco/setup.js +304 -202
  129. package/dist/utils/dco/setup.js.map +1 -1
  130. package/dist/utils/dco/ssh-key.d.ts +13 -0
  131. package/dist/utils/dco/ssh-key.d.ts.map +1 -1
  132. package/dist/utils/dco/ssh-key.js +21 -0
  133. package/dist/utils/dco/ssh-key.js.map +1 -1
  134. package/dist/utils/dco/status.d.ts +1 -1
  135. package/dist/utils/dco/status.d.ts.map +1 -1
  136. package/dist/utils/dco/status.js +3 -3
  137. package/dist/utils/dco/status.js.map +1 -1
  138. package/dist/utils/dco/verify.d.ts +114 -0
  139. package/dist/utils/dco/verify.d.ts.map +1 -0
  140. package/dist/utils/dco/verify.js +383 -0
  141. package/dist/utils/dco/verify.js.map +1 -0
  142. package/dist/utils/gitignore.d.ts +17 -0
  143. package/dist/utils/gitignore.d.ts.map +1 -0
  144. package/dist/utils/gitignore.js +40 -0
  145. package/dist/utils/gitignore.js.map +1 -0
  146. package/dist/utils/identity-heal.d.ts +16 -0
  147. package/dist/utils/identity-heal.d.ts.map +1 -0
  148. package/dist/utils/identity-heal.js +37 -0
  149. package/dist/utils/identity-heal.js.map +1 -0
  150. package/dist/utils/poll.d.ts +50 -0
  151. package/dist/utils/poll.d.ts.map +1 -0
  152. package/dist/utils/poll.js +73 -0
  153. package/dist/utils/poll.js.map +1 -0
  154. package/package.json +4 -3
  155. package/dist/utils/claim-polling.d.ts +0 -21
  156. package/dist/utils/claim-polling.d.ts.map +0 -1
  157. package/dist/utils/claim-polling.js.map +0 -1
  158. package/dist/utils/dco/fs-safe.d.ts +0 -14
  159. package/dist/utils/dco/fs-safe.d.ts.map +0 -1
  160. package/dist/utils/dco/fs-safe.js +0 -20
  161. package/dist/utils/dco/fs-safe.js.map +0 -1
@@ -0,0 +1,268 @@
1
+ /**
2
+ * Detect-layer scaffolding for `kya-os checkpoint init` (KYA-1037).
3
+ *
4
+ * Maps the repo's detected platform onto one of the three Detect layers
5
+ * Checkpoint ships (Next.js middleware, Express snippet, the keyless
6
+ * Beacon), and, for Next.js, installs the SDK and writes middleware.ts
7
+ * directly (no shelling out to another package's setup script, see the
8
+ * comment on scaffoldNextjs for why). Every install/write step is behind
9
+ * an injectable ScaffoldRunner, so tests never spawn a real process or
10
+ * touch the real filesystem.
11
+ */
12
+ import { execFileSync } from "child_process";
13
+ import { existsSync, readFileSync, writeFileSync } from "fs";
14
+ import { basename, join } from "path";
15
+ import { detectPlatform } from "./platform-detector.js";
16
+ /** True if package.json declares a `next` dependency, checked directly rather than through detectPlatform's derived fields. */
17
+ function hasNextDependency(projectRoot) {
18
+ const pkgPath = join(projectRoot, "package.json");
19
+ if (!existsSync(pkgPath))
20
+ return false;
21
+ try {
22
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
23
+ return Boolean(pkg.dependencies?.next || pkg.devDependencies?.next);
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ /**
30
+ * Maps `detectPlatform()`'s general-purpose platform/framework detection
31
+ * onto the three layers Checkpoint's `init` can scaffold. A repo with no
32
+ * `package.json` at all (a plain HTML/CSS/JS site) maps to `static`; one
33
+ * with a `package.json` but no recognized framework maps to `unknown`,
34
+ * both get the same keyless Beacon snippet, but the distinction is kept
35
+ * server-side as a hint for future support triage.
36
+ *
37
+ * Checks package.json's own `next` dependency directly, not just
38
+ * platformInfo's derived platform/framework fields: detectPlatform()
39
+ * unconditionally overwrites both to 'cloudflare'/'cloudflare-workers'
40
+ * whenever wrangler.toml/json exists, even for a Next.js repo deployed
41
+ * there, silently losing the nextjs detection underneath it.
42
+ */
43
+ export function detectCheckpointFramework(projectRoot = process.cwd(), platformInfo = detectPlatform(projectRoot)) {
44
+ if (platformInfo.framework === "nextjs" ||
45
+ platformInfo.platform === "nextjs" ||
46
+ platformInfo.platform === "vercel" ||
47
+ hasNextDependency(projectRoot)) {
48
+ return "nextjs";
49
+ }
50
+ if (platformInfo.framework === "express") {
51
+ return "express";
52
+ }
53
+ return existsSync(join(projectRoot, "package.json")) ? "unknown" : "static";
54
+ }
55
+ export function checkpointFrameworkLabel(framework) {
56
+ switch (framework) {
57
+ case "nextjs":
58
+ return "Next.js app";
59
+ case "express":
60
+ return "Express app";
61
+ case "static":
62
+ return "static site";
63
+ case "unknown":
64
+ default:
65
+ return "project";
66
+ }
67
+ }
68
+ /** Best-effort repo name: git remote slug, else the directory name. */
69
+ export function detectRepoName(projectRoot = process.cwd()) {
70
+ try {
71
+ const remote = execFileSync("git", ["config", "--get", "remote.origin.url"], {
72
+ cwd: projectRoot,
73
+ encoding: "utf-8",
74
+ stdio: ["ignore", "pipe", "ignore"],
75
+ }).trim();
76
+ const match = remote.match(/([^/:]+?)(\.git)?$/);
77
+ if (match?.[1])
78
+ return match[1];
79
+ }
80
+ catch {
81
+ // Not a git repo, or no `origin` remote, fall through to the directory name.
82
+ }
83
+ const dir = basename(projectRoot);
84
+ return dir || undefined;
85
+ }
86
+ /** Best-effort domain hint from `package.json`'s `homepage` field. */
87
+ export function detectDomainHint(projectRoot = process.cwd()) {
88
+ const pkgPath = join(projectRoot, "package.json");
89
+ if (!existsSync(pkgPath))
90
+ return undefined;
91
+ try {
92
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
93
+ if (typeof pkg.homepage === "string" && pkg.homepage) {
94
+ try {
95
+ return new URL(pkg.homepage).hostname;
96
+ }
97
+ catch {
98
+ return undefined;
99
+ }
100
+ }
101
+ }
102
+ catch {
103
+ // Malformed package.json, no hint, not a fatal error for `init`.
104
+ }
105
+ return undefined;
106
+ }
107
+ /** The real runner: shells out via execFileSync (swallowing spawn errors into a non-zero status) and touches the real filesystem. */
108
+ export const defaultScaffoldRunner = {
109
+ run(command, args, cwd) {
110
+ try {
111
+ execFileSync(command, args, {
112
+ cwd,
113
+ stdio: "ignore",
114
+ // npm/pnpm/yarn/npx resolve to .cmd shims on Windows; execFileSync
115
+ // without shell:true throws ENOENT/EINVAL there (this is also the
116
+ // shape Node's CVE-2024-27980 .bat/.cmd fix requires), so every
117
+ // install would otherwise "fail" for Windows users even when the
118
+ // tool is genuinely on PATH.
119
+ shell: process.platform === "win32",
120
+ });
121
+ return { status: 0 };
122
+ }
123
+ catch {
124
+ return { status: 1 };
125
+ }
126
+ },
127
+ writeFile(path, content) {
128
+ writeFileSync(path, content, "utf-8");
129
+ },
130
+ fileExists(path) {
131
+ return existsSync(path);
132
+ },
133
+ };
134
+ const NEXTJS_PACKAGE = "@kya-os/checkpoint-nextjs";
135
+ const EXPRESS_PACKAGE = "@kya-os/checkpoint-express";
136
+ const BEACON_PACKAGE = "@kya-os/checkpoint-beacon";
137
+ const BEACON_CDN_URL = `https://cdn.jsdelivr.net/npm/${BEACON_PACKAGE}/dist/beacon.min.js`;
138
+ /** `npm install <pkg>` / `pnpm add <pkg>` / `yarn add <pkg>`, matching the target repo's package manager. */
139
+ function installCommand(packageManager, pkg) {
140
+ if (packageManager === "pnpm")
141
+ return { command: "pnpm", args: ["add", pkg] };
142
+ if (packageManager === "yarn")
143
+ return { command: "yarn", args: ["add", pkg] };
144
+ return { command: "npm", args: ["install", pkg] };
145
+ }
146
+ export const NEXTJS_MANUAL_SNIPPET = `import { createMiddleware } from '${NEXTJS_PACKAGE}';
147
+
148
+ export default createMiddleware({
149
+ apiKey: process.env.CHECKPOINT_API_KEY!,
150
+ projectId: process.env.CHECKPOINT_PROJECT_ID!,
151
+ // The SDK default is 'enforce', which is inert without a deployed
152
+ // policy, spelled out explicitly so flipping it later is a one-word diff.
153
+ enforcementMode: 'observe',
154
+ });
155
+
156
+ export const config = { matcher: '/((?!_next/static|_next/image|favicon.ico).*)' };
157
+ `;
158
+ export const EXPRESS_SNIPPET = `import { withCheckpoint } from '${EXPRESS_PACKAGE}';
159
+
160
+ app.use(withCheckpoint({
161
+ apiKey: process.env.CHECKPOINT_API_KEY!,
162
+ projectId: process.env.CHECKPOINT_PROJECT_ID!,
163
+ }));
164
+ `;
165
+ export function beaconSnippet(projectId) {
166
+ // The exact CDN Usage snippet from checkpoint-beacon's own README:
167
+ // loads the global CheckpointBeacon constructor from jsDelivr and
168
+ // instantiates it inline. Keyless by design (credentials.mdx), the
169
+ // Beacon takes only a projectId and nothing else credential-shaped, so
170
+ // no CHECKPOINT_API_KEY here.
171
+ return `<script src="${BEACON_CDN_URL}"></script>
172
+ <script>
173
+ const beacon = new CheckpointBeacon({ projectId: '${projectId}' });
174
+ beacon.collect('pageview');
175
+ </script>\n`;
176
+ }
177
+ const DOCS_LINK = "https://docs.kya-os.ai/checkpoint/install";
178
+ /** Next.js's own convention: middleware.ts lives at the project root, or inside src/ when the app uses a src directory. */
179
+ function middlewareTargetPath(projectRoot, runner) {
180
+ const usesSrcDir = runner.fileExists(join(projectRoot, "src", "app")) ||
181
+ runner.fileExists(join(projectRoot, "src", "pages"));
182
+ return usesSrcDir
183
+ ? join(projectRoot, "src", "middleware.ts")
184
+ : join(projectRoot, "middleware.ts");
185
+ }
186
+ /** Any of the file locations/extensions Next.js recognizes as middleware, already present. */
187
+ function existingMiddlewarePath(projectRoot, runner) {
188
+ const candidates = [
189
+ join(projectRoot, "middleware.ts"),
190
+ join(projectRoot, "middleware.js"),
191
+ join(projectRoot, "src", "middleware.ts"),
192
+ join(projectRoot, "src", "middleware.js"),
193
+ ];
194
+ return candidates.find((path) => runner.fileExists(path));
195
+ }
196
+ export function scaffoldNextjs(projectRoot, packageManager, runner = defaultScaffoldRunner) {
197
+ const install = installCommand(packageManager, NEXTJS_PACKAGE);
198
+ const installResult = runner.run(install.command, install.args, projectRoot);
199
+ if (installResult.status !== 0) {
200
+ return {
201
+ framework: "nextjs",
202
+ installed: false,
203
+ setupRan: false,
204
+ message: `Could not install ${NEXTJS_PACKAGE} automatically. Add it yourself, then:\n\n${NEXTJS_MANUAL_SNIPPET}\nDocs: ${DOCS_LINK}`,
205
+ };
206
+ }
207
+ // Writes middleware.ts directly instead of shelling out to
208
+ // checkpoint-setup-edge (@kya-os/checkpoint-nextjs's own bin): that bin
209
+ // hard-exits 1 unless the LEGACY node_modules/@kya-os/agentshield-nextjs
210
+ // path exists, which this command never installs, so it always failed;
211
+ // even a success would have written the legacy offline middleware that
212
+ // never reads CHECKPOINT_API_KEY/CHECKPOINT_PROJECT_ID; and invoking a
213
+ // bare unscoped name via npx can silently fetch and run a squatted
214
+ // package from the public registry on a .bin-layout miss (Yarn PnP,
215
+ // among others). Writing the file ourselves avoids all three.
216
+ const existing = existingMiddlewarePath(projectRoot, runner);
217
+ if (existing) {
218
+ return {
219
+ framework: "nextjs",
220
+ installed: true,
221
+ setupRan: false,
222
+ message: `Installed ${NEXTJS_PACKAGE}. ${existing} already exists, so it was left untouched, wire it up yourself:\n\n${NEXTJS_MANUAL_SNIPPET}\nDocs: ${DOCS_LINK}`,
223
+ };
224
+ }
225
+ const targetPath = middlewareTargetPath(projectRoot, runner);
226
+ try {
227
+ runner.writeFile(targetPath, NEXTJS_MANUAL_SNIPPET);
228
+ }
229
+ catch {
230
+ return {
231
+ framework: "nextjs",
232
+ installed: true,
233
+ setupRan: false,
234
+ message: `${NEXTJS_PACKAGE} installed, but writing middleware.ts failed. Wire it up yourself:\n\n${NEXTJS_MANUAL_SNIPPET}\nDocs: ${DOCS_LINK}`,
235
+ };
236
+ }
237
+ return {
238
+ framework: "nextjs",
239
+ installed: true,
240
+ setupRan: true,
241
+ message: `Installed ${NEXTJS_PACKAGE} and wrote ${targetPath}.`,
242
+ };
243
+ }
244
+ export function scaffoldExpress(projectRoot, packageManager, runner = defaultScaffoldRunner) {
245
+ const install = installCommand(packageManager, EXPRESS_PACKAGE);
246
+ const installResult = runner.run(install.command, install.args, projectRoot);
247
+ const message = installResult.status === 0
248
+ ? `Installed ${EXPRESS_PACKAGE}. Wire it into your app:\n\n${EXPRESS_SNIPPET}`
249
+ : `Could not install ${EXPRESS_PACKAGE} automatically. Add it yourself, then:\n\n${EXPRESS_SNIPPET}\nDocs: ${DOCS_LINK}`;
250
+ return {
251
+ framework: "express",
252
+ installed: installResult.status === 0,
253
+ // Express scaffolding never edits the target app's source (per plan);
254
+ // printing the snippet IS the setup step, so it "ran" whenever we got
255
+ // far enough to print it, which is always.
256
+ setupRan: true,
257
+ message,
258
+ };
259
+ }
260
+ export function scaffoldBeacon(projectId, framework) {
261
+ return {
262
+ framework,
263
+ installed: false,
264
+ setupRan: true,
265
+ message: `Add this before the closing </head> tag:\n\n${beaconSnippet(projectId)}`,
266
+ };
267
+ }
268
+ //# sourceMappingURL=checkpoint-scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint-scaffold.js","sourceRoot":"","sources":["../../src/utils/checkpoint-scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface OpenUrlInBrowserOptions {
2
+ /** Wait for the user to press Enter before opening, when attached to a TTY. Default true. */
3
+ waitForEnter?: boolean;
4
+ /** Max time to wait for Enter, in ms. Default 30000. */
5
+ enterTimeoutMs?: number;
6
+ }
7
+ export interface OpenUrlInBrowserResult {
8
+ opened: boolean;
9
+ /** Present when `opened` is false: "non-tty", or the `open()` failure message. */
10
+ reason?: string;
11
+ }
12
+ /**
13
+ * Open a URL in the user's browser, but only when attached to an
14
+ * interactive terminal.
15
+ *
16
+ * A non-TTY run (CI, Docker, a piped process) has no user present to
17
+ * consent to a browser launching, so this never attempts to open one
18
+ * there — it returns immediately with `{ opened: false, reason: "non-tty" }`
19
+ * so the caller can print the URL instead. Auto-opening anyway after a
20
+ * short delay was a real bug in the code this replaces: a non-interactive
21
+ * `init` run would pop a browser window with no user watching for it.
22
+ */
23
+ export declare function openUrlInBrowser(url: string, options?: OpenUrlInBrowserOptions): Promise<OpenUrlInBrowserResult>;
24
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/utils/cli-kit/browser.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,uBAAuB;IACtC,6FAA6F;IAC7F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,OAAO,CAAC;IAChB,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CA+CjC"}
@@ -0,0 +1,58 @@
1
+ import chalk from "chalk";
2
+ /**
3
+ * Open a URL in the user's browser, but only when attached to an
4
+ * interactive terminal.
5
+ *
6
+ * A non-TTY run (CI, Docker, a piped process) has no user present to
7
+ * consent to a browser launching, so this never attempts to open one
8
+ * there — it returns immediately with `{ opened: false, reason: "non-tty" }`
9
+ * so the caller can print the URL instead. Auto-opening anyway after a
10
+ * short delay was a real bug in the code this replaces: a non-interactive
11
+ * `init` run would pop a browser window with no user watching for it.
12
+ */
13
+ export async function openUrlInBrowser(url, options = {}) {
14
+ const { waitForEnter = true, enterTimeoutMs = 30000 } = options;
15
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
16
+ return { opened: false, reason: "non-tty" };
17
+ }
18
+ if (waitForEnter) {
19
+ console.log(` ${chalk.gray("Press Enter to open in browser...")}`);
20
+ // The two arms must cancel each other: a leaked timer would later fire
21
+ // process.stdin.pause() and freeze any interactive prompt on screen at
22
+ // that moment.
23
+ const cleanup = () => {
24
+ process.stdin.pause();
25
+ process.stdin.removeAllListeners("data");
26
+ };
27
+ let enterTimeout;
28
+ await Promise.race([
29
+ new Promise((resolve) => {
30
+ process.stdin.once("data", () => {
31
+ if (enterTimeout)
32
+ clearTimeout(enterTimeout);
33
+ cleanup();
34
+ resolve();
35
+ });
36
+ process.stdin.resume();
37
+ }),
38
+ new Promise((resolve) => {
39
+ enterTimeout = setTimeout(() => {
40
+ cleanup();
41
+ resolve();
42
+ }, enterTimeoutMs);
43
+ }),
44
+ ]);
45
+ }
46
+ try {
47
+ const open = (await import("open")).default;
48
+ await open(url);
49
+ return { opened: true };
50
+ }
51
+ catch (error) {
52
+ return {
53
+ opened: false,
54
+ reason: error instanceof Error ? error.message : String(error),
55
+ };
56
+ }
57
+ }
58
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../src/utils/cli-kit/browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAe1B;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,UAAmC,EAAE;IAErC,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,cAAc,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEhE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC9C,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,EAAE,CAAC,CAAC;QAErE,uEAAuE;QACvE,uEAAuE;QACvE,eAAe;QACf,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC,CAAC;QAEF,IAAI,YAAwC,CAAC;QAC7C,MAAM,OAAO,CAAC,IAAI,CAAC;YACjB,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAC5B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;oBAC9B,IAAI,YAAY;wBAAE,YAAY,CAAC,YAAY,CAAC,CAAC;oBAC7C,OAAO,EAAE,CAAC;oBACV,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACzB,CAAC,CAAC;YACF,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAC5B,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC7B,OAAO,EAAE,CAAC;oBACV,OAAO,EAAE,CAAC;gBACZ,CAAC,EAAE,cAAc,CAAC,CAAC;YACrB,CAAC,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAC5C,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC/D,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface ClaimPollingOptions {
2
+ verbose?: boolean;
3
+ maxAttempts?: number;
4
+ pollInterval?: number;
5
+ }
6
+ /**
7
+ * Poll a claim-status endpoint until claimed, timed out, or interrupted.
8
+ *
9
+ * Endpoint-agnostic: `endpoint` is the base URL and `statusPath` builds the
10
+ * per-check path from it, so a caller can point this at knowthat.ai's
11
+ * `/api/agents/:slug` today or a Checkpoint `/api/v1/cli/claim-status`
12
+ * tomorrow without forking the polling logic. A response is "claimed" when
13
+ * `isClaimed` returns true for its parsed JSON body.
14
+ *
15
+ * Returns true when claimed, false on timeout or user interrupt (Ctrl+C).
16
+ */
17
+ export declare function pollForClaimStatus(statusUrl: string, isClaimed: (body: unknown) => boolean, options?: ClaimPollingOptions): Promise<boolean>;
18
+ //# sourceMappingURL=claim-polling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claim-polling.d.ts","sourceRoot":"","sources":["../../../src/utils/cli-kit/claim-polling.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,EACrC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,OAAO,CAAC,CA4FlB"}
@@ -1,17 +1,17 @@
1
1
  import chalk from "chalk";
2
2
  import ora from "ora";
3
3
  /**
4
- * Poll for agent claim status
4
+ * Poll a claim-status endpoint until claimed, timed out, or interrupted.
5
5
  *
6
- * Polls the KTA API to check if an agent has been claimed.
7
- * Returns true when claimed, false if timeout or interrupted.
6
+ * Endpoint-agnostic: `endpoint` is the base URL and `statusPath` builds the
7
+ * per-check path from it, so a caller can point this at knowthat.ai's
8
+ * `/api/agents/:slug` today or a Checkpoint `/api/v1/cli/claim-status`
9
+ * tomorrow without forking the polling logic. A response is "claimed" when
10
+ * `isClaimed` returns true for its parsed JSON body.
8
11
  *
9
- * @param agentName - The agent's name (slug) to check
10
- * @param did - The agent's DID
11
- * @param endpoint - API endpoint URL (default: https://knowthat.ai)
12
- * @param options - Polling options
12
+ * Returns true when claimed, false on timeout or user interrupt (Ctrl+C).
13
13
  */
14
- export async function pollForClaimStatus(agentName, did, endpoint = "https://knowthat.ai", options = {}) {
14
+ export async function pollForClaimStatus(statusUrl, isClaimed, options = {}) {
15
15
  const { verbose = false, maxAttempts = 60, // 5 minutes at 5 second intervals
16
16
  pollInterval = 5000, // 5 seconds
17
17
  } = options;
@@ -26,12 +26,11 @@ export async function pollForClaimStatus(agentName, did, endpoint = "https://kno
26
26
  skipPolling = true;
27
27
  spinner.warn(chalk.yellow("⏭️ Skipping claim check..."));
28
28
  };
29
- process.on('SIGINT', handleInterrupt);
29
+ process.on("SIGINT", handleInterrupt);
30
30
  try {
31
31
  while (attempts < maxAttempts && !skipPolling) {
32
32
  try {
33
- const statusCheckUrl = new URL("/api/agents/" + encodeURIComponent(agentName), endpoint);
34
- const response = await fetch(statusCheckUrl.toString(), {
33
+ const response = await fetch(statusUrl, {
35
34
  method: "GET",
36
35
  headers: {
37
36
  "User-Agent": "kya-os-cli",
@@ -41,25 +40,19 @@ export async function pollForClaimStatus(agentName, did, endpoint = "https://kno
41
40
  if (response.ok) {
42
41
  const data = await response.json();
43
42
  if (verbose) {
44
- console.log(chalk.gray(`\n[DEBUG] Agent status:`));
43
+ console.log(chalk.gray(`\n[DEBUG] Claim status:`));
45
44
  console.log(chalk.gray(JSON.stringify(data, null, 2)));
46
45
  }
47
- // Check if claimed (multiple possible indicators)
48
- if (data &&
49
- (data.userId ||
50
- data.status === 'active' ||
51
- data.owner ||
52
- data.claimedAt ||
53
- data.isDraft === false)) {
54
- spinner.succeed(chalk.green("✅ Agent claimed successfully!"));
55
- process.removeListener('SIGINT', handleInterrupt);
46
+ if (isClaimed(data)) {
47
+ spinner.succeed(chalk.green("✅ Claimed successfully!"));
48
+ process.removeListener("SIGINT", handleInterrupt);
56
49
  return true;
57
50
  }
58
51
  }
59
52
  else if (response.status === 404) {
60
- // Agent not found - might not be indexed yet, continue polling
53
+ // Not found yet - might not be indexed yet, continue polling
61
54
  if (verbose) {
62
- console.log(chalk.gray(`\n[DEBUG] Agent not found yet (404), continuing...`));
55
+ console.log(chalk.gray(`\n[DEBUG] Not found yet (404), continuing...`));
63
56
  }
64
57
  }
65
58
  }
@@ -79,17 +72,17 @@ export async function pollForClaimStatus(agentName, did, endpoint = "https://kno
79
72
  .toString()
80
73
  .padStart(2, "0")} remaining)`;
81
74
  }
82
- process.removeListener('SIGINT', handleInterrupt);
75
+ process.removeListener("SIGINT", handleInterrupt);
83
76
  if (skipPolling) {
84
77
  console.log(chalk.gray("\n You can complete the claim process later."));
85
78
  return false;
86
79
  }
87
80
  spinner.warn(chalk.yellow("⏱️ Claim check timed out"));
88
- console.log(chalk.gray("\n Don't worry! You can still claim your agent."));
81
+ console.log(chalk.gray("\n Don't worry! You can still complete the claim."));
89
82
  return false;
90
83
  }
91
84
  catch (error) {
92
- process.removeListener('SIGINT', handleInterrupt);
85
+ process.removeListener("SIGINT", handleInterrupt);
93
86
  spinner.fail("Claim polling failed");
94
87
  throw error;
95
88
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claim-polling.js","sourceRoot":"","sources":["../../../src/utils/cli-kit/claim-polling.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Run a named set of async checks in parallel and collect their results
3
+ * under the same keys, e.g. `doctor`-style commands that report several
4
+ * independent health checks (packages, connectivity, config, ...) at once.
5
+ */
6
+ export declare function runDiagnosticChecks<T extends Record<string, unknown>>(checks: {
7
+ [K in keyof T]: () => Promise<T[K]>;
8
+ }): Promise<T>;
9
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../src/utils/cli-kit/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,MAAM,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAC9C,OAAO,CAAC,CAAC,CAAC,CAIZ"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Run a named set of async checks in parallel and collect their results
3
+ * under the same keys, e.g. `doctor`-style commands that report several
4
+ * independent health checks (packages, connectivity, config, ...) at once.
5
+ */
6
+ export async function runDiagnosticChecks(checks) {
7
+ const keys = Object.keys(checks);
8
+ const values = await Promise.all(keys.map((key) => checks[key]()));
9
+ return Object.fromEntries(keys.map((key, i) => [key, values[i]]));
10
+ }
11
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../../src/utils/cli-kit/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAA+C;IAE/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAgB,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnE,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAM,CAAC;AACzE,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Atomic, symlink-safe file replace.
3
+ *
4
+ * The destination and its temp sibling may live in an untrusted working
5
+ * tree (e.g. a cloned repo). A tracked symlink planted at the predictable
6
+ * `<path>.mcpi-tmp` sibling would otherwise make a plain writeFileSync
7
+ * follow it and clobber an arbitrary file the caller can write. So: unlink
8
+ * any pre-existing temp (rmSync removes the link itself, never its
9
+ * target), then create it with O_EXCL (`wx`) so a planted or racing
10
+ * symlink makes the write fail closed instead of being followed.
11
+ * renameSync replaces the destination without following a symlink there.
12
+ */
13
+ export declare function writeFileAtomicSafe(path: string, content: string, mode?: number): void;
14
+ //# sourceMappingURL=fs-safe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-safe.d.ts","sourceRoot":"","sources":["../../../src/utils/cli-kit/fs-safe.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,SAAQ,GACX,IAAI,CAKN"}
@@ -0,0 +1,20 @@
1
+ import { renameSync, rmSync, writeFileSync } from "fs";
2
+ /**
3
+ * Atomic, symlink-safe file replace.
4
+ *
5
+ * The destination and its temp sibling may live in an untrusted working
6
+ * tree (e.g. a cloned repo). A tracked symlink planted at the predictable
7
+ * `<path>.mcpi-tmp` sibling would otherwise make a plain writeFileSync
8
+ * follow it and clobber an arbitrary file the caller can write. So: unlink
9
+ * any pre-existing temp (rmSync removes the link itself, never its
10
+ * target), then create it with O_EXCL (`wx`) so a planted or racing
11
+ * symlink makes the write fail closed instead of being followed.
12
+ * renameSync replaces the destination without following a symlink there.
13
+ */
14
+ export function writeFileAtomicSafe(path, content, mode = 0o644) {
15
+ const tempPath = `${path}.mcpi-tmp`;
16
+ rmSync(tempPath, { force: true });
17
+ writeFileSync(tempPath, content, { flag: "wx", mode });
18
+ renameSync(tempPath, path);
19
+ }
20
+ //# sourceMappingURL=fs-safe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-safe.js","sourceRoot":"","sources":["../../../src/utils/cli-kit/fs-safe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,OAAe,EACf,IAAI,GAAG,KAAK;IAEZ,MAAM,QAAQ,GAAG,GAAG,IAAI,WAAW,CAAC;IACpC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,15 @@
1
+ export { writeFileAtomicSafe } from "./fs-safe.js";
2
+ export { upsertMarkerBlock } from "./marker-block.js";
3
+ export type { UpsertResult } from "./marker-block.js";
4
+ export { mergeJsonFile } from "./json-file.js";
5
+ export type { MergeJsonResult } from "./json-file.js";
6
+ export { renderSteps, statusLabel } from "./step-report.js";
7
+ export type { StepStatus, StepResult } from "./step-report.js";
8
+ export { SLUG_PATTERN, isValidSlug, stateDir } from "./paths.js";
9
+ export { ensureSecureDir, writeSecureFile } from "./secure-storage.js";
10
+ export { pollForClaimStatus } from "./claim-polling.js";
11
+ export type { ClaimPollingOptions } from "./claim-polling.js";
12
+ export { openUrlInBrowser } from "./browser.js";
13
+ export type { OpenUrlInBrowserOptions, OpenUrlInBrowserResult, } from "./browser.js";
14
+ export { runDiagnosticChecks } from "./diagnostics.js";
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/cli-kit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EACV,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,10 @@
1
+ export { writeFileAtomicSafe } from "./fs-safe.js";
2
+ export { upsertMarkerBlock } from "./marker-block.js";
3
+ export { mergeJsonFile } from "./json-file.js";
4
+ export { renderSteps, statusLabel } from "./step-report.js";
5
+ export { SLUG_PATTERN, isValidSlug, stateDir } from "./paths.js";
6
+ export { ensureSecureDir, writeSecureFile } from "./secure-storage.js";
7
+ export { pollForClaimStatus } from "./claim-polling.js";
8
+ export { openUrlInBrowser } from "./browser.js";
9
+ export { runDiagnosticChecks } from "./diagnostics.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/cli-kit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,21 @@
1
+ export type MergeJsonResult = "created" | "updated" | "unchanged" | "skipped-invalid" | "would-change";
2
+ /**
3
+ * Merge `patch` into a JSON file at `path`, preserving every other key.
4
+ *
5
+ * A file we cannot parse (or that doesn't hold a plain object) is left
6
+ * untouched and reported "skipped-invalid": clobbering a caller's existing
7
+ * config is worse than leaving the patch unapplied. Already-applied patches
8
+ * report "unchanged" without writing.
9
+ *
10
+ * `path` is used as given, with no containment check against a base
11
+ * directory (unlike `upsertMarkerBlock`, this function takes a fully
12
+ * resolved path, not a `cwd` + relative segment) — resolving it safely is
13
+ * the caller's responsibility.
14
+ */
15
+ export declare function mergeJsonFile(path: string, patch: Record<string, unknown>, options?: {
16
+ dryRun?: boolean;
17
+ }): {
18
+ result: MergeJsonResult;
19
+ path: string;
20
+ };
21
+ //# sourceMappingURL=json-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-file.d.ts","sourceRoot":"","sources":["../../../src/utils/cli-kit/json-file.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,SAAS,GACT,WAAW,GACX,iBAAiB,GACjB,cAAc,CAAC;AAEnB;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAoC3C"}