howtofixcli 0.7.8 → 0.7.10

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 (152) hide show
  1. package/dist/chunk-27TRKD65.js +2 -0
  2. package/dist/chunk-2YYQ3OBQ.js +1 -0
  3. package/dist/chunk-3FYCFLNK.js +1 -0
  4. package/dist/chunk-3KT55SQP.js +34 -0
  5. package/dist/chunk-4BWDGEXH.js +5 -0
  6. package/dist/chunk-56SEAGAQ.js +1 -0
  7. package/dist/chunk-6FUWMLWO.js +1 -0
  8. package/dist/chunk-7CHDNTH6.js +1 -0
  9. package/dist/chunk-ACOMNDUL.js +185 -0
  10. package/dist/chunk-AGGIYXN7.js +2 -0
  11. package/dist/chunk-BHVBO4SC.js +1 -0
  12. package/dist/chunk-CGHISVXB.js +1 -0
  13. package/dist/chunk-FPXVDP32.js +8 -0
  14. package/dist/chunk-FRGMJPNO.js +2 -0
  15. package/dist/chunk-GXB7RZHH.js +1 -0
  16. package/dist/chunk-ILDDDLRC.js +1 -0
  17. package/dist/chunk-JFYVRWJI.js +2 -0
  18. package/dist/chunk-MTNY7MFG.js +6 -0
  19. package/dist/chunk-MVLCGU3G.js +1 -0
  20. package/dist/chunk-N345KWWK.js +1 -0
  21. package/dist/chunk-ORJ2QZBG.js +3 -0
  22. package/dist/chunk-PCALBZOO.js +2 -0
  23. package/dist/chunk-PIEAJJRE.js +5 -0
  24. package/dist/chunk-RDRF7DIS.js +109 -0
  25. package/dist/chunk-TEW62VDF.js +1 -0
  26. package/dist/chunk-TSEKPGK4.js +1 -0
  27. package/dist/chunk-UTYFLLSM.js +1 -0
  28. package/dist/chunk-V3R4FYTJ.js +1 -0
  29. package/dist/chunk-V656XVXV.js +8 -0
  30. package/dist/chunk-VICEM5Y2.js +2 -0
  31. package/dist/chunk-WKUJ7CFO.js +1 -0
  32. package/dist/chunk-WOT6VMZA.js +1 -0
  33. package/dist/chunk-WUPU6LTD.js +4 -0
  34. package/dist/chunk-WX3V5P7U.js +5 -0
  35. package/dist/chunk-WZKWT757.js +2 -0
  36. package/dist/main.js +94 -536
  37. package/package.json +16 -63
  38. package/dist/account-credential.js +0 -136
  39. package/dist/account-credential.test.js +0 -38
  40. package/dist/activity.js +0 -124
  41. package/dist/agent-defs.js +0 -237
  42. package/dist/agent-limiter.js +0 -68
  43. package/dist/agents.js +0 -554
  44. package/dist/anim.js +0 -361
  45. package/dist/args.js +0 -228
  46. package/dist/at-file.js +0 -28
  47. package/dist/brand-extension.js +0 -87
  48. package/dist/brand.js +0 -76
  49. package/dist/browser.js +0 -58
  50. package/dist/cache-report.js +0 -139
  51. package/dist/checkpoint.js +0 -437
  52. package/dist/claims.js +0 -167
  53. package/dist/cli-auth.js +0 -142
  54. package/dist/cli-checkin.js +0 -120
  55. package/dist/cli-credentials.js +0 -254
  56. package/dist/clipboard.js +0 -149
  57. package/dist/collapse.js +0 -129
  58. package/dist/commands.js +0 -301
  59. package/dist/compaction-guard.js +0 -81
  60. package/dist/context-extension.js +0 -17
  61. package/dist/dcp/commands.js +0 -172
  62. package/dist/dcp/compress-state.js +0 -139
  63. package/dist/dcp/compress.js +0 -329
  64. package/dist/dcp/dcp-extension.js +0 -288
  65. package/dist/dcp/dedup.js +0 -93
  66. package/dist/dcp/ids.js +0 -189
  67. package/dist/dcp/index.js +0 -25
  68. package/dist/dcp/prompts.js +0 -68
  69. package/dist/dcp/protected-content.js +0 -221
  70. package/dist/dcp/protected.js +0 -161
  71. package/dist/dcp/prune.js +0 -418
  72. package/dist/dcp/state.js +0 -176
  73. package/dist/device-id.js +0 -90
  74. package/dist/device-id.test.js +0 -23
  75. package/dist/errors.js +0 -63
  76. package/dist/extensions.js +0 -48
  77. package/dist/fatal.js +0 -35
  78. package/dist/feed.js +0 -498
  79. package/dist/fs-atomic.js +0 -54
  80. package/dist/gateway-errors.js +0 -90
  81. package/dist/git.js +0 -230
  82. package/dist/goal-extension.js +0 -88
  83. package/dist/goal.js +0 -222
  84. package/dist/hooks-extension.js +0 -176
  85. package/dist/hooks.js +0 -443
  86. package/dist/howtofix-account.js +0 -715
  87. package/dist/hud-line.js +0 -153
  88. package/dist/hwid.js +0 -130
  89. package/dist/interrupt.js +0 -60
  90. package/dist/json-events.js +0 -50
  91. package/dist/level-style.js +0 -112
  92. package/dist/loop-guard.js +0 -95
  93. package/dist/lsp-tools.js +0 -32
  94. package/dist/lsp.js +0 -347
  95. package/dist/mcp-config.js +0 -85
  96. package/dist/mcp-lifecycle.js +0 -147
  97. package/dist/model-catalog.js +0 -217
  98. package/dist/model-resolve.js +0 -65
  99. package/dist/notes.js +0 -78
  100. package/dist/oauth-login.js +0 -568
  101. package/dist/paths.js +0 -61
  102. package/dist/permissions.js +0 -298
  103. package/dist/plan-mode.js +0 -363
  104. package/dist/preset-command.js +0 -227
  105. package/dist/preset-extension.js +0 -35
  106. package/dist/preset-mcp.js +0 -292
  107. package/dist/presets.js +0 -727
  108. package/dist/prompt-files.js +0 -103
  109. package/dist/prompt-text.js +0 -41
  110. package/dist/proxy.js +0 -137
  111. package/dist/quality/ast.js +0 -196
  112. package/dist/quality/cognitive.js +0 -83
  113. package/dist/quality/cyclomatic.js +0 -30
  114. package/dist/quality/halstead.js +0 -83
  115. package/dist/quality/index.js +0 -18
  116. package/dist/quality/length.js +0 -3
  117. package/dist/quality/maintainability.js +0 -15
  118. package/dist/quality/nesting.js +0 -57
  119. package/dist/quality/report.js +0 -803
  120. package/dist/quality/smells.js +0 -67
  121. package/dist/quality-tool.js +0 -63
  122. package/dist/read-only-commands.js +0 -597
  123. package/dist/repo-map.js +0 -292
  124. package/dist/rtk.js +0 -193
  125. package/dist/sandbox.js +0 -105
  126. package/dist/schema.js +0 -214
  127. package/dist/session-lifecycle.js +0 -19
  128. package/dist/session-retention.js +0 -111
  129. package/dist/session.js +0 -446
  130. package/dist/sessions.js +0 -100
  131. package/dist/settings.js +0 -148
  132. package/dist/skills.js +0 -35
  133. package/dist/slop-tool.js +0 -96
  134. package/dist/spend-cap.js +0 -43
  135. package/dist/subagent.js +0 -171
  136. package/dist/tar.js +0 -146
  137. package/dist/theme.js +0 -79
  138. package/dist/thinking.js +0 -45
  139. package/dist/todo.js +0 -114
  140. package/dist/tool-loadout.js +0 -97
  141. package/dist/tool-render.js +0 -769
  142. package/dist/tools.js +0 -176
  143. package/dist/ui.js +0 -4757
  144. package/dist/update.js +0 -533
  145. package/dist/usage-segment.js +0 -69
  146. package/dist/web-tools.js +0 -46
  147. package/dist/web.js +0 -265
  148. package/dist/welcome.js +0 -179
  149. package/dist/workflow-engine.js +0 -246
  150. package/dist/workflow-progress.js +0 -446
  151. package/dist/workflow-view.js +0 -195
  152. package/dist/workflow.js +0 -349
package/dist/schema.js DELETED
@@ -1,214 +0,0 @@
1
- /**
2
- * A small JSON Schema validator, sufficient for the `schema` option of
3
- * `agent()` in a workflow script.
4
- *
5
- * Why not a library: `ajv` is not installed and the SDK does not export a
6
- * validator, so a dependency would have to be vendored into a repo whose rule is
7
- * not to re-vendor the SDK. The supported subset is the one the workflow spec names
8
- * for structured output — `type`, `properties`, `required`, `items`, `enum`,
9
- * `anyOf`/`oneOf`/`allOf`, `$defs`/`definitions`, `additionalProperties` — which
10
- * is small enough to implement honestly, and the failure messages matter more
11
- * than breadth here: they are fed back to the model as a repair turn.
12
- *
13
- * Validation is intentionally permissive about keywords it does not understand
14
- * (they are ignored rather than failing the value), because the contract is that
15
- * a reply validating against the authored schema is accepted.
16
- */
17
- const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
18
- function typeOf(value) {
19
- if (value === null)
20
- return "null";
21
- if (Array.isArray(value))
22
- return "array";
23
- if (Number.isInteger(value))
24
- return "integer";
25
- return typeof value;
26
- }
27
- function matchesType(value, want) {
28
- const actual = typeOf(value);
29
- if (want === "number")
30
- return actual === "number" || actual === "integer";
31
- if (want === "integer")
32
- return actual === "integer";
33
- return actual === want;
34
- }
35
- /** Resolve a `$ref` against the document root (`#/$defs/name` or `#/definitions/name`). */
36
- function resolveRef(root, ref) {
37
- if (typeof ref !== "string" || !ref.startsWith("#/"))
38
- return undefined;
39
- let node = root;
40
- for (const rawPart of ref.slice(2).split("/")) {
41
- const part = rawPart.replace(/~1/g, "/").replace(/~0/g, "~");
42
- if (!isObject(node) && !Array.isArray(node))
43
- return undefined;
44
- node = node[part];
45
- }
46
- return isObject(node) ? node : undefined;
47
- }
48
- function validateNode(value, schema, root, path, issues) {
49
- if (!isObject(schema))
50
- return;
51
- if (schema.$ref !== undefined) {
52
- const target = resolveRef(root, schema.$ref);
53
- if (target)
54
- validateNode(value, target, root, path, issues);
55
- return;
56
- }
57
- // Combinators. `allOf` must hold everywhere; `anyOf`/`oneOf` need a passing branch.
58
- if (Array.isArray(schema.allOf)) {
59
- for (const branch of schema.allOf)
60
- validateNode(value, branch, root, path, issues);
61
- }
62
- for (const keyword of ["anyOf", "oneOf"]) {
63
- const branches = schema[keyword];
64
- if (!Array.isArray(branches) || branches.length === 0)
65
- continue;
66
- const passes = branches.filter((branch) => {
67
- const scratch = [];
68
- validateNode(value, branch, root, path, scratch);
69
- return scratch.length === 0;
70
- }).length;
71
- if (keyword === "anyOf" && passes === 0)
72
- issues.push({ path, message: "does not match any allowed shape" });
73
- if (keyword === "oneOf" && passes !== 1)
74
- issues.push({ path, message: `must match exactly one shape (matched ${passes})` });
75
- }
76
- const declaredType = schema.type;
77
- if (declaredType !== undefined) {
78
- const wanted = Array.isArray(declaredType) ? declaredType.map(String) : [String(declaredType)];
79
- if (!wanted.some((want) => matchesType(value, want))) {
80
- issues.push({ path, message: `expected ${wanted.join(" or ")}, got ${typeOf(value)}` });
81
- return; // A wrong type makes the remaining checks noise.
82
- }
83
- }
84
- if (Array.isArray(schema.enum) && !schema.enum.some((option) => JSON.stringify(option) === JSON.stringify(value))) {
85
- issues.push({ path, message: `must be one of ${schema.enum.map((option) => JSON.stringify(option)).join(", ")}` });
86
- }
87
- if (isObject(value)) {
88
- const properties = isObject(schema.properties) ? schema.properties : {};
89
- if (Array.isArray(schema.required)) {
90
- for (const key of schema.required.map(String)) {
91
- if (!(key in value))
92
- issues.push({ path: path ? `${path}.${key}` : key, message: "is required" });
93
- }
94
- }
95
- for (const [key, propertySchema] of Object.entries(properties)) {
96
- if (key in value)
97
- validateNode(value[key], propertySchema, root, path ? `${path}.${key}` : key, issues);
98
- }
99
- if (schema.additionalProperties === false) {
100
- for (const key of Object.keys(value)) {
101
- if (!(key in properties))
102
- issues.push({ path: path ? `${path}.${key}` : key, message: "is not an allowed property" });
103
- }
104
- }
105
- else if (isObject(schema.additionalProperties)) {
106
- for (const [key, entry] of Object.entries(value)) {
107
- if (!(key in properties))
108
- validateNode(entry, schema.additionalProperties, root, path ? `${path}.${key}` : key, issues);
109
- }
110
- }
111
- }
112
- if (Array.isArray(value) && schema.items !== undefined) {
113
- const items = schema.items;
114
- if (Array.isArray(items)) {
115
- // Tuple form: validate positionally.
116
- value.forEach((entry, index) => {
117
- if (index < items.length)
118
- validateNode(entry, items[index], root, `${path}[${index}]`, issues);
119
- });
120
- }
121
- else {
122
- value.forEach((entry, index) => validateNode(entry, items, root, `${path}[${index}]`, issues));
123
- }
124
- }
125
- if (typeof value === "string") {
126
- if (typeof schema.minLength === "number" && value.length < schema.minLength) {
127
- issues.push({ path, message: `is shorter than ${schema.minLength} characters` });
128
- }
129
- if (typeof schema.pattern === "string") {
130
- try {
131
- if (!new RegExp(schema.pattern).test(value))
132
- issues.push({ path, message: `does not match ${schema.pattern}` });
133
- }
134
- catch {
135
- // An invalid pattern is the schema author's problem, not the value's.
136
- }
137
- }
138
- }
139
- if (typeof value === "number") {
140
- if (typeof schema.minimum === "number" && value < schema.minimum)
141
- issues.push({ path, message: `is below ${schema.minimum}` });
142
- if (typeof schema.maximum === "number" && value > schema.maximum)
143
- issues.push({ path, message: `is above ${schema.maximum}` });
144
- }
145
- }
146
- /** Every way `value` fails `schema`. Empty means it validates. */
147
- export function validateSchema(value, schema) {
148
- if (!isObject(schema))
149
- return [];
150
- const issues = [];
151
- validateNode(value, schema, schema, "", issues);
152
- return issues;
153
- }
154
- /** One line per issue, for a repair turn. */
155
- export function formatIssues(issues) {
156
- return issues.map((issue) => `- ${issue.path || "(root)"}: ${issue.message}`).join("\n");
157
- }
158
- /**
159
- * Pull a JSON value out of a model reply.
160
- *
161
- * Models wrap JSON in prose or fences often enough that a bare `JSON.parse` is
162
- * not a fair test of whether they followed the schema. Only the first complete
163
- * value is taken; anything before or after it is ignored.
164
- */
165
- export function extractJson(text) {
166
- const trimmed = text.trim();
167
- const fenced = /```(?:json)?\s*([\s\S]*?)```/.exec(trimmed);
168
- const candidates = [trimmed, fenced?.[1]?.trim()].filter((candidate) => Boolean(candidate));
169
- for (const candidate of candidates) {
170
- try {
171
- return JSON.parse(candidate);
172
- }
173
- catch {
174
- /* try to find a balanced value inside */
175
- }
176
- for (let start = 0; start < candidate.length; start++) {
177
- const opener = candidate[start];
178
- if (opener !== "{" && opener !== "[")
179
- continue;
180
- const closer = opener === "{" ? "}" : "]";
181
- let depth = 0;
182
- let inString = false;
183
- let escaped = false;
184
- for (let index = start; index < candidate.length; index++) {
185
- const char = candidate[index];
186
- if (inString) {
187
- if (escaped)
188
- escaped = false;
189
- else if (char === "\\")
190
- escaped = true;
191
- else if (char === '"')
192
- inString = false;
193
- continue;
194
- }
195
- if (char === '"')
196
- inString = true;
197
- else if (char === opener)
198
- depth++;
199
- else if (char === closer) {
200
- depth--;
201
- if (depth === 0) {
202
- try {
203
- return JSON.parse(candidate.slice(start, index + 1));
204
- }
205
- catch {
206
- break;
207
- }
208
- }
209
- }
210
- }
211
- }
212
- }
213
- return undefined;
214
- }
@@ -1,19 +0,0 @@
1
- /**
2
- * Close extension-owned resources before disposing an agent session.
3
- *
4
- * AgentSession.dispose() disconnects the agent itself, but extension resources
5
- * (including MCP transports) are released by the session_shutdown event. The
6
- * SDK exposes the runner so callers can deliver that lifecycle event even when
7
- * a session is replaced outside the interactive mode.
8
- *
9
- * The returned promise settles once the shutdown has been delivered and the
10
- * session is disposed. Callers must await it: dropping the promise leaves the
11
- * MCP processes and tool registrations alive after the configuration that
12
- * created them is gone.
13
- */
14
- export function disposeAgentSession(session) {
15
- return session.extensionRunner
16
- .emit({ type: "session_shutdown", reason: "quit" })
17
- .catch(() => undefined)
18
- .finally(() => session.dispose());
19
- }
@@ -1,111 +0,0 @@
1
- import { readdir, rmdir, stat, unlink } from "node:fs/promises";
2
- import { dirname, join, resolve } from "node:path";
3
- import { RETENTION_DAYS } from "./checkpoint.js";
4
- import { AGENT_DIR } from "./paths.js";
5
- /**
6
- * Unlink session files idle for longer than `RETENTION_DAYS`, across every
7
- * project directory — the store's whole problem is that it is per-cwd and
8
- * nothing ever looked outside the current one.
9
- *
10
- * The SDK writes `<agentDir>/sessions/--<encoded-cwd>--/<timestamp>_<id>.jsonl`
11
- * and never removes one: `SessionManager` only appends, the TUI's delete is a
12
- * single user-chosen session (and prefers `trash`), and the CLI had no sweep at
13
- * all, so a machine that uses the product for a year keeps a transcript of every
14
- * folder it was ever pointed at. Rewind's shadow store already sweeps at 30 days
15
- * (checkpoint.ts, `RETENTION_DAYS`) — same window here on purpose, so "old" means
16
- * one thing across both stores and a session whose snapshots are gone does not
17
- * linger as a transcript.
18
- *
19
- * Age is the file's mtime, not the timestamp in its name: a session resumed last
20
- * week was written last week and must survive, while its filename still says the
21
- * day it was created. `keep` is the stronger rule on top of that — `--continue`
22
- * and `/resume` exist to bring an old session back, so the file this process just
23
- * opened is kept whatever its age.
24
- *
25
- * Housekeeping, so it never throws and never reports to the user: every step is
26
- * per-file, an error only leaves the store larger than it needed to be. Files are
27
- * unlinked rather than trashed — the TUI's `trash` path is a person deleting one
28
- * session they chose, this is a bulk sweep they did not ask to watch.
29
- */
30
- export async function sweepStaleSessions(options = {}) {
31
- const result = { removed: [], failed: [], removedDirs: [] };
32
- const root = join(options.agentDir ?? AGENT_DIR, "sessions");
33
- const cutoff = (options.now ?? Date.now()) - RETENTION_DAYS * 24 * 60 * 60 * 1000;
34
- const keep = options.keep ? resolve(options.keep) : undefined;
35
- let projects;
36
- try {
37
- projects = await readdir(root, { withFileTypes: true });
38
- }
39
- catch {
40
- // No store, or an unreadable one: nothing to sweep and nothing to say.
41
- return result;
42
- }
43
- for (const project of projects) {
44
- if (!project.isDirectory())
45
- continue;
46
- const dir = join(root, project.name);
47
- let files;
48
- try {
49
- files = await readdir(dir);
50
- }
51
- catch {
52
- continue;
53
- }
54
- // What will still be in the directory when the sweep is done. Sidecars a
55
- // stale session left behind (`plan.md`, `plan_mode.json`) count and keep the
56
- // directory on purpose: they are project state a later session of the same
57
- // folder still restores.
58
- const surviving = files.filter((file) => !file.endsWith(".jsonl"));
59
- for (const file of files) {
60
- if (!file.endsWith(".jsonl"))
61
- continue;
62
- const path = join(dir, file);
63
- let stale;
64
- try {
65
- if (keep && resolve(path) === keep)
66
- stale = false;
67
- else {
68
- // mtime, not the timestamp in the name: a session resumed last week
69
- // was written last week, whatever its filename says.
70
- stale = (await stat(path)).mtimeMs < cutoff;
71
- }
72
- }
73
- catch {
74
- // Raced with another sweeper (two processes starting at once).
75
- stale = false;
76
- }
77
- if (!stale) {
78
- surviving.push(file);
79
- continue;
80
- }
81
- try {
82
- await unlink(path);
83
- result.removed.push(path);
84
- }
85
- catch {
86
- // A directory called `x.jsonl`, a permission wall, a file another
87
- // process holds oddly: count it and keep going.
88
- result.failed.push(path);
89
- surviving.push(file);
90
- }
91
- }
92
- // Drop the per-project directory when nothing is left in it, so the encoded
93
- // cwd names stop piling up too.
94
- if (surviving.length === 0) {
95
- // Never drop the directory the live session writes into. On a fresh start
96
- // the session file does not exist yet, so the directory looks empty and
97
- // the sweep removed it — the next prompt then failed with ENOENT because
98
- // the writer's parent had been deleted underneath it.
99
- if (keep && dirname(keep) === dir)
100
- continue;
101
- try {
102
- await rmdir(dir);
103
- result.removedDirs.push(dir);
104
- }
105
- catch {
106
- // Non-empty after all, or racing a writer: the directory stays.
107
- }
108
- }
109
- }
110
- return result;
111
- }