@hasna/loops 0.3.24 → 0.3.25

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.
package/dist/cli/index.js CHANGED
@@ -4770,6 +4770,9 @@ function bounded(value, limit = EVIDENCE_CHARS) {
4770
4770
  return `${value.slice(0, limit)}
4771
4771
  [truncated ${value.length - limit} chars]`;
4772
4772
  }
4773
+ function redactedEvidence(value) {
4774
+ return redact(bounded(value));
4775
+ }
4773
4776
  function searchableText(run) {
4774
4777
  return [run.error, run.stderr, run.stdout].filter(Boolean).join(`
4775
4778
  `).toLowerCase();
@@ -4790,9 +4793,9 @@ function stableFailureFingerprint(run, classification) {
4790
4793
  function healthRun(run) {
4791
4794
  return {
4792
4795
  ...run,
4793
- error: bounded(run.error),
4794
- stdout: bounded(run.stdout),
4795
- stderr: bounded(run.stderr)
4796
+ error: redactedEvidence(run.error),
4797
+ stdout: redactedEvidence(run.stdout),
4798
+ stderr: redactedEvidence(run.stderr)
4796
4799
  };
4797
4800
  }
4798
4801
  function classifyRunFailure(run) {
@@ -4824,9 +4827,9 @@ function classifyRunFailure(run) {
4824
4827
  classification,
4825
4828
  fingerprint: stableFailureFingerprint(run, classification),
4826
4829
  evidence: {
4827
- error: bounded(run.error),
4828
- stdout: bounded(run.stdout),
4829
- stderr: bounded(run.stderr),
4830
+ error: redactedEvidence(run.error),
4831
+ stdout: redactedEvidence(run.stdout),
4832
+ stderr: redactedEvidence(run.stderr),
4830
4833
  exitCode: run.exitCode
4831
4834
  }
4832
4835
  };
@@ -5201,7 +5204,7 @@ function buildScriptInventoryReport(store, opts = {}) {
5201
5204
  // package.json
5202
5205
  var package_default = {
5203
5206
  name: "@hasna/loops",
5204
- version: "0.3.24",
5207
+ version: "0.3.25",
5205
5208
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
5206
5209
  type: "module",
5207
5210
  main: "dist/index.js",
@@ -5398,8 +5401,17 @@ function accountForRole(input, role, seed) {
5398
5401
  return input.verifierAccount;
5399
5402
  return rolePoolValue(input.accountPool, seed, role) ?? input.account;
5400
5403
  }
5404
+ function assertNativeAuthProfileSupport(input, provider) {
5405
+ if (provider === "codewith")
5406
+ return;
5407
+ const hasNativeAuthProfiles = Boolean(input.authProfile || input.authProfilePool?.length || input.workerAuthProfile || input.verifierAuthProfile);
5408
+ if (!hasNativeAuthProfiles)
5409
+ return;
5410
+ throw new Error(`authProfile, authProfilePool, workerAuthProfile, and verifierAuthProfile are supported only for provider codewith; use account/accountPool for ${provider} profile isolation`);
5411
+ }
5401
5412
  function agentTarget(input, prompt, role, seed) {
5402
5413
  const provider = input.provider ?? "codewith";
5414
+ assertNativeAuthProfileSupport(input, provider);
5403
5415
  const sandbox = input.sandbox ?? (provider === "codewith" || provider === "codex" ? "danger-full-access" : provider === "cursor" ? "disabled" : undefined);
5404
5416
  return {
5405
5417
  type: "agent",
@@ -4525,7 +4525,7 @@ function enableStartup(result) {
4525
4525
  // package.json
4526
4526
  var package_default = {
4527
4527
  name: "@hasna/loops",
4528
- version: "0.3.24",
4528
+ version: "0.3.25",
4529
4529
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
4530
4530
  type: "module",
4531
4531
  main: "dist/index.js",
package/dist/index.js CHANGED
@@ -4330,8 +4330,17 @@ function accountForRole(input, role, seed) {
4330
4330
  return input.verifierAccount;
4331
4331
  return rolePoolValue(input.accountPool, seed, role) ?? input.account;
4332
4332
  }
4333
+ function assertNativeAuthProfileSupport(input, provider) {
4334
+ if (provider === "codewith")
4335
+ return;
4336
+ const hasNativeAuthProfiles = Boolean(input.authProfile || input.authProfilePool?.length || input.workerAuthProfile || input.verifierAuthProfile);
4337
+ if (!hasNativeAuthProfiles)
4338
+ return;
4339
+ throw new Error(`authProfile, authProfilePool, workerAuthProfile, and verifierAuthProfile are supported only for provider codewith; use account/accountPool for ${provider} profile isolation`);
4340
+ }
4333
4341
  function agentTarget(input, prompt, role, seed) {
4334
4342
  const provider = input.provider ?? "codewith";
4343
+ assertNativeAuthProfileSupport(input, provider);
4335
4344
  const sandbox = input.sandbox ?? (provider === "codewith" || provider === "codex" ? "danger-full-access" : provider === "cursor" ? "disabled" : undefined);
4336
4345
  return {
4337
4346
  type: "agent",
@@ -4842,6 +4851,117 @@ function runDoctor(store) {
4842
4851
  }
4843
4852
  // src/lib/health.ts
4844
4853
  import { createHash } from "crypto";
4854
+
4855
+ // src/lib/format.ts
4856
+ var TEXT_OUTPUT_LIMIT = 32 * 1024;
4857
+ var SENSITIVE_PAYLOAD_KEYS = new Set(["env", "error", "prompt", "reason", "stderr", "stdout"]);
4858
+ function redact(value, visible = 0) {
4859
+ if (!value)
4860
+ return value;
4861
+ if (value.length <= visible)
4862
+ return value;
4863
+ if (visible <= 0)
4864
+ return `[redacted ${value.length} chars]`;
4865
+ return `${value.slice(0, visible)}... [redacted ${value.length - visible} chars]`;
4866
+ }
4867
+ function truncateTextOutput(value) {
4868
+ if (value.length <= TEXT_OUTPUT_LIMIT)
4869
+ return value;
4870
+ return `${value.slice(0, TEXT_OUTPUT_LIMIT)}
4871
+ [truncated ${value.length - TEXT_OUTPUT_LIMIT} chars]`;
4872
+ }
4873
+ function redactSensitivePayload(value, key) {
4874
+ if (key && SENSITIVE_PAYLOAD_KEYS.has(key)) {
4875
+ if (typeof value === "string")
4876
+ return redact(value);
4877
+ if (value === undefined || value === null)
4878
+ return value;
4879
+ return "[redacted]";
4880
+ }
4881
+ if (Array.isArray(value))
4882
+ return value.map((item) => redactSensitivePayload(item));
4883
+ if (value && typeof value === "object") {
4884
+ return Object.fromEntries(Object.entries(value).map(([entryKey, entryValue]) => [entryKey, redactSensitivePayload(entryValue, entryKey)]));
4885
+ }
4886
+ return value;
4887
+ }
4888
+ function textOutputBlocks(value, opts = {}) {
4889
+ const indent = opts.indent ?? "";
4890
+ const nested = `${indent} `;
4891
+ const blocks = [];
4892
+ for (const [label, output] of [
4893
+ ["stdout", value.stdout],
4894
+ ["stderr", value.stderr]
4895
+ ]) {
4896
+ if (!output)
4897
+ continue;
4898
+ blocks.push(`${indent}${label}:`);
4899
+ for (const line of truncateTextOutput(output).replace(/\s+$/, "").split(/\r?\n/)) {
4900
+ blocks.push(`${nested}${line}`);
4901
+ }
4902
+ }
4903
+ return blocks;
4904
+ }
4905
+ function publicLoop(loop) {
4906
+ const target = loop.target.type === "command" ? { ...loop.target, env: loop.target.env ? "[redacted]" : undefined } : loop.target.type === "agent" ? { ...loop.target, prompt: redact(loop.target.prompt) } : loop.target;
4907
+ return {
4908
+ ...loop,
4909
+ target
4910
+ };
4911
+ }
4912
+ function publicRun(run, showOutput = false) {
4913
+ return {
4914
+ ...run,
4915
+ stdout: showOutput ? run.stdout : run.stdout ? `[redacted ${run.stdout.length} chars]` : undefined,
4916
+ stderr: showOutput ? run.stderr : run.stderr ? `[redacted ${run.stderr.length} chars]` : undefined
4917
+ };
4918
+ }
4919
+ function publicExecutorResult(result, showOutput = false) {
4920
+ return {
4921
+ ...result,
4922
+ stdout: showOutput ? result.stdout : result.stdout ? `[redacted ${result.stdout.length} chars]` : undefined,
4923
+ stderr: showOutput ? result.stderr : result.stderr ? `[redacted ${result.stderr.length} chars]` : undefined,
4924
+ error: redact(result.error)
4925
+ };
4926
+ }
4927
+ function publicWorkflow(workflow) {
4928
+ return {
4929
+ ...workflow,
4930
+ steps: workflow.steps.map((step) => ({
4931
+ ...step,
4932
+ target: step.target.type === "agent" ? { ...step.target, prompt: redact(step.target.prompt) } : step.target.type === "command" && step.target.env ? { ...step.target, env: "[redacted]" } : step.target
4933
+ }))
4934
+ };
4935
+ }
4936
+ function publicWorkflowRun(run) {
4937
+ return { ...run, error: redact(run.error) };
4938
+ }
4939
+ function publicWorkflowStepRun(run, showOutput = false) {
4940
+ return {
4941
+ ...run,
4942
+ stdout: showOutput ? run.stdout : run.stdout ? `[redacted ${run.stdout.length} chars]` : undefined,
4943
+ stderr: showOutput ? run.stderr : run.stderr ? `[redacted ${run.stderr.length} chars]` : undefined,
4944
+ error: redact(run.error)
4945
+ };
4946
+ }
4947
+ function publicWorkflowEvent(event) {
4948
+ return { ...event, payload: redactSensitivePayload(event.payload) };
4949
+ }
4950
+ function publicGoal(goal) {
4951
+ return {
4952
+ ...goal,
4953
+ objective: redact(goal.objective, 120)
4954
+ };
4955
+ }
4956
+ function publicGoalRun(run) {
4957
+ return {
4958
+ ...run,
4959
+ evidence: redactSensitivePayload(run.evidence),
4960
+ rawResponse: redactSensitivePayload(run.rawResponse)
4961
+ };
4962
+ }
4963
+
4964
+ // src/lib/health.ts
4845
4965
  var EVIDENCE_CHARS = 2000;
4846
4966
  var FINGERPRINT_EVIDENCE_CHARS = 120;
4847
4967
  var CLASSIFICATIONS = [
@@ -4865,6 +4985,9 @@ function bounded(value, limit = EVIDENCE_CHARS) {
4865
4985
  return `${value.slice(0, limit)}
4866
4986
  [truncated ${value.length - limit} chars]`;
4867
4987
  }
4988
+ function redactedEvidence(value) {
4989
+ return redact(bounded(value));
4990
+ }
4868
4991
  function searchableText(run) {
4869
4992
  return [run.error, run.stderr, run.stdout].filter(Boolean).join(`
4870
4993
  `).toLowerCase();
@@ -4885,9 +5008,9 @@ function stableFailureFingerprint(run, classification) {
4885
5008
  function healthRun(run) {
4886
5009
  return {
4887
5010
  ...run,
4888
- error: bounded(run.error),
4889
- stdout: bounded(run.stdout),
4890
- stderr: bounded(run.stderr)
5011
+ error: redactedEvidence(run.error),
5012
+ stdout: redactedEvidence(run.stdout),
5013
+ stderr: redactedEvidence(run.stderr)
4891
5014
  };
4892
5015
  }
4893
5016
  function classifyRunFailure(run) {
@@ -4919,9 +5042,9 @@ function classifyRunFailure(run) {
4919
5042
  classification,
4920
5043
  fingerprint: stableFailureFingerprint(run, classification),
4921
5044
  evidence: {
4922
- error: bounded(run.error),
4923
- stdout: bounded(run.stdout),
4924
- stderr: bounded(run.stderr),
5045
+ error: redactedEvidence(run.error),
5046
+ stdout: redactedEvidence(run.stdout),
5047
+ stderr: redactedEvidence(run.stderr),
4925
5048
  exitCode: run.exitCode
4926
5049
  }
4927
5050
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/loops",
3
- "version": "0.3.24",
3
+ "version": "0.3.25",
4
4
  "description": "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",