@integrity-labs/agt-cli 0.28.1094 → 0.28.1096

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.
@@ -16,7 +16,7 @@ import {
16
16
  parseEnvFileEntries,
17
17
  parseEnvIntegrations,
18
18
  shellQuote
19
- } from "./chunk-6VIH2UFL.js";
19
+ } from "./chunk-CRVS3GGR.js";
20
20
  import {
21
21
  BIND_FAILURE_QUARANTINE_THRESHOLD,
22
22
  INTEGRATIONS_SECTION_END,
@@ -79,7 +79,7 @@ import {
79
79
  sessionTranscriptDir,
80
80
  worseConnectivityOutcome,
81
81
  wrapScheduledTaskPrompt
82
- } from "./chunk-KEMDLWTE.js";
82
+ } from "./chunk-DH3QU73N.js";
83
83
  import {
84
84
  classifyUnanswerablePane,
85
85
  isConsumerTermsDialogVisible,
@@ -7122,7 +7122,7 @@ function exchangeFailureKind(err) {
7122
7122
  }
7123
7123
 
7124
7124
  // src/lib/api-client.ts
7125
- var agtCliVersion = true ? "0.28.1094" : "dev";
7125
+ var agtCliVersion = true ? "0.28.1096" : "dev";
7126
7126
  var lastConfigHash = null;
7127
7127
  function setConfigHash(hash) {
7128
7128
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -12095,4 +12095,4 @@ export {
12095
12095
  managerInstallSystemUnitCommand,
12096
12096
  managerUninstallSystemUnitCommand
12097
12097
  };
12098
- //# sourceMappingURL=chunk-JJYOF5KM.js.map
12098
+ //# sourceMappingURL=chunk-WFKQVAYW.js.map
@@ -266,7 +266,7 @@ async function spawnPairSession(session) {
266
266
  return { ok: true };
267
267
  } catch {
268
268
  }
269
- const { resolveClaudeBinary } = await import("./persistent-session-FLPQZ35P.js");
269
+ const { resolveClaudeBinary } = await import("./persistent-session-5GWNAPCW.js");
270
270
  const claudeBin = resolveClaudeBinary();
271
271
  const pairEnv = {
272
272
  ...process.env,
@@ -734,4 +734,4 @@ export {
734
734
  startClaudePair,
735
735
  submitClaudePairCode
736
736
  };
737
- //# sourceMappingURL=claude-pair-runtime-5ONG4ZYY.js.map
737
+ //# sourceMappingURL=claude-pair-runtime-NGRPLOG2.js.map
@@ -67,7 +67,7 @@ import {
67
67
  safeWriteJsonAtomic,
68
68
  setConfigHash,
69
69
  tripClass
70
- } from "../chunk-JJYOF5KM.js";
70
+ } from "../chunk-WFKQVAYW.js";
71
71
  import {
72
72
  getProjectDir as getProjectDir2,
73
73
  getReadyTasks,
@@ -154,7 +154,7 @@ import {
154
154
  webFetchBaselineValue,
155
155
  webFetchRestartNeeded,
156
156
  writeEgressAllowlist
157
- } from "../chunk-6VIH2UFL.js";
157
+ } from "../chunk-CRVS3GGR.js";
158
158
  import {
159
159
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
160
160
  AnchorSessionClient,
@@ -264,7 +264,7 @@ import {
264
264
  subagentActivityAgeSeconds,
265
265
  sumTranscriptUsageInWindow,
266
266
  transcriptActivityAgeSeconds
267
- } from "../chunk-KEMDLWTE.js";
267
+ } from "../chunk-DH3QU73N.js";
268
268
  import {
269
269
  classifyUnanswerablePane,
270
270
  paneRemedy
@@ -14142,7 +14142,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
14142
14142
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
14143
14143
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
14144
14144
  async function channelInboundActivityAgeSecondsFor(codeName) {
14145
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-VIDFFFM4.js");
14145
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-3EODWLBJ.js");
14146
14146
  const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
14147
14147
  if (newest === null) return null;
14148
14148
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -14900,7 +14900,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
14900
14900
  var lastVersionCheckAt = 0;
14901
14901
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
14902
14902
  var lastResponsivenessProbeAt = 0;
14903
- var agtCliVersion = true ? "0.28.1094" : "dev";
14903
+ var agtCliVersion = true ? "0.28.1096" : "dev";
14904
14904
  function resolveBrewPath(execFileSync3) {
14905
14905
  try {
14906
14906
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -16517,7 +16517,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
16517
16517
  if (codeNames.length === 0) return;
16518
16518
  void (async () => {
16519
16519
  try {
16520
- const { collectDiagnostics } = await import("../persistent-session-FLPQZ35P.js");
16520
+ const { collectDiagnostics } = await import("../persistent-session-5GWNAPCW.js");
16521
16521
  await api.post("/host/heartbeat", {
16522
16522
  host_id: hostId,
16523
16523
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
@@ -16659,7 +16659,7 @@ async function pollCycleInner() {
16659
16659
  }
16660
16660
  try {
16661
16661
  const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
16662
- const { collectDiagnostics } = await import("../persistent-session-FLPQZ35P.js");
16662
+ const { collectDiagnostics } = await import("../persistent-session-5GWNAPCW.js");
16663
16663
  const diagCodeNames = [...agentState.persistentSessionAgents];
16664
16664
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor) : void 0;
16665
16665
  let tailscaleHostname;
@@ -16867,7 +16867,7 @@ async function pollCycleInner() {
16867
16867
  collectPanelessActivityProbes,
16868
16868
  getResponsivenessIntervalMs,
16869
16869
  occupancyQualificationClassifications
16870
- } = await import("../responsiveness-probe-VIDFFFM4.js");
16870
+ } = await import("../responsiveness-probe-3EODWLBJ.js");
16871
16871
  const probeIntervalMs = getResponsivenessIntervalMs();
16872
16872
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
16873
16873
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -16984,7 +16984,7 @@ async function pollCycleInner() {
16984
16984
  collectResponsivenessProbes,
16985
16985
  livePendingInboundOldestAgeSeconds,
16986
16986
  parkPendingInbound
16987
- } = await import("../responsiveness-probe-VIDFFFM4.js");
16987
+ } = await import("../responsiveness-probe-3EODWLBJ.js");
16988
16988
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
16989
16989
  const wedgeNow = /* @__PURE__ */ new Date();
16990
16990
  const liveAgents = agentState.persistentSessionAgents;
@@ -17270,7 +17270,7 @@ async function pollCycleInner() {
17270
17270
  }
17271
17271
  }
17272
17272
  );
17273
- const { parkPendingInbound } = await import("../responsiveness-probe-VIDFFFM4.js");
17273
+ const { parkPendingInbound } = await import("../responsiveness-probe-3EODWLBJ.js");
17274
17274
  const { parked, deadLettered } = parkPendingInbound(codeName, new Date(fatalNowMs));
17275
17275
  paneFatalStreak.delete(codeName);
17276
17276
  paneFatalRestarts.set(codeName, [...history, fatalNowMs]);
@@ -17301,7 +17301,7 @@ async function pollCycleInner() {
17301
17301
  TRANSCRIPT_MOUNT_ESCALATION_REFRESH_MS,
17302
17302
  bindSourceEscalations
17303
17303
  } = await import("../transcript-mount-health-OHE6IVJV.js");
17304
- const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-FLPQZ35P.js");
17304
+ const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-5GWNAPCW.js");
17305
17305
  const mountConfig = resolveTranscriptMountConfig();
17306
17306
  const liveAgents = agentState.persistentSessionAgents;
17307
17307
  for (const tracked of [
@@ -17466,7 +17466,7 @@ async function pollCycleInner() {
17466
17466
  }
17467
17467
  try {
17468
17468
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
17469
- const { probeSessionAuth } = await import("../session-auth-dead-PMMJ6RYS.js");
17469
+ const { probeSessionAuth } = await import("../session-auth-dead-RNRQZEB3.js");
17470
17470
  const observations = [];
17471
17471
  const pendingCacheCommits = [];
17472
17472
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -22038,7 +22038,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
22038
22038
  try {
22039
22039
  const freshId = rotateSessionForWedge(codeName);
22040
22040
  consecutiveWedgeCycles.delete(codeName);
22041
- const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-VIDFFFM4.js");
22041
+ const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-3EODWLBJ.js");
22042
22042
  const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
22043
22043
  const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
22044
22044
  const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
@@ -22081,7 +22081,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
22081
22081
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
22082
22082
  void (async () => {
22083
22083
  try {
22084
- const { collectDiagnostics } = await import("../persistent-session-FLPQZ35P.js");
22084
+ const { collectDiagnostics } = await import("../persistent-session-5GWNAPCW.js");
22085
22085
  await api.post("/host/heartbeat", {
22086
22086
  host_id: hostId,
22087
22087
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
@@ -22132,7 +22132,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
22132
22132
  }
22133
22133
  try {
22134
22134
  const hostId = await getHostId();
22135
- const { collectDiagnostics } = await import("../persistent-session-FLPQZ35P.js");
22135
+ const { collectDiagnostics } = await import("../persistent-session-5GWNAPCW.js");
22136
22136
  await api.post("/host/heartbeat", {
22137
22137
  host_id: hostId,
22138
22138
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
@@ -22804,7 +22804,7 @@ async function processClaudePairSessions(agents) {
22804
22804
  // cannot take it for itself — by the time it runs, the write it is looking
22805
22805
  // for may already have happened.
22806
22806
  snapshotPairConfig
22807
- } = await import("../claude-pair-runtime-5ONG4ZYY.js");
22807
+ } = await import("../claude-pair-runtime-NGRPLOG2.js");
22808
22808
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
22809
22809
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
22810
22810
  const killed = await killPairSession(pairTmuxSession(pairId));
package/dist/mcp/index.js CHANGED
@@ -50003,6 +50003,66 @@ Give your manager this link so they can accept or decline it: ${data.review_url}
50003
50003
  }
50004
50004
  }
50005
50005
  );
50006
+ server.tool(
50007
+ "routine_retire",
50008
+ "Ask for approval to RETIRE one of your routines, so it stops for good. The card goes to the person who accepted the routine (your manager if nobody did). Use this when a routine should no longer run at all: a duplicate, a responsibility that has ended, or one its owner has asked you to delete. This is the only way to end a routine - schedule_delete refuses a routine's schedules, and routine_revise only changes what it does. Nothing stops until they approve: they get an approve/deny card, and the routine keeps running until they decide. On approval the platform retires the routine and turns off every schedule in it at once. Poll the returned request_id with check_approval. To change WHAT a routine does, use routine_revise instead; to change WHEN it runs, send only schedule fields to schedule_update.",
50009
+ {
50010
+ routine_id: external_exports.string().trim().min(1).describe("The routine to retire. Get this from routine_list. A schedule_id from schedule_list is also accepted and resolved server-side. It must be a routine YOU own; anything else reads as not-found."),
50011
+ reason: external_exports.string().trim().min(1).max(500).describe("Why this routine should stop, and who asked if someone did. The approver reads this on the card before deciding. Required."),
50012
+ idempotency_key: external_exports.string().trim().min(1).max(200).describe('A stable key for this request so a retry does not file a second card (e.g. "retire-<routine_id>").')
50013
+ },
50014
+ async (params) => {
50015
+ let data;
50016
+ try {
50017
+ data = await apiPost("/host/routines/retire", {
50018
+ agent_id: AGT_AGENT_ID,
50019
+ routine_id: params.routine_id,
50020
+ reason: params.reason,
50021
+ idempotency_key: params.idempotency_key
50022
+ });
50023
+ } catch (err) {
50024
+ const msg = err instanceof Error ? err.message : String(err);
50025
+ if (/returned\s+[45]\d\d/.test(msg)) {
50026
+ let detail = msg;
50027
+ const jsonStart = msg.indexOf("{");
50028
+ if (jsonStart !== -1) {
50029
+ try {
50030
+ const parsedErr = JSON.parse(msg.slice(jsonStart));
50031
+ if (parsedErr.error) detail = parsedErr.error;
50032
+ } catch {
50033
+ }
50034
+ }
50035
+ return { content: [{ type: "text", text: `Could not request the retire: ${detail}` }], isError: true };
50036
+ }
50037
+ return {
50038
+ content: [
50039
+ {
50040
+ type: "text",
50041
+ text: `The retire request's outcome is unknown (${msg}); it may already have been filed. Retry with the SAME idempotency_key: that re-attaches to the existing request if there is one instead of filing a second card. Do not use a new key. If it keeps failing, tell your operator.`
50042
+ }
50043
+ ],
50044
+ isError: true
50045
+ };
50046
+ }
50047
+ if (!data.ok) {
50048
+ return {
50049
+ content: [{ type: "text", text: `Could not request the retire: ${data.error ?? "unknown error"}` }],
50050
+ isError: true
50051
+ };
50052
+ }
50053
+ const name = data.routine_name ? `"${data.routine_name}"` : "the routine";
50054
+ const idLine = data.request_id ? ` Request id: ${data.request_id} (poll it with check_approval).` : "";
50055
+ const unpaged = data.notification_status === "failed" ? " WARNING: the approval card could not be delivered, so nobody has been paged yet. Tell your operator." : "";
50056
+ return {
50057
+ content: [
50058
+ {
50059
+ type: "text",
50060
+ text: `Asked for approval to retire ${name}.${idLine} It keeps running until they approve; on approval it is retired and every schedule in it stops. Do not re-send while it is pending.${unpaged}`
50061
+ }
50062
+ ]
50063
+ };
50064
+ }
50065
+ );
50006
50066
  server.tool(
50007
50067
  "routine_proposal_status",
50008
50068
  "Read the outcome of the routine revisions YOU proposed with routine_revise: pending (your manager has not resolved it yet), accepted, declined, or expired - plus the summary and the FULL replacement description you submitted, so you can see what is actually waiting on them. A pending proposal also returns a review_url to hand to your manager, and is flagged `stale` when the routine has changed since you proposed (accepting it would apply a rewrite of text the routine no longer says - propose again against the current prompt instead). Call this when routine_list shows a revision pending, when routine_revise refuses because one already is, or to close the loop on a proposal you filed in an earlier session. No decline reason is recorded anywhere on this path, so a declined proposal tells you THAT it was declined and not why - ask the person rather than reporting a reason you do not have.",
@@ -50965,6 +51025,9 @@ var LOCAL_TOOL_NAMES = /* @__PURE__ */ new Set([
50965
51025
  // ENG-10494: the verdict loop for routine_revise. Without it a proposed
50966
51026
  // revision is write-only, and an unseen one blocks that routine for good.
50967
51027
  "routine_proposal_status",
51028
+ // CS-1964: the ending half. Files a routine.retirement approval; there was no
51029
+ // agent path to stop a routine at all.
51030
+ "routine_retire",
50968
51031
  // ENG-10276: knowledge_get is the untruncated single-entry read. The list and
50969
51032
  // search tools serve a stored SUMMARY column, not the entry, so this is the
50970
51033
  // only one that can be trusted before a knowledge_update.
package/dist/mcp/xero.js CHANGED
@@ -22704,12 +22704,12 @@ var require_lineAmountTypes = __commonJS({
22704
22704
  "use strict";
22705
22705
  Object.defineProperty(exports, "__esModule", { value: true });
22706
22706
  exports.LineAmountTypes = void 0;
22707
- var LineAmountTypes;
22708
- (function(LineAmountTypes2) {
22709
- LineAmountTypes2[LineAmountTypes2["Exclusive"] = "Exclusive"] = "Exclusive";
22710
- LineAmountTypes2[LineAmountTypes2["Inclusive"] = "Inclusive"] = "Inclusive";
22711
- LineAmountTypes2[LineAmountTypes2["NoTax"] = "NoTax"] = "NoTax";
22712
- })(LineAmountTypes || (exports.LineAmountTypes = LineAmountTypes = {}));
22707
+ var LineAmountTypes3;
22708
+ (function(LineAmountTypes4) {
22709
+ LineAmountTypes4[LineAmountTypes4["Exclusive"] = "Exclusive"] = "Exclusive";
22710
+ LineAmountTypes4[LineAmountTypes4["Inclusive"] = "Inclusive"] = "Inclusive";
22711
+ LineAmountTypes4[LineAmountTypes4["NoTax"] = "NoTax"] = "NoTax";
22712
+ })(LineAmountTypes3 || (exports.LineAmountTypes = LineAmountTypes3 = {}));
22713
22713
  }
22714
22714
  });
22715
22715
 
@@ -114893,11 +114893,28 @@ function messageForStatus(status, detail) {
114893
114893
  return detail ? redactSensitiveText(detail) : "An error occurred while communicating with Xero.";
114894
114894
  }
114895
114895
  }
114896
+ var MAX_VALIDATION_MESSAGES = 5;
114896
114897
  function readDetail(body) {
114897
- if (body && typeof body === "object" && "Detail" in body) {
114898
- const d = body.Detail;
114899
- return typeof d === "string" ? d : null;
114900
- }
114898
+ if (!body || typeof body !== "object") return null;
114899
+ const b = body;
114900
+ if (typeof b.Detail === "string" && b.Detail.trim() !== "") return b.Detail;
114901
+ const messages = [];
114902
+ if (Array.isArray(b.Elements)) {
114903
+ for (const element of b.Elements) {
114904
+ const errors = element?.ValidationErrors;
114905
+ if (!Array.isArray(errors)) continue;
114906
+ for (const e of errors) {
114907
+ const m = e?.Message;
114908
+ if (typeof m === "string" && m.trim() !== "" && !messages.includes(m.trim())) messages.push(m.trim());
114909
+ }
114910
+ }
114911
+ }
114912
+ if (messages.length > 0) {
114913
+ const shown = messages.slice(0, MAX_VALIDATION_MESSAGES);
114914
+ const more = messages.length - shown.length;
114915
+ return `Xero rejected the request: ${shown.join("; ")}${more > 0 ? ` (and ${more} more)` : ""}`;
114916
+ }
114917
+ if (typeof b.Message === "string" && b.Message.trim() !== "") return b.Message;
114901
114918
  return null;
114902
114919
  }
114903
114920
 
@@ -115495,7 +115512,7 @@ var create_credit_note_tool_default = CreateCreditNoteTool;
115495
115512
 
115496
115513
  // src/handlers/create-xero-invoice.handler.ts
115497
115514
  var import_xero_node5 = __toESM(require_dist2(), 1);
115498
- async function createInvoice(contactId, lineItems, type, reference, date3) {
115515
+ async function createInvoice(contactId, lineItems, type, reference, date3, lineAmountTypes) {
115499
115516
  await xeroClient.authenticate();
115500
115517
  const invoice = {
115501
115518
  type,
@@ -115508,7 +115525,11 @@ async function createInvoice(contactId, lineItems, type, reference, date3) {
115508
115525
  dueDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3).toISOString().split("T")[0],
115509
115526
  // 30 days from now
115510
115527
  ...type === import_xero_node5.Invoice.TypeEnum.ACCPAY ? { invoiceNumber: reference } : { reference },
115511
- status: import_xero_node5.Invoice.StatusEnum.DRAFT
115528
+ status: import_xero_node5.Invoice.StatusEnum.DRAFT,
115529
+ // CS-1974: omitted unless asked for, so Xero's own default (Exclusive)
115530
+ // still applies to every existing caller. Inclusive lets a tax-inclusive
115531
+ // price list be entered as-is instead of as retail/1.1 with cent rounding.
115532
+ ...lineAmountTypes !== void 0 ? { lineAmountTypes } : {}
115512
115533
  };
115513
115534
  const response = await xeroClient.accountingApi.createInvoices(
115514
115535
  xeroClient.tenantId,
@@ -115527,14 +115548,15 @@ async function createInvoice(contactId, lineItems, type, reference, date3) {
115527
115548
  const createdInvoice = response.body.invoices?.[0];
115528
115549
  return createdInvoice;
115529
115550
  }
115530
- async function createXeroInvoice(contactId, lineItems, type = import_xero_node5.Invoice.TypeEnum.ACCREC, reference, date3) {
115551
+ async function createXeroInvoice(contactId, lineItems, type = import_xero_node5.Invoice.TypeEnum.ACCREC, reference, date3, lineAmountTypes) {
115531
115552
  try {
115532
115553
  const createdInvoice = await createInvoice(
115533
115554
  contactId,
115534
115555
  lineItems,
115535
115556
  type,
115536
115557
  reference,
115537
- date3
115558
+ date3,
115559
+ lineAmountTypes
115538
115560
  );
115539
115561
  if (!createdInvoice) {
115540
115562
  throw new Error("Invoice creation failed.");
@@ -115569,6 +115591,11 @@ var lineItemSchema3 = external_exports.object({
115569
115591
  itemCode: external_exports.string().describe("The item code of the line item - can be obtained from the list-items tool If the item is not listed, add without an item code and ask the user if they would like to add an item code.").optional(),
115570
115592
  tracking: external_exports.array(trackingSchema).describe("Up to 2 tracking categories and options can be added to the line item. Can be obtained from the list-tracking-categories tool. Only use if prompted by the user.").optional()
115571
115593
  });
115594
+ var LINE_AMOUNT_TYPES = {
115595
+ Exclusive: import_xero_node6.LineAmountTypes.Exclusive,
115596
+ Inclusive: import_xero_node6.LineAmountTypes.Inclusive,
115597
+ NoTax: import_xero_node6.LineAmountTypes.NoTax
115598
+ };
115572
115599
  var CreateInvoiceTool = CreateXeroTool(
115573
115600
  "create-invoice",
115574
115601
  "Create an invoice in Xero. When an invoice is created, a deep link to the invoice in Xero is returned. This deep link can be used to view the invoice in Xero directly. This link should be displayed to the user.",
@@ -115577,11 +115604,19 @@ var CreateInvoiceTool = CreateXeroTool(
115577
115604
  lineItems: external_exports.array(lineItemSchema3),
115578
115605
  type: external_exports.enum(["ACCREC", "ACCPAY"]).describe("The type of invoice to create. ACCREC is for sales invoices, Accounts Receivable, or customer invoices. ACCPAY is for purchase invoices, Accounts Payable invoices, supplier invoices, or bills. If the type is not specified, the default is ACCREC."),
115579
115606
  reference: external_exports.string().describe("A reference number for the invoice.").optional(),
115580
- date: external_exports.string().describe("The date the invoice was created (YYYY-MM-DD format).").optional()
115607
+ date: external_exports.string().describe("The date the invoice was created (YYYY-MM-DD format).").optional(),
115608
+ lineAmountTypes: external_exports.enum(["Exclusive", "Inclusive", "NoTax"]).describe("Whether the line unitAmounts INCLUDE tax. Inclusive: the amounts already include tax (e.g. retail prices incl. GST) - use this rather than dividing by 1.1. Exclusive: tax is added on top (Xero's default when omitted). NoTax: no tax applies.").optional()
115581
115609
  },
115582
- async ({ contactId, lineItems, type, reference, date: date3 }) => {
115610
+ async ({ contactId, lineItems, type, reference, date: date3, lineAmountTypes }) => {
115583
115611
  const xeroInvoiceType = type === "ACCREC" ? import_xero_node6.Invoice.TypeEnum.ACCREC : import_xero_node6.Invoice.TypeEnum.ACCPAY;
115584
- const result = await createXeroInvoice(contactId, lineItems, xeroInvoiceType, reference, date3);
115612
+ const result = await createXeroInvoice(
115613
+ contactId,
115614
+ lineItems,
115615
+ xeroInvoiceType,
115616
+ reference,
115617
+ date3,
115618
+ lineAmountTypes === void 0 ? void 0 : LINE_AMOUNT_TYPES[lineAmountTypes]
115619
+ );
115585
115620
  if (result.isError) {
115586
115621
  return {
115587
115622
  content: [
@@ -115631,7 +115666,8 @@ async function createItem(itemDetails) {
115631
115666
  purchaseDetails: itemDetails.purchaseDetails ? {
115632
115667
  unitPrice: itemDetails.purchaseDetails.unitPrice,
115633
115668
  taxType: itemDetails.purchaseDetails.taxType,
115634
- accountCode: itemDetails.purchaseDetails.accountCode
115669
+ accountCode: itemDetails.purchaseDetails.accountCode,
115670
+ cOGSAccountCode: itemDetails.purchaseDetails.cOGSAccountCode
115635
115671
  } : void 0,
115636
115672
  salesDetails: itemDetails.salesDetails ? {
115637
115673
  unitPrice: itemDetails.salesDetails.unitPrice,
@@ -115679,7 +115715,9 @@ async function createXeroItem(itemDetails) {
115679
115715
  var purchaseDetailsSchema = external_exports.object({
115680
115716
  unitPrice: external_exports.number(),
115681
115717
  taxType: external_exports.string().optional(),
115682
- accountCode: external_exports.string().optional()
115718
+ accountCode: external_exports.string().optional(),
115719
+ // CS-1974: without this a tracked item cannot be created at all.
115720
+ cOGSAccountCode: external_exports.string().optional().describe("Cost of goods sold account code. REQUIRED by Xero when the item is tracked as inventory (isTrackedAsInventory true): Xero rejects a tracked item without it. Use a cost of sales / COGS account from list-accounts.")
115683
115721
  });
115684
115722
  var salesDetailsSchema = external_exports.object({
115685
115723
  unitPrice: external_exports.number(),
@@ -115696,8 +115734,8 @@ var CreateItemTool = CreateXeroTool(
115696
115734
  purchaseDescription: external_exports.string().optional(),
115697
115735
  purchaseDetails: purchaseDetailsSchema.optional(),
115698
115736
  salesDetails: salesDetailsSchema.optional(),
115699
- isTrackedAsInventory: external_exports.boolean().optional(),
115700
- inventoryAssetAccountCode: external_exports.string().optional()
115737
+ isTrackedAsInventory: external_exports.boolean().optional().describe("Track quantity and value. A tracked item needs inventoryAssetAccountCode AND purchaseDetails.cOGSAccountCode, and Xero records purchases against the inventory asset account rather than purchaseDetails.accountCode."),
115738
+ inventoryAssetAccountCode: external_exports.string().optional().describe("Inventory asset account code. Required when isTrackedAsInventory is true.")
115701
115739
  },
115702
115740
  async ({
115703
115741
  code,
@@ -120080,7 +120118,9 @@ async function updateXeroItem(itemId, itemDetails) {
120080
120118
  var purchaseDetailsSchema2 = external_exports.object({
120081
120119
  unitPrice: external_exports.number().optional(),
120082
120120
  taxType: external_exports.string().optional(),
120083
- accountCode: external_exports.string().optional()
120121
+ accountCode: external_exports.string().optional(),
120122
+ // CS-1974: lets an existing item be switched to tracked inventory.
120123
+ cOGSAccountCode: external_exports.string().optional().describe("Cost of goods sold account code. REQUIRED by Xero when the item is tracked as inventory (isTrackedAsInventory true): Xero rejects a tracked item without it. Use a cost of sales / COGS account from list-accounts.")
120084
120124
  });
120085
120125
  var salesDetailsSchema2 = external_exports.object({
120086
120126
  unitPrice: external_exports.number().optional(),
@@ -68,8 +68,8 @@ import {
68
68
  writeDirectChatSessionState,
69
69
  writeEgressAllowlist,
70
70
  writePersistentClaudeWrapper
71
- } from "./chunk-6VIH2UFL.js";
72
- import "./chunk-KEMDLWTE.js";
71
+ } from "./chunk-CRVS3GGR.js";
72
+ import "./chunk-DH3QU73N.js";
73
73
  import "./chunk-OCMJ5E6J.js";
74
74
  import "./chunk-XWVM4KPK.js";
75
75
  import "./chunk-EL5MWGGH.js";
@@ -145,4 +145,4 @@ export {
145
145
  writeEgressAllowlist,
146
146
  writePersistentClaudeWrapper
147
147
  };
148
- //# sourceMappingURL=persistent-session-FLPQZ35P.js.map
148
+ //# sourceMappingURL=persistent-session-5GWNAPCW.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-6VIH2UFL.js";
4
- import "./chunk-KEMDLWTE.js";
3
+ } from "./chunk-CRVS3GGR.js";
4
+ import "./chunk-DH3QU73N.js";
5
5
  import "./chunk-OCMJ5E6J.js";
6
6
  import "./chunk-XWVM4KPK.js";
7
7
  import "./chunk-EL5MWGGH.js";
@@ -802,4 +802,4 @@ export {
802
802
  readAndResetSlackReplyBindingClassifications,
803
803
  readAndResetSlackReplyTargetClassifications
804
804
  };
805
- //# sourceMappingURL=responsiveness-probe-VIDFFFM4.js.map
805
+ //# sourceMappingURL=responsiveness-probe-3EODWLBJ.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionTranscriptDir
3
- } from "./chunk-KEMDLWTE.js";
3
+ } from "./chunk-DH3QU73N.js";
4
4
  import "./chunk-DGUM43GV.js";
5
5
 
6
6
  // src/lib/session-auth-dead.ts
@@ -204,4 +204,4 @@ export {
204
204
  decideSessionAuthState,
205
205
  probeSessionAuth
206
206
  };
207
- //# sourceMappingURL=session-auth-dead-PMMJ6RYS.js.map
207
+ //# sourceMappingURL=session-auth-dead-RNRQZEB3.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.1094",
3
+ "version": "0.28.1096",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {