@gitroll/tacitt-cli 0.6.9 → 0.6.11

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 (57) hide show
  1. package/README.md +43 -4
  2. package/dist/{agent-setup-CODlN6zl.mjs → agent-setup-DdfF3zch.mjs} +2 -2
  3. package/dist/agent-setup-worker.mjs +5 -5
  4. package/dist/cli.mjs +35 -12
  5. package/dist/codex-title-worker.mjs +1 -1
  6. package/dist/configured-preview-worker.mjs +5 -5
  7. package/dist/configured-session-worker.mjs +9 -7
  8. package/dist/{frame-Dj5Zs6UW.mjs → frame-Bq2zRh-i.mjs} +1 -1
  9. package/dist/{heap-Dt3-d27v.mjs → heap-CV8Eca8V.mjs} +217 -13
  10. package/dist/inspection-worker.mjs +4 -4
  11. package/dist/{job-BQXssW46.mjs → job-BKsifhyv.mjs} +38 -18
  12. package/dist/{locate-BWkblijS.mjs → locate-Cx52Zqxv.mjs} +204 -20
  13. package/dist/{model-CSx2dP_P.mjs → model-C1UXkHh9.mjs} +1 -1
  14. package/dist/operation-executor.mjs +3 -3
  15. package/dist/preview-worker.mjs +1 -1
  16. package/dist/privacy-validator.mjs +29 -2
  17. package/dist/{query-CfhcS4gd.mjs → query-AMZerUh8.mjs} +712 -215
  18. package/dist/{run-xlOaKCk8.mjs → run-CaPktPhH.mjs} +4 -4
  19. package/dist/{src-DzKuzGVH.mjs → src-D1iONla3.mjs} +2215 -1613
  20. package/dist/{src-V9GHLZQs.mjs → src-DlVbGB32.mjs} +74 -37
  21. package/dist/{src-BgsEnMsy.mjs → src-wZx_v0Ih.mjs} +297 -207
  22. package/dist/store-database-worker.mjs +1 -1
  23. package/dist/web/assets/index-CYl7eDUu.js +172 -0
  24. package/dist/web/assets/index-DzOozqms.css +1 -0
  25. package/dist/web/index.html +2 -2
  26. package/package.json +1 -1
  27. package/skills/tacitt/INDEX.md +6 -6
  28. package/skills/tacitt/SKILL.md +11 -11
  29. package/skills/tacitt/references/INDEX.md +3 -3
  30. package/skills/tacitt/references/b-method.md +2 -2
  31. package/skills/tacitt/references/bootstrap.md +2 -2
  32. package/skills/tacitt/references/classification.md +15 -5
  33. package/skills/tacitt/references/commands.md +37 -30
  34. package/skills/tacitt/references/journey.md +14 -6
  35. package/skills/tacitt/references/parallel-review.md +27 -33
  36. package/skills/tacitt/references/send.md +35 -9
  37. package/skills/tacitt/scripts/INDEX.md +37 -37
  38. package/skills/tacitt/scripts/answer.mjs +73 -15
  39. package/skills/tacitt/scripts/journey-classification-metadata.mjs +75 -26
  40. package/skills/tacitt/scripts/journey-classification-progress.mjs +1 -2
  41. package/skills/tacitt/scripts/journey-classification-validation.d.mts +13 -0
  42. package/skills/tacitt/scripts/journey-classification-validation.mjs +38 -0
  43. package/skills/tacitt/scripts/journey-classification.mjs +6 -1
  44. package/skills/tacitt/scripts/journey-consolidation.mjs +1 -0
  45. package/skills/tacitt/scripts/journey-scan-timing.d.mts +1 -0
  46. package/skills/tacitt/scripts/journey-scan-timing.mjs +19 -4
  47. package/skills/tacitt/scripts/journey-state.d.mts +15 -1
  48. package/skills/tacitt/scripts/journey-state.mjs +104 -5
  49. package/skills/tacitt/scripts/journey-tasks.d.mts +1 -0
  50. package/skills/tacitt/scripts/journey-tasks.mjs +13 -5
  51. package/skills/tacitt/scripts/journey.d.mts +46 -28
  52. package/skills/tacitt/scripts/journey.mjs +57 -8
  53. package/skills/tacitt/scripts/privacy-validator.mjs +178 -12
  54. package/skills/tacitt/scripts/review.d.mts +7 -6
  55. package/skills/tacitt/scripts/review.mjs +576 -147
  56. package/dist/web/assets/index-9UfCT_2C.js +0 -174
  57. package/dist/web/assets/index-CYJBq1px.css +0 -1
@@ -5484,12 +5484,33 @@ object({
5484
5484
  });
5485
5485
  //#endregion
5486
5486
  //#region packages/processing/src/errors.ts
5487
+ const sitePattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+){0,7}$/;
5488
+ const harnessPattern = /^[a-z]{1,16}$/;
5489
+ const versionPattern = /^\d{1,6}(?:\.\d{1,6}){1,3}(?:-[0-9A-Za-z.]{1,24})?$/;
5490
+ /** The validated site fields of `value`; anything that does not match its pattern is dropped. */
5491
+ function siteFields(value) {
5492
+ if (typeof value !== "object" || value === null) return void 0;
5493
+ const site = Reflect.get(value, "site");
5494
+ if (typeof site !== "string" || !sitePattern.test(site)) return void 0;
5495
+ const harness = Reflect.get(value, "harness");
5496
+ const harnessVersion = Reflect.get(value, "harnessVersion");
5497
+ return {
5498
+ site,
5499
+ ...typeof harness === "string" && harnessPattern.test(harness) ? { harness } : {},
5500
+ ...typeof harnessVersion === "string" && versionPattern.test(harnessVersion) ? { harnessVersion } : {}
5501
+ };
5502
+ }
5487
5503
  var ProcessingError = class extends Error {
5488
5504
  code;
5505
+ site;
5506
+ harness;
5507
+ harnessVersion;
5489
5508
  constructor(code, options) {
5490
5509
  super(code, options);
5491
5510
  this.name = "ProcessingError";
5492
5511
  this.code = code;
5512
+ const named = siteFields(options);
5513
+ if (named) Object.assign(this, named);
5493
5514
  }
5494
5515
  };
5495
5516
  function fail(code, options) {
@@ -5552,6 +5573,10 @@ const credentialNames = Object.freeze([
5552
5573
  "auth_token",
5553
5574
  "session_token",
5554
5575
  "authorization",
5576
+ "authorization_code",
5577
+ "oauth_code",
5578
+ "密碼",
5579
+ "密码",
5555
5580
  "proxy_authorization",
5556
5581
  "x_api_key",
5557
5582
  "private_key",
@@ -5837,13 +5862,13 @@ function assignments(input, output) {
5837
5862
  }
5838
5863
  if (input.field.kind === "key") return;
5839
5864
  const consumed = headers(input, output);
5840
- if (!/[:=]|--/u.test(input.text)) return;
5865
+ if (!/[:=:]|--/u.test(input.text)) return;
5841
5866
  if (!mayContainCredentialName(input.text)) return;
5842
- const expression = /(?:(?<![\p{L}\p{N}_/?&#-])(\\?["']?)([\p{L}\p{N}_-]{1,64})\1([ \t]*)[:=]([ \t]*)|(?<![\p{L}\p{N}_-])--([\p{L}\p{N}_-]{1,64})([ \t]+)(?![ \t-]))/giu;
5867
+ const expression = /(?:(?<![\p{L}\p{N}_/?&#-])(\\?["']?)((?:oauth[ \t]+)?authorization[ \t]+code|oauth[ \t]+code|[\p{L}\p{N}_-]{1,64})\1([ \t]*)[:=:]([ \t]*)|(?<![\p{L}\p{N}_-])--([\p{L}\p{N}_-]{1,64})([ \t]+)(?![ \t-]))/giu;
5843
5868
  let match;
5844
5869
  let headerIndex = 0;
5845
5870
  while ((match = expression.exec(input.text)) !== null) {
5846
- const label = normalizeCredentialName(match[2] ?? match[5] ?? "");
5871
+ const label = normalizeCredentialName((match[2] ?? match[5] ?? "").replace(/[ \t]+/gu, "_"));
5847
5872
  if (!credentialName(label)) continue;
5848
5873
  while ((consumed[headerIndex]?.end ?? Infinity) <= match.index) headerIndex += 1;
5849
5874
  const header = consumed[headerIndex];
@@ -7661,10 +7686,10 @@ function urlActions(locator, input, result) {
7661
7686
  actions: [action]
7662
7687
  });
7663
7688
  }
7664
- const inspect = (range, key, query = false) => {
7689
+ const inspect = (range, key, query = false, oauthResponse = false) => {
7665
7690
  if (range.start >= range.end) return;
7666
7691
  const raw = input.text.slice(range.start, range.end);
7667
- const credential = key !== void 0 && credentialName(key);
7692
+ const credential = key !== void 0 && (credentialName(key) || oauthResponse && key === "code");
7668
7693
  if (!withinLimit({
7669
7694
  raw,
7670
7695
  range
@@ -7711,6 +7736,8 @@ function urlActions(locator, input, result) {
7711
7736
  const end = hash < 0 ? locator.raw.length : hash;
7712
7737
  const question = locator.raw.indexOf("?", pathEnd);
7713
7738
  if (question >= 0 && question < end) {
7739
+ const keys = new URLSearchParams(locator.raw.slice(question + 1, end));
7740
+ const oauthResponse = (locator.scheme === "http" || locator.scheme === "https") && keys.has("code") && (keys.has("state") || keys.has("session_state") || /(?:^|\/)(?:oauth2?|callback|oauth2?[_-]callback)(?:\/|$)/iu.test(locator.raw.slice(suffix, pathEnd)));
7714
7741
  start = question + 1;
7715
7742
  for (let index = start; index <= end; index++) {
7716
7743
  if (index !== end && locator.raw[index] !== "&") continue;
@@ -7720,7 +7747,7 @@ function urlActions(locator, input, result) {
7720
7747
  if (key !== null) inspect({
7721
7748
  start: offset + equals + 1,
7722
7749
  end: offset + index
7723
- }, key, true);
7750
+ }, key, true, oauthResponse);
7724
7751
  } else inspect({
7725
7752
  start: offset + start,
7726
7753
  end: offset + index
@@ -9431,7 +9458,7 @@ Object.freeze([
9431
9458
  ]);
9432
9459
  Object.freeze({
9433
9460
  implementation: originalInspectionVersion,
9434
- detector: `static-catalog-11`,
9461
+ detector: `static-catalog-12`,
9435
9462
  parser: nativeParserVersion,
9436
9463
  dictionary: entityDictionaryVersion
9437
9464
  });
@@ -9679,6 +9706,24 @@ const termEvidenceSchema = object({
9679
9706
  rationale: termAssessmentSchema.shape.rationale,
9680
9707
  stance: termAssessmentSchema.shape.stance
9681
9708
  }).strict().refine((evidence) => evidence.end > evidence.start);
9709
+ const namedBatch = object({
9710
+ journeyId: id$1,
9711
+ batchId: id$1,
9712
+ batchDigest: digest$2
9713
+ }).strict();
9714
+ discriminatedUnion("kind", [namedBatch.extend({ kind: literal("inspect") }).strict(), namedBatch.extend({
9715
+ kind: literal("apply"),
9716
+ expectedPackId: id$1,
9717
+ idempotencyKey: id$1
9718
+ }).strict()]);
9719
+ object({
9720
+ status: _enum([
9721
+ "eligible",
9722
+ "reopened",
9723
+ "replayed"
9724
+ ]),
9725
+ packId: id$1
9726
+ }).strict();
9682
9727
  object({
9683
9728
  journeyId: id$1,
9684
9729
  idempotencyKey: id$1,
@@ -9688,6 +9733,10 @@ object({
9688
9733
  units: array(object({
9689
9734
  batchId: id$1,
9690
9735
  batchDigest: digest$2,
9736
+ coverage: object({
9737
+ attemptId: id$1,
9738
+ receipts: array(digest$2).min(1).max(8e4)
9739
+ }).strict().optional(),
9691
9740
  /** Legacy unit summary in stored packs; accepted and never read (ADR 0178). */
9692
9741
  summary: string().trim().min(1).refine((value) => Buffer.byteLength(value) <= 1024).optional(),
9693
9742
  exclude: string().trim().refine((value) => codePoints(value) >= 1 && codePoints(value) <= 500).nullable()
@@ -10107,6 +10156,13 @@ const journeyArtifactSchema = object({
10107
10156
  archiveBytes: count$1
10108
10157
  }).strict()
10109
10158
  }).strict();
10159
+ /** A closed reader attempt that left named units without a coverage receipt. */
10160
+ const reviewInterruptionSchema = object({
10161
+ inputRevision: count$1.min(1),
10162
+ packId: journeyIdSchema,
10163
+ reason: _enum(["reader-refused", "retry-exhausted"]),
10164
+ batchIds: array(journeyIdSchema).min(1).max(1e4).refine((ids) => new Set(ids).size === ids.length)
10165
+ }).strict();
10110
10166
  const journeyWorkSchema = object({
10111
10167
  id: journeyIdSchema,
10112
10168
  title: label,
@@ -10131,7 +10187,8 @@ const journeyWorkSchema = object({
10131
10187
  "default",
10132
10188
  "model",
10133
10189
  "explicit",
10134
- "delegate"
10190
+ "delegate",
10191
+ "account"
10135
10192
  ]),
10136
10193
  placement: _enum([
10137
10194
  "placed",
@@ -10148,6 +10205,15 @@ const journeyWorkSchema = object({
10148
10205
  grouping: _enum(["workspace", "regrouped"]),
10149
10206
  access: journeyAccessSchema,
10150
10207
  accessConfirmed: boolean(),
10208
+ accessChoice: object({
10209
+ channel: _enum([
10210
+ "conversation",
10211
+ "panel",
10212
+ "account"
10213
+ ]),
10214
+ at: datetime()
10215
+ }).strict().optional(),
10216
+ accountAccessConflict: boolean().optional(),
10151
10217
  reason: string().max(1e3),
10152
10218
  revision: count$1,
10153
10219
  inputRevision: count$1.min(1),
@@ -10188,6 +10254,7 @@ const journeyWorkSchema = object({
10188
10254
  /** Images the Work's sessions leave out (D7); absent when a session receipt predates it. */
10189
10255
  imagesOmitted: count$1.optional()
10190
10256
  }).strict().optional(),
10257
+ reviewInterruptions: array(reviewInterruptionSchema).optional(),
10191
10258
  totalBatches: count$1,
10192
10259
  completedBatches: count$1,
10193
10260
  groupIds: array(journeyIdSchema),
@@ -10211,7 +10278,12 @@ const journeyWorkSchema = object({
10211
10278
  const journeyConsentSchema = object({
10212
10279
  provider: label,
10213
10280
  allowedAt: datetime(),
10214
- source: _enum(["conversation", "panel"])
10281
+ source: _enum(["conversation", "panel"]),
10282
+ /**
10283
+ * The account signed in when consent was recorded (ADR 0276 D8). Absent in a build with no
10284
+ * sign-in client and in a journey started before this version (Q11 a, Q13 a).
10285
+ */
10286
+ subject: string().min(1).max(128).optional()
10215
10287
  }).strict();
10216
10288
  const journeyExceptionSchema = object({
10217
10289
  id: journeyIdSchema,
@@ -10282,7 +10354,21 @@ object({
10282
10354
  /** Sessions whose last activity lies in this period (ADR 0206); absent means all. */
10283
10355
  period: sessionPeriodSchema.optional(),
10284
10356
  /** The Passport address and links chosen in this Journey (ADR 0246); absent means none yet. */
10285
- profile: journeyProfileSchema.optional()
10357
+ profile: journeyProfileSchema.optional(),
10358
+ /**
10359
+ * The last account read that re-seeded every Work (ADR 0277 section 5). Only scope
10360
+ * confirmation and Retry set `read`; late classification records only a failure. Absent in a
10361
+ * journey of an earlier version, which reads as not `read`.
10362
+ */
10363
+ accountRead: object({
10364
+ status: _enum([
10365
+ "read",
10366
+ "signed-out",
10367
+ "unavailable"
10368
+ ]),
10369
+ subject: string().min(1).max(128).optional(),
10370
+ at: datetime()
10371
+ }).strict().optional()
10286
10372
  }).strict();
10287
10373
  //#endregion
10288
10374
  //#region packages/application/src/journey/b/model.ts
@@ -10606,7 +10692,7 @@ function locateTerms(batches, terms) {
10606
10692
  }];
10607
10693
  }));
10608
10694
  for (const { type, value, index } of unique.values()) {
10609
- if (admitCustomTerm(value)?.value !== value || !texts.some((item) => item.text.includes(value))) {
10695
+ if (value.includes("█") || admitCustomTerm(value)?.value !== value || !texts.some((item) => item.text.includes(value))) {
10610
10696
  unlocated++;
10611
10697
  unlocatedIndices.push(index);
10612
10698
  continue;
@@ -10630,7 +10716,87 @@ function locateTerms(batches, terms) {
10630
10716
  };
10631
10717
  }
10632
10718
  //#endregion
10719
+ //#region packages/application/src/journey/terms/read-pages.ts
10720
+ /** Leave ample space for tool framing, JSON escaping and the final receipt on each read. */
10721
+ const pageBytes = 6e3;
10722
+ /** Each receipt binds the delivered text, its position, the frozen batch and its assignment. */
10723
+ function reviewReadPages(batch, attemptId) {
10724
+ const pages = [];
10725
+ let text = "";
10726
+ function flush() {
10727
+ if (!text) return;
10728
+ const receipt = createHash("sha256").update(JSON.stringify([
10729
+ "scan-read-v1",
10730
+ attemptId,
10731
+ batch.id,
10732
+ batch.digest,
10733
+ pages.length,
10734
+ text
10735
+ ])).digest("hex");
10736
+ pages.push({
10737
+ text,
10738
+ receipt
10739
+ });
10740
+ text = "";
10741
+ }
10742
+ for (const chunk of batch.chunks) {
10743
+ if (!chunk.text.length) throw new Error("EMPTY_REVIEW_PAGE");
10744
+ let offset = 0;
10745
+ while (offset < chunk.text.length) {
10746
+ const header = "\nCHUNK " + chunk.id + " " + (chunk.core ? "review" : "context") + " " + chunk.role + " UTF16_START " + offset + "\n";
10747
+ const available = pageBytes - Buffer.byteLength(text + header);
10748
+ if (available < 4) {
10749
+ if (!text) throw new Error("INVALID_REVIEW_PAGE_HEADER");
10750
+ flush();
10751
+ continue;
10752
+ }
10753
+ let end = offset;
10754
+ let bytes = 0;
10755
+ while (end < chunk.text.length) {
10756
+ const point = chunk.text.codePointAt(end);
10757
+ if (point === void 0) throw new Error("INVALID_REVIEW_PAGE_RANGE");
10758
+ const size = point < 128 ? 1 : point < 2048 ? 2 : point < 65536 ? 3 : 4;
10759
+ if (bytes + size > available) break;
10760
+ end += point >= 65536 ? 2 : 1;
10761
+ bytes += size;
10762
+ }
10763
+ text += header + chunk.text.slice(offset, end);
10764
+ offset = end;
10765
+ if (offset < chunk.text.length) flush();
10766
+ }
10767
+ }
10768
+ flush();
10769
+ return pages;
10770
+ }
10771
+ //#endregion
10633
10772
  //#region apps/cli/src/skill-install/privacy-validator.ts
10773
+ const sourceReferenceSchema = object({
10774
+ chunkId: uuid(),
10775
+ start: number().int().nonnegative(),
10776
+ end: number().int().positive()
10777
+ }).strict();
10778
+ /** Resolve sensitive spans locally against the projected, assigned core text. */
10779
+ function resolvePrivacySources(raw, batches) {
10780
+ if (!Array.isArray(raw)) throw new Error("INVALID_FINDING");
10781
+ if (!raw.some((term) => typeof term === "object" && term !== null && "source" in term)) return raw;
10782
+ const chunks = new Map(batches.flatMap(({ chunks }) => chunks.map((chunk) => [chunk.id, chunk])));
10783
+ return raw.map((term, index) => {
10784
+ if (typeof term !== "object" || term === null || !("source" in term)) return term;
10785
+ const reference = sourceReferenceSchema.safeParse(term.source);
10786
+ const invalid = () => new Error("INVALID_REVIEW_SPAN", { cause: [`draft.terms[${index}].source`] });
10787
+ if (!reference.success || "value" in term) throw invalid();
10788
+ const { chunkId, start, end } = reference.data;
10789
+ const chunk = chunks.get(chunkId);
10790
+ if (!chunk?.core || end <= start || end > chunk.text.length || end - start > 8e3 || chunk.displayMasks?.some((range) => range.start < end && start < range.end)) throw invalid();
10791
+ const value = chunk.text.slice(start, end);
10792
+ if (!value.isWellFormed() || value.includes("█") || !value.trim() || Array.from(value).length > 4e3) throw invalid();
10793
+ const { source: _source, ...rest } = term;
10794
+ return {
10795
+ ...rest,
10796
+ value
10797
+ };
10798
+ });
10799
+ }
10634
10800
  const suppliedTerms = array(object({
10635
10801
  key: string(),
10636
10802
  type: string(),
@@ -10673,4 +10839,4 @@ function validateStageAnswer(input, answer) {
10673
10839
  }
10674
10840
  }
10675
10841
  //#endregion
10676
- export { locateTerms, validateStageAnswer };
10842
+ export { locateTerms, resolvePrivacySources, reviewReadPages, validateStageAnswer };
@@ -3,11 +3,7 @@ export function parseReply(text: string): Record<string, unknown>
3
3
  export function estimateTokens(text: string): number
4
4
  export function readPlan(text: string, pageTokens?: number): { offset: number; limit: number }[]
5
5
  export function renderGuidance(guidance: unknown): string
6
- export function renderPackTask(
7
- packId: string,
8
- guidance: unknown,
9
- units: readonly { ref: string; unit: unknown }[],
10
- ): string
6
+ export function renderPackTask(packId: string, guidance: unknown): string
11
7
  export function readAnswer(replies: readonly Record<string, unknown>[]): {
12
8
  units: Map<string, { summary: string; exclude: string | null }>
13
9
  terms: { type: string; value: string; disposition: string; reason: string }[]
@@ -74,9 +70,13 @@ export function writePackTask(
74
70
  task: string,
75
71
  text: string,
76
72
  unitRefs: readonly string[],
77
- sourceBatches?: readonly {
73
+ sourceBatches: readonly {
74
+ id: string
75
+ digest: string
78
76
  workId: string
79
77
  chunks: readonly {
78
+ id: string
79
+ role: string
80
80
  text: string
81
81
  offset: number
82
82
  core: boolean
@@ -84,4 +84,5 @@ export function writePackTask(
84
84
  fieldHash: string
85
85
  }[]
86
86
  }[],
87
+ attemptId?: string,
87
88
  ): Promise<string>