@iamu-dev/iamu 0.2.0-beta.1 → 0.2.0-beta.2

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 (67) hide show
  1. package/dist/bin.js +29 -8
  2. package/dist/index.js +29 -8
  3. package/dist/templates/skills/iamu-setup.md +8 -16
  4. package/package.json +3 -3
  5. package/dist/adapters/claude-plugin.d.ts +0 -13
  6. package/dist/adapters/registry.d.ts +0 -6
  7. package/dist/adapters/types.d.ts +0 -19
  8. package/dist/bin.d.ts +0 -2
  9. package/dist/build-info.d.ts +0 -53
  10. package/dist/cloud-url.d.ts +0 -19
  11. package/dist/commands/auth-http.d.ts +0 -37
  12. package/dist/commands/auth-project-choice.d.ts +0 -74
  13. package/dist/commands/auth-token-input.d.ts +0 -21
  14. package/dist/commands/auth.d.ts +0 -84
  15. package/dist/commands/browse-actions.d.ts +0 -56
  16. package/dist/commands/browse-driver.d.ts +0 -117
  17. package/dist/commands/browse.d.ts +0 -156
  18. package/dist/commands/cloud-push.d.ts +0 -27
  19. package/dist/commands/complete.d.ts +0 -131
  20. package/dist/commands/completion.d.ts +0 -2
  21. package/dist/commands/context.d.ts +0 -58
  22. package/dist/commands/credentials.d.ts +0 -144
  23. package/dist/commands/diff-filter.d.ts +0 -11
  24. package/dist/commands/doctor.d.ts +0 -24
  25. package/dist/commands/evaluate.d.ts +0 -30
  26. package/dist/commands/findings.d.ts +0 -7
  27. package/dist/commands/init.d.ts +0 -9
  28. package/dist/commands/instructions-walk.d.ts +0 -59
  29. package/dist/commands/list.d.ts +0 -5
  30. package/dist/commands/match.d.ts +0 -12
  31. package/dist/commands/mcp-config.d.ts +0 -10
  32. package/dist/commands/new-entity.d.ts +0 -15
  33. package/dist/commands/new-finding.d.ts +0 -19
  34. package/dist/commands/open.d.ts +0 -8
  35. package/dist/commands/port.d.ts +0 -17
  36. package/dist/commands/prune.d.ts +0 -11
  37. package/dist/commands/pull.d.ts +0 -5
  38. package/dist/commands/register-cloud.d.ts +0 -5
  39. package/dist/commands/register-findings.d.ts +0 -5
  40. package/dist/commands/register-project.d.ts +0 -5
  41. package/dist/commands/register-walkthrough.d.ts +0 -5
  42. package/dist/commands/register.d.ts +0 -10
  43. package/dist/commands/report.d.ts +0 -3
  44. package/dist/commands/serve.d.ts +0 -11
  45. package/dist/commands/skills.d.ts +0 -34
  46. package/dist/commands/start-run.d.ts +0 -49
  47. package/dist/commands/status.d.ts +0 -3
  48. package/dist/commands/step-numbering.d.ts +0 -87
  49. package/dist/commands/step.d.ts +0 -95
  50. package/dist/commands/sync.d.ts +0 -6
  51. package/dist/commands/triage.d.ts +0 -21
  52. package/dist/commands/update.d.ts +0 -4
  53. package/dist/commands/validate.d.ts +0 -8
  54. package/dist/commands/view-results.d.ts +0 -9
  55. package/dist/index.d.ts +0 -9
  56. package/dist/sync-mcp/fatal.d.ts +0 -42
  57. package/dist/sync-mcp/server.d.ts +0 -1
  58. package/dist/sync-mcp/tools.d.ts +0 -12
  59. package/dist/templates.d.ts +0 -10
  60. package/dist/ui/journey-diff.d.ts +0 -3
  61. package/dist/ui/json.d.ts +0 -6
  62. package/dist/ui/logger.d.ts +0 -5
  63. package/dist/ui/panic.d.ts +0 -11
  64. package/dist/ui/symbols.d.ts +0 -11
  65. package/dist/ui/table.d.ts +0 -20
  66. package/dist/ui/update-check.d.ts +0 -6
  67. package/dist/worktree-state.d.ts +0 -49
