happy-imou-cloud 2.1.41 → 2.1.42

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 (25) hide show
  1. package/dist/{BaseReasoningProcessor-Dica2zdX.mjs → BaseReasoningProcessor-Bq2Eh351.mjs} +2 -2
  2. package/dist/{BaseReasoningProcessor-DAPsauUX.cjs → BaseReasoningProcessor-BwuoSz2l.cjs} +2 -2
  3. package/dist/{ProviderSelectionHandler-4nuTd8AP.cjs → ProviderSelectionHandler-BpBO_5F5.cjs} +2 -2
  4. package/dist/{ProviderSelectionHandler-CmeZ92yO.mjs → ProviderSelectionHandler-Dz9bzO6r.mjs} +2 -2
  5. package/dist/{api-C_Tnx4UG.cjs → api-Btcmobjm.cjs} +139 -6
  6. package/dist/{api-CwNEbJBM.mjs → api-DHHrvH1L.mjs} +139 -7
  7. package/dist/{command-D0FxDynx.mjs → command-CZh0T9p1.mjs} +2 -2
  8. package/dist/{command-C3RwwPVD.cjs → command-MtPPL26Y.cjs} +2 -2
  9. package/dist/{index-Dh0qGrEd.cjs → index-CCsk2Klg.cjs} +16 -10
  10. package/dist/{index-D5m2Duxd.mjs → index-CKuJSLuU.mjs} +13 -7
  11. package/dist/index.cjs +2 -2
  12. package/dist/index.mjs +2 -2
  13. package/dist/lib.cjs +1 -1
  14. package/dist/lib.d.cts +36 -36
  15. package/dist/lib.d.mts +36 -36
  16. package/dist/lib.mjs +1 -1
  17. package/dist/{registerKillSessionHandler-6JloVYkb.mjs → registerKillSessionHandler-CStAJszS.mjs} +6 -4
  18. package/dist/{registerKillSessionHandler-Bkh8uLhC.cjs → registerKillSessionHandler-DdJrfRVO.cjs} +6 -4
  19. package/dist/{runClaude-Bng_IsE7.mjs → runClaude-DxeIMKax.mjs} +4 -4
  20. package/dist/{runClaude-mIFO7YxF.cjs → runClaude-ge-0Ex7x.cjs} +4 -4
  21. package/dist/{runCodex-cNuxGshy.cjs → runCodex-DBAVYSvY.cjs} +5 -5
  22. package/dist/{runCodex-DAc6flez.mjs → runCodex-tXxg-NBv.mjs} +5 -5
  23. package/dist/{runGemini-DdXj8ltI.mjs → runGemini-BLWj_J4D.mjs} +4 -4
  24. package/dist/{runGemini-DsRFV8WN.cjs → runGemini-CF8Pq4xx.cjs} +4 -4
  25. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- import { a as createSessionMetadata, p as publishSessionRegistration } from './index-D5m2Duxd.mjs';
2
- import { s as startOfflineReconnection, c as configuration, i as isAuthenticationRequiredError, l as logger } from './api-CwNEbJBM.mjs';
1
+ import { a as createSessionMetadata, p as publishSessionRegistration } from './index-CKuJSLuU.mjs';
2
+ import { s as startOfflineReconnection, c as configuration, i as isAuthenticationRequiredError, l as logger } from './api-DHHrvH1L.mjs';
3
3
  import { EventEmitter } from 'node:events';
4
4
  import { randomUUID } from 'node:crypto';
5
5
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Dh0qGrEd.cjs');
4
- var persistence = require('./api-C_Tnx4UG.cjs');
3
+ var index = require('./index-CCsk2Klg.cjs');
4
+ var persistence = require('./api-Btcmobjm.cjs');
5
5
  var node_events = require('node:events');
6
6
  var node_crypto = require('node:crypto');
7
7
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var persistence = require('./api-C_Tnx4UG.cjs');
4
- var registerKillSessionHandler = require('./registerKillSessionHandler-Bkh8uLhC.cjs');
3
+ var persistence = require('./api-Btcmobjm.cjs');
4
+ var registerKillSessionHandler = require('./registerKillSessionHandler-DdJrfRVO.cjs');
5
5
 
