harness-everything 0.2.1 → 0.2.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 (70) hide show
  1. package/README.md +1 -1
  2. package/build-multi-agent-system/SKILL.md +68 -68
  3. package/create-agent-launcher/SKILL.md +48 -48
  4. package/docs/architecture.md +2 -2
  5. package/docs/workflows/build-multi-agent-system.md +62 -62
  6. package/docs/workflows/create-agent-launcher.md +62 -62
  7. package/docs/workflows/environment-detection.md +63 -63
  8. package/docs/workflows/eval-harness.md +57 -57
  9. package/docs/workflows/fable-discipline.md +59 -59
  10. package/docs/workflows/fable-mode.md +32 -32
  11. package/docs/workflows/git-commit.md +62 -62
  12. package/docs/workflows/grill-me.md +62 -62
  13. package/docs/workflows/grill-with-docs.md +62 -62
  14. package/docs/workflows/improve-codebase-architecture.md +60 -60
  15. package/docs/workflows/repo-docs.md +59 -59
  16. package/docs/workflows/rewrite-commits.md +60 -60
  17. package/docs/workflows/security-review.md +58 -58
  18. package/docs/workflows/self-evolve.md +59 -59
  19. package/docs/workflows/tdd.md +39 -39
  20. package/docs/workflows/todo-driven-workflow.md +36 -36
  21. package/docs/workflows/using-git-worktrees.md +63 -63
  22. package/docs/workflows/verification-loop.md +69 -69
  23. package/docs/workflows/verify-before-claim.md +60 -60
  24. package/docs/workflows/zoom-out.md +62 -62
  25. package/environment-detection/SKILL.md +77 -77
  26. package/eval-framework/behavioral-test.js +105 -105
  27. package/eval-framework/mechanism-test.js +251 -251
  28. package/eval-harness/SKILL.md +59 -59
  29. package/fable-discipline/SKILL.md +38 -38
  30. package/fable-mode/SKILL.md +51 -51
  31. package/git-commit/SKILL.md +55 -55
  32. package/grill-me/SKILL.md +36 -36
  33. package/grill-with-docs/SKILL.md +99 -99
  34. package/harness-everything/SKILL.md +141 -141
  35. package/harness-everything/examples/README.md +9 -9
  36. package/harness-everything/examples/todo-workflow.md +22 -22
  37. package/harness-everything/scripts/todo-cli.js +157 -157
  38. package/harness-everything/scripts/verify-gate.js +31 -31
  39. package/hooks/scripts/atomic-commit-check.js +68 -68
  40. package/hooks/scripts/context-compact.js +114 -114
  41. package/hooks/scripts/lib/platforms/claude.js +132 -42
  42. package/hooks/scripts/lib/platforms/codex.js +96 -46
  43. package/hooks/scripts/lib/platforms/continue.js +73 -41
  44. package/hooks/scripts/lib/platforms/copilot.js +91 -41
  45. package/hooks/scripts/lib/platforms/cursor.js +71 -41
  46. package/hooks/scripts/lib/platforms/hermes.js +25 -0
  47. package/hooks/scripts/rule-of-3.js +176 -176
  48. package/improve-codebase-architecture/SKILL.md +44 -44
  49. package/install-cognitive-os/SKILL.md +95 -95
  50. package/package.json +1 -1
  51. package/repo-docs/SKILL.md +45 -45
  52. package/rewrite-commits/SKILL.md +32 -32
  53. package/scripts/installer.js +57 -200
  54. package/scripts/lib/advisory-text.js +163 -163
  55. package/scripts/lib/claude-hooks.js +71 -71
  56. package/scripts/lib/manifest.js +82 -82
  57. package/scripts/lib/prompts.js +241 -241
  58. package/scripts/lib/skills.js +174 -172
  59. package/scripts/lib/workspace.js +28 -28
  60. package/security-review/SKILL.md +510 -510
  61. package/self-evolve/SKILL.md +54 -54
  62. package/skill-creator/SKILL.md +91 -91
  63. package/skill-creator/references/testing-workflow.md +32 -32
  64. package/skill-style/SKILL.md +48 -48
  65. package/tdd/SKILL.md +53 -53
  66. package/todo-driven-workflow/SKILL.md +54 -54
  67. package/using-git-worktrees/SKILL.md +161 -161
  68. package/verification-loop/SKILL.md +138 -138
  69. package/verify-before-claim/SKILL.md +86 -86
  70. package/zoom-out/SKILL.md +90 -90
@@ -1,71 +1,71 @@
1
- // Merge/remove Harness's hook entries in a Claude Code settings.json without
2
- // disturbing anything else a user (or another tool) put there.
3
- const fs = require('fs');
4
-
5
- // Every hook this package ships is namespaced "harness:<phase>:<name>" (see
6
- // hooks/hooks.json) specifically so removal can match on that prefix alone -
7
- // never on loose text like "does the command mention harness", which could
8
- // false-positive on someone else's unrelated hook (e.g. a script whose path
9
- // or name happens to contain "harness").
10
- function isHarnessHook(hook) {
11
- return !!(hook && hook.id && hook.id.startsWith('harness:'));
12
- }
13
-
14
- function mergeHarnessHooks(claudeConfig, resolvedHooks) {
15
- claudeConfig.hooks = claudeConfig.hooks || {};
16
- for (const [hookType, hookList] of Object.entries(resolvedHooks)) {
17
- const existingList = claudeConfig.hooks[hookType] || [];
18
- const mergedList = [...existingList];
19
- hookList.forEach(newHook => {
20
- const existsIdx = mergedList.findIndex(h => h.id === newHook.id);
21
- if (existsIdx !== -1) {
22
- mergedList[existsIdx] = newHook;
23
- } else {
24
- mergedList.push(newHook);
25
- }
26
- });
27
- claudeConfig.hooks[hookType] = mergedList;
28
- }
29
- return claudeConfig;
30
- }
31
-
32
- function removeHarnessHooks(claudeSettingsFile) {
33
- if (!fs.existsSync(claudeSettingsFile)) return false;
34
- try {
35
- const content = fs.readFileSync(claudeSettingsFile, 'utf8');
36
- let config = JSON.parse(content);
37
- if (!config.hooks) return false;
38
-
39
- let modified = false;
40
- for (const [hookType, hookList] of Object.entries(config.hooks)) {
41
- if (!Array.isArray(hookList)) continue;
42
- const originalLength = hookList.length;
43
- config.hooks[hookType] = hookList.filter(hook => !isHarnessHook(hook));
44
- if (config.hooks[hookType].length !== originalLength) {
45
- modified = true;
46
- }
47
- if (config.hooks[hookType].length === 0) {
48
- delete config.hooks[hookType];
49
- }
50
- }
51
- if (Object.keys(config.hooks || {}).length === 0) {
52
- delete config.hooks;
53
- }
54
-
55
- if (modified) {
56
- if (Object.keys(config).length === 0) {
57
- fs.unlinkSync(claudeSettingsFile);
58
- console.log(` ✅ Cleaned up and removed empty Claude settings file: ${claudeSettingsFile}`);
59
- } else {
60
- fs.writeFileSync(claudeSettingsFile, JSON.stringify(config, null, 2), 'utf8');
61
- console.log(` ✅ Safely removed Harness hooks from Claude settings: ${claudeSettingsFile}`);
62
- }
63
- return true;
64
- }
65
- } catch (e) {
66
- console.warn(` ⚠️ Error cleaning Claude settings file ${claudeSettingsFile}: ${e.message}`);
67
- }
68
- return false;
69
- }
70
-
71
- module.exports = { isHarnessHook, mergeHarnessHooks, removeHarnessHooks };
1
+ // Merge/remove Harness's hook entries in a Claude Code settings.json without
2
+ // disturbing anything else a user (or another tool) put there.
3
+ const fs = require('fs');
4
+
5
+ // Every hook this package ships is namespaced "harness:<phase>:<name>" (see
6
+ // hooks/hooks.json) specifically so removal can match on that prefix alone -
7
+ // never on loose text like "does the command mention harness", which could
8
+ // false-positive on someone else's unrelated hook (e.g. a script whose path
9
+ // or name happens to contain "harness").
10
+ function isHarnessHook(hook) {
11
+ return !!(hook && hook.id && hook.id.startsWith('harness:'));
12
+ }
13
+
14
+ function mergeHarnessHooks(claudeConfig, resolvedHooks) {
15
+ claudeConfig.hooks = claudeConfig.hooks || {};
16
+ for (const [hookType, hookList] of Object.entries(resolvedHooks)) {
17
+ const existingList = claudeConfig.hooks[hookType] || [];
18
+ const mergedList = [...existingList];
19
+ hookList.forEach(newHook => {
20
+ const existsIdx = mergedList.findIndex(h => h.id === newHook.id);
21
+ if (existsIdx !== -1) {
22
+ mergedList[existsIdx] = newHook;
23
+ } else {
24
+ mergedList.push(newHook);
25
+ }
26
+ });
27
+ claudeConfig.hooks[hookType] = mergedList;
28
+ }
29
+ return claudeConfig;
30
+ }
31
+
32
+ function removeHarnessHooks(claudeSettingsFile) {
33
+ if (!fs.existsSync(claudeSettingsFile)) return false;
34
+ try {
35
+ const content = fs.readFileSync(claudeSettingsFile, 'utf8');
36
+ let config = JSON.parse(content);
37
+ if (!config.hooks) return false;
38
+
39
+ let modified = false;
40
+ for (const [hookType, hookList] of Object.entries(config.hooks)) {
41
+ if (!Array.isArray(hookList)) continue;
42
+ const originalLength = hookList.length;
43
+ config.hooks[hookType] = hookList.filter(hook => !isHarnessHook(hook));
44
+ if (config.hooks[hookType].length !== originalLength) {
45
+ modified = true;
46
+ }
47
+ if (config.hooks[hookType].length === 0) {
48
+ delete config.hooks[hookType];
49
+ }
50
+ }
51
+ if (Object.keys(config.hooks || {}).length === 0) {
52
+ delete config.hooks;
53
+ }
54
+
55
+ if (modified) {
56
+ if (Object.keys(config).length === 0) {
57
+ fs.unlinkSync(claudeSettingsFile);
58
+ console.log(` ✅ Cleaned up and removed empty Claude settings file: ${claudeSettingsFile}`);
59
+ } else {
60
+ fs.writeFileSync(claudeSettingsFile, JSON.stringify(config, null, 2), 'utf8');
61
+ console.log(` ✅ Safely removed Harness hooks from Claude settings: ${claudeSettingsFile}`);
62
+ }
63
+ return true;
64
+ }
65
+ } catch (e) {
66
+ console.warn(` ⚠️ Error cleaning Claude settings file ${claudeSettingsFile}: ${e.message}`);
67
+ }
68
+ return false;
69
+ }
70
+
71
+ module.exports = { isHarnessHook, mergeHarnessHooks, removeHarnessHooks };
@@ -1,82 +1,82 @@
1
- // Tracks exactly what this package installed, so uninstall can remove
2
- // precisely those paths instead of sweeping shared directories that may also
3
- // hold content from other tools, the user's own manual additions, or
4
- // self-evolve's locally-generated skills.
5
- //
6
- // The manifest always lives at <platform-home>/harness-everything/manifest.json
7
- // - e.g. .claude/harness-everything/manifest.json, .cursor/harness-everything/
8
- // manifest.json, or (global scope) ~/.agents/harness-everything/manifest.json.
9
- // harness-everything/ is a subfolder this package exclusively owns inside a
10
- // directory that already belongs to that platform (or, for global scope, the
11
- // shared ~/.agents convention) - nothing else creates a directory literally
12
- // named "harness-everything" there, so nesting under it is what makes "the
13
- // manifest can only describe our own installs" actually true.
14
- const fs = require('fs');
15
- const path = require('path');
16
-
17
- const PACKAGE_NAME = 'harness-everything';
18
- const HARNESS_AUTHOR = 'Miya Daniel | Harness Core Team';
19
- const HARNESS_DIR_NAME = 'harness-everything';
20
-
21
- function getHarnessDir(homeDir) {
22
- return path.join(homeDir, HARNESS_DIR_NAME);
23
- }
24
-
25
- function getManifestPath(homeDir) {
26
- return path.join(getHarnessDir(homeDir), 'manifest.json');
27
- }
28
-
29
- function readManifest(manifestPath) {
30
- if (!fs.existsSync(manifestPath)) {
31
- return { package: PACKAGE_NAME, skills: [] };
32
- }
33
- try {
34
- const data = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
35
- if (!Array.isArray(data.skills)) data.skills = [];
36
- return data;
37
- } catch (e) {
38
- return { package: PACKAGE_NAME, skills: [] };
39
- }
40
- }
41
-
42
- function writeManifest(manifestPath, data) {
43
- fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
44
- fs.writeFileSync(manifestPath, JSON.stringify(data, null, 2), 'utf8');
45
- }
46
-
47
- function recordSkillInstall(manifestPath, packageVersion, skillId, dirPath) {
48
- const data = readManifest(manifestPath);
49
- data.package = PACKAGE_NAME;
50
- data.version = packageVersion;
51
- data.updatedAt = new Date().toISOString();
52
- const idx = data.skills.findIndex(s => s.dirPath === dirPath);
53
- const entry = { id: skillId, dirPath, installedAt: new Date().toISOString() };
54
- if (idx !== -1) data.skills[idx] = entry;
55
- else data.skills.push(entry);
56
- writeManifest(manifestPath, data);
57
- }
58
-
59
- // Removes one skill entry, and - once no skills remain in it - deletes the
60
- // manifest file itself rather than leaving an empty bookkeeping file behind.
61
- function removeSkillFromManifest(manifestPath, dirPath) {
62
- if (!fs.existsSync(manifestPath)) return;
63
- const data = readManifest(manifestPath);
64
- data.skills = data.skills.filter(s => s.dirPath !== dirPath);
65
- if (data.skills.length === 0) {
66
- fs.unlinkSync(manifestPath);
67
- } else {
68
- writeManifest(manifestPath, data);
69
- }
70
- }
71
-
72
- module.exports = {
73
- PACKAGE_NAME,
74
- HARNESS_AUTHOR,
75
- HARNESS_DIR_NAME,
76
- getHarnessDir,
77
- getManifestPath,
78
- readManifest,
79
- writeManifest,
80
- recordSkillInstall,
81
- removeSkillFromManifest,
82
- };
1
+ // Tracks exactly what this package installed, so uninstall can remove
2
+ // precisely those paths instead of sweeping shared directories that may also
3
+ // hold content from other tools, the user's own manual additions, or
4
+ // self-evolve's locally-generated skills.
5
+ //
6
+ // The manifest always lives at <platform-home>/harness-everything/manifest.json
7
+ // - e.g. .claude/harness-everything/manifest.json, .cursor/harness-everything/
8
+ // manifest.json, or (global scope) ~/.agents/harness-everything/manifest.json.
9
+ // harness-everything/ is a subfolder this package exclusively owns inside a
10
+ // directory that already belongs to that platform (or, for global scope, the
11
+ // shared ~/.agents convention) - nothing else creates a directory literally
12
+ // named "harness-everything" there, so nesting under it is what makes "the
13
+ // manifest can only describe our own installs" actually true.
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+
17
+ const PACKAGE_NAME = 'harness-everything';
18
+ const HARNESS_AUTHOR = 'Miya Daniel | Harness Core Team';
19
+ const HARNESS_DIR_NAME = 'harness-everything';
20
+
21
+ function getHarnessDir(homeDir) {
22
+ return path.join(homeDir, HARNESS_DIR_NAME);
23
+ }
24
+
25
+ function getManifestPath(homeDir) {
26
+ return path.join(getHarnessDir(homeDir), 'manifest.json');
27
+ }
28
+
29
+ function readManifest(manifestPath) {
30
+ if (!fs.existsSync(manifestPath)) {
31
+ return { package: PACKAGE_NAME, skills: [] };
32
+ }
33
+ try {
34
+ const data = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
35
+ if (!Array.isArray(data.skills)) data.skills = [];
36
+ return data;
37
+ } catch (e) {
38
+ return { package: PACKAGE_NAME, skills: [] };
39
+ }
40
+ }
41
+
42
+ function writeManifest(manifestPath, data) {
43
+ fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
44
+ fs.writeFileSync(manifestPath, JSON.stringify(data, null, 2), 'utf8');
45
+ }
46
+
47
+ function recordSkillInstall(manifestPath, packageVersion, skillId, dirPath) {
48
+ const data = readManifest(manifestPath);
49
+ data.package = PACKAGE_NAME;
50
+ data.version = packageVersion;
51
+ data.updatedAt = new Date().toISOString();
52
+ const idx = data.skills.findIndex(s => s.dirPath === dirPath);
53
+ const entry = { id: skillId, dirPath, installedAt: new Date().toISOString() };
54
+ if (idx !== -1) data.skills[idx] = entry;
55
+ else data.skills.push(entry);
56
+ writeManifest(manifestPath, data);
57
+ }
58
+
59
+ // Removes one skill entry, and - once no skills remain in it - deletes the
60
+ // manifest file itself rather than leaving an empty bookkeeping file behind.
61
+ function removeSkillFromManifest(manifestPath, dirPath) {
62
+ if (!fs.existsSync(manifestPath)) return;
63
+ const data = readManifest(manifestPath);
64
+ data.skills = data.skills.filter(s => s.dirPath !== dirPath);
65
+ if (data.skills.length === 0) {
66
+ fs.unlinkSync(manifestPath);
67
+ } else {
68
+ writeManifest(manifestPath, data);
69
+ }
70
+ }
71
+
72
+ module.exports = {
73
+ PACKAGE_NAME,
74
+ HARNESS_AUTHOR,
75
+ HARNESS_DIR_NAME,
76
+ getHarnessDir,
77
+ getManifestPath,
78
+ readManifest,
79
+ writeManifest,
80
+ recordSkillInstall,
81
+ removeSkillFromManifest,
82
+ };