@open-agent-toolkit/cli 0.2.65 → 0.2.66

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 (142) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/cli-utilities/configuration.md +19 -1
  3. package/assets/docs/cli-utilities/index.md +3 -0
  4. package/assets/docs/cli-utilities/remote-project-management.md +191 -0
  5. package/assets/docs/reference/cli-reference.md +12 -1
  6. package/assets/docs/reference/file-locations.md +22 -0
  7. package/assets/docs/reference/oat-directory-structure.md +30 -17
  8. package/assets/docs/reference/troubleshooting.md +44 -0
  9. package/assets/docs/workflows/skills/index.md +33 -0
  10. package/assets/public-package-versions.json +4 -4
  11. package/assets/skills/oat-doctor/SKILL.md +4 -4
  12. package/assets/skills/oat-pjm-remote/SKILL.md +101 -0
  13. package/assets/skills/oat-pjm-remote/references/external-action-protocol.md +43 -0
  14. package/dist/commands/backlog/new.d.ts +1 -0
  15. package/dist/commands/backlog/new.d.ts.map +1 -1
  16. package/dist/commands/backlog/new.js +3 -1
  17. package/dist/commands/config/index.d.ts +1 -0
  18. package/dist/commands/config/index.d.ts.map +1 -1
  19. package/dist/commands/config/index.js +232 -1
  20. package/dist/commands/pjm/doctor.d.ts +2 -0
  21. package/dist/commands/pjm/doctor.d.ts.map +1 -1
  22. package/dist/commands/pjm/doctor.js +71 -1
  23. package/dist/commands/pjm/index.d.ts +2 -0
  24. package/dist/commands/pjm/index.d.ts.map +1 -1
  25. package/dist/commands/pjm/index.js +3 -0
  26. package/dist/commands/pjm/remote/__integration__/lifecycle-harness.d.ts +60 -0
  27. package/dist/commands/pjm/remote/__integration__/lifecycle-harness.d.ts.map +1 -0
  28. package/dist/commands/pjm/remote/__integration__/lifecycle-harness.js +151 -0
  29. package/dist/commands/pjm/remote/association.d.ts +27 -0
  30. package/dist/commands/pjm/remote/association.d.ts.map +1 -0
  31. package/dist/commands/pjm/remote/association.js +68 -0
  32. package/dist/commands/pjm/remote/authority.d.ts +210 -0
  33. package/dist/commands/pjm/remote/authority.d.ts.map +1 -0
  34. package/dist/commands/pjm/remote/authority.js +341 -0
  35. package/dist/commands/pjm/remote/batch.d.ts +15 -0
  36. package/dist/commands/pjm/remote/batch.d.ts.map +1 -0
  37. package/dist/commands/pjm/remote/batch.js +126 -0
  38. package/dist/commands/pjm/remote/closeout.d.ts +69 -0
  39. package/dist/commands/pjm/remote/closeout.d.ts.map +1 -0
  40. package/dist/commands/pjm/remote/closeout.js +208 -0
  41. package/dist/commands/pjm/remote/create-binding.d.ts +62 -0
  42. package/dist/commands/pjm/remote/create-binding.d.ts.map +1 -0
  43. package/dist/commands/pjm/remote/create-binding.js +126 -0
  44. package/dist/commands/pjm/remote/credential-safety.d.ts +7 -0
  45. package/dist/commands/pjm/remote/credential-safety.d.ts.map +1 -0
  46. package/dist/commands/pjm/remote/credential-safety.js +21 -0
  47. package/dist/commands/pjm/remote/discussion.d.ts +49 -0
  48. package/dist/commands/pjm/remote/discussion.d.ts.map +1 -0
  49. package/dist/commands/pjm/remote/discussion.js +124 -0
  50. package/dist/commands/pjm/remote/doctor.d.ts +22 -0
  51. package/dist/commands/pjm/remote/doctor.d.ts.map +1 -0
  52. package/dist/commands/pjm/remote/doctor.js +380 -0
  53. package/dist/commands/pjm/remote/external-action.d.ts +208 -0
  54. package/dist/commands/pjm/remote/external-action.d.ts.map +1 -0
  55. package/dist/commands/pjm/remote/external-action.js +367 -0
  56. package/dist/commands/pjm/remote/host-execution.d.ts +28 -0
  57. package/dist/commands/pjm/remote/host-execution.d.ts.map +1 -0
  58. package/dist/commands/pjm/remote/host-execution.js +63 -0
  59. package/dist/commands/pjm/remote/index.d.ts +41 -0
  60. package/dist/commands/pjm/remote/index.d.ts.map +1 -0
  61. package/dist/commands/pjm/remote/index.js +280 -0
  62. package/dist/commands/pjm/remote/jira-adf.d.ts +35 -0
  63. package/dist/commands/pjm/remote/jira-adf.d.ts.map +1 -0
  64. package/dist/commands/pjm/remote/jira-adf.js +169 -0
  65. package/dist/commands/pjm/remote/lifecycle.d.ts +163 -0
  66. package/dist/commands/pjm/remote/lifecycle.d.ts.map +1 -0
  67. package/dist/commands/pjm/remote/lifecycle.js +224 -0
  68. package/dist/commands/pjm/remote/local-projection.d.ts +30 -0
  69. package/dist/commands/pjm/remote/local-projection.d.ts.map +1 -0
  70. package/dist/commands/pjm/remote/local-projection.js +95 -0
  71. package/dist/commands/pjm/remote/managed-markdown.d.ts +30 -0
  72. package/dist/commands/pjm/remote/managed-markdown.d.ts.map +1 -0
  73. package/dist/commands/pjm/remote/managed-markdown.js +128 -0
  74. package/dist/commands/pjm/remote/migrate.d.ts +14 -0
  75. package/dist/commands/pjm/remote/migrate.d.ts.map +1 -0
  76. package/dist/commands/pjm/remote/migrate.js +32 -0
  77. package/dist/commands/pjm/remote/operation-state.d.ts +15 -0
  78. package/dist/commands/pjm/remote/operation-state.d.ts.map +1 -0
  79. package/dist/commands/pjm/remote/operation-state.js +143 -0
  80. package/dist/commands/pjm/remote/outbound-projection-safety.d.ts +25 -0
  81. package/dist/commands/pjm/remote/outbound-projection-safety.d.ts.map +1 -0
  82. package/dist/commands/pjm/remote/outbound-projection-safety.js +99 -0
  83. package/dist/commands/pjm/remote/output.d.ts +60 -0
  84. package/dist/commands/pjm/remote/output.d.ts.map +1 -0
  85. package/dist/commands/pjm/remote/output.js +48 -0
  86. package/dist/commands/pjm/remote/preview.d.ts +88 -0
  87. package/dist/commands/pjm/remote/preview.d.ts.map +1 -0
  88. package/dist/commands/pjm/remote/preview.js +154 -0
  89. package/dist/commands/pjm/remote/provider-conformance.d.ts +13 -0
  90. package/dist/commands/pjm/remote/provider-conformance.d.ts.map +1 -0
  91. package/dist/commands/pjm/remote/provider-conformance.js +37 -0
  92. package/dist/commands/pjm/remote/provider.d.ts +57 -0
  93. package/dist/commands/pjm/remote/provider.d.ts.map +1 -0
  94. package/dist/commands/pjm/remote/provider.js +28 -0
  95. package/dist/commands/pjm/remote/providers/github-publication-safety.d.ts +46 -0
  96. package/dist/commands/pjm/remote/providers/github-publication-safety.d.ts.map +1 -0
  97. package/dist/commands/pjm/remote/providers/github-publication-safety.js +126 -0
  98. package/dist/commands/pjm/remote/providers/github.d.ts +207 -0
  99. package/dist/commands/pjm/remote/providers/github.d.ts.map +1 -0
  100. package/dist/commands/pjm/remote/providers/github.js +1456 -0
  101. package/dist/commands/pjm/remote/providers/jira.d.ts +245 -0
  102. package/dist/commands/pjm/remote/providers/jira.d.ts.map +1 -0
  103. package/dist/commands/pjm/remote/providers/jira.js +1650 -0
  104. package/dist/commands/pjm/remote/providers/linear.d.ts +182 -0
  105. package/dist/commands/pjm/remote/providers/linear.d.ts.map +1 -0
  106. package/dist/commands/pjm/remote/providers/linear.js +1289 -0
  107. package/dist/commands/pjm/remote/purpose-policy.d.ts +29 -0
  108. package/dist/commands/pjm/remote/purpose-policy.d.ts.map +1 -0
  109. package/dist/commands/pjm/remote/purpose-policy.js +118 -0
  110. package/dist/commands/pjm/remote/reconcile.d.ts +42 -0
  111. package/dist/commands/pjm/remote/reconcile.d.ts.map +1 -0
  112. package/dist/commands/pjm/remote/reconcile.js +101 -0
  113. package/dist/commands/pjm/remote/resolution.d.ts +122 -0
  114. package/dist/commands/pjm/remote/resolution.d.ts.map +1 -0
  115. package/dist/commands/pjm/remote/resolution.js +243 -0
  116. package/dist/commands/pjm/remote/schema.d.ts +9309 -0
  117. package/dist/commands/pjm/remote/schema.d.ts.map +1 -0
  118. package/dist/commands/pjm/remote/schema.js +1503 -0
  119. package/dist/commands/pjm/remote/service.d.ts +20 -0
  120. package/dist/commands/pjm/remote/service.d.ts.map +1 -0
  121. package/dist/commands/pjm/remote/service.js +5121 -0
  122. package/dist/commands/pjm/remote/shared-storage.d.ts +36 -0
  123. package/dist/commands/pjm/remote/shared-storage.d.ts.map +1 -0
  124. package/dist/commands/pjm/remote/shared-storage.js +110 -0
  125. package/dist/commands/pjm/remote/snapshot.d.ts +32 -0
  126. package/dist/commands/pjm/remote/snapshot.d.ts.map +1 -0
  127. package/dist/commands/pjm/remote/snapshot.js +140 -0
  128. package/dist/commands/pjm/remote/storage-locator.d.ts +29 -0
  129. package/dist/commands/pjm/remote/storage-locator.d.ts.map +1 -0
  130. package/dist/commands/pjm/remote/storage-locator.js +62 -0
  131. package/dist/commands/pjm/remote/store.d.ts +85 -0
  132. package/dist/commands/pjm/remote/store.d.ts.map +1 -0
  133. package/dist/commands/pjm/remote/store.js +553 -0
  134. package/dist/commands/pjm/remote/verification.d.ts +40 -0
  135. package/dist/commands/pjm/remote/verification.d.ts.map +1 -0
  136. package/dist/commands/pjm/remote/verification.js +100 -0
  137. package/dist/commands/tools/shared/pack-manifest.d.ts.map +1 -1
  138. package/dist/commands/tools/shared/pack-manifest.js +1 -0
  139. package/dist/config/oat-config.d.ts +26 -0
  140. package/dist/config/oat-config.d.ts.map +1 -1
  141. package/dist/config/oat-config.js +186 -2
  142. package/package.json +2 -2
