@tech-leads-club/harness-toolkit 0.3.0 → 0.3.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 (44) hide show
  1. package/README.md +46 -11
  2. package/bin/tlc-build.mjs +35 -6
  3. package/config.example.json +1 -1
  4. package/dist/chunks/compact-before-1e4qg1qt.mjs +1185 -0
  5. package/dist/chunks/compact-before-2hpbfxm5.mjs +5782 -0
  6. package/dist/chunks/compact-before-49j320yp.mjs +1283 -0
  7. package/dist/chunks/compact-before-4jrq0sqs.mjs +61 -0
  8. package/dist/chunks/compact-before-6w8n1vh1.mjs +186 -0
  9. package/dist/chunks/compact-before-7sdmwswh.mjs +52 -0
  10. package/dist/chunks/compact-before-beqpmqrm.mjs +187 -0
  11. package/dist/chunks/compact-before-j9y4jgn4.mjs +845 -0
  12. package/dist/chunks/compact-before-pk86tqx2.mjs +118 -0
  13. package/dist/chunks/compact-before-pkqk5v29.mjs +137 -0
  14. package/dist/chunks/compact-before-w1293m4n.mjs +315 -0
  15. package/dist/chunks/compact-before-wnnds45y.mjs +26 -0
  16. package/dist/chunks/compact-before-wt2c3nh4.mjs +551 -0
  17. package/dist/compact-before.mjs +13 -7961
  18. package/dist/doctor.mjs +33 -8480
  19. package/dist/help-topic.mjs +6 -14
  20. package/dist/init-project.mjs +36 -793
  21. package/dist/install-runtime.mjs +18 -1039
  22. package/dist/lessons-cli.mjs +25 -7043
  23. package/dist/obs-cli.mjs +27 -7037
  24. package/dist/price-lookup.mjs +11 -201
  25. package/dist/prompt-submit.mjs +14 -7974
  26. package/dist/refresh-model-prices.mjs +26 -7061
  27. package/dist/response-after.mjs +11 -7961
  28. package/dist/run.mjs +10 -7960
  29. package/dist/session-end.mjs +14 -8029
  30. package/dist/session-start.mjs +20 -8075
  31. package/dist/shim.mjs +18 -7024
  32. package/dist/stop.mjs +29 -8042
  33. package/dist/subagent-start.mjs +13 -7983
  34. package/dist/subagent-stop.mjs +11 -7961
  35. package/dist/support.mjs +21 -7168
  36. package/dist/tlc-cli.mjs +65 -8200
  37. package/dist/tool-after.mjs +20 -8176
  38. package/dist/tool-before.mjs +15 -7990
  39. package/dist/tool-failure.mjs +14 -7961
  40. package/dist/uninstall-runtime.mjs +61 -1008
  41. package/docs/log.md +4 -0
  42. package/package.json +2 -2
  43. package/src/core/release/release.version.ts +10 -4
  44. package/tools/install-runtime.ts +21 -1
@@ -1,784 +1,27 @@
1
- import { createRequire } from "node:module";
2
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
-
4
- // tools/init-project.ts
5
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
6
- import { dirname as dirname3, join as join4, sep } from "node:path";
7
-
8
- // bin/write-user-hooks.mjs
9
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
10
- import { dirname as dirname2, join as join3 } from "node:path";
11
-
12
- // src/providers/claude/claude.wiring.ts
13
- import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
14
- import { dirname, join as join2 } from "node:path";
15
-
16
- // src/platform/paths.ts
17
- import { homedir } from "node:os";
18
- import { join } from "node:path";
19
- function harnessDir(root) {
20
- return join(root, ".tlc", "harness");
21
- }
22
- function conventionalRuntimeHome() {
23
- return join(homedir(), ".tlc", "harness");
24
- }
25
- function runtimeHome(env = process.env) {
26
- return env.TLC_HOME ?? conventionalRuntimeHome();
27
- }
28
- function projectConfigPath(root) {
29
- return join(harnessDir(root), "config.json");
30
- }
31
- function claudeConfigDir() {
32
- const custom = process.env.CLAUDE_CONFIG_DIR?.trim();
33
- return custom && custom.length > 0 ? custom : join(homedir(), ".claude");
34
- }
35
- function cursorConfigDir() {
36
- const custom = process.env.CURSOR_CONFIG_DIR?.trim();
37
- return custom && custom.length > 0 ? custom : join(homedir(), ".cursor");
38
- }
39
-
40
- // src/providers/claude/claude.wiring.ts
41
- function isPlainRecord(value) {
42
- return value !== null && typeof value === "object" && !Array.isArray(value);
43
- }
44
- function isHooksRecord(value) {
45
- return isPlainRecord(value);
46
- }
47
- function deepEqual(a, b) {
48
- if (a === b) {
49
- return true;
50
- }
51
- if (Array.isArray(a) || Array.isArray(b)) {
52
- if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
53
- return false;
54
- }
55
- return a.every((item, index) => deepEqual(item, b[index]));
56
- }
57
- if (isPlainRecord(a) && isPlainRecord(b)) {
58
- const aKeys = Object.keys(a);
59
- const bKeys = Object.keys(b);
60
- if (aKeys.length !== bKeys.length) {
61
- return false;
62
- }
63
- return aKeys.every((key) => bKeys.includes(key) && deepEqual(a[key], b[key]));
64
- }
65
- return false;
66
- }
67
- function desiredHooksFor(entries) {
68
- const hooks = {};
69
- for (const entry of entries) {
70
- const group = {
71
- hooks: [{ type: "command", command: entry.command, args: entry.args }]
72
- };
73
- hooks[entry.hookEvent] = [...hooks[entry.hookEvent] ?? [], group];
74
- }
75
- return hooks;
76
- }
77
- var LAUNCHER_MARKER = "tlc-exec.mjs";
78
- function isHarnessGroup(group) {
79
- return JSON.stringify(group ?? null).includes(LAUNCHER_MARKER);
80
- }
81
- function canonicalLauncherPath(path, resolve = realpathSync) {
82
- try {
83
- return resolve(path);
84
- } catch {
85
- return path;
86
- }
87
- }
88
- function canonicalizeGroups(groups, resolve) {
89
- return JSON.parse(JSON.stringify(groups ?? null, (_key, value) => typeof value === "string" && value.includes(LAUNCHER_MARKER) ? canonicalLauncherPath(value, resolve) : value));
90
- }
91
- function mergeClaudeSettings(existingText, entries) {
92
- const desired = desiredHooksFor(entries);
93
- let settings = {};
94
- if (existingText !== null && existingText.trim() !== "") {
95
- let parsed;
96
- try {
97
- parsed = JSON.parse(existingText);
98
- } catch (error) {
99
- const message = error instanceof Error ? error.message : String(error);
100
- return { ok: false, error: message, block: JSON.stringify({ hooks: desired }, null, 2) };
101
- }
102
- if (!isPlainRecord(parsed)) {
103
- return {
104
- ok: false,
105
- error: "settings.json root is not a JSON object",
106
- block: JSON.stringify({ hooks: desired }, null, 2)
107
- };
108
- }
109
- settings = parsed;
110
- }
111
- const currentHooks = isHooksRecord(settings.hooks) ? settings.hooks : {};
112
- const mergedHooks = { ...currentHooks };
113
- let changed = false;
114
- for (const [hookEvent, groups] of Object.entries(desired)) {
115
- const existingGroups = mergedHooks[hookEvent] ?? [];
116
- const foreign = existingGroups.filter((group) => !isHarnessGroup(group));
117
- const nextGroups = [...foreign, ...groups];
118
- if (!deepEqual(canonicalizeGroups(existingGroups), canonicalizeGroups(nextGroups))) {
119
- changed = true;
120
- }
121
- mergedHooks[hookEvent] = nextGroups;
122
- }
123
- const mergedSettings = { ...settings, hooks: mergedHooks };
124
- return { ok: true, settingsText: JSON.stringify(mergedSettings, null, 2), changed };
125
- }
126
- function applyClaudeWiring(settingsPath, entries) {
127
- const existingText = existsSync(settingsPath) ? readFileSync(settingsPath, "utf8") : null;
128
- const result = mergeClaudeSettings(existingText, entries);
129
- if (result.ok && result.changed) {
130
- mkdirSync(dirname(settingsPath), { recursive: true });
131
- writeFileSync(settingsPath, result.settingsText, "utf8");
132
- }
133
- return result;
134
- }
135
- // src/providers/provider.degrade.ts
136
- var NO_HUMAN_MODES = new Set(["bypassPermissions", "dontAsk"]);
137
- // bin/write-user-hooks.mjs
138
- var CURSOR_MARKER = "tlc-exec.mjs";
139
- function quoteIfNeeded(token) {
140
- return token.includes(" ") ? `"${token}"` : token;
141
- }
142
- function commandStringFor(entry) {
143
- return [entry.command, ...entry.args].map(quoteIfNeeded).join(" ");
144
- }
145
- function renderCursorHooksDocument(entries) {
146
- const hooks = {};
147
- for (const entry of entries) {
148
- const rendered = { command: commandStringFor(entry), timeout: entry.timeoutSeconds };
149
- if (entry.failClosed) {
150
- rendered.failClosed = true;
151
- }
152
- if (entry.matcher !== undefined) {
153
- rendered.matcher = entry.matcher;
154
- }
155
- if (entry.loopLimit !== undefined) {
156
- rendered.loop_limit = entry.loopLimit;
157
- }
158
- hooks[entry.hookEvent] = [...hooks[entry.hookEvent] ?? [], rendered];
159
- }
160
- return { version: 1, hooks };
161
- }
162
- function isCursorWired(targetPath) {
163
- return existsSync2(targetPath) && readFileSync2(targetPath, "utf8").includes(CURSOR_MARKER);
164
- }
165
- function applyCursorWiring(wiring, { force = false } = {}) {
166
- const targetPath = wiring.target;
167
- const document = renderCursorHooksDocument(wiring.entries);
168
- const rendered = `${JSON.stringify(document, null, 2)}
169
- `;
170
- if (existsSync2(targetPath) && !force) {
171
- if (isCursorWired(targetPath)) {
172
- return { status: "unchanged", target: targetPath };
173
- }
174
- return {
175
- status: "refused",
176
- target: targetPath,
177
- reason: `${targetPath} exists without harness entries — rerun with --force to overwrite, or merge manually.`
178
- };
179
- }
180
- mkdirSync2(dirname2(targetPath), { recursive: true });
181
- writeFileSync2(targetPath, rendered);
182
- return { status: "written", target: targetPath };
183
- }
184
- if (false) {}
185
-
186
- // src/core/comment-policy/comment-syntax.catalog.ts
187
- var COMMENT_SYNTAX = [
188
- {
189
- id: "typescript",
190
- extensions: [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"],
191
- line: ["//"],
192
- block: [["/*", "*/"]],
193
- middle: ["*"]
194
- },
195
- {
196
- id: "python",
197
- extensions: [".py", ".pyi", ".pyw"],
198
- line: ["#"],
199
- block: [
200
- ['"""', '"""'],
201
- ["'''", "'''"]
202
- ],
203
- middle: []
204
- },
205
- {
206
- id: "ruby",
207
- extensions: [".rb", ".rake", ".gemspec"],
208
- line: ["#"],
209
- block: [["=begin", "=end"]],
210
- middle: []
211
- },
212
- {
213
- id: "shell",
214
- extensions: [".sh", ".bash", ".zsh", ".ksh", ".fish"],
215
- line: ["#"],
216
- block: [],
217
- middle: []
218
- },
219
- {
220
- id: "go",
221
- extensions: [".go"],
222
- line: ["//"],
223
- block: [["/*", "*/"]],
224
- middle: ["*"]
225
- },
226
- {
227
- id: "rust",
228
- extensions: [".rs"],
229
- line: ["//"],
230
- block: [["/*", "*/"]],
231
- middle: ["*"]
232
- },
233
- {
234
- id: "java",
235
- extensions: [".java"],
236
- line: ["//"],
237
- block: [["/*", "*/"]],
238
- middle: ["*"]
239
- },
240
- {
241
- id: "kotlin",
242
- extensions: [".kt", ".kts"],
243
- line: ["//"],
244
- block: [["/*", "*/"]],
245
- middle: ["*"]
246
- },
247
- {
248
- id: "swift",
249
- extensions: [".swift"],
250
- line: ["//"],
251
- block: [["/*", "*/"]],
252
- middle: ["*"]
253
- },
254
- {
255
- id: "c",
256
- extensions: [".c", ".h"],
257
- line: ["//"],
258
- block: [["/*", "*/"]],
259
- middle: ["*"]
260
- },
261
- {
262
- id: "cpp",
263
- extensions: [".cc", ".cpp", ".cxx", ".hpp", ".hh", ".hxx"],
264
- line: ["//"],
265
- block: [["/*", "*/"]],
266
- middle: ["*"]
267
- },
268
- {
269
- id: "csharp",
270
- extensions: [".cs"],
271
- line: ["//"],
272
- block: [["/*", "*/"]],
273
- middle: ["*"]
274
- },
275
- {
276
- id: "php",
277
- extensions: [".php"],
278
- line: ["//", "#"],
279
- block: [["/*", "*/"]],
280
- middle: ["*"]
281
- },
282
- {
283
- id: "scala",
284
- extensions: [".scala", ".sc"],
285
- line: ["//"],
286
- block: [["/*", "*/"]],
287
- middle: ["*"]
288
- },
289
- {
290
- id: "dart",
291
- extensions: [".dart"],
292
- line: ["//"],
293
- block: [["/*", "*/"]],
294
- middle: ["*"]
295
- },
296
- {
297
- id: "elixir",
298
- extensions: [".ex", ".exs"],
299
- line: ["#"],
300
- block: [],
301
- middle: []
302
- },
303
- {
304
- id: "erlang",
305
- extensions: [".erl", ".hrl"],
306
- line: ["%"],
307
- block: [],
308
- middle: []
309
- },
310
- {
311
- id: "haskell",
312
- extensions: [".hs"],
313
- line: ["--"],
314
- block: [["{-", "-}"]],
315
- middle: []
316
- },
317
- {
318
- id: "lua",
319
- extensions: [".lua"],
320
- line: ["--"],
321
- block: [["--[[", "]]"]],
322
- middle: []
323
- },
324
- {
325
- id: "sql",
326
- extensions: [".sql"],
327
- line: ["--"],
328
- block: [["/*", "*/"]],
329
- middle: ["*"]
330
- },
331
- {
332
- id: "css",
333
- extensions: [".css", ".scss", ".sass", ".less"],
334
- line: ["//"],
335
- block: [["/*", "*/"]],
336
- middle: ["*"]
337
- },
338
- {
339
- id: "yaml",
340
- extensions: [".yaml", ".yml"],
341
- line: ["#"],
342
- block: [],
343
- middle: []
344
- },
345
- {
346
- id: "toml",
347
- extensions: [".toml"],
348
- line: ["#"],
349
- block: [],
350
- middle: []
351
- },
352
- {
353
- id: "ini",
354
- extensions: [".ini", ".cfg", ".conf", ".properties"],
355
- line: [";", "#"],
356
- block: [],
357
- middle: []
358
- },
359
- {
360
- id: "dockerfile",
361
- extensions: [".dockerfile", "dockerfile"],
362
- line: ["#"],
363
- block: [],
364
- middle: []
365
- },
366
- {
367
- id: "makefile",
368
- extensions: [".mk", "makefile"],
369
- line: ["#"],
370
- block: [],
371
- middle: []
372
- },
373
- {
374
- id: "terraform",
375
- extensions: [".tf", ".tfvars"],
376
- line: ["#", "//"],
377
- block: [["/*", "*/"]],
378
- middle: ["*"]
379
- },
380
- {
381
- id: "powershell",
382
- extensions: [".ps1", ".psm1", ".psd1"],
383
- line: ["#"],
384
- block: [["<#", "#>"]],
385
- middle: []
386
- },
387
- {
388
- id: "perl",
389
- extensions: [".pl", ".pm"],
390
- line: ["#"],
391
- block: [],
392
- middle: []
393
- },
394
- {
395
- id: "r",
396
- extensions: [".r"],
397
- line: ["#"],
398
- block: [],
399
- middle: []
400
- },
401
- {
402
- id: "julia",
403
- extensions: [".jl"],
404
- line: ["#"],
405
- block: [["#=", "=#"]],
406
- middle: []
407
- },
408
- {
409
- id: "vue",
410
- extensions: [".vue", ".svelte"],
411
- line: ["//"],
412
- block: [
413
- ["/*", "*/"],
414
- ["<!--", "-->"]
415
- ],
416
- middle: ["*"]
417
- },
418
- {
419
- id: "html",
420
- extensions: [".html", ".htm", ".xml", ".xhtml"],
421
- line: [],
422
- block: [["<!--", "-->"]],
423
- middle: []
424
- },
425
- {
426
- id: "graphql",
427
- extensions: [".graphql", ".gql"],
428
- line: ["#"],
429
- block: [],
430
- middle: []
431
- },
432
- {
433
- id: "protobuf",
434
- extensions: [".proto"],
435
- line: ["//"],
436
- block: [["/*", "*/"]],
437
- middle: ["*"]
438
- },
439
- {
440
- id: "zig",
441
- extensions: [".zig"],
442
- line: ["//"],
443
- block: [],
444
- middle: []
445
- },
446
- {
447
- id: "clojure",
448
- extensions: [".clj", ".cljs", ".cljc", ".edn"],
449
- line: [";"],
450
- block: [],
451
- middle: []
452
- },
453
- {
454
- id: "ocaml",
455
- extensions: [".ml", ".mli"],
456
- line: [],
457
- block: [["(*", "*)"]],
458
- middle: ["*"]
459
- },
460
- {
461
- id: "fsharp",
462
- extensions: [".fs", ".fsi", ".fsx"],
463
- line: ["//"],
464
- block: [["(*", "*)"]],
465
- middle: ["*"]
466
- },
467
- {
468
- id: "vim",
469
- extensions: [".vim"],
470
- line: ['"'],
471
- block: [],
472
- middle: []
473
- },
474
- {
475
- id: "tex",
476
- extensions: [".tex", ".sty", ".cls"],
477
- line: ["%"],
478
- block: [],
479
- middle: []
480
- }
481
- ];
482
-
483
- // src/core/comment-policy/comment-syntax.store.ts
484
- function buildIndex(entries) {
485
- const byKey = new Map;
486
- for (const entry of entries) {
487
- const syntax = { line: entry.line, block: entry.block, middle: entry.middle };
488
- for (const extension of entry.extensions) {
489
- byKey.set(extension.toLowerCase(), syntax);
490
- }
491
- }
492
- return byKey;
493
- }
494
- var INDEX = buildIndex(COMMENT_SYNTAX);
495
- var KNOWN_EXTENSION_COUNT = INDEX.size;
496
-
497
- // src/core/comment-policy/comment-policy.service.ts
498
- var STOPWORDS = new Set([
499
- "a",
500
- "an",
501
- "and",
502
- "are",
503
- "as",
504
- "at",
505
- "be",
506
- "by",
507
- "for",
508
- "from",
509
- "get",
510
- "gets",
511
- "has",
512
- "in",
513
- "into",
514
- "is",
515
- "it",
516
- "its",
517
- "of",
518
- "on",
519
- "or",
520
- "return",
521
- "returns",
522
- "set",
523
- "sets",
524
- "that",
525
- "the",
526
- "then",
527
- "this",
528
- "to",
529
- "true",
530
- "when",
531
- "which",
532
- "with"
533
- ]);
534
-
535
- // src/core/duplication/duplication.service.ts
536
- var MIN_RUN = 6;
537
-
538
- // src/core/observability/observability.types.ts
539
- var DEFAULT_OBS = {
540
- enabled: true,
541
- signalPath: "obs.jsonl",
542
- debugPath: "debug.jsonl",
543
- debugEnabled: false,
544
- includePayloads: false,
545
- maxAttrChars: 500,
546
- sessionCostAlertUsd: 5,
547
- retentionDays: 14,
548
- maxSignalEvents: 50000,
549
- globalSpool: false
550
- };
551
- var SIGNAL_KINDS = new Set([
552
- "session.start",
553
- "session.end",
554
- "generation.end",
555
- "tool.fail",
556
- "subagent.start",
557
- "subagent.end",
558
- "prompt.submit",
559
- "compact",
560
- "gate.outcome",
561
- "cost.turn",
562
- "cost.session_alert",
563
- "ship.claim",
564
- "policy.deny",
565
- "policy.observe"
566
- ]);
567
- var LIVE_ALLOWLIST = new Set([
568
- "session.start",
569
- "session.end",
570
- "generation.end",
571
- "tool.fail",
572
- "shell.end",
573
- "subagent.start",
574
- "subagent.end",
575
- "gate.outcome",
576
- "cost.turn",
577
- "cost.session_alert",
578
- "ship.claim",
579
- "policy.deny",
580
- "compact",
581
- "prompt.submit"
582
- ]);
583
-
584
- // src/core/policy/policy.defaults.ts
585
- var DEFAULT_LESSONS_POLICY = {
586
- enabled: false,
587
- maxInjectSession: 5,
588
- maxInjectRetry: 8,
589
- maxCharsSession: 900,
590
- maxCharsRetry: 1400,
591
- promoteHitCount: 2,
592
- decayLambda: 0.02,
593
- projectBoost: 1.5,
594
- syncRulesFile: "auto",
595
- gardenOnSessionEnd: true
596
- };
597
- var DEFAULTS = {
598
- version: 1,
599
- mode: "solo",
600
- codePaths: ["src", "apps", "libs", "packages"],
601
- grind: {
602
- enabled: false,
603
- maxLoops: 5,
604
- lintCommand: null,
605
- testCommand: null,
606
- appendFiles: "auto"
607
- },
608
- shipGate: {
609
- enabled: false,
610
- runtimePathPrefixes: ["src", "apps", "libs", "packages", "deploy", "scripts"],
611
- runtimePathExcludes: [".tlc/", "**/node_modules/", "**/.git/"],
612
- evidenceDir: null,
613
- evidenceMaxAgeHours: 48,
614
- emptyDiffAntiShip: false,
615
- claimWindowMinutes: 10
616
- },
617
- subagents: {
618
- enforceAllowlist: false,
619
- requireModel: false,
620
- allowedModels: [],
621
- blockedPatterns: ["-fast(?:$|[^a-z0-9])", "/fast(?:$|[^a-z0-9])"],
622
- minEffort: null,
623
- blockParentFast: false,
624
- blockMode: "deny",
625
- readOnlyTypes: ["explore"]
626
- },
627
- docs: {
628
- command: null,
629
- severity: "warn"
630
- },
631
- observe: {
632
- enabled: false,
633
- rails: []
634
- },
635
- comments: {
636
- enabled: false,
637
- onViolation: "followup",
638
- mode: "declared"
639
- },
640
- supplyChain: {
641
- enabled: false
642
- },
643
- duplication: {
644
- enabled: false,
645
- minRun: MIN_RUN
646
- },
647
- obs: {
648
- globalSpool: false,
649
- includePayloads: DEFAULT_OBS.includePayloads,
650
- maxAttrChars: DEFAULT_OBS.maxAttrChars,
651
- sessionCostAlertUsd: DEFAULT_OBS.sessionCostAlertUsd,
652
- retentionDays: DEFAULT_OBS.retentionDays
653
- },
654
- untrustedContent: {
655
- mode: "frame",
656
- enabled: false,
657
- extraTools: [],
658
- extraCommandPatterns: []
659
- },
660
- planGate: {
661
- enabled: false,
662
- windowMinutes: 120
663
- },
664
- shell: {
665
- catastrophicAsk: true,
666
- stallDetection: false,
667
- stallRepeatThreshold: 3
668
- },
669
- intelligence: {
670
- gapFeedback: true,
671
- failureClassification: true,
672
- progressiveHandoff: true,
673
- progressiveContext: true,
674
- autopilot: true,
675
- idleTurnGate: false,
676
- budgetContinue: false,
677
- budgetContinueAfterLoops: 3,
678
- lessons: { ...DEFAULT_LESSONS_POLICY }
679
- },
680
- mcpPrime: [],
681
- bootstrapExtra: []
682
- };
683
-
684
- // src/platform/style.ts
685
- var COLORS = {
686
- structure: "#3d3a4a",
687
- accent: "#a78bfa",
688
- success: "#6ee7b7",
689
- warning: "#d4a574",
690
- error: "#f87171",
691
- info: "#93c5fd",
692
- textMain: "#f5f5f7",
693
- textMuted: "#9ca3af",
694
- textDim: "#6b7280"
695
- };
696
- var SYMBOLS = {
697
- check: "✔",
698
- cross: "✖",
699
- warning: "⚠",
700
- arrow: "→",
701
- arrowRight: "▸",
702
- dot: "•",
703
- bar: "│",
704
- rule: "══",
705
- dash: "──"
706
- };
707
- function rgb(hex) {
708
- const match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex.trim());
709
- if (!match) {
710
- return "255;255;255";
711
- }
712
- return [match[1], match[2], match[3]].map((part) => Number.parseInt(part, 16)).join(";");
713
- }
714
- var ESC = String.fromCharCode(27);
715
- var RESET = `${ESC}[0m`;
716
- function colorEnabled(env = process.env, argv = process.argv, isTty = process.stdout.isTTY === true) {
717
- if ("NO_COLOR" in env) {
718
- return false;
719
- }
720
- if (argv.includes("--no-color")) {
721
- return false;
722
- }
723
- return isTty;
724
- }
725
- var STATUS_COLOR = {
726
- ok: "success",
727
- warn: "warning",
728
- fail: "error",
729
- info: "info"
730
- };
731
- var STATUS_MARK = {
732
- ok: SYMBOLS.check,
733
- warn: SYMBOLS.warning,
734
- fail: SYMBOLS.cross,
735
- info: SYMBOLS.arrowRight
736
- };
737
- var KV_WIDTH = 16;
738
- function createStyle(enabled = colorEnabled()) {
739
- const wrap = (code, text) => enabled ? `${ESC}[${code}m${text}${RESET}` : text;
740
- const paint = (name, text) => wrap(`38;2;${rgb(COLORS[name])}`, text);
741
- return {
742
- enabled,
743
- paint,
744
- bold: (text) => wrap("1", text),
745
- dim: (text) => paint("textDim", text),
746
- heading: (text) => paint("accent", `${SYMBOLS.rule} ${text} ${SYMBOLS.rule}`),
747
- footer: (text) => paint("textDim", `${SYMBOLS.dash} ${text} ${SYMBOLS.dash}`),
748
- kv: (label, value, width = KV_WIDTH) => ` ${paint("textMuted", `${label}:`.padEnd(width))} ${value}`,
749
- status: (level, text) => `${paint(STATUS_COLOR[level], STATUS_MARK[level])} ${text}`
750
- };
751
- }
752
- var PLAIN = createStyle(false);
753
-
754
- // src/platform/screen.ts
755
- function render(screen, style) {
756
- const out = [style.heading(screen.title.toUpperCase())];
757
- if (screen.summary && screen.summary.length > 0) {
758
- out.push(` ${screen.summary.join(style.dim(` ${SYMBOLS.bar} `))}`);
759
- }
760
- const width = Math.max(KV_WIDTH, ...screen.sections.flatMap((section) => (section.rows ?? []).map((row) => row.label.length + 1)));
761
- for (const section of screen.sections) {
762
- out.push("");
763
- if (section.title) {
764
- out.push(style.paint("accent", section.title));
765
- }
766
- for (const row of section.rows ?? []) {
767
- const value = row.level ? style.status(row.level, row.value) : row.value;
768
- out.push(style.kv(row.label, value, width));
769
- }
770
- for (const line of section.lines ?? []) {
771
- out.push(line === "" ? "" : ` ${line}`);
772
- }
773
- }
774
- if (screen.footer) {
775
- out.push("", style.footer(screen.footer));
776
- }
777
- return out.join(`
778
- `);
779
- }
1
+ import {
2
+ applyCursorWiring,
3
+ renderCursorHooksDocument
4
+ } from "./chunks/compact-before-7sdmwswh.mjs";
5
+ import"./chunks/compact-before-j9y4jgn4.mjs";
6
+ import {
7
+ applyClaudeWiring
8
+ } from "./chunks/compact-before-w1293m4n.mjs";
9
+ import {
10
+ DEFAULTS,
11
+ PLAIN,
12
+ render
13
+ } from "./chunks/compact-before-49j320yp.mjs";
14
+ import {
15
+ __require,
16
+ claudeConfigDir,
17
+ cursorConfigDir,
18
+ projectConfigPath,
19
+ runtimeHome
20
+ } from "./chunks/compact-before-4jrq0sqs.mjs";
780
21
 
781
22
  // tools/init-project.ts
23
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
24
+ import { dirname, join, sep } from "node:path";
782
25
  class UsageError extends Error {
783
26
  }
784
27
  function parseFlags(args) {
@@ -809,7 +52,7 @@ function usageText(style = PLAIN) {
809
52
  return render(usageScreen(), style);
810
53
  }
811
54
  function launcherPath(home = runtimeHome()) {
812
- return join4(home, "bin", "tlc-exec.mjs");
55
+ return join(home, "bin", "tlc-exec.mjs");
813
56
  }
814
57
  var SHIM_COMMAND = { command: "node", argsPrefix: [] };
815
58
  var CURSOR_SHIM_SPECS = [
@@ -853,14 +96,14 @@ function claudeShimEntries(launcher) {
853
96
  ...spec.loopLimit !== undefined ? { loopLimit: spec.loopLimit } : {}
854
97
  }));
855
98
  }
856
- var PROJECT_SHIMS = [join4(".cursor", "hooks.json"), join4(".claude", "settings.json")];
99
+ var PROJECT_SHIMS = [join(".cursor", "hooks.json"), join(".claude", "settings.json")];
857
100
  var GITIGNORE_STATE = ".tlc/harness/state/";
858
101
  function gitignoreEntries() {
859
102
  return [GITIGNORE_STATE, ...PROJECT_SHIMS.map((path) => path.split(sep).join("/"))];
860
103
  }
861
104
  function mergeGitignore(root) {
862
- const path = join4(root, ".gitignore");
863
- const existing = existsSync3(path) ? readFileSync3(path, "utf8") : "";
105
+ const path = join(root, ".gitignore");
106
+ const existing = existsSync(path) ? readFileSync(path, "utf8") : "";
864
107
  const lines = existing.split(`
865
108
  `);
866
109
  const missing = gitignoreEntries().filter((entry) => !lines.includes(entry));
@@ -882,15 +125,15 @@ function resolvePolicy(root, flags, stdinText) {
882
125
  }
883
126
  return JSON.parse(stdinText);
884
127
  }
885
- if (!flags.minimal && !flags.stdinJson && existsSync3(projectConfigPath(root))) {
886
- return JSON.parse(readFileSync3(projectConfigPath(root), "utf8"));
128
+ if (!flags.minimal && !flags.stdinJson && existsSync(projectConfigPath(root))) {
129
+ return JSON.parse(readFileSync(projectConfigPath(root), "utf8"));
887
130
  }
888
131
  return DEFAULTS;
889
132
  }
890
133
  function detectProviders(dirs = {}) {
891
134
  return {
892
- cursor: existsSync3(dirs.cursor ?? cursorConfigDir()),
893
- claude: existsSync3(dirs.claude ?? claudeConfigDir())
135
+ cursor: existsSync(dirs.cursor ?? cursorConfigDir()),
136
+ claude: existsSync(dirs.claude ?? claudeConfigDir())
894
137
  };
895
138
  }
896
139
  function buildPlan(root, flags, stdinText, presence) {
@@ -906,28 +149,28 @@ function buildPlan(root, flags, stdinText, presence) {
906
149
  function applyPlan(root, flags, presence, stdinText) {
907
150
  const policy = resolvePolicy(root, flags, stdinText);
908
151
  const configPath = projectConfigPath(root);
909
- mkdirSync3(dirname3(configPath), { recursive: true });
910
- writeFileSync3(configPath, `${JSON.stringify(policy, null, 2)}
152
+ mkdirSync(dirname(configPath), { recursive: true });
153
+ writeFileSync(configPath, `${JSON.stringify(policy, null, 2)}
911
154
  `);
912
155
  const launcher = launcherPath();
913
156
  const cursor = presence.cursor ? (() => {
914
157
  const result = applyCursorWiring({
915
- target: join4(root, ".cursor", "hooks.json"),
158
+ target: join(root, ".cursor", "hooks.json"),
916
159
  strategy: "replace",
917
160
  entries: cursorShimEntries(launcher)
918
161
  }, { force: flags.force });
919
162
  return { skipped: false, status: result.status, target: result.target };
920
163
  })() : { skipped: true };
921
164
  const claude = presence.claude ? (() => {
922
- const result = applyClaudeWiring(join4(root, ".claude", "settings.json"), claudeShimEntries(launcher));
165
+ const result = applyClaudeWiring(join(root, ".claude", "settings.json"), claudeShimEntries(launcher));
923
166
  return {
924
167
  skipped: false,
925
168
  status: result.ok ? result.changed ? "written" : "unchanged" : "failed",
926
- target: join4(root, ".claude", "settings.json")
169
+ target: join(root, ".claude", "settings.json")
927
170
  };
928
171
  })() : { skipped: true };
929
172
  const gitignore = mergeGitignore(root);
930
- writeFileSync3(join4(root, ".gitignore"), gitignore.text);
173
+ writeFileSync(join(root, ".gitignore"), gitignore.text);
931
174
  return { configPath, cursor, claude };
932
175
  }
933
176
  async function readStdin() {