sprag-cli 3.67.0 → 3.69.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 (54) hide show
  1. package/README.ko.md +33 -66
  2. package/README.md +41 -74
  3. package/bin/cli.js +150 -62
  4. package/docs/CODEX.ko.md +32 -0
  5. package/docs/CODEX.md +34 -0
  6. package/package.json +15 -4
  7. package/src/{codex-brief.js → codex/brief.js} +7 -7
  8. package/src/{codex-budget.js → codex/budget.js} +2 -2
  9. package/src/{codex-cache-policy.js → codex/cache-policy.js} +9 -9
  10. package/src/{codex-delegation-diagnostics.js → codex/delegation-diagnostics.js} +2 -2
  11. package/src/{codex-delegation.js → codex/delegation.js} +11 -11
  12. package/src/{codex-doc2md-ledger.js → codex/doc2md-ledger.js} +5 -5
  13. package/src/{codex-doc2md.js → codex/doc2md.js} +4 -4
  14. package/src/{codex-doctor.js → codex/doctor.js} +4 -4
  15. package/src/{codex-harness.js → codex/harness.js} +5 -5
  16. package/src/{codex-hooks.js → codex/hooks.js} +20 -20
  17. package/src/{codex-installer.js → codex/installer.js} +2 -2
  18. package/src/{codex-ledger.js → codex/ledger.js} +6 -6
  19. package/src/{codex-panel-launcher.js → codex/panel-launcher.js} +2 -2
  20. package/src/{codex-panel-runner.js → codex/panel-runner.js} +2 -2
  21. package/src/{codex-panel-session.js → codex/panel-session.js} +1 -1
  22. package/src/{codex-panel-setup.js → codex/panel-setup.js} +1 -1
  23. package/src/{codex-panel-state.js → codex/panel-state.js} +3 -3
  24. package/src/{codex-panel.js → codex/panel.js} +43 -34
  25. package/src/{codex-parser.js → codex/parser.js} +5 -9
  26. package/src/{codex-reply-language.js → codex/reply-language.js} +2 -2
  27. package/src/{codex-route-scan.js → codex/route-scan.js} +10 -10
  28. package/src/{codex-rule-health.js → codex/rule-health.js} +4 -4
  29. package/src/commands/codex-delegate.js +6 -6
  30. package/src/commands/codex.js +44 -44
  31. package/src/commands/install.js +10 -7
  32. package/src/commands/korean.js +1 -1
  33. package/src/commands/litellm-budget.js +56 -0
  34. package/src/commands/saved.js +60 -5
  35. package/src/commands/uninstall.js +3 -3
  36. package/src/config.js +4 -0
  37. package/src/delegation-agents.js +13 -0
  38. package/src/first-run-note.js +16 -0
  39. package/src/formatters/statusline.js +725 -504
  40. package/src/formatters/table.js +33 -2
  41. package/src/glyphs.js +2 -0
  42. package/src/installer.js +77 -1
  43. package/src/model-alias.js +45 -60
  44. package/src/model-rules.js +25 -4
  45. package/src/model-share.js +136 -0
  46. package/src/parser.js +4 -13
  47. package/src/session-records.js +2 -8
  48. package/src/star-note.js +62 -0
  49. package/src/statusline-base.js +9 -3
  50. package/src/stdin-payload.js +1 -1
  51. package/src/transcript-lines.js +40 -0
  52. package/src/changelog.js +0 -70
  53. /package/src/{codex-cache.js → codex/cache.js} +0 -0
  54. /package/src/{codex-panel-shell.js → codex/panel-shell.js} +0 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Lines of a transcript file, with the file closed before the loop is over.
3
+ *
4
+ * Every transcript reader used to build its own readline over createReadStream.
5
+ * That works until a loop leaves early: `return` inside `for await` closes the
6
+ * readline interface, but on Node 20 the ReadStream underneath keeps its
7
+ * descriptor until garbage collection. And even a loop that runs to the end is
8
+ * not done when it ends: 'end' fires before the asynchronous fs.close() has
9
+ * run, so a caller that deletes the directory right away still finds the file
10
+ * open. POSIX does not mind; Windows answers ENOTEMPTY, which is how the
11
+ * Windows CI job failed on Node 20 alone.
12
+ *
13
+ * A generator's finally block runs on `break`, `return` and throw alike, so
14
+ * the stream is destroyed on every exit, and the 'close' event is awaited so
15
+ * the descriptor is gone when the loop is.
16
+ */
17
+
18
+ import { createReadStream } from 'node:fs';
19
+ import { createInterface } from 'node:readline';
20
+ import { once } from 'node:events';
21
+
22
+ /**
23
+ * @param {string} filePath
24
+ * @returns {AsyncGenerator<string>}
25
+ */
26
+ export async function* transcriptLines(filePath) {
27
+ const input = createReadStream(filePath, { encoding: 'utf8' });
28
+ const rl = createInterface({ input, crlfDelay: Infinity });
29
+ try {
30
+ for await (const line of rl) yield line;
31
+ } finally {
32
+ rl.close();
33
+ input.destroy();
34
+ // A stream that failed to open has already closed itself; one that was
35
+ // still open closes asynchronously, and the wait is what makes the file
36
+ // deletable the moment the caller gets control back. 'error' after
37
+ // destroy() is not something to surface here: the loop already threw.
38
+ if (!input.closed) await once(input, 'close').catch(() => {});
39
+ }
40
+ }
package/src/changelog.js DELETED
@@ -1,70 +0,0 @@
1
- /**
2
- * changelog — read one version's section out of CHANGELOG.md, and say whether a
3
- * notes draft is still waiting on a person.
4
- *
5
- * Separate from scripts/release-notes.mjs, which is a CLI: importing that file
6
- * runs its argument parsing and exits, so the extraction it depends on cannot be
7
- * tested through it. The boundary logic is the part worth pinning — a section
8
- * pulled one line short drops the release's last item, and one line long carries
9
- * the previous release's first, and the upgrade offer shows either without
10
- * complaint.
11
- *
12
- * The draft marker lives here for a reason. Two scripts gate on it — the one that
13
- * writes drafts and the one that deploys — and they used to carry the string
14
- * separately. Renaming it in one left the other looking for text that no longer
15
- * existed, and a gate that greps for an absent string does not fail: it passes,
16
- * and an unreviewed draft goes out as the release. One definition, imported.
17
- */
18
-
19
- /**
20
- * The body of one version's section, heading excluded.
21
- *
22
- * @param {string} changelog - CHANGELOG.md contents
23
- * @param {string} version - e.g. "3.45.0"
24
- * @returns {string|null} the section text, or null when that version has none
25
- */
26
- export function sectionFor(changelog, version) {
27
- const lines = String(changelog).split(/\r?\n/);
28
- // The version has to match to its end: without the boundary, "3.42.0" would
29
- // also match the "### v3.42.7" heading and publish the wrong notes.
30
- const head = new RegExp(`^### v${String(version).replace(/\./g, '\\.')}(\\s|$|\\()`);
31
- const start = lines.findIndex((l) => head.test(l));
32
- if (start < 0) return null;
33
- const out = [];
34
- for (let i = start + 1; i < lines.length; i += 1) {
35
- // The next version heading ends this section, and so does a shallower one:
36
- // "## All releases" is a container, not part of any release.
37
- if (/^### v/.test(lines[i]) || /^## /.test(lines[i])) break;
38
- out.push(lines[i]);
39
- }
40
- return out.join('\n').trim();
41
- }
42
-
43
- /**
44
- * The line `release-notes.mjs` writes at the top of a fresh draft, and the line
45
- * every gate refuses on. A draft still carrying it has not been through a person.
46
- */
47
- export const DRAFT_MARKER =
48
- '<!-- REVIEW: edit this draft, add the English half, then delete this line -->';
49
-
50
- /** Heading that opens the Korean half of a bilingual release body. */
51
- export const KO_HEADING = '## 한국어';
52
-
53
- /**
54
- * The opening of the marker, which is what the gate actually matches. Spelled out
55
- * rather than sliced off `DRAFT_MARKER`, so that editing the marker's front does
56
- * not silently change what is being tested for.
57
- */
58
- const REVIEW_OPENING = '<!-- REVIEW:';
59
-
60
- /**
61
- * Whether a draft still needs review. Matches on the `<!-- REVIEW:` opening
62
- * rather than the whole line, so editing the wording of the instruction does not
63
- * quietly disarm the gate.
64
- *
65
- * @param {string} draft - the draft file's contents
66
- * @returns {boolean} true while the draft is unreviewed
67
- */
68
- export function needsReview(draft) {
69
- return String(draft || '').includes(REVIEW_OPENING);
70
- }
File without changes