6
6
  async function runModeLoop(opts) {
7
7
  let currentMode = opts.startingMode;
@@ -1,5 +1,5 @@
1
- import { l as logger } from './api-CwNEbJBM.mjs';
2
- import { g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, a as INTERACTION_TIMED_OUT_ERROR } from './registerKillSessionHandler-6JloVYkb.mjs';
1
+ import { l as logger } from './api-DHHrvH1L.mjs';
2
+ import { g as getPendingInteractionTimeoutMs, I as INTERACTION_SUPERSEDED_ERROR, a as INTERACTION_TIMED_OUT_ERROR } from './registerKillSessionHandler-CStAJszS.mjs';
3
3
 
4
4
  async function runModeLoop(opts) {
5
5
  let currentMode = opts.startingMode;
@@ -38,7 +38,7 @@ function _interopNamespaceDefault(e) {
38
38
  var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
39
39
 
40
40
  var name = "happy-imou-cloud";
41
- var version = "2.1.41";
41
+ var version = "2.1.42";
42
42
  var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
43
43
  var author = "long.zhu";
44
44
  var license = "MIT";
@@ -1702,6 +1702,59 @@ function isNeedsHandoffTask(task) {
1702
1702
  }
1703
1703
  return false;
1704
1704
  }
1705
+ function resolveRuntimeSessionId(task) {
1706
+ return task.specialistHomeSessionId ?? null;
1707
+ }
1708
+ function resolveMachineId(task) {
1709
+ return task.specialistHomeMachineId ?? null;
1710
+ }
1711
+ function resolveTaskMergeState(task) {
1712
+ const runtimeSessionId = resolveRuntimeSessionId(task);
1713
+ const machineId = resolveMachineId(task);
1714
+ if (task.accessChannelState === "runtime_replaced") {
1715
+ return "conflict";
1716
+ }
1717
+ if (task.activeOwnerAgentId && task.activeOwnerAgentId !== task.ownerAgentId) {
1718
+ return "conflict";
1719
+ }
1720
+ if (task.accessChannelState === "reattach_required") {
1721
+ return "merge_pending";
1722
+ }
1723
+ if (task.hasActiveOwner === false && task.status !== "done" && task.status !== "terminated") {
1724
+ return "merge_pending";
1725
+ }
1726
+ if ((task.status === "active" || task.status === "waiting_close") && (!runtimeSessionId || !machineId)) {
1727
+ return "merge_pending";
1728
+ }
1729
+ return "stable";
1730
+ }
1731
+ function resolveTaskMergeStateSummary(task, mergeState, runtimeSessionId, machineId) {
1732
+ if (mergeState === "conflict") {
1733
+ if (task.accessChannelState === "runtime_replaced") {
1734
+ return "runtime was replaced before the merge view stabilized";
1735
+ }
1736
+ if (task.activeOwnerAgentId && task.activeOwnerAgentId !== task.ownerAgentId) {
1737
+ return `active owner moved to ${task.activeOwnerAgentId}`;
1738
+ }
1739
+ return "merge conflict needs owner review";
1740
+ }
1741
+ if (mergeState === "merge_pending") {
1742
+ if (task.accessChannelState === "reattach_required") {
1743
+ return "runtime reattach required before merge becomes stable";
1744
+ }
1745
+ if (task.hasActiveOwner === false) {
1746
+ return "no active owner is attached to the task yet";
1747
+ }
1748
+ if (!runtimeSessionId || !machineId) {
1749
+ return "runtime or machine attribution is still missing";
1750
+ }
1751
+ return "merge visibility is still pending";
1752
+ }
1753
+ if (runtimeSessionId && machineId) {
1754
+ return `runtime ${runtimeSessionId} on machine ${machineId}`;
1755
+ }
1756
+ return "merge is stable";
1757
+ }
1705
1758
  function classifyHappyOrgTaskBoardSection(task) {
1706
1759
  if (task.status === "done") {
1707
1760
  return "closed";
@@ -1715,8 +1768,12 @@ function classifyHappyOrgTaskBoardSection(task) {
1715
1768
  return "in_progress";
1716
1769
  }
1717
1770
  function buildHappyOrgTaskBoardView(tasks) {
1771
+ const organizationManifestId = tasks.find((task) => task.organizationManifestId)?.organizationManifestId ?? null;
1718
1772
  const items = [...tasks].filter((task) => task.status !== "terminated").sort((left, right) => right.updatedAt - left.updatedAt || left.taskId.localeCompare(right.taskId)).map((task) => {
1719
1773
  const sectionKey = classifyHappyOrgTaskBoardSection(task);
1774
+ const runtimeSessionId = resolveRuntimeSessionId(task);
1775
+ const machineId = resolveMachineId(task);
1776
+ const mergeState = resolveTaskMergeState(task);
1720
1777
  return {
1721
1778
  taskId: task.taskId,
1722
1779
  title: task.title,
@@ -1725,8 +1782,15 @@ function buildHappyOrgTaskBoardView(tasks) {
1725
1782
  lane: sectionKey,
1726
1783
  ownerAgentId: task.ownerAgentId,
1727
1784
  ownerName: task.ownerName,
1785
+ organizationManifestId: task.organizationManifestId ?? null,
1786
+ positionId: task.positionId ?? null,
1728
1787
  responsibilityId: task.responsibilityId ?? null,
1729
1788
  responsibilityLabel: task.responsibilityLabel ?? null,
1789
+ runtimeSessionId,
1790
+ machineId,
1791
+ accessChannelState: task.accessChannelState ?? null,
1792
+ mergeState,
1793
+ mergeStateSummary: resolveTaskMergeStateSummary(task, mergeState, runtimeSessionId, machineId),
1730
1794
  currentProgress: task.positionStatus || task.summary || null,
1731
1795
  latestResult: task.latestUserVisibleResult || task.reviewSummary || task.resultSummary || null,
1732
1796
  blockerOrDecision: task.blockerSummary || task.blocker || task.decisionNeeded || task.adviceSummary || task.ceoWriteNextStep || null,
@@ -1750,6 +1814,7 @@ function buildHappyOrgTaskBoardView(tasks) {
1750
1814
  { key: "closed", count: buckets.closed.length, items: buckets.closed }
1751
1815
  ];
1752
1816
  return {
1817
+ organizationManifestId,
1753
1818
  totalCount: items.length,
1754
1819
  inProgressCount: sections[0].count,
1755
1820
  handoffCount: sections[1].count,
@@ -1760,6 +1825,49 @@ function buildHappyOrgTaskBoardView(tasks) {
1760
1825
  };
1761
1826
  }
1762
1827
 
1828
+ const HTTP_URL_PATTERN = /^https?:\/\//i;
1829
+ const FILE_URL_PATTERN = /^file:\/\//i;
1830
+ const FILE_EXTENSION_PATTERN = /\.[A-Za-z0-9_-]{1,16}$/;
1831
+ const SPECIAL_FILE_NAME_PATTERN = /(^|[\\/])(Dockerfile|Makefile|README(?:\.[A-Za-z0-9_-]+)?)$/i;
1832
+ function isLikelyPreviewableArtifactTarget(target) {
1833
+ const trimmed = typeof target === "string" ? target.trim() : "";
1834
+ if (!trimmed) {
1835
+ return false;
1836
+ }
1837
+ if (HTTP_URL_PATTERN.test(trimmed) || FILE_URL_PATTERN.test(trimmed)) {
1838
+ return true;
1839
+ }
1840
+ const stripped = trimmed.split(/[?#]/)[0] ?? trimmed;
1841
+ const basename = stripped.split(/[\\/]/).pop() ?? stripped;
1842
+ if (!basename) {
1843
+ return false;
1844
+ }
1845
+ return FILE_EXTENSION_PATTERN.test(basename) || SPECIAL_FILE_NAME_PATTERN.test(basename);
1846
+ }
1847
+ function resolveArtifactTarget(target) {
1848
+ const trimmed = typeof target === "string" ? target.trim() : "";
1849
+ if (!trimmed || !isLikelyPreviewableArtifactTarget(trimmed)) {
1850
+ return {
1851
+ kind: "unknown",
1852
+ target: trimmed
1853
+ };
1854
+ }
1855
+ if (HTTP_URL_PATTERN.test(trimmed) || FILE_URL_PATTERN.test(trimmed)) {
1856
+ return {
1857
+ kind: "external",
1858
+ target: trimmed
1859
+ };
1860
+ }
1861
+ return {
1862
+ kind: "path",
1863
+ target: trimmed
1864
+ };
1865
+ }
1866
+ function normalizePreviewableArtifactTarget(target) {
1867
+ const resolved = resolveArtifactTarget(target);
1868
+ return resolved.kind === "unknown" ? null : resolved.target;
1869
+ }
1870
+
1763
1871
  const HAPPY_ORG_LOCAL_REPO_SCHEMA_VERSION = "1.7.3-local-repo-v1";
1764
1872
  const HAPPY_ORG_WRITER_LOCK_SCHEMA_VERSION = "1.7.3-writer-lock-v1";
1765
1873
  const WRITER_LOCK_LEASE_DURATION_SECONDS = 900;
@@ -1801,6 +1909,12 @@ const GoalSchema = z.z.object({
1801
1909
  approvedBy: z.z.string().nullable(),
1802
1910
  updatedAt: z.z.number()
1803
1911
  });
1912
+ const OrganizationValueSchema = z.z.object({
1913
+ name: z.z.string(),
1914
+ slug: z.z.string().min(1),
1915
+ summary: z.z.string().nullable(),
1916
+ createdAt: z.z.number()
1917
+ });
1804
1918
  const TaskUpdatePayloadSchema = z.z.object({
1805
1919
  taskId: z.z.string().min(1),
1806
1920
  status: TaskStatusSchema,
@@ -2028,6 +2142,7 @@ const LogValueSchema = z.z.object({
2028
2142
  taskId: z.z.string(),
2029
2143
  entries: z.z.array(LogEntrySchema)
2030
2144
  });
2145
+ const OrganizationEnvelopeSchema = RevisionEnvelopeSchema(OrganizationValueSchema);
2031
2146
  const GoalEnvelopeSchema = RevisionEnvelopeSchema(GoalSchema);
2032
2147
  const PositionEnvelopeSchema = RevisionEnvelopeSchema(PositionValueSchema);
2033
2148
  const WorkspaceEnvelopeSchema = RevisionEnvelopeSchema(WorkspaceValueSchema);
@@ -2324,20 +2439,31 @@ async function readHappyOrgDispatchTruthSnapshot(rootPath) {
2324
2439
  };
2325
2440
  }
2326
2441
  async function readHappyOrgRepoTaskBoard(rootPath) {
2327
- const [taskIds, positions, responsibilities] = await Promise.all([
2442
+ const [taskIds, positions, responsibilities, organization] = await Promise.all([
2328
2443
  listTaskIds(rootPath),
2329
2444
  listPositionEnvelopes(rootPath),
2330
- readResponsibilities(rootPath)
2445
+ readResponsibilities(rootPath),
2446
+ readEnvelope(path.join(rootPath, "ORGANIZATION.json"), OrganizationEnvelopeSchema)
2331
2447
  ]);
2448
+ const organizationManifestId = organization?.value.slug ?? null;
2332
2449
  const responsibilityLabelById = /* @__PURE__ */ new Map();
2450
+ const responsibilityPositionIdById = /* @__PURE__ */ new Map();
2451
+ const positionIdByAgentId = /* @__PURE__ */ new Map();
2333
2452
  for (const responsibility of responsibilities?.value ?? []) {
2334
2453
  responsibilityLabelById.set(responsibility.responsibilityId, responsibility.title);
2454
+ responsibilityPositionIdById.set(responsibility.responsibilityId, responsibility.positionId);
2335
2455
  }
2336
2456
  for (const position of positions) {
2337
2457
  const fallbackResponsibilityId = position.value.responsibilityIds[0] ?? buildResponsibilityId(position.value.slug);
2338
2458
  if (!responsibilityLabelById.has(fallbackResponsibilityId)) {
2339
2459
  responsibilityLabelById.set(fallbackResponsibilityId, position.value.label || position.value.agentName || position.value.slug);
2340
2460
  }
2461
+ if (!responsibilityPositionIdById.has(fallbackResponsibilityId)) {
2462
+ responsibilityPositionIdById.set(fallbackResponsibilityId, position.value.positionId);
2463
+ }
2464
+ if (position.value.agentId) {
2465
+ positionIdByAgentId.set(position.value.agentId, position.value.positionId);
2466
+ }
2341
2467
  }
2342
2468
  const tasks = await Promise.all(taskIds.map(async (taskId) => {
2343
2469
  const bundle = await loadTaskEnvelope(rootPath, taskId);
@@ -2345,6 +2471,8 @@ async function readHappyOrgRepoTaskBoard(rootPath) {
2345
2471
  }));
2346
2472
  return buildHappyOrgTaskBoardView(tasks.filter((task) => task !== null).map((task) => ({
2347
2473
  ...task,
2474
+ organizationManifestId,
2475
+ positionId: (task.responsibilityId ? responsibilityPositionIdById.get(task.responsibilityId) ?? null : null) ?? positionIdByAgentId.get(task.activeOwnerAgentId ?? "") ?? positionIdByAgentId.get(task.ownerAgentId) ?? null,
2348
2476
  responsibilityLabel: task.responsibilityLabel ?? (task.responsibilityId ? responsibilityLabelById.get(task.responsibilityId) ?? null : null)
2349
2477
  })));
2350
2478
  }
@@ -3037,6 +3165,10 @@ async function recordHappyOrgTurnReport(options) {
3037
3165
  }
3038
3166
  const now = Date.now();
3039
3167
  const nextStatus = nextStatusFromTurnReport(options.report);
3168
+ const artifactReference = normalizePreviewableArtifactTarget(options.report.targetArtifact);
3169
+ const artifactTarget = resolveArtifactTarget(options.report.targetArtifact);
3170
+ const nextPath = artifactTarget.kind === "path" ? artifactTarget.target : bundle.task.value.path;
3171
+ const nextPortablePath = artifactTarget.kind === "path" ? normalizePortablePath(artifactTarget.target) : bundle.task.value.portablePath;
3040
3172
  const nextTaskValue = {
3041
3173
  ...bundle.task.value,
3042
3174
  status: nextStatus,
@@ -3064,8 +3196,8 @@ async function recordHappyOrgTurnReport(options) {
3064
3196
  blockerSummary: options.report.acceptanceHandoff?.blockerSummary ?? bundle.task.value.blockerSummary ?? null,
3065
3197
  acceptanceState: options.report.acceptanceHandoff?.acceptanceState ?? bundle.task.value.acceptanceState ?? null,
3066
3198
  ceoWriteNextStep: options.report.acceptanceHandoff?.ceoWriteNextStep ?? bundle.task.value.ceoWriteNextStep ?? null,
3067
- path: options.report.targetArtifact ?? bundle.task.value.path,
3068
- portablePath: normalizePortablePath(options.report.targetArtifact ?? bundle.task.value.path)
3199
+ path: nextPath,
3200
+ portablePath: nextPortablePath
3069
3201
  };
3070
3202
  const taskRoot = buildTaskRoot(options.rootPath, options.report.taskId);
3071
3203
  await writeEnvelope(path.join(taskRoot, "TASK.json"), {
@@ -3104,7 +3236,7 @@ async function recordHappyOrgTurnReport(options) {
3104
3236
  reviewSummary: bundle.result?.value.reviewSummary ?? null,
3105
3237
  assetCaptureStatus: bundle.result?.value.assetCaptureStatus ?? null,
3106
3238
  assetCaptureSummary: bundle.result?.value.assetCaptureSummary ?? null,
3107
- assetReference: options.report.targetArtifact ?? bundle.result?.value.assetReference ?? null,
3239
+ assetReference: artifactReference ?? bundle.result?.value.assetReference ?? null,
3108
3240
  closedAt: nextStatus === "waiting_close" ? now : bundle.result?.value.closedAt ?? null,
3109
3241
  updatedAt: now,
3110
3242
  updatedBy: options.report.memberAgentId
@@ -6970,6 +7102,7 @@ exports.getLatestDaemonLog = getLatestDaemonLog;
6970
7102
  exports.getProfileEnvironmentVariables = getProfileEnvironmentVariables;
6971
7103
  exports.isAuthenticationRequiredError = isAuthenticationRequiredError;
6972
7104
  exports.logger = logger;
7105
+ exports.normalizePreviewableArtifactTarget = normalizePreviewableArtifactTarget;
6973
7106
  exports.packageJson = packageJson;
6974
7107
  exports.persistence = persistence;
6975
7108
  exports.preserveSessionRuntimeMetadata = preserveSessionRuntimeMetadata;
@@ -18,7 +18,7 @@ import { spawn } from 'node:child_process';
18
18
  import { Expo } from 'expo-server-sdk';
19
19
 
20
20
  var name = "happy-imou-cloud";
21
- var version = "2.1.41";
21
+ var version = "2.1.42";
22
22
  var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
23
23
  var author = "long.zhu";
24
24
  var license = "MIT";
@@ -1682,6 +1682,59 @@ function isNeedsHandoffTask(task) {
1682
1682
  }
1683
1683
  return false;
1684
1684
  }
1685
+ function resolveRuntimeSessionId(task) {
1686
+ return task.specialistHomeSessionId ?? null;
1687
+ }
1688
+ function resolveMachineId(task) {
1689
+ return task.specialistHomeMachineId ?? null;
1690
+ }
1691
+ function resolveTaskMergeState(task) {
1692
+ const runtimeSessionId = resolveRuntimeSessionId(task);
1693
+ const machineId = resolveMachineId(task);
1694
+ if (task.accessChannelState === "runtime_replaced") {
1695
+ return "conflict";
1696
+ }
1697
+ if (task.activeOwnerAgentId && task.activeOwnerAgentId !== task.ownerAgentId) {
1698
+ return "conflict";
1699
+ }
1700
+ if (task.accessChannelState === "reattach_required") {
1701
+ return "merge_pending";
1702
+ }
1703
+ if (task.hasActiveOwner === false && task.status !== "done" && task.status !== "terminated") {
1704
+ return "merge_pending";
1705
+ }
1706
+ if ((task.status === "active" || task.status === "waiting_close") && (!runtimeSessionId || !machineId)) {
1707
+ return "merge_pending";
1708
+ }
1709
+ return "stable";
1710
+ }
1711
+ function resolveTaskMergeStateSummary(task, mergeState, runtimeSessionId, machineId) {
1712
+ if (mergeState === "conflict") {
1713
+ if (task.accessChannelState === "runtime_replaced") {
1714
+ return "runtime was replaced before the merge view stabilized";
1715
+ }
1716
+ if (task.activeOwnerAgentId && task.activeOwnerAgentId !== task.ownerAgentId) {
1717
+ return `active owner moved to ${task.activeOwnerAgentId}`;
1718
+ }
1719
+ return "merge conflict needs owner review";
1720
+ }
1721
+ if (mergeState === "merge_pending") {
1722
+ if (task.accessChannelState === "reattach_required") {
1723
+ return "runtime reattach required before merge becomes stable";
1724
+ }
1725
+ if (task.hasActiveOwner === false) {
1726
+ return "no active owner is attached to the task yet";
1727
+ }
1728
+ if (!runtimeSessionId || !machineId) {
1729
+ return "runtime or machine attribution is still missing";
1730
+ }
1731
+ return "merge visibility is still pending";
1732
+ }
1733
+ if (runtimeSessionId && machineId) {
1734
+ return `runtime ${runtimeSessionId} on machine ${machineId}`;
1735
+ }
1736
+ return "merge is stable";
1737
+ }
1685
1738
  function classifyHappyOrgTaskBoardSection(task) {
1686
1739
  if (task.status === "done") {
1687
1740
  return "closed";
@@ -1695,8 +1748,12 @@ function classifyHappyOrgTaskBoardSection(task) {
1695
1748
  return "in_progress";
1696
1749
  }
1697
1750
  function buildHappyOrgTaskBoardView(tasks) {
1751
+ const organizationManifestId = tasks.find((task) => task.organizationManifestId)?.organizationManifestId ?? null;
1698
1752
  const items = [...tasks].filter((task) => task.status !== "terminated").sort((left, right) => right.updatedAt - left.updatedAt || left.taskId.localeCompare(right.taskId)).map((task) => {
1699
1753
  const sectionKey = classifyHappyOrgTaskBoardSection(task);
1754
+ const runtimeSessionId = resolveRuntimeSessionId(task);
1755
+ const machineId = resolveMachineId(task);
1756
+ const mergeState = resolveTaskMergeState(task);
1700
1757
  return {
1701
1758
  taskId: task.taskId,
1702
1759
  title: task.title,
@@ -1705,8 +1762,15 @@ function buildHappyOrgTaskBoardView(tasks) {
1705
1762
  lane: sectionKey,
1706
1763
  ownerAgentId: task.ownerAgentId,
1707
1764
  ownerName: task.ownerName,
1765
+ organizationManifestId: task.organizationManifestId ?? null,
1766
+ positionId: task.positionId ?? null,
1708
1767
  responsibilityId: task.responsibilityId ?? null,
1709
1768
  responsibilityLabel: task.responsibilityLabel ?? null,
1769
+ runtimeSessionId,
1770
+ machineId,
1771
+ accessChannelState: task.accessChannelState ?? null,
1772
+ mergeState,
1773
+ mergeStateSummary: resolveTaskMergeStateSummary(task, mergeState, runtimeSessionId, machineId),
1710
1774
  currentProgress: task.positionStatus || task.summary || null,
1711
1775
  latestResult: task.latestUserVisibleResult || task.reviewSummary || task.resultSummary || null,
1712
1776
  blockerOrDecision: task.blockerSummary || task.blocker || task.decisionNeeded || task.adviceSummary || task.ceoWriteNextStep || null,
@@ -1730,6 +1794,7 @@ function buildHappyOrgTaskBoardView(tasks) {
1730
1794
  { key: "closed", count: buckets.closed.length, items: buckets.closed }
1731
1795
  ];
1732
1796
  return {
1797
+ organizationManifestId,
1733
1798
  totalCount: items.length,
1734
1799
  inProgressCount: sections[0].count,
1735
1800
  handoffCount: sections[1].count,
@@ -1740,6 +1805,49 @@ function buildHappyOrgTaskBoardView(tasks) {
1740
1805
  };
1741
1806
  }
1742
1807
 
1808
+ const HTTP_URL_PATTERN = /^https?:\/\//i;
1809
+ const FILE_URL_PATTERN = /^file:\/\//i;
1810
+ const FILE_EXTENSION_PATTERN = /\.[A-Za-z0-9_-]{1,16}$/;
1811
+ const SPECIAL_FILE_NAME_PATTERN = /(^|[\\/])(Dockerfile|Makefile|README(?:\.[A-Za-z0-9_-]+)?)$/i;
1812
+ function isLikelyPreviewableArtifactTarget(target) {
1813
+ const trimmed = typeof target === "string" ? target.trim() : "";
1814
+ if (!trimmed) {
1815
+ return false;
1816
+ }
1817
+ if (HTTP_URL_PATTERN.test(trimmed) || FILE_URL_PATTERN.test(trimmed)) {
1818
+ return true;
1819
+ }
1820
+ const stripped = trimmed.split(/[?#]/)[0] ?? trimmed;
1821
+ const basename = stripped.split(/[\\/]/).pop() ?? stripped;
1822
+ if (!basename) {
1823
+ return false;
1824
+ }
1825
+ return FILE_EXTENSION_PATTERN.test(basename) || SPECIAL_FILE_NAME_PATTERN.test(basename);
1826
+ }
1827
+ function resolveArtifactTarget(target) {
1828
+ const trimmed = typeof target === "string" ? target.trim() : "";
1829
+ if (!trimmed || !isLikelyPreviewableArtifactTarget(trimmed)) {
1830
+ return {
1831
+ kind: "unknown",
1832
+ target: trimmed
1833
+ };
1834
+ }
1835
+ if (HTTP_URL_PATTERN.test(trimmed) || FILE_URL_PATTERN.test(trimmed)) {
1836
+ return {
1837
+ kind: "external",
1838
+ target: trimmed
1839
+ };
1840
+ }
1841
+ return {
1842
+ kind: "path",
1843
+ target: trimmed
1844
+ };
1845
+ }
1846
+ function normalizePreviewableArtifactTarget(target) {
1847
+ const resolved = resolveArtifactTarget(target);
1848
+ return resolved.kind === "unknown" ? null : resolved.target;
1849
+ }
1850
+
1743
1851
  const HAPPY_ORG_LOCAL_REPO_SCHEMA_VERSION = "1.7.3-local-repo-v1";
1744
1852
  const HAPPY_ORG_WRITER_LOCK_SCHEMA_VERSION = "1.7.3-writer-lock-v1";
1745
1853
  const WRITER_LOCK_LEASE_DURATION_SECONDS = 900;
@@ -1781,6 +1889,12 @@ const GoalSchema = z$1.object({
1781
1889
  approvedBy: z$1.string().nullable(),
1782
1890
  updatedAt: z$1.number()
1783
1891
  });
1892
+ const OrganizationValueSchema = z$1.object({
1893
+ name: z$1.string(),
1894
+ slug: z$1.string().min(1),
1895
+ summary: z$1.string().nullable(),
1896
+ createdAt: z$1.number()
1897
+ });
1784
1898
  const TaskUpdatePayloadSchema = z$1.object({
1785
1899
  taskId: z$1.string().min(1),
1786
1900
  status: TaskStatusSchema,
@@ -2008,6 +2122,7 @@ const LogValueSchema = z$1.object({
2008
2122
  taskId: z$1.string(),
2009
2123
  entries: z$1.array(LogEntrySchema)
2010
2124
  });
2125
+ const OrganizationEnvelopeSchema = RevisionEnvelopeSchema(OrganizationValueSchema);
2011
2126
  const GoalEnvelopeSchema = RevisionEnvelopeSchema(GoalSchema);
2012
2127
  const PositionEnvelopeSchema = RevisionEnvelopeSchema(PositionValueSchema);
2013
2128
  const WorkspaceEnvelopeSchema = RevisionEnvelopeSchema(WorkspaceValueSchema);
@@ -2304,20 +2419,31 @@ async function readHappyOrgDispatchTruthSnapshot(rootPath) {
2304
2419
  };
2305
2420
  }
2306
2421
  async function readHappyOrgRepoTaskBoard(rootPath) {
2307
- const [taskIds, positions, responsibilities] = await Promise.all([
2422
+ const [taskIds, positions, responsibilities, organization] = await Promise.all([
2308
2423
  listTaskIds(rootPath),
2309
2424
  listPositionEnvelopes(rootPath),
2310
- readResponsibilities(rootPath)
2425
+ readResponsibilities(rootPath),
2426
+ readEnvelope(path.join(rootPath, "ORGANIZATION.json"), OrganizationEnvelopeSchema)
2311
2427
  ]);
2428
+ const organizationManifestId = organization?.value.slug ?? null;
2312
2429
  const responsibilityLabelById = /* @__PURE__ */ new Map();
2430
+ const responsibilityPositionIdById = /* @__PURE__ */ new Map();
2431
+ const positionIdByAgentId = /* @__PURE__ */ new Map();
2313
2432
  for (const responsibility of responsibilities?.value ?? []) {
2314
2433
  responsibilityLabelById.set(responsibility.responsibilityId, responsibility.title);
2434
+ responsibilityPositionIdById.set(responsibility.responsibilityId, responsibility.positionId);
2315
2435
  }
2316
2436
  for (const position of positions) {
2317
2437
  const fallbackResponsibilityId = position.value.responsibilityIds[0] ?? buildResponsibilityId(position.value.slug);
2318
2438
  if (!responsibilityLabelById.has(fallbackResponsibilityId)) {
2319
2439
  responsibilityLabelById.set(fallbackResponsibilityId, position.value.label || position.value.agentName || position.value.slug);
2320
2440
  }
2441
+ if (!responsibilityPositionIdById.has(fallbackResponsibilityId)) {
2442
+ responsibilityPositionIdById.set(fallbackResponsibilityId, position.value.positionId);
2443
+ }
2444
+ if (position.value.agentId) {
2445
+ positionIdByAgentId.set(position.value.agentId, position.value.positionId);
2446
+ }
2321
2447
  }
2322
2448
  const tasks = await Promise.all(taskIds.map(async (taskId) => {
2323
2449
  const bundle = await loadTaskEnvelope(rootPath, taskId);
@@ -2325,6 +2451,8 @@ async function readHappyOrgRepoTaskBoard(rootPath) {
2325
2451
  }));
2326
2452
  return buildHappyOrgTaskBoardView(tasks.filter((task) => task !== null).map((task) => ({
2327
2453
  ...task,
2454
+ organizationManifestId,
2455
+ positionId: (task.responsibilityId ? responsibilityPositionIdById.get(task.responsibilityId) ?? null : null) ?? positionIdByAgentId.get(task.activeOwnerAgentId ?? "") ?? positionIdByAgentId.get(task.ownerAgentId) ?? null,
2328
2456
  responsibilityLabel: task.responsibilityLabel ?? (task.responsibilityId ? responsibilityLabelById.get(task.responsibilityId) ?? null : null)
2329
2457
  })));
2330
2458
  }
@@ -3017,6 +3145,10 @@ async function recordHappyOrgTurnReport(options) {
3017
3145
  }
3018
3146
  const now = Date.now();
3019
3147
  const nextStatus = nextStatusFromTurnReport(options.report);
3148
+ const artifactReference = normalizePreviewableArtifactTarget(options.report.targetArtifact);
3149
+ const artifactTarget = resolveArtifactTarget(options.report.targetArtifact);
3150
+ const nextPath = artifactTarget.kind === "path" ? artifactTarget.target : bundle.task.value.path;
3151
+ const nextPortablePath = artifactTarget.kind === "path" ? normalizePortablePath(artifactTarget.target) : bundle.task.value.portablePath;
3020
3152
  const nextTaskValue = {
3021
3153
  ...bundle.task.value,
3022
3154
  status: nextStatus,
@@ -3044,8 +3176,8 @@ async function recordHappyOrgTurnReport(options) {
3044
3176
  blockerSummary: options.report.acceptanceHandoff?.blockerSummary ?? bundle.task.value.blockerSummary ?? null,
3045
3177
  acceptanceState: options.report.acceptanceHandoff?.acceptanceState ?? bundle.task.value.acceptanceState ?? null,
3046
3178
  ceoWriteNextStep: options.report.acceptanceHandoff?.ceoWriteNextStep ?? bundle.task.value.ceoWriteNextStep ?? null,
3047
- path: options.report.targetArtifact ?? bundle.task.value.path,
3048
- portablePath: normalizePortablePath(options.report.targetArtifact ?? bundle.task.value.path)
3179
+ path: nextPath,
3180
+ portablePath: nextPortablePath
3049
3181
  };
3050
3182
  const taskRoot = buildTaskRoot(options.rootPath, options.report.taskId);
3051
3183
  await writeEnvelope(path.join(taskRoot, "TASK.json"), {
@@ -3084,7 +3216,7 @@ async function recordHappyOrgTurnReport(options) {
3084
3216
  reviewSummary: bundle.result?.value.reviewSummary ?? null,
3085
3217
  assetCaptureStatus: bundle.result?.value.assetCaptureStatus ?? null,
3086
3218
  assetCaptureSummary: bundle.result?.value.assetCaptureSummary ?? null,
3087
- assetReference: options.report.targetArtifact ?? bundle.result?.value.assetReference ?? null,
3219
+ assetReference: artifactReference ?? bundle.result?.value.assetReference ?? null,
3088
3220
  closedAt: nextStatus === "waiting_close" ? now : bundle.result?.value.closedAt ?? null,
3089
3221
  updatedAt: now,
3090
3222
  updatedBy: options.report.memberAgentId
@@ -6918,4 +7050,4 @@ var api = /*#__PURE__*/Object.freeze({
6918
7050
  ApiClient: ApiClient
6919
7051
  });
6920
7052
 
6921
- export { ApiClient as A, HAPPY_CLOUD_DAEMON_PORT as B, clearDaemonState as C, packageJson as D, acquireDaemonLock as E, writeDaemonState as F, releaseDaemonLock as G, HeadTailPreviewBuffer as H, validateProfileForAgent as I, getProfileEnvironmentVariables as J, clearCredentials as K, clearMachineId as L, readHappyOrgDispatchTruthSnapshot as M, processHappyOrgRepoRequests as N, readHappyOrgRepoTaskBoard as O, HappyOrgTurnReportSchema as P, recordHappyOrgTurnReport as Q, MessageContentSchema as R, buildSocketAuth as S, encrypt as T, getLatestDaemonLog as U, persistence as V, api as W, ApiSessionClient as a, connectionState as b, configuration as c, AssistantMessageStream as d, HAPPY_ORG_REPLY_ACK_VERSION as e, HAPPY_ORG_TURN_REPORT_TAG as f, HAPPY_ORG_SUMMARY_MAX_LENGTH as g, HAPPY_ORG_REPEAT_THRESHOLD as h, isAuthenticationRequiredError as i, backoff as j, delay as k, logger as l, AsyncLock as m, encodeBase64 as n, readCredentials as o, preserveSessionRuntimeMetadata as p, ensureSigningCredentials as q, readSettings as r, startOfflineReconnection as s, encodeBase64Url as t, updateSettings as u, buildClientHeaders as v, decodeBase64 as w, writeCredentialsLegacy as x, writeCredentialsDataKey as y, readDaemonState as z };
7053
+ export { ApiClient as A, readDaemonState as B, HAPPY_CLOUD_DAEMON_PORT as C, clearDaemonState as D, packageJson as E, acquireDaemonLock as F, writeDaemonState as G, HeadTailPreviewBuffer as H, releaseDaemonLock as I, validateProfileForAgent as J, getProfileEnvironmentVariables as K, clearCredentials as L, clearMachineId as M, readHappyOrgDispatchTruthSnapshot as N, processHappyOrgRepoRequests as O, readHappyOrgRepoTaskBoard as P, HappyOrgTurnReportSchema as Q, recordHappyOrgTurnReport as R, MessageContentSchema as S, buildSocketAuth as T, encrypt as U, getLatestDaemonLog as V, persistence as W, api as X, ApiSessionClient as a, connectionState as b, configuration as c, AssistantMessageStream as d, HAPPY_ORG_REPLY_ACK_VERSION as e, HAPPY_ORG_TURN_REPORT_TAG as f, HAPPY_ORG_SUMMARY_MAX_LENGTH as g, HAPPY_ORG_REPEAT_THRESHOLD as h, isAuthenticationRequiredError as i, backoff as j, delay as k, logger as l, AsyncLock as m, normalizePreviewableArtifactTarget as n, encodeBase64 as o, preserveSessionRuntimeMetadata as p, readCredentials as q, readSettings as r, startOfflineReconnection as s, ensureSigningCredentials as t, updateSettings as u, encodeBase64Url as v, buildClientHeaders as w, decodeBase64 as x, writeCredentialsLegacy as y, writeCredentialsDataKey as z };
@@ -1,6 +1,6 @@
1
- import { c as createDefaultRuntimeShell } from './index-D5m2Duxd.mjs';
1
+ import { c as createDefaultRuntimeShell } from './index-CKuJSLuU.mjs';
2
2
  import 'chalk';
3
- import './api-CwNEbJBM.mjs';
3
+ import './api-DHHrvH1L.mjs';
4
4
  import 'axios';
5
5
  import 'fs';
6
6
  import 'node:fs';
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Dh0qGrEd.cjs');
3
+ var index = require('./index-CCsk2Klg.cjs');
4
4
  require('chalk');
5
- require('./api-C_Tnx4UG.cjs');
5
+ require('./api-Btcmobjm.cjs');
6
6
  require('axios');
7
7
  require('fs');
8
8
  require('node:fs');