@apptoolkit/harness 1.0.4 → 1.0.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apptoolkit/harness",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "A portable harness for configuring AI coding agents and engineering workflows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,6 +37,7 @@
37
37
  "payload/author-style/spacing.llm.md",
38
38
  "payload/author-style/spacing.test.ts",
39
39
  "payload/author-style/spacing.ts",
40
+ "payload/harness/LEARNING.md",
40
41
  "payload/harness/POLICY.md",
41
42
  "payload/harness/PROJECT.md",
42
43
  "payload/harness/REVIEW.md",
@@ -2,6 +2,12 @@
2
2
 
3
3
  Use this index when adopting a project or opening a fresh agent session. Resolve the project, read its applicable rules, and open the smallest workflow that matches the request.
4
4
 
5
+ ## Every session
6
+
7
+ 1. Resolve the active repository and its rules with the [project guide](harness/PROJECT.md) and [operating policy](harness/POLICY.md). Use the workflow index for the task. The native setup command is for init and update.
8
+ 2. Look up relevant prior work in [project knowledge](harness-local/KNOWLEDGE.md). Use the matching record and bounded evidence. Prefer tested [project tools](harness-local/TOOLS.md) for deterministic work.
9
+ 3. At each decision, correction, useful discovery, repeated operation or handoff, follow the [learning and improvement procedure](harness/LEARNING.md). Maintain applicable sibling source maps after code changes and verify the latest links before handoff.
10
+
5
11
  | Need | Start here |
6
12
  | --- | --- |
7
13
  | Find the procedure for a natural request | [Workflow index](harness/WORKFLOWS.md) |
@@ -9,6 +15,7 @@ Use this index when adopting a project or opening a fresh agent session. Resolve
9
15
  | Adopt, initialize or update this installation | [W20 Adoption](harness/workflows/W20.md) |
10
16
  | Resolve repositories, services and project conventions | [Project guide](harness/PROJECT.md) |
11
17
  | Check permissions, engineering rules and learning | [Operating policy](harness/POLICY.md) |
18
+ | Apply a lesson, preserve research or improve a check | [Learning and improvement](harness/LEARNING.md) |
12
19
  | Audit a claim or independently review code | [Independent review](harness/REVIEW.md) |
13
20
  | Prepare a decision, work unit or checkpoint | [Templates](harness/TEMPLATES.md) |
14
21
  | Verify coverage against an explicit source inventory | [W23 Verification](harness/workflows/W23.md) |
@@ -5,7 +5,7 @@ Use this profile whenever an agent writes or changes authored TypeScript in a pr
5
5
  - [Writing rules](#writing-rules): Read before editing code.
6
6
  - [Deterministic checks](#deterministic-checks): Select an appropriate profile.
7
7
  - [Install and run](#install-and-run): Run after each code edit batch and before handoff. See the [checker map](check.llm.md) when maintaining the tool.
8
- - [Evidence and precedence](#evidence-and-precedence): Determine what is personal, historical or specific to a project.
8
+ - [Evidence and precedence](#evidence-and-precedence): Apply the target project rules and verify changes.
9
9
 
10
10
  ## Writing rules
11
11
 
@@ -49,6 +49,8 @@ For an existing project, follow its own rules and tools first. The verifier refu
49
49
 
50
50
  Record the selected paths and result in the normal verification evidence. Add this instruction to the adopting agent's entry point or shared verification instructions. Every agent should run the same command after a code edit batch and before delivery. The package installs no editor, Git, CI or model-specific hook.
51
51
 
52
+ For an agent-only rule confirmed by project review, keep its configuration in a project-owned path such as `llm/harness-local/biome-agent.json`. Set `linter.rules.recommended` to false and add the scoped rules and project-owned plugins. Run the same checker with `--project-config llm/harness-local/biome-agent.json` and explicit authored paths. The checker runs the pinned profile first, followed by a separate lint pass for the local configuration. Use the corresponding `--profile` when its supplementary checks apply. A project-wide Biome configuration keeps its native command.
53
+
52
54
  > After each code edit batch and before handoff, run the project's applicable Biome checks. When no applicable Biome configuration exists, run the compatible profile in `llm/author-style/README.md` on the edited TypeScript files. Use the project's established formatter and lint policy first. Record the result with the other verification evidence.
53
55
 
54
56
  ## Evidence and precedence
@@ -84,6 +84,32 @@ test('uses the isolated formatter and linter on exact paths outside the harness
84
84
  assert.match(success.stdout, /Checked 1 file/);
85
85
  });
86
86
 
87
+ test('checks learned project rules in isolation and keeps adjacent unselected files out of scope', (context) => {
88
+ const root = mkdtempSync(join(tmpdir(), 'harness-style-'));
89
+ const directory = join(root, 'llm');
90
+ const profile = fileURLToPath(new URL('biome-core.json', import.meta.url));
91
+
92
+ context.after(() => rmSync(root, { recursive: true, force: true }));
93
+ mkdirSync(directory);
94
+ writeFileSync(
95
+ join(directory, 'review.json'),
96
+ JSON.stringify({ linter: { rules: { recommended: false, suspicious: { noConsole: 'error' } } } }),
97
+ );
98
+ writeFileSync(join(root, 'good.ts'), 'export const value = 1;\n');
99
+ writeFileSync(join(root, 'bad.ts'), "console.log('noise');\n");
100
+
101
+ const good = execute(root, '--project-config', 'llm/review.json', 'good.ts');
102
+ const bad = execute(root, '--project-config', 'llm/review.json', 'bad.ts');
103
+
104
+ assert.equal(good.status, 0, good.stderr);
105
+ assert.equal(bad.status, 1);
106
+ assert.match(bad.stderr, /noConsole/u);
107
+ assert.equal(execute(root, 'bad.ts').status, 0);
108
+ assert.match(execute(root, '--project-config', profile, 'good.ts').stderr, /inside/u);
109
+ symlinkSync('review.json', join(directory, 'alias.json'));
110
+ assert.match(execute(root, '--project-config', 'llm/alias.json', 'good.ts').stderr, /project-owned/u);
111
+ });
112
+
87
113
  test('enforces core types, explicit updates, braces, branches and class layout', (context) => {
88
114
  const root = mkdtempSync(join(tmpdir(), 'harness-style-'));
89
115
 
@@ -14,6 +14,7 @@ const requestSchema = z.object({
14
14
  root: z.string().refine(isAbsolute, 'Supply the absolute project directory with --root.'),
15
15
  profile: z.enum(['core', 'react', 'sql']),
16
16
  lintOnly: z.boolean(),
17
+ projectConfig: z.string().endsWith('.json').optional(),
17
18
  files: z.array(z.string().min(1)).min(1, 'Supply the files you changed.'),
18
19
  });
19
20
 
@@ -63,12 +64,14 @@ function checkFiles(argumentsList: string[]): number {
63
64
  root: { type: 'string' },
64
65
  profile: { type: 'string', default: 'core' },
65
66
  'lint-only': { type: 'boolean', default: false },
67
+ 'project-config': { type: 'string' },
66
68
  },
67
69
  });
68
70
  const request = requestSchema.parse({
69
71
  root: parsed.values.root,
70
72
  profile: parsed.values.profile,
71
73
  lintOnly: parsed.values['lint-only'],
74
+ projectConfig: parsed.values['project-config'],
72
75
  files: parsed.positionals,
73
76
  });
74
77
  const requestedRoot = resolve(request.root);
@@ -120,36 +123,52 @@ function checkFiles(argumentsList: string[]): number {
120
123
  }
121
124
 
122
125
  const config = fileURLToPath(new URL(configurations[request.profile], import.meta.url));
126
+ const checks = [{ config, command: request.lintOnly ? 'lint' : 'check' }];
127
+
128
+ if (request.projectConfig) {
129
+ const localConfig = resolve(root, request.projectConfig);
130
+
131
+ targetRelativePath(root, localConfig);
132
+
133
+ if (realpathSync(localConfig) !== localConfig || !statSync(localConfig).isFile()) {
134
+ throw new Error(`Use a regular project-owned Biome configuration: ${localConfig}`);
135
+ }
136
+
137
+ checks.push({ config: localConfig, command: 'lint' });
138
+ }
139
+
123
140
  const biome = requireFromProfile.resolve('@biomejs/biome/bin/biome');
124
141
  const runtimeArguments = process.versions.bun ? ['--no-env-file', '--no-install'] : [];
125
142
  const environment = { ...process.env };
126
143
 
127
144
  delete environment.BIOME_BINARY;
128
145
 
129
- const result = spawnSync(
130
- process.execPath,
131
- [
132
- ...runtimeArguments,
133
- biome,
134
- request.lintOnly ? 'lint' : 'check',
135
- `--config-path=${config}`,
136
- '--error-on-warnings',
137
- '--',
138
- ...sources.keys(),
139
- ],
140
- { cwd: root, env: environment, stdio: 'inherit' },
141
- );
142
-
143
- if (result.error) {
144
- throw new Error(`Cannot launch Biome in ${root}: ${result.error.message}`, { cause: result.error });
145
- }
146
+ for (const check of checks) {
147
+ const result = spawnSync(
148
+ process.execPath,
149
+ [
150
+ ...runtimeArguments,
151
+ biome,
152
+ check.command,
153
+ `--config-path=${check.config}`,
154
+ '--error-on-warnings',
155
+ '--',
156
+ ...sources.keys(),
157
+ ],
158
+ { cwd: root, env: environment, stdio: 'inherit' },
159
+ );
160
+
161
+ if (result.error) {
162
+ throw new Error(`Cannot launch Biome in ${root}: ${result.error.message}`, { cause: result.error });
163
+ }
146
164
 
147
- if (result.status === null) {
148
- throw new Error(`Biome did not complete in ${root}${result.signal ? ` (${result.signal})` : ''}.`);
149
- }
165
+ if (result.status === null) {
166
+ throw new Error(`Biome did not complete in ${root}${result.signal ? ` (${result.signal})` : ''}.`);
167
+ }
150
168
 
151
- if (result.status !== 0) {
152
- return result.status;
169
+ if (result.status !== 0) {
170
+ return result.status;
171
+ }
153
172
  }
154
173
 
155
174
  let count = 0;
@@ -0,0 +1,18 @@
1
+ # Project learning and improvement
2
+
3
+ ## Find prior work
4
+
5
+ Open `llm/harness-local/KNOWLEDGE.md` when a task involves a project rule, domain question, feedback or investigation. Match by repository, feature, ticket vocabulary and related systems. Use `rtk proxy rg -in -- <topic> llm/harness-local/KNOWLEDGE.md` when the index grows. Read the smallest relevant record with the installed `context` command and reuse its verified findings. Check the authority, evidence revision and revalidation trigger before relying on a conclusion. Open original sources when resolving gaps, changes or contradictions.
6
+
7
+ ## Capture a durable finding
8
+
9
+ Capture important user decisions, human explanations, PR feedback, and findings from documentation or ticket research at the point of discovery. Use the project's established authority and record type. Where a project does not have one, add a topical note under `llm/harness-local/` and link it from the knowledge index. Give each record a short topical title, search terms, repository and version scope, observed or decided date, compact finding, source locator, authority, confidence or approval status, owner and revalidation trigger. Include a usable example when it disambiguates behavior. Link to the source revision, comment, message, email or document section through the approved route. Keep restricted detail and raw excerpts in the approved private store. Record a discoverable pointer only when its visibility is authorized.
10
+
11
+ Keep hypotheses and proposed standards visibly pending. Capture conflicting evidence with its applicable scopes and ask the decision owner when precedence is unresolved. When a finding changes, preserve the older record or its history and link to the decision that supersedes it.
12
+
13
+ ## Improve tools and rules
14
+
15
+ 1. When work repeats, fails in a preventable way or consumes context through noisy stdout, inspect the project tool catalog and existing runner. Prefer native commands or a tested utility. Extend the smallest suitable implementation or add a parameterized TypeScript utility under the project-owned `llm/` tools area. Quote arguments independently, keep warnings and failure details, preserve exit status, and offer a native unfiltered mode. Test ordinary inputs, unexpected output and failures. Index the exact command, inputs, outputs, effects, recovery and limits.
16
+ 2. When human or PR review confirms a repeatable code rule, capture a passing and a failing example and check for a compatible Biome rule or Grit pattern. Apply it in the repository configuration for project-wide Biome, or in an agent-only configuration passed to the isolated checker with `--project-config`. Store that configuration with the applicable project rules and register the exact check in the tools index. Preserve the project's formatter, scope and existing rules. Verify both examples and the intended scope against the actual checker. Use a tested supplement for a mechanical rule that Biome cannot express. Index judgment-based guidance with examples and a review gate.
17
+ 3. Apply scoped, authorized corrections to project-owned harness instructions, indexes, tools, checks and workflows as part of ordinary work. Put shared harness changes under source control in its owning project through that project's workflow. In an installed project, keep local additions under `llm/harness-local/` or its established project-owned paths. Link extensions from the improvements index. Preserve evidence, tests, the scope of the change, and the recovery route. If a rule or permission would change, obtain the decision from its owner.
18
+ 4. Rerun affected checks and confirm a fresh session can reach the resulting artifact from the installed index. Use [W21](workflows/W21.md) for maps and knowledge records, [W23](workflows/W23.md) for checks and [W20](workflows/W20.md) for package updates.
@@ -26,6 +26,8 @@ For a new project, account for every source family and require 100 percent measu
26
26
 
27
27
  ## Knowledge and improvement
28
28
 
29
+ Apply the [learning and improvement procedure](LEARNING.md) during ordinary work. Follow its retrieval, capture and verification steps whenever the corresponding trigger occurs.
30
+
29
31
  Maintain an indexed, concise project memory. Before dependent work, capture confirmed decisions, corrections and discoveries at the right checkpoint with scope, rationale, evidence, owner and approval status. Separate observations, proposals and unresolved choices from accepted rules. Keep private source material and raw sensitive output in approved private storage outside the harness.
30
32
 
31
33
  Use a sibling `.llm.md` for authored implementation above 200 physical lines, for shorter important entry points, or where safe navigation needs a map. Apply the project's own thresholds and exemptions where established. Give each map a small index and stable heading or symbol locators for responsibilities, interfaces, dependencies, decisions, invariants, effects and tests. Link it from the relevant project or directory index and verify it against the source after changes.