@arcforgelabs/flow 2026.11.3 → 2026.11.4

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.
Files changed (36) hide show
  1. package/SECURITY.md +2 -1
  2. package/npm-shrinkwrap.json +2 -2
  3. package/package.json +1 -1
  4. package/server/agents/gate.js +25 -5
  5. package/server/api/invoicing.js +68 -1
  6. package/server/app.js +3 -2
  7. package/server/auth/session.js +13 -7
  8. package/server/auth/settings.js +18 -7
  9. package/server/core/alerts.js +38 -3
  10. package/server/core/automations.js +8 -3
  11. package/server/core/invoice-rules.js +158 -8
  12. package/server/core/invoices.js +9 -1
  13. package/server/core/invoicing-rules.js +31 -6
  14. package/server/core/job-board.js +16 -1
  15. package/server/core/ledger.js +3 -1
  16. package/server/core/reconcile.js +11 -3
  17. package/server/core/sending.js +14 -3
  18. package/server/db/migrations/0027_high_doctor_strange.sql +24 -0
  19. package/server/db/migrations/0028_sharp_power_pack.sql +2 -0
  20. package/server/db/migrations/meta/0027_snapshot.json +5050 -0
  21. package/server/db/migrations/meta/0028_snapshot.json +5062 -0
  22. package/server/db/migrations/meta/_journal.json +14 -0
  23. package/server/db/schema.js +21 -0
  24. package/server/integrations/seazona/feed.js +10 -3
  25. package/server/integrations/xero/drafts.js +1 -1
  26. package/server/integrations/xero/index.js +1 -1
  27. package/server/integrations/xero/ledger.js +12 -7
  28. package/server/integrations/xero/links.js +39 -1
  29. package/server/integrations/xero/lookup.js +3 -1
  30. package/server/integrations/xero/routes.js +18 -1
  31. package/server/ui/flow.css +1 -0
  32. package/server/ui/invoice-rules.js +11 -3
  33. package/server/ui/invoicing.js +73 -5
  34. package/server/ui/jobs.js +14 -2
  35. package/skills/flow/SKILL.md +71 -2
  36. package/skills/flow/flow.sh +32 -1
@@ -7,6 +7,9 @@
7
7
  # flow.sh put <path> <json> PUT with a JSON body
8
8
  # flow.sh delete <path> DELETE
9
9
  # flow.sh health GET <FLOW_URL>/health (public, no key sent)
10
+ # flow.sh link <kind> <id> print a Flow page address to give a person:
11
+ # invoice <invoice id>, reconcile <job id>,
12
+ # contact <contact id>, job <case number>
10
13
  # flow.sh update replace this skill with the copy the
11
14
  # saved Flow serves (its own release)
12
15
  # The key stays in FLOW_AGENT_KEY_FILE (mode 600). It never goes on a command
@@ -41,6 +44,7 @@ setup() {
41
44
  fi
42
45
  chmod 600 "$KEY_FILE"
43
46
  echo "FLOW_AGENT_KEY_SHA256=$(tr -d '\n' < "$KEY_FILE" | sha256sum | cut -d' ' -f1)"
47
+ echo "(For a second assistant, the host sets this digest as FLOW_AGENT_KEY_SHA256_2.)"
44
48
  }
45
49
 
46
50
  call() {
@@ -78,6 +82,32 @@ update() {
78
82
  echo "Skill updated from $(flow_url)"
79
83
  }
80
84
 
85
+ # A Flow page address for a person: the saved Flow address plus the page's
86
+ # path. Ids are Flow's own (the `id` in an answer), never an invoice number.
87
+ UUID_RE='^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'
88
+ urlencode() {
89
+ local LC_ALL=C
90
+ local s="$1" out="" c i
91
+ for ((i = 0; i < ${#s}; i++)); do
92
+ c="${s:i:1}"
93
+ case "$c" in [A-Za-z0-9.~_-]) out+="$c" ;; *) out+="$(printf '%%%02X' "'$c")" ;; esac
94
+ done
95
+ printf '%s' "$out"
96
+ }
97
+ link() {
98
+ local kind="${1:-}" id="${2:-}" base
99
+ [[ -n "$id" && "$id" != null && "$id" != undefined ]] || die "give a kind and an id, for example: link invoice <invoice id>"
100
+ base="$(flow_url)"
101
+ case "$kind" in
102
+ invoice|reconcile|contact)
103
+ [[ "$id" =~ $UUID_RE ]] || die "$kind needs Flow's id (a UUID from the answer's \"id\"), not a number like INV-0123"
104
+ local page=invoices; [[ "$kind" == reconcile ]] && page=reconcile; [[ "$kind" == contact ]] && page=contacts
105
+ printf '%s/%s/%s\n' "$base" "$page" "$id" ;;
106
+ job) printf '%s/jobs?q=%s\n' "$base" "$(urlencode "$id")" ;;
107
+ *) die "link kinds: invoice, reconcile, contact, job" ;;
108
+ esac
109
+ }
110
+
81
111
  case "${1:-}" in
82
112
  setup) setup "${2:-}" ;;
83
113
  get) call GET "${2:-}" ;;
@@ -86,5 +116,6 @@ case "${1:-}" in
86
116
  delete) call DELETE "${2:-}" ;;
87
117
  health) curl -sS -H 'Accept: application/json' -w '\nHTTP %{http_code}\n' "$(flow_url)/health" ;;
88
118
  update) update ;;
89
- *) sed -n '2,12p' "$0"; exit 2 ;;
119
+ link) link "${2:-}" "${3:-}" ;;
120
+ *) sed -n '2,15p' "$0"; exit 2 ;;
90
121
  esac