@guiho/runx 0.4.1 → 0.5.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 (72) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/DOCS.md +27 -5
  3. package/README.md +6 -1
  4. package/devops/build-binaries.ts +3 -3
  5. package/devops/devops.xdocs.md +9 -6
  6. package/devops/extract-release-notes.spec.ts +54 -0
  7. package/devops/extract-release-notes.ts +40 -0
  8. package/devops/install.ps1 +29 -6
  9. package/devops/install.sh +61 -22
  10. package/devops/installers.spec.ts +162 -5
  11. package/devops/verify-release-assets.ts +14 -0
  12. package/docs/architecture/architecture.xdocs.md +2 -1
  13. package/docs/architecture/cli-architecture.md +18 -9
  14. package/docs/decisions/decisions.xdocs.md +4 -0
  15. package/docs/decisions/markdown-release-assets-and-version-scoped-notes.md +84 -0
  16. package/docs/plans/automatic-agent-maintenance.md +120 -0
  17. package/docs/plans/linux-installer-latest-release.md +43 -0
  18. package/docs/plans/plans.xdocs.md +6 -0
  19. package/docs/plans/platform-aware-startup-greeting.md +43 -0
  20. package/docs/plans/rfc-0034-cli-compliance-migration.md +17 -8
  21. package/docs/plans/upgrade-reliability-implementation.md +1 -1
  22. package/docs/reviews/implementation/automatic-agent-maintenance-review.md +63 -0
  23. package/docs/reviews/implementation/bash-installer-review.md +42 -0
  24. package/docs/reviews/implementation/implementation.xdocs.md +14 -0
  25. package/docs/reviews/implementation/linux-installer-latest-release-review.md +49 -0
  26. package/docs/reviews/implementation/platform-aware-startup-greeting-review.md +51 -0
  27. package/docs/reviews/implementation/rfc-0034-cli-compliance-migration-review.md +5 -2
  28. package/docs/reviews/implementation/unicode-help-tree-review.md +41 -0
  29. package/docs/reviews/implementation/upgrade-reliability-issue-12-review.md +62 -0
  30. package/docs/reviews/implementation/upgrade-reliability-issue-13-review.md +63 -0
  31. package/docs/reviews/plans/automatic-agent-maintenance-review.md +56 -0
  32. package/docs/reviews/plans/plans.xdocs.md +2 -0
  33. package/docs/superpowers/specs/2026-07-15-upgrade-reliability-design.md +1 -1
  34. package/docs/todo/automatic-agent-maintenance-implementation.md +55 -0
  35. package/docs/todo/automatic-agent-maintenance.md +86 -0
  36. package/docs/todo/bash-installer.md +45 -0
  37. package/docs/todo/linux-installer-latest-release.md +47 -0
  38. package/docs/todo/platform-aware-startup-greeting.md +41 -0
  39. package/docs/todo/rfc-0034-cli-compliance-migration-implementation.md +7 -2
  40. package/docs/todo/rfc-0034-cli-compliance-migration.md +7 -3
  41. package/docs/todo/todo.xdocs.md +14 -0
  42. package/docs/todo/unicode-help-tree.md +44 -0
  43. package/docs/todo/upgrade-reliability.md +51 -0
  44. package/docs/validation/automatic-agent-maintenance.md +63 -0
  45. package/docs/validation/bash-installer.md +55 -0
  46. package/docs/validation/linux-installer-latest-release.md +50 -0
  47. package/docs/validation/platform-aware-startup-greeting.md +50 -0
  48. package/docs/validation/rfc-0034-cli-compliance-migration.md +10 -4
  49. package/docs/validation/unicode-help-tree.md +43 -0
  50. package/docs/validation/upgrade-reliability-issue-12.md +74 -0
  51. package/docs/validation/upgrade-reliability-issue-13.md +72 -0
  52. package/docs/validation/upgrade-reliability.md +38 -99
  53. package/docs/validation/validation.xdocs.md +16 -2
  54. package/library/agent-maintenance.d.ts +19 -0
  55. package/library/agent-maintenance.d.ts.map +1 -0
  56. package/library/agent-maintenance.js +49 -0
  57. package/library/agents.d.ts +6 -1
  58. package/library/agents.d.ts.map +1 -1
  59. package/library/agents.js +58 -11
  60. package/library/cli.d.ts +2 -1
  61. package/library/cli.d.ts.map +1 -1
  62. package/library/cli.js +34 -9
  63. package/library/recovery.js +1 -1
  64. package/library/release-catalog.d.ts +2 -1
  65. package/library/release-catalog.d.ts.map +1 -1
  66. package/library/release-catalog.js +9 -1
  67. package/library/storage.d.ts +2 -1
  68. package/library/storage.d.ts.map +1 -1
  69. package/library/storage.js +13 -1
  70. package/package.json +1 -1
  71. package/skills/guiho-s-runx/SKILL.md +11 -0
  72. package/skills/guiho-s-runx/guiho-s-runx.xdocs.md +4 -1
@@ -3,29 +3,186 @@
3
3
  */
4
4
 
5
5
  import { describe, expect, test } from 'bun:test'
6
+ import { $ } from 'bun'
6
7
 
7
8
  describe('RunX direct installers', () => {
8
9
  test('PowerShell installer exposes the complete RFC sequence', async () => {
9
10
  const script = await Bun.file(new URL('./install.ps1', import.meta.url)).text()
10
11
  expect(script).toContain('Initiating GUIHO CLI Upgrade / Installation Sequence...')
11
- expect(script).toContain('guiho-s-runx')
12
- expect(script).toContain('guiho-i-runx')
12
+ expect(script).toContain('guiho-s-runx.md')
13
+ expect(script).toContain('guiho-i-runx.md')
13
14
  expect(script).toContain('.agents\\skills\\guiho-s-runx')
14
15
  expect(script).toContain('.claude\\skills\\guiho-s-runx')
15
16
  expect(script).toContain('BEGIN RUNX — DO NOT EDIT THIS SECTION')
16
17
  expect(script).toContain('Test-NativeBinary')
17
18
  expect(script).toContain('Install-Transactional')
19
+ expect(script).toContain('function Test-MarkdownAsset')
20
+ expect(script).toContain("Test-MarkdownAsset -Path $skillAsset -ExpectedName 'guiho-s-runx'")
21
+ expect(script).toContain("Test-MarkdownAsset -Path $promptAsset -ExpectedName 'guiho-i-runx'")
22
+ expect(script).toContain('Windows executable header')
23
+ expect(script).toContain('binary NUL bytes')
24
+ expect(script).toContain('not valid UTF-8 text')
18
25
  })
19
26
 
20
- test('POSIX installer selects Darwin assets and has no Bun dependency', async () => {
27
+ test('Bash installer selects Darwin assets and resolves latest assets without parsing redirect tags', async () => {
21
28
  const script = await Bun.file(new URL('./install.sh', import.meta.url)).text()
29
+ expect(script).toStartWith('#!/usr/bin/env bash\nset -euo pipefail')
22
30
  expect(script).toContain("Darwin) printf 'darwin")
23
31
  expect(script).toContain('--progress-bar')
24
- expect(script).toContain('guiho-s-runx')
25
- expect(script).toContain('guiho-i-runx')
32
+ expect(script).toContain('/releases/latest/download/')
33
+ expect(script).not.toContain("write-out '%{url_effective}'")
34
+ expect(script).toContain('guiho-s-runx.md')
35
+ expect(script).toContain('guiho-i-runx.md')
26
36
  expect(script).toContain('.agents/skills/guiho-s-runx')
27
37
  expect(script).toContain('.claude/skills/guiho-s-runx')
38
+ expect(script).toContain('verify_markdown_asset()')
39
+ expect(script).toContain("verify_markdown_asset \"$TMP/guiho-s-runx.md\" 'guiho-s-runx'")
40
+ expect(script).toContain("verify_markdown_asset \"$TMP/guiho-i-runx.md\" 'guiho-i-runx'")
41
+ expect(script).toContain('Windows executable header')
42
+ expect(script).toContain('binary NUL bytes')
43
+ expect(script).toContain('iconv -f UTF-8 -t UTF-8')
28
44
  expect(script).toContain('BEGIN RUNX — DO NOT EDIT THIS SECTION')
29
45
  expect(script).not.toContain(' bun ')
30
46
  })
47
+
48
+ test('Bash installer passes syntax, piped startup, exact versions, and executable verification', async () => {
49
+ const bash = await bashExecutable()
50
+ const script = Bun.fileURLToPath(new URL('./install.sh', import.meta.url))
51
+ const syntax = Bun.spawnSync([bash, '-n', script])
52
+ expect(syntax.exitCode).toBe(0)
53
+
54
+ const piped = Bun.spawnSync([
55
+ bash,
56
+ '-c',
57
+ 'cat "$1" | RUNX_INSTALLER_SOURCE_ONLY=1 bash -s --',
58
+ 'bash',
59
+ script,
60
+ ])
61
+ expect(piped.exitCode).toBe(0)
62
+ expect(piped.stderr.toString()).toBe('')
63
+
64
+ const functions = Bun.spawnSync([
65
+ bash,
66
+ '-c',
67
+ [
68
+ 'RUNX_INSTALLER_SOURCE_ONLY=1 source "$1"',
69
+ 'stable=$(normalize_version v1.2.3)',
70
+ 'prerelease=$(normalize_version @guiho/runx@1.3.0-alpha.2)',
71
+ 'test "$stable" = 1.2.3',
72
+ 'test "$prerelease" = 1.3.0-alpha.2',
73
+ 'VERSION=latest',
74
+ 'TARGET_VERSION=$(resolve_target_version)',
75
+ 'latest=$(build_asset_url runx-linux-x64-baseline)',
76
+ 'test "$latest" = https://github.com/CGuiho/runx/releases/latest/download/runx-linux-x64-baseline',
77
+ 'VERSION=@guiho/runx@1.3.0-alpha.2',
78
+ 'TARGET_VERSION=$(resolve_target_version)',
79
+ 'exact=$(build_asset_url runx-linux-x64-baseline)',
80
+ 'test "$exact" = https://github.com/CGuiho/runx/releases/download/%40guiho%2Frunx%401.3.0-alpha.2/runx-linux-x64-baseline',
81
+ 'TARGET_VERSION=$(bun --version)',
82
+ 'verify_installed_version "$(command -v bun)"',
83
+ ].join('; '),
84
+ 'bash',
85
+ script,
86
+ ])
87
+ expect(functions.exitCode).toBe(0)
88
+ })
89
+
90
+ test('platform installer rejects a PE payload disguised as Markdown', async () => {
91
+ const temporaryDirectory = `${Bun.env.TEMP ?? Bun.env.TMPDIR ?? '/tmp'}/runx-markdown-${crypto.randomUUID()}`
92
+ const validAsset = `${temporaryDirectory}/valid.md`
93
+ const executableAsset = `${temporaryDirectory}/payload.md`
94
+ await $`mkdir -p ${temporaryDirectory}`
95
+ try {
96
+ await Bun.write(validAsset, '---\nname: guiho-s-runx\n---\n\n# Skill\n')
97
+ await Bun.write(executableAsset, new Uint8Array([0x4d, 0x5a, 0x00, 0x00]))
98
+
99
+ if (process.platform === 'win32') {
100
+ const script = Bun.fileURLToPath(new URL('./install.ps1', import.meta.url))
101
+ const valid = Bun.spawnSync([
102
+ 'powershell',
103
+ '-NoLogo',
104
+ '-NoProfile',
105
+ '-NonInteractive',
106
+ '-ExecutionPolicy',
107
+ 'Bypass',
108
+ '-Command',
109
+ `$env:RUNX_INSTALLER_SOURCE_ONLY='1'; . '${script.replaceAll("'", "''")}'; Test-MarkdownAsset -Path '${validAsset.replaceAll("'", "''")}' -ExpectedName 'guiho-s-runx'`,
110
+ ])
111
+ const invalid = Bun.spawnSync([
112
+ 'powershell',
113
+ '-NoLogo',
114
+ '-NoProfile',
115
+ '-NonInteractive',
116
+ '-ExecutionPolicy',
117
+ 'Bypass',
118
+ '-Command',
119
+ `$env:RUNX_INSTALLER_SOURCE_ONLY='1'; . '${script.replaceAll("'", "''")}'; Test-MarkdownAsset -Path '${executableAsset.replaceAll("'", "''")}' -ExpectedName 'guiho-s-runx'`,
120
+ ])
121
+ expect(valid.exitCode).toBe(0)
122
+ expect(invalid.exitCode).not.toBe(0)
123
+ expect(invalid.stderr.toString()).toContain('Windows executable header')
124
+ } else {
125
+ const script = Bun.fileURLToPath(new URL('./install.sh', import.meta.url))
126
+ const bash = await bashExecutable()
127
+ const valid = Bun.spawnSync([
128
+ bash,
129
+ '-c',
130
+ `RUNX_INSTALLER_SOURCE_ONLY=1 . "$1"; verify_markdown_asset "$2" guiho-s-runx`,
131
+ 'bash',
132
+ script,
133
+ validAsset,
134
+ ])
135
+ const invalid = Bun.spawnSync([
136
+ bash,
137
+ '-c',
138
+ `RUNX_INSTALLER_SOURCE_ONLY=1 . "$1"; verify_markdown_asset "$2" guiho-s-runx`,
139
+ 'bash',
140
+ script,
141
+ executableAsset,
142
+ ])
143
+ expect(valid.exitCode).toBe(0)
144
+ expect(invalid.exitCode).not.toBe(0)
145
+ expect(invalid.stderr.toString()).toContain('Windows executable header')
146
+ }
147
+ } finally {
148
+ await $`rm -rf ${temporaryDirectory}`
149
+ }
150
+ })
151
+
152
+ if (process.platform === 'win32') {
153
+ test('PowerShell installer accepts exact stable and prerelease versions and verifies the executable', () => {
154
+ const script = Bun.fileURLToPath(new URL('./install.ps1', import.meta.url)).replaceAll("'", "''")
155
+ const bun = process.execPath.replaceAll("'", "''")
156
+ const command = [
157
+ "$env:RUNX_INSTALLER_SOURCE_ONLY='1'",
158
+ `. '${script}'`,
159
+ "$stable = Resolve-TargetVersion -RequestedVersion 'v1.2.3'",
160
+ "$prerelease = Resolve-TargetVersion -RequestedVersion '@guiho/runx@1.3.0-alpha.2'",
161
+ "if ($stable -ne '1.2.3' -or $prerelease -ne '1.3.0-alpha.2') { throw 'exact version normalization failed' }",
162
+ `Test-InstalledVersion -Path '${bun}' -ExpectedVersion '${process.versions.bun}'`,
163
+ "$mismatchRejected = $false",
164
+ `try { Test-InstalledVersion -Path '${bun}' -ExpectedVersion '0.0.0-impossible' } catch { $mismatchRejected = $true }`,
165
+ "if (-not $mismatchRejected) { throw 'version mismatch was not rejected' }",
166
+ ].join('; ')
167
+ const result = Bun.spawnSync([
168
+ 'powershell',
169
+ '-NoLogo',
170
+ '-NoProfile',
171
+ '-NonInteractive',
172
+ '-ExecutionPolicy',
173
+ 'Bypass',
174
+ '-Command',
175
+ command,
176
+ ])
177
+ expect(result.exitCode).toBe(0)
178
+ })
179
+ }
31
180
  })
181
+
182
+ async function bashExecutable(): Promise<string> {
183
+ const gitBash = 'C:\\Program Files\\Git\\bin\\bash.exe'
184
+ if (process.platform === 'win32' && await Bun.file(gitBash).exists()) return gitBash
185
+ const bash = Bun.which('bash')
186
+ if (!bash) throw new Error('Bash is required to validate devops/install.sh.')
187
+ return bash
188
+ }
@@ -14,4 +14,18 @@ if (JSON.stringify(observed) !== JSON.stringify(expected)) {
14
14
  throw new Error(`Expected exactly ${expected.length} release assets.\nExpected: ${expected.join(', ')}\nObserved: ${observed.join(', ')}`)
15
15
  }
16
16
 
17
+ for (const [assetName, expectedName] of [
18
+ ['guiho-s-runx.md', 'guiho-s-runx'],
19
+ ['guiho-i-runx.md', 'guiho-i-runx'],
20
+ ] as const) {
21
+ const bytes = await Bun.file(joinPath(bin, assetName)).bytes()
22
+ if (bytes.length === 0 || (bytes[0] === 0x4d && bytes[1] === 0x5a) || bytes.includes(0)) {
23
+ throw new Error(`Release Markdown asset is empty or binary: ${assetName}`)
24
+ }
25
+ const text = new TextDecoder('utf-8', { fatal: true }).decode(bytes).replace(/\r\n/g, '\n')
26
+ if (!text.startsWith('---\n') || !new RegExp(`^name:\\s*${expectedName}\\s*$`, 'm').test(text)) {
27
+ throw new Error(`Release Markdown asset has invalid frontmatter identity: ${assetName}`)
28
+ }
29
+ }
30
+
17
31
  process.stdout.write(`${JSON.stringify({ count: observed.length, assets: observed }, null, 2)}\n`)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  subject: runx-architecture
3
- description: Technical architecture for the RunX manifest, Citty command tree, agent skill, and native distribution.
3
+ description: Technical architecture for the RunX manifest, Citty command tree, automatic agent maintenance, and native distribution.
4
4
  parent: runx-docs
5
5
  children: []
6
6
  files:
@@ -14,6 +14,7 @@ keywords:
14
14
  - bun
15
15
  - cli
16
16
  - citty
17
+ - agent maintenance
17
18
  flags: []
18
19
  status: stable
19
20
  ---
@@ -20,13 +20,18 @@ owner: runx-architecture
20
20
 
21
21
  ## Flow
22
22
 
23
- `cli.ts` defines a Citty command tree. Citty parses options and positionals,
24
- resolves nested commands and aliases, and renders ordinary usage. A bounded
25
- command-map adapter preserves the legacy `runx <selector>` shorthand while
26
- known Citty commands retain precedence. Manifest commands use `manifest.ts` to
27
- discover the nearest `runx.yaml`, parse YAML, validate a strict TypeBox schema,
28
- and resolve a selector. `render.ts` presents text or JSON. `executor.ts` spawns
29
- exactly one configured shell command only for a real run.
23
+ `cli.ts` defines one Citty command tree. Citty parses options and positionals,
24
+ resolves nested commands, and renders usage. Manifest commands use
25
+ `configuration.ts` to resolve `runx.yaml` by explicit path, effective cwd, then
26
+ global fallback; TypeBox validates the complete shape. `render.ts` presents
27
+ text or JSON. `executor.ts` spawns exactly one configured shell command only for
28
+ a real `runx run`.
29
+
30
+ After an ordinary command routes through Citty, `agent-maintenance.ts` receives
31
+ the decoded effective cwd and detaches a hidden worker. The worker compares
32
+ embedded skill content with both global copies and atomically reconciles one
33
+ nearest `AGENTS.md` block. Explicit agent-resource and uninstall commands are
34
+ excluded so intentional removal is not reversed.
30
35
 
31
36
  ## Boundaries
32
37
 
@@ -34,8 +39,12 @@ exactly one configured shell command only for a real run.
34
39
  - Help, version, and CLI usage failures do not discover a manifest.
35
40
  - `source/flags.ts` no longer exists; RunX has no second token parser or manual
36
41
  execution router behind Citty.
37
- - `agents.ts` copies the embedded or packaged skill into the requested standard
38
- or Claude-compatible skill location.
42
+ - `agents.ts` owns explicit dual-tool actions plus idempotent, legacy-aware
43
+ automatic skill and instruction reconciliation.
44
+ - `storage.ts` performs same-directory temporary writes and atomic replacement
45
+ for automatic resource maintenance.
46
+ - Hidden update and agent-maintenance routes never appear in public help and
47
+ cannot recursively schedule themselves.
39
48
  - `self-management.ts` queries GitHub Releases and only replaces/removes a
40
49
  native executable, never a Bun development process.
41
50
  - Native builds register `embedded-resources.ts`, which includes the skill.
@@ -7,6 +7,7 @@ files:
7
7
  alpha-boundaries.md: Captures accepted alpha scope, safety, distribution, and compatibility decisions.
8
8
  citty-cli-migration.md: Defines the accepted full migration from handwritten parsing and routing to Citty.
9
9
  interactive-init-manifest.md: Defines interactive initialization, Semantic Versioning, the public group, and the scripts directory contract.
10
+ markdown-release-assets-and-version-scoped-notes.md: Defines .md agent release filenames, downloaded-resource validation, and exact-version idempotent GitHub Release notes.
10
11
  mirror-automatic-push.md: Defines automatic Mirror release pushes with a synchronized protected-main gate.
11
12
  npm-trusted-publishing.md: Defines the accepted npm OIDC publishing workflow and protected-branch patch-release trial.
12
13
  windows-self-upgrade.md: Defines synchronous Windows executable replacement, verification, rollback, and cleanup.
@@ -14,6 +15,7 @@ documents:
14
15
  alpha-boundaries.md: Decision record for RunX alpha boundaries.
15
16
  citty-cli-migration.md: Decision record for the complete Citty CLI parser and router migration.
16
17
  interactive-init-manifest.md: Accepted manifest and interactive initialization decision for runx init.
18
+ markdown-release-assets-and-version-scoped-notes.md: Accepted public asset filename, validation, and release-description policy.
17
19
  mirror-automatic-push.md: Accepted release-policy decision for Mirror push=true and protected delivery ordering.
18
20
  npm-trusted-publishing.md: Decision record for GitHub Actions npm trusted publishing and the first automated patch release.
19
21
  windows-self-upgrade.md: Accepted design for synchronous and recoverable Windows native self-upgrade.
@@ -25,6 +27,8 @@ keywords:
25
27
  - runx init
26
28
  - scripts directory
27
29
  - mirror push
30
+ - markdown release assets
31
+ - version-scoped release notes
28
32
  - windows self-upgrade
29
33
  flags: []
30
34
  status: stable
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: RunX Markdown Release Assets And Version-Scoped Notes
3
+ purpose: Preserve the accepted RunX GitHub Release filename and release-description policy.
4
+ description: Records the project override requiring .md agent asset filenames and exact-version changelog sections for idempotent GitHub Release notes.
5
+ created: 2026-07-19
6
+ flags:
7
+ - accepted
8
+ - release-policy
9
+ tags:
10
+ - decisions
11
+ - releases
12
+ - cli
13
+ keywords:
14
+ - guiho-s-runx.md
15
+ - guiho-i-runx.md
16
+ - GitHub Release notes
17
+ - changelog extraction
18
+ owner: runx-decisions
19
+ ---
20
+
21
+ # RunX Markdown Release Assets And Version-Scoped Notes
22
+
23
+ ## Status
24
+
25
+ Accepted by the developer on 2026-07-19.
26
+
27
+ ## Context
28
+
29
+ The bundled RFC 0034 skill originally named the two Markdown release artifacts
30
+ without extensions. That makes their content type less obvious and conflicts
31
+ with the explicit RunX release contract chosen by the developer. The publish
32
+ workflow also passed the complete changelog to GitHub, causing one release to
33
+ describe unrelated versions.
34
+
35
+ ## Decision
36
+
37
+ Every RunX GitHub Release contains exactly fourteen assets: twelve native
38
+ binaries plus `guiho-s-runx.md` and `guiho-i-runx.md`.
39
+
40
+ The `.md` suffixes are public filename requirements. Installers download those
41
+ names, install the skill content as `SKILL.md`, and use the instruction asset
42
+ content for managed instruction blocks.
43
+
44
+ Release notes contain only the exact `## <version> - <date>` section from
45
+ `CHANGELOG.md`, ending before the next `## ` heading. Publishing fails closed
46
+ when the exact section is missing or empty. Rerunning a tag updates the existing
47
+ release notes before replacing its assets.
48
+
49
+ Downloaded agent artifacts are treated as untrusted release inputs. Installers
50
+ reject empty payloads, Windows executable headers, NUL-containing binary data,
51
+ invalid UTF-8, missing YAML frontmatter, and mismatched resource identities
52
+ before writing any global skill or project instruction file.
53
+
54
+ ## Alternatives Considered
55
+
56
+ - Extensionless agent assets: rejected because the developer explicitly
57
+ requires recognizable Markdown filenames.
58
+ - Full-changelog release notes: rejected because they include unrelated release
59
+ history.
60
+ - Creating notes only on first publish: rejected because reruns must repair
61
+ stale release descriptions idempotently.
62
+ - Trusting the filename extension alone: rejected because a `.md` download can
63
+ still contain an executable or corrupted payload.
64
+
65
+ ## Consequences
66
+
67
+ - RunX intentionally differs from the original extensionless RFC asset spelling.
68
+ - All build, verification, workflow, installer, test, and public documentation
69
+ surfaces must use the `.md` filenames.
70
+ - Every version tag requires an exact matching changelog heading before its
71
+ protected publish workflow can succeed.
72
+ - Installer validation must complete before any downloaded agent resource is
73
+ copied or applied.
74
+
75
+ ## Reversal Or Revisit Conditions
76
+
77
+ Revisit only through an explicit developer decision that changes the public
78
+ release contract and migrates all consumers together.
79
+
80
+ ## References
81
+
82
+ - [RFC migration plan](../plans/rfc-0034-cli-compliance-migration.md)
83
+ - [RFC task specification](../todo/rfc-0034-cli-compliance-migration.md)
84
+ - [RunX documentation](../../DOCS.md)
@@ -0,0 +1,120 @@
1
+ ---
2
+ name: RunX Automatic Agent Maintenance Plan
3
+ purpose: Define executable units for GitHub issue 11 automatic skill and AGENTS.md maintenance.
4
+ description: Sequences atomic resource reconciliation, a hidden worker, startup integration, regression coverage, documentation, review, and validation.
5
+ created: 2026-07-19
6
+ flags:
7
+ - approved
8
+ - implementation-ready
9
+ - implemented
10
+ tags:
11
+ - planning
12
+ - cli
13
+ - agents
14
+ keywords:
15
+ - RunX
16
+ - issue 11
17
+ - background worker
18
+ - atomic writes
19
+ - AGENTS.md
20
+ owner: runx-plans
21
+ ---
22
+
23
+ # RunX Automatic Agent Maintenance Plan
24
+
25
+ ## Outcome
26
+
27
+ Every ordinary RunX invocation schedules a hidden, non-blocking,
28
+ failure-isolated worker that reconciles the bundled `guiho-s-runx` skill in
29
+ both global tool locations and one compact managed block in the nearest
30
+ applicable `AGENTS.md`. Current resources remain untouched, stale or legacy
31
+ resources converge to bundled content, and foreground text, JSON, help,
32
+ version, command execution, and exit behavior remain deterministic.
33
+
34
+ ## Authority
35
+
36
+ - GitHub issue [#11](https://github.com/CGuiho/runx/issues/11) is the accepted
37
+ behavior requirement.
38
+ - `guiho-a-0001-swe` coordinates execution.
39
+ - `guiho-s-0034-cli-engineer`, `guiho-s-0023-plan-executor`,
40
+ `guiho-s-0015-bun`, `guiho-s-0019-typescript`, `guiho-s-0011-typebox`, and
41
+ `guiho-s-xdocs` govern implementation.
42
+ - The approved RFC breaking boundary remains: the namespace is singular
43
+ `runx agent`; no plural compatibility alias will be restored.
44
+
45
+ ## Unit AM-01 - Atomic Reconciliation Primitives
46
+
47
+ - Goal: reconcile only missing or stale agent resources without partial writes.
48
+ - Expected files: `source/storage.ts`, `source/agents.ts`, colocated tests.
49
+ - Actions:
50
+ 1. Add same-directory temporary-file writes followed by atomic replacement.
51
+ 2. Compare both global skill targets with the bundled skill before writing.
52
+ 3. Find the nearest existing `AGENTS.md` from effective cwd; create one at
53
+ effective cwd only when no ancestor contains it.
54
+ 4. Replace current or legacy RunX blocks without duplicating them.
55
+ 5. Preserve user-authored content outside recognized markers.
56
+ - Acceptance:
57
+ - Missing and stale resources are repaired.
58
+ - Current resources report no change and are not rewritten.
59
+ - Concurrent reconciliations converge to identical content.
60
+ - Failures do not leave a truncated destination.
61
+
62
+ ## Unit AM-02 - Hidden Worker Lifecycle
63
+
64
+ - Goal: schedule maintenance without blocking or polluting foreground output.
65
+ - Expected files: new `source/agent-maintenance.ts`, `source/cli.ts`, tests.
66
+ - Dependencies: AM-01.
67
+ - Actions:
68
+ 1. Add one hidden exact worker route absent from public help/tree/docs.
69
+ 2. Pass the Citty-decoded effective cwd to the detached worker.
70
+ 3. Disable recursive scheduling in the worker process.
71
+ 4. Ignore worker stdout/stderr and isolate spawn/worker failures.
72
+ 5. Exclude explicit agent-resource and uninstall commands so explicit removal
73
+ is not immediately reversed.
74
+ - Acceptance:
75
+ - Plain RunX and ordinary catalog commands schedule the worker.
76
+ - The foreground does not wait for reconciliation.
77
+ - Text and JSON output and exit codes remain unchanged.
78
+ - Hidden worker execution cannot recursively spawn itself.
79
+
80
+ ## Unit AM-03 - Acceptance Regressions
81
+
82
+ - Goal: prove every issue criterion with temporary homes and projects.
83
+ - Expected files: `source/agent-maintenance.spec.ts`, `source/cli.spec.ts`.
84
+ - Dependencies: AM-01 and AM-02.
85
+ - Tests:
86
+ - missing, current, and outdated skills in both global tool locations;
87
+ - nearest `AGENTS.md` insertion and stale/legacy block replacement;
88
+ - preservation of user-authored content;
89
+ - two concurrent reconciliations;
90
+ - worker spawn failure and maintenance failure isolation;
91
+ - plain invocation scheduling and effective `--cwd` routing;
92
+ - stable text/JSON output and hidden help tree.
93
+ - Acceptance:
94
+ - The full suite exits cleanly with no real global mutation.
95
+
96
+ ## Unit AM-04 - Documentation, Review, And Validation
97
+
98
+ - Goal: close durable state and provide issue-resolution evidence.
99
+ - Dependencies: AM-03.
100
+ - Actions:
101
+ 1. Document automatic behavior and explicit-command boundaries.
102
+ 2. Review implementation against every issue checkbox.
103
+ 3. Run typecheck, tests, build, native smoke, prohibited-import scan, and
104
+ narrow XDocs checks.
105
+ 4. Commit one file at a time, push main, comment factual evidence on issue
106
+ #11, and close only after GitHub contains the implementation.
107
+ - Acceptance:
108
+ - No review finding remains.
109
+ - Pushed commit and validation evidence precede closure.
110
+
111
+ ## Release Boundary
112
+
113
+ This externally observable capability requires a final Mirror `minor` plan
114
+ after all open issues are resolved. Do not version or tag during this unit.
115
+
116
+ ## References
117
+
118
+ - [Task specification](../todo/automatic-agent-maintenance.md)
119
+ - [CLI architecture](../architecture/cli-architecture.md)
120
+ - [RFC migration plan](./rfc-0034-cli-compliance-migration.md)
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: Latest RunX Bash Installer Plan
3
+ purpose: Sequence the GitHub issue 20 installer fix from URL resolution through public release verification.
4
+ description: Replaces redirect-tag parsing with latest-download aliases while preserving exact releases and transactional installation.
5
+ created: 2026-07-20
6
+ flags:
7
+ - approved
8
+ - implemented
9
+ owner: runx-plans
10
+ tags:
11
+ - installer
12
+ - linux
13
+ keywords:
14
+ - issue 20
15
+ - latest download
16
+ - regression test
17
+ ---
18
+
19
+ # Latest RunX Bash Installer Plan
20
+
21
+ ## Unit 1: Replace Fragile Latest-Tag Discovery
22
+
23
+ 1. Keep exact-version normalization for explicit stable and prerelease inputs.
24
+ 2. Route `latest` binary and agent assets through
25
+ `releases/latest/download/<asset>`, matching the proven XDocs installer.
26
+ 3. Verify the installed executable's semantic version and report the resolved
27
+ version after installation.
28
+
29
+ ## Unit 2: Prove The Regression
30
+
31
+ 1. Assert that latest URLs use the stable GitHub download alias.
32
+ 2. Assert that redirect `url_effective` parsing is absent.
33
+ 3. Preserve exact encoded-tag URL coverage, Bash syntax, piping, native payload
34
+ validation, agent-asset validation, and executable version checks.
35
+ 4. Run focused tests, then the full RunX typecheck, test, build, binary, asset,
36
+ and XDocs gates.
37
+
38
+ ## Unit 3: Release And Close
39
+
40
+ 1. Prepare a Mirror patch release with version-only changelog notes.
41
+ 2. Publish exactly fourteen assets.
42
+ 3. Execute the public Linux installer path against the release.
43
+ 4. Post evidence to issue 20 and close it only after the public install passes.
@@ -5,19 +5,25 @@ parent: runx-docs
5
5
  children: []
6
6
  files:
7
7
  alpha-implementation.md: Breaks the accepted alpha into implementation and validation units.
8
+ automatic-agent-maintenance.md: Implements non-blocking automatic global skill and nearest AGENTS.md reconciliation for issue 11.
8
9
  citty-cli-migration.md: Executes the full Citty command-tree migration, compatibility validation, protected delivery, and patch release.
9
10
  interactive-init-manifest.md: Sequences the SemVer manifest, public group, scripts directory, and interactive initializer delivery.
11
+ linux-installer-latest-release.md: Replaces redirect-tag parsing with latest-download aliases, regression tests the URLs, and sequences public issue verification.
10
12
  mirror-automatic-push.md: Enables automatic Mirror release pushes with a synchronized protected-main safety gate.
11
13
  npm-trusted-publishing-release.md: Sequences workflow implementation, protected delivery, Mirror patching, and public trusted-publishing verification.
14
+ platform-aware-startup-greeting.md: Centralizes Windows, Linux, and macOS greeting rendering, deterministic tests, documentation, release, and issue closure.
12
15
  rfc-0034-cli-compliance-migration.md: Executes the breaking full RFC 0034 migration across runtime, configuration, help, agents, upgrades, distribution, release assets, documentation, and validation.
13
16
  windows-self-upgrade.md: Sequences synchronous Windows replacement, rollback coverage, validation, issue closure, and patch delivery.
14
17
  upgrade-reliability-implementation.md: Sequences release discovery, streamed progress, transactional replacement, recovery, installers, and validation.
15
18
  documents:
16
19
  alpha-implementation.md: Plan used for the initial RunX implementation.
20
+ automatic-agent-maintenance.md: Approved automatic agent-maintenance implementation plan.
17
21
  citty-cli-migration.md: Active plan for replacing handwritten CLI parsing and routing with Citty and delivering its patch release.
18
22
  interactive-init-manifest.md: Approved implementation plan for the RunX interactive init manifest feature.
23
+ linux-installer-latest-release.md: Approved implementation plan for GitHub issue 20.
19
24
  mirror-automatic-push.md: Approved plan for configuring, validating, and merging Mirror push=true without applying another release.
20
25
  npm-trusted-publishing-release.md: Approved executable plan for the RunX 0.2.1 trusted-publishing release trial.
26
+ platform-aware-startup-greeting.md: Approved implementation plan for GitHub issue 21.
21
27
  rfc-0034-cli-compliance-migration.md: Approved step-by-step plan for making RunX fully compliant with the GUIHO CLI engineer contract.
22
28
  windows-self-upgrade.md: Approved executable plan for fixing Windows native self-upgrade and delivering its patch.
23
29
  upgrade-reliability-implementation.md: Approved executable plan for GitHub issues 12 and 13.
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: Platform-Aware RunX Greeting Plan
3
+ purpose: Sequence the GitHub issue 21 greeting fix from pure rendering through released Linux verification.
4
+ description: Centralizes supported platform labels, deterministic tests, documentation, patch release, and issue closure.
5
+ created: 2026-07-20
6
+ flags:
7
+ - approved
8
+ - implemented
9
+ owner: runx-plans
10
+ tags:
11
+ - cli
12
+ - startup
13
+ keywords:
14
+ - issue 21
15
+ - platform label
16
+ - regression test
17
+ ---
18
+
19
+ # Platform-Aware RunX Greeting Plan
20
+
21
+ ## Unit 1: Centralize Greeting Rendering
22
+
23
+ 1. Add a pure greeting renderer to the existing Citty CLI module.
24
+ 2. Map `win32`, `linux`, and `darwin` to Windows, Linux, and macOS.
25
+ 3. Route the no-argument command through the renderer without changing cached
26
+ update notice ordering.
27
+
28
+ ## Unit 2: Prove Every Supported Platform
29
+
30
+ 1. Add deterministic renderer assertions for Windows, Linux, and macOS.
31
+ 2. Update child-process expectations to use the runtime platform.
32
+ 3. Run the focused CLI suite and retry only independently diagnosed timing
33
+ flakes.
34
+ 4. Run the full RunX validation gates.
35
+
36
+ ## Unit 3: Document, Release, And Close
37
+
38
+ 1. Replace literal-Windows startup guidance in repository instructions and CLI
39
+ documentation.
40
+ 2. Update the owning XDocs descriptors.
41
+ 3. Include the correction in the same Mirror patch as issue 20.
42
+ 4. Verify the released Linux binary prints `Hello Linux`, post evidence to
43
+ issue 21, and close it.
@@ -447,13 +447,17 @@ execution session rather than assuming it remains active from an earlier unit.
447
447
  4. Validate integrity and architecture.
448
448
  5. Transactionally install and verify the binary.
449
449
  6. Add the global binary directory to PATH when missing.
450
- 7. Download/extract `guiho-s-runx` into both global skill locations.
451
- 8. Download `guiho-i-runx`, discover instruction files, and reconcile their
450
+ 7. Download `guiho-s-runx.md` and install it as `SKILL.md` in both global
451
+ skill locations.
452
+ 8. Download `guiho-i-runx.md`, discover instruction files, and reconcile their
452
453
  managed blocks.
453
- 9. Log every action and final `runx --version` verification.
454
+ 9. Reject empty, executable, binary, invalid UTF-8, missing-frontmatter, or
455
+ wrong-identity agent assets before any skill or instruction write.
456
+ 10. Log every action and final `runx --version` verification.
454
457
  - Acceptance:
455
458
  - Isolated Windows and POSIX installer tests cover success, fallback,
456
- corruption, rollback, PATH, both skills, instructions, and progress.
459
+ binary Markdown rejection, rollback, PATH, both skills, instructions, and
460
+ progress.
457
461
 
458
462
  ### Unit RX-13 - Replace The Npm Launcher With A Node-Compatible Bootstrap
459
463
 
@@ -494,18 +498,23 @@ execution session rather than assuming it remains active from an earlier unit.
494
498
  - `runx-windows-x64-baseline.exe`
495
499
  - `runx-windows-x64-modern.exe`
496
500
  - Agent asset names:
497
- - `guiho-s-runx`
498
- - `guiho-i-runx`
501
+ - `guiho-s-runx.md`
502
+ - `guiho-i-runx.md`
499
503
  - Actions:
500
504
  1. Replace every `macos` name and selector with `darwin`.
501
505
  2. Use Bun APIs in the binary builder rather than Node filesystem/path
502
506
  imports.
503
507
  3. Package the skill directory and instruction/prompt artifact reproducibly.
504
- 4. Upload only the fourteen expected assets.
505
- 5. Make CI fail for missing, duplicate, extra, wrongly suffixed, or legacy
508
+ 4. Treat the `.md` suffixes as part of both public agent-asset filenames.
509
+ 5. Extract only the exact version heading and body from `CHANGELOG.md` for
510
+ GitHub Release notes; fail closed if it is missing and update existing
511
+ releases idempotently.
512
+ 6. Upload only the fourteen expected assets.
513
+ 7. Make CI fail for missing, duplicate, extra, wrongly suffixed, or legacy
506
514
  assets.
507
515
  - Acceptance:
508
516
  - Automated verification observes exactly fourteen unique names.
517
+ - Release notes exclude changelog frontmatter and every older/newer version.
509
518
 
510
519
  ### Unit RX-15 - Align Documentation, Skill, TODO, And XDocs
511
520