opencode-swarm 7.164.0 → 7.164.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 (103) hide show
  1. package/.opencode/skills/codebase-review-swarm/SKILL.md +4 -0
  2. package/.opencode/skills/commit-pr/SKILL.md +4 -1
  3. package/.opencode/skills/critic-gate/SKILL.md +4 -0
  4. package/.opencode/skills/deep-dive/SKILL.md +4 -0
  5. package/.opencode/skills/engineering-conventions/SKILL.md +2 -0
  6. package/.opencode/skills/execute/SKILL.md +4 -0
  7. package/.opencode/skills/phase-wrap/SKILL.md +4 -0
  8. package/.opencode/skills/plan/SKILL.md +4 -0
  9. package/.opencode/skills/running-tests/SKILL.md +4 -0
  10. package/.opencode/skills/swarm-pr-review/SKILL.md +4 -0
  11. package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +2 -0
  12. package/.opencode/skills/writing-tests/SKILL.md +4 -0
  13. package/dist/agents/critic.d.ts +6 -6
  14. package/dist/cli/{coder-settlement-84je6bza.js → coder-settlement-kv1x94w6.js} +12 -13
  15. package/dist/cli/{config-doctor-vfze38e1.js → config-doctor-8d7ydxck.js} +3 -3
  16. package/dist/cli/{core-q5hv8e2w.js → core-7jjgxczp.js} +2 -2
  17. package/dist/cli/{curation-policy-a2zty4br.js → curation-policy-7pnmnfct.js} +6 -7
  18. package/dist/cli/{curator-4pckmmyf.js → curator-5nyth2rj.js} +35 -38
  19. package/dist/cli/{curator-drift-wy7ejcvw.js → curator-drift-ykrdf08r.js} +4 -5
  20. package/dist/cli/curator-llm-factory-d415s169.js +66 -0
  21. package/dist/cli/{evidence-summary-service-b15yes21.js → evidence-summary-service-aebn7nb9.js} +16 -17
  22. package/dist/cli/{gate-evidence-70h0w4tb.js → gate-evidence-es59pysy.js} +8 -9
  23. package/dist/cli/guardrail-explain-mn2x7w2y.js +67 -0
  24. package/dist/cli/{guardrail-log-7rxbd20p.js → guardrail-log-fd3c5rks.js} +8 -9
  25. package/dist/cli/{guardrail-reset-3b4gs357.js → guardrail-reset-r49rvptv.js} +35 -38
  26. package/dist/cli/{hive-promoter-s80g1gwb.js → hive-promoter-qp2kjhhp.js} +35 -38
  27. package/dist/cli/{index-93sepnc9.js → index-0145kpjr.js} +2 -2
  28. package/dist/cli/{index-v3a9rmyh.js → index-1r6p1wpa.js} +4 -4
  29. package/dist/cli/{index-c4pynht5.js → index-2xj34nkh.js} +1 -1
  30. package/dist/cli/{index-g64154pd.js → index-34exj2e3.js} +2 -2
  31. package/dist/cli/{index-td6n935w.js → index-3704v4e6.js} +2 -2
  32. package/dist/cli/{index-ynqp3jb6.js → index-5d7bzpfn.js} +1 -1
  33. package/dist/cli/{index-hyq20s2v.js → index-6vtm4rd0.js} +12 -12
  34. package/dist/cli/{index-4afh2cz7.js → index-92q98ry8.js} +7 -7
  35. package/dist/cli/{index-wdtckfnf.js → index-ac39znep.js} +2 -2
  36. package/dist/cli/{index-4jersar8.js → index-axtnc0xf.js} +5 -5
  37. package/dist/cli/{index-e3hwzcjv.js → index-b85jnfp4.js} +2 -2
  38. package/dist/cli/{index-bm73pych.js → index-br7q79t2.js} +7 -7
  39. package/dist/cli/{index-1b1h770t.js → index-bzd67m2j.js} +3 -3
  40. package/dist/cli/{index-ma8w6pfp.js → index-c8k4cs94.js} +5 -5
  41. package/dist/cli/{index-t90gjc0k.js → index-cm4r8gh2.js} +1 -1
  42. package/dist/cli/{index-3b762978.js → index-f9nfknjg.js} +182 -37
  43. package/dist/cli/{index-t9rhtvy9.js → index-fyt5byhd.js} +3 -3
  44. package/dist/cli/{index-zbpcpsk0.js → index-gz5rn6w6.js} +9 -9
  45. package/dist/cli/{index-7r9vpkwa.js → index-h9wnkr2e.js} +5 -5
  46. package/dist/cli/{index-1hpjwz3s.js → index-hcn69kp0.js} +1 -1
  47. package/dist/cli/{index-12f1tsn2.js → index-hnwg5gt6.js} +655 -16
  48. package/dist/cli/{index-qkk2skff.js → index-jw9wbwdh.js} +37 -40
  49. package/dist/cli/{index-pvgcex0d.js → index-kwd09y5a.js} +4 -4
  50. package/dist/cli/{index-9xd073d4.js → index-m1nrd3yd.js} +9 -2
  51. package/dist/cli/{index-c69jbpex.js → index-pcnhh2vt.js} +2 -2
  52. package/dist/cli/{index-gxd8fwyt.js → index-q3xn3m3g.js} +4 -4
  53. package/dist/cli/{index-fckfgptr.js → index-qbr05tbw.js} +2 -2
  54. package/dist/cli/{index-9sy65e94.js → index-qmeewt3g.js} +32 -34
  55. package/dist/cli/{index-tb1k8jya.js → index-sb4eanpv.js} +1 -1
  56. package/dist/cli/{index-dtn0pne5.js → index-v56mhyhs.js} +1 -1
  57. package/dist/cli/{index-2s4s9n82.js → index-w5jpjaqe.js} +2 -2
  58. package/dist/cli/{index-1z4jzwja.js → index-w8qt2612.js} +3 -3
  59. package/dist/cli/{index-nhxaa9j5.js → index-xm6c1tnf.js} +1 -1
  60. package/dist/cli/{index-0515j0cz.js → index-y2f5s2cf.js} +1 -1
  61. package/dist/cli/{index-36nt17m8.js → index-yep24wn4.js} +1 -1
  62. package/dist/cli/{index-xk0kc1py.js → index-yjftcanv.js} +7767 -2575
  63. package/dist/cli/{index-t5t82jy8.js → index-yqhwrjw9.js} +5 -5
  64. package/dist/cli/{index-nzrhw31r.js → index-zgeqwbhw.js} +2 -2
  65. package/dist/cli/{index-70bfj3v1.js → index-zs1jrsta.js} +2 -2
  66. package/dist/cli/index.js +35 -38
  67. package/dist/cli/{knowledge-escalator-sttdnwf8.js → knowledge-escalator-439jajb3.js} +14 -15
  68. package/dist/cli/{knowledge-events-4h88stj7.js → knowledge-events-wz3h98kk.js} +12 -13
  69. package/dist/cli/{knowledge-link-yykmxdyw.js → knowledge-link-2gh1cnk3.js} +5 -6
  70. package/dist/cli/{knowledge-store-j832fxpx.js → knowledge-store-y1cwe80n.js} +6 -7
  71. package/dist/cli/{knowledge-validator-edbg761g.js → knowledge-validator-bk2qfqe2.js} +8 -9
  72. package/dist/cli/{model-preflight-c3mc8njg.js → model-preflight-pmnbfzjv.js} +1 -1
  73. package/dist/cli/{pending-delegations-sphntrs0.js → pending-delegations-kh4mkvzb.js} +6 -8
  74. package/dist/cli/{pr-subscriptions-1a4gcnzv.js → pr-subscriptions-sdv0n59c.js} +6 -7
  75. package/dist/cli/pr-workflow-gate-a9vj11e5.js +221 -0
  76. package/dist/cli/{runner-d294h1by.js → runner-m95v9d47.js} +6 -7
  77. package/dist/cli/{scan-cursor-5frvp7nb.js → scan-cursor-pjek24k7.js} +7 -8
  78. package/dist/cli/{schema-9xkt5hvd.js → schema-674qw3aj.js} +2 -2
  79. package/dist/cli/{scope-persistence-gk55h3sp.js → scope-persistence-sq331eqh.js} +10 -11
  80. package/dist/cli/{skill-generator-sxxf7jbb.js → skill-generator-pcw7c50r.js} +16 -17
  81. package/dist/cli/{telemetry-q51s6tyt.js → telemetry-c4j18da8.js} +1 -1
  82. package/dist/cli/{worktree-collision-ownership-7kj2ryt1.js → worktree-collision-ownership-vnj31rgc.js} +7 -9
  83. package/dist/cli/{worktree-isolation-67fs6rz9.js → worktree-isolation-tje6p4zt.js} +35 -38
  84. package/dist/hooks/delegate-ack-collector.d.ts +5 -0
  85. package/dist/hooks/delegation-gate.d.ts +14 -2
  86. package/dist/hooks/plan-task-id-context.d.ts +24 -0
  87. package/dist/hooks/pr-workflow-gate.d.ts +14 -8
  88. package/dist/hooks/pr-workflow-response-gate.d.ts +9 -12
  89. package/dist/hooks/skill-injection.d.ts +7 -3
  90. package/dist/hooks/skill-propagation-gate.d.ts +1 -1
  91. package/dist/hooks/task-id-resolver.d.ts +46 -0
  92. package/dist/index.js +118 -92
  93. package/dist/pr-review/authorization.d.ts +18 -12
  94. package/dist/tools/authorize-pr-review-reentry.d.ts +12 -8
  95. package/dist/tools/tool-metadata.d.ts +1 -1
  96. package/opencode-swarm.schema.json +4 -1
  97. package/package.json +1 -1
  98. package/dist/cli/authorization-vstrh7ra.js +0 -23
  99. package/dist/cli/curator-llm-factory-msbj3hpn.js +0 -69
  100. package/dist/cli/guardrail-explain-kksdy032.js +0 -70
  101. package/dist/cli/index-ed5ykebp.js +0 -151
  102. package/dist/cli/index-mmngnxev.js +0 -883
  103. package/dist/cli/index-w7ekntej.js +0 -643