package/dist/bin.js CHANGED
@@ -12388,10 +12388,10 @@ var init_registry = __esm({
12388
12388
  {
12389
12389
  name: "Antigravity",
12390
12390
  value: "antigravity",
12391
- detectionPaths: [".gemini", ".agent", "GEMINI.md", "AGENTS.md"],
12391
+ detectionPaths: [".agent", ".agents", "AGENTS.md", ".gemini", "GEMINI.md"],
12392
12392
  supportsSkills: true,
12393
- getSkillsDir: (root) => existsSync3(join3(root, ".agent")) && !existsSync3(join3(root, ".gemini")) ? join3(root, ".agent", "skills") : join3(root, ".gemini", "skills"),
12394
- getCommandPath: (root, id) => existsSync3(join3(root, ".agent")) && !existsSync3(join3(root, ".gemini")) ? join3(root, ".agent", "skills", `iamu-${id}`, "SKILL.md") : join3(root, ".gemini", "skills", `iamu-${id}`, "SKILL.md"),
12393
+ getSkillsDir: (root) => existsSync3(join3(root, ".agents")) ? join3(root, ".agents", "skills") : join3(root, ".agent", "skills"),
12394
+ getCommandPath: (root, id) => existsSync3(join3(root, ".agents")) ? join3(root, ".agents", "skills", `iamu-${id}`, "SKILL.md") : join3(root, ".agent", "skills", `iamu-${id}`, "SKILL.md"),
12395
12395
  formatCommand: richFormat,
12396
12396
  getMcpConfigPath: (root) => join3(root, ".mcp.json"),
12397
12397
  formatMcpConfig: mcpJson
@@ -12546,6 +12546,20 @@ function planSkillFiles(hosts, projectRoot, version2) {
12546
12546
  for (const [name, content] of skillTemplates) {
12547
12547
  files.push({ host, path: join4(skillsDir, name, "SKILL.md"), content });
12548
12548
  }
12549
+ if (host.value === "antigravity") {
12550
+ for (const name of skillTemplates.keys()) {
12551
+ const legacyPath = join4(
12552
+ projectRoot,
12553
+ ".gemini",
12554
+ "skills",
12555
+ name,
12556
+ "SKILL.md"
12557
+ );
12558
+ if (isCliWrittenSkill(legacyPath)) {
12559
+ files.push({ host, path: legacyPath, content: null });
12560
+ }
12561
+ }
12562
+ }
12549
12563
  } else {
12550
12564
  for (const cmd of commandsFromSkills(skillTemplates)) {
12551
12565
  files.push({
@@ -12636,7 +12650,13 @@ async function installSkillsForHosts(hosts, projectRoot, version2, opts) {
12636
12650
  let hostUpdated = 0;
12637
12651
  let hostTotal = 0;
12638
12652
  for (const f of planned) {
12639
- if (f.host !== host || f.content === null) continue;
12653
+ if (f.host !== host) continue;
12654
+ if (f.content === null) {
12655
+ await rm(f.path, { force: true });
12656
+ await rmdir(dirname3(f.path)).catch(() => {
12657
+ });
12658
+ continue;
12659
+ }
12640
12660
  hostTotal++;
12641
12661
  if (host.supportsSkills) totalSkills++;
12642
12662
  else totalCommands++;
@@ -15744,7 +15764,8 @@ var init_serve = __esm({
15744
15764
  // src/commands/init.ts
15745
15765
  var init_exports = {};
15746
15766
  __export(init_exports, {
15747
- init: () => init
15767
+ init: () => init,
15768
+ setupCommand: () => setupCommand
15748
15769
  });
15749
15770
  import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
15750
15771
  import { mkdir as mkdir4, writeFile as writeFile3 } from "fs/promises";
@@ -15771,9 +15792,9 @@ function loadPromptTemplates() {
15771
15792
  return templates;
15772
15793
  }
15773
15794
  function setupCommand(projectRoot, hosts) {
15774
- if (!iamuPluginEnabled(projectRoot)) return "iamu-setup";
15795
+ if (!iamuPluginEnabled(projectRoot)) return "/iamu-setup";
15775
15796
  if (hosts.every((h) => h.value === "claude")) return "/iamu:init";
15776
- return "iamu-setup (Claude Code: /iamu:init)";
15797
+ return "/iamu-setup (Claude Code: /iamu:init)";
15777
15798
  }
15778
15799
  async function init(opts) {
15779
15800
  const options = typeof opts === "string" ? { name: opts } : opts ?? {};
@@ -15917,7 +15938,7 @@ async function init(opts) {
15917
15938
  if (freshInit) {
15918
15939
  console.log(chalk17.bold(" Next step:"));
15919
15940
  console.log();
15920
- console.log(chalk17.dim(" Open your editor and run:"));
15941
+ console.log(chalk17.dim(" In your AI agent chat, run:"));
15921
15942
  console.log();
15922
15943
  console.log(` ${chalk17.cyan(setupCommand(projectRoot, selectedHosts))}`);
15923
15944
  console.log();
package/dist/index.js CHANGED
@@ -12367,10 +12367,10 @@ var init_registry = __esm({
12367
12367
  {
12368
12368
  name: "Antigravity",
12369
12369
  value: "antigravity",
12370
- detectionPaths: [".gemini", ".agent", "GEMINI.md", "AGENTS.md"],
12370
+ detectionPaths: [".agent", ".agents", "AGENTS.md", ".gemini", "GEMINI.md"],
12371
12371
  supportsSkills: true,
12372
- getSkillsDir: (root) => existsSync3(join3(root, ".agent")) && !existsSync3(join3(root, ".gemini")) ? join3(root, ".agent", "skills") : join3(root, ".gemini", "skills"),
12373
- getCommandPath: (root, id) => existsSync3(join3(root, ".agent")) && !existsSync3(join3(root, ".gemini")) ? join3(root, ".agent", "skills", `iamu-${id}`, "SKILL.md") : join3(root, ".gemini", "skills", `iamu-${id}`, "SKILL.md"),
12372
+ getSkillsDir: (root) => existsSync3(join3(root, ".agents")) ? join3(root, ".agents", "skills") : join3(root, ".agent", "skills"),
12373
+ getCommandPath: (root, id) => existsSync3(join3(root, ".agents")) ? join3(root, ".agents", "skills", `iamu-${id}`, "SKILL.md") : join3(root, ".agent", "skills", `iamu-${id}`, "SKILL.md"),
12374
12374
  formatCommand: richFormat,
12375
12375
  getMcpConfigPath: (root) => join3(root, ".mcp.json"),
12376
12376
  formatMcpConfig: mcpJson
@@ -12525,6 +12525,20 @@ function planSkillFiles(hosts, projectRoot, version) {
12525
12525
  for (const [name, content] of skillTemplates) {
12526
12526
  files.push({ host, path: join4(skillsDir, name, "SKILL.md"), content });
12527
12527
  }
12528
+ if (host.value === "antigravity") {
12529
+ for (const name of skillTemplates.keys()) {
12530
+ const legacyPath = join4(
12531
+ projectRoot,
12532
+ ".gemini",
12533
+ "skills",
12534
+ name,
12535
+ "SKILL.md"
12536
+ );
12537
+ if (isCliWrittenSkill(legacyPath)) {
12538
+ files.push({ host, path: legacyPath, content: null });
12539
+ }
12540
+ }
12541
+ }
12528
12542
  } else {
12529
12543
  for (const cmd of commandsFromSkills(skillTemplates)) {
12530
12544
  files.push({
@@ -12615,7 +12629,13 @@ async function installSkillsForHosts(hosts, projectRoot, version, opts) {
12615
12629
  let hostUpdated = 0;
12616
12630
  let hostTotal = 0;
12617
12631
  for (const f of planned) {
12618
- if (f.host !== host || f.content === null) continue;
12632
+ if (f.host !== host) continue;
12633
+ if (f.content === null) {
12634
+ await rm(f.path, { force: true });
12635
+ await rmdir(dirname3(f.path)).catch(() => {
12636
+ });
12637
+ continue;
12638
+ }
12619
12639
  hostTotal++;
12620
12640
  if (host.supportsSkills) totalSkills++;
12621
12641
  else totalCommands++;
@@ -15723,7 +15743,8 @@ var init_serve = __esm({
15723
15743
  // src/commands/init.ts
15724
15744
  var init_exports = {};
15725
15745
  __export(init_exports, {
15726
- init: () => init
15746
+ init: () => init,
15747
+ setupCommand: () => setupCommand
15727
15748
  });
15728
15749
  import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
15729
15750
  import { mkdir as mkdir4, writeFile as writeFile3 } from "fs/promises";
@@ -15750,9 +15771,9 @@ function loadPromptTemplates() {
15750
15771
  return templates;
15751
15772
  }
15752
15773
  function setupCommand(projectRoot, hosts) {
15753
- if (!iamuPluginEnabled(projectRoot)) return "iamu-setup";
15774
+ if (!iamuPluginEnabled(projectRoot)) return "/iamu-setup";
15754
15775
  if (hosts.every((h) => h.value === "claude")) return "/iamu:init";
15755
- return "iamu-setup (Claude Code: /iamu:init)";
15776
+ return "/iamu-setup (Claude Code: /iamu:init)";
15756
15777
  }
15757
15778
  async function init(opts) {
15758
15779
  const options = typeof opts === "string" ? { name: opts } : opts ?? {};
@@ -15896,7 +15917,7 @@ async function init(opts) {
15896
15917
  if (freshInit) {
15897
15918
  console.log(chalk17.bold(" Next step:"));
15898
15919
  console.log();
15899
- console.log(chalk17.dim(" Open your editor and run:"));
15920
+ console.log(chalk17.dim(" In your AI agent chat, run:"));
15900
15921
  console.log();
15901
15922
  console.log(` ${chalk17.cyan(setupCommand(projectRoot, selectedHosts))}`);
15902
15923
  console.log();
@@ -23,22 +23,14 @@ $ARGUMENTS
23
23
 
24
24
  ### 1. Scaffold the iamu/ tree
25
25
 
26
- Run `iamu init` in the terminal. Pass a project name when the user names one explicitly; otherwise the tool derives it from the directory basename.
27
-
28
- ```
29
- iamu init [project-name]
30
- ```
31
-
32
- The command scaffolds `iamu/config.json`, entity subdirs, `.runs/`, `.cache/`, `.gitignore`.
33
-
34
- - If `iamu/` was already present, existing files are not overwritten. Treat as success and continue.
35
- - Error containing "legacy `.iamu/` layout" → tell the user to remove the legacy directory, then re-run.
36
-
37
- On fresh scaffold, introduce iamu first:
38
-
39
- > **iamu** tests your product as realistic personas and reports what works, what doesn't, and how to fix it. I'll analyze your codebase now to understand the domain and propose primary personas.
40
-
41
- On re-run (already scaffolded), skip the intro — the user knows what iamu is.
26
+ Check whether `iamu/config.json` already exists:
27
+
28
+ - **If already scaffolded (`iamu/config.json` exists):** Do not re-run `iamu init`. Introduce the step concisely and proceed directly to Step 2:
29
+ > Analyzing your codebase now to understand the domain and propose primary personas.
30
+ - **If not yet scaffolded:** Run `iamu init [project-name]` in the terminal (pass a project name if the user named one explicitly; otherwise omit). The command scaffolds `iamu/config.json`, entity subdirs, `.runs/`, `.cache/`, `.gitignore`.
31
+ Introduce iamu first:
32
+ > **iamu** tests your product as realistic personas and reports what works, what doesn't, and how to fix it. I'll analyze your codebase now to understand the domain and propose primary personas.
33
+ - **Error containing "legacy `.iamu/` layout"** → tell the user to remove the legacy directory, then re-run.
42
34
 
43
35
  ### 2. Understand the project
44
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iamu-dev/iamu",
3
- "version": "0.2.0-beta.1",
3
+ "version": "0.2.0-beta.2",
4
4
  "type": "module",
5
5
  "description": "Test your product as realistic personas — scenario-driven development CLI",
6
6
  "license": "UNLICENSED",
@@ -57,9 +57,9 @@
57
57
  "tsup": "^8.5.1",
58
58
  "typescript": "^5.8.0",
59
59
  "vitest": "^4.1.11",
60
- "@iamu-dev/protocol": "0.1.0",
61
60
  "@iamu-dev/local-store": "0.1.0",
62
- "@iamu/tsconfig": "0.1.0"
61
+ "@iamu/tsconfig": "0.1.0",
62
+ "@iamu-dev/protocol": "0.1.0"
63
63
  },
64
64
  "scripts": {
65
65
  "build": "tsup && tsc -b tsconfig.build.json --emitDeclarationOnly && node scripts/copy-assets.mjs",
@@ -1,13 +0,0 @@
1
- import type { HostAdapter } from "./types.js";
2
- /**
3
- * Whether the Iamu Claude Code plugin is enabled for `projectRoot`.
4
- * Settings merge key by key and the highest-precedence mention wins, so
5
- * `"iamu@iamu": false` in settings.local.json overrides a user-level true.
6
- */
7
- export declare function iamuPluginEnabled(projectRoot: string): boolean;
8
- /**
9
- * The plugin ships the same skills as `/iamu:<name>`. Claude Code loads
10
- * plugin and project skills side by side, so installing both would put
11
- * every skill in context twice.
12
- */
13
- export declare function pluginProvidesSkills(host: HostAdapter, projectRoot: string): boolean;
@@ -1,6 +0,0 @@
1
- import type { HostAdapter } from "./types.js";
2
- export declare const HOST_ADAPTERS: HostAdapter[];
3
- /**
4
- * Detect which host editors are present in the given project root.
5
- */
6
- export declare function detectHosts(projectRoot: string): HostAdapter[];
@@ -1,19 +0,0 @@
1
- export interface CommandContent {
2
- id: string;
3
- name: string;
4
- description: string;
5
- category: string;
6
- tags: string[];
7
- body: string;
8
- }
9
- export interface HostAdapter {
10
- name: string;
11
- value: string;
12
- detectionPaths: string[];
13
- supportsSkills: boolean;
14
- getSkillsDir(projectRoot: string): string;
15
- getCommandPath(projectRoot: string, commandId: string): string;
16
- formatCommand(content: CommandContent): string;
17
- getMcpConfigPath(projectRoot: string): string;
18
- formatMcpConfig(serverCommand: string[]): string;
19
- }
package/dist/bin.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
@@ -1,53 +0,0 @@
1
- import { type BuildMetadata } from "@iamu-dev/protocol";
2
- import { type WorktreeDetector } from "./worktree-state.js";
3
- /** Environment variables, as `process.env` holds them. */
4
- export type Env = Record<string, string | undefined>;
5
- /** Runs `git <args>` in `cwd`; returns trimmed stdout or null. */
6
- export type GitRunner = (args: string[], cwd: string) => string | null;
7
- /** `git` via execFile, silent and bounded; null when git is absent or fails. */
8
- export declare const runGit: GitRunner;
9
- interface CiInfo {
10
- git_sha?: string;
11
- git_branch?: string;
12
- base_sha?: string;
13
- ci?: {
14
- provider: string;
15
- run_url: string;
16
- };
17
- }
18
- /**
19
- * What the CI environment says about the build. Recognizes GitHub
20
- * Actions and Azure Pipelines; an empty object anywhere else.
21
- */
22
- export declare function detectCi(env: Env): CiInfo;
23
- export interface DetectBuildOptions {
24
- /** `--build <label>`. */
25
- label?: string;
26
- /** Directory to ask git about. */
27
- cwd: string;
28
- env?: Env;
29
- git?: GitRunner;
30
- /**
31
- * Uncommitted changes outside `iamu/` (`git_dirty`, `worktree_hash`).
32
- * Recorded alongside a `--build` label, not instead of it.
33
- */
34
- worktree?: WorktreeDetector;
35
- }
36
- /**
37
- * Build metadata for a run started now. Flags win over CI variables,
38
- * CI variables over the local checkout. Returns undefined when nothing
39
- * at all is known.
40
- *
41
- * @example
42
- * ```ts
43
- * const build = detectBuild({ cwd: projectRoot, label: "2.4.0" });
44
- * // { label: "2.4.0", git_sha: "3f9c2a1…", git_branch: "main", git_dirty: false }
45
- * ```
46
- */
47
- export declare function detectBuild(opts: DetectBuildOptions): BuildMetadata | undefined;
48
- /**
49
- * The run's environment: `--env <name>` when given, otherwise the
50
- * target URL's origin.
51
- */
52
- export declare function resolveEnvironment(explicit: string | undefined, targetUrl: string): string | undefined;
53
- export {};
@@ -1,19 +0,0 @@
1
- /**
2
- * Resolves cloud web dashboard URLs for projects and walkthrough runs.
3
- */
4
- /**
5
- * Resolves the web dashboard base URL from an API URL or environment variable.
6
- *
7
- * Precedence:
8
- * 1. IAMU_WEB_URL environment variable (explicit override)
9
- * 2. If apiUrl targets api.iamu.dev -> https://app.iamu.dev
10
- * 3. If apiUrl targets localhost:3000 -> http://localhost:3001 (standard local dev split)
11
- * unless overridden by IAMU_WEB_URL
12
- * 4. If apiUrl starts with https://api. -> https://app.
13
- * 5. Fallback: apiUrl without trailing slash
14
- */
15
- export declare function getCloudWebBase(apiUrl?: string | null): string;
16
- /**
17
- * Builds the cloud dashboard URL for a project or specific walkthrough run.
18
- */
19
- export declare function getCloudDashboardUrl(apiUrl: string | null | undefined, projectId: string, walkthroughId?: string): string;
@@ -1,37 +0,0 @@
1
- /** Per-request budget for auth endpoints, headers plus body. */
2
- export declare const AUTH_REQUEST_TIMEOUT_MS = 10000;
3
- /** A fully read response from an auth endpoint. */
4
- export interface AuthHttpResponse {
5
- status: number;
6
- ok: boolean;
7
- /** Raw body text. */
8
- text: string;
9
- /** Body parsed as JSON, or `null` when it is not JSON. */
10
- json: unknown;
11
- }
12
- /** Request options for {@link requestAuthApi}. */
13
- export interface AuthRequestOptions {
14
- method?: "GET" | "POST";
15
- headers?: Record<string, string>;
16
- body?: string;
17
- /** Budget for this request; default {@link AUTH_REQUEST_TIMEOUT_MS}. */
18
- timeoutMs?: number;
19
- }
20
- /**
21
- * Call an auth endpoint and read the whole body within `timeoutMs`.
22
- *
23
- * @param url - Absolute endpoint URL.
24
- * @param opts - Method, headers, body and timeout.
25
- * @returns Status plus the body as text and (when parseable) JSON.
26
- * @throws {@link IamuNetworkError} when the timeout fires; other fetch
27
- * failures propagate unchanged.
28
- *
29
- * @example
30
- * ```ts
31
- * const res = await requestAuthApi(`${apiUrl}/api/projects`, {
32
- * headers: { Authorization: `Bearer ${token}` },
33
- * });
34
- * if (res.ok) console.log(res.json);
35
- * ```
36
- */
37
- export declare function requestAuthApi(url: string, opts?: AuthRequestOptions): Promise<AuthHttpResponse>;
@@ -1,74 +0,0 @@
1
- /**
2
- * Which cloud project `iamu auth login` links to. Pure, so every branch
3
- * is testable without a TTY or network.
4
- *
5
- * Linking pushes every local entity to the chosen project, so a wrong
6
- * guess leaks one product's data into another. The rules therefore
7
- * never pick between several projects on the user's behalf.
8
- */
9
- /** A cloud project as `GET /api/projects` lists it. */
10
- export interface CloudProjectSummary {
11
- id: string;
12
- name: string;
13
- slug: string;
14
- }
15
- /** `--project` value that asks for a new cloud project. */
16
- export declare const CREATE_NEW_PROJECT = "new";
17
- /** Inputs to {@link decideCloudProject}. */
18
- export interface ProjectChoiceInput {
19
- /** Projects the account can see. */
20
- projects: readonly CloudProjectSummary[];
21
- /** `--project` value, if given. */
22
- requested?: string;
23
- /** Project this repo is already linked to (credentials were lost). */
24
- linkedProjectId?: string | null;
25
- /** `--yes`: accept the only candidate. */
26
- yes?: boolean;
27
- /** Whether a human can be prompted. */
28
- interactive: boolean;
29
- }
30
- /** Outcome of {@link decideCloudProject}. */
31
- export type ProjectDecision = {
32
- kind: "link";
33
- projectId: string;
34
- } | {
35
- kind: "create";
36
- } | {
37
- kind: "prompt";
38
- } | {
39
- kind: "refuse";
40
- reason: "ambiguous" | "unknown_project";
41
- };
42
- /**
43
- * Decide the project to link.
44
- *
45
- * - `--project new` creates; `--project <id>` must be one of `projects`.
46
- * - An existing link is kept.
47
- * - No projects at all: create one named after the local project.
48
- * - `--yes` links the single project when there is exactly one; with
49
- * several it does not pick, it falls through.
50
- * - Otherwise prompt when interactive, refuse (and list) when not.
51
- *
52
- * @param input - Available projects plus flags and TTY state.
53
- * @returns What to do next.
54
- *
55
- * @example
56
- * ```ts
57
- * const d = decideCloudProject({ projects, requested: "new", interactive: false });
58
- * // { kind: "create" }
59
- * ```
60
- */
61
- export declare function decideCloudProject(input: ProjectChoiceInput): ProjectDecision;
62
- /**
63
- * Narrow a `GET /api/projects` body to project summaries.
64
- *
65
- * @param body - Parsed JSON body.
66
- * @returns The projects, or `null` when the body is not a project list.
67
- *
68
- * @example
69
- * ```ts
70
- * const projects = parseProjectList(res.json);
71
- * if (!projects) throw new Error("unexpected response");
72
- * ```
73
- */
74
- export declare function parseProjectList(body: unknown): CloudProjectSummary[] | null;
@@ -1,21 +0,0 @@
1
- /** The readable side `readTokenFromStdin` needs. */
2
- export type TokenInputStream = AsyncIterable<string | Uint8Array> & {
3
- isTTY?: boolean;
4
- };
5
- /**
6
- * Read an API token piped on stdin (`--token-stdin`), so it never shows
7
- * up in `ps`, shell history or CI logs the way `--token <value>` does.
8
- * Surrounding whitespace (a trailing newline from `echo`) is dropped.
9
- *
10
- * @param stream - Input stream; defaults to `process.stdin`.
11
- * @returns The token.
12
- * @throws {@link IamuValidationError} when stdin is a terminal, empty,
13
- * oversized, or holds more than one word.
14
- *
15
- * @example
16
- * ```ts
17
- * // printf %s "$IAMU_CI_TOKEN" | iamu auth login --token-stdin
18
- * const token = await readTokenFromStdin();
19
- * ```
20
- */
21
- export declare function readTokenFromStdin(stream?: TokenInputStream): Promise<string>;
@@ -1,84 +0,0 @@
1
- /** Launches a program with its arguments as an argv array — no shell. */
2
- export type CommandRunner = (file: string, args: readonly string[]) => void;
3
- /**
4
- * Open `url` in the platform browser. The URL is always a separate argv
5
- * element: interpolating it into a shell command line let a crafted
6
- * login URL run commands.
7
- *
8
- * @param url - The URL to open.
9
- * @param run - Process launcher; injectable so tests never spawn.
10
- *
11
- * @example
12
- * ```ts
13
- * openBrowser("https://iamu.dev/login");
14
- * ```
15
- */
16
- export declare function openBrowser(url: string, run?: CommandRunner): void;
17
- /** Flags of `iamu auth login`. */
18
- export interface AuthLoginOptions {
19
- url?: string;
20
- /** Accept the only candidate project; never picks between several. */
21
- yes?: boolean;
22
- /** Cloud project id to link, or `new` to create one. */
23
- project?: string;
24
- browser?: boolean;
25
- local?: boolean | string | number;
26
- staging?: boolean;
27
- /** Token on argv. Visible to `ps` and shell history; prefer `tokenStdin`. */
28
- token?: string;
29
- /** Read the token from stdin instead of argv. */
30
- tokenStdin?: boolean;
31
- webUrl?: string;
32
- }
33
- /**
34
- * Timing knobs for {@link authLogin}. Exposed so tests can shrink them.
35
- *
36
- * @internal
37
- */
38
- export interface AuthLoginTiming {
39
- /** Pause between token polls. */
40
- pollIntervalMs: number;
41
- /** Hard deadline for the whole browser login. */
42
- pollTimeoutMs: number;
43
- /** Budget for each HTTP request. */
44
- requestTimeoutMs: number;
45
- }
46
- /**
47
- * `iamu auth login`: obtain a token (flag, stdin, stored/env, or browser
48
- * device flow), store it, then link the project to a cloud project.
49
- * Every failure sets exit code 1 (2 for conflicting flags); in a
50
- * non-interactive shell it never chooses between cloud projects.
51
- *
52
- * @param opts - Command flags.
53
- * @param timing - Test-only timing overrides.
54
- *
55
- * @example
56
- * ```ts
57
- * await authLogin({ project: "new" });
58
- * ```
59
- */
60
- export declare function authLogin(opts?: AuthLoginOptions, timing?: Partial<AuthLoginTiming>): Promise<void>;
61
- /**
62
- * `iamu auth disconnect`: unlink the project and forget the stored token
63
- * for its API URL. Local entities are kept.
64
- *
65
- * @example
66
- * ```ts
67
- * await authDisconnect();
68
- * ```
69
- */
70
- export declare function authDisconnect(): Promise<void>;
71
- /**
72
- * `iamu auth status`: whether a token is available and the project is
73
- * linked. Never prints the token.
74
- *
75
- * @param opts - `json` prints a machine-readable object on stdout.
76
- *
77
- * @example
78
- * ```ts
79
- * await authStatus({ json: true });
80
- * ```
81
- */
82
- export declare function authStatus(opts?: {
83
- json?: boolean;
84
- }): Promise<void>;
@@ -1,56 +0,0 @@
1
- /**
2
- * The page actions `iamu browse` can perform — one table shared by the
3
- * direct commands (`iamu browse click …`) and by `iamu browse step
4
- * click …`, so the two can never drift apart.
5
- */
6
- import type { Page } from "playwright-core";
7
- /** Options an action reads. */
8
- export interface ActionOptions {
9
- /** Pick the nth (0-based) match instead of the first. */
10
- nth?: string;
11
- /** Press Enter after fill/select. */
12
- submit?: boolean;
13
- }
14
- /**
15
- * One page action: how it is called, what it targets (for the "nothing
16
- * matches" error), and what it does.
17
- *
18
- * @public
19
- */
20
- export interface PageAction {
21
- /** Call shape after `iamu browse`, e.g. `click <role> "<name>" [--nth N]`. */
22
- usage: string;
23
- /** Positional arguments required after the action name. */
24
- minArgs: number;
25
- /** What the action looks for, named the way the error message says it. */
26
- target?: (args: string[]) => string;
27
- run(page: Page, args: string[], opts: ActionOptions): Promise<void>;
28
- }
29
- /**
30
- * Every page action, by name. `shot` does nothing to the page; the
31
- * screenshot is taken after any action when one is asked for.
32
- *
33
- * @example
34
- * ```ts
35
- * const action = PAGE_ACTIONS.click;
36
- * if (args.length >= action.minArgs) await action.run(page, args, {});
37
- * ```
38
- *
39
- * @public
40
- */
41
- export declare const PAGE_ACTIONS: Readonly<Record<string, PageAction>>;
42
- /**
43
- * Look up a page action by name, own properties only (so `toString`
44
- * and friends are not actions).
45
- *
46
- * @param name - The action name as typed.
47
- * @returns The action, or undefined.
48
- *
49
- * @example
50
- * ```ts
51
- * findPageAction("click")?.usage; // 'click <role> "<name>" [--nth N]'
52
- * ```
53
- *
54
- * @public
55
- */
56
- export declare function findPageAction(name: string): PageAction | undefined;