@plainconceptsplatform/agent-harness 3.1.1 → 3.3.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 (87) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +24 -4
  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/wizard.js +134 -134
  8. package/cli/fragments/ops-backlog/az.md +28 -28
  9. package/cli/fragments/ops-backlog/gh.md +28 -28
  10. package/cli/fragments/ops-backlog/jira.md +28 -28
  11. package/cli/fragments/ops-review/az.md +62 -62
  12. package/cli/fragments/ops-review/gh.md +51 -51
  13. package/cli/fragments/ops-review/gl.md +55 -55
  14. package/cli/fragments/ops-ship/gh.md +67 -67
  15. package/cli/fragments/ops-ship/gl.md +84 -84
  16. package/cli/index.js +116 -116
  17. package/cli/presets/clean.json +21 -21
  18. package/cli/presets/models.json +68 -68
  19. package/cli/presets/optimization.json +32 -32
  20. package/cli/presets/platforms.json +76 -76
  21. package/cli/presets/source.json +23 -23
  22. package/cli/steps/clean/index.js +120 -120
  23. package/cli/steps/copy/agents.js +120 -120
  24. package/cli/steps/copy/fullstack-engineer.js +89 -89
  25. package/cli/steps/copy/opencode-json.js +324 -324
  26. package/cli/steps/models/format.js +88 -88
  27. package/cli/steps/models/index.js +64 -64
  28. package/cli/steps/openspec/index.js +136 -136
  29. package/cli/steps/optimization/codegraph.js +141 -127
  30. package/cli/steps/optimization/detect.js +66 -66
  31. package/cli/steps/optimization/humanizer.js +17 -17
  32. package/cli/steps/optimization/index.js +158 -158
  33. package/cli/steps/optimization/memory.js +91 -88
  34. package/cli/steps/optimization/patch-guardrails.js +111 -111
  35. package/cli/steps/optimization/simple-english.js +17 -17
  36. package/cli/steps/optimization/skills-lock.js +30 -30
  37. package/cli/steps/platform/index.js +109 -109
  38. package/cli/steps/source/index.js +123 -123
  39. package/cli/utils/agent-color.js +111 -111
  40. package/cli/utils/copy.js +134 -131
  41. package/cli/utils/exec-spinner.js +47 -47
  42. package/cli/utils/exec.js +134 -134
  43. package/cli/utils/legacy-check.js +30 -30
  44. package/cli/utils/models-cache.js +58 -58
  45. package/cli/utils/models-pricing.js +42 -42
  46. package/cli/utils/process.js +3 -3
  47. package/cli/utils/terminal.js +6 -6
  48. package/cli/utils/update-manifest.js +75 -75
  49. package/harness/.opencode/commands/ops-backlog.md +10 -10
  50. package/harness/.opencode/commands/ops-review.md +8 -8
  51. package/harness/.opencode/commands/ops-ship.md +9 -9
  52. package/harness/.opencode/commands/plan-archive.md +5 -5
  53. package/harness/.opencode/commands/plan-explore.md +9 -9
  54. package/harness/.opencode/commands/plan-propose.md +9 -9
  55. package/harness/.opencode/commands/repo-help.md +5 -5
  56. package/harness/.opencode/package.json +5 -5
  57. package/harness/.opencode/plugins/pc-subagent-monitor.js +184 -184
  58. package/harness/.opencode/plugins/pc-subagent-tiers.js +354 -354
  59. package/harness/.opencode/plugins/pc-system-reminders.js +386 -386
  60. package/harness/.opencode/scripts/check-diff.mjs +244 -0
  61. package/harness/.opencode/scripts/code-rules.mjs +288 -0
  62. package/harness/ARCHITECTURE.md +13 -13
  63. package/harness/DESIGN.md +13 -13
  64. package/harness/opencode.jsonc +36 -36
  65. package/harness/openspec/config.yaml +20 -20
  66. package/harness/skills-lock.json +17 -17
  67. package/package.json +14 -12
  68. package/skills/agent-harness-cli/SKILL.md +86 -86
  69. package/skills/pc-guardrails-generic/SKILL.md +2 -1
  70. package/skills/pc-guardrails-project/SKILL.md +8 -8
  71. package/skills/pc-make-architecture/structure-template.md +64 -64
  72. package/skills/pc-make-engineer/SKILL.md +59 -59
  73. package/skills/pc-make-engineer/template.md +36 -36
  74. package/skills/pc-make-guardrails/category-reference.md +112 -112
  75. package/skills/pc-make-merge-risk-assess/SKILL.md +70 -70
  76. package/skills/pc-make-merge-risk-assess/category-reference.md +114 -114
  77. package/skills/pc-ops-ship/SKILL.md +22 -18
  78. package/skills/pc-plan-apply/SKILL.md +86 -86
  79. package/skills/pc-plan-apply/simple-mode.md +1 -1
  80. package/skills/pc-plan-explore/SKILL.md +21 -21
  81. package/skills/pc-plan-goal/SKILL.md +91 -91
  82. package/skills/pc-plan-goal/failure-policy.md +30 -30
  83. package/skills/pc-plan-goal/output-mode.md +10 -10
  84. package/skills/pc-plan-propose/SKILL.md +125 -125
  85. package/skills/pc-plan-propose/task-annotation.md +39 -39
  86. package/skills/pc-plan-quick/SKILL.md +1 -1
  87. package/skills/pc-repo-audit/SKILL.md +44 -44
@@ -1,89 +1,89 @@
1
- import fse from 'fs-extra'
2
- import path from 'path'
3
- import { success } from '../../utils/exec.js'
4
- import { agentColor, yamlColor } from '../../utils/agent-color.js'
5
-
6
- const FULLSTACK_FILE = 'fullstack-engineer.md'
7
- const FULLSTACK_DESCRIPTION = 'Default engineer that accumulates skills from all created persona engineers. Use as fallback when no specialist matches: but prefer spawning a specific engineer for deterministic results.'
8
- const FULLSTACK_IDENTITY = 'You are the default engineer, and your body is what the build and plan agents run. You are more complete but less accurate than specialized engineers, so prefer spawning a specialist when one matches the task domain.'
9
-
10
- // The reminder plugin owns ability bootstrap. Remove the old prompt-level
11
- // directive when regenerating so it cannot duplicate the plugin reminder.
12
- function stripStartupDirective(text) {
13
- if (!text) return text
14
- return text
15
- .split(/\r?\n\r?\n+/)
16
- .filter(paragraph => !paragraph.trim().startsWith('**Startup'))
17
- .join('\n\n')
18
- .trim()
19
- }
20
-
21
- export async function removeLegacyStartupDirectives({ cwd = process.cwd() } = {}) {
22
- const agentsDir = path.join(cwd, '.opencode', 'agents')
23
- if (!await fse.pathExists(agentsDir)) return 0
24
-
25
- let updated = 0
26
- for (const fileName of await fse.readdir(agentsDir)) {
27
- if (!fileName.endsWith('.md')) continue
28
- const filePath = path.join(agentsDir, fileName)
29
- const content = await fse.readFile(filePath, 'utf-8')
30
- const cleaned = stripStartupDirective(content)
31
- if (cleaned === content.trim()) continue
32
- await fse.writeFile(filePath, `${cleaned}\n`, 'utf-8')
33
- updated++
34
- }
35
- return updated
36
- }
37
-
38
- export async function generateFullstackEngineer({ cwd = process.cwd(), updateMode = false } = {}) {
39
- const agentsDir = path.join(cwd, '.opencode', 'agents')
40
- await fse.ensureDir(agentsDir)
41
- const filePath = path.join(agentsDir, FULLSTACK_FILE)
42
-
43
- if (updateMode && await fse.pathExists(filePath)) {
44
- return { generated: false, preserved: true }
45
- }
46
-
47
- let existingAbilities = null
48
- let existingIdentity = null
49
- if (await fse.pathExists(filePath)) {
50
- const content = await fse.readFile(filePath, 'utf-8')
51
- const abilitiesMatch = content.match(/## Abilities\n([\s\S]*?)$/)
52
- if (abilitiesMatch) existingAbilities = abilitiesMatch[1].trim()
53
- const identityMatch = content.match(/^---\n[\s\S]*?\n---\n\n(.*?)(?:\n\n## Abilities)/s)
54
- if (identityMatch) existingIdentity = stripStartupDirective(identityMatch[1])
55
- }
56
-
57
- const frontmatter = [
58
- '---',
59
- `description: ${FULLSTACK_DESCRIPTION}`,
60
- // subagent, not primary: build.md and plan.md are the primaries, and
61
- // pc-subagent-tiers generates both from this file on every startup.
62
- 'mode: subagent',
63
- // warning is reserved for plan, so fullstack takes its name-derived hex
64
- // like every other subagent.
65
- // Quoted: a bare #hex is a YAML comment, which opencode rejects.
66
- `color: ${yamlColor(agentColor('fullstack-engineer'))}`,
67
- 'permission:',
68
- ' edit: allow',
69
- ' bash: allow',
70
- ' read: allow',
71
- ' glob: allow',
72
- ' grep: allow',
73
- ' question: allow',
74
- ' todowrite: allow',
75
- '---',
76
- ]
77
-
78
- const identity = existingIdentity ?? FULLSTACK_IDENTITY
79
-
80
- const abilities = existingAbilities ?? [
81
- '- Guardrails: @pc-guardrails-generic, @pc-guardrails-project',
82
- ].join('\n')
83
-
84
- const content = `${frontmatter.join('\n')}\n\n${identity}\n\n## Abilities\n${abilities}\n`
85
-
86
- await fse.writeFile(filePath, content, 'utf-8')
87
- success(`Generated ${FULLSTACK_FILE}`)
88
- return { generated: true }
89
- }
1
+ import fse from 'fs-extra'
2
+ import path from 'path'
3
+ import { success } from '../../utils/exec.js'
4
+ import { agentColor, yamlColor } from '../../utils/agent-color.js'
5
+
6
+ const FULLSTACK_FILE = 'fullstack-engineer.md'
7
+ const FULLSTACK_DESCRIPTION = 'Default engineer that accumulates skills from all created persona engineers. Use as fallback when no specialist matches: but prefer spawning a specific engineer for deterministic results.'
8
+ const FULLSTACK_IDENTITY = 'You are the default engineer, and your body is what the build and plan agents run. You are more complete but less accurate than specialized engineers, so prefer spawning a specialist when one matches the task domain.'
9
+
10
+ // The reminder plugin owns ability bootstrap. Remove the old prompt-level
11
+ // directive when regenerating so it cannot duplicate the plugin reminder.
12
+ function stripStartupDirective(text) {
13
+ if (!text) return text
14
+ return text
15
+ .split(/\r?\n\r?\n+/)
16
+ .filter(paragraph => !paragraph.trim().startsWith('**Startup'))
17
+ .join('\n\n')
18
+ .trim()
19
+ }
20
+
21
+ export async function removeLegacyStartupDirectives({ cwd = process.cwd() } = {}) {
22
+ const agentsDir = path.join(cwd, '.opencode', 'agents')
23
+ if (!await fse.pathExists(agentsDir)) return 0
24
+
25
+ let updated = 0
26
+ for (const fileName of await fse.readdir(agentsDir)) {
27
+ if (!fileName.endsWith('.md')) continue
28
+ const filePath = path.join(agentsDir, fileName)
29
+ const content = await fse.readFile(filePath, 'utf-8')
30
+ const cleaned = stripStartupDirective(content)
31
+ if (cleaned === content.trim()) continue
32
+ await fse.writeFile(filePath, `${cleaned}\n`, 'utf-8')
33
+ updated++
34
+ }
35
+ return updated
36
+ }
37
+
38
+ export async function generateFullstackEngineer({ cwd = process.cwd(), updateMode = false } = {}) {
39
+ const agentsDir = path.join(cwd, '.opencode', 'agents')
40
+ await fse.ensureDir(agentsDir)
41
+ const filePath = path.join(agentsDir, FULLSTACK_FILE)
42
+
43
+ if (updateMode && await fse.pathExists(filePath)) {
44
+ return { generated: false, preserved: true }
45
+ }
46
+
47
+ let existingAbilities = null
48
+ let existingIdentity = null
49
+ if (await fse.pathExists(filePath)) {
50
+ const content = await fse.readFile(filePath, 'utf-8')
51
+ const abilitiesMatch = content.match(/## Abilities\n([\s\S]*?)$/)
52
+ if (abilitiesMatch) existingAbilities = abilitiesMatch[1].trim()
53
+ const identityMatch = content.match(/^---\n[\s\S]*?\n---\n\n(.*?)(?:\n\n## Abilities)/s)
54
+ if (identityMatch) existingIdentity = stripStartupDirective(identityMatch[1])
55
+ }
56
+
57
+ const frontmatter = [
58
+ '---',
59
+ `description: ${FULLSTACK_DESCRIPTION}`,
60
+ // subagent, not primary: build.md and plan.md are the primaries, and
61
+ // pc-subagent-tiers generates both from this file on every startup.
62
+ 'mode: subagent',
63
+ // warning is reserved for plan, so fullstack takes its name-derived hex
64
+ // like every other subagent.
65
+ // Quoted: a bare #hex is a YAML comment, which opencode rejects.
66
+ `color: ${yamlColor(agentColor('fullstack-engineer'))}`,
67
+ 'permission:',
68
+ ' edit: allow',
69
+ ' bash: allow',
70
+ ' read: allow',
71
+ ' glob: allow',
72
+ ' grep: allow',
73
+ ' question: allow',
74
+ ' todowrite: allow',
75
+ '---',
76
+ ]
77
+
78
+ const identity = existingIdentity ?? FULLSTACK_IDENTITY
79
+
80
+ const abilities = existingAbilities ?? [
81
+ '- Guardrails: @pc-guardrails-generic, @pc-guardrails-project',
82
+ ].join('\n')
83
+
84
+ const content = `${frontmatter.join('\n')}\n\n${identity}\n\n## Abilities\n${abilities}\n`
85
+
86
+ await fse.writeFile(filePath, content, 'utf-8')
87
+ success(`Generated ${FULLSTACK_FILE}`)
88
+ return { generated: true }
89
+ }