@@ -7,10 +7,11 @@
7
7
  * `reviewer`/`test_engineer` may bypass the generic Stage-A task-workflow
8
8
  * requirement. The PR workflow controller issues an authorization bound to
9
9
  * the exact active session, workflow, run, base/head SHA, worktree revision
10
- * digest, role, and gate generation; the Task delegation gate consumes it
11
- * atomically, exactly once. Stale, cross-session, wrong-role, replayed,
12
- * expired, or revision-drifted requests fail closed to the normal gating
13
- * path.
10
+ * digest, role, and gate generation; the PR workflow controller boundary
11
+ * reserves it atomically for exactly one Task call and the Task delegation
12
+ * gate verifies that same call-bound reservation (idempotent for the same
13
+ * callID). Stale, cross-session, wrong-role, replayed, expired, or
14
+ * revision-drifted requests fail closed to the normal gating path.
14
15
  *
15
16
  * Binding verification: the CURRENT gate binding (head/revision/generation)
16
17
  * is supplied by the owning gate through a bound reader
@@ -80,7 +81,11 @@ type AuthorizationFile = z.infer<typeof AuthorizationFileSchema>;
80
81
  declare function reentryAuthorizationFilePath(directory: string, sessionID: string): string;
81
82
  declare function renameWithRetryAsync(tempPath: string, targetPath: string): Promise<void>;
82
83
  declare function writeAuthorizationFile(filePath: string, file: AuthorizationFile): Promise<void>;
83
- /** Drop consumed/expired records past the retention bound; keep newest first. */
84
+ /**
85
+ * Drop expired records past the retention bound; keep newest first. A burst
86
+ * of consumed records must never evict a still-live unconsumed authorization
87
+ * before its TTL, so unconsumed records take priority within the cap.
88
+ */
84
89
  declare function pruneAuthorizations(records: readonly PrReviewReentryAuthorizationRecord[], nowMs: number): PrReviewReentryAuthorizationRecord[];
85
90
  /**
86
91
  * Issue a one-use authorization for the CURRENT active PR_REVIEW workflow.
@@ -93,22 +98,23 @@ export declare function issuePrReviewReentryAuthorization(directory: string, ses
93
98
  prHeadSha: string;
94
99
  role: PrReviewReentryRole;
95
100
  }): Promise<PrReviewReentryAuthorizationRecord>;
101
+ declare function authorizationMatchesBinding(record: PrReviewReentryAuthorizationRecord, binding: PrReviewReentryBindingContext): boolean;
96
102
  /**
97
- * Atomically consume the one active authorization for this session+role.
98
- * Re-verifies the binding against the CURRENT PR_REVIEW gate state any
99
- * drift (mode change, head change, revision digest change, generation bump)
100
- * fails closed to null, as does replay, expiry, cross-session use, or wrong
101
- * role. Returns the consumed record on success.
103
+ * Reserve or verify one authorization against a binding whose owning workflow
104
+ * lock is held by the caller. The authorization-file lock is always acquired
105
+ * second. A consumed record is retained until expiry so the exact same Task
106
+ * call can verify its reservation in a later hook (and after process restart).
102
107
  */
103
- export declare function consumePrReviewReentryAuthorization(directory: string, sessionID: string, request: {
108
+ export declare function reservePrReviewReentryAuthorizationAgainstBinding(directory: string, sessionID: string, request: {
104
109
  role: PrReviewReentryRole;
105
110
  callID: string;
106
- }): Promise<PrReviewReentryAuthorizationRecord | null>;
111
+ }, binding: PrReviewReentryBindingContext): Promise<PrReviewReentryAuthorizationRecord | null>;
107
112
  export declare const _internals: {
108
113
  AUTHORIZATION_TTL_MS: number;
109
114
  MAX_ACTIVE_AUTHORIZATIONS: number;
110
115
  reentryAuthorizationFilePath: typeof reentryAuthorizationFilePath;
111
116
  pruneAuthorizations: typeof pruneAuthorizations;
117
+ authorizationMatchesBinding: typeof authorizationMatchesBinding;
112
118
  /** DI seam: the rename implementation (tests inject failure modes). */
113
119
  renameImpl: (from: string, to: string) => Promise<void>;
114
120
  /** DI seam: retry backoff schedule (tests shrink to avoid real sleeps). */
@@ -1,14 +1,18 @@
1
1
  import { createSwarmTool } from './create-tool.js';
2
2
  /**
3
3
  * Issue a ONE-USE reviewer re-entry authorization (issue #2383) for the
4
- * CURRENT active PR_REVIEW workflow. The very next direct Task dispatch of
5
- * the declared role consumes it atomically and bypasses ONLY the generic
6
- * Stage-A task-workflow requirement; every other delegation gate stays
7
- * authoritative. Bindings are exact (session, workflow, run, head SHA,
8
- * worktree revision digest, role, gate generation): replay, cross-session
9
- * use, wrong role, expiry, or any workflow progress since issuance fails
10
- * closed. Issue immediately before the Task dispatch authorizations are
11
- * not stockpilable.
4
+ * CURRENT active PR_REVIEW workflow. The very next direct subagent_type Task
5
+ * dispatch of the declared role reserves it atomically at the controller
6
+ * boundary admitting that one dispatch past the PR_REVIEW read-only
7
+ * restriction and the delegation gate verifies the same call-bound
8
+ * reservation while bypassing ONLY the generic Stage-A task-workflow
9
+ * requirement; every other delegation gate stays authoritative. Bindings are
10
+ * exact (session, workflow, run, head SHA, worktree revision digest, role,
11
+ * gate generation): replay, cross-session use, wrong role, expiry, or any
12
+ * workflow progress since issuance fails closed. A Task the delegation gate
13
+ * later rejects for an unrelated reason still burns the authorization —
14
+ * issue a fresh one before retrying. Issue immediately before the Task
15
+ * dispatch — authorizations are not stockpilable.
12
16
  */
13
17
  export declare function executeAuthorizePrReviewReentry(args: unknown, directory: string, context?: {
14
18
  sessionID?: string;
@@ -466,7 +466,7 @@ export declare const TOOL_METADATA: {
466
466
  };
467
467
  repo_map: {
468
468
  description: string;
469
- agents: ("coder" | "reviewer" | "critic" | "critic_oversight" | "critic_finding_validator" | "explorer" | "architect" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier" | "critic_architecture_supervisor")[];
469
+ agents: ("coder" | "reviewer" | "test_engineer" | "critic" | "critic_oversight" | "critic_finding_validator" | "explorer" | "architect" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier" | "critic_architecture_supervisor")[];
470
470
  prWorkflow: {
471
471
  modes: ("PR_REVIEW" | "PR_FEEDBACK")[];
472
472
  capability: "observe";
@@ -1583,7 +1583,10 @@
1583
1583
  {
1584
1584
  "type": "string"
1585
1585
  }
1586
- ]
1586
+ ],
1587
+ "items": false,
1588
+ "minItems": 2,
1589
+ "maxItems": 2
1587
1590
  }
1588
1591
  }
1589
1592
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.164.0",
3
+ "version": "7.164.2",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,23 +0,0 @@
1
- // @bun
2
- import {
3
- _internals,
4
- bindPrReviewReentryBindingReader,
5
- consumePrReviewReentryAuthorization,
6
- issuePrReviewReentryAuthorization
7
- } from "./index-mmngnxev.js";
8
- import"./index-w7ekntej.js";
9
- import"./index-dtn0pne5.js";
10
- import"./index-z6xqpmqg.js";
11
- import"./index-r3mvsbtq.js";
12
- import"./index-zjygnfay.js";
13
- import"./index-ed5ykebp.js";
14
- import"./index-7g4c7s5r.js";
15
- import"./index-bpmtbmy9.js";
16
- import"./index-zgwm4ryv.js";
17
- import"./index-a76rekgs.js";
18
- export {
19
- issuePrReviewReentryAuthorization,
20
- consumePrReviewReentryAuthorization,
21
- bindPrReviewReentryBindingReader,
22
- _internals
23
- };
@@ -1,69 +0,0 @@
1
- // @bun
2
- import {
3
- createCuratorLLMDelegate
4
- } from "./index-xk0kc1py.js";
5
- import"./index-c4pynht5.js";
6
- import"./index-9sy65e94.js";
7
- import"./index-g64154pd.js";
8
- import"./index-hyq20s2v.js";
9
- import"./index-2s4s9n82.js";
10
- import"./index-txdagbh7.js";
11
- import"./index-3146wmgv.js";
12
- import"./index-pvgcex0d.js";
13
- import"./index-t5t82jy8.js";
14
- import"./index-e3hwzcjv.js";
15
- import"./index-70ha9e09.js";
16
- import"./index-0515j0cz.js";
17
- import"./index-1hpjwz3s.js";
18
- import"./index-zaab1wz9.js";
19
- import"./index-ma8w6pfp.js";
20
- import"./index-zsrtt42s.js";
21
- import"./index-4afh2cz7.js";
22
- import"./index-3f7hqtgg.js";
23
- import"./index-fckfgptr.js";
24
- import"./index-gxd8fwyt.js";
25
- import"./index-tb1k8jya.js";
26
- import"./index-rtry5xyf.js";
27
- import"./index-7r9vpkwa.js";
28
- import"./index-nzrhw31r.js";
29
- import"./index-12f1tsn2.js";
30
- import"./index-ddszzne4.js";
31
- import"./index-mmngnxev.js";
32
- import"./index-w7ekntej.js";
33
- import"./index-4jersar8.js";
34
- import"./index-1z4jzwja.js";
35
- import"./index-93sepnc9.js";
36
- import"./index-556ja8an.js";
37
- import"./index-4fwbbad3.js";
38
- import"./index-b43rt5ph.js";
39
- import"./index-q7sjgr1y.js";
40
- import"./index-bm73pych.js";
41
- import"./index-zbpcpsk0.js";
42
- import"./index-t9rhtvy9.js";
43
- import"./index-zg9d392c.js";
44
- import"./index-n832052r.js";
45
- import"./index-dtn0pne5.js";
46
- import"./index-z6xqpmqg.js";
47
- import"./index-r3mvsbtq.js";
48
- import"./index-nhxaa9j5.js";
49
- import"./index-td6n935w.js";
50
- import"./index-9e6fdz2h.js";
51
- import"./index-4rhhvd1a.js";
52
- import"./index-wdtckfnf.js";
53
- import"./index-9xd073d4.js";
54
- import"./index-zjygnfay.js";
55
- import"./index-ae75rja9.js";
56
- import"./index-ynqp3jb6.js";
57
- import"./index-70bfj3v1.js";
58
- import"./index-bk5tah7q.js";
59
- import"./index-36nt17m8.js";
60
- import"./index-3b762978.js";
61
- import"./index-1b1h770t.js";
62
- import"./index-ed5ykebp.js";
63
- import"./index-7g4c7s5r.js";
64
- import"./index-bpmtbmy9.js";
65
- import"./index-zgwm4ryv.js";
66
- import"./index-a76rekgs.js";
67
- export {
68
- createCuratorLLMDelegate
69
- };
@@ -1,70 +0,0 @@
1
- // @bun
2
- import {
3
- handleGuardrailExplain
4
- } from "./index-c69jbpex.js";
5
- import"./index-xk0kc1py.js";
6
- import"./index-c4pynht5.js";
7
- import"./index-9sy65e94.js";
8
- import"./index-g64154pd.js";
9
- import"./index-hyq20s2v.js";
10
- import"./index-2s4s9n82.js";
11
- import"./index-txdagbh7.js";
12
- import"./index-3146wmgv.js";
13
- import"./index-pvgcex0d.js";
14
- import"./index-t5t82jy8.js";
15
- import"./index-e3hwzcjv.js";
16
- import"./index-70ha9e09.js";
17
- import"./index-0515j0cz.js";
18
- import"./index-1hpjwz3s.js";
19
- import"./index-zaab1wz9.js";
20
- import"./index-ma8w6pfp.js";
21
- import"./index-zsrtt42s.js";
22
- import"./index-4afh2cz7.js";
23
- import"./index-3f7hqtgg.js";
24
- import"./index-fckfgptr.js";
25
- import"./index-gxd8fwyt.js";
26
- import"./index-tb1k8jya.js";
27
- import"./index-rtry5xyf.js";
28
- import"./index-7r9vpkwa.js";
29
- import"./index-nzrhw31r.js";
30
- import"./index-12f1tsn2.js";
31
- import"./index-ddszzne4.js";
32
- import"./index-mmngnxev.js";
33
- import"./index-w7ekntej.js";
34
- import"./index-4jersar8.js";
35
- import"./index-1z4jzwja.js";
36
- import"./index-93sepnc9.js";
37
- import"./index-556ja8an.js";
38
- import"./index-4fwbbad3.js";
39
- import"./index-b43rt5ph.js";
40
- import"./index-q7sjgr1y.js";
41
- import"./index-bm73pych.js";
42
- import"./index-zbpcpsk0.js";
43
- import"./index-t9rhtvy9.js";
44
- import"./index-zg9d392c.js";
45
- import"./index-n832052r.js";
46
- import"./index-dtn0pne5.js";
47
- import"./index-z6xqpmqg.js";
48
- import"./index-r3mvsbtq.js";
49
- import"./index-nhxaa9j5.js";
50
- import"./index-td6n935w.js";
51
- import"./index-9e6fdz2h.js";
52
- import"./index-4rhhvd1a.js";
53
- import"./index-wdtckfnf.js";
54
- import"./index-9xd073d4.js";
55
- import"./index-zjygnfay.js";
56
- import"./index-ae75rja9.js";
57
- import"./index-ynqp3jb6.js";
58
- import"./index-70bfj3v1.js";
59
- import"./index-bk5tah7q.js";
60
- import"./index-36nt17m8.js";
61
- import"./index-3b762978.js";
62
- import"./index-1b1h770t.js";
63
- import"./index-ed5ykebp.js";
64
- import"./index-7g4c7s5r.js";
65
- import"./index-bpmtbmy9.js";
66
- import"./index-zgwm4ryv.js";
67
- import"./index-a76rekgs.js";
68
- export {
69
- handleGuardrailExplain
70
- };
@@ -1,151 +0,0 @@
1
- // @bun
2
- // src/utils/swarm-artifact-cache.ts
3
- import * as fsSync from "fs";
4
- import * as fs from "fs/promises";
5
- import * as path from "path";
6
- var MAX_CACHE_ENTRIES = 128;
7
- var textCache = new Map;
8
- var parsedCache = new Map;
9
- var stats = {
10
- textReadCount: 0,
11
- textCacheHitCount: 0,
12
- textCacheMissCount: 0,
13
- parsedReadCount: 0,
14
- parseCount: 0,
15
- parsedCacheHitCount: 0,
16
- parsedCacheMissCount: 0,
17
- statFailureCount: 0,
18
- evictionCount: 0,
19
- textEvictionCount: 0,
20
- parsedEvictionCount: 0,
21
- cloneFallbackCount: 0,
22
- textEntryCount: 0,
23
- parsedEntryCount: 0
24
- };
25
- function sameStamp(a, b) {
26
- return a.mtimeMs === b.mtimeMs && a.ctimeMs === b.ctimeMs && a.size === b.size;
27
- }
28
- var _internals = {
29
- stat: fs.stat,
30
- statSync: fsSync.statSync
31
- };
32
- async function getStamp(filePath) {
33
- try {
34
- const stat2 = await _internals.stat(filePath);
35
- if (!stat2.isFile())
36
- return null;
37
- return { mtimeMs: stat2.mtimeMs, ctimeMs: stat2.ctimeMs, size: stat2.size };
38
- } catch {
39
- stats.statFailureCount++;
40
- return null;
41
- }
42
- }
43
- function canStoreRead(before, after) {
44
- return after !== null && sameStamp(before, after);
45
- }
46
- function setBounded(cache, key, value, cacheKind) {
47
- cache.set(key, value);
48
- while (cache.size > MAX_CACHE_ENTRIES) {
49
- const oldest = cache.keys().next().value;
50
- if (oldest === undefined)
51
- break;
52
- cache.delete(oldest);
53
- stats.evictionCount++;
54
- if (cacheKind === "text") {
55
- stats.textEvictionCount++;
56
- } else {
57
- stats.parsedEvictionCount++;
58
- }
59
- }
60
- stats.textEntryCount = textCache.size;
61
- stats.parsedEntryCount = parsedCache.size;
62
- }
63
- function cloneCachedValue(value) {
64
- if (value === null || typeof value !== "object")
65
- return value;
66
- if (typeof structuredClone === "function") {
67
- return structuredClone(value);
68
- }
69
- stats.cloneFallbackCount++;
70
- return JSON.parse(JSON.stringify(value));
71
- }
72
- async function readCachedTextFile(filePath, directRead) {
73
- const cacheKey = path.resolve(filePath);
74
- const stamp = await getStamp(cacheKey);
75
- if (!stamp) {
76
- stats.textReadCount++;
77
- return directRead();
78
- }
79
- const cached = textCache.get(cacheKey);
80
- if (cached && sameStamp(cached, stamp)) {
81
- stats.textCacheHitCount++;
82
- return cached.value;
83
- }
84
- stats.textCacheMissCount++;
85
- stats.textReadCount++;
86
- const value = await directRead();
87
- const afterReadStamp = await getStamp(cacheKey);
88
- if (value !== null && canStoreRead(stamp, afterReadStamp)) {
89
- setBounded(textCache, cacheKey, { ...afterReadStamp, value }, "text");
90
- }
91
- return value;
92
- }
93
- async function readCachedParsedFile(filePath, namespace, readText, parse) {
94
- const resolvedPath = path.resolve(filePath);
95
- const cacheKey = `${resolvedPath}\x00${namespace}`;
96
- const stamp = await getStamp(resolvedPath);
97
- if (!stamp) {
98
- stats.parsedReadCount++;
99
- const content2 = await readText();
100
- if (content2 === null)
101
- return null;
102
- stats.parseCount++;
103
- return parse(content2);
104
- }
105
- const cached = parsedCache.get(cacheKey);
106
- if (cached && sameStamp(cached, stamp)) {
107
- stats.parsedCacheHitCount++;
108
- return cloneCachedValue(cached.value);
109
- }
110
- stats.parsedCacheMissCount++;
111
- stats.parsedReadCount++;
112
- const content = await readText();
113
- if (content === null)
114
- return null;
115
- stats.parseCount++;
116
- const value = parse(content);
117
- const afterReadStamp = await getStamp(resolvedPath);
118
- if (canStoreRead(stamp, afterReadStamp)) {
119
- setBounded(parsedCache, cacheKey, { ...afterReadStamp, value }, "parsed");
120
- }
121
- return cloneCachedValue(value);
122
- }
123
- function invalidateCachedArtifact(filePath) {
124
- const resolvedPath = path.resolve(filePath);
125
- textCache.delete(resolvedPath);
126
- const prefix = `${resolvedPath}\x00`;
127
- for (const key of parsedCache.keys()) {
128
- if (key.startsWith(prefix))
129
- parsedCache.delete(key);
130
- }
131
- }
132
- function resetSwarmArtifactCache() {
133
- textCache.clear();
134
- parsedCache.clear();
135
- stats.textReadCount = 0;
136
- stats.textCacheHitCount = 0;
137
- stats.textCacheMissCount = 0;
138
- stats.parsedReadCount = 0;
139
- stats.parseCount = 0;
140
- stats.parsedCacheHitCount = 0;
141
- stats.parsedCacheMissCount = 0;
142
- stats.statFailureCount = 0;
143
- stats.evictionCount = 0;
144
- stats.textEvictionCount = 0;
145
- stats.parsedEvictionCount = 0;
146
- stats.cloneFallbackCount = 0;
147
- stats.textEntryCount = 0;
148
- stats.parsedEntryCount = 0;
149
- }
150
-
151
- export { readCachedTextFile, readCachedParsedFile, invalidateCachedArtifact, resetSwarmArtifactCache };