@zhivex-ai/harness 1.4.1 → 1.6.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.
- package/CHANGELOG.md +23 -0
- package/README.md +1 -1
- package/SUPPORT.md +1 -1
- package/contracts/stable-api-signatures.json +7 -7
- package/dist/acp-cli.js +10 -10
- package/dist/approvals/approval-diff.d.ts +2 -1
- package/dist/approvals/approval-preview.d.ts +1 -1
- package/dist/approvals/auto-approve.d.ts +137 -0
- package/dist/audit/index.js +6 -6
- package/dist/{audit-pack-e4vaq7np.js → audit-pack-fckpqfsb.js} +3 -3
- package/dist/{cli-1cf4dcnj.js → cli-84en174d.js} +14 -8
- package/dist/{cli-entry-3s63zn4w.js → cli-entry-10th5awp.js} +16 -15
- package/dist/{cli-entry-a890x3kq.js → cli-entry-4g2ewcnw.js} +15 -5
- package/dist/{cli-entry-7f0cen32.js → cli-entry-6amx4mcc.js} +209 -68
- package/dist/{cli-entry-rgs6bxmy.js → cli-entry-z1pbjrg4.js} +2 -2
- package/dist/cli.js +2 -2
- package/dist/compat/code-support.js +8 -8
- package/dist/engine/acp.js +11 -11
- package/dist/engine/client.js +10 -10
- package/dist/engine/desktop-state-v1.js +6 -6
- package/dist/engine/index.js +15 -15
- package/dist/engine/mcp-stdio-v1.js +5 -5
- package/dist/engine/service.js +11 -11
- package/dist/hostile-repository-demo.js +235 -84
- package/dist/{index-mv8sb1ns.js → index-1pn0ecs4.js} +55 -13
- package/dist/{index-dtb2c6ds.js → index-2r4f0p4n.js} +2 -2
- package/dist/{index-6599mpmy.js → index-4mn6m3bq.js} +3 -3
- package/dist/{index-xdbkcccf.js → index-6dxrbnxm.js} +2 -2
- package/dist/{index-crta5wzv.js → index-74f9yhfh.js} +4 -4
- package/dist/{index-f6mqa5gk.js → index-amjttjaj.js} +11 -39
- package/dist/{index-wm9xeq1n.js → index-bt2p8x7r.js} +1 -1
- package/dist/{index-sk3cap35.js → index-eps3c3g6.js} +1 -1
- package/dist/{index-zxg4ve4j.js → index-fqqz1yt8.js} +77 -4
- package/dist/{index-02pqtbbg.js → index-paf7z8kn.js} +10 -10
- package/dist/{index-0zs2dz26.js → index-pf73y4gt.js} +18 -9
- package/dist/{index-74kkpyqk.js → index-rgqzdgv6.js} +12 -6
- package/dist/{index-4fx5f3k5.js → index-rz7wmp71.js} +16 -15
- package/dist/{index-d9zkmhz3.js → index-w0m1nckc.js} +127 -28
- package/dist/{index-sstgcsr0.js → index-yx52bt4a.js} +1 -1
- package/dist/{index-j6zxnc8m.js → index-zrz4rs7p.js} +5 -5
- package/dist/index.js +14 -14
- package/dist/integrations/mcp-stdio-tools.d.ts +4 -1
- package/dist/providers/bedrock.d.ts +1 -1
- package/dist/review/reveal-invisible.d.ts +13 -0
- package/dist/runtime/budget-ledger-scope.d.ts +14 -0
- package/dist/service-cli.js +11 -11
- package/dist/{service-client-cli-eqrdc9zq.js → service-client-cli-pp5z4dmf.js} +4 -4
- package/dist/tools/workspace.d.ts +2 -2
- package/dist/verify-historical-migrations.js +240 -86
- package/dist/workspace/edit-contracts.d.ts +2 -2
- package/dist/workspace/path-policy.d.ts +2 -1
- package/dist/workspace/text-integrity.d.ts +19 -0
- package/dist/workspace/workspace.d.ts +21 -3
- package/dist/zhx.js +2 -2
- package/docs/AUTO_APPROVE.md +51 -0
- package/docs/AZURE_OPENAI.md +4 -4
- package/docs/BEDROCK.md +4 -4
- package/docs/CLI.md +13 -0
- package/docs/CODE_RELEASE.md +36 -6
- package/docs/CODE_WEB_TASKS.md +1 -1
- package/docs/CREDENTIALS.md +1 -1
- package/docs/DURABLE_OPERATIONS.md +1 -1
- package/docs/ENGINE_API.md +1 -1
- package/docs/EXTENSIBILITY.md +7 -3
- package/docs/FIRST_USE.md +6 -6
- package/docs/MINIMUM_TASK_AUTHORITY.md +5 -5
- package/docs/PROJECT_MEMORY.md +1 -1
- package/docs/PUBLIC_SECURITY.md +14 -1
- package/docs/REPOSITORY_EDITING.md +1 -1
- package/docs/TOOL_POLICY.md +7 -1
- package/docs/VERTEX.md +2 -2
- package/docs/WEB_LIMITS.md +2 -2
- package/docs/adr/0002-isolated-mcp-stdio.md +2 -2
- package/evaluations/representative-assembly-matrix.json +37 -1
- package/examples/README.md +3 -3
- package/package.json +16 -15
|
@@ -96,8 +96,8 @@ var quarantineFileInputSchema = z.strictObject({
|
|
|
96
96
|
});
|
|
97
97
|
var restoreFileInputSchema = z.strictObject({
|
|
98
98
|
quarantineId: z.string().min(1).max(200).regex(/^[A-Za-z0-9._:-]+$/),
|
|
99
|
-
destination: workspaceFilePathSchema.
|
|
100
|
-
expectedDigest: fileDigestSchema.
|
|
99
|
+
destination: workspaceFilePathSchema.describe("Required workspace path for the quarantined bytes. Restore does not fall back to the original path."),
|
|
100
|
+
expectedDigest: fileDigestSchema.describe("Required sha256 of the quarantined bytes the operator reviewed.")
|
|
101
101
|
});
|
|
102
102
|
var mutationOperationSchema = z.enum(["create", "update", "move", "quarantine", "restore"]);
|
|
103
103
|
var mutationAuditEntrySchema = z.strictObject({
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createHarnessClientAdapter
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-paf7z8kn.js";
|
|
4
4
|
import {
|
|
5
5
|
harnessPolicyDecisionEventSchema
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-bt2p8x7r.js";
|
|
7
7
|
import {
|
|
8
8
|
openCliSessionStore
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-fqqz1yt8.js";
|
|
10
10
|
import {
|
|
11
11
|
SqliteDatabase
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-6dxrbnxm.js";
|
|
13
13
|
import {
|
|
14
14
|
harnessClientRequestSchema,
|
|
15
15
|
streamEventDocument
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
harnessExecutionSession
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-w0m1nckc.js";
|
|
4
4
|
import {
|
|
5
5
|
defaultHarnessNamespace
|
|
6
6
|
} from "./index-1265j7t2.js";
|
|
@@ -9,20 +9,23 @@ import {
|
|
|
9
9
|
TASK_BUDGET_KEY,
|
|
10
10
|
TaskBudget,
|
|
11
11
|
USAGE_LEDGER_KEY,
|
|
12
|
+
bindBudgetLedgerStore,
|
|
13
|
+
budgetLedgerScope,
|
|
12
14
|
ensurePrivateDatabase,
|
|
13
15
|
estimateRequestTokens,
|
|
14
16
|
inspectRuntimeDiagnostics,
|
|
15
17
|
inspectRuntimeManifest,
|
|
16
18
|
inspectTaskBudgetSummary,
|
|
17
19
|
inspectUsageLedger,
|
|
20
|
+
isReservedBudgetNamespace,
|
|
18
21
|
protectStateFromGit,
|
|
19
22
|
readTaskAcceptanceLedger,
|
|
20
23
|
validateStateDirectory,
|
|
21
24
|
withRuntimeInstruction
|
|
22
|
-
} from "./index-
|
|
25
|
+
} from "./index-fqqz1yt8.js";
|
|
23
26
|
import {
|
|
24
27
|
SqliteDatabase
|
|
25
|
-
} from "./index-
|
|
28
|
+
} from "./index-6dxrbnxm.js";
|
|
26
29
|
import {
|
|
27
30
|
HarnessConfigError,
|
|
28
31
|
HarnessStateConflictError,
|
|
@@ -869,37 +872,7 @@ import {
|
|
|
869
872
|
createSqliteAgentRunStore
|
|
870
873
|
} from "@zhivex-ai/agents/ops";
|
|
871
874
|
import { createAgentRunLedger } from "@zhivex-ai/agents/control-plane";
|
|
872
|
-
var
|
|
873
|
-
tenantId: config.scope.tenantId,
|
|
874
|
-
...config.scope.userId ? { userId: config.scope.userId } : {},
|
|
875
|
-
namespace: "__zhivex_budget__"
|
|
876
|
-
});
|
|
877
|
-
var withBudgetLedgerStore = (primary, budget, config) => {
|
|
878
|
-
const scope = budgetScopeFor(config);
|
|
879
|
-
const budgetScope = (value) => value?.namespace === scope.namespace && value.tenantId === scope.tenantId && (value.userId ?? undefined) === (scope.userId ?? undefined);
|
|
880
|
-
const assertId = (id) => {
|
|
881
|
-
if (!/^budget_[a-f0-9]{64}$/.test(id))
|
|
882
|
-
throw new HarnessStateConflictError("Invalid budget ledger identity.");
|
|
883
|
-
};
|
|
884
|
-
return {
|
|
885
|
-
...primary,
|
|
886
|
-
load: async (id, requestedScope) => {
|
|
887
|
-
if (!budgetScope(requestedScope))
|
|
888
|
-
return primary.load(id, requestedScope);
|
|
889
|
-
assertId(id);
|
|
890
|
-
return budget.load(id, requestedScope);
|
|
891
|
-
},
|
|
892
|
-
save: async (state, options) => {
|
|
893
|
-
if (!budgetScope(state.scope))
|
|
894
|
-
return primary.save(state, options);
|
|
895
|
-
assertId(state.runId);
|
|
896
|
-
if (state.provider !== "zhivex" || state.modelId !== "budget-coordinator" || state.metadata?.budgetCoordinator !== true) {
|
|
897
|
-
throw new HarnessStateConflictError("Only SDK budget ledger states may use the reserved namespace.");
|
|
898
|
-
}
|
|
899
|
-
return budget.save(state, options);
|
|
900
|
-
}
|
|
901
|
-
};
|
|
902
|
-
};
|
|
875
|
+
var withBudgetLedgerStore = (primary, budget, config) => bindBudgetLedgerStore(primary, config.scope, budget);
|
|
903
876
|
var HARNESS_SQLITE_FILE = "operations.sqlite";
|
|
904
877
|
var HARNESS_OPERATIONS_SCHEMA_VERSION = 1;
|
|
905
878
|
var TERMINAL_RUN_STATUSES = ["completed", "failed", "cancelled", "timed_out"];
|
|
@@ -1154,13 +1127,12 @@ var migrateLegacyFileRuns = async (directory, target, config) => {
|
|
|
1154
1127
|
return result;
|
|
1155
1128
|
};
|
|
1156
1129
|
var openHarnessPersistence = async (config, options = {}) => {
|
|
1157
|
-
|
|
1158
|
-
throw new HarnessStateConflictError("The budget ledger namespace is reserved.");
|
|
1130
|
+
const budgetScope = budgetLedgerScope(config.scope);
|
|
1159
1131
|
await validateStateDirectory(config.workspace, config.stateDirectory);
|
|
1160
1132
|
await ensurePrivateStateDirectory(config.stateDirectory);
|
|
1161
1133
|
await protectStateFromGit(config.workspace, config.stateDirectory);
|
|
1162
1134
|
if (config.storeBackend === "file") {
|
|
1163
|
-
const store = withBudgetLedgerStore(createFileAgentRunStore({ directory: config.stateDirectory, scope: config.scope }), createFileAgentRunStore({ directory: config.stateDirectory, scope:
|
|
1135
|
+
const store = withBudgetLedgerStore(createFileAgentRunStore({ directory: config.stateDirectory, scope: config.scope }), createFileAgentRunStore({ directory: config.stateDirectory, scope: budgetScope }), config);
|
|
1164
1136
|
const migration = shouldMigrateLegacyRuns(config, options.migrateLegacyFileStore) ? await migrateLegacyFileRuns(config.stateDirectory, store, config) : emptyMigration();
|
|
1165
1137
|
return {
|
|
1166
1138
|
backend: "file",
|
|
@@ -1205,7 +1177,7 @@ var openHarnessPersistence = async (config, options = {}) => {
|
|
|
1205
1177
|
database.exec("PRAGMA foreign_keys = ON");
|
|
1206
1178
|
await chmod(databasePath, 384);
|
|
1207
1179
|
const databaseLike = sqliteAdapter(database);
|
|
1208
|
-
const store = withBudgetLedgerStore(createSqliteAgentRunStore({ db: databaseLike, scope: config.scope, history: "incremental" }), createSqliteAgentRunStore({ db: databaseLike, scope:
|
|
1180
|
+
const store = withBudgetLedgerStore(createSqliteAgentRunStore({ db: databaseLike, scope: config.scope, history: "incremental" }), createSqliteAgentRunStore({ db: databaseLike, scope: budgetScope }), config);
|
|
1209
1181
|
database.exec(`CREATE TRIGGER IF NOT EXISTS zhivex_task_budget_retain_run
|
|
1210
1182
|
BEFORE DELETE ON zhivex_agent_runs
|
|
1211
1183
|
WHEN json_type(OLD.state_json, '$.metadata.zhivexTaskBudgetAccountV1') IS NOT NULL
|
|
@@ -1302,7 +1274,7 @@ var projectMemoryBinding = (workspace, scope) => {
|
|
|
1302
1274
|
segment(scope.userId);
|
|
1303
1275
|
if (scope.namespace !== undefined)
|
|
1304
1276
|
segment(scope.namespace);
|
|
1305
|
-
if (scope.namespace
|
|
1277
|
+
if (isReservedBudgetNamespace(scope.namespace))
|
|
1306
1278
|
throw new HarnessConfigError("Reserved memory namespace.");
|
|
1307
1279
|
const key = (kind, value) => createHash4("sha256").update(kind).update("\x00").update(value).digest("hex");
|
|
1308
1280
|
const workspaceKey = key("workspace", workspace);
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
taskAcceptanceOutcome,
|
|
6
6
|
taskCheckReceiptSchema,
|
|
7
7
|
workspaceFilePathSchema
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-6dxrbnxm.js";
|
|
9
9
|
import {
|
|
10
10
|
HarnessConfigError,
|
|
11
11
|
HarnessStateConflictError,
|
|
@@ -1604,6 +1604,79 @@ function taskAcceptanceCheckpointStore(store, runId, ledger) {
|
|
|
1604
1604
|
import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
|
|
1605
1605
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
1606
1606
|
import { z as z7 } from "zod";
|
|
1607
|
+
|
|
1608
|
+
// src/runtime/budget-ledger-scope.ts
|
|
1609
|
+
var BUDGET_LEDGER_NAMESPACE = "__zhivex_budget__";
|
|
1610
|
+
var BUDGET_OWNER_NAMESPACE_KEY = "budgetOwnerNamespace";
|
|
1611
|
+
var isReservedBudgetNamespace = (namespace) => namespace === BUDGET_LEDGER_NAMESPACE || (namespace?.startsWith(`${BUDGET_LEDGER_NAMESPACE}:`) ?? false);
|
|
1612
|
+
var budgetLedgerNamespace = (namespace) => {
|
|
1613
|
+
if (!namespace || isReservedBudgetNamespace(namespace)) {
|
|
1614
|
+
throw new HarnessStateConflictError("The budget ledger namespace is reserved.");
|
|
1615
|
+
}
|
|
1616
|
+
return `${BUDGET_LEDGER_NAMESPACE}:${namespace}`;
|
|
1617
|
+
};
|
|
1618
|
+
var budgetLedgerScope = (scope) => {
|
|
1619
|
+
if (scope.namespace && isReservedBudgetNamespace(scope.namespace)) {
|
|
1620
|
+
throw new HarnessStateConflictError("The budget ledger namespace is reserved.");
|
|
1621
|
+
}
|
|
1622
|
+
return {
|
|
1623
|
+
tenantId: scope.tenantId,
|
|
1624
|
+
...scope.userId ? { userId: scope.userId } : {},
|
|
1625
|
+
namespace: scope.namespace ? budgetLedgerNamespace(scope.namespace) : `${BUDGET_LEDGER_NAMESPACE}:`
|
|
1626
|
+
};
|
|
1627
|
+
};
|
|
1628
|
+
var sameIdentity = (left, right) => left?.tenantId === right.tenantId && (left.userId ?? undefined) === (right.userId ?? undefined);
|
|
1629
|
+
var bindBudgetLedgerStore = (primary, scope, budget = primary) => {
|
|
1630
|
+
const bound = budgetLedgerScope(scope);
|
|
1631
|
+
const ownerNamespace = scope.namespace ?? "";
|
|
1632
|
+
const isSdkBudget = (value) => sameIdentity(value, bound) && value?.namespace === BUDGET_LEDGER_NAMESPACE;
|
|
1633
|
+
const isBoundBudget = (value) => sameIdentity(value, bound) && value?.namespace === bound.namespace;
|
|
1634
|
+
const assertId = (id) => {
|
|
1635
|
+
if (!/^budget_[a-f0-9]{64}$/.test(id))
|
|
1636
|
+
throw new HarnessStateConflictError("Invalid budget ledger identity.");
|
|
1637
|
+
};
|
|
1638
|
+
const bindState = (state) => {
|
|
1639
|
+
const metadata = { ...state.metadata ?? {} };
|
|
1640
|
+
const owner = metadata[BUDGET_OWNER_NAMESPACE_KEY];
|
|
1641
|
+
if (owner !== undefined && owner !== ownerNamespace) {
|
|
1642
|
+
throw new HarnessStateConflictError("Budget ledger is bound to another namespace.");
|
|
1643
|
+
}
|
|
1644
|
+
return {
|
|
1645
|
+
...state,
|
|
1646
|
+
scope: bound,
|
|
1647
|
+
metadata: { ...metadata, [BUDGET_OWNER_NAMESPACE_KEY]: ownerNamespace }
|
|
1648
|
+
};
|
|
1649
|
+
};
|
|
1650
|
+
const assertStored = (state) => {
|
|
1651
|
+
if (!state)
|
|
1652
|
+
return state;
|
|
1653
|
+
const owner = state.metadata?.[BUDGET_OWNER_NAMESPACE_KEY];
|
|
1654
|
+
if (state.scope?.namespace !== bound.namespace || owner !== ownerNamespace) {
|
|
1655
|
+
throw new HarnessStateConflictError("Budget ledger is not bound to this namespace.");
|
|
1656
|
+
}
|
|
1657
|
+
return state;
|
|
1658
|
+
};
|
|
1659
|
+
return {
|
|
1660
|
+
...primary,
|
|
1661
|
+
load: async (id, requestedScope) => {
|
|
1662
|
+
if (!isSdkBudget(requestedScope) && !isBoundBudget(requestedScope))
|
|
1663
|
+
return primary.load(id, requestedScope);
|
|
1664
|
+
assertId(id);
|
|
1665
|
+
return assertStored(await budget.load(id, bound));
|
|
1666
|
+
},
|
|
1667
|
+
save: async (state, options) => {
|
|
1668
|
+
if (!isSdkBudget(state.scope) && !isBoundBudget(state.scope))
|
|
1669
|
+
return primary.save(state, options);
|
|
1670
|
+
assertId(state.runId);
|
|
1671
|
+
if (state.provider !== "zhivex" || state.modelId !== "budget-coordinator" || state.metadata?.budgetCoordinator !== true) {
|
|
1672
|
+
throw new HarnessStateConflictError("Only SDK budget ledger states may use the reserved namespace.");
|
|
1673
|
+
}
|
|
1674
|
+
return budget.save(bindState(state), options);
|
|
1675
|
+
}
|
|
1676
|
+
};
|
|
1677
|
+
};
|
|
1678
|
+
|
|
1679
|
+
// src/runtime/task-budget.ts
|
|
1607
1680
|
import {
|
|
1608
1681
|
createAgentBudgetCoordinator,
|
|
1609
1682
|
fingerprintAgentHarness as fingerprintAgentHarness2,
|
|
@@ -1751,10 +1824,10 @@ class TaskBudget {
|
|
|
1751
1824
|
this.accountRunId = TaskBudget.accountId(scope, taskId);
|
|
1752
1825
|
this.policy = structuredClone(account.policy);
|
|
1753
1826
|
const budgetId = this.accountRunId;
|
|
1754
|
-
this.coordinator = createAgentBudgetCoordinator({ store, scope, budgetId, limits: this.policy.limits });
|
|
1827
|
+
this.coordinator = createAgentBudgetCoordinator({ store: bindBudgetLedgerStore(store, scope), scope, budgetId, limits: this.policy.limits });
|
|
1755
1828
|
this.coordinatorId = this.coordinator.id;
|
|
1756
1829
|
this.budgetRunId = `budget_${fingerprintAgentHarness2({ budgetId, scope }).slice("sha256:".length)}`;
|
|
1757
|
-
this.budgetScope =
|
|
1830
|
+
this.budgetScope = budgetLedgerScope(scope);
|
|
1758
1831
|
}
|
|
1759
1832
|
static accountId(scope, taskId) {
|
|
1760
1833
|
return `task_budget_${fingerprintAgentHarness2({ scope, taskId }).slice("sha256:".length)}`;
|
|
@@ -2268,4 +2341,4 @@ class TaskBudget {
|
|
|
2268
2341
|
}
|
|
2269
2342
|
}
|
|
2270
2343
|
|
|
2271
|
-
export { protectStateFromGit, validateStateDirectory, HARNESS_SESSION_INDEX_FILE, HARNESS_SESSION_SCHEMA_VERSION, SESSION_RUN_STATUSES, TERMINAL_SESSION_RUN_STATUSES, ensurePrivateDatabase, openCliSessionStore, openSessionStore, withRuntimeInstruction, withFreshSystemInstructions, inspectRuntimeDiagnostics, inspectRuntimeManifest, estimateContextTokens, measureContext, MODEL_BUDGET_KEY, estimateRequestTokens, workBudgetReached, createModelBudget, USAGE_LEDGER_KEY, usagePricingSchema, inspectUsageLedger, formatUsageLedger, runUsageLedgerWithPolicy, UsageLedger, inspectTaskMonetaryUsage, taskAcceptanceContractSchema, compileTaskAcceptanceContract, TASK_ACCEPTANCE_KEY, TASK_ACCEPTANCE_EVIDENCE_KEY, readTaskAcceptanceLedger, nextTaskAcceptanceLedger, persistTaskAcceptanceRevision, taskAcceptanceCheckpointStore, TASK_BUDGET_KEY, TASK_BUDGET_ACCOUNT_KEY, inspectTaskBudgetSummary, assertTaskBudgetBackupLinks, TaskBudget };
|
|
2344
|
+
export { protectStateFromGit, validateStateDirectory, HARNESS_SESSION_INDEX_FILE, HARNESS_SESSION_SCHEMA_VERSION, SESSION_RUN_STATUSES, TERMINAL_SESSION_RUN_STATUSES, ensurePrivateDatabase, openCliSessionStore, openSessionStore, withRuntimeInstruction, withFreshSystemInstructions, inspectRuntimeDiagnostics, inspectRuntimeManifest, estimateContextTokens, measureContext, MODEL_BUDGET_KEY, estimateRequestTokens, workBudgetReached, createModelBudget, USAGE_LEDGER_KEY, usagePricingSchema, inspectUsageLedger, formatUsageLedger, runUsageLedgerWithPolicy, UsageLedger, inspectTaskMonetaryUsage, taskAcceptanceContractSchema, compileTaskAcceptanceContract, TASK_ACCEPTANCE_KEY, TASK_ACCEPTANCE_EVIDENCE_KEY, readTaskAcceptanceLedger, nextTaskAcceptanceLedger, persistTaskAcceptanceRevision, taskAcceptanceCheckpointStore, BUDGET_LEDGER_NAMESPACE, BUDGET_OWNER_NAMESPACE_KEY, isReservedBudgetNamespace, budgetLedgerNamespace, budgetLedgerScope, bindBudgetLedgerStore, TASK_BUDGET_KEY, TASK_BUDGET_ACCOUNT_KEY, inspectTaskBudgetSummary, assertTaskBudgetBackupLinks, TaskBudget };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
openWorkspaceCheckpointStore
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-4mn6m3bq.js";
|
|
4
4
|
import {
|
|
5
5
|
appendUserMessage,
|
|
6
6
|
checkEvidence,
|
|
@@ -16,17 +16,17 @@ import {
|
|
|
16
16
|
reviseHarnessTaskAcceptance,
|
|
17
17
|
runHarness,
|
|
18
18
|
runHarnessTask
|
|
19
|
-
} from "./index-
|
|
19
|
+
} from "./index-pf73y4gt.js";
|
|
20
20
|
import {
|
|
21
21
|
ASSISTANT_RESPONSE_KEY,
|
|
22
22
|
TASK_SOURCE_KEY,
|
|
23
23
|
assistantResponses,
|
|
24
24
|
cancelHarnessRun,
|
|
25
25
|
captureTaskSources
|
|
26
|
-
} from "./index-
|
|
26
|
+
} from "./index-amjttjaj.js";
|
|
27
27
|
import {
|
|
28
28
|
resolvePackageCheckCommand
|
|
29
|
-
} from "./index-
|
|
29
|
+
} from "./index-w0m1nckc.js";
|
|
30
30
|
import {
|
|
31
31
|
APPROVAL_HISTORY_KEY,
|
|
32
32
|
approvalDecisionViews,
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
inspectHarnessPolicy,
|
|
36
36
|
observeHarnessPolicyDecisions,
|
|
37
37
|
readApprovalDecisions
|
|
38
|
-
} from "./index-
|
|
38
|
+
} from "./index-bt2p8x7r.js";
|
|
39
39
|
import {
|
|
40
40
|
SESSION_RUN_STATUSES,
|
|
41
41
|
TASK_ACCEPTANCE_KEY,
|
|
@@ -48,12 +48,12 @@ import {
|
|
|
48
48
|
nextTaskAcceptanceLedger,
|
|
49
49
|
openCliSessionStore,
|
|
50
50
|
readTaskAcceptanceLedger
|
|
51
|
-
} from "./index-
|
|
51
|
+
} from "./index-fqqz1yt8.js";
|
|
52
52
|
import {
|
|
53
53
|
createEditProposal,
|
|
54
54
|
editProposalInputSchema,
|
|
55
55
|
fileDigestSchema
|
|
56
|
-
} from "./index-
|
|
56
|
+
} from "./index-6dxrbnxm.js";
|
|
57
57
|
import {
|
|
58
58
|
CLI_JSON_SCHEMA_VERSION,
|
|
59
59
|
harnessClientRequestSchema,
|
|
@@ -476,7 +476,7 @@ import { createHash as createHash3 } from "node:crypto";
|
|
|
476
476
|
import { z } from "zod";
|
|
477
477
|
var APPROVAL_DIFFS_KEY = "clientApprovalDiffsV1";
|
|
478
478
|
var sha2 = z.string().regex(/^sha256:[a-f0-9]{64}$/);
|
|
479
|
-
var file = z.object({ path: z.string().max(1024), expectedDigest: sha2.nullable(), before: z.string().nullable(), after: z.string().nullable(), afterDigest: sha2.nullable(), beforeMode: z.number().int().optional(), afterMode: z.number().int().optional(), operation: z.enum(["create", "update", "delete"]).optional() }).strict();
|
|
479
|
+
var file = z.object({ path: z.string().max(1024), expectedDigest: sha2.nullable(), before: z.string().nullable(), after: z.string().nullable(), afterDigest: sha2.nullable(), beforeMode: z.number().int().optional(), afterMode: z.number().int().optional(), operation: z.enum(["create", "update", "delete", "restore"]).optional() }).strict();
|
|
480
480
|
var archive = z.object({ approvalId: z.string().max(256), digest: z.string().regex(/^[a-f0-9]{64}$/), proposalId: sha2, files: z.array(file).min(1).max(50) }).strict();
|
|
481
481
|
var archives = z.array(archive).max(512);
|
|
482
482
|
var maxBytes = 2 * 1024 * 1024;
|
|
@@ -534,14 +534,14 @@ async function attachApprovalPreviews(run, workspace, options = {}) {
|
|
|
534
534
|
let remaining = 256 * 1024;
|
|
535
535
|
for (const approval of run.approvals) {
|
|
536
536
|
const action = approval.action;
|
|
537
|
-
if (!action || !["apply_patch", "apply_reviewed_edits", "apply_reviewed_replacement", "apply_environment_patch", "verify_and_apply_environment_patch", "verify_and_apply_reviewed_edits"].includes(String(action.name)))
|
|
537
|
+
if (!action || !["apply_patch", "apply_reviewed_edits", "apply_reviewed_replacement", "apply_environment_patch", "verify_and_apply_environment_patch", "verify_and_apply_reviewed_edits", "restore_file"].includes(String(action.name)))
|
|
538
538
|
continue;
|
|
539
539
|
approval.filePreview = { status: "unavailable" };
|
|
540
540
|
try {
|
|
541
541
|
if (typeof action.arguments !== "string" || Buffer.byteLength(action.arguments) > 256 * 1024)
|
|
542
542
|
continue;
|
|
543
543
|
const args = JSON.parse(action.arguments);
|
|
544
|
-
const preview = action.name === "apply_environment_patch" || action.name === "verify_and_apply_environment_patch" ? await (async () => {
|
|
544
|
+
const preview = action.name === "restore_file" ? await workspace.previewRestore(args) : action.name === "apply_environment_patch" || action.name === "verify_and_apply_environment_patch" ? await (async () => {
|
|
545
545
|
if (!options.environment)
|
|
546
546
|
throw new Error("OCI_REVIEW_UNAVAILABLE");
|
|
547
547
|
const patchId = fileDigestSchema.parse(args?.patchId);
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
runtimeManifest,
|
|
21
21
|
taskSources,
|
|
22
22
|
tokenUsageCheckpointStore
|
|
23
|
-
} from "./index-
|
|
23
|
+
} from "./index-amjttjaj.js";
|
|
24
24
|
import {
|
|
25
25
|
HARNESS_MCP_CONFIG_SCHEMA_VERSION,
|
|
26
26
|
closeMcpHostSession,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
mcpConfigurationFingerprintInput,
|
|
30
30
|
normalizeHarnessMcpConfiguration,
|
|
31
31
|
resolveMcpHostSession
|
|
32
|
-
} from "./index-
|
|
32
|
+
} from "./index-2r4f0p4n.js";
|
|
33
33
|
import {
|
|
34
34
|
EnvironmentPatchDriftError,
|
|
35
35
|
Workspace,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
isHardIgnored,
|
|
41
41
|
replacementEditSchema,
|
|
42
42
|
resolvePackageCheckCommand
|
|
43
|
-
} from "./index-
|
|
43
|
+
} from "./index-w0m1nckc.js";
|
|
44
44
|
import {
|
|
45
45
|
DEFAULT_PROVIDER_REGISTRY,
|
|
46
46
|
HARNESS_CONFIG_SCHEMA_VERSION,
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
publishHarnessPolicyDecision,
|
|
61
61
|
publishPendingPolicyDecision,
|
|
62
62
|
readApprovalDecisions
|
|
63
|
-
} from "./index-
|
|
63
|
+
} from "./index-bt2p8x7r.js";
|
|
64
64
|
import {
|
|
65
65
|
MODEL_BUDGET_KEY,
|
|
66
66
|
TASK_ACCEPTANCE_EVIDENCE_KEY,
|
|
@@ -85,10 +85,10 @@ import {
|
|
|
85
85
|
withFreshSystemInstructions,
|
|
86
86
|
withRuntimeInstruction,
|
|
87
87
|
workBudgetReached
|
|
88
|
-
} from "./index-
|
|
88
|
+
} from "./index-fqqz1yt8.js";
|
|
89
89
|
import {
|
|
90
90
|
HARNESS_VERSION
|
|
91
|
-
} from "./index-
|
|
91
|
+
} from "./index-rz7wmp71.js";
|
|
92
92
|
import {
|
|
93
93
|
FileSizeLimitError,
|
|
94
94
|
MAX_EDIT_CHANGES,
|
|
@@ -108,7 +108,7 @@ import {
|
|
|
108
108
|
validateEditProposal,
|
|
109
109
|
withTaskAcceptanceDelivery,
|
|
110
110
|
workspaceFilePathSchema
|
|
111
|
-
} from "./index-
|
|
111
|
+
} from "./index-6dxrbnxm.js";
|
|
112
112
|
import {
|
|
113
113
|
HarnessConfigError,
|
|
114
114
|
HarnessError,
|
|
@@ -1832,6 +1832,7 @@ var record = (value) => value !== null && typeof value === "object" && !Array.is
|
|
|
1832
1832
|
var LOCAL_TOOLS = LOCAL_TOOL_NAMES;
|
|
1833
1833
|
var MAX_USER_STEERING = 10;
|
|
1834
1834
|
var CONTEXT_PRIORITY = "Latest user > chronological user steering > historical objective. Assistant never overrides user facts. Questions retain task.";
|
|
1835
|
+
var EARLIER = "[before later user messages] ";
|
|
1835
1836
|
var summarizeHarnessMessages = (messages, maxCharacters = 4000) => {
|
|
1836
1837
|
const redaction = createRedactionPolicy({ includeEmails: true });
|
|
1837
1838
|
const clean = (text, limit = 512) => redaction.redactText(text).replace(/\bBearer\s+\S+/gi, "Bearer [REDACTED]").replace(/\b([A-Z][A-Z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD)|api[_-]?key|access[_-]?token|password)\s*([=:])\s*(?:"[^"]*"|'[^']*'|\S+)/gi, "$1$2[REDACTED]").replace(/\b(?:sk|ghp|gho|github_pat)-[A-Za-z0-9_-]{8,}\b/g, "[REDACTED]").replace(/\s+/g, " ").trim().slice(0, limit);
|
|
@@ -1857,6 +1858,12 @@ var summarizeHarnessMessages = (messages, maxCharacters = 4000) => {
|
|
|
1857
1858
|
omitted = true;
|
|
1858
1859
|
}
|
|
1859
1860
|
};
|
|
1861
|
+
const markRecentEarlier = () => {
|
|
1862
|
+
const marked = recent.map((value) => value.startsWith(EARLIER) ? value : `${EARLIER}${value}`);
|
|
1863
|
+
recent.length = 0;
|
|
1864
|
+
for (const value of marked)
|
|
1865
|
+
add(recent, value, 4);
|
|
1866
|
+
};
|
|
1860
1867
|
const rememberObservation = (tool2, detail) => {
|
|
1861
1868
|
if (typeof tool2 !== "string" || !LOCAL_TOOLS.has(tool2) || typeof detail !== "string")
|
|
1862
1869
|
return;
|
|
@@ -1974,6 +1981,7 @@ var summarizeHarnessMessages = (messages, maxCharacters = 4000) => {
|
|
|
1974
1981
|
objective = text;
|
|
1975
1982
|
if (historicalObjective)
|
|
1976
1983
|
add(steering, text, MAX_USER_STEERING);
|
|
1984
|
+
markRecentEarlier();
|
|
1977
1985
|
} else
|
|
1978
1986
|
add(recent, `${message.role}: ${text}`, 4);
|
|
1979
1987
|
} else if (part.type === "tool-call") {
|
|
@@ -4199,7 +4207,8 @@ var resolvers = {
|
|
|
4199
4207
|
const parsed = moveFileInputSchema.parse(input);
|
|
4200
4208
|
return [parsed.source, parsed.destination];
|
|
4201
4209
|
},
|
|
4202
|
-
quarantine_file: (input) => [quarantineFileInputSchema.parse(input).path]
|
|
4210
|
+
quarantine_file: (input) => [quarantineFileInputSchema.parse(input).path],
|
|
4211
|
+
restore_file: (input) => [restoreFileInputSchema.parse(input).destination]
|
|
4203
4212
|
};
|
|
4204
4213
|
var validateBuiltinToolPolicy = (policy, tools) => {
|
|
4205
4214
|
for (const rule of policy.rules)
|
|
@@ -4656,7 +4665,7 @@ var createWorkspaceTools = (workspace, allowedChecks) => ({
|
|
|
4656
4665
|
}),
|
|
4657
4666
|
restore_file: tool4({
|
|
4658
4667
|
name: "restore_file",
|
|
4659
|
-
description: "Restore a quarantined file to
|
|
4668
|
+
description: "Restore a quarantined file to the required destination after the reviewed expectedDigest matches the quarantined bytes. Restore does not fall back to the original path and never overwrites an existing file.",
|
|
4660
4669
|
schema: restoreFileInputSchema,
|
|
4661
4670
|
...mutationApproval,
|
|
4662
4671
|
execute: async (input, context) => serializeJsonValue6(editContractDocument("restore-result", await (harnessExecutionSession(context)?.workspace ?? workspace).restoreQuarantined(input)))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
workspaceCheckpointSchema,
|
|
3
3
|
workspaceRestoreOperationSchema
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-4mn6m3bq.js";
|
|
5
5
|
import {
|
|
6
6
|
HARNESS_OPERATIONS_SCHEMA_VERSION,
|
|
7
7
|
HARNESS_SQLITE_FILE,
|
|
@@ -9,17 +9,20 @@ import {
|
|
|
9
9
|
openHarnessPersistence,
|
|
10
10
|
projectMemoryRecordKey,
|
|
11
11
|
sqliteAdapter
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-amjttjaj.js";
|
|
13
13
|
import {
|
|
14
|
+
BUDGET_LEDGER_NAMESPACE,
|
|
15
|
+
BUDGET_OWNER_NAMESPACE_KEY,
|
|
14
16
|
HARNESS_SESSION_SCHEMA_VERSION,
|
|
15
17
|
assertTaskBudgetBackupLinks,
|
|
18
|
+
budgetLedgerNamespace,
|
|
16
19
|
openCliSessionStore,
|
|
17
20
|
validateStateDirectory
|
|
18
|
-
} from "./index-
|
|
21
|
+
} from "./index-fqqz1yt8.js";
|
|
19
22
|
import {
|
|
20
23
|
SqliteDatabase,
|
|
21
24
|
readRegularFileChunksNoFollow
|
|
22
|
-
} from "./index-
|
|
25
|
+
} from "./index-6dxrbnxm.js";
|
|
23
26
|
import {
|
|
24
27
|
HarnessStateConflictError,
|
|
25
28
|
HarnessWorkspaceError
|
|
@@ -398,7 +401,8 @@ var coordinatorIds = (runs) => new Set(runs.flatMap(({ state }) => {
|
|
|
398
401
|
var validateBudgetLedger = (config, run, identities) => {
|
|
399
402
|
const state = validatedRunState(run.state, `Budget ledger ${run.key}`);
|
|
400
403
|
const identity = state.metadata?.budgetIdentity;
|
|
401
|
-
|
|
404
|
+
const ownerNamespace = config.scope.namespace;
|
|
405
|
+
if (!ownerNamespace || state.scope?.namespace !== budgetLedgerNamespace(ownerNamespace) || state.metadata?.[BUDGET_OWNER_NAMESPACE_KEY] !== ownerNamespace || state.scope?.tenantId !== config.scope.tenantId || (state.scope?.userId ?? undefined) !== (config.scope.userId ?? undefined) || state.provider !== "zhivex" || state.modelId !== "budget-coordinator" || state.metadata?.budgetCoordinator !== true || typeof identity !== "string" || !identities.has(identity) || !/^budget_[a-f0-9]{64}$/.test(state.runId) || !sdkRunKeyMatches(run.key, state.scope, state.runId)) {
|
|
402
406
|
throw new HarnessStateConflictError("Budget ledger is not bound to an exported run and durable scope.");
|
|
403
407
|
}
|
|
404
408
|
assertTerminalState(state, `Budget ledger ${run.key}`);
|
|
@@ -532,7 +536,9 @@ var readPayload = async (config, recordedWorkspace, accessLease) => {
|
|
|
532
536
|
const metadata = state.metadata;
|
|
533
537
|
if (typeof metadata?.budgetIdentity !== "string" || !identities.has(metadata.budgetIdentity)) {
|
|
534
538
|
const scope = state.scope;
|
|
535
|
-
|
|
539
|
+
const sameTenant = scope?.tenantId === config.scope.tenantId && (scope?.userId ?? undefined) === (config.scope.userId ?? undefined);
|
|
540
|
+
const boundNamespace = config.scope.namespace ? budgetLedgerNamespace(config.scope.namespace) : undefined;
|
|
541
|
+
if (sameTenant && (scope?.namespace === BUDGET_LEDGER_NAMESPACE || scope?.namespace === boundNamespace)) {
|
|
536
542
|
throw new HarnessStateConflictError("An unlinked shared budget ledger cannot be safely assigned to this backup scope; retain the original database.");
|
|
537
543
|
}
|
|
538
544
|
return [];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@zhivex-ai/harness",
|
|
4
|
-
version: "1.
|
|
4
|
+
version: "1.6.2",
|
|
5
5
|
description: "Governed, provider-portable runtime for coding agents with durable approvals and isolated repository execution.",
|
|
6
6
|
type: "module",
|
|
7
7
|
license: "MIT",
|
|
@@ -101,6 +101,7 @@ var package_default = {
|
|
|
101
101
|
"LICENSE",
|
|
102
102
|
"docs/CHANGE_ENVELOPES.md",
|
|
103
103
|
"docs/CLI.md",
|
|
104
|
+
"docs/AUTO_APPROVE.md",
|
|
104
105
|
"docs/WEB_LIMITS.md",
|
|
105
106
|
"docs/CODE_RELEASE.md",
|
|
106
107
|
"docs/CODE_WEB_TASKS.md",
|
|
@@ -217,26 +218,26 @@ var package_default = {
|
|
|
217
218
|
"smoke:mcp:installed": "bun run build && bun scripts/mcp-installed-smoke.ts"
|
|
218
219
|
},
|
|
219
220
|
dependencies: {
|
|
220
|
-
"@zhivex-ai/agents": "1.
|
|
221
|
-
"@zhivex-ai/anthropic": "0.
|
|
222
|
-
"@zhivex-ai/azure-openai": "0.
|
|
223
|
-
"@zhivex-ai/bedrock": "2.0
|
|
224
|
-
"@zhivex-ai/core": "1.
|
|
225
|
-
"@zhivex-ai/gemini": "0.
|
|
226
|
-
"@zhivex-ai/meta": "0.
|
|
227
|
-
"@zhivex-ai/openai": "0.
|
|
228
|
-
"@zhivex-ai/qwen": "0.
|
|
229
|
-
"@zhivex-ai/vertex": "1.
|
|
230
|
-
"google-auth-library": "11.1
|
|
231
|
-
zod: "4.6.
|
|
221
|
+
"@zhivex-ai/agents": "1.12.0",
|
|
222
|
+
"@zhivex-ai/anthropic": "0.15.0",
|
|
223
|
+
"@zhivex-ai/azure-openai": "0.8.0",
|
|
224
|
+
"@zhivex-ai/bedrock": "2.1.0",
|
|
225
|
+
"@zhivex-ai/core": "1.36.0",
|
|
226
|
+
"@zhivex-ai/gemini": "0.14.0",
|
|
227
|
+
"@zhivex-ai/meta": "0.3.0",
|
|
228
|
+
"@zhivex-ai/openai": "0.17.0",
|
|
229
|
+
"@zhivex-ai/qwen": "0.18.0",
|
|
230
|
+
"@zhivex-ai/vertex": "1.3.0",
|
|
231
|
+
"google-auth-library": "11.3.1",
|
|
232
|
+
zod: "4.6.7"
|
|
232
233
|
},
|
|
233
234
|
overrides: {
|
|
234
|
-
"@zhivex-ai/core": "1.
|
|
235
|
+
"@zhivex-ai/core": "1.36.0"
|
|
235
236
|
},
|
|
236
237
|
devDependencies: {
|
|
237
238
|
"@agentclientprotocol/sdk": "1.8.0",
|
|
238
239
|
"@modelcontextprotocol/server": "2.3.1",
|
|
239
|
-
"@types/bun": "1.4.
|
|
240
|
+
"@types/bun": "1.4.3",
|
|
240
241
|
"@types/node": "^26.6.5",
|
|
241
242
|
typescript: "7.0.2",
|
|
242
243
|
"typescript-compiler-api": "npm:typescript@6.0.3"
|