@plainconceptsplatform/agent-harness 3.9.0 → 3.10.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 (142) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +551 -551
  3. package/cli/commands/join.js +259 -259
  4. package/cli/commands/migrate.js +310 -310
  5. package/cli/commands/shared.js +27 -27
  6. package/cli/commands/single.js +79 -79
  7. package/cli/commands/update.js +121 -121
  8. package/cli/commands/wizard.js +134 -134
  9. package/cli/fragments/archive/az.md +97 -97
  10. package/cli/fragments/archive/gh.md +96 -96
  11. package/cli/fragments/archive/gl.md +96 -96
  12. package/cli/fragments/archive/none.md +75 -75
  13. package/cli/fragments/guardrails/codegraph.md +5 -5
  14. package/cli/fragments/guardrails/humanizer.md +4 -4
  15. package/cli/fragments/guardrails/memory.md +4 -4
  16. package/cli/fragments/guardrails/rtk.md +3 -3
  17. package/cli/fragments/guardrails/simple-english.md +4 -4
  18. package/cli/fragments/ops-backlog/az.md +28 -28
  19. package/cli/fragments/ops-backlog/gh.md +28 -28
  20. package/cli/fragments/ops-backlog/jira.md +28 -28
  21. package/cli/fragments/ops-review/az.md +62 -62
  22. package/cli/fragments/ops-review/gh.md +51 -51
  23. package/cli/fragments/ops-review/gl.md +55 -55
  24. package/cli/fragments/ops-ship/az.md +81 -81
  25. package/cli/fragments/ops-ship/gh.md +67 -67
  26. package/cli/fragments/ops-ship/gl.md +84 -84
  27. package/cli/index.js +116 -116
  28. package/cli/presets/agents-content.json +34 -34
  29. package/cli/presets/browser.json +10 -10
  30. package/cli/presets/clean.json +21 -21
  31. package/cli/presets/models.json +68 -68
  32. package/cli/presets/optimization.json +32 -32
  33. package/cli/presets/platforms.json +76 -76
  34. package/cli/presets/source.json +23 -23
  35. package/cli/steps/browser/index.js +52 -48
  36. package/cli/steps/clean/index.js +120 -120
  37. package/cli/steps/copy/agents.js +176 -176
  38. package/cli/steps/copy/commands.js +79 -79
  39. package/cli/steps/copy/fullstack-engineer.js +81 -81
  40. package/cli/steps/copy/index.js +88 -88
  41. package/cli/steps/copy/opencode-json.js +359 -324
  42. package/cli/steps/copy/skills.js +316 -316
  43. package/cli/steps/metadata/index.js +115 -115
  44. package/cli/steps/models/format.js +88 -88
  45. package/cli/steps/models/index.js +64 -64
  46. package/cli/steps/models/write.js +38 -38
  47. package/cli/steps/openspec/index.js +136 -136
  48. package/cli/steps/optimization/codegraph.js +141 -141
  49. package/cli/steps/optimization/detect.js +66 -66
  50. package/cli/steps/optimization/humanizer.js +17 -17
  51. package/cli/steps/optimization/index.js +158 -158
  52. package/cli/steps/optimization/memory.js +91 -91
  53. package/cli/steps/optimization/patch-guardrails.js +111 -111
  54. package/cli/steps/optimization/simple-english.js +17 -17
  55. package/cli/steps/optimization/skills-lock.js +30 -30
  56. package/cli/steps/platform/index.js +109 -109
  57. package/cli/steps/source/index.js +123 -123
  58. package/cli/utils/agent-color.js +111 -111
  59. package/cli/utils/copy.js +134 -134
  60. package/cli/utils/exec-spinner.js +47 -47
  61. package/cli/utils/exec.js +134 -134
  62. package/cli/utils/legacy-check.js +30 -30
  63. package/cli/utils/models-cache.js +58 -58
  64. package/cli/utils/models-pricing.js +42 -42
  65. package/cli/utils/paths.js +82 -82
  66. package/cli/utils/process.js +3 -3
  67. package/cli/utils/terminal.js +6 -6
  68. package/cli/utils/update-manifest.js +75 -75
  69. package/harness/.opencode/_gitignore +12 -12
  70. package/harness/.opencode/commands/init.md +5 -5
  71. package/harness/.opencode/commands/make-architecture.md +5 -5
  72. package/harness/.opencode/commands/make-design.md +5 -5
  73. package/harness/.opencode/commands/make-engineer.md +5 -5
  74. package/harness/.opencode/commands/make-guardrails.md +5 -5
  75. package/harness/.opencode/commands/make-user-model.md +5 -5
  76. package/harness/.opencode/commands/ops-backlog.md +10 -10
  77. package/harness/.opencode/commands/ops-review.md +10 -10
  78. package/harness/.opencode/commands/ops-ship.md +9 -9
  79. package/harness/.opencode/commands/plan-apply.md +9 -9
  80. package/harness/.opencode/commands/plan-archive.md +7 -7
  81. package/harness/.opencode/commands/plan-explore.md +11 -11
  82. package/harness/.opencode/commands/plan-goal.md +5 -5
  83. package/harness/.opencode/commands/plan-propose.md +11 -11
  84. package/harness/.opencode/commands/plan-quick.md +7 -7
  85. package/harness/.opencode/commands/plan-story.md +11 -11
  86. package/harness/.opencode/commands/repo-audit.md +7 -7
  87. package/harness/.opencode/commands/repo-help.md +5 -5
  88. package/harness/.opencode/commands/repo-initialize.md +5 -5
  89. package/harness/.opencode/commands/repo-onboard.md +5 -5
  90. package/harness/.opencode/commands/repo-verify.md +5 -5
  91. package/harness/.opencode/plugins/pc-commit-coauthor.js +41 -41
  92. package/harness/.opencode/plugins/pc-subagent-monitor.js +184 -184
  93. package/harness/.opencode/plugins/pc-system-reminders.js +424 -424
  94. package/harness/.opencode/scripts/check-diff.mjs +305 -305
  95. package/harness/.opencode/scripts/code-rules.mjs +288 -288
  96. package/harness/.opencode/scripts/platform-contract.mjs +366 -366
  97. package/harness/AGENTS.md +55 -55
  98. package/harness/ARCHITECTURE.md +13 -13
  99. package/harness/DESIGN.md +13 -13
  100. package/harness/opencode.jsonc +37 -36
  101. package/harness/openspec/config.yaml +20 -20
  102. package/harness/skills-lock.json +17 -17
  103. package/package.json +14 -12
  104. package/skills/README.md +18 -18
  105. package/skills/agent-harness-cli/SKILL.md +86 -86
  106. package/skills/browser-automation/SKILL.md +100 -72
  107. package/skills/pc-guardrails-generic/SKILL.md +53 -53
  108. package/skills/pc-guardrails-project/SKILL.md +8 -8
  109. package/skills/pc-make-architecture/SKILL.md +33 -33
  110. package/skills/pc-make-architecture/structure-template.md +64 -64
  111. package/skills/pc-make-design/SKILL.md +45 -45
  112. package/skills/pc-make-engineer/SKILL.md +59 -59
  113. package/skills/pc-make-engineer/signal-mapping.md +53 -53
  114. package/skills/pc-make-engineer/template.md +36 -36
  115. package/skills/pc-make-guardrails/SKILL.md +44 -44
  116. package/skills/pc-make-guardrails/category-reference.md +112 -112
  117. package/skills/pc-make-merge-risk-assess/SKILL.md +70 -70
  118. package/skills/pc-make-merge-risk-assess/category-reference.md +114 -114
  119. package/skills/pc-make-user-model/SKILL.md +56 -56
  120. package/skills/pc-ops-ship/SKILL.md +22 -22
  121. package/skills/pc-plan-apply/SKILL.md +90 -90
  122. package/skills/pc-plan-apply/simple-mode.md +21 -21
  123. package/skills/pc-plan-archive/SKILL.md +66 -66
  124. package/skills/pc-plan-explore/SKILL.md +21 -21
  125. package/skills/pc-plan-goal/SKILL.md +91 -91
  126. package/skills/pc-plan-goal/branching.md +39 -39
  127. package/skills/pc-plan-goal/failure-policy.md +30 -30
  128. package/skills/pc-plan-goal/output-mode.md +10 -10
  129. package/skills/pc-plan-goal/output.md +71 -71
  130. package/skills/pc-plan-propose/SKILL.md +127 -127
  131. package/skills/pc-plan-propose/task-annotation.md +39 -39
  132. package/skills/pc-plan-quick/SKILL.md +46 -46
  133. package/skills/pc-plan-story/SKILL.md +93 -93
  134. package/skills/pc-repo-audit/SKILL.md +44 -44
  135. package/skills/pc-repo-help/SKILL.md +87 -87
  136. package/skills/pc-repo-initialize/SKILL.md +119 -119
  137. package/skills/pc-repo-onboard/SKILL.md +32 -32
  138. package/skills/pc-repo-verify/SKILL.md +150 -150
  139. package/skills/pc-userstory-az/SKILL.md +71 -71
  140. package/skills/pc-userstory-browser/SKILL.md +73 -64
  141. package/skills/pc-userstory-gh/SKILL.md +63 -63
  142. package/skills/pc-userstory-jira/SKILL.md +74 -74
@@ -1,68 +1,68 @@
1
- {
2
- "costTiers": [
3
- { "max": 1, "label": "[$]" },
4
- { "max": 10, "label": "[$$]" },
5
- { "label": "[$$$]" }
6
- ],
7
- "providers": [
8
- { "value": "opencode", "name": "OpenCode Zen" },
9
- { "value": "opencode-go", "name": "OpenCode Go" },
10
- { "value": "github-copilot", "name": "GitHub Copilot" },
11
- { "value": "anthropic", "name": "Anthropic" },
12
- { "value": "google", "name": "Google" },
13
- { "value": "openai", "name": "OpenAI" },
14
- { "value": "deepseek", "name": "DeepSeek" },
15
- { "value": "", "name": "Other (show all)" }
16
- ],
17
- "roles": {
18
- "plan": {
19
- "prompt": "Plan model:",
20
- "info": [
21
- "PLAN: main session: reads issues, writes proposals, coordinates the agent team.",
22
- "Needs to be strong. A weak model here will silently skip steps and break the workflow."
23
- ],
24
- "suggestions": {
25
- "opencode": "opencode/claude-sonnet-4",
26
- "opencode-go": null,
27
- "github-copilot": "github-copilot/claude-sonnet-4.5",
28
- "anthropic": "anthropic/claude-sonnet-4-5",
29
- "google": "google/gemini-2.5-pro",
30
- "openai": "openai/o3",
31
- "deepseek": null
32
- }
33
- },
34
- "build": {
35
- "prompt": "Build model:",
36
- "info": [
37
- "BUILD: engineers: implements code, runs tests, commits.",
38
- "Code quality matters here. DeepSeek V4 is outstanding value. Claude Sonnet is the gold standard."
39
- ],
40
- "suggestions": {
41
- "opencode": "opencode/deepseek-v4-flash",
42
- "opencode-go": "opencode-go/deepseek-v4-pro",
43
- "github-copilot": "github-copilot/claude-sonnet-4.5",
44
- "anthropic": "anthropic/claude-sonnet-4-5",
45
- "google": "google/gemini-2.5-flash",
46
- "openai": "openai/gpt-4.1",
47
- "deepseek": "deepseek/deepseek-v4-pro"
48
- },
49
- "agents": ["fullstack-engineer"]
50
- },
51
- "fast": {
52
- "prompt": "Fast model:",
53
- "info": [
54
- "FAST: light commands: /pc-pullrequest, /pc-explore, /pc-archive, status checks.",
55
- "No heavy reasoning needed. Cheap and fast is the right call here."
56
- ],
57
- "suggestions": {
58
- "opencode": "opencode/glm-4.7",
59
- "opencode-go": "opencode-go/qwen3.6-plus",
60
- "github-copilot": "github-copilot/gpt-5.4-nano",
61
- "anthropic": "anthropic/claude-haiku-4-5",
62
- "google": "google/gemini-2.0-flash",
63
- "openai": "openai/gpt-4o-mini",
64
- "deepseek": null
65
- }
66
- }
67
- }
68
- }
1
+ {
2
+ "costTiers": [
3
+ { "max": 1, "label": "[$]" },
4
+ { "max": 10, "label": "[$$]" },
5
+ { "label": "[$$$]" }
6
+ ],
7
+ "providers": [
8
+ { "value": "opencode", "name": "OpenCode Zen" },
9
+ { "value": "opencode-go", "name": "OpenCode Go" },
10
+ { "value": "github-copilot", "name": "GitHub Copilot" },
11
+ { "value": "anthropic", "name": "Anthropic" },
12
+ { "value": "google", "name": "Google" },
13
+ { "value": "openai", "name": "OpenAI" },
14
+ { "value": "deepseek", "name": "DeepSeek" },
15
+ { "value": "", "name": "Other (show all)" }
16
+ ],
17
+ "roles": {
18
+ "plan": {
19
+ "prompt": "Plan model:",
20
+ "info": [
21
+ "PLAN: main session: reads issues, writes proposals, coordinates the agent team.",
22
+ "Needs to be strong. A weak model here will silently skip steps and break the workflow."
23
+ ],
24
+ "suggestions": {
25
+ "opencode": "opencode/claude-sonnet-4",
26
+ "opencode-go": null,
27
+ "github-copilot": "github-copilot/claude-sonnet-4.5",
28
+ "anthropic": "anthropic/claude-sonnet-4-5",
29
+ "google": "google/gemini-2.5-pro",
30
+ "openai": "openai/o3",
31
+ "deepseek": null
32
+ }
33
+ },
34
+ "build": {
35
+ "prompt": "Build model:",
36
+ "info": [
37
+ "BUILD: engineers: implements code, runs tests, commits.",
38
+ "Code quality matters here. DeepSeek V4 is outstanding value. Claude Sonnet is the gold standard."
39
+ ],
40
+ "suggestions": {
41
+ "opencode": "opencode/deepseek-v4-flash",
42
+ "opencode-go": "opencode-go/deepseek-v4-pro",
43
+ "github-copilot": "github-copilot/claude-sonnet-4.5",
44
+ "anthropic": "anthropic/claude-sonnet-4-5",
45
+ "google": "google/gemini-2.5-flash",
46
+ "openai": "openai/gpt-4.1",
47
+ "deepseek": "deepseek/deepseek-v4-pro"
48
+ },
49
+ "agents": ["fullstack-engineer"]
50
+ },
51
+ "fast": {
52
+ "prompt": "Fast model:",
53
+ "info": [
54
+ "FAST: light commands: /pc-pullrequest, /pc-explore, /pc-archive, status checks.",
55
+ "No heavy reasoning needed. Cheap and fast is the right call here."
56
+ ],
57
+ "suggestions": {
58
+ "opencode": "opencode/glm-4.7",
59
+ "opencode-go": "opencode-go/qwen3.6-plus",
60
+ "github-copilot": "github-copilot/gpt-5.4-nano",
61
+ "anthropic": "anthropic/claude-haiku-4-5",
62
+ "google": "google/gemini-2.0-flash",
63
+ "openai": "openai/gpt-4o-mini",
64
+ "deepseek": null
65
+ }
66
+ }
67
+ }
68
+ }
@@ -1,32 +1,32 @@
1
- {
2
- "message": "Enable tools:",
3
- "info": "Choose which optimization tools to enable (recommended: all).",
4
- "timeoutMs": 30000,
5
- "choices": [
6
- {
7
- "name": "RTK check (recommended)",
8
- "value": "rtk",
9
- "checked": true
10
- },
11
- {
12
- "name": "Simple English concise mode (recommended)",
13
- "value": "simpleEnglish",
14
- "checked": true
15
- },
16
- {
17
- "name": "codegraph semantic index (recommended)",
18
- "value": "codegraph",
19
- "checked": true
20
- },
21
- {
22
- "name": "agentmemory local memory server",
23
- "value": "memory",
24
- "checked": true
25
- },
26
- {
27
- "name": "humanizer skill (removes AI writing patterns)",
28
- "value": "humanizer",
29
- "checked": true
30
- }
31
- ]
32
- }
1
+ {
2
+ "message": "Enable tools:",
3
+ "info": "Choose which optimization tools to enable (recommended: all).",
4
+ "timeoutMs": 30000,
5
+ "choices": [
6
+ {
7
+ "name": "RTK check (recommended)",
8
+ "value": "rtk",
9
+ "checked": true
10
+ },
11
+ {
12
+ "name": "Simple English concise mode (recommended)",
13
+ "value": "simpleEnglish",
14
+ "checked": true
15
+ },
16
+ {
17
+ "name": "codegraph semantic index (recommended)",
18
+ "value": "codegraph",
19
+ "checked": true
20
+ },
21
+ {
22
+ "name": "agentmemory local memory server",
23
+ "value": "memory",
24
+ "checked": true
25
+ },
26
+ {
27
+ "name": "humanizer skill (removes AI writing patterns)",
28
+ "value": "humanizer",
29
+ "checked": true
30
+ }
31
+ ]
32
+ }
@@ -1,76 +1,76 @@
1
- [
2
- {
3
- "value": "github",
4
- "name": "GitHub",
5
- "cli": {
6
- "command": "gh",
7
- "displayName": "GitHub CLI (gh)",
8
- "installUrl": "https://cli.github.com",
9
- "authCheck": {
10
- "args": ["auth", "status"],
11
- "notAuthenticatedMessage": "GitHub CLI not authenticated. Run:",
12
- "commands": ["gh auth login"]
13
- }
14
- }
15
- },
16
- {
17
- "value": "azure",
18
- "name": "Azure DevOps",
19
- "cli": {
20
- "command": "az",
21
- "displayName": "Azure CLI (az)",
22
- "installUrl": "https://learn.microsoft.com/en-us/cli/azure/install-azure-cli",
23
- "extensionCheck": {
24
- "args": ["extension", "list", "--query", "[?name=='azure-devops']", "-o", "tsv"],
25
- "expectedOutput": "azure-devops",
26
- "missingMessage": "azure-devops extension not found. Run:",
27
- "errorMessage": "Could not check azure-devops extension. Run:",
28
- "commands": [
29
- "az extension add --name azure-devops",
30
- "az config set extension.dynamic_install_allow_preview=true",
31
- "az login",
32
- "az devops login --organization https://dev.azure.com/<your-org>"
33
- ]
34
- }
35
- }
36
- },
37
- {
38
- "value": "jira",
39
- "name": "Jira (Atlassian)",
40
- "backlogOnly": true,
41
- "cli": {
42
- "command": "acli",
43
- "displayName": "Atlassian CLI (acli)",
44
- "installUrl": "https://developer.atlassian.com/cloud/acli/guides/install-acli/",
45
- "authCheck": {
46
- "args": ["jira", "auth", "status"],
47
- "notAuthenticatedMessage": "Atlassian CLI not authenticated. Run:",
48
- "commands": ["acli jira auth login --site <yoursite>.atlassian.net --email <email> --token"]
49
- }
50
- }
51
- },
52
- {
53
- "value": "gitlab",
54
- "name": "GitLab",
55
- "repoOnly": true,
56
- "cli": {
57
- "command": "glab",
58
- "displayName": "GitLab CLI (glab)",
59
- "installUrl": "https://gitlab.com/gitlab-org/cli/#installation",
60
- "authCheck": {
61
- "args": ["auth", "status"],
62
- "notAuthenticatedMessage": "GitLab CLI not authenticated. Run:",
63
- "commands": ["glab auth login"]
64
- }
65
- }
66
- },
67
- {
68
- "value": "browser",
69
- "name": "Others (Browser)",
70
- "backlogOnly": true
71
- },
72
- {
73
- "value": "none",
74
- "name": "None"
75
- }
76
- ]
1
+ [
2
+ {
3
+ "value": "github",
4
+ "name": "GitHub",
5
+ "cli": {
6
+ "command": "gh",
7
+ "displayName": "GitHub CLI (gh)",
8
+ "installUrl": "https://cli.github.com",
9
+ "authCheck": {
10
+ "args": ["auth", "status"],
11
+ "notAuthenticatedMessage": "GitHub CLI not authenticated. Run:",
12
+ "commands": ["gh auth login"]
13
+ }
14
+ }
15
+ },
16
+ {
17
+ "value": "azure",
18
+ "name": "Azure DevOps",
19
+ "cli": {
20
+ "command": "az",
21
+ "displayName": "Azure CLI (az)",
22
+ "installUrl": "https://learn.microsoft.com/en-us/cli/azure/install-azure-cli",
23
+ "extensionCheck": {
24
+ "args": ["extension", "list", "--query", "[?name=='azure-devops']", "-o", "tsv"],
25
+ "expectedOutput": "azure-devops",
26
+ "missingMessage": "azure-devops extension not found. Run:",
27
+ "errorMessage": "Could not check azure-devops extension. Run:",
28
+ "commands": [
29
+ "az extension add --name azure-devops",
30
+ "az config set extension.dynamic_install_allow_preview=true",
31
+ "az login",
32
+ "az devops login --organization https://dev.azure.com/<your-org>"
33
+ ]
34
+ }
35
+ }
36
+ },
37
+ {
38
+ "value": "jira",
39
+ "name": "Jira (Atlassian)",
40
+ "backlogOnly": true,
41
+ "cli": {
42
+ "command": "acli",
43
+ "displayName": "Atlassian CLI (acli)",
44
+ "installUrl": "https://developer.atlassian.com/cloud/acli/guides/install-acli/",
45
+ "authCheck": {
46
+ "args": ["jira", "auth", "status"],
47
+ "notAuthenticatedMessage": "Atlassian CLI not authenticated. Run:",
48
+ "commands": ["acli jira auth login --site <yoursite>.atlassian.net --email <email> --token"]
49
+ }
50
+ }
51
+ },
52
+ {
53
+ "value": "gitlab",
54
+ "name": "GitLab",
55
+ "repoOnly": true,
56
+ "cli": {
57
+ "command": "glab",
58
+ "displayName": "GitLab CLI (glab)",
59
+ "installUrl": "https://gitlab.com/gitlab-org/cli/#installation",
60
+ "authCheck": {
61
+ "args": ["auth", "status"],
62
+ "notAuthenticatedMessage": "GitLab CLI not authenticated. Run:",
63
+ "commands": ["glab auth login"]
64
+ }
65
+ }
66
+ },
67
+ {
68
+ "value": "browser",
69
+ "name": "Others (Browser)",
70
+ "backlogOnly": true
71
+ },
72
+ {
73
+ "value": "none",
74
+ "name": "None"
75
+ }
76
+ ]
@@ -1,23 +1,23 @@
1
- {
2
- "message": "Source code location:",
3
- "default": "current",
4
- "choices": [
5
- {
6
- "name": "Current folder (default)",
7
- "value": "current",
8
- "description": "Use this repository only"
9
- },
10
- {
11
- "name": "Select folders in parent (../)",
12
- "value": "parent",
13
- "description": "Use when this repo only contains agent config"
14
- },
15
- {
16
- "name": "Select child folders (./*/)",
17
- "value": "children",
18
- "description": "Use when source code lives in subdirectories of this repo"
19
- }
20
- ],
21
- "parentSelectionMessage": "Select source folders from parent directory:",
22
- "childrenSelectionMessage": "Select child folders to include as source:"
23
- }
1
+ {
2
+ "message": "Source code location:",
3
+ "default": "current",
4
+ "choices": [
5
+ {
6
+ "name": "Current folder (default)",
7
+ "value": "current",
8
+ "description": "Use this repository only"
9
+ },
10
+ {
11
+ "name": "Select folders in parent (../)",
12
+ "value": "parent",
13
+ "description": "Use when this repo only contains agent config"
14
+ },
15
+ {
16
+ "name": "Select child folders (./*/)",
17
+ "value": "children",
18
+ "description": "Use when source code lives in subdirectories of this repo"
19
+ }
20
+ ],
21
+ "parentSelectionMessage": "Select source folders from parent directory:",
22
+ "childrenSelectionMessage": "Select child folders to include as source:"
23
+ }
@@ -1,48 +1,52 @@
1
- import { execa } from 'execa'
2
- import fse from 'fs-extra'
3
- import { header, info, success, warn, error } from '../../utils/exec.js'
4
- import os from 'os'
5
- import path from 'path'
6
- import { fileURLToPath } from 'url'
7
-
8
- const __dirname = path.dirname(fileURLToPath(import.meta.url))
9
- const BROWSER_PRESET_PATH = path.resolve(__dirname, '../../presets/browser.json')
10
- const browserPreset = await fse.readJson(BROWSER_PRESET_PATH)
11
-
12
- export async function installBrowser() {
13
- header('Step 9, Installing agent-browser')
14
-
15
- try {
16
- const install = await execa(browserPreset.installer.command, browserPreset.installer.args, {
17
- cwd: os.homedir(),
18
- reject: false,
19
- })
20
-
21
- if (install.exitCode !== 0) {
22
- warn('agent-browser npm install exited with non-zero code')
23
- if (install.stderr) info(install.stderr)
24
- return
25
- }
26
- success('agent-browser installed')
27
- } catch (err) {
28
- error(`Failed to install agent-browser: ${err.message}`)
29
- return
30
- }
31
-
32
- try {
33
- const chrome = await execa(browserPreset.chromeSetup.command, browserPreset.chromeSetup.args, {
34
- cwd: os.homedir(),
35
- reject: false,
36
- })
37
-
38
- if (chrome.exitCode === 0) {
39
- success('agent-browser Chrome ready')
40
- if (chrome.stdout) info(chrome.stdout.trim())
41
- } else {
42
- warn('agent-browser install (Chrome setup) exited with non-zero code')
43
- if (chrome.stderr) info(chrome.stderr)
44
- }
45
- } catch (err) {
46
- error(`Failed to set up Chrome for agent-browser: ${err.message}`)
47
- }
48
- }
1
+ import { execa } from 'execa'
2
+ import fse from 'fs-extra'
3
+ import { header, info, success, warn, error } from '../../utils/exec.js'
4
+ import os from 'os'
5
+ import path from 'path'
6
+ import { fileURLToPath } from 'url'
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
9
+ const BROWSER_PRESET_PATH = path.resolve(__dirname, '../../presets/browser.json')
10
+ const browserPreset = await fse.readJson(BROWSER_PRESET_PATH)
11
+
12
+ export async function installBrowser() {
13
+ header('Step 9, Installing browse')
14
+
15
+ try {
16
+ const install = await execa(browserPreset.installer.command, browserPreset.installer.args, {
17
+ cwd: os.homedir(),
18
+ reject: false,
19
+ })
20
+
21
+ if (install.exitCode !== 0) {
22
+ warn('browse npm install exited with non-zero code')
23
+ if (install.stderr) info(install.stderr)
24
+ return
25
+ }
26
+ success('browse installed')
27
+ } catch (err) {
28
+ error(`Failed to install browse: ${err.message}`)
29
+ return
30
+ }
31
+
32
+ try {
33
+ const setup = await execa(browserPreset.setup.command, browserPreset.setup.args, {
34
+ cwd: os.homedir(),
35
+ reject: false,
36
+ timeout: 180000,
37
+ })
38
+
39
+ if (setup.exitCode === 0) {
40
+ success('browse paired with your browser')
41
+ if (setup.stdout) info(setup.stdout.trim())
42
+ } else {
43
+ // browse install opens the Chrome Web Store and waits for the extension to connect.
44
+ // A non-zero exit often just means the user didn't finish pairing in time; browse is
45
+ // still installed and usable once they add the extension and run `browse pair`.
46
+ warn('browse setup did not complete — install the extension and run `browse pair`')
47
+ if (setup.stderr) info(setup.stderr)
48
+ }
49
+ } catch (err) {
50
+ error(`Failed to set up browse: ${err.message}`)
51
+ }
52
+ }