@entelligentsia/forgecli 0.11.3 → 0.15.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 (62) hide show
  1. package/CHANGELOG.md +314 -0
  2. package/README.md +2 -1
  3. package/dist/CHANGELOG-forge-plugin.md +183 -0
  4. package/dist/bin/forge.js +20 -1
  5. package/dist/bin/forge.js.map +1 -1
  6. package/dist/extensions/forgecli/config-layer.d.ts +15 -0
  7. package/dist/extensions/forgecli/config-layer.js.map +1 -1
  8. package/dist/extensions/forgecli/enhance.js +1 -1
  9. package/dist/extensions/forgecli/enhance.js.map +1 -1
  10. package/dist/extensions/forgecli/forge-cli-schema.json +19 -0
  11. package/dist/extensions/forgecli/forge-tools.js +80 -0
  12. package/dist/extensions/forgecli/forge-tools.js.map +1 -1
  13. package/dist/extensions/forgecli/forge-update-command.js +24 -18
  14. package/dist/extensions/forgecli/forge-update-command.js.map +1 -1
  15. package/dist/extensions/forgecli/friction-emit.d.ts +97 -0
  16. package/dist/extensions/forgecli/friction-emit.js +246 -0
  17. package/dist/extensions/forgecli/friction-emit.js.map +1 -0
  18. package/dist/extensions/forgecli/hook-dispatcher.js +20 -0
  19. package/dist/extensions/forgecli/hook-dispatcher.js.map +1 -1
  20. package/dist/extensions/forgecli/index.js +29 -5
  21. package/dist/extensions/forgecli/index.js.map +1 -1
  22. package/dist/extensions/forgecli/regenerate.d.ts +22 -0
  23. package/dist/extensions/forgecli/regenerate.js +133 -3
  24. package/dist/extensions/forgecli/regenerate.js.map +1 -1
  25. package/dist/extensions/forgecli/skill-curation-flag.d.ts +21 -0
  26. package/dist/extensions/forgecli/skill-curation-flag.js +71 -0
  27. package/dist/extensions/forgecli/skill-curation-flag.js.map +1 -0
  28. package/dist/extensions/forgecli/skill-curator-subagent.d.ts +101 -0
  29. package/dist/extensions/forgecli/skill-curator-subagent.js +342 -0
  30. package/dist/extensions/forgecli/skill-curator-subagent.js.map +1 -0
  31. package/dist/extensions/forgecli/skill-retriever.d.ts +84 -0
  32. package/dist/extensions/forgecli/skill-retriever.js +246 -0
  33. package/dist/extensions/forgecli/skill-retriever.js.map +1 -0
  34. package/dist/extensions/forgecli/skill-usage-tracker.d.ts +91 -0
  35. package/dist/extensions/forgecli/skill-usage-tracker.js +224 -0
  36. package/dist/extensions/forgecli/skill-usage-tracker.js.map +1 -0
  37. package/dist/forge-payload/.base-pack/workflows/enhance.md +331 -11
  38. package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
  39. package/dist/forge-payload/.schemas/event.schema.json +20 -2
  40. package/dist/forge-payload/.schemas/migrations.json +96 -0
  41. package/dist/forge-payload/.schemas/proposal.schema.json +40 -0
  42. package/dist/forge-payload/agents/store-query-validator.md +103 -0
  43. package/dist/forge-payload/agents/tomoshibi.md +185 -0
  44. package/dist/forge-payload/commands/regenerate.md +109 -20
  45. package/dist/forge-payload/hooks/check-update.js +378 -0
  46. package/dist/forge-payload/hooks/forge-permissions.js +158 -0
  47. package/dist/forge-payload/hooks/triage-error.js +71 -0
  48. package/dist/forge-payload/hooks/validate-write.js +236 -0
  49. package/dist/forge-payload/integrity.json +32 -0
  50. package/dist/forge-payload/meta/workflows/meta-enhance.md +331 -11
  51. package/dist/forge-payload/schemas/structure-manifest.json +511 -0
  52. package/dist/forge-payload/tools/compression-gate.cjs +192 -0
  53. package/dist/forge-payload/tools/delete-candidate-detector.cjs +114 -0
  54. package/dist/forge-payload/tools/judge-proposal.cjs +177 -0
  55. package/dist/forge-payload/tools/manage-versions.cjs +132 -4
  56. package/dist/forge-payload/tools/queue-drain.cjs +152 -0
  57. package/dist/forge-payload/tools/replay-scoring.cjs +117 -0
  58. package/node_modules/@mariozechner/clipboard/package.json +2 -1
  59. package/node_modules/@mariozechner/clipboard-linux-x64-musl/README.md +3 -0
  60. package/node_modules/@mariozechner/clipboard-linux-x64-musl/clipboard.linux-x64-musl.node +0 -0
  61. package/node_modules/@mariozechner/clipboard-linux-x64-musl/package.json +25 -0
  62. package/package.json +4 -2