@@ -0,0 +1,36 @@
1
+ export interface SharedStoragePreview {
2
+ schemaVersion: 1;
3
+ digest: string;
4
+ repositoryFingerprint: string;
5
+ configTarget: string;
6
+ targetKind: 'repository' | 'project';
7
+ projectScope: 'shared' | 'synced' | 'local' | null;
8
+ currentMode: 'local' | 'shared';
9
+ proposedMode: 'shared';
10
+ retainedDataWarning: string;
11
+ proposedPaths: string[];
12
+ createdAt: string;
13
+ }
14
+ export declare function parseSharedStoragePreview(value: unknown): SharedStoragePreview;
15
+ export declare function buildSharedStoragePreview(input: Omit<SharedStoragePreview, 'schemaVersion' | 'digest' | 'proposedMode'>): SharedStoragePreview;
16
+ export declare function applySharedStorageTransition(input: {
17
+ preview: SharedStoragePreview;
18
+ approval: {
19
+ previewDigest: string;
20
+ approvedAt: string;
21
+ actor: string;
22
+ source: string;
23
+ } | null;
24
+ now: string;
25
+ maxAgeMs: number;
26
+ current: {
27
+ repositoryFingerprint: string;
28
+ configTarget: string;
29
+ mode: 'local' | 'shared';
30
+ };
31
+ writeSharedConfig(mode: 'shared'): Promise<void>;
32
+ }): Promise<{
33
+ status: 'applied';
34
+ movedRecords: false;
35
+ }>;
36
+ //# sourceMappingURL=shared-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-storage.d.ts","sourceRoot":"","sources":["../../../../src/commands/pjm/remote/shared-storage.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,CAAC,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB,EAAE,MAAM,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,YAAY,GAAG,SAAS,CAAC;IACrC,YAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAC;IACnD,WAAW,EAAE,OAAO,GAAG,QAAQ,CAAC;IAChC,YAAY,EAAE,QAAQ,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAkBD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,oBAAoB,CAgBtB;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,IAAI,CACT,oBAAoB,EACpB,eAAe,GAAG,QAAQ,GAAG,cAAc,CAC5C,GACA,oBAAoB,CAqBtB;AAED,wBAAsB,4BAA4B,CAAC,KAAK,EAAE;IACxD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,IAAI,CAAC;IACT,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE;QACP,qBAAqB,EAAE,MAAM,CAAC;QAC9B,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;KAC1B,CAAC;IACF,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,KAAK,CAAA;CAAE,CAAC,CA0DtD"}
@@ -0,0 +1,110 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { containsSensitiveContentSignal } from './credential-safety.js';
4
+ const SharedStoragePreviewSchema = z
5
+ .object({
6
+ schemaVersion: z.literal(1),
7
+ digest: z.string().min(1).max(512),
8
+ repositoryFingerprint: z.string().min(1).max(512),
9
+ configTarget: z.string().min(1).max(4_096),
10
+ targetKind: z.enum(['repository', 'project']),
11
+ projectScope: z.enum(['shared', 'synced', 'local']).nullable(),
12
+ currentMode: z.enum(['local', 'shared']),
13
+ proposedMode: z.literal('shared'),
14
+ retainedDataWarning: z.string().min(1).max(8_192),
15
+ proposedPaths: z.array(z.string().min(1).max(4_096)).min(1).max(64),
16
+ createdAt: z.string().datetime({ offset: true }),
17
+ })
18
+ .strict();
19
+ export function parseSharedStoragePreview(value) {
20
+ const preview = SharedStoragePreviewSchema.parse(value);
21
+ const rebuilt = buildSharedStoragePreview({
22
+ repositoryFingerprint: preview.repositoryFingerprint,
23
+ configTarget: preview.configTarget,
24
+ targetKind: preview.targetKind,
25
+ projectScope: preview.projectScope,
26
+ currentMode: preview.currentMode,
27
+ retainedDataWarning: preview.retainedDataWarning,
28
+ proposedPaths: preview.proposedPaths,
29
+ createdAt: preview.createdAt,
30
+ });
31
+ if (rebuilt.digest !== preview.digest) {
32
+ throw new Error('Shared storage preview digest is stale or mismatched.');
33
+ }
34
+ return preview;
35
+ }
36
+ export function buildSharedStoragePreview(input) {
37
+ if (input.targetKind === 'project' && input.projectScope === 'local') {
38
+ throw new Error('Local project targets cannot use shared operational storage.');
39
+ }
40
+ if (!input.repositoryFingerprint ||
41
+ !input.configTarget ||
42
+ input.proposedPaths.length === 0) {
43
+ throw new Error('Shared storage preview requires repository, config target, and proposed paths.');
44
+ }
45
+ const body = {
46
+ schemaVersion: 1,
47
+ ...input,
48
+ proposedMode: 'shared',
49
+ };
50
+ return { ...body, digest: digest(body) };
51
+ }
52
+ export async function applySharedStorageTransition(input) {
53
+ if (!input.approval)
54
+ throw new Error('Shared storage transition requires fresh preview approval.');
55
+ const rebuilt = buildSharedStoragePreview({
56
+ repositoryFingerprint: input.preview.repositoryFingerprint,
57
+ configTarget: input.preview.configTarget,
58
+ targetKind: input.preview.targetKind,
59
+ projectScope: input.preview.projectScope,
60
+ currentMode: input.preview.currentMode,
61
+ retainedDataWarning: input.preview.retainedDataWarning,
62
+ proposedPaths: input.preview.proposedPaths,
63
+ createdAt: input.preview.createdAt,
64
+ });
65
+ if (rebuilt.digest !== input.preview.digest ||
66
+ input.approval.previewDigest !== input.preview.digest) {
67
+ throw new Error('Shared storage approval is stale or mismatched.');
68
+ }
69
+ if (input.current.repositoryFingerprint !==
70
+ input.preview.repositoryFingerprint ||
71
+ input.current.configTarget !== input.preview.configTarget ||
72
+ input.current.mode !== input.preview.currentMode) {
73
+ throw new Error('Shared storage preview inputs changed before apply.');
74
+ }
75
+ const approvedAt = Date.parse(input.approval.approvedAt);
76
+ const previewAt = Date.parse(input.preview.createdAt);
77
+ const now = Date.parse(input.now);
78
+ if (!Number.isFinite(approvedAt) ||
79
+ !Number.isFinite(previewAt) ||
80
+ !Number.isFinite(now) ||
81
+ !Number.isFinite(input.maxAgeMs) ||
82
+ input.maxAgeMs < 0) {
83
+ throw new Error('Shared storage approval contains an invalid time.');
84
+ }
85
+ if (approvedAt < previewAt) {
86
+ throw new Error('Shared storage approval predates its preview.');
87
+ }
88
+ if (approvedAt > now) {
89
+ throw new Error('Shared storage approval is dated in the future.');
90
+ }
91
+ if (now - approvedAt > input.maxAgeMs) {
92
+ throw new Error('Shared storage approval is expired.');
93
+ }
94
+ if (!isSafeEvidence(input.approval.actor) ||
95
+ !isSafeEvidence(input.approval.source)) {
96
+ throw new Error('Shared storage approval evidence is unsafe.');
97
+ }
98
+ await input.writeSharedConfig('shared');
99
+ return { status: 'applied', movedRecords: false };
100
+ }
101
+ function isSafeEvidence(value) {
102
+ return (value.length > 0 &&
103
+ value.length <= 255 &&
104
+ !/[\r\n]/.test(value) &&
105
+ !value.includes('\0') &&
106
+ !containsSensitiveContentSignal(value));
107
+ }
108
+ function digest(value) {
109
+ return `sha256:${createHash('sha256').update(JSON.stringify(value)).digest('hex')}`;
110
+ }
@@ -0,0 +1,32 @@
1
+ import { type RemoteSnapshotRecord } from './schema.js';
2
+ export interface SanitizableRemoteSnapshot {
3
+ snapshotId: string;
4
+ bindingId: string;
5
+ provider: RemoteSnapshotRecord['provider'];
6
+ observedAt: string;
7
+ observedBy: RemoteSnapshotRecord['observedBy'];
8
+ identity: RemoteSnapshotRecord['identity'];
9
+ revision: RemoteSnapshotRecord['revision'];
10
+ issue: {
11
+ title: string;
12
+ description: string;
13
+ priority: string | null;
14
+ status: string;
15
+ [key: string]: unknown;
16
+ };
17
+ lifecycle: RemoteSnapshotRecord['lifecycle'];
18
+ extensions?: Record<string, unknown>;
19
+ [key: string]: unknown;
20
+ }
21
+ export interface SnapshotSanitizationOptions {
22
+ allowedExtensionKeys?: readonly string[];
23
+ suppressedCoreFields?: readonly CoreSnapshotField[];
24
+ suppressedFields?: readonly SnapshotRedaction['field'][];
25
+ }
26
+ type SnapshotRedaction = RemoteSnapshotRecord['redactions'][number];
27
+ type CoreSnapshotField = Extract<SnapshotRedaction['field'], {
28
+ kind: 'core';
29
+ }>['name'];
30
+ export declare function sanitizeRemoteSnapshot(input: SanitizableRemoteSnapshot, options?: SnapshotSanitizationOptions): RemoteSnapshotRecord;
31
+ export {};
32
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../../../src/commands/pjm/remote/snapshot.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,KAAK,oBAAoB,EAC1B,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAC/C,QAAQ,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC3C,QAAQ,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC3C,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,SAAS,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,oBAAoB,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACpD,gBAAgB,CAAC,EAAE,SAAS,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;CAC1D;AAOD,KAAK,iBAAiB,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,KAAK,iBAAiB,GAAG,OAAO,CAC9B,iBAAiB,CAAC,OAAO,CAAC,EAC1B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CACjB,CAAC,MAAM,CAAC,CAAC;AAEV,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,yBAAyB,EAChC,OAAO,GAAE,2BAAgC,GACxC,oBAAoB,CAiEtB"}
@@ -0,0 +1,140 @@
1
+ import { containsSensitiveContentSignal, containsSensitiveContentSignalInValue, } from './credential-safety.js';
2
+ import { MAX_PROVIDER_EXTENSION_BYTES, MAX_SNAPSHOT_SUPPRESSION_EVIDENCE, RemoteSnapshotRecordSchema, WHOLE_FIELD_SUPPRESSION_MARKER, } from './schema.js';
3
+ const CORE_SNAPSHOT_FIELD_COUNT = 4;
4
+ const MAX_ALLOWED_EXTENSION_KEYS = MAX_SNAPSHOT_SUPPRESSION_EVIDENCE - CORE_SNAPSHOT_FIELD_COUNT;
5
+ const SCHEMA_SAFE_EXTENSION_KEY = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
6
+ export function sanitizeRemoteSnapshot(input, options = {}) {
7
+ const redactions = [];
8
+ const pairedSuppression = validateSuppressedFieldReferences(options.suppressedFields ?? [], options.allowedExtensionKeys ?? []);
9
+ const suppressedCoreFields = validateSuppressedCoreFields([
10
+ ...(options.suppressedCoreFields ?? []),
11
+ ...pairedSuppression.core,
12
+ ]);
13
+ const issue = {
14
+ title: sanitizeCoreField('title', input.issue.title, redactions, suppressedCoreFields),
15
+ description: sanitizeCoreField('description', input.issue.description, redactions, suppressedCoreFields),
16
+ priority: input.issue.priority === null
17
+ ? null
18
+ : sanitizeCoreField('priority', input.issue.priority, redactions, suppressedCoreFields),
19
+ status: sanitizeCoreField('status', input.issue.status, redactions, suppressedCoreFields),
20
+ };
21
+ const extensions = sanitizeExtensions(input.provider, input.extensions, options.allowedExtensionKeys ?? [], redactions, pairedSuppression.extensions);
22
+ return RemoteSnapshotRecordSchema.parse({
23
+ recordType: 'snapshot',
24
+ schemaVersion: 2,
25
+ snapshotId: input.snapshotId,
26
+ bindingId: input.bindingId,
27
+ provider: input.provider,
28
+ observedAt: input.observedAt,
29
+ observedBy: input.observedBy,
30
+ identity: input.identity,
31
+ revision: input.revision,
32
+ issue,
33
+ lifecycle: input.lifecycle,
34
+ contentRedacted: redactions.length > 0,
35
+ redactionCount: redactions.length,
36
+ redactions,
37
+ extensions,
38
+ });
39
+ }
40
+ function sanitizeCoreField(field, value, redactions, suppressedCoreFields) {
41
+ if (suppressedCoreFields.has(field)) {
42
+ if (value !== WHOLE_FIELD_SUPPRESSION_MARKER) {
43
+ throw new Error(`Suppressed snapshot field '${field}' must contain only the suppression marker.`);
44
+ }
45
+ redactions.push({
46
+ field: { kind: 'core', name: field },
47
+ reason: 'sensitive-content',
48
+ representation: 'whole-field-marker',
49
+ });
50
+ return value;
51
+ }
52
+ if (!containsSensitiveContentSignal(value))
53
+ return value;
54
+ redactions.push({
55
+ field: { kind: 'core', name: field },
56
+ reason: 'sensitive-content',
57
+ representation: 'whole-field-marker',
58
+ });
59
+ return WHOLE_FIELD_SUPPRESSION_MARKER;
60
+ }
61
+ function validateSuppressedCoreFields(fields) {
62
+ const allowed = new Set([
63
+ 'title',
64
+ 'description',
65
+ 'priority',
66
+ 'status',
67
+ ]);
68
+ if (fields.length > CORE_SNAPSHOT_FIELD_COUNT ||
69
+ new Set(fields).size !== fields.length ||
70
+ fields.some((field) => !allowed.has(field))) {
71
+ throw new Error('Suppressed snapshot fields must be unique bounded core fields.');
72
+ }
73
+ return new Set(fields);
74
+ }
75
+ function validateSuppressedFieldReferences(fields, allowedExtensionKeys) {
76
+ if (fields.length > MAX_SNAPSHOT_SUPPRESSION_EVIDENCE) {
77
+ throw new Error('Suppression evidence exceeds the bounded field limit.');
78
+ }
79
+ const identities = fields.map((field) => field.kind === 'core' ? `core:${field.name}` : `extension:${field.key}`);
80
+ if (new Set(identities).size !== identities.length) {
81
+ throw new Error('Suppression evidence must consume each field once.');
82
+ }
83
+ const allowed = new Set(allowedExtensionKeys);
84
+ const extensions = fields.flatMap((field) => field.kind === 'extension' ? [field.key] : []);
85
+ if (extensions.some((key) => !allowed.has(key))) {
86
+ throw new Error('Suppressed adapter extensions must be present in the adapter allowlist.');
87
+ }
88
+ return {
89
+ core: fields.flatMap((field) => field.kind === 'core' ? [field.name] : []),
90
+ extensions: new Set(extensions),
91
+ };
92
+ }
93
+ function sanitizeExtensions(provider, extensions, allowedKeys, redactions, suppressedExtensions) {
94
+ validateExtensionAllowlist(allowedKeys);
95
+ if (!extensions || allowedKeys.length === 0)
96
+ return undefined;
97
+ const retained = {};
98
+ for (const key of allowedKeys) {
99
+ if (!Object.hasOwn(extensions, key))
100
+ continue;
101
+ const value = extensions[key];
102
+ if (suppressedExtensions.has(key)) {
103
+ if (value !== WHOLE_FIELD_SUPPRESSION_MARKER) {
104
+ throw new Error(`Suppressed adapter extension '${key}' must contain only the suppression marker.`);
105
+ }
106
+ retained[key] = value;
107
+ redactions.push({
108
+ field: { kind: 'extension', key },
109
+ reason: 'sensitive-content',
110
+ representation: 'whole-field-marker',
111
+ });
112
+ continue;
113
+ }
114
+ if (containsSensitiveContentSignalInValue(value)) {
115
+ retained[key] = WHOLE_FIELD_SUPPRESSION_MARKER;
116
+ redactions.push({
117
+ field: { kind: 'extension', key },
118
+ reason: 'sensitive-content',
119
+ representation: 'whole-field-marker',
120
+ });
121
+ continue;
122
+ }
123
+ retained[key] = value;
124
+ }
125
+ if (Object.keys(retained).length === 0)
126
+ return undefined;
127
+ const result = { [provider]: retained };
128
+ if (Buffer.byteLength(JSON.stringify(result), 'utf8') >
129
+ MAX_PROVIDER_EXTENSION_BYTES) {
130
+ throw new Error(`Provider extension exceeds ${MAX_PROVIDER_EXTENSION_BYTES} byte limit.`);
131
+ }
132
+ return result;
133
+ }
134
+ function validateExtensionAllowlist(allowedKeys) {
135
+ if (allowedKeys.length > MAX_ALLOWED_EXTENSION_KEYS ||
136
+ new Set(allowedKeys).size !== allowedKeys.length ||
137
+ allowedKeys.some((key) => !SCHEMA_SAFE_EXTENSION_KEY.test(key))) {
138
+ throw new Error('Adapter extension keys must be unique, bounded, and schema-safe.');
139
+ }
140
+ }
@@ -0,0 +1,29 @@
1
+ export type RemoteStorageClass = 'shared' | 'synced' | 'local';
2
+ export interface RemoteStorageTarget {
3
+ kind: 'backlog' | 'project';
4
+ scope: RemoteStorageClass;
5
+ path: string | null;
6
+ }
7
+ export interface ResolveRemoteStorageLocationsInput {
8
+ repoRoot: string;
9
+ gitCommonDir: string;
10
+ repositoryIdentity: string;
11
+ stateStorage: 'local' | 'shared';
12
+ target: RemoteStorageTarget;
13
+ }
14
+ export interface RemoteStorageLocations {
15
+ repositoryFingerprint: string;
16
+ portable: {
17
+ storageClass: RemoteStorageClass;
18
+ bindingsDir: string;
19
+ };
20
+ operational: {
21
+ storageClass: 'local' | 'shared';
22
+ root: string;
23
+ bindingsDir: string;
24
+ operationsDir: string;
25
+ batchesDir: string;
26
+ };
27
+ }
28
+ export declare function resolveRemoteStorageLocations(input: ResolveRemoteStorageLocationsInput): RemoteStorageLocations;
29
+ //# sourceMappingURL=storage-locator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-locator.d.ts","sourceRoot":"","sources":["../../../../src/commands/pjm/remote/storage-locator.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IAC5B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,kCAAkC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,OAAO,GAAG,QAAQ,CAAC;IACjC,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACrC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE;QACR,YAAY,EAAE,kBAAkB,CAAC;QACjC,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,WAAW,EAAE;QACX,YAAY,EAAE,OAAO,GAAG,QAAQ,CAAC;QACjC,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,kCAAkC,GACxC,sBAAsB,CAyCxB"}
@@ -0,0 +1,62 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { isAbsolute, join, relative, resolve } from 'node:path';
3
+ export function resolveRemoteStorageLocations(input) {
4
+ const repoRoot = resolve(input.repoRoot);
5
+ const gitCommonDir = resolve(input.gitCommonDir);
6
+ const repositoryFingerprint = fingerprintRepository(input.repositoryIdentity);
7
+ const localOperationalRoot = join(gitCommonDir, 'oat', 'pjm-remote', repositoryFingerprint);
8
+ const ownerRemoteRoot = resolveOwnerRemoteRoot(repoRoot, input.target);
9
+ if (input.stateStorage === 'shared' && input.target.scope === 'local') {
10
+ throw new Error('Local projects cannot use shared operational storage; choose local state storage.');
11
+ }
12
+ const operationalRoot = input.stateStorage === 'shared'
13
+ ? join(ownerRemoteRoot, 'state')
14
+ : localOperationalRoot;
15
+ const portableBindingsDir = input.target.scope === 'local'
16
+ ? join(localOperationalRoot, 'metadata', 'bindings')
17
+ : join(ownerRemoteRoot, 'bindings');
18
+ return {
19
+ repositoryFingerprint,
20
+ portable: {
21
+ storageClass: input.target.scope,
22
+ bindingsDir: portableBindingsDir,
23
+ },
24
+ operational: {
25
+ storageClass: input.stateStorage,
26
+ root: operationalRoot,
27
+ bindingsDir: join(operationalRoot, 'bindings'),
28
+ operationsDir: join(operationalRoot, 'operations'),
29
+ batchesDir: join(operationalRoot, 'batches'),
30
+ },
31
+ };
32
+ }
33
+ function resolveOwnerRemoteRoot(repoRoot, target) {
34
+ if (target.kind === 'backlog') {
35
+ if (target.scope !== 'shared') {
36
+ throw new Error('Backlog remote metadata must use shared scope.');
37
+ }
38
+ return join(repoRoot, '.oat', 'repo', 'pjm', 'remote');
39
+ }
40
+ if (!target.path || !isAbsolute(target.path)) {
41
+ throw new Error('Project remote storage requires an absolute project path.');
42
+ }
43
+ const projectPath = resolve(target.path);
44
+ const relativePath = relative(repoRoot, projectPath);
45
+ if (relativePath === '..' ||
46
+ relativePath.startsWith(`..${process.platform === 'win32' ? '\\' : '/'}`) ||
47
+ isAbsolute(relativePath)) {
48
+ throw new Error('Project remote storage path must remain inside the repository.');
49
+ }
50
+ return join(projectPath, 'remote');
51
+ }
52
+ function fingerprintRepository(repositoryIdentity) {
53
+ const normalized = repositoryIdentity
54
+ .trim()
55
+ .replace(/\.git$/i, '')
56
+ .replace(/\/$/, '')
57
+ .toLowerCase();
58
+ if (!normalized) {
59
+ throw new Error('A stable repository identity is required for remote state.');
60
+ }
61
+ return createHash('sha256').update(normalized).digest('hex').slice(0, 24);
62
+ }
@@ -0,0 +1,85 @@
1
+ import { type ExternalActionEnvelope } from './external-action.js';
2
+ import { type RemoteBatchRecord, type RemoteBindingMetadata, type RemoteBindingState, type RemoteOperationOutcome, type RemoteOperationRecord, type RemoteOperationStep, type FieldVerification, type PlannedBindingCreate, type VerifiedDurableRemoteIdentity } from './schema.js';
3
+ import { type SharedStoragePreview } from './shared-storage.js';
4
+ import type { RemoteStorageLocations } from './storage-locator.js';
5
+ export interface RemoteStoreFileHandle {
6
+ writeFile(data: string): Promise<unknown>;
7
+ sync(): Promise<void>;
8
+ close(): Promise<void>;
9
+ }
10
+ export interface RemoteStoreFilesystem {
11
+ mkdir(path: string, options: {
12
+ recursive: true;
13
+ mode: number;
14
+ }): Promise<unknown>;
15
+ open(path: string, flags: string, mode?: number): Promise<RemoteStoreFileHandle>;
16
+ readFile(path: string, encoding: 'utf8'): Promise<string>;
17
+ readdir(path: string): Promise<string[]>;
18
+ rename(from: string, to: string): Promise<void>;
19
+ unlink(path: string): Promise<void>;
20
+ syncDirectory(path: string): Promise<void>;
21
+ }
22
+ export declare const defaultRemoteStoreFilesystem: RemoteStoreFilesystem;
23
+ export interface RemoteSyncStoreDependencies {
24
+ filesystem: RemoteStoreFilesystem;
25
+ randomId: () => string;
26
+ }
27
+ export type RemoteOperationState = RemoteOperationRecord['state'];
28
+ export interface RemoteOperationTransition {
29
+ state: RemoteOperationState;
30
+ updatedAt: string;
31
+ approval?: RemoteOperationRecord['approval'];
32
+ selectedExecution?: RemoteOperationRecord['selectedExecution'];
33
+ outcome?: RemoteOperationOutcome;
34
+ appendStep?: RemoteOperationStep;
35
+ verification?: FieldVerification[];
36
+ lastSafeStep?: RemoteOperationRecord['lastSafeStep'];
37
+ retryDisposition?: RemoteOperationRecord['retryDisposition'];
38
+ appendAttempt?: RemoteOperationRecord['attempts'][number];
39
+ completeAttempt?: {
40
+ attemptId: string;
41
+ completedAt: string;
42
+ receiptDigest: string;
43
+ };
44
+ appendObservation?: RemoteOperationRecord['observations'][number];
45
+ appendMaterializationStep?: NonNullable<RemoteOperationRecord['materializationSteps']>[number];
46
+ materializationPlan?: NonNullable<RemoteOperationRecord['materializationPlan']>;
47
+ verificationHandoff?: NonNullable<RemoteOperationRecord['verificationHandoff']>;
48
+ currentAction?: NonNullable<RemoteOperationRecord['currentAction']>;
49
+ }
50
+ export interface ConcurrentOperationIntentInspection {
51
+ bindingState: RemoteBindingState | null;
52
+ activeOperations: RemoteOperationRecord[];
53
+ hasConcurrentIntents: boolean;
54
+ }
55
+ export declare class RemoteSyncStore {
56
+ #private;
57
+ readonly locations: RemoteStorageLocations;
58
+ constructor(locations: RemoteStorageLocations, dependencies?: Partial<RemoteSyncStoreDependencies>);
59
+ readBindingMetadata(bindingId: string): Promise<RemoteBindingMetadata | null>;
60
+ materializeVerifiedBinding(operationId: string, record: RemoteBindingMetadata, verification: VerifiedDurableRemoteIdentity): Promise<void>;
61
+ listBindingMetadata(): Promise<RemoteBindingMetadata[]>;
62
+ updateBindingMetadata(record: RemoteBindingMetadata): Promise<void>;
63
+ readBindingState(bindingId: string): Promise<RemoteBindingState | null>;
64
+ writeBindingState(record: RemoteBindingState): Promise<void>;
65
+ readOperation(operationId: string): Promise<RemoteOperationRecord | null>;
66
+ readCurrentAction(operationId: string): Promise<ExternalActionEnvelope | null>;
67
+ writeCurrentAction(operationId: string, action: ExternalActionEnvelope): Promise<void>;
68
+ writeActionEvidence(operationId: string, action: ExternalActionEnvelope): Promise<ExternalActionEnvelope>;
69
+ retireCurrentAction(operationId: string, expectedAction: ExternalActionEnvelope): Promise<void>;
70
+ retireCurrentActionPointerIfPresent(operationId: string, expectedAction: ExternalActionEnvelope): Promise<void>;
71
+ readAction(operationId: string, stepId: string): Promise<ExternalActionEnvelope | null>;
72
+ readSharedStoragePreview(): Promise<SharedStoragePreview | null>;
73
+ writeSharedStoragePreview(preview: SharedStoragePreview): Promise<void>;
74
+ materializeIntakeBinding(record: RemoteBindingMetadata): Promise<void>;
75
+ createOperation(record: RemoteOperationRecord): Promise<void>;
76
+ updateOperation(record: RemoteOperationRecord): Promise<void>;
77
+ createBindingIntent(intent: PlannedBindingCreate): Promise<void>;
78
+ listActiveOperations(bindingId: string): Promise<RemoteOperationRecord[]>;
79
+ detectConcurrentOperationIntents(bindingId: string): Promise<ConcurrentOperationIntentInspection>;
80
+ transitionOperation(operationId: string, expectedState: RemoteOperationState, update: RemoteOperationTransition): Promise<RemoteOperationRecord>;
81
+ readBatch(batchId: string): Promise<RemoteBatchRecord | null>;
82
+ createBatch(record: RemoteBatchRecord): Promise<void>;
83
+ updateBatch(record: RemoteBatchRecord): Promise<void>;
84
+ }
85
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/commands/pjm/remote/store.ts"],"names":[],"mappings":"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"}