@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 +19 -7
- package/dist/daemon/index.js +1 -1
- package/dist/index.js +129 -6
- package/package.json +1 -1
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:
|
|
4794
|
-
stdout:
|
|
4795
|
-
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:
|
|
4828
|
-
stdout:
|
|
4829
|
-
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.
|
|
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",
|
package/dist/daemon/index.js
CHANGED
|
@@ -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.
|
|
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:
|
|
4889
|
-
stdout:
|
|
4890
|
-
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:
|
|
4923
|
-
stdout:
|
|
4924
|
-
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