@@ -0,0 +1,117 @@
1
+ 'use strict';
2
+ // FORGE-S24-T04 — cross-task replay scoring (recurrence boost).
3
+ //
4
+ // For each enhancement proposal synthesised from a friction event at task `t`,
5
+ // scan friction events in tasks `t+1..N` (within the same sprint) for the
6
+ // same `(subkind, evidence.skillId)` pair. Surface the count + task list on
7
+ // the proposal so the T03 judge sees "this friction happened 3 times" rather
8
+ // than "this friction happened once".
9
+ //
10
+ // Pure module; consumed by Phase 2 step 5/6 of meta-enhance.md after the
11
+ // dedup pass and before the proposal artifact is written.
12
+ //
13
+ // Exports:
14
+ // computeRecurrence({ events, subkind, skillId, fromTaskId, taskOrder })
15
+ // -> { recurrence_count, recurrence_task_ids }
16
+ // annotateProposals(proposals, frictionEvents, taskOrder)
17
+ // -> new array of proposals, each carrying recurrence_count +
18
+ // recurrence_task_ids.
19
+
20
+ function computeRecurrence({ events, subkind, skillId, fromTaskId, taskOrder }) {
21
+ if (!Array.isArray(events)) throw new TypeError('events must be an array');
22
+ if (!Array.isArray(taskOrder)) throw new TypeError('taskOrder must be an array');
23
+ if (typeof subkind !== 'string' || subkind === '') throw new TypeError('subkind required');
24
+ if (typeof skillId !== 'string' || skillId === '') throw new TypeError('skillId required');
25
+ if (typeof fromTaskId !== 'string' || fromTaskId === '') throw new TypeError('fromTaskId required');
26
+
27
+ const originIdx = taskOrder.indexOf(fromTaskId);
28
+
29
+ // Distinct taskIds with a matching friction event.
30
+ const matchingTaskIds = new Set();
31
+
32
+ for (const evt of events) {
33
+ if (!evt || evt.type !== 'friction') continue;
34
+ if (evt.subkind !== subkind) continue;
35
+ const evtSkillId = evt.evidence && evt.evidence.skillId;
36
+ if (evtSkillId !== skillId) continue;
37
+ if (!evt.taskId) continue;
38
+
39
+ if (originIdx === -1) {
40
+ // fromTaskId not in taskOrder: only count the origin task itself.
41
+ if (evt.taskId === fromTaskId) matchingTaskIds.add(evt.taskId);
42
+ continue;
43
+ }
44
+
45
+ const evtIdx = taskOrder.indexOf(evt.taskId);
46
+ // Forward-only: include origin task (evtIdx === originIdx) and later
47
+ // (evtIdx > originIdx). Skip earlier and unknown tasks.
48
+ if (evtIdx >= originIdx) matchingTaskIds.add(evt.taskId);
49
+ }
50
+
51
+ // Always include the origin task so recurrence_count >= 1.
52
+ matchingTaskIds.add(fromTaskId);
53
+
54
+ // Sort by taskOrder position; tasks not in taskOrder go last in insertion order.
55
+ const ordered = [...matchingTaskIds].sort((a, b) => {
56
+ const ai = taskOrder.indexOf(a);
57
+ const bi = taskOrder.indexOf(b);
58
+ if (ai === -1 && bi === -1) return 0;
59
+ if (ai === -1) return 1;
60
+ if (bi === -1) return -1;
61
+ return ai - bi;
62
+ });
63
+
64
+ return {
65
+ recurrence_count: ordered.length,
66
+ recurrence_task_ids: ordered,
67
+ };
68
+ }
69
+
70
+ function annotateProposals(proposals, frictionEvents, taskOrder) {
71
+ if (!Array.isArray(proposals)) throw new TypeError('proposals must be an array');
72
+ if (!Array.isArray(frictionEvents)) throw new TypeError('frictionEvents must be an array');
73
+ if (!Array.isArray(taskOrder)) throw new TypeError('taskOrder must be an array');
74
+
75
+ // Index friction events by eventId for O(1) sourceFrictionIds resolution.
76
+ const byEventId = new Map();
77
+ for (const evt of frictionEvents) {
78
+ if (evt && evt.eventId) byEventId.set(evt.eventId, evt);
79
+ }
80
+
81
+ return proposals.map((proposal) => {
82
+ const sourceIds = Array.isArray(proposal.sourceFrictionIds)
83
+ ? proposal.sourceFrictionIds
84
+ : [];
85
+
86
+ // Resolve the first sourceFrictionId that points at a known friction event
87
+ // with subkind + evidence.skillId. The originating event determines
88
+ // (subkind, skillId, fromTaskId) for the recurrence scan.
89
+ let originEvent = null;
90
+ for (const id of sourceIds) {
91
+ const evt = byEventId.get(id);
92
+ if (evt && evt.subkind && evt.evidence && evt.evidence.skillId && evt.taskId) {
93
+ originEvent = evt;
94
+ break;
95
+ }
96
+ }
97
+
98
+ if (!originEvent) {
99
+ // No resolvable provenance: neutral annotation. recurrence_count=1
100
+ // keeps the schema invariant; recurrence_task_ids is empty so the
101
+ // judge can distinguish "single observation" from "unresolved origin".
102
+ return { ...proposal, recurrence_count: 1, recurrence_task_ids: [] };
103
+ }
104
+
105
+ const { recurrence_count, recurrence_task_ids } = computeRecurrence({
106
+ events: frictionEvents,
107
+ subkind: originEvent.subkind,
108
+ skillId: originEvent.evidence.skillId,
109
+ fromTaskId: originEvent.taskId,
110
+ taskOrder,
111
+ });
112
+
113
+ return { ...proposal, recurrence_count, recurrence_task_ids };
114
+ });
115
+ }
116
+
117
+ module.exports = { computeRecurrence, annotateProposals };
@@ -42,6 +42,7 @@
42
42
  "version": "napi version"
