@ai-content-space/loopx 0.2.0 → 0.2.1
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.
- package/AGENTS.md +7 -8
- package/README.md +22 -10
- package/README.zh-CN.md +22 -10
- package/docs/loopx/design/loopx-skill-suite-v1-design.md +14 -7
- package/docs/loopx/plans/loopx-skill-suite-v1-implementation.md +7 -3
- package/package.json +3 -2
- package/plugins/loopx/.codex-plugin/plugin.json +1 -1
- package/plugins/loopx/skills/clarify/SKILL.md +4 -4
- package/plugins/loopx/skills/debug/SKILL.md +1 -1
- package/plugins/loopx/skills/exec/SKILL.md +1 -1
- package/plugins/loopx/skills/finish/SKILL.md +103 -8
- package/plugins/loopx/skills/fix-review/SKILL.md +1 -1
- package/plugins/loopx/skills/go-style/SKILL.md +2 -2
- package/plugins/loopx/skills/kratos/SKILL.md +1 -1
- package/plugins/loopx/skills/plan/SKILL.md +2 -2
- package/plugins/loopx/skills/refactor-plan/SKILL.md +1 -1
- package/plugins/loopx/skills/review/SKILL.md +1 -1
- package/plugins/loopx/skills/spec/DESIGN_SPEC_TEMPLATE.md +2 -2
- package/plugins/loopx/skills/spec/SKILL.md +2 -2
- package/plugins/loopx/skills/subagent-exec/SKILL.md +1 -1
- package/plugins/loopx/skills/tdd/SKILL.md +1 -1
- package/plugins/loopx/skills/verify/SKILL.md +1 -1
- package/scripts/verify-skills.mjs +2 -1
- package/skills/RESOLVER.md +0 -4
- package/skills/clarify/SKILL.md +4 -4
- package/skills/debug/SKILL.md +1 -1
- package/skills/exec/SKILL.md +1 -1
- package/skills/finish/SKILL.md +103 -8
- package/skills/fix-review/SKILL.md +1 -1
- package/skills/go-style/SKILL.md +2 -2
- package/skills/kratos/SKILL.md +1 -1
- package/skills/plan/SKILL.md +2 -2
- package/skills/refactor-plan/SKILL.md +1 -1
- package/skills/review/SKILL.md +1 -1
- package/skills/spec/DESIGN_SPEC_TEMPLATE.md +2 -2
- package/skills/spec/SKILL.md +2 -2
- package/skills/subagent-exec/SKILL.md +1 -1
- package/skills/tdd/SKILL.md +1 -1
- package/skills/verify/SKILL.md +1 -1
- package/src/cli.mjs +1 -2
- package/src/plan-runtime.mjs +0 -352
- package/src/workflow.mjs +5 -124
- package/plugins/loopx/scripts/plugin-install.test.mjs +0 -125
- package/skills/ai-slop-cleaner/SKILL.md +0 -114
- package/skills/autoresearch/SKILL.md +0 -68
- package/skills/deep-interview/SKILL.md +0 -461
- package/skills/ralph/SKILL.md +0 -271
- package/skills/ralplan/SKILL.md +0 -49
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
import { execFile } from 'node:child_process';
|
|
4
|
-
import { mkdtemp, readdir, readFile } from 'node:fs/promises';
|
|
5
|
-
import { promisify } from 'node:util';
|
|
6
|
-
import { tmpdir } from 'node:os';
|
|
7
|
-
import { dirname, join, resolve } from 'node:path';
|
|
8
|
-
import { fileURLToPath } from 'node:url';
|
|
9
|
-
|
|
10
|
-
import { LOOPX_BUNDLED_SKILLS, verifyInstallState } from '../../../src/install-discovery.mjs';
|
|
11
|
-
|
|
12
|
-
const execFileAsync = promisify(execFile);
|
|
13
|
-
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
14
|
-
const PLUGIN_ROOT = resolve(MODULE_DIR, '..');
|
|
15
|
-
const REPO_ROOT = resolve(PLUGIN_ROOT, '..', '..');
|
|
16
|
-
const MANIFEST_PATH = join(PLUGIN_ROOT, '.codex-plugin', 'plugin.json');
|
|
17
|
-
const INSTALL_SCRIPT = join(MODULE_DIR, 'plugin-install.mjs');
|
|
18
|
-
const ROOT_SKILLS_DIR = join(REPO_ROOT, 'skills');
|
|
19
|
-
const PLUGIN_SKILLS_DIR = join(PLUGIN_ROOT, 'skills');
|
|
20
|
-
const LOOPX_SKILLS = LOOPX_BUNDLED_SKILLS;
|
|
21
|
-
|
|
22
|
-
function loopxEnv(home) {
|
|
23
|
-
return {
|
|
24
|
-
...process.env,
|
|
25
|
-
HOME: home,
|
|
26
|
-
LOOPX_HOME: home,
|
|
27
|
-
LOOPX_AGENTS_ROOT: join(home, '.agents'),
|
|
28
|
-
LOOPX_SKILLS_ROOT: join(home, '.agents', 'skills'),
|
|
29
|
-
LOOPX_SKILL_LOCK_PATH: join(home, '.agents', '.skill-lock.json'),
|
|
30
|
-
LOOPX_PROJECT_ROOT: REPO_ROOT,
|
|
31
|
-
LOOPX_SKILL_SOURCE_ROOT: PLUGIN_SKILLS_DIR,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
describe('loopx plugin shell', () => {
|
|
36
|
-
it('defines a plugin manifest that only references plugin-root-relative assets', async () => {
|
|
37
|
-
const manifest = JSON.parse(await readFile(MANIFEST_PATH, 'utf8'));
|
|
38
|
-
const packageJson = JSON.parse(await readFile(join(REPO_ROOT, 'package.json'), 'utf8'));
|
|
39
|
-
const codexPluginEntries = await readdir(join(PLUGIN_ROOT, '.codex-plugin'));
|
|
40
|
-
|
|
41
|
-
assert.deepEqual(codexPluginEntries.sort(), ['plugin.json']);
|
|
42
|
-
assert.equal(manifest.name, 'loopx');
|
|
43
|
-
assert.equal(manifest.version, packageJson.version);
|
|
44
|
-
assert.equal(manifest.skills, './skills/');
|
|
45
|
-
assert.equal(manifest.interface.displayName, 'loopx');
|
|
46
|
-
|
|
47
|
-
for (const key of ['skills', 'mcpServers', 'apps']) {
|
|
48
|
-
if (typeof manifest[key] === 'string') {
|
|
49
|
-
assert.equal(manifest[key].startsWith('./'), true, `${key} must stay plugin-root-relative`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('mirrors the canonical loopx skill payload into the plugin shell', async () => {
|
|
55
|
-
for (const skillName of LOOPX_SKILLS) {
|
|
56
|
-
const rootSkill = await readFile(join(ROOT_SKILLS_DIR, skillName, 'SKILL.md'), 'utf8');
|
|
57
|
-
const pluginSkill = await readFile(join(PLUGIN_SKILLS_DIR, skillName, 'SKILL.md'), 'utf8');
|
|
58
|
-
assert.equal(rootSkill.startsWith('---\n'), true, `${skillName} root skill must start with YAML frontmatter`);
|
|
59
|
-
assert.equal(pluginSkill.startsWith('---\n'), true, `${skillName} plugin skill must start with YAML frontmatter`);
|
|
60
|
-
assert.equal(pluginSkill, rootSkill, skillName);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('locks plan as the canonical implementation-planning contract', async () => {
|
|
65
|
-
const planSkill = await readFile(join(ROOT_SKILLS_DIR, 'plan', 'SKILL.md'), 'utf8');
|
|
66
|
-
const pluginPlanSkill = await readFile(join(PLUGIN_SKILLS_DIR, 'plan', 'SKILL.md'), 'utf8');
|
|
67
|
-
|
|
68
|
-
assert.match(planSkill, /Bite-Sized Task Granularity/);
|
|
69
|
-
assert.match(planSkill, /No Placeholders/);
|
|
70
|
-
assert.match(planSkill, /docs\/loopx\/plans\/YYYY-MM-DD-<feature-name>\.md/);
|
|
71
|
-
assert.match(planSkill, /loopx:subagent-exec/);
|
|
72
|
-
assert.doesNotMatch(planSkill, /Planner -> Architect -> Critic/);
|
|
73
|
-
assert.doesNotMatch(planSkill, /consensus-first/i);
|
|
74
|
-
assert.equal(pluginPlanSkill, planSkill);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('locks clarify to use the conditional spec or plan handoff gate', async () => {
|
|
78
|
-
const clarifySkill = await readFile(join(ROOT_SKILLS_DIR, 'clarify', 'SKILL.md'), 'utf8');
|
|
79
|
-
const pluginClarifySkill = await readFile(join(PLUGIN_SKILLS_DIR, 'clarify', 'SKILL.md'), 'utf8');
|
|
80
|
-
|
|
81
|
-
assert.equal(pluginClarifySkill, clarifySkill);
|
|
82
|
-
assert.match(clarifySkill, /needs_spec/);
|
|
83
|
-
assert.match(clarifySkill, /direct_to_plan/);
|
|
84
|
-
assert.match(clarifySkill, /docs\/loopx\/design\/<需求名>需求设计文档\.md/);
|
|
85
|
-
assert.match(clarifySkill, /docs\/loopx\/plans\/YYYY-MM-DD-<feature-name>\.md/);
|
|
86
|
-
assert.doesNotMatch(clarifySkill, /Recommended invocation: `\$spec/);
|
|
87
|
-
assert.doesNotMatch(clarifySkill, /Default handoff after normal loopx clarify: `\$plan <slug>`/);
|
|
88
|
-
assert.doesNotMatch(clarifySkill, /hand off to `build` only/i);
|
|
89
|
-
assert.doesNotMatch(clarifySkill, /direct execution/i);
|
|
90
|
-
assert.doesNotMatch(clarifySkill, /direct implementation/i);
|
|
91
|
-
assert.doesNotMatch(clarifySkill, /directly to implementation/i);
|
|
92
|
-
assert.doesNotMatch(clarifySkill, /Proceed directly to implementation/i);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('reuses the shared install core while materializing skills from the plugin shell', async () => {
|
|
96
|
-
const home = await mkdtemp(join(tmpdir(), 'loopx-plugin-home-'));
|
|
97
|
-
const env = loopxEnv(home);
|
|
98
|
-
|
|
99
|
-
await execFileAsync(process.execPath, [INSTALL_SCRIPT], {
|
|
100
|
-
cwd: REPO_ROOT,
|
|
101
|
-
env,
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
const inspection = await verifyInstallState(env);
|
|
105
|
-
assert.equal(inspection.ok, true);
|
|
106
|
-
for (const skillName of LOOPX_SKILLS) {
|
|
107
|
-
const installedSkill = await readFile(join(home, '.agents', 'skills', skillName, 'SKILL.md'), 'utf8');
|
|
108
|
-
const pluginSkill = await readFile(join(PLUGIN_SKILLS_DIR, skillName, 'SKILL.md'), 'utf8');
|
|
109
|
-
assert.equal(installedSkill, pluginSkill, skillName);
|
|
110
|
-
assert.equal(inspection.inspection.skills[skillName].registryRow.installationIdentity, 'loopx');
|
|
111
|
-
assert.equal(inspection.inspection.skills[skillName].registryRow.distributionChannel, 'plugin');
|
|
112
|
-
assert.equal(inspection.inspection.skills[skillName].registryRow.sourceUrl, PLUGIN_ROOT);
|
|
113
|
-
assert.equal(
|
|
114
|
-
inspection.inspection.skills[skillName].registryRow.provenance.some(
|
|
115
|
-
(entry) => entry.distributionChannel === 'plugin' && entry.sourceUrl === PLUGIN_ROOT,
|
|
116
|
-
),
|
|
117
|
-
true,
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const installedSpecTemplate = await readFile(join(home, '.agents', 'skills', 'spec', 'DESIGN_SPEC_TEMPLATE.md'), 'utf8');
|
|
122
|
-
const pluginSpecTemplate = await readFile(join(PLUGIN_SKILLS_DIR, 'spec', 'DESIGN_SPEC_TEMPLATE.md'), 'utf8');
|
|
123
|
-
assert.equal(installedSpecTemplate, pluginSpecTemplate);
|
|
124
|
-
});
|
|
125
|
-
});
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ai-slop-cleaner
|
|
3
|
-
description: Run an anti-slop cleanup/refactor/deslop workflow
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# AI Slop Cleaner Skill
|
|
7
|
-
|
|
8
|
-
Reduce AI-generated slop with a regression-tests-first, smell-by-smell cleanup workflow that preserves behavior and raises signal quality.
|
|
9
|
-
|
|
10
|
-
## When to Use
|
|
11
|
-
|
|
12
|
-
Use this skill when:
|
|
13
|
-
- A code path works but feels bloated, noisy, repetitive, or over-abstracted
|
|
14
|
-
- A user asks to “cleanup”, “refactor”, or “deslop” AI-generated output
|
|
15
|
-
- Follow-up implementation left duplicate code, dead code, weak boundaries, missing tests, or unnecessary wrapper layers
|
|
16
|
-
- You need a disciplined cleanup workflow without broad rewrites
|
|
17
|
-
|
|
18
|
-
## GPT-5.4 Guidance Alignment
|
|
19
|
-
|
|
20
|
-
- Keep outputs concise and evidence-dense unless risk or the user requests more detail.
|
|
21
|
-
- Treat newer user instructions as local workflow updates without discarding earlier non-conflicting constraints.
|
|
22
|
-
- Keep using inspection, tests, diagnostics, and verification until the cleanup is grounded.
|
|
23
|
-
- Proceed automatically through clear, reversible cleanup steps; ask only when a choice materially changes scope or behavior.
|
|
24
|
-
|
|
25
|
-
## Scoped File Lists and Ralph Workflow
|
|
26
|
-
|
|
27
|
-
- This skill can accept a **file list scope** instead of a whole feature area.
|
|
28
|
-
- When the caller provides a changed-files list (for example, Ralph session-owned edits), keep the cleanup strictly bounded to those files.
|
|
29
|
-
- In the **Ralph workflow**, the mandatory deslop pass should run this skill on Ralph's changed files only, in standard mode unless the caller explicitly requests otherwise.
|
|
30
|
-
|
|
31
|
-
## Procedure
|
|
32
|
-
|
|
33
|
-
1. **Lock behavior with regression tests first**
|
|
34
|
-
- Identify the behavior that must not change
|
|
35
|
-
- Add or run targeted regression tests before editing cleanup candidates
|
|
36
|
-
- If behavior is currently untested, create the narrowest test coverage needed first
|
|
37
|
-
|
|
38
|
-
2. **Create a cleanup plan before code**
|
|
39
|
-
- List the specific smells to remove
|
|
40
|
-
- Bound the pass to the requested files/scope
|
|
41
|
-
- If a file list scope is provided, keep the pass restricted to that changed-files list
|
|
42
|
-
- Order fixes from safest/highest-signal to riskiest
|
|
43
|
-
- Do not start coding until the cleanup plan is explicit
|
|
44
|
-
|
|
45
|
-
3. **Categorize issues before editing**
|
|
46
|
-
- **Duplication** — repeated logic, copy-paste branches, redundant helpers
|
|
47
|
-
- **Dead code** — unused code, unreachable branches, stale flags, debug leftovers
|
|
48
|
-
- **Needless abstraction** — pass-through wrappers, speculative indirection, single-use helper layers
|
|
49
|
-
- **Boundary violations** — hidden coupling, leaky responsibilities, wrong-layer imports or side effects
|
|
50
|
-
- **Missing tests** — behavior not locked, weak regression coverage, gaps around edge cases
|
|
51
|
-
|
|
52
|
-
4. **Execute passes one smell at a time**
|
|
53
|
-
- **Pass 1: Dead code deletion**
|
|
54
|
-
- **Pass 2: Duplicate removal**
|
|
55
|
-
- **Pass 3: Naming/error handling cleanup**
|
|
56
|
-
- **Pass 4: Test reinforcement**
|
|
57
|
-
- Re-run targeted verification after each pass
|
|
58
|
-
- Avoid bundling unrelated refactors into the same edit set
|
|
59
|
-
|
|
60
|
-
5. **Run quality gates**
|
|
61
|
-
- Regression tests stay green
|
|
62
|
-
- Lint passes
|
|
63
|
-
- Typecheck passes
|
|
64
|
-
- Relevant unit/integration tests pass
|
|
65
|
-
- Static/security scan passes when available
|
|
66
|
-
- Diff stays minimal and scoped
|
|
67
|
-
- No new abstractions or dependencies unless explicitly required
|
|
68
|
-
|
|
69
|
-
6. **Finish with an evidence-dense report**
|
|
70
|
-
- Changed files
|
|
71
|
-
- Simplifications made
|
|
72
|
-
- Tests/diagnostics/build checks run
|
|
73
|
-
- Remaining risks
|
|
74
|
-
- Residual follow-ups or consciously deferred cleanup
|
|
75
|
-
|
|
76
|
-
## Output Format
|
|
77
|
-
|
|
78
|
-
```text
|
|
79
|
-
AI SLOP CLEANUP REPORT
|
|
80
|
-
======================
|
|
81
|
-
|
|
82
|
-
Scope: [files or feature area]
|
|
83
|
-
Behavior Lock: [targeted regression tests added/run]
|
|
84
|
-
Cleanup Plan: [bounded smells and order]
|
|
85
|
-
|
|
86
|
-
Passes Completed:
|
|
87
|
-
1. Pass 1: Dead code deletion - [concise fix]
|
|
88
|
-
2. Pass 2: Duplicate removal - [concise fix]
|
|
89
|
-
3. Pass 3: Naming/error handling cleanup - [concise fix]
|
|
90
|
-
4. Pass 4: Test reinforcement - [concise fix]
|
|
91
|
-
|
|
92
|
-
Quality Gates:
|
|
93
|
-
- Regression tests: PASS/FAIL
|
|
94
|
-
- Lint: PASS/FAIL
|
|
95
|
-
- Typecheck: PASS/FAIL
|
|
96
|
-
- Tests: PASS/FAIL
|
|
97
|
-
- Static/security scan: PASS/FAIL or N/A
|
|
98
|
-
|
|
99
|
-
Changed Files:
|
|
100
|
-
- [path] - [simplification]
|
|
101
|
-
|
|
102
|
-
Remaining Risks:
|
|
103
|
-
- [none or short deferred item]
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Scenario Examples
|
|
107
|
-
|
|
108
|
-
**Good:** The user says `continue` after tests already lock behavior and the next smell pass is clear. Continue with the next bounded cleanup pass.
|
|
109
|
-
|
|
110
|
-
**Good:** The user narrows the scope to a specific file after planning. Keep the regression-tests-first workflow, but apply the new scope locally.
|
|
111
|
-
|
|
112
|
-
**Bad:** Start rewriting architecture before protecting behavior with tests.
|
|
113
|
-
|
|
114
|
-
**Bad:** Collapse multiple smell categories into one large refactor with no intermediate verification.
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: autoresearch
|
|
3
|
-
description: Stateful validator-gated research loop with native-hook persistence
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Autoresearch
|
|
7
|
-
|
|
8
|
-
Autoresearch is the skill-first replacement for the deprecated `omx autoresearch` command.
|
|
9
|
-
It keeps the useful measured-research loop, but it now runs as a native-hook stateful workflow instead of a direct CLI or tmux launch surface.
|
|
10
|
-
|
|
11
|
-
## Use when
|
|
12
|
-
- You want a Ralph-ish persistent research loop
|
|
13
|
-
- The task should keep nudging until explicit validation evidence exists
|
|
14
|
-
- You want init-time choice between script validation and prompt+architect validation
|
|
15
|
-
|
|
16
|
-
## Do not use when
|
|
17
|
-
- You want the old `omx autoresearch` command surface (hard-deprecated)
|
|
18
|
-
- You want detached tmux or split-pane launch parity
|
|
19
|
-
- You have not decided the validation regime yet
|
|
20
|
-
|
|
21
|
-
## Core contract
|
|
22
|
-
1. **Init chooses validation mode.** Pick exactly one:
|
|
23
|
-
- `mission-validator-script`
|
|
24
|
-
- `prompt-architect-artifact`
|
|
25
|
-
2. **Persist mode state** in `.omx/state/.../autoresearch-state.json` including:
|
|
26
|
-
- `validation_mode`
|
|
27
|
-
- `completion_artifact_path`
|
|
28
|
-
- `mission_validator_command` **or** `validator_prompt`
|
|
29
|
-
- optional `output_artifact_path`
|
|
30
|
-
3. **Completion is artifact-gated.** The loop does not stop because the model says “done”, because a stop hook fired once, or because several turns were no-ops.
|
|
31
|
-
4. **Direct CLI launch is gone.** Use `$deep-interview --autoresearch` for intake and `$autoresearch` for execution.
|
|
32
|
-
|
|
33
|
-
## Completion artifact contract
|
|
34
|
-
|
|
35
|
-
### `mission-validator-script`
|
|
36
|
-
The completion artifact must exist and record a passing validator result, for example:
|
|
37
|
-
|
|
38
|
-
```json
|
|
39
|
-
{
|
|
40
|
-
"status": "passed",
|
|
41
|
-
"passed": true,
|
|
42
|
-
"summary": "metric improved beyond baseline"
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### `prompt-architect-artifact`
|
|
47
|
-
The completion artifact must include both an architect approval verdict and an output artifact path, for example:
|
|
48
|
-
|
|
49
|
-
```json
|
|
50
|
-
{
|
|
51
|
-
"validator_prompt": "Review the research output against the mission.",
|
|
52
|
-
"architect_review": { "verdict": "approved" },
|
|
53
|
-
"output_artifact_path": ".omx/specs/autoresearch-demo/report.md"
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Recommended flow
|
|
58
|
-
1. Run `$deep-interview --autoresearch` to clarify mission + evaluator.
|
|
59
|
-
2. Materialize `.omx/specs/autoresearch-{slug}/mission.md`, `sandbox.md`, and `result.json`.
|
|
60
|
-
3. Start `$autoresearch` with the chosen validation mode stored in mode state.
|
|
61
|
-
4. Let stop-hook / auto-nudge continue until the completion artifact satisfies the chosen validation mode.
|
|
62
|
-
5. Finish only after the validator artifact is complete.
|
|
63
|
-
|
|
64
|
-
## Migration note
|
|
65
|
-
- `omx autoresearch` is hard-deprecated.
|
|
66
|
-
- No direct CLI launch.
|
|
67
|
-
- No tmux split-pane launch.
|
|
68
|
-
- No noop-count completion gate.
|