@thinkingai/ae-cli 6.1.14 → 6.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/README.zh.md +5 -2
- package/dist/{auth-GBMV6TEJ.js → auth-2WTQOP77.js} +3 -3
- package/dist/{auth-NDSXE54J.js → auth-77BUFLGC.js} +57 -13
- package/dist/{capability-TAMDRZYV.js → capability-72DTW5M2.js} +9 -9
- package/dist/{capability-U7TDEEEG.js → capability-PJHNI4GJ.js} +9 -9
- package/dist/{chunk-AFXA7BRK.js → chunk-4KVPKXFX.js} +5 -5
- package/dist/chunk-4SGZG4XY.js +311 -0
- package/dist/chunk-6EIJSNBD.js +8 -0
- package/dist/chunk-C4MGVGJW.js +13 -0
- package/dist/{chunk-WZRX4KOH.js → chunk-GT46FPXN.js} +4 -6
- package/dist/{chunk-5XUSIK27.js → chunk-ILIU36SU.js} +10 -7
- package/dist/{chunk-JHENBQ5B.js → chunk-LYVNONC4.js} +0 -35
- package/dist/{chunk-JUW4AJXN.js → chunk-P3FGXJTU.js} +12 -7
- package/dist/chunk-QGM4M3NI.js +37 -0
- package/dist/{chunk-753BUTNZ.js → chunk-RGKJGKT7.js} +2 -2
- package/dist/{chunk-UIHQJK5E.js → chunk-SAU3QFIQ.js} +3 -3
- package/dist/{chunk-VLWOLBGZ.js → chunk-UOUS37JQ.js} +149 -161
- package/dist/{chunk-AXDXJTPC.js → chunk-UW5UN47B.js} +19 -2
- package/dist/chunk-VPKZ7I72.js +509 -0
- package/dist/{chunk-QATA32VR.js → chunk-VR3LCBHW.js} +2 -2
- package/dist/{chunk-IBH3LDAH.js → chunk-YA6SMTXG.js} +3 -3
- package/dist/chunk-ZZUOD757.js +598 -0
- package/dist/{client-L2YDMHQ6.js → client-TKG4WBHN.js} +4 -5
- package/dist/{community-report-client-M2RW4MXD.js → community-report-client-FI4LNVYS.js} +3 -2
- package/dist/{config-OL2LWGBV.js → config-RE6CMGPK.js} +7 -7
- package/dist/data-integration-XQYB4X4F.js +3503 -0
- package/dist/index.js +68 -34
- package/dist/local-data-upload-client-BWHSUQQK.js +167 -0
- package/dist/{memory-MUP7PPL7.js → memory-CHRU2F7W.js} +7 -6
- package/dist/{memory-U4O5PMXH.js → memory-YK33G4T7.js} +7 -6
- package/dist/{metadata-5MIMNIMT.js → metadata-UILXHBWF.js} +10 -9
- package/dist/{metadata-LERKDJN6.js → metadata-XXR34N5P.js} +10 -9
- package/dist/{model-JTUEO5M4.js → model-K3KLWIW6.js} +7 -3
- package/dist/model-NR3JHFSJ.js +139 -0
- package/dist/{sync-MOSFNBVR.js → sync-DAVKYVMW.js} +8 -6
- package/dist/sync-FCKOVWWS.js +10261 -0
- package/dist/{te-agent-IFKZDHZI.js → te-agent-4BKBODMF.js} +686 -71
- package/dist/te-agent-HLW4VTQK.js +3893 -0
- package/dist/{te-analysis-FCHRTNIY.js → te-analysis-O6DCO6BS.js} +36 -13
- package/dist/{te-analysis-QG7UKGDA.js → te-analysis-ZMNGOVNW.js} +36 -13
- package/dist/{te-community-HNKVTERD.js → te-community-6HPBWJUZ.js} +24 -19
- package/dist/{te-community-IWE5B7W6.js → te-community-HLC43QKH.js} +24 -20
- package/dist/{te-dataops-KXCEB4CS.js → te-dataops-EJP56W3K.js} +57 -34
- package/dist/{te-dataops-KQPYNAE3.js → te-dataops-HDRUXY4K.js} +59 -34
- package/dist/{te-engage-D6EG3NOR.js → te-engage-FGBGQ4IY.js} +9 -8
- package/dist/{te-engage-ZSMIJLUW.js → te-engage-RAK5PESW.js} +9 -8
- package/dist/{te-experiment-K5US7RMG.js → te-experiment-SO5MPDMJ.js} +9 -8
- package/dist/{te-experiment-WA7TFMEL.js → te-experiment-VZF7BT6G.js} +9 -8
- package/dist/{te-kb-OIH3T6CS.js → te-kb-SQCLHG6X.js} +250 -126
- package/dist/{te-system-AZ3URMUO.js → te-system-YARIK4S5.js} +7 -4
- package/dist/te-system-Z77IKZFN.js +2213 -0
- package/dist/{te-team-GZPU6UWA.js → te-team-EFKWYKMK.js} +7 -7
- package/dist/{update-TOBFXF2V.js → update-OGPSZM5A.js} +7 -7
- package/package.json +14 -3
- package/skills/ae-agent/SKILL.md +21 -11
- package/skills/ae-agent/references/approval-effect.md +44 -0
- package/skills/ae-agent/references/approval-request.md +46 -0
- package/skills/ae-agent/references/approval-task.md +45 -0
- package/skills/ae-agent/references/approval-type.md +32 -0
- package/skills/ae-agent/references/command_index.md +19 -0
- package/skills/ae-analysis/SKILL.md +11 -7
- package/skills/ae-analysis/references/adhoc_run.md +2 -0
- package/skills/ae-analysis/references/ai_models.md +27 -0
- package/skills/ae-analysis/references/analysis_gateway_assets.md +3 -2
- package/skills/ae-analysis/references/command_index.md +4 -1
- package/skills/ae-analysis/references/dashboard_get.md +8 -2
- package/skills/ae-analysis/references/dashboard_report_data_run.md +3 -1
- package/skills/ae-analysis/references/dashboard_update.md +4 -1
- package/skills/ae-analysis/references/project_space_business_filter_upsert.md +17 -0
- package/skills/ae-analysis/references/user_tag_models.md +4 -4
- package/skills/ae-data-integration/SKILL.md +54 -0
- package/skills/ae-data-integration/references/handoff.md +43 -0
- package/skills/ae-data-integration/references/local-analysis.md +27 -0
- package/skills/ae-data-integration/references/reuse.md +41 -0
- package/skills/ae-data-integration/references/sink-upload.md +58 -0
- package/skills/ae-data-integration/references/source-inspect.md +68 -0
- package/skills/ae-data-integration/references/sync-json-upload.md +60 -0
- package/skills/ae-data-integration/references/tracking-plan.md +35 -0
- package/skills/ae-data-integration/references/transform.md +65 -0
- package/skills/ae-data-integration/references/ue-mapping.md +142 -0
- package/skills/ae-data-integration/references/ue-routing.md +35 -0
- package/skills/ae-data-integration-helper/SKILL.md +1 -1
- package/skills/ae-dataops/SKILL.md +1 -1
- package/skills/ae-dataops/references/dataops-query.md +4 -4
- package/skills/ae-generate-tracking-plan/SKILL.md +54 -3
- package/skills/ae-kb/SKILL.md +55 -50
- package/skills/ae-kb/references/query-workflow.md +112 -0
- package/skills/ae-kb-discovery/SKILL.md +105 -0
- package/skills/ae-metadata/SKILL.md +0 -1
- package/dist/chunk-3FY3RJ26.js +0 -293
- package/dist/chunk-S5NTSDBS.js +0 -198
- package/dist/chunk-ZQKDZXDO.js +0 -317
- package/dist/cli-token-4UPER74P.js +0 -21
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# ae-kb deterministic query workflow
|
|
2
|
+
|
|
3
|
+
How to answer a knowledge question with the deterministic retrieval primitives
|
|
4
|
+
(`+list` / `+index` / `+grep` / `+read`) instead of `+ask`. Follow this order;
|
|
5
|
+
it is designed to reach the right section in a few calls and to avoid crawling a
|
|
6
|
+
page line by line.
|
|
7
|
+
|
|
8
|
+
Use `+ask` when the question requires synthesizing across multiple pages or
|
|
9
|
+
multi-hop reasoning; simple factual lookups are served by the steps below.
|
|
10
|
+
Everything below is server-side LLM-free.
|
|
11
|
+
|
|
12
|
+
## The loop
|
|
13
|
+
|
|
14
|
+
This picks up **after** `ae-kb-discovery` has listed accessible knowledge bases
|
|
15
|
+
and ranked candidates. Start here with a chosen candidate; scope every `+index`
|
|
16
|
+
/ `+grep` / `+read` call to it with `--sources` / `--source`. If the candidate
|
|
17
|
+
turns out not to cover the question, go back to `ae-kb-discovery` for the next
|
|
18
|
+
candidate rather than searching everything blindly.
|
|
19
|
+
|
|
20
|
+
1. **Index the candidate.** Call `+index --sources` with the discovery pick.
|
|
21
|
+
Use `index.md` for navigation, a fit check, and **query wording** — the real
|
|
22
|
+
terms in the index (product names, API identifiers, section titles) become
|
|
23
|
+
your `+grep` keywords.
|
|
24
|
+
|
|
25
|
+
**Done when:** you have the candidate's `index.md`, and a list of `wiki/...`
|
|
26
|
+
links you can **copy** (0 items still counts as done).
|
|
27
|
+
|
|
28
|
+
2. **Grep copied paths.** Copy 1–3 `wiki/...` entries from the index (a page
|
|
29
|
+
such as `wiki/sandbox.md`, or a subdirectory such as `wiki/guides`). Call
|
|
30
|
+
`+grep` with the candidate `--sources` and the copied list as `--paths`. Search
|
|
31
|
+
with the index terms. If the first grep misses, rewrite the query **once**
|
|
32
|
+
using different index terms — still with this same `--paths` — then stop
|
|
33
|
+
rewriting.
|
|
34
|
+
|
|
35
|
+
**Done when:** you have hits, or you have rewritten once, or step 1 copied
|
|
36
|
+
0 paths. Copied 0 paths → skip grep and `+read --outline` the likeliest
|
|
37
|
+
title page, or go back to discovery for the next candidate.
|
|
38
|
+
|
|
39
|
+
A grep hit gives both a hit anchor and its enclosing section range:
|
|
40
|
+
|
|
41
|
+
- `line` is the exact matched line. Use it as the anchor when the evidence
|
|
42
|
+
is local.
|
|
43
|
+
- `sectionStartLine` / `sectionEndLine` are the enclosing heading-section
|
|
44
|
+
boundaries. Use them when the answer needs the whole section context, or
|
|
45
|
+
as the maximum boundary when choosing a smaller window.
|
|
46
|
+
- `+read --offset` / `--limit` are the actual read window. Choose the
|
|
47
|
+
smallest reliable window that preserves the needed evidence; do not
|
|
48
|
+
shell-truncate with `| head`.
|
|
49
|
+
|
|
50
|
+
3. **Choose the section locator.** Pick one locator for the current target
|
|
51
|
+
page:
|
|
52
|
+
|
|
53
|
+
- **Same-page grep hit:** choose a read window from the hit. For narrow
|
|
54
|
+
fact/table/code evidence, read a bounded window anchored at `line`; stay
|
|
55
|
+
within `sectionStartLine`–`sectionEndLine`. For section-level meaning,
|
|
56
|
+
field definitions, caveats, or rows that depend on the heading context,
|
|
57
|
+
read the section range with
|
|
58
|
+
`--offset sectionStartLine` and
|
|
59
|
+
`--limit sectionEndLine - sectionStartLine + 1`. If the first window is
|
|
60
|
+
too small, widen once up to the section range. Do not crawl by shifting
|
|
61
|
+
offsets line by line.
|
|
62
|
+
- **Linked or related page:** if you follow a catalog/detail/related link to
|
|
63
|
+
a different page, the old grep range no longer applies. If you have
|
|
64
|
+
concrete terms for that new page, run `+grep --paths '["<new-page>"]'`
|
|
65
|
+
scoped to that page and use the new hit range.
|
|
66
|
+
- **No reliable range:** if the new page has no concrete grep terms, its
|
|
67
|
+
grep misses, or headings are needed to choose the right section, call
|
|
68
|
+
`+read --outline` for that page. It returns only the heading tree
|
|
69
|
+
(`{level, heading, line}`), independent of any offset/limit window, with
|
|
70
|
+
empty content.
|
|
71
|
+
|
|
72
|
+
A bare `+read` without `--offset` / `--limit` is only acceptable after the
|
|
73
|
+
response proves the whole page was returned (`startLine: 1`,
|
|
74
|
+
`endLine: totalLines`, and `truncated: false`).
|
|
75
|
+
|
|
76
|
+
**Done when:** you have a reliable range from the same-page grep hit, a new
|
|
77
|
+
page grep hit, an outline-derived heading range, or a complete untruncated
|
|
78
|
+
page response.
|
|
79
|
+
|
|
80
|
+
4. **Read the selected window.** Read the selected window in one call. Windows
|
|
81
|
+
come from the hit anchor, the grep hit's section boundaries, or two adjacent
|
|
82
|
+
outline headings (`heading.line` of the target section to `heading.line - 1`
|
|
83
|
+
of the next). If a window turns out too small, widen to the section boundary
|
|
84
|
+
in one more call.
|
|
85
|
+
|
|
86
|
+
**Done when:** the needed evidence is in context without shell truncation,
|
|
87
|
+
or the page response is complete and untruncated.
|
|
88
|
+
|
|
89
|
+
5. **Assess coverage, then answer or iterate.** Map the user's question into
|
|
90
|
+
subquestions and check each one against the sections you actually read. If a
|
|
91
|
+
subquestion is covered, answer with citations (knowledge base + page path +
|
|
92
|
+
section). If a gap remains, go back to step 2 with another set of `--paths`
|
|
93
|
+
**copied** from the index, or return to discovery for the next candidate.
|
|
94
|
+
If the evidence is missing after the allowed search, say which subquestion is
|
|
95
|
+
not covered instead of filling it from memory.
|
|
96
|
+
|
|
97
|
+
**Done when:** every answered subquestion is supported by read sections, or
|
|
98
|
+
the remaining gaps are explicitly reported as missing evidence.
|
|
99
|
+
|
|
100
|
+
## Anti-pattern: same-page offset crawling
|
|
101
|
+
|
|
102
|
+
The failure this workflow prevents: grep returns a line number, you `+read` a
|
|
103
|
+
tiny window around it, it is cut mid-evidence, so you nudge the window one line
|
|
104
|
+
at a time. That wastes calls and never shows page structure. Instead: use the
|
|
105
|
+
hit anchor, widen once up to the section boundary, or open `--outline` and read
|
|
106
|
+
the selected heading range.
|
|
107
|
+
|
|
108
|
+
## Related
|
|
109
|
+
|
|
110
|
+
- Command flags and JSON shapes: see the `+grep` / `+read` sections in
|
|
111
|
+
[`../SKILL.md`](../SKILL.md).
|
|
112
|
+
- Use `+ask` for multi-page synthesis or multi-hop questions. Default `+ask` submits then polls until the answer is ready; `--no-wait` and `+ask-status` are for batch submit/retrieve. See the `+ask` section in [`../SKILL.md`](../SKILL.md).
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ae-kb-discovery
|
|
3
|
+
description: >
|
|
4
|
+
Discover which AE/TE/ThinkingEngine knowledge bases accessible to the current user are worth searching, and decide whether to search at all, through read-only operations. Use when the user explicitly asks to search knowledge bases, internal documentation, or company materials. Also use when a task requires internal facts or business context, including product design and rules, events, campaign or operations calendars, release and iteration records, workflows, policies, and terminology; use it as well when this context is needed to explain data analysis results, anomalies, or trends and form evidence-backed conclusions. Do not use if the user explicitly asks not to access knowledge bases. This skill covers discovery and candidate selection; run the actual `+index` / `+grep` / `+read` / `+ask` retrieval with the `ae-kb` skill.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Knowledge Base Discovery
|
|
8
|
+
|
|
9
|
+
Treat knowledge bases as an optional source of internal facts and business context. Keep the user's original goal unchanged; knowledge base retrieval is a supporting workflow, not the task itself.
|
|
10
|
+
|
|
11
|
+
This skill decides **whether** to use a knowledge base and **which** knowledge base is worth searching. The retrieval procedure itself — inspecting the index, grep, reading sections, and optional LLM synthesis — lives in the `ae-kb` skill (`references/query-workflow.md`). Discover here, then hand off to `ae-kb` to execute.
|
|
12
|
+
|
|
13
|
+
## Decide Whether to Use This Skill
|
|
14
|
+
|
|
15
|
+
Use this skill when:
|
|
16
|
+
|
|
17
|
+
- The user explicitly asks to search a knowledge base, internal documentation, or company materials.
|
|
18
|
+
- The task requires organization-specific facts or context, such as product design and rules, events, campaign or operations calendars, release and iteration records, workflows, policies, or terminology.
|
|
19
|
+
- Internal context is needed to explain data analysis results, anomalies, or trends and form evidence-backed conclusions.
|
|
20
|
+
- The knowledge base context currently available does not cover the question, and discovering other accessible sources has clear value.
|
|
21
|
+
|
|
22
|
+
Do not use this skill when:
|
|
23
|
+
|
|
24
|
+
- The user explicitly asks not to use knowledge bases.
|
|
25
|
+
- The task only requires querying real-time state or performing an operation and does not need document context.
|
|
26
|
+
- General knowledge is sufficient for a reliable answer and internal evidence would not materially improve it.
|
|
27
|
+
|
|
28
|
+
## Discovery Workflow
|
|
29
|
+
|
|
30
|
+
### 1. Get the List of Accessible Knowledge Bases
|
|
31
|
+
|
|
32
|
+
First, get the lightweight list of knowledge bases accessible to the current user:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
ae-cli kb +list
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Use the exact `scope` and knowledge base name returned by the command, together with available metadata such as description, tags, language, and `bindings`. A binding identifies an associated context through `targetType`, `targetId`, and optional `targetName`. Do not guess a name, scope, or binding. Treat metadata returned by `+list` only as input for candidate selection, not as evidence from knowledge base content.
|
|
39
|
+
|
|
40
|
+
If `+list` is unavailable or fails, do not guess which knowledge bases exist. If the user explicitly requested a knowledge base search, explain that discovery cannot currently be completed. Otherwise, return to the original task and reassess the capabilities currently available.
|
|
41
|
+
|
|
42
|
+
### 2. Rank Candidate Knowledge Bases
|
|
43
|
+
|
|
44
|
+
Rank candidates in this order:
|
|
45
|
+
|
|
46
|
+
1. Prefer a knowledge base explicitly named by the user. Use the exact name and scope returned by `+list`, regardless of whether it has a matching binding.
|
|
47
|
+
2. Prefer candidates whose bindings exactly match the current session context. Match `targetType: project` against the current analysis project ID, `targetType: space` against the current community space ID, and `targetType: dwSpace` against the current digital workspace code.
|
|
48
|
+
3. For the remaining candidates, compare the user's request with the knowledge base name, description, and tags. Use language only as a preference between candidates with similar relevance; language alone does not establish relevance.
|
|
49
|
+
|
|
50
|
+
Compare `targetId` with the corresponding current ID or code first. Use `targetName` only as a secondary signal when an ID or code is unavailable; do not replace a conflicting ID match with a name match. A candidate with no bindings or no current-context match remains eligible for semantic ranking. A binding to another project or space lowers implicit priority but does not exclude the candidate, and an explicit user choice still takes precedence.
|
|
51
|
+
|
|
52
|
+
Select one preferred knowledge base by default. When several candidates are highly relevant, retain no more than three and try them one at a time in priority order. Do not read the indexes of all candidates in advance. A binding, name, description, tag, or language match only indicates that a knowledge base is worth searching; it does not prove a content match, grant access, or count as knowledge base evidence.
|
|
53
|
+
|
|
54
|
+
### 3. Hand Off to Retrieval
|
|
55
|
+
|
|
56
|
+
Once a preferred knowledge base is selected, hand off to the `ae-kb` skill and follow its `references/query-workflow.md` for the entire retrieval procedure — including when `+ask` is appropriate.
|
|
57
|
+
|
|
58
|
+
## Assess Coverage
|
|
59
|
+
|
|
60
|
+
- Full coverage: The page content read supports the key conclusions required for the information request or analysis.
|
|
61
|
+
- Partial coverage: The page content read provides only background, definitions, or partially relevant facts and cannot independently support the required conclusions.
|
|
62
|
+
- No coverage: No suitable candidate knowledge base exists, or `+grep` and `+read` return no content that can support the conclusions.
|
|
63
|
+
|
|
64
|
+
A candidate returned by `+list`, navigation returned by `+index`, a successful command, a tool call, or a metadata match does not count as a knowledge base hit. Only relevant page content that has actually been read can serve as knowledge base evidence.
|
|
65
|
+
|
|
66
|
+
## Use Knowledge Base Evidence in Analysis
|
|
67
|
+
|
|
68
|
+
When using internal context to explain data analysis results, anomalies, or trends:
|
|
69
|
+
|
|
70
|
+
1. First state what the analysis itself demonstrates, including the metric change, time range, affected entity, and magnitude.
|
|
71
|
+
2. Search using the affected entity, metric, time range, campaign or event name, product area, and release or version name.
|
|
72
|
+
3. Verify that the retrieved evidence:
|
|
73
|
+
- Applies to the same entity, product area, or business scope.
|
|
74
|
+
- Overlaps with the time range covered by the analysis.
|
|
75
|
+
- Records an event, rule, release, or change that actually took effect.
|
|
76
|
+
- Uses a version and effective date that remained valid during the analysis period.
|
|
77
|
+
4. Distinguish planned activities from completed events. A calendar or roadmap does not prove that an activity or release occurred unless the retrieved content confirms execution.
|
|
78
|
+
5. Combine analytical facts with retrieved internal evidence and state directly what the evidence supports. Do not list possible causes that lack evidence.
|
|
79
|
+
6. Use causal language such as "caused" or "led to" only when the available evidence establishes causality. Otherwise, say that the evidence supports a factor as a key explanation or that the factor is consistent with the observed change.
|
|
80
|
+
7. If the evidence is insufficient, state clearly that the cause cannot be determined from the available evidence. Do not fill evidence gaps with speculation.
|
|
81
|
+
8. When appropriate, organize the final answer in this order:
|
|
82
|
+
- Conclusion.
|
|
83
|
+
- Analytical evidence.
|
|
84
|
+
- Knowledge base evidence and relevant page paths.
|
|
85
|
+
- Necessary limitations of the evidence.
|
|
86
|
+
|
|
87
|
+
## Handle Partial or No Coverage
|
|
88
|
+
|
|
89
|
+
When knowledge base evidence provides only partial coverage, is entirely absent, or retrieval fails:
|
|
90
|
+
|
|
91
|
+
1. Stop repeating searches against the same candidate knowledge base.
|
|
92
|
+
2. If ranked candidates remain, switch to the next candidate. Search no more than three knowledge bases in one task.
|
|
93
|
+
3. When all candidates provide no coverage, return to the user's original request instead of remaining in the knowledge base retrieval subtask.
|
|
94
|
+
4. Reassess the capabilities currently available and choose the next path that best serves the original task. Do not hard-code a fixed fallback.
|
|
95
|
+
5. Retain verified background evidence when useful, but never attribute conclusions drawn from other sources to a knowledge base.
|
|
96
|
+
6. Do not report an unsuccessful knowledge base search unless the retrieval failure itself affects the user's decision.
|
|
97
|
+
|
|
98
|
+
Knowledge base information must not replace required business operations. If the original task also requires real-time data or an action, complete that part through the appropriate available capability.
|
|
99
|
+
|
|
100
|
+
## Safety Boundaries
|
|
101
|
+
|
|
102
|
+
- Limit knowledge base access to the read-only retrieval primitives (`+list`, `+index`, `+grep`, `+read`, and `+ask` when the question requires multi-page synthesis or multi-hop reasoning). Do not create, upload, compile, or delete knowledge bases.
|
|
103
|
+
- Respect existing scope, tenant, and membership permissions. Do not attempt to bypass an inaccessible knowledge base.
|
|
104
|
+
- Do not expose internal root paths, access tokens, or raw permission metadata.
|
|
105
|
+
- For protected knowledge bases, provide only summaries and synthesized conclusions allowed by the current permissions. Do not export complete source text or extensive verbatim excerpts.
|
|
@@ -83,4 +83,3 @@ ae-cli analysis input-file purpose list --project-id 1
|
|
|
83
83
|
## Related Skills
|
|
84
84
|
|
|
85
85
|
- **`ae-analysis`**: `analysis-meta event get` / `analysis-meta property get` for detail, and `analysis-meta event list` / `analysis-meta property list` to discover names.
|
|
86
|
-
- **Dev workflow**: `.cursor/skills/te-cli-capability-gateway` — inspect gateway schema when adding new metadata capabilities.
|
package/dist/chunk-3FY3RJ26.js
DELETED
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
logger
|
|
3
|
-
} from "./chunk-JHENBQ5B.js";
|
|
4
|
-
|
|
5
|
-
// src/core/json-utils.ts
|
|
6
|
-
import fs from "fs";
|
|
7
|
-
import { createRequire } from "module";
|
|
8
|
-
var require2 = createRequire(import.meta.url);
|
|
9
|
-
var JSONbig = require2("json-bigint");
|
|
10
|
-
var jsonParser = JSONbig({ storeAsString: true });
|
|
11
|
-
var INTEGER_TOKEN = /^-?(?:0|[1-9]\d*)$/;
|
|
12
|
-
function normalizeParsedNumbers(lossless, native) {
|
|
13
|
-
if (typeof lossless === "string" && typeof native === "number") {
|
|
14
|
-
if (INTEGER_TOKEN.test(lossless) && !Number.isSafeInteger(native)) {
|
|
15
|
-
return lossless;
|
|
16
|
-
}
|
|
17
|
-
return native;
|
|
18
|
-
}
|
|
19
|
-
if (Array.isArray(lossless) && Array.isArray(native)) {
|
|
20
|
-
for (let index = 0; index < lossless.length; index++) {
|
|
21
|
-
lossless[index] = normalizeParsedNumbers(lossless[index], native[index]);
|
|
22
|
-
}
|
|
23
|
-
return lossless;
|
|
24
|
-
}
|
|
25
|
-
if (lossless !== null && native !== null && typeof lossless === "object" && typeof native === "object") {
|
|
26
|
-
for (const key of Object.keys(lossless)) {
|
|
27
|
-
lossless[key] = normalizeParsedNumbers(lossless[key], native[key]);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return lossless;
|
|
31
|
-
}
|
|
32
|
-
function safeJsonParse(text) {
|
|
33
|
-
const lossless = jsonParser.parse(text);
|
|
34
|
-
return normalizeParsedNumbers(lossless, JSON.parse(text));
|
|
35
|
-
}
|
|
36
|
-
function safeReadJsonFile(filePath) {
|
|
37
|
-
const content = fs.readFileSync(filePath, "utf-8");
|
|
38
|
-
return safeJsonParse(content);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// src/core/url-utils.ts
|
|
42
|
-
function normalizeUrl(url) {
|
|
43
|
-
if (!url) return url;
|
|
44
|
-
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
45
|
-
url = `https://${url}`;
|
|
46
|
-
}
|
|
47
|
-
return url.replace(/\/$/, "");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// src/core/config.ts
|
|
51
|
-
import fs3 from "fs";
|
|
52
|
-
import path from "path";
|
|
53
|
-
|
|
54
|
-
// src/core/sandbox-runtime.ts
|
|
55
|
-
import { homedir } from "os";
|
|
56
|
-
import { join } from "path";
|
|
57
|
-
import fs2 from "fs";
|
|
58
|
-
var LINUX_SANDBOX_RUNTIME_ROOT = "/home/ta/te_agent_ta";
|
|
59
|
-
function getDefaultSandboxRuntimeRoot() {
|
|
60
|
-
if (process.platform === "linux") {
|
|
61
|
-
return LINUX_SANDBOX_RUNTIME_ROOT;
|
|
62
|
-
}
|
|
63
|
-
return homedir();
|
|
64
|
-
}
|
|
65
|
-
function getSandboxRuntimeRoot() {
|
|
66
|
-
return process.env.SANDBOX_RUNTIME_ROOT || getDefaultSandboxRuntimeRoot();
|
|
67
|
-
}
|
|
68
|
-
function getSandboxAeConfigDir() {
|
|
69
|
-
return join(getSandboxRuntimeRoot(), ".ae-config");
|
|
70
|
-
}
|
|
71
|
-
function getSandboxCliTokenFilePath() {
|
|
72
|
-
return join(getSandboxAeConfigDir(), "cli-token.json");
|
|
73
|
-
}
|
|
74
|
-
function isAeSandboxRuntime() {
|
|
75
|
-
if (process.env.SANDBOX_RUNTIME_ROOT) {
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
try {
|
|
79
|
-
if (fs2.existsSync(getSandboxCliTokenFilePath())) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
} catch {
|
|
83
|
-
}
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// src/core/config.ts
|
|
88
|
-
var CONFIG_DIR = path.join(process.env.HOME || "", ".ae-cli");
|
|
89
|
-
var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
90
|
-
function sandboxCliTokenCandidatePaths() {
|
|
91
|
-
const paths = [getSandboxCliTokenFilePath()];
|
|
92
|
-
const homeFallback = path.join(process.env.HOME || "", ".ae-config", "cli-token.json");
|
|
93
|
-
if (!paths.includes(homeFallback)) {
|
|
94
|
-
paths.push(homeFallback);
|
|
95
|
-
}
|
|
96
|
-
return paths;
|
|
97
|
-
}
|
|
98
|
-
function readSandboxCliTokenEntry() {
|
|
99
|
-
for (const file of sandboxCliTokenCandidatePaths()) {
|
|
100
|
-
if (!fs3.existsSync(file)) continue;
|
|
101
|
-
try {
|
|
102
|
-
const data = safeReadJsonFile(file);
|
|
103
|
-
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
104
|
-
const url = data.url;
|
|
105
|
-
const token = data.token ?? data["cli-token"];
|
|
106
|
-
if (url && token) {
|
|
107
|
-
return { url, token };
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
} catch {
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
function forceMigrateFromFallback() {
|
|
116
|
-
const entry = readSandboxCliTokenEntry();
|
|
117
|
-
if (!entry) return null;
|
|
118
|
-
return { [entry.url]: entry.token };
|
|
119
|
-
}
|
|
120
|
-
function getFallbackCliToken(hostUrl) {
|
|
121
|
-
const store = forceMigrateFromFallback();
|
|
122
|
-
if (!store) return null;
|
|
123
|
-
if (hostUrl && store[hostUrl]) return store[hostUrl];
|
|
124
|
-
const entries = Object.values(store);
|
|
125
|
-
if (entries.length === 1) return entries[0];
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
function ensureDir() {
|
|
129
|
-
if (!fs3.existsSync(CONFIG_DIR)) fs3.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
130
|
-
}
|
|
131
|
-
function dedupeNormalizedHosts(config) {
|
|
132
|
-
const hosts = {};
|
|
133
|
-
for (const [url, entry] of Object.entries(config.hosts)) {
|
|
134
|
-
const key = normalizeUrl(url);
|
|
135
|
-
if (!hosts[key]) {
|
|
136
|
-
hosts[key] = entry;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return {
|
|
140
|
-
activeHost: config.activeHost ? normalizeUrl(config.activeHost) : "",
|
|
141
|
-
hosts
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
function configNeedsNormalization(config) {
|
|
145
|
-
if (config.activeHost && normalizeUrl(config.activeHost) !== config.activeHost) return true;
|
|
146
|
-
const keys = Object.keys(config.hosts);
|
|
147
|
-
if (keys.some((url) => normalizeUrl(url) !== url)) return true;
|
|
148
|
-
return new Set(keys.map(normalizeUrl)).size !== keys.length;
|
|
149
|
-
}
|
|
150
|
-
function loadConfig() {
|
|
151
|
-
try {
|
|
152
|
-
if (fs3.existsSync(CONFIG_FILE)) {
|
|
153
|
-
const raw = safeReadJsonFile(CONFIG_FILE);
|
|
154
|
-
if (raw.defaultHost && !raw.activeHost) {
|
|
155
|
-
const migrated = dedupeNormalizedHosts(migrateConfig(raw));
|
|
156
|
-
saveConfig(migrated);
|
|
157
|
-
return migrated;
|
|
158
|
-
}
|
|
159
|
-
const rawConfig = raw;
|
|
160
|
-
if (configNeedsNormalization(rawConfig)) {
|
|
161
|
-
const config = dedupeNormalizedHosts(rawConfig);
|
|
162
|
-
saveConfig(config);
|
|
163
|
-
return config;
|
|
164
|
-
}
|
|
165
|
-
return rawConfig;
|
|
166
|
-
}
|
|
167
|
-
} catch (err) {
|
|
168
|
-
logger.error(`Error loading config: ${err.message}`);
|
|
169
|
-
console.error(`Error loading config: ${err.message}`);
|
|
170
|
-
}
|
|
171
|
-
return { activeHost: "", hosts: {} };
|
|
172
|
-
}
|
|
173
|
-
function migrateConfig(old) {
|
|
174
|
-
const hosts = {};
|
|
175
|
-
const oldHost = old.defaultHost;
|
|
176
|
-
if (old.hosts) {
|
|
177
|
-
for (const [key, val] of Object.entries(old.hosts)) {
|
|
178
|
-
const url = normalizeUrl(key.startsWith("http") ? key : `https://${key}`);
|
|
179
|
-
hosts[url] = val;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
const activeHost = normalizeUrl(oldHost.startsWith("http") ? oldHost : `https://${oldHost}`);
|
|
183
|
-
if (!hosts[activeHost]) {
|
|
184
|
-
hosts[activeHost] = { label: "default" };
|
|
185
|
-
}
|
|
186
|
-
return { activeHost, hosts };
|
|
187
|
-
}
|
|
188
|
-
function saveConfig(config) {
|
|
189
|
-
ensureDir();
|
|
190
|
-
fs3.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
191
|
-
logger.info(`Config saved: activeHost=${config.activeHost}, hosts=${Object.keys(config.hosts).length}`);
|
|
192
|
-
}
|
|
193
|
-
function getActiveHost() {
|
|
194
|
-
const sandboxHost = readSandboxCliTokenEntry()?.url;
|
|
195
|
-
if (sandboxHost) return sandboxHost;
|
|
196
|
-
const config = loadConfig();
|
|
197
|
-
return config.activeHost || "";
|
|
198
|
-
}
|
|
199
|
-
function setActiveHost(url) {
|
|
200
|
-
url = normalizeUrl(url);
|
|
201
|
-
const config = loadConfig();
|
|
202
|
-
if (!config.hosts[url]) {
|
|
203
|
-
throw new Error(`Host ${url} is not in the configured hosts list. Add it first.`);
|
|
204
|
-
}
|
|
205
|
-
config.activeHost = url;
|
|
206
|
-
saveConfig(config);
|
|
207
|
-
}
|
|
208
|
-
function addHost(url, label) {
|
|
209
|
-
url = normalizeUrl(url);
|
|
210
|
-
label = normalizeLabel(label);
|
|
211
|
-
const config = loadConfig();
|
|
212
|
-
assertUniqueHostLabel(config, label, url);
|
|
213
|
-
config.hosts[url] = { label };
|
|
214
|
-
if (!config.activeHost) {
|
|
215
|
-
config.activeHost = url;
|
|
216
|
-
}
|
|
217
|
-
saveConfig(config);
|
|
218
|
-
}
|
|
219
|
-
function updateHostLabel(url, label) {
|
|
220
|
-
url = normalizeUrl(url);
|
|
221
|
-
label = normalizeLabel(label);
|
|
222
|
-
const config = loadConfig();
|
|
223
|
-
if (!config.hosts[url]) {
|
|
224
|
-
throw new Error(`Host is not configured: ${url}`);
|
|
225
|
-
}
|
|
226
|
-
assertUniqueHostLabel(config, label, url);
|
|
227
|
-
config.hosts[url].label = label;
|
|
228
|
-
saveConfig(config);
|
|
229
|
-
}
|
|
230
|
-
function normalizeLabel(label) {
|
|
231
|
-
const normalized = label.trim();
|
|
232
|
-
if (!normalized) {
|
|
233
|
-
throw new Error("Label cannot be empty.");
|
|
234
|
-
}
|
|
235
|
-
return normalized;
|
|
236
|
-
}
|
|
237
|
-
function assertUniqueHostLabel(config, label, excludeUrl) {
|
|
238
|
-
const duplicate = Object.entries(config.hosts).find(([url, entry]) => url !== excludeUrl && entry.label === label);
|
|
239
|
-
if (duplicate) {
|
|
240
|
-
throw new Error(`Label already exists: ${label}. Rename the existing label first: ${duplicate[0]}`);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
function removeHost(url) {
|
|
244
|
-
url = normalizeUrl(url);
|
|
245
|
-
const config = loadConfig();
|
|
246
|
-
delete config.hosts[url];
|
|
247
|
-
if (config.activeHost === url) {
|
|
248
|
-
const remaining = Object.keys(config.hosts);
|
|
249
|
-
config.activeHost = remaining.length > 0 ? remaining[0] : "";
|
|
250
|
-
}
|
|
251
|
-
saveConfig(config);
|
|
252
|
-
}
|
|
253
|
-
function listHosts() {
|
|
254
|
-
const config = loadConfig();
|
|
255
|
-
return Object.entries(config.hosts).map(([url, entry]) => ({
|
|
256
|
-
url,
|
|
257
|
-
label: entry.label,
|
|
258
|
-
active: url === config.activeHost
|
|
259
|
-
}));
|
|
260
|
-
}
|
|
261
|
-
function resolveHostSelector(env) {
|
|
262
|
-
const raw = env.trim();
|
|
263
|
-
const selector = raw.startsWith("http://") || raw.startsWith("https://") ? normalizeUrl(raw) : raw;
|
|
264
|
-
const hosts = listHosts();
|
|
265
|
-
const byUrl = hosts.find((host) => host.url === selector);
|
|
266
|
-
if (byUrl) return { status: "found", host: byUrl };
|
|
267
|
-
const byLabel = hosts.filter((host) => host.label === raw);
|
|
268
|
-
if (byLabel.length === 1) return { status: "found", host: byLabel[0] };
|
|
269
|
-
if (byLabel.length > 1) return { status: "duplicate-label", matches: byLabel };
|
|
270
|
-
return { status: "not-found", hosts };
|
|
271
|
-
}
|
|
272
|
-
function getConfigDir() {
|
|
273
|
-
return CONFIG_DIR;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
export {
|
|
277
|
-
safeJsonParse,
|
|
278
|
-
safeReadJsonFile,
|
|
279
|
-
normalizeUrl,
|
|
280
|
-
getSandboxRuntimeRoot,
|
|
281
|
-
isAeSandboxRuntime,
|
|
282
|
-
getFallbackCliToken,
|
|
283
|
-
loadConfig,
|
|
284
|
-
saveConfig,
|
|
285
|
-
getActiveHost,
|
|
286
|
-
setActiveHost,
|
|
287
|
-
addHost,
|
|
288
|
-
updateHostLabel,
|
|
289
|
-
removeHost,
|
|
290
|
-
listHosts,
|
|
291
|
-
resolveHostSelector,
|
|
292
|
-
getConfigDir
|
|
293
|
-
};
|