43
43
  },
44
44
  "optionalDependencies": {
45
- "@mariozechner/clipboard-linux-x64-gnu": "0.3.6"
45
+ "@mariozechner/clipboard-linux-x64-gnu": "0.3.6",
46
+ "@mariozechner/clipboard-linux-x64-musl": "0.3.6"
46
47
  }
47
48
  }
@@ -0,0 +1,3 @@
1
+ # `@mariozechner/clipboard-linux-x64-musl`
2
+
3
+ This is the **x86_64-unknown-linux-musl** binary for `@mariozechner/clipboard`
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@mariozechner/clipboard-linux-x64-musl",
3
+ "version": "0.3.6",
4
+ "os": [
5
+ "linux"
6
+ ],
7
+ "cpu": [
8
+ "x64"
9
+ ],
10
+ "main": "clipboard.linux-x64-musl.node",
11
+ "files": [
12
+ "clipboard.linux-x64-musl.node"
13
+ ],
14
+ "license": "MIT",
15
+ "engines": {
16
+ "node": ">= 10"
17
+ },
18
+ "libc": [
19
+ "musl"
20
+ ],
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/badlogic/clipboard.git"
24
+ }
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@entelligentsia/forgecli",
3
- "version": "0.11.3",
3
+ "version": "0.15.0",
4
4
  "description": "Forge SDLC ported onto @earendil-works/pi-coding-agent — production launcher with three bin aliases (forge/forgecli/4ge). Bundles a curated fork of pi-coding-agent vendored under earendil-works names.",
5
5
  "license": "MIT",
6
6
  "author": "Entelligentsia",
@@ -49,7 +49,7 @@
49
49
  ]
50
50
  },
51
51
  "forge": {
52
- "bundledVersion": "0.44.6",
52
+ "bundledVersion": "0.45.0",
53
53
  "forgeRoot": "../forge/forge"
54
54
  },
55
55
  "scripts": {
@@ -76,6 +76,7 @@
76
76
  "@earendil-works/pi-tui": "file:./vendor-pi/earendil-works-pi-tui-0.75.3.tgz",
77
77
  "ajv": "^8.20.0",
78
78
  "js-yaml": "^4.1.0",
79
+ "lunr": "2.3.9",
79
80
  "typebox": "^1.1.24"
80
81
  },
81
82
  "peerDependencies": {
@@ -84,6 +85,7 @@
84
85
  "devDependencies": {
85
86
  "@biomejs/biome": "^2.3.5",
86
87
  "@types/js-yaml": "^4.0.9",
88
+ "@types/lunr": "2.3.7",
87
89
  "@types/node": "^24.3.0",
88
90
  "typescript": "^5.7.3",
89
91
  "vitest": "^3.2.4"