@integrity-labs/agt-cli 0.28.1094 → 0.28.1095

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/bin/agt.js CHANGED
@@ -40,7 +40,7 @@ import {
40
40
  success,
41
41
  table,
42
42
  warn
43
- } from "../chunk-JJYOF5KM.js";
43
+ } from "../chunk-OHKWHHTS.js";
44
44
  import {
45
45
  getProjectDir,
46
46
  isSessionResumeDisabled,
@@ -5474,7 +5474,7 @@ import { execFileSync, execSync } from "child_process";
5474
5474
  import { existsSync as existsSync11, realpathSync as realpathSync2 } from "fs";
5475
5475
  import chalk18 from "chalk";
5476
5476
  import ora16 from "ora";
5477
- var cliVersion = true ? "0.28.1094" : "dev";
5477
+ var cliVersion = true ? "0.28.1095" : "dev";
5478
5478
  async function fetchLatestVersion() {
5479
5479
  const host2 = getHost();
5480
5480
  if (!host2) return null;
@@ -6734,7 +6734,7 @@ function handleError(err) {
6734
6734
  }
6735
6735
 
6736
6736
  // src/bin/agt.ts
6737
- var cliVersion2 = true ? "0.28.1094" : "dev";
6737
+ var cliVersion2 = true ? "0.28.1095" : "dev";
6738
6738
  var program = new Command();
6739
6739
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
6740
6740
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -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.1095" : "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-OHKWHHTS.js.map
@@ -67,7 +67,7 @@ import {
67
67
  safeWriteJsonAtomic,
68
68
  setConfigHash,
69
69
  tripClass
70
- } from "../chunk-JJYOF5KM.js";
70
+ } from "../chunk-OHKWHHTS.js";
71
71
  import {
72
72
  getProjectDir as getProjectDir2,
73
73
  getReadyTasks,
@@ -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.1095" : "dev";
14904
14904
  function resolveBrewPath(execFileSync3) {
14905
14905
  try {
14906
14906
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
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(),
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.1095",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {