@plainconceptsplatform/agent-harness 2.2.1 → 2.4.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 (155) hide show
  1. package/README.md +23 -12
  2. package/{src → cli}/commands/join.js +3 -4
  3. package/{src → cli}/commands/migrate.js +1 -1
  4. package/{src → cli}/commands/update.js +13 -1
  5. package/{src → cli}/commands/wizard.js +1 -1
  6. package/{src → cli}/index.js +1 -1
  7. package/{src → cli}/presets/agents-content.json +4 -4
  8. package/cli/presets/browser.json +10 -0
  9. package/{src → cli}/presets/clean.json +21 -21
  10. package/{src → cli}/presets/optimization.json +37 -37
  11. package/{src → cli}/presets/platforms.json +76 -76
  12. package/{src → cli}/presets/quota.json +16 -16
  13. package/{src → cli}/presets/source.json +23 -23
  14. package/cli/steps/browser/index.js +48 -0
  15. package/{src → cli}/steps/clean/index.js +120 -120
  16. package/{src → cli}/steps/copy/agents.js +119 -119
  17. package/{src → cli}/steps/copy/commands.js +95 -95
  18. package/{src → cli}/steps/copy/fullstack-engineer.js +5 -1
  19. package/{src → cli}/steps/copy/index.js +1 -1
  20. package/{src → cli}/steps/copy/opencode-json.js +50 -1
  21. package/{src → cli}/steps/copy/skills.js +2 -2
  22. package/{src → cli}/steps/metadata/index.js +4 -0
  23. package/{src → cli}/steps/models/format.js +88 -88
  24. package/{src → cli}/steps/models/index.js +64 -64
  25. package/{src → cli}/steps/openspec/index.js +136 -136
  26. package/{src → cli}/steps/optimization/codegraph.js +127 -127
  27. package/cli/steps/optimization/detect.js +66 -0
  28. package/{src → cli}/steps/optimization/humanizer.js +17 -17
  29. package/{src → cli}/steps/optimization/index.js +163 -163
  30. package/{src → cli}/steps/optimization/memory.js +88 -88
  31. package/{src → cli}/steps/optimization/patch-guardrails.js +109 -109
  32. package/{src → cli}/steps/optimization/quota.js +119 -119
  33. package/{src → cli}/steps/optimization/simple-english.js +17 -17
  34. package/{src → cli}/steps/optimization/skills-lock.js +30 -30
  35. package/{src → cli}/steps/platform/index.js +109 -109
  36. package/{src → cli}/steps/source/index.js +123 -123
  37. package/cli/utils/agent-color.js +111 -0
  38. package/{src → cli}/utils/exec-spinner.js +47 -47
  39. package/{src → cli}/utils/exec.js +134 -134
  40. package/{src → cli}/utils/models-pricing.js +42 -42
  41. package/{src → cli}/utils/paths.js +1 -1
  42. package/{src → cli}/utils/process.js +3 -3
  43. package/{src → cli}/utils/terminal.js +6 -6
  44. package/harness/.agents/skills/browser-automation/SKILL.md +72 -0
  45. package/{src/content → harness}/.agents/skills/pc-make-engineer/SKILL.md +1 -1
  46. package/{src/content → harness}/.agents/skills/pc-make-engineer/template.md +1 -2
  47. package/{src/content → harness}/.agents/skills/pc-plan-archive/SKILL.md +3 -0
  48. package/{src/content → harness}/.agents/skills/pc-plan-explore/SKILL.md +3 -0
  49. package/{src/content → harness}/.agents/skills/pc-plan-goal/SKILL.md +5 -16
  50. package/{src/content → harness}/.agents/skills/pc-plan-goal/branching.md +1 -1
  51. package/{src/content → harness}/.agents/skills/pc-plan-goal/output.md +5 -8
  52. package/{src/content → harness}/.agents/skills/pc-plan-story/SKILL.md +3 -0
  53. package/{src/content → harness}/.agents/skills/pc-userstory-browser/SKILL.md +136 -132
  54. package/{src/content → harness}/.opencode/package.json +9 -10
  55. package/{src/content → harness}/.opencode/plugins/pc-subagent-tiers.js +91 -4
  56. package/{src/content → harness}/ARCHITECTURE.md +16 -16
  57. package/{src/content → harness}/DESIGN.md +16 -16
  58. package/{src/content → harness}/opencode.jsonc +11 -3
  59. package/{src/content → harness}/openspec/config.yaml +20 -20
  60. package/{src/content → harness}/skills-lock.json +17 -17
  61. package/package.json +7 -7
  62. package/src/content/.agents/skills/browser-automation/SKILL.md +0 -66
  63. package/src/presets/browser.json +0 -22
  64. package/src/steps/browser/index.js +0 -91
  65. /package/{src → cli}/commands/shared.js +0 -0
  66. /package/{src → cli}/commands/single.js +0 -0
  67. /package/{src → cli}/fragments/archive/az.md +0 -0
  68. /package/{src → cli}/fragments/archive/gh.md +0 -0
  69. /package/{src → cli}/fragments/archive/gl.md +0 -0
  70. /package/{src → cli}/fragments/archive/none.md +0 -0
  71. /package/{src → cli}/fragments/guardrails/codegraph.md +0 -0
  72. /package/{src → cli}/fragments/guardrails/humanizer.md +0 -0
  73. /package/{src → cli}/fragments/guardrails/memory.md +0 -0
  74. /package/{src → cli}/fragments/guardrails/rtk.md +0 -0
  75. /package/{src → cli}/fragments/guardrails/simple-english.md +0 -0
  76. /package/{src → cli}/fragments/ops-backlog/az.md +0 -0
  77. /package/{src → cli}/fragments/ops-backlog/gh.md +0 -0
  78. /package/{src → cli}/fragments/ops-backlog/jira.md +0 -0
  79. /package/{src → cli}/fragments/ops-evidence/az.md +0 -0
  80. /package/{src → cli}/fragments/ops-evidence/gh.md +0 -0
  81. /package/{src → cli}/fragments/ops-evidence/jira.md +0 -0
  82. /package/{src → cli}/fragments/ops-review/az.md +0 -0
  83. /package/{src → cli}/fragments/ops-review/gh.md +0 -0
  84. /package/{src → cli}/fragments/ops-review/gl.md +0 -0
  85. /package/{src → cli}/fragments/ops-ship/az.md +0 -0
  86. /package/{src → cli}/fragments/ops-ship/gh.md +0 -0
  87. /package/{src → cli}/fragments/ops-ship/gl.md +0 -0
  88. /package/{src → cli}/presets/models.json +0 -0
  89. /package/{src → cli}/presets/openspec.json +0 -0
  90. /package/{src → cli}/steps/models/write.js +0 -0
  91. /package/{src → cli}/utils/copy.js +0 -0
  92. /package/{src → cli}/utils/legacy-check.js +0 -0
  93. /package/{src → cli}/utils/models-cache.js +0 -0
  94. /package/{src → cli}/utils/update-manifest.js +0 -0
  95. /package/{src/content → harness}/.agents/skills/pc-guardrails-generic/SKILL.md +0 -0
  96. /package/{src/content → harness}/.agents/skills/pc-guardrails-project/SKILL.md +0 -0
  97. /package/{src/content → harness}/.agents/skills/pc-make-architecture/SKILL.md +0 -0
  98. /package/{src/content → harness}/.agents/skills/pc-make-architecture/structure-template.md +0 -0
  99. /package/{src/content → harness}/.agents/skills/pc-make-design/SKILL.md +0 -0
  100. /package/{src/content → harness}/.agents/skills/pc-make-engineer/signal-mapping.md +0 -0
  101. /package/{src/content → harness}/.agents/skills/pc-make-evidence-scaffold/SKILL.md +0 -0
  102. /package/{src/content → harness}/.agents/skills/pc-make-evidence-scaffold/evidence-contract.md +0 -0
  103. /package/{src/content → harness}/.agents/skills/pc-make-guardrails/SKILL.md +0 -0
  104. /package/{src/content → harness}/.agents/skills/pc-make-guardrails/category-reference.md +0 -0
  105. /package/{src/content → harness}/.agents/skills/pc-make-merge-risk-assess/SKILL.md +0 -0
  106. /package/{src/content → harness}/.agents/skills/pc-make-merge-risk-assess/category-reference.md +0 -0
  107. /package/{src/content → harness}/.agents/skills/pc-make-user-model/SKILL.md +0 -0
  108. /package/{src/content → harness}/.agents/skills/pc-ops-evidence/SKILL.md +0 -0
  109. /package/{src/content → harness}/.agents/skills/pc-ops-ship/SKILL.md +0 -0
  110. /package/{src/content → harness}/.agents/skills/pc-plan-apply/SKILL.md +0 -0
  111. /package/{src/content → harness}/.agents/skills/pc-plan-apply/simple-mode.md +0 -0
  112. /package/{src/content → harness}/.agents/skills/pc-plan-goal/failure-policy.md +0 -0
  113. /package/{src/content → harness}/.agents/skills/pc-plan-goal/output-mode.md +0 -0
  114. /package/{src/content → harness}/.agents/skills/pc-plan-propose/SKILL.md +0 -0
  115. /package/{src/content → harness}/.agents/skills/pc-plan-propose/task-annotation.md +0 -0
  116. /package/{src/content → harness}/.agents/skills/pc-plan-quick/SKILL.md +0 -0
  117. /package/{src/content → harness}/.agents/skills/pc-repo-audit/SKILL.md +0 -0
  118. /package/{src/content → harness}/.agents/skills/pc-repo-help/SKILL.md +0 -0
  119. /package/{src/content → harness}/.agents/skills/pc-repo-initialize/SKILL.md +0 -0
  120. /package/{src/content → harness}/.agents/skills/pc-repo-onboard/SKILL.md +0 -0
  121. /package/{src/content → harness}/.agents/skills/pc-repo-verify/SKILL.md +0 -0
  122. /package/{src/content → harness}/.agents/skills/pc-userstory-az/SKILL.md +0 -0
  123. /package/{src/content → harness}/.agents/skills/pc-userstory-gh/SKILL.md +0 -0
  124. /package/{src/content → harness}/.agents/skills/pc-userstory-jira/SKILL.md +0 -0
  125. /package/{src/content → harness}/.opencode/_gitignore +0 -0
  126. /package/{src/content → harness}/.opencode/commands/init.md +0 -0
  127. /package/{src/content → harness}/.opencode/commands/make-architecture.md +0 -0
  128. /package/{src/content → harness}/.opencode/commands/make-design.md +0 -0
  129. /package/{src/content → harness}/.opencode/commands/make-engineer.md +0 -0
  130. /package/{src/content → harness}/.opencode/commands/make-evidence-scaffold.md +0 -0
  131. /package/{src/content → harness}/.opencode/commands/make-guardrails.md +0 -0
  132. /package/{src/content → harness}/.opencode/commands/make-user-model.md +0 -0
  133. /package/{src/content → harness}/.opencode/commands/ops-backlog.md +0 -0
  134. /package/{src/content → harness}/.opencode/commands/ops-evidence.md +0 -0
  135. /package/{src/content → harness}/.opencode/commands/ops-review.md +0 -0
  136. /package/{src/content → harness}/.opencode/commands/ops-ship.md +0 -0
  137. /package/{src/content → harness}/.opencode/commands/plan-apply.md +0 -0
  138. /package/{src/content → harness}/.opencode/commands/plan-archive.md +0 -0
  139. /package/{src/content → harness}/.opencode/commands/plan-explore.md +0 -0
  140. /package/{src/content → harness}/.opencode/commands/plan-goal.md +0 -0
  141. /package/{src/content → harness}/.opencode/commands/plan-propose.md +0 -0
  142. /package/{src/content → harness}/.opencode/commands/plan-quick.md +0 -0
  143. /package/{src/content → harness}/.opencode/commands/plan-story.md +0 -0
  144. /package/{src/content → harness}/.opencode/commands/repo-audit.md +0 -0
  145. /package/{src/content → harness}/.opencode/commands/repo-help.md +0 -0
  146. /package/{src/content → harness}/.opencode/commands/repo-initialize.md +0 -0
  147. /package/{src/content → harness}/.opencode/commands/repo-onboard.md +0 -0
  148. /package/{src/content → harness}/.opencode/commands/repo-verify.md +0 -0
  149. /package/{src/content → harness}/.opencode/plugins/pc-subagent-monitor.js +0 -0
  150. /package/{src/content → harness}/.opencode/plugins/pc-system-reminders.js +0 -0
  151. /package/{src/content → harness}/.opencode/tui/pc-subagents.tsx +0 -0
  152. /package/{src/content → harness}/.opencode/tui.json +0 -0
  153. /package/{src/content → harness}/AGENTS.md +0 -0
  154. /package/{src/content → harness}/openspec/changes/archive/.gitkeep +0 -0
  155. /package/{src/content → harness}/openspec/specs/.gitkeep +0 -0
@@ -1,132 +1,136 @@
1
- ---
2
- name: pc-userstory
3
- description: Parse work item from any URL using browser automation. Use when user provides a URL that doesn't match GitHub/Azure/Jira CLI platforms, or when backlog platform is 'browser'.
4
- license: MIT
5
- compatibility: Requires opencode-browser extension and openspec CLI.
6
- metadata:
7
- author: copilots
8
- version: "1.0"
9
- ---
10
-
11
- This skill is used when the backlog platform is set to "Others (Browser)": when there is no CLI integration for the backlog system, or the user doesn't have API tokens. Work items are read directly from the web page using the opencode-browser plugin.
12
-
13
- This skill overrides the `browser-automation` skill's external navigation restriction, but only for URLs the user explicitly provides as work items. Navigate only to URLs the user gives you.
14
-
15
- ## Prerequisites
16
-
17
- - opencode-browser extension installed and running (installed during onboarding)
18
- - The user must be authenticated to the backlog system in their browser (e.g. logged into Azure DevOps, Jira, Trello, Linear, etc.)
19
-
20
- ## Steps
21
-
22
- 1. **Extract the URL** from the user's message
23
- - The user provides a direct URL to a work item, issue, ticket, or PBI
24
- - Examples: `https://dev.azure.com/org/project/_workitems/edit/123`, `https://linear.app/team/issue/ENG-123`, `https://trello.com/c/abc123`, `https://your-tool.com/ticket/456`
25
-
26
- 2. **Navigate to the URL**
27
- ```bash
28
- browser_open_tab url="https://the-url-the-user-provided"
29
- ```
30
-
31
- 3. **Wait for the page to load**
32
- ```bash
33
- browser_wait ms=3000
34
- ```
35
-
36
- 4. **Read the work item content**
37
- ```bash
38
- browser_query mode="page_text"
39
- ```
40
-
41
- Also try to get structured content:
42
- ```bash
43
- browser_snapshot
44
- ```
45
- The accessibility snapshot often reveals the work item title, description, and fields more precisely than raw page text.
46
-
47
- 5. **Parse work item fields**
48
-
49
- From the page text and/or snapshot, extract:
50
- - Title/Summary: usually the main heading or the `<h1>` / page title
51
- - Description: the body text, acceptance criteria, or "Definition of Done" section
52
- - ID/Key: the work item ID from the URL or page (e.g. `123`, `ENG-123`)
53
- - Status: if visible (e.g. "To Do", "In Progress", "Active")
54
- - Assignee: if visible
55
- - Priority: if visible
56
- - Labels/Tags: if visible
57
-
58
- If the page is a SPA that loads content dynamically:
59
- - Wait longer (`browser_wait ms=5000`)
60
- - Use `browser_query` with `mode=page_text` after the wait
61
- - Try `browser_snapshot` which may capture more structured content
62
-
63
- 6. **Create OpenSpec Change**
64
- ```bash
65
- openspec new change "{slug-from-title}"
66
- ```
67
-
68
- Write `proposal.md` with:
69
- - Title: the work item title from the page
70
- - Context: mention the source URL and the work item ID
71
- - Requirements: extracted from description and acceptance criteria
72
- - Scope: what's in/out based on the ticket
73
-
74
- 7. **Hand off to proposal.** Load the `pc-plan-propose` skill (interactive mode) to generate the proposal, specs, and tasks. After it completes, call the `question` tool:
75
-
76
- ```json
77
- {
78
- "questions": [
79
- {
80
- "header": "Ready to implement",
81
- "question": "Ready to implement?",
82
- "options": [
83
- { "label": "yes", "description": "Load the pc-plan-apply skill to start implementation." },
84
- { "label": "no", "description": "Stop here. You can run /plan-apply later." }
85
- ]
86
- }
87
- ]
88
- }
89
- ```
90
-
91
- Wait for confirmation before loading `pc-plan-apply`.
92
-
93
- ## Working with common backlog tools
94
-
95
- ### Azure DevOps (browser fallback)
96
- - URL: `https://dev.azure.com/{org}/{project}/_workitems/edit/{id}`
97
- - Title: visible in the work item header
98
- - Description: "Description" field section
99
- - Acceptance Criteria: "Acceptance Criteria" field section
100
- - State: visible in the top-right area
101
-
102
- ### Linear
103
- - URL: `https://linear.app/{team}/issue/{key}`
104
- - Title: the issue title
105
- - Description: the issue body
106
- - Status: visible as a dropdown
107
-
108
- ### Jira (browser fallback)
109
- - URL: `https://yoursite.atlassian.net/browse/{key}`
110
- - Title: the issue summary
111
- - Description: the description field
112
- - Status: visible in the status badge
113
-
114
- ### Trello
115
- - URL: `https://trello.com/c/{short-id}`
116
- - Title: the card title
117
- - Description: the card description
118
- - Labels: visible as colored badges
119
-
120
- ### Other tools (generic)
121
- - Look for `<h1>` or page title for the work item title
122
- - Look for the main content area for description
123
- - Use `browser_snapshot` to get structured accessibility tree data
124
-
125
- ## Rules
126
-
127
- - Navigate only to URLs the user explicitly provides. Never guess or browse randomly.
128
- - The user must already be authenticated in their browser to the backlog system.
129
- - If the page requires login and the user isn't authenticated, tell them to log in via their browser and retry.
130
- - For GitHub/Azure/Jira URLs when the CLI is configured for those platforms, use the CLI-based skill instead (faster, more reliable, no browser needed).
131
- - This skill is read-only: no clicking buttons, no changing status.
132
- - Browser is a backlog-only platform: it has no PR or repo integration. PR creation uses the repo platform configured separately.
1
+ ---
2
+ name: pc-userstory
3
+ description: Parse work item from any URL using browser automation. Use when user provides a URL that doesn't match GitHub/Azure/Jira CLI platforms, or when backlog platform is 'browser'.
4
+ license: MIT
5
+ compatibility: Requires agent-browser CLI installed and openspec CLI.
6
+ metadata:
7
+ author: copilots
8
+ version: "2.0"
9
+ ---
10
+
11
+ This skill is used when the backlog platform is set to "Others (Browser)": when there is no CLI integration for the backlog system, or the user doesn't have API tokens. Work items are read directly from the web page using agent-browser.
12
+
13
+ This skill overrides the `browser-automation` skill's external navigation restriction, but only for URLs the user explicitly provides as work items. Navigate only to URLs the user gives you.
14
+
15
+ ## Prerequisites
16
+
17
+ - agent-browser installed (installed during onboarding) — verify with `agent-browser doctor`
18
+ - An authenticated session for the backlog system:
19
+ - agent-browser runs its own Chrome, not the user's daily browser. Login state persists per session via `--session <slug> --restore`: log in once, and later runs restore cookies automatically.
20
+ - On first use, the user logs in manually in the opened window; state is saved on close and auto-restored afterwards.
21
+
22
+ ## Steps
23
+
24
+ 1. **Extract the URL** from the user's message
25
+ - The user provides a direct URL to a work item, issue, ticket, or PBI
26
+ - Examples: `https://dev.azure.com/org/project/_workitems/edit/123`, `https://linear.app/team/issue/ENG-123`, `https://trello.com/c/abc123`, `https://your-tool.com/ticket/456`
27
+
28
+ 2. **Open the URL in a persistent session**
29
+ ```bash
30
+ agent-browser --session backlog --restore open "https://the-url-the-user-provided"
31
+ ```
32
+
33
+ 3. **Wait for the page to load**
34
+ ```bash
35
+ agent-browser wait --load networkidle
36
+ ```
37
+ Prefer load-state waits over fixed sleeps; for SPAs that render after idle, add `agent-browser wait --text "<known heading>"` when a stable string is known.
38
+
39
+ 4. **Read the work item content**
40
+ ```bash
41
+ agent-browser snapshot
42
+ ```
43
+ The accessibility tree with `@ref` handles usually reveals the work item title, description, and fields more precisely than raw page text. Also useful:
44
+ ```bash
45
+ agent-browser read # agent-readable text of the active tab
46
+ agent-browser get text "h1" # the heading, when present
47
+ ```
48
+
49
+ 5. **Parse work item fields**
50
+
51
+ From the snapshot and/or text, extract:
52
+ - Title/Summary: usually the main heading or the `<h1>` / page title
53
+ - Description: the body text, acceptance criteria, or "Definition of Done" section
54
+ - ID/Key: the work item ID from the URL or page (e.g. `123`, `ENG-123`)
55
+ - Status: if visible (e.g. "To Do", "In Progress", "Active")
56
+ - Assignee: if visible
57
+ - Priority: if visible
58
+ - Labels/Tags: if visible
59
+
60
+ If the page is a SPA that loads content dynamically:
61
+ - Wait for load state again (`agent-browser wait --load networkidle`)
62
+ - Take a fresh `snapshot` after the wait
63
+ - `agent-browser get url` confirms you are still on the work item
64
+
65
+ If a login page appears instead, the session is not authenticated: tell the user to log in manually in the opened browser window, then retry from step 2 with the same `--session backlog --restore` (the login is saved for future runs).
66
+
67
+ 6. **Create OpenSpec Change**
68
+ ```bash
69
+ openspec new change "{slug-from-title}"
70
+ ```
71
+
72
+ Write `proposal.md` with:
73
+ - Title: the work item title from the page
74
+ - Context: mention the source URL and the work item ID
75
+ - Requirements: extracted from description and acceptance criteria
76
+ - Scope: what's in/out based on the ticket
77
+
78
+ 7. **Hand off to proposal.** Load the `pc-plan-propose` skill (interactive mode) to generate the proposal, specs, and tasks. After it completes, call the `question` tool:
79
+
80
+ ```json
81
+ {
82
+ "questions": [
83
+ {
84
+ "header": "Ready to implement",
85
+ "question": "Ready to implement?",
86
+ "options": [
87
+ { "label": "yes", "description": "Load the pc-plan-apply skill to start implementation." },
88
+ { "label": "no", "description": "Stop here. You can run /plan-apply later." }
89
+ ]
90
+ }
91
+ ]
92
+ }
93
+ ```
94
+
95
+ Wait for confirmation before loading `pc-plan-apply`.
96
+
97
+ ## Working with common backlog tools
98
+
99
+ ### Azure DevOps (browser fallback)
100
+ - URL: `https://dev.azure.com/{org}/{project}/_workitems/edit/{id}`
101
+ - Title: visible in the work item header
102
+ - Description: "Description" field section
103
+ - Acceptance Criteria: "Acceptance Criteria" field section
104
+ - State: visible in the top-right area
105
+
106
+ ### Linear
107
+ - URL: `https://linear.app/{team}/issue/{key}`
108
+ - Title: the issue title
109
+ - Description: the issue body
110
+ - Status: visible as a dropdown
111
+
112
+ ### Jira (browser fallback)
113
+ - URL: `https://yoursite.atlassian.net/browse/{key}`
114
+ - Title: the issue summary
115
+ - Description: the description field
116
+ - Status: visible in the status badge
117
+
118
+ ### Trello
119
+ - URL: `https://trello.com/c/{short-id}`
120
+ - Title: the card title
121
+ - Description: the card description
122
+ - Labels: visible as colored badges
123
+
124
+ ### Other tools (generic)
125
+ - Look for `<h1>` or page title for the work item title
126
+ - Look for the main content area for description
127
+ - Use `agent-browser snapshot` to get structured accessibility tree data
128
+
129
+ ## Rules
130
+
131
+ - Navigate only to URLs the user explicitly provide. Never guess or browse randomly.
132
+ - Reuse the `backlog` session (`--session backlog --restore`) so login state persists across runs.
133
+ - If the page requires login and the session is not authenticated, tell them to log in via the opened browser window and retry.
134
+ - For GitHub/Azure/Jira URLs when the CLI is configured for those platforms, use the CLI-based skill instead (faster, more reliable, no browser needed).
135
+ - This skill is read-only: no clicking buttons, no changing status.
136
+ - Browser is a backlog-only platform: it has no PR or repo integration. PR creation uses the repo platform configured separately.
@@ -1,10 +1,9 @@
1
- {
2
- "dependencies": {
3
- "@opencode-ai/plugin": "1.18.19",
4
- "@different-ai/opencode-browser": "4.6.1",
5
- "@mohak34/opencode-notifier": "0.2.8",
6
- "@opentui/core": "0.5.6",
7
- "@opentui/solid": "0.5.6",
8
- "solid-js": "1.9.12"
9
- }
10
- }
1
+ {
2
+ "dependencies": {
3
+ "@opencode-ai/plugin": "1.18.19",
4
+ "@mohak34/opencode-notifier": "0.2.8",
5
+ "@opentui/core": "0.5.6",
6
+ "@opentui/solid": "0.5.6",
7
+ "solid-js": "1.9.12"
8
+ }
9
+ }
@@ -24,19 +24,94 @@ const TIERS = ["build", "fast", "plan"]
24
24
  // The two primaries, and the tier each takes its model from. plan denies edit
25
25
  // so a planning session cannot mutate the tree; bash stays allowed because the
26
26
  // planning skills shell out to git and openspec to read state.
27
+ //
28
+ // Their colours are theme keywords rather than derived hexes, and they are
29
+ // fixed: these are the two agents a human picks, so they should look the same
30
+ // in every project regardless of the theme in use.
27
31
  const PRIMARIES = {
28
32
  build: {
29
33
  tier: "build",
34
+ color: "primary",
30
35
  description: "Implement changes in this repository. Full write access, spawns specialist engineers for parallel work.",
31
36
  permission: null,
32
37
  },
33
38
  plan: {
34
39
  tier: "plan",
40
+ color: "warning",
35
41
  description: "Explore and plan without touching the tree. Read-only: proposes work for build to carry out.",
36
42
  permission: { edit: "deny" },
37
43
  },
38
44
  }
39
45
 
46
+ // opencode's theme keywords. Treated as unset so a name-derived hex wins: the
47
+ // old /make-engineer template asked whoever ran it to pick one of these and
48
+ // avoid collisions by hand, which does not survive more than a few agents.
49
+ const THEME_COLORS = new Set(["primary", "secondary", "accent", "success", "warning", "error", "info"])
50
+
51
+ // Mirrors cli/utils/agent-color.js in the CLI, duplicated because a plugin has
52
+ // to stand alone in the consumer repo. agent-color.test.js asserts the two stay
53
+ // in step; change one and change the other.
54
+ //
55
+ // Only the hue is hashed. Fixed saturation and lightness are what keep every
56
+ // result usable: hashing those too would eventually produce a near-grey,
57
+ // near-black or near-white agent, invisible against one theme or the other.
58
+ function agentColor(name) {
59
+ let h = 0x811c9dc5
60
+ for (let i = 0; i < name.length; i++) {
61
+ h ^= name.charCodeAt(i)
62
+ h = Math.imul(h, 0x01000193) >>> 0
63
+ }
64
+ const hue = (h >>> 0) % 360
65
+ const sat = 0.68
66
+ const light = 0.52
67
+ const c = (1 - Math.abs(2 * light - 1)) * sat
68
+ const x = c * (1 - Math.abs(((hue / 60) % 2) - 1))
69
+ const m = light - c / 2
70
+ const [r, g, b] =
71
+ hue < 60 ? [c, x, 0] :
72
+ hue < 120 ? [x, c, 0] :
73
+ hue < 180 ? [0, c, x] :
74
+ hue < 240 ? [0, x, c] :
75
+ hue < 300 ? [x, 0, c] :
76
+ [c, 0, x]
77
+ const toHex = v => Math.round((v + m) * 255).toString(16).padStart(2, "0")
78
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase()
79
+ }
80
+
81
+ /** A theme keyword or a missing value yields to the derived hex; a hex stays. */
82
+ function shouldDeriveColor(current) {
83
+ if (!current) return true
84
+ return THEME_COLORS.has(current.trim().toLowerCase())
85
+ }
86
+
87
+ /**
88
+ * Render a colour for YAML frontmatter.
89
+ *
90
+ * A hex has to be quoted. `#` opens a comment in YAML, so `color: #D83155`
91
+ * parses as null and opencode refuses the agent with "Invalid input color".
92
+ * Theme keywords need no quoting and stay bare.
93
+ */
94
+ function yamlColor(value) {
95
+ return value.startsWith("#") ? `"${value}"` : value
96
+ }
97
+
98
+ function unquoteColor(raw) {
99
+ return (raw ?? "").trim().replace(/^["']/, "").replace(/["']$/, "")
100
+ }
101
+
102
+ /**
103
+ * The colour line an agent should have, or null when the current one is already
104
+ * right. Handles both choosing the colour and quoting it, so a file written by
105
+ * an earlier version with a bare hex is repaired in place rather than left
106
+ * broken.
107
+ */
108
+ function colorLineFor(name, rawCurrent) {
109
+ const current = unquoteColor(rawCurrent)
110
+ const target = shouldDeriveColor(current) ? agentColor(name) : current
111
+ const rendered = yamlColor(target)
112
+ return (rawCurrent ?? "").trim() === rendered ? null : `color: ${rendered}`
113
+ }
114
+
40
115
  const FULLSTACK_NAME = "fullstack-engineer"
41
116
  const FULLSTACK_TEMPLATE = `${FULLSTACK_NAME}.md`
42
117
 
@@ -102,7 +177,7 @@ export const PcSubagentTiers = async ({ directory }) => {
102
177
  // startup and are injected into generated files only, so a stale model: (from
103
178
  // a prior `stampAgentModels` run, or from when these were primary) is
104
179
  // stripped and the agent falls back to the session model in opencode.jsonc.
105
- function normalizeTemplate(templateContent) {
180
+ function normalizeTemplate(templateContent, name) {
106
181
  const fmMatch = templateContent.match(/^---\r?\n([\s\S]*?)\r?\n---/)
107
182
  if (!fmMatch) return templateContent
108
183
 
@@ -113,6 +188,17 @@ export const PcSubagentTiers = async ({ directory }) => {
113
188
  fm = /^mode:/m.test(fm) ? fm.replace(/^mode:.*$/m, 'mode: subagent') : `mode: subagent\n${fm}`
114
189
  changed = true
115
190
  }
191
+ // Give every agent a colour derived from its name, so the same engineer
192
+ // reads the same in any project and two agents never collide by accident.
193
+ // colorLineFor also repairs a bare #hex written by an earlier version,
194
+ // which YAML read as a comment and opencode rejected outright.
195
+ if (name) {
196
+ const colorLine = colorLineFor(name, fm.match(/^color:\s*(.+)$/m)?.[1])
197
+ if (colorLine) {
198
+ fm = /^color:/m.test(fm) ? fm.replace(/^color:.*$/m, () => colorLine) : `${fm}\n${colorLine}`
199
+ changed = true
200
+ }
201
+ }
116
202
  if (/^model:/m.test(fm)) {
117
203
  // Remove the model: line and its trailing newline without leaving a
118
204
  // leading blank line (model: can be the first frontmatter entry).
@@ -140,7 +226,7 @@ export const PcSubagentTiers = async ({ directory }) => {
140
226
  'mode: primary',
141
227
  ]
142
228
  if (model) lines.push(`model: ${model}`)
143
- lines.push('color: warning')
229
+ lines.push(`color: ${yamlColor(spec.color)}`)
144
230
  lines.push('permission:')
145
231
  // plan denies edit; everything else stays allowed so the planning skills can
146
232
  // still read the tree, shell out to git and openspec, and spawn engineers.
@@ -179,7 +265,7 @@ export const PcSubagentTiers = async ({ directory }) => {
179
265
  if (hasFullstack) {
180
266
  const fullstackPath = path.join(agentsDir, FULLSTACK_TEMPLATE)
181
267
  const rawFullstack = await fs.readFile(fullstackPath, "utf-8")
182
- const fullstack = normalizeTemplate(rawFullstack)
268
+ const fullstack = normalizeTemplate(rawFullstack, FULLSTACK_NAME)
183
269
  if (fullstack !== rawFullstack) {
184
270
  await writeIfChanged(fullstackPath, fullstack)
185
271
  console.error(`[pc-subagent-tiers] Normalized ${FULLSTACK_TEMPLATE} (mode: subagent)`)
@@ -198,6 +284,7 @@ export const PcSubagentTiers = async ({ directory }) => {
198
284
  ...cfg.agent[name],
199
285
  mode: 'primary',
200
286
  description: spec.description,
287
+ color: spec.color,
201
288
  ...(model ? { model } : {}),
202
289
  ...(spec.permission ? { permission: { ...cfg.agent[name]?.permission, ...spec.permission } } : {}),
203
290
  }
@@ -211,7 +298,7 @@ export const PcSubagentTiers = async ({ directory }) => {
211
298
  const templateContents = await Promise.all(
212
299
  templates.map(async name => {
213
300
  const rawContent = await fs.readFile(path.join(agentsDir, `${name}.md`), "utf-8")
214
- const content = normalizeTemplate(rawContent)
301
+ const content = normalizeTemplate(rawContent, name)
215
302
  // If the template had the wrong mode or a stale model:, persist the fix to disk
216
303
  if (content !== rawContent) {
217
304
  await writeIfChanged(path.join(agentsDir, `${name}.md`), content)
@@ -1,16 +1,16 @@
1
- > NOT GENERATED YET
2
- >
3
- > This file has not been populated yet. It is intentionally empty.
4
- >
5
- > **If this is a greenfield project** (no codebase exists yet): skip this for now.
6
- > Come back and run `/make-architecture` once you have meaningful code, structure, or infrastructure in place.
7
- >
8
- > **If this is a brownfield project** (existing codebase): run this command now to generate the architecture documentation:
9
- >
10
- > ```
11
- > /make-architecture
12
- > ```
13
- >
14
- > This command analyzes your folder structure, config files, routes, data models, integrations, and build setup,
15
- > then writes a complete ARCHITECTURE.md covering components, data flow, tech stack, deployment, and more.
16
- > It is safe to rerun any time the architecture changes significantly.
1
+ > NOT GENERATED YET
2
+ >
3
+ > This file has not been populated yet. It is intentionally empty.
4
+ >
5
+ > **If this is a greenfield project** (no codebase exists yet): skip this for now.
6
+ > Come back and run `/make-architecture` once you have meaningful code, structure, or infrastructure in place.
7
+ >
8
+ > **If this is a brownfield project** (existing codebase): run this command now to generate the architecture documentation:
9
+ >
10
+ > ```
11
+ > /make-architecture
12
+ > ```
13
+ >
14
+ > This command analyzes your folder structure, config files, routes, data models, integrations, and build setup,
15
+ > then writes a complete ARCHITECTURE.md covering components, data flow, tech stack, deployment, and more.
16
+ > It is safe to rerun any time the architecture changes significantly.
@@ -1,16 +1,16 @@
1
- > NOT GENERATED YET
2
- >
3
- > This file has not been populated yet. It is intentionally empty.
4
- >
5
- > **If this is a greenfield project** (no UI exists yet): skip this for now.
6
- > Come back and run `/make-design` once you have a design system, UI components, or styles in place.
7
- >
8
- > **If this is a brownfield project** (existing UI/styles): run this command now to generate the design documentation:
9
- >
10
- > ```
11
- > /make-design
12
- > ```
13
- >
14
- > This command analyzes your CSS, Tailwind config, component files, and design tokens,
15
- > then writes a complete DESIGN.md with structured YAML tokens and written design intent.
16
- > It is safe to rerun any time your design system changes.
1
+ > NOT GENERATED YET
2
+ >
3
+ > This file has not been populated yet. It is intentionally empty.
4
+ >
5
+ > **If this is a greenfield project** (no UI exists yet): skip this for now.
6
+ > Come back and run `/make-design` once you have a design system, UI components, or styles in place.
7
+ >
8
+ > **If this is a brownfield project** (existing UI/styles): run this command now to generate the design documentation:
9
+ >
10
+ > ```
11
+ > /make-design
12
+ > ```
13
+ >
14
+ > This command analyzes your CSS, Tailwind config, component files, and design tokens,
15
+ > then writes a complete DESIGN.md with structured YAML tokens and written design intent.
16
+ > It is safe to rerun any time your design system changes.
@@ -4,9 +4,15 @@
4
4
  "AGENTS.md"
5
5
  ],
6
6
  "plugin": [
7
- "@different-ai/opencode-browser@4.6.1",
8
7
  "@mohak34/opencode-notifier@0.2.8"
9
8
  ],
9
+ "mcp": {
10
+ "agent-browser": {
11
+ "type": "local",
12
+ "command": ["agent-browser", "mcp", "--tools", "core"],
13
+ "enabled": true
14
+ }
15
+ },
10
16
  "experimental": {
11
17
  "mcp_timeout": 300000
12
18
  },
@@ -23,12 +29,14 @@
23
29
  "skills": {
24
30
  "paths": [".agents/skills"]
25
31
  },
26
- // build and plan are the only primaries. The pc-subagent-tiers plugin
32
+ // build and plan are the only primaries, and plan is the default: a session
33
+ // starts read-only and you switch to build once you know what to change.
34
+ // The pc-subagent-tiers plugin
27
35
  // regenerates .opencode/agents/{build,plan}.md from fullstack-engineer.md on
28
36
  // every startup and overrides these two entries with the resolved tier model,
29
37
  // so what is here is only the floor if the plugin cannot run. Every engineer
30
38
  // is mode: subagent and reached through task(), never picked by a human.
31
- "default_agent": "build",
39
+ "default_agent": "plan",
32
40
  "agent": {
33
41
  "build": { "mode": "primary" },
34
42
  "plan": {
@@ -1,20 +1,20 @@
1
- schema: spec-driven
2
-
3
- # Project context (optional)
4
- # This is shown to AI when creating artifacts.
5
- # Add your tech stack, conventions, style guides, domain knowledge, etc.
6
- # Example:
7
- # context: |
8
- # Tech stack: TypeScript, React, Node.js
9
- # We use conventional commits
10
- # Domain: e-commerce platform
11
-
12
- # Per-artifact rules (optional)
13
- # Add custom rules for specific artifacts.
14
- # Example:
15
- # rules:
16
- # proposal:
17
- # - Keep proposals under 500 words
18
- # - Always include a "Non-goals" section
19
- # tasks:
20
- # - Break tasks into chunks of max 2 hours
1
+ schema: spec-driven
2
+
3
+ # Project context (optional)
4
+ # This is shown to AI when creating artifacts.
5
+ # Add your tech stack, conventions, style guides, domain knowledge, etc.
6
+ # Example:
7
+ # context: |
8
+ # Tech stack: TypeScript, React, Node.js
9
+ # We use conventional commits
10
+ # Domain: e-commerce platform
11
+
12
+ # Per-artifact rules (optional)
13
+ # Add custom rules for specific artifacts.
14
+ # Example:
15
+ # rules:
16
+ # proposal:
17
+ # - Keep proposals under 500 words
18
+ # - Always include a "Non-goals" section
19
+ # tasks:
20
+ # - Break tasks into chunks of max 2 hours
@@ -1,17 +1,17 @@
1
- {
2
- "version": 1,
3
- "skills": {
4
- "find-skills": {
5
- "source": "vercel-labs/skills",
6
- "sourceType": "github",
7
- "skillPath": "skills/find-skills/SKILL.md",
8
- "computedHash": "781bd6d3f9b19f8c9af6b53d8d0e4876d0183841b565db34ca7092ffa412d111"
9
- },
10
- "user-story": {
11
- "source": "deanpeters/product-manager-skills",
12
- "sourceType": "github",
13
- "skillPath": "skills/user-story/SKILL.md",
14
- "computedHash": "user-story-placeholder"
15
- }
16
- }
17
- }
1
+ {
2
+ "version": 1,
3
+ "skills": {
4
+ "find-skills": {
5
+ "source": "vercel-labs/skills",
6
+ "sourceType": "github",
7
+ "skillPath": "skills/find-skills/SKILL.md",
8
+ "computedHash": "781bd6d3f9b19f8c9af6b53d8d0e4876d0183841b565db34ca7092ffa412d111"
9
+ },
10
+ "user-story": {
11
+ "source": "deanpeters/product-manager-skills",
12
+ "sourceType": "github",
13
+ "skillPath": "skills/user-story/SKILL.md",
14
+ "computedHash": "user-story-placeholder"
15
+ }
16
+ }
17